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

Artifact aafcd5b0bc0f7f5c0fc95fb09964ac1055e371d00881c30b42280e9d5e956206:


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 69  )} {.          i
3660: 66 20 7b 30 3d 3d 24 3a 3a 73 71 6c 69 74 65 5f  f {0==$::sqlite_
3670: 6f 70 74 69 6f 6e 73 28 6d 65 6d 64 65 62 75 67  options(memdebug
3680: 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  )} {.           
3690: 20 73 65 74 20 65 72 72 20 22 45 72 72 6f 72 3a   set err "Error:
36a0: 20 2d 2d 6d 61 6c 6c 6f 63 74 72 61 63 65 3d 31   --malloctrace=1
36b0: 20 72 65 71 75 69 72 65 73 20 61 6e 20 53 51 4c   requires an SQL
36c0: 49 54 45 5f 4d 45 4d 44 45 42 55 47 20 62 75 69  ITE_MEMDEBUG bui
36d0: 6c 64 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  ld".            
36e0: 70 75 74 73 20 73 74 64 65 72 72 20 24 65 72 72  puts stderr $err
36f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 78 69  .            exi
3700: 74 20 31 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  t 1.          }.
3710: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
3720: 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73  3_memdebug_log s
3730: 74 61 72 74 0a 20 20 20 20 20 20 20 20 7d 0a 20  tart.        }. 
3740: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d       }.      {^-
3750: 2b 62 61 63 6b 74 72 61 63 65 3d 2e 2b 24 7d 20  +backtrace=.+$} 
3760: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
3770: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
3780: 61 72 67 28 62 61 63 6b 74 72 61 63 65 29 7d 20  arg(backtrace)} 
3790: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
37a0: 61 6b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  ak.        sqlit
37b0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63 6b  e3_memdebug_back
37c0: 74 72 61 63 65 20 24 63 6d 64 6c 69 6e 65 61 72  trace $cmdlinear
37d0: 67 28 62 61 63 6b 74 72 61 63 65 29 0a 20 20 20  g(backtrace).   
37e0: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 62     }.      {^-+b
37f0: 69 6e 61 72 79 6c 6f 67 3d 2e 2b 24 7d 20 7b 0a  inarylog=.+$} {.
3800: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
3810: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
3820: 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 5b 73  g(binarylog)} [s
3830: 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b  plit $a =] break
3840: 0a 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64  .        set cmd
3850: 6c 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f  linearg(binarylo
3860: 67 29 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69  g) [file normali
3870: 7a 65 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 62  ze $cmdlinearg(b
3880: 69 6e 61 72 79 6c 6f 67 29 5d 0a 20 20 20 20 20  inarylog)].     
3890: 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 73 6f 61   }.      {^-+soa
38a0: 6b 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20  k=.+$} {.       
38b0: 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20   foreach {dummy 
38c0: 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f 61 6b 29  cmdlinearg(soak)
38d0: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
38e0: 72 65 61 6b 0a 20 20 20 20 20 20 20 20 73 65 74  reak.        set
38f0: 20 3a 3a 47 28 69 73 73 6f 61 6b 29 20 24 63 6d   ::G(issoak) $cm
3900: 64 6c 69 6e 65 61 72 67 28 73 6f 61 6b 29 0a 20  dlinearg(soak). 
3910: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d       }.      {^-
3920: 2b 66 69 6c 65 2d 72 65 74 72 69 65 73 3d 2e 2b  +file-retries=.+
3930: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
3940: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
3950: 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72  inearg(file-retr
3960: 69 65 73 29 7d 20 5b 73 70 6c 69 74 20 24 61 20  ies)} [split $a 
3970: 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20  =] break.       
3980: 20 73 65 74 20 3a 3a 47 28 66 69 6c 65 2d 72 65   set ::G(file-re
3990: 74 72 69 65 73 29 20 24 63 6d 64 6c 69 6e 65 61  tries) $cmdlinea
39a0: 72 67 28 66 69 6c 65 2d 72 65 74 72 69 65 73 29  rg(file-retries)
39b0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
39c0: 5e 2d 2b 66 69 6c 65 2d 72 65 74 72 79 2d 64 65  ^-+file-retry-de
39d0: 6c 61 79 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20  lay=.+$} {.     
39e0: 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d     foreach {dumm
39f0: 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c  y cmdlinearg(fil
3a00: 65 2d 72 65 74 72 79 2d 64 65 6c 61 79 29 7d 20  e-retry-delay)} 
3a10: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
3a20: 61 6b 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a  ak.        set :
3a30: 3a 47 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65  :G(file-retry-de
3a40: 6c 61 79 29 20 24 63 6d 64 6c 69 6e 65 61 72 67  lay) $cmdlinearg
3a50: 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61  (file-retry-dela
3a60: 79 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  y).      }.     
3a70: 20 7b 5e 2d 2b 73 74 61 72 74 3d 2e 2b 24 7d 20   {^-+start=.+$} 
3a80: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
3a90: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
3aa0: 61 72 67 28 73 74 61 72 74 29 7d 20 5b 73 70 6c  arg(start)} [spl
3ab0: 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 0a  it $a =] break..
3ac0: 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28          set ::G(
3ad0: 73 74 61 72 74 3a 66 69 6c 65 29 20 24 63 6d 64  start:file) $cmd
3ae0: 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29 0a 20  linearg(start). 
3af0: 20 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65         if {[rege
3b00: 78 70 20 7b 28 2e 2a 29 3a 28 2e 2a 29 7d 20 24  xp {(.*):(.*)} $
3b10: 63 6d 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74  cmdlinearg(start
3b20: 29 20 2d 3e 20 73 2e 70 65 72 6d 20 73 2e 66 69  ) -> s.perm s.fi
3b30: 6c 65 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  le]} {.         
3b40: 20 73 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 70   set ::G(start:p
3b50: 65 72 6d 75 74 61 74 69 6f 6e 29 20 24 7b 73 2e  ermutation) ${s.
3b60: 70 65 72 6d 7d 0a 20 20 20 20 20 20 20 20 20 20  perm}.          
3b70: 73 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69  set ::G(start:fi
3b80: 6c 65 29 20 20 20 20 20 20 20 20 24 7b 73 2e 66  le)        ${s.f
3b90: 69 6c 65 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20  ile}.        }. 
3ba0: 20 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 47 28         if {$::G(
3bb0: 73 74 61 72 74 3a 66 69 6c 65 29 20 3d 3d 20 22  start:file) == "
3bc0: 22 7d 20 7b 75 6e 73 65 74 20 3a 3a 47 28 73 74  "} {unset ::G(st
3bd0: 61 72 74 3a 66 69 6c 65 29 7d 0a 20 20 20 20 20  art:file)}.     
3be0: 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 6d 61 74   }.      {^-+mat
3bf0: 63 68 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  ch=.+$} {.      
3c00: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
3c10: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 74 63   cmdlinearg(matc
3c20: 68 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d  h)} [split $a =]
3c30: 20 62 72 65 61 6b 0a 0a 20 20 20 20 20 20 20 20   break..        
3c40: 73 65 74 20 3a 3a 47 28 6d 61 74 63 68 29 20 24  set ::G(match) $
3c50: 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 74 63 68  cmdlinearg(match
3c60: 29 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 3a  ).        if {$:
3c70: 3a 47 28 6d 61 74 63 68 29 20 3d 3d 20 22 22 7d  :G(match) == ""}
3c80: 20 7b 75 6e 73 65 74 20 3a 3a 47 28 6d 61 74 63   {unset ::G(matc
3c90: 68 29 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  h)}.      }..   
3ca0: 20 20 20 7b 5e 2d 2b 6f 75 74 70 75 74 3d 2e 2b     {^-+output=.+
3cb0: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
3cc0: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
3cd0: 69 6e 65 61 72 67 28 6f 75 74 70 75 74 29 7d 20  inearg(output)} 
3ce0: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
3cf0: 61 6b 0a 20 20 20 20 20 20 20 20 73 65 74 20 63  ak.        set c
3d00: 6d 64 6c 69 6e 65 61 72 67 28 6f 75 74 70 75 74  mdlinearg(output
3d10: 29 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a  ) [file normaliz
3d20: 65 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75  e $cmdlinearg(ou
3d30: 74 70 75 74 29 5d 0a 20 20 20 20 20 20 20 20 69  tput)].        i
3d40: 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 76  f {$cmdlinearg(v
3d50: 65 72 62 6f 73 65 29 3d 3d 22 22 7d 20 7b 0a 20  erbose)==""} {. 
3d60: 20 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64           set cmd
3d70: 6c 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29  linearg(verbose)
3d80: 20 32 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   2.        }.   
3d90: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 76     }.      {^-+v
3da0: 65 72 62 6f 73 65 3d 2e 2b 24 7d 20 7b 0a 20 20  erbose=.+$} {.  
3db0: 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64        foreach {d
3dc0: 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28  ummy cmdlinearg(
3dd0: 76 65 72 62 6f 73 65 29 7d 20 5b 73 70 6c 69 74  verbose)} [split
3de0: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20   $a =] break.   
3df0: 20 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e       if {$cmdlin
3e00: 65 61 72 67 28 76 65 72 62 6f 73 65 29 3d 3d 22  earg(verbose)=="
3e10: 66 69 6c 65 22 7d 20 7b 0a 20 20 20 20 20 20 20  file"} {.       
3e20: 20 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72     set cmdlinear
3e30: 67 28 76 65 72 62 6f 73 65 29 20 32 0a 20 20 20  g(verbose) 2.   
3e40: 20 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b       } elseif {[
3e50: 73 74 72 69 6e 67 20 69 73 20 62 6f 6f 6c 65 61  string is boolea
3e60: 6e 20 2d 73 74 72 69 63 74 20 24 63 6d 64 6c 69  n -strict $cmdli
3e70: 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 5d 3d  nearg(verbose)]=
3e80: 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20  =0} {.          
3e90: 65 72 72 6f 72 20 22 6f 70 74 69 6f 6e 20 2d 2d  error "option --
3ea0: 76 65 72 62 6f 73 65 3d 20 6d 75 73 74 20 62 65  verbose= must be
3eb0: 20 73 65 74 20 74 6f 20 61 20 62 6f 6f 6c 65 61   set to a boolea
3ec0: 6e 20 6f 72 20 74 6f 20 5c 22 66 69 6c 65 5c 22  n or to \"file\"
3ed0: 22 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ".        }.    
3ee0: 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 74 65    }.      {^-+te
3ef0: 73 74 64 69 72 3d 2e 2a 24 7d 20 7b 0a 20 20 20  stdir=.*$} {.   
3f00: 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75       foreach {du
3f10: 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 74  mmy cmdlinearg(t
3f20: 65 73 74 64 69 72 29 7d 20 5b 73 70 6c 69 74 20  estdir)} [split 
3f30: 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20  $a =] break.    
3f40: 20 20 7d 0a 20 20 20 20 20 20 7b 2e 2a 68 65 6c    }.      {.*hel
3f50: 70 2e 2a 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  p.*} {.         
3f60: 70 72 69 6e 74 5f 68 65 6c 70 5f 61 6e 64 5f 71  print_help_and_q
3f70: 75 69 74 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  uit.      }.    
3f80: 20 20 7b 5e 2d 71 24 7d 20 7b 0a 20 20 20 20 20    {^-q$} {.     
3f90: 20 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72     set cmdlinear
3fa0: 67 28 6f 75 74 70 75 74 29 20 74 65 73 74 2d 6f  g(output) test-o
3fb0: 75 74 2e 74 78 74 0a 20 20 20 20 20 20 20 20 73  ut.txt.        s
3fc0: 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 76 65  et cmdlinearg(ve
3fd0: 72 62 6f 73 65 29 20 32 0a 20 20 20 20 20 20 7d  rbose) 2.      }
3fe0: 0a 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 20  ..      default 
3ff0: 7b 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 66  {.        if {[f
4000: 69 6c 65 20 74 61 69 6c 20 24 61 5d 3d 3d 24 61  ile tail $a]==$a
4010: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 61  } {.          la
4020: 70 70 65 6e 64 20 6c 65 66 74 6f 76 65 72 20 24  ppend leftover $
4030: 61 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65  a.        } else
4040: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 61 70   {.          lap
4050: 70 65 6e 64 20 6c 65 66 74 6f 76 65 72 20 5b 66  pend leftover [f
4060: 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 24 61  ile normalize $a
4070: 5d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ].        }.    
4080: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
4090: 73 65 74 20 74 65 73 74 64 69 72 20 5b 66 69 6c  set testdir [fil
40a0: 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 24 74 65 73  e normalize $tes
40b0: 74 64 69 72 5d 0a 20 20 73 65 74 20 63 6d 64 6c  tdir].  set cmdl
40c0: 69 6e 65 61 72 67 28 54 45 53 54 46 49 58 54 55  inearg(TESTFIXTU
40d0: 52 45 5f 48 4f 4d 45 29 20 5b 70 77 64 5d 0a 20  RE_HOME) [pwd]. 
40e0: 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28   set cmdlinearg(
40f0: 49 4e 46 4f 5f 53 43 52 49 50 54 29 20 5b 66 69  INFO_SCRIPT) [fi
4100: 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 5b 69 6e  le normalize [in
4110: 66 6f 20 73 63 72 69 70 74 5d 5d 0a 20 20 73 65  fo script]].  se
4120: 74 20 61 72 67 76 30 20 5b 66 69 6c 65 20 6e 6f  t argv0 [file no
4130: 72 6d 61 6c 69 7a 65 20 24 61 72 67 76 30 5d 0a  rmalize $argv0].
4140: 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72    if {$cmdlinear
4150: 67 28 74 65 73 74 64 69 72 29 21 3d 22 22 7d 20  g(testdir)!=""} 
4160: 7b 0a 20 20 20 20 66 69 6c 65 20 6d 6b 64 69 72  {.    file mkdir
4170: 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 74 65 73   $cmdlinearg(tes
4180: 74 64 69 72 29 0a 20 20 20 20 63 64 20 24 63 6d  tdir).    cd $cm
4190: 64 6c 69 6e 65 61 72 67 28 74 65 73 74 64 69 72  dlinearg(testdir
41a0: 29 0a 20 20 7d 0a 20 20 73 65 74 20 61 72 67 76  ).  }.  set argv
41b0: 20 24 6c 65 66 74 6f 76 65 72 0a 0a 20 20 23 20   $leftover..  # 
41c0: 49 6e 73 74 61 6c 6c 20 74 68 65 20 6d 61 6c 6c  Install the mall
41d0: 6f 63 20 6c 61 79 65 72 20 75 73 65 64 20 74 6f  oc layer used to
41e0: 20 69 6e 6a 65 63 74 20 4f 4f 4d 20 65 72 72 6f   inject OOM erro
41f0: 72 73 2e 20 41 6e 64 20 74 68 65 20 27 61 75 74  rs. And the 'aut
4200: 6f 6d 61 74 69 63 27 0a 20 20 23 20 65 78 74 65  omatic'.  # exte
4210: 6e 73 69 6f 6e 73 2e 20 54 68 69 73 20 6f 6e 6c  nsions. This onl
4220: 79 20 6e 65 65 64 73 20 74 6f 20 62 65 20 64 6f  y needs to be do
4230: 6e 65 20 6f 6e 63 65 20 66 6f 72 20 74 68 65 20  ne once for the 
4240: 70 72 6f 63 65 73 73 2e 0a 20 20 23 0a 20 20 73  process..  #.  s
4250: 71 6c 69 74 65 33 5f 73 68 75 74 64 6f 77 6e 0a  qlite3_shutdown.
4260: 20 20 69 6e 73 74 61 6c 6c 5f 6d 61 6c 6c 6f 63    install_malloc
4270: 5f 66 61 75 6c 74 73 69 6d 20 31 0a 20 20 73 71  _faultsim 1.  sq
4280: 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65  lite3_initialize
4290: 0a 20 20 61 75 74 6f 69 6e 73 74 61 6c 6c 5f 74  .  autoinstall_t
42a0: 65 73 74 5f 66 75 6e 63 74 69 6f 6e 73 0a 0a 20  est_functions.. 
42b0: 20 23 20 49 66 20 74 68 65 20 2d 2d 62 69 6e 61   # If the --bina
42c0: 72 79 6c 6f 67 20 6f 70 74 69 6f 6e 20 77 61 73  rylog option was
42d0: 20 73 70 65 63 69 66 69 65 64 2c 20 63 72 65 61   specified, crea
42e0: 74 65 20 74 68 65 20 6c 6f 67 67 69 6e 67 20 56  te the logging V
42f0: 46 53 2e 20 54 68 69 73 0a 20 20 23 20 63 61 6c  FS. This.  # cal
4300: 6c 20 69 6e 73 74 61 6c 6c 73 20 74 68 65 20 6e  l installs the n
4310: 65 77 20 56 46 53 20 61 73 20 74 68 65 20 64 65  ew VFS as the de
4320: 66 61 75 6c 74 20 66 6f 72 20 61 6c 6c 20 53 51  fault for all SQ
4330: 4c 69 74 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73  Lite connections
4340: 2e 0a 20 20 23 0a 20 20 69 66 20 7b 24 63 6d 64  ..  #.  if {$cmd
4350: 6c 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f  linearg(binarylo
4360: 67 29 7d 20 7b 0a 20 20 20 20 76 66 73 6c 6f 67  g)} {.    vfslog
4370: 20 6e 65 77 20 62 69 6e 61 72 79 6c 6f 67 20 7b   new binarylog {
4380: 7d 20 76 66 73 6c 6f 67 2e 62 69 6e 0a 20 20 7d  } vfslog.bin.  }
4390: 0a 0a 20 20 23 20 53 65 74 20 74 68 65 20 62 61  ..  # Set the ba
43a0: 63 6b 74 72 61 63 65 20 64 65 70 74 68 2c 20 69  cktrace depth, i
43b0: 66 20 6d 61 6c 6c 6f 63 20 74 72 61 63 69 6e 67  f malloc tracing
43c0: 20 69 73 20 65 6e 61 62 6c 65 64 2e 0a 20 20 23   is enabled..  #
43d0: 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61  .  if {$cmdlinea
43e0: 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d  rg(malloctrace)}
43f0: 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d   {.    sqlite3_m
4400: 65 6d 64 65 62 75 67 5f 62 61 63 6b 74 72 61 63  emdebug_backtrac
4410: 65 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 62 61  e $cmdlinearg(ba
4420: 63 6b 74 72 61 63 65 29 0a 20 20 7d 0a 0a 20 20  cktrace).  }..  
4430: 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28  if {$cmdlinearg(
4440: 6f 75 74 70 75 74 29 21 3d 22 22 7d 20 7b 0a 20  output)!=""} {. 
4450: 20 20 20 70 75 74 73 20 22 43 6f 70 79 69 6e 67     puts "Copying
4460: 20 6f 75 74 70 75 74 20 74 6f 20 66 69 6c 65 20   output to file 
4470: 24 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75 74 70  $cmdlinearg(outp
4480: 75 74 29 22 0a 20 20 20 20 73 65 74 20 3a 3a 47  ut)".    set ::G
4490: 28 6f 75 74 70 75 74 5f 66 64 29 20 5b 6f 70 65  (output_fd) [ope
44a0: 6e 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75  n $cmdlinearg(ou
44b0: 74 70 75 74 29 20 77 5d 0a 20 20 20 20 66 63 6f  tput) w].    fco
44c0: 6e 66 69 67 75 72 65 20 24 3a 3a 47 28 6f 75 74  nfigure $::G(out
44d0: 70 75 74 5f 66 64 29 20 2d 62 75 66 66 65 72 69  put_fd) -bufferi
44e0: 6e 67 20 6c 69 6e 65 0a 20 20 7d 0a 0a 20 20 69  ng line.  }..  i
44f0: 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 76  f {$cmdlinearg(v
4500: 65 72 62 6f 73 65 29 3d 3d 22 22 7d 20 7b 0a 20  erbose)==""} {. 
4510: 20 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72     set cmdlinear
4520: 67 28 76 65 72 62 6f 73 65 29 20 31 0a 20 20 7d  g(verbose) 1.  }
4530: 0a 7d 0a 0a 23 20 55 70 64 61 74 65 20 74 68 65  .}..# Update the
4540: 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74   soft-heap-limit
4550: 20 65 61 63 68 20 74 69 6d 65 20 74 68 69 73 20   each time this 
4560: 73 63 72 69 70 74 20 69 73 20 72 75 6e 2e 20 49  script is run. I
4570: 6e 20 74 68 61 74 0a 23 20 77 61 79 20 69 66 20  n that.# way if 
4580: 61 6e 20 69 6e 64 69 76 69 64 75 61 6c 20 74 65  an individual te
4590: 73 74 20 66 69 6c 65 20 63 68 61 6e 67 65 73 20  st file changes 
45a0: 74 68 65 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69  the soft-heap-li
45b0: 6d 69 74 2c 20 69 74 0a 23 20 77 69 6c 6c 20 62  mit, it.# will b
45c0: 65 20 72 65 73 65 74 20 61 74 20 74 68 65 20 73  e reset at the s
45d0: 74 61 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74  tart of the next
45e0: 20 74 65 73 74 20 66 69 6c 65 2e 0a 23 0a 73 71   test file..#.sq
45f0: 6c 69 74 65 33 5f 73 6f 66 74 5f 68 65 61 70 5f  lite3_soft_heap_
4600: 6c 69 6d 69 74 20 24 63 6d 64 6c 69 6e 65 61 72  limit $cmdlinear
4610: 67 28 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69  g(soft-heap-limi
4620: 74 29 0a 0a 23 20 43 72 65 61 74 65 20 61 20 74  t)..# Create a t
4630: 65 73 74 20 64 61 74 61 62 61 73 65 0a 23 0a 70  est database.#.p
4640: 72 6f 63 20 72 65 73 65 74 5f 64 62 20 7b 7d 20  roc reset_db {} 
4650: 7b 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c  {.  catch {db cl
4660: 6f 73 65 7d 0a 20 20 66 6f 72 63 65 64 65 6c 65  ose}.  forcedele
4670: 74 65 20 74 65 73 74 2e 64 62 0a 20 20 66 6f 72  te test.db.  for
4680: 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62  cedelete test.db
4690: 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72 63 65  -journal.  force
46a0: 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62 2d 77  delete test.db-w
46b0: 61 6c 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20  al.  sqlite3 db 
46c0: 2e 2f 74 65 73 74 2e 64 62 0a 20 20 73 65 74 20  ./test.db.  set 
46d0: 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 5f 63 6f  ::DB [sqlite3_co
46e0: 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72  nnection_pointer
46f0: 20 64 62 5d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f   db].  if {[info
4700: 20 65 78 69 73 74 73 20 3a 3a 53 45 54 55 50 5f   exists ::SETUP_
4710: 53 51 4c 5d 7d 20 7b 0a 20 20 20 20 64 62 20 65  SQL]} {.    db e
4720: 76 61 6c 20 24 3a 3a 53 45 54 55 50 5f 53 51 4c  val $::SETUP_SQL
4730: 0a 20 20 7d 0a 7d 0a 72 65 73 65 74 5f 64 62 0a  .  }.}.reset_db.
4740: 0a 23 20 41 62 6f 72 74 20 65 61 72 6c 79 20 69  .# Abort early i
4750: 66 20 74 68 69 73 20 73 63 72 69 70 74 20 68 61  f this script ha
4760: 73 20 62 65 65 6e 20 72 75 6e 20 62 65 66 6f 72  s been run befor
4770: 65 2e 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f 20 65  e..#.if {[info e
4780: 78 69 73 74 73 20 54 43 28 63 6f 75 6e 74 29 5d  xists TC(count)]
4790: 7d 20 72 65 74 75 72 6e 0a 0a 23 20 4d 61 6b 65  } return..# Make
47a0: 20 73 75 72 65 20 6d 65 6d 6f 72 79 20 73 74 61   sure memory sta
47b0: 74 69 73 74 69 63 73 20 61 72 65 20 65 6e 61 62  tistics are enab
47c0: 6c 65 64 2e 0a 23 0a 73 71 6c 69 74 65 33 5f 63  led..#.sqlite3_c
47d0: 6f 6e 66 69 67 5f 6d 65 6d 73 74 61 74 75 73 20  onfig_memstatus 
47e0: 31 0a 0a 23 20 49 6e 69 74 69 61 6c 69 7a 65 20  1..# Initialize 
47f0: 74 68 65 20 74 65 73 74 20 63 6f 75 6e 74 65 72  the test counter
4800: 73 20 61 6e 64 20 73 65 74 20 75 70 20 63 6f 6d  s and set up com
4810: 6d 61 6e 64 73 20 74 6f 20 61 63 63 65 73 73 20  mands to access 
4820: 74 68 65 6d 2e 0a 23 20 4f 72 2c 20 69 66 20 74  them..# Or, if t
4830: 68 69 73 20 69 73 20 61 20 73 6c 61 76 65 20 69  his is a slave i
4840: 6e 74 65 72 70 72 65 74 65 72 2c 20 73 65 74 20  nterpreter, set 
4850: 75 70 20 61 6c 69 61 73 65 73 20 74 6f 20 77 72  up aliases to wr
4860: 69 74 65 20 74 68 65 0a 23 20 63 6f 75 6e 74 65  ite the.# counte
4870: 72 73 20 69 6e 20 74 68 65 20 70 61 72 65 6e 74  rs in the parent
4880: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 23 0a   interpreter..#.
4890: 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69  if {0==[info exi
48a0: 73 74 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 0a  sts ::SLAVE]} {.
48b0: 20 20 73 65 74 20 54 43 28 65 72 72 6f 72 73 29    set TC(errors)
48c0: 20 20 20 20 30 0a 20 20 73 65 74 20 54 43 28 63      0.  set TC(c
48d0: 6f 75 6e 74 29 20 20 20 20 20 30 0a 20 20 73 65  ount)     0.  se
48e0: 74 20 54 43 28 66 61 69 6c 5f 6c 69 73 74 29 20  t TC(fail_list) 
48f0: 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 54 43 28  [list].  set TC(
4900: 6f 6d 69 74 5f 6c 69 73 74 29 20 5b 6c 69 73 74  omit_list) [list
4910: 5d 0a 20 20 73 65 74 20 54 43 28 77 61 72 6e 5f  ].  set TC(warn_
4920: 6c 69 73 74 29 20 5b 6c 69 73 74 5d 0a 0a 20 20  list) [list]..  
4930: 70 72 6f 63 20 73 65 74 5f 74 65 73 74 5f 63 6f  proc set_test_co
4940: 75 6e 74 65 72 20 7b 63 6f 75 6e 74 65 72 20 61  unter {counter a
4950: 72 67 73 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b  rgs} {.    if {[
4960: 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 7d 20  llength $args]} 
4970: 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 54 43  {.      set ::TC
4980: 28 24 63 6f 75 6e 74 65 72 29 20 5b 6c 69 6e 64  ($counter) [lind
4990: 65 78 20 24 61 72 67 73 20 30 5d 0a 20 20 20 20  ex $args 0].    
49a0: 7d 0a 20 20 20 20 73 65 74 20 3a 3a 54 43 28 24  }.    set ::TC($
49b0: 63 6f 75 6e 74 65 72 29 0a 20 20 7d 0a 7d 0a 0a  counter).  }.}..
49c0: 23 20 52 65 63 6f 72 64 20 74 68 65 20 66 61 63  # Record the fac
49d0: 74 20 74 68 61 74 20 61 20 73 65 71 75 65 6e 63  t that a sequenc
49e0: 65 20 6f 66 20 74 65 73 74 73 20 77 65 72 65 20  e of tests were 
49f0: 6f 6d 69 74 74 65 64 2e 0a 23 0a 70 72 6f 63 20  omitted..#.proc 
4a00: 6f 6d 69 74 5f 74 65 73 74 20 7b 6e 61 6d 65 20  omit_test {name 
4a10: 72 65 61 73 6f 6e 20 7b 61 70 70 65 6e 64 20 31  reason {append 1
4a20: 7d 7d 20 7b 0a 20 20 73 65 74 20 6f 6d 69 74 4c  }} {.  set omitL
4a30: 69 73 74 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  ist [set_test_co
4a40: 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74 5d  unter omit_list]
4a50: 0a 20 20 69 66 20 7b 24 61 70 70 65 6e 64 7d 20  .  if {$append} 
4a60: 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 6f 6d  {.    lappend om
4a70: 69 74 4c 69 73 74 20 5b 6c 69 73 74 20 24 6e 61  itList [list $na
4a80: 6d 65 20 24 72 65 61 73 6f 6e 5d 0a 20 20 7d 0a  me $reason].  }.
4a90: 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74    set_test_count
4aa0: 65 72 20 6f 6d 69 74 5f 6c 69 73 74 20 24 6f 6d  er omit_list $om
4ab0: 69 74 4c 69 73 74 0a 7d 0a 0a 23 20 52 65 63 6f  itList.}..# Reco
4ac0: 72 64 20 74 68 65 20 66 61 63 74 20 74 68 61 74  rd the fact that
4ad0: 20 61 20 74 65 73 74 20 66 61 69 6c 65 64 2e 0a   a test failed..
4ae0: 23 0a 70 72 6f 63 20 66 61 69 6c 5f 74 65 73 74  #.proc fail_test
4af0: 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 73 65 74 20   {name} {.  set 
4b00: 66 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  f [set_test_coun
4b10: 74 65 72 20 66 61 69 6c 5f 6c 69 73 74 5d 0a 20  ter fail_list]. 
4b20: 20 6c 61 70 70 65 6e 64 20 66 20 24 6e 61 6d 65   lappend f $name
4b30: 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  .  set_test_coun
4b40: 74 65 72 20 66 61 69 6c 5f 6c 69 73 74 20 24 66  ter fail_list $f
4b50: 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  .  set_test_coun
4b60: 74 65 72 20 65 72 72 6f 72 73 20 5b 65 78 70 72  ter errors [expr
4b70: 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74   [set_test_count
4b80: 65 72 20 65 72 72 6f 72 73 5d 20 2b 20 31 5d 0a  er errors] + 1].
4b90: 0a 20 20 73 65 74 20 6e 46 61 69 6c 20 5b 73 65  .  set nFail [se
4ba0: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 65  t_test_counter e
4bb0: 72 72 6f 72 73 5d 0a 20 20 69 66 20 7b 24 6e 46  rrors].  if {$nF
4bc0: 61 69 6c 3e 3d 24 3a 3a 63 6d 64 6c 69 6e 65 61  ail>=$::cmdlinea
4bd0: 72 67 28 6d 61 78 65 72 72 6f 72 29 7d 20 7b 0a  rg(maxerror)} {.
4be0: 20 20 20 20 6f 75 74 70 75 74 32 20 22 2a 2a 2a      output2 "***
4bf0: 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e 22 0a 20   Giving up...". 
4c00: 20 20 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74     finalize_test
4c10: 69 6e 67 0a 20 20 7d 0a 7d 0a 0a 23 20 52 65 6d  ing.  }.}..# Rem
4c20: 65 6d 62 65 72 20 61 20 77 61 72 6e 69 6e 67 20  ember a warning 
4c30: 6d 65 73 73 61 67 65 20 74 6f 20 62 65 20 64 69  message to be di
4c40: 73 70 6c 61 79 65 64 20 61 74 20 74 68 65 20 63  splayed at the c
4c50: 6f 6e 63 6c 75 73 69 6f 6e 20 6f 66 20 61 6c 6c  onclusion of all
4c60: 20 74 65 73 74 69 6e 67 0a 23 0a 70 72 6f 63 20   testing.#.proc 
4c70: 77 61 72 6e 69 6e 67 20 7b 6d 73 67 20 7b 61 70  warning {msg {ap
4c80: 70 65 6e 64 20 31 7d 7d 20 7b 0a 20 20 6f 75 74  pend 1}} {.  out
4c90: 70 75 74 32 20 22 57 61 72 6e 69 6e 67 3a 20 24  put2 "Warning: $
4ca0: 6d 73 67 22 0a 20 20 73 65 74 20 77 61 72 6e 4c  msg".  set warnL
4cb0: 69 73 74 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  ist [set_test_co
4cc0: 75 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73 74 5d  unter warn_list]
4cd0: 0a 20 20 69 66 20 7b 24 61 70 70 65 6e 64 7d 20  .  if {$append} 
4ce0: 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 77 61  {.    lappend wa
4cf0: 72 6e 4c 69 73 74 20 24 6d 73 67 0a 20 20 7d 0a  rnList $msg.  }.
4d00: 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74    set_test_count
4d10: 65 72 20 77 61 72 6e 5f 6c 69 73 74 20 24 77 61  er warn_list $wa
4d20: 72 6e 4c 69 73 74 0a 7d 0a 0a 0a 23 20 49 6e 63  rnList.}...# Inc
4d30: 72 65 6d 65 6e 74 20 74 68 65 20 6e 75 6d 62 65  rement the numbe
4d40: 72 20 6f 66 20 74 65 73 74 73 20 72 75 6e 0a 23  r of tests run.#
4d50: 0a 70 72 6f 63 20 69 6e 63 72 5f 6e 74 65 73 74  .proc incr_ntest
4d60: 20 7b 7d 20 7b 0a 20 20 73 65 74 5f 74 65 73 74   {} {.  set_test
4d70: 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74 20 5b  _counter count [
4d80: 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f 63  expr [set_test_c
4d90: 6f 75 6e 74 65 72 20 63 6f 75 6e 74 5d 20 2b 20  ounter count] + 
4da0: 31 5d 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 20 74  1].}..# Return t
4db0: 72 75 65 20 69 66 20 2d 2d 76 65 72 62 6f 73 65  rue if --verbose
4dc0: 3d 31 20 77 61 73 20 73 70 65 63 69 66 69 65 64  =1 was specified
4dd0: 20 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 20   on the command 
4de0: 6c 69 6e 65 2e 20 4f 74 68 65 72 77 69 73 65 2c  line. Otherwise,
4df0: 0a 23 20 72 65 74 75 72 6e 20 66 61 6c 73 65 2e  .# return false.
4e00: 0a 23 0a 70 72 6f 63 20 76 65 72 62 6f 73 65 20  .#.proc verbose 
4e10: 7b 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20 24 3a  {} {.  return $:
4e20: 3a 63 6d 64 6c 69 6e 65 61 72 67 28 76 65 72 62  :cmdlinearg(verb
4e30: 6f 73 65 29 0a 7d 0a 0a 23 20 55 73 65 20 74 68  ose).}..# Use th
4e40: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6d 6d  e following comm
4e50: 61 6e 64 73 20 69 6e 73 74 65 61 64 20 6f 66 20  ands instead of 
4e60: 5b 70 75 74 73 5d 20 66 6f 72 20 74 65 73 74 20  [puts] for test 
4e70: 6f 75 74 70 75 74 20 77 69 74 68 69 6e 0a 23 20  output within.# 
4e80: 74 68 69 73 20 66 69 6c 65 2e 20 54 65 73 74 20  this file. Test 
4e90: 73 63 72 69 70 74 73 20 63 61 6e 20 73 74 69 6c  scripts can stil
4ea0: 6c 20 75 73 65 20 72 65 67 75 6c 61 72 20 5b 70  l use regular [p
4eb0: 75 74 73 5d 2c 20 77 68 69 63 68 20 69 73 20 64  uts], which is d
4ec0: 69 72 65 63 74 65 64 0a 23 20 74 6f 20 73 74 64  irected.# to std
4ed0: 6f 75 74 20 61 6e 64 2c 20 69 66 20 6f 6e 65 20  out and, if one 
4ee0: 69 73 20 6f 70 65 6e 2c 20 74 68 65 20 2d 2d 6f  is open, the --o
4ef0: 75 74 70 75 74 20 66 69 6c 65 2e 0a 23 0a 23 20  utput file..#.# 
4f00: 6f 75 74 70 75 74 31 3a 20 6f 75 74 70 75 74 20  output1: output 
4f10: 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20 70  that should be p
4f20: 72 69 6e 74 65 64 20 69 66 20 2d 2d 76 65 72 62  rinted if --verb
4f30: 6f 73 65 3d 31 20 77 61 73 20 73 70 65 63 69 66  ose=1 was specif
4f40: 69 65 64 2e 0a 23 20 6f 75 74 70 75 74 32 3a 20  ied..# output2: 
4f50: 6f 75 74 70 75 74 20 74 68 61 74 20 73 68 6f 75  output that shou
4f60: 6c 64 20 62 65 20 70 72 69 6e 74 65 64 20 75 6e  ld be printed un
4f70: 63 6f 6e 64 69 74 69 6f 6e 61 6c 6c 79 2e 0a 23  conditionally..#
4f80: 20 6f 75 74 70 75 74 32 5f 69 66 5f 6e 6f 5f 76   output2_if_no_v
4f90: 65 72 62 6f 73 65 3a 20 6f 75 74 70 75 74 20 74  erbose: output t
4fa0: 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20 70 72  hat should be pr
4fb0: 69 6e 74 65 64 20 6f 6e 6c 79 20 69 66 20 2d 2d  inted only if --
4fc0: 76 65 72 62 6f 73 65 3d 30 2e 0a 23 0a 70 72 6f  verbose=0..#.pro
4fd0: 63 20 6f 75 74 70 75 74 31 20 7b 61 72 67 73 7d  c output1 {args}
4fe0: 20 7b 0a 20 20 73 65 74 20 76 20 5b 76 65 72 62   {.  set v [verb
4ff0: 6f 73 65 5d 0a 20 20 69 66 20 7b 24 76 3d 3d 31  ose].  if {$v==1
5000: 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c 20  } {.    uplevel 
5010: 6f 75 74 70 75 74 32 20 24 61 72 67 73 0a 20 20  output2 $args.  
5020: 7d 20 65 6c 73 65 69 66 20 7b 24 76 3d 3d 32 7d  } elseif {$v==2}
5030: 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c 20 70   {.    uplevel p
5040: 75 74 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67  uts [lrange $arg
5050: 73 20 30 20 65 6e 64 2d 31 5d 20 24 3a 3a 47 28  s 0 end-1] $::G(
5060: 6f 75 74 70 75 74 5f 66 64 29 20 5b 6c 72 61 6e  output_fd) [lran
5070: 67 65 20 24 61 72 67 73 20 65 6e 64 20 65 6e 64  ge $args end end
5080: 5d 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 6f 75 74  ].  }.}.proc out
5090: 70 75 74 32 20 7b 61 72 67 73 7d 20 7b 0a 20 20  put2 {args} {.  
50a0: 73 65 74 20 6e 41 72 67 20 5b 6c 6c 65 6e 67 74  set nArg [llengt
50b0: 68 20 24 61 72 67 73 5d 0a 20 20 75 70 6c 65 76  h $args].  uplev
50c0: 65 6c 20 70 75 74 73 20 24 61 72 67 73 0a 7d 0a  el puts $args.}.
50d0: 70 72 6f 63 20 6f 75 74 70 75 74 32 5f 69 66 5f  proc output2_if_
50e0: 6e 6f 5f 76 65 72 62 6f 73 65 20 7b 61 72 67 73  no_verbose {args
50f0: 7d 20 7b 0a 20 20 73 65 74 20 76 20 5b 76 65 72  } {.  set v [ver
5100: 62 6f 73 65 5d 0a 20 20 69 66 20 7b 24 76 3d 3d  bose].  if {$v==
5110: 30 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c  0} {.    uplevel
5120: 20 6f 75 74 70 75 74 32 20 24 61 72 67 73 0a 20   output2 $args. 
5130: 20 7d 20 65 6c 73 65 69 66 20 7b 24 76 3d 3d 32   } elseif {$v==2
5140: 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c 20  } {.    uplevel 
5150: 70 75 74 73 20 5b 6c 72 61 6e 67 65 20 24 61 72  puts [lrange $ar
5160: 67 73 20 30 20 65 6e 64 2d 31 5d 20 73 74 64 6f  gs 0 end-1] stdo
5170: 75 74 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73  ut [lrange $args
5180: 20 65 6e 64 20 65 6e 64 5d 0a 20 20 7d 0a 7d 0a   end end].  }.}.
5190: 0a 23 20 4f 76 65 72 72 69 64 65 20 74 68 65 20  .# Override the 
51a0: 5b 70 75 74 73 5d 20 63 6f 6d 6d 61 6e 64 20 73  [puts] command s
51b0: 6f 20 74 68 61 74 20 69 66 20 6e 6f 20 63 68 61  o that if no cha
51c0: 6e 6e 65 6c 20 69 73 20 65 78 70 6c 69 63 69 74  nnel is explicit
51d0: 6c 79 20 0a 23 20 73 70 65 63 69 66 69 65 64 20  ly .# specified 
51e0: 74 68 65 20 73 74 72 69 6e 67 20 69 73 20 77 72  the string is wr
51f0: 69 74 74 65 6e 20 74 6f 20 62 6f 74 68 20 73 74  itten to both st
5200: 64 6f 75 74 20 61 6e 64 20 74 6f 20 74 68 65 20  dout and to the 
5210: 66 69 6c 65 20 0a 23 20 73 70 65 63 69 66 69 65  file .# specifie
5220: 64 20 62 79 20 22 2d 2d 6f 75 74 70 75 74 3d 22  d by "--output="
5230: 2c 20 69 66 20 61 6e 79 2e 0a 23 0a 70 72 6f 63  , if any..#.proc
5240: 20 70 75 74 73 5f 6f 76 65 72 72 69 64 65 20 7b   puts_override {
5250: 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 6e 41  args} {.  set nA
5260: 72 67 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67  rg [llength $arg
5270: 73 5d 0a 20 20 69 66 20 7b 24 6e 41 72 67 3d 3d  s].  if {$nArg==
5280: 31 20 7c 7c 20 28 24 6e 41 72 67 3d 3d 32 20 26  1 || ($nArg==2 &
5290: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
52a0: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d  [lindex $args 0]
52b0: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 5d 3d 3d 30 29   -nonewline]==0)
52c0: 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c 20  } {.    uplevel 
52d0: 70 75 74 73 5f 6f 72 69 67 69 6e 61 6c 20 24 61  puts_original $a
52e0: 72 67 73 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66  rgs.    if {[inf
52f0: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6f 75 74  o exists ::G(out
5300: 70 75 74 5f 66 64 29 5d 7d 20 7b 0a 20 20 20 20  put_fd)]} {.    
5310: 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73 20 5b    uplevel puts [
5320: 6c 72 61 6e 67 65 20 24 61 72 67 73 20 30 20 65  lrange $args 0 e
5330: 6e 64 2d 31 5d 20 24 3a 3a 47 28 6f 75 74 70 75  nd-1] $::G(outpu
5340: 74 5f 66 64 29 20 5b 6c 72 61 6e 67 65 20 24 61  t_fd) [lrange $a
5350: 72 67 73 20 65 6e 64 20 65 6e 64 5d 0a 20 20 20  rgs end end].   
5360: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
5370: 20 20 23 20 41 20 63 68 61 6e 6e 65 6c 20 77 61    # A channel wa
5380: 73 20 65 78 70 6c 69 63 69 74 6c 79 20 73 70 65  s explicitly spe
5390: 63 69 66 69 65 64 2e 0a 20 20 20 20 75 70 6c 65  cified..    uple
53a0: 76 65 6c 20 70 75 74 73 5f 6f 72 69 67 69 6e 61  vel puts_origina
53b0: 6c 20 24 61 72 67 73 0a 20 20 7d 0a 7d 0a 72 65  l $args.  }.}.re
53c0: 6e 61 6d 65 20 70 75 74 73 20 70 75 74 73 5f 6f  name puts puts_o
53d0: 72 69 67 69 6e 61 6c 0a 70 72 6f 63 20 70 75 74  riginal.proc put
53e0: 73 20 7b 61 72 67 73 7d 20 7b 20 75 70 6c 65 76  s {args} { uplev
53f0: 65 6c 20 70 75 74 73 5f 6f 76 65 72 72 69 64 65  el puts_override
5400: 20 24 61 72 67 73 20 7d 0a 0a 0a 23 20 49 6e 76   $args }...# Inv
5410: 6f 6b 65 20 74 68 65 20 64 6f 5f 74 65 73 74 20  oke the do_test 
5420: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 72 75 6e  procedure to run
5430: 20 61 20 73 69 6e 67 6c 65 20 74 65 73 74 0a 23   a single test.#
5440: 0a 23 20 54 68 65 20 24 65 78 70 65 63 74 65 64  .# The $expected
5450: 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 74 68   parameter is th
5460: 65 20 65 78 70 65 63 74 65 64 20 72 65 73 75 6c  e expected resul
5470: 74 2e 20 20 54 68 65 20 72 65 73 75 6c 74 20 69  t.  The result i
5480: 73 20 74 68 65 20 72 65 74 75 72 6e 0a 23 20 76  s the return.# v
5490: 61 6c 75 65 20 66 72 6f 6d 20 74 68 65 20 6c 61  alue from the la
54a0: 73 74 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 20 69  st TCL command i
54b0: 6e 20 24 63 6d 64 2e 0a 23 0a 23 20 4e 6f 72 6d  n $cmd..#.# Norm
54c0: 61 6c 6c 79 2c 20 24 65 78 70 65 63 74 65 64 20  ally, $expected 
54d0: 6d 75 73 74 20 6d 61 74 63 68 20 65 78 61 63 74  must match exact
54e0: 6c 79 2e 20 20 42 75 74 20 69 66 20 24 65 78 70  ly.  But if $exp
54f0: 65 63 74 65 64 20 69 73 20 6f 66 20 74 68 65 20  ected is of the 
5500: 66 6f 72 6d 0a 23 20 22 2f 72 65 67 65 78 70 2f  form.# "/regexp/
5510: 22 20 74 68 65 6e 20 72 65 67 75 6c 61 72 20 65  " then regular e
5520: 78 70 72 65 73 73 69 6f 6e 20 6d 61 74 63 68 69  xpression matchi
5530: 6e 67 20 69 73 20 75 73 65 64 2e 20 20 49 66 20  ng is used.  If 
5540: 24 65 78 70 65 63 74 65 64 20 69 73 0a 23 20 22  $expected is.# "
5550: 7e 2f 72 65 67 65 78 70 2f 22 20 74 68 65 6e 20  ~/regexp/" then 
5560: 74 68 65 20 72 65 67 75 6c 61 72 20 65 78 70 72  the regular expr
5570: 65 73 73 69 6f 6e 20 6d 75 73 74 20 4e 4f 54 20  ession must NOT 
5580: 6d 61 74 63 68 2e 20 20 49 66 20 24 65 78 70 65  match.  If $expe
5590: 63 74 65 64 20 69 73 0a 23 20 6f 66 20 74 68 65  cted is.# of the
55a0: 20 66 6f 72 6d 20 22 23 2f 76 61 6c 75 65 2d 6c   form "#/value-l
55b0: 69 73 74 2f 22 20 74 68 65 6e 20 65 61 63 68 20  ist/" then each 
55c0: 74 65 72 6d 20 69 6e 20 76 61 6c 75 65 2d 6c 69  term in value-li
55d0: 73 74 20 6d 75 73 74 20 62 65 20 6e 75 6d 65 72  st must be numer
55e0: 69 63 0a 23 20 61 6e 64 20 6d 75 73 74 20 61 70  ic.# and must ap
55f0: 70 72 6f 78 69 6d 61 74 65 6c 79 20 6d 61 74 63  proximately matc
5600: 68 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64  h the correspond
5610: 69 6e 67 20 6e 75 6d 65 72 69 63 20 74 65 72 6d  ing numeric term
5620: 20 69 6e 20 24 72 65 73 75 6c 74 2e 0a 23 20 56   in $result..# V
5630: 61 6c 75 65 73 20 6d 75 73 74 20 6d 61 74 63 68  alues must match
5640: 20 77 69 74 68 69 6e 20 31 30 25 2e 20 20 4f 72   within 10%.  Or
5650: 20 69 66 20 74 68 65 20 24 65 78 70 65 63 74 65   if the $expecte
5660: 64 20 74 65 72 6d 20 69 73 20 41 2e 2e 42 20 74  d term is A..B t
5670: 68 65 6e 20 74 68 65 0a 23 20 24 72 65 73 75 6c  hen the.# $resul
5680: 74 20 74 65 72 6d 20 6d 75 73 74 20 62 65 20 69  t term must be i
5690: 6e 20 62 65 74 77 65 65 6e 20 41 20 61 6e 64 20  n between A and 
56a0: 42 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 74 65 73  B..#.proc do_tes
56b0: 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70 65  t {name cmd expe
56c0: 63 74 65 64 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c  cted} {.  global
56d0: 20 61 72 67 76 20 63 6d 64 6c 69 6e 65 61 72 67   argv cmdlinearg
56e0: 0a 0a 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65  ..  fix_testname
56f0: 20 6e 61 6d 65 0a 0a 20 20 73 71 6c 69 74 65 33   name..  sqlite3
5700: 5f 6d 65 6d 64 65 62 75 67 5f 73 65 74 74 69 74  _memdebug_settit
5710: 6c 65 20 24 6e 61 6d 65 0a 0a 23 20 20 69 66 20  le $name..#  if 
5720: 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d  {[llength $argv]
5730: 3d 3d 30 7d 20 7b 0a 23 20 20 20 20 73 65 74 20  ==0} {.#    set 
5740: 67 6f 20 31 0a 23 20 20 7d 20 65 6c 73 65 20 7b  go 1.#  } else {
5750: 0a 23 20 20 20 20 73 65 74 20 67 6f 20 30 0a 23  .#    set go 0.#
5760: 20 20 20 20 66 6f 72 65 61 63 68 20 70 61 74 74      foreach patt
5770: 65 72 6e 20 24 61 72 67 76 20 7b 0a 23 20 20 20  ern $argv {.#   
5780: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6d     if {[string m
5790: 61 74 63 68 20 24 70 61 74 74 65 72 6e 20 24 6e  atch $pattern $n
57a0: 61 6d 65 5d 7d 20 7b 0a 23 20 20 20 20 20 20 20  ame]} {.#       
57b0: 20 73 65 74 20 67 6f 20 31 0a 23 20 20 20 20 20   set go 1.#     
57c0: 20 20 20 62 72 65 61 6b 0a 23 20 20 20 20 20 20     break.#      
57d0: 7d 0a 23 20 20 20 20 7d 0a 23 20 20 7d 0a 0a 20  }.#    }.#  }.. 
57e0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
57f0: 73 20 3a 3a 47 28 70 65 72 6d 3a 70 72 65 66 69  s ::G(perm:prefi
5800: 78 29 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 6e  x)]} {.    set n
5810: 61 6d 65 20 22 24 3a 3a 47 28 70 65 72 6d 3a 70  ame "$::G(perm:p
5820: 72 65 66 69 78 29 24 6e 61 6d 65 22 0a 20 20 7d  refix)$name".  }
5830: 0a 0a 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a 20  ..  incr_ntest. 
5840: 20 6f 75 74 70 75 74 31 20 2d 6e 6f 6e 65 77 6c   output1 -nonewl
5850: 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 66  ine $name....  f
5860: 6c 75 73 68 20 73 74 64 6f 75 74 0a 0a 20 20 69  lush stdout..  i
5870: 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73  f {![info exists
5880: 20 3a 3a 47 28 6d 61 74 63 68 29 5d 20 7c 7c 20   ::G(match)] || 
5890: 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 3a  [string match $:
58a0: 3a 47 28 6d 61 74 63 68 29 20 24 6e 61 6d 65 5d  :G(match) $name]
58b0: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 63 61 74  } {.    if {[cat
58c0: 63 68 20 7b 75 70 6c 65 76 65 6c 20 23 30 20 22  ch {uplevel #0 "
58d0: 24 63 6d 64 3b 5c 6e 22 7d 20 72 65 73 75 6c 74  $cmd;\n"} result
58e0: 5d 7d 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75  ]} {.      outpu
58f0: 74 32 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f 73 65  t2_if_no_verbose
5900: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d   -nonewline $nam
5910: 65 2e 2e 2e 0a 20 20 20 20 20 20 6f 75 74 70 75  e....      outpu
5920: 74 32 20 22 5c 6e 45 72 72 6f 72 3a 20 24 72 65  t2 "\nError: $re
5930: 73 75 6c 74 22 0a 20 20 20 20 20 20 66 61 69 6c  sult".      fail
5940: 5f 74 65 73 74 20 24 6e 61 6d 65 0a 20 20 20 20  _test $name.    
5950: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 69  } else {.      i
5960: 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 5b 7e 23  f {[regexp {^[~#
5970: 5d 3f 2f 2e 2a 2f 24 7d 20 24 65 78 70 65 63 74  ]?/.*/$} $expect
5980: 65 64 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 23  ed]} {.        #
5990: 20 22 65 78 70 65 63 74 65 64 22 20 69 73 20 6f   "expected" is o
59a0: 66 20 74 68 65 20 66 6f 72 6d 20 22 2f 50 41 54  f the form "/PAT
59b0: 54 45 52 4e 2f 22 20 74 68 65 6e 20 74 68 65 20  TERN/" then the 
59c0: 72 65 73 75 6c 74 20 69 66 20 63 6f 72 72 65 63  result if correc
59d0: 74 20 69 66 0a 20 20 20 20 20 20 20 20 23 20 72  t if.        # r
59e0: 65 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f  egular expressio
59f0: 6e 20 50 41 54 54 45 52 4e 20 6d 61 74 63 68 65  n PATTERN matche
5a00: 73 20 74 68 65 20 72 65 73 75 6c 74 2e 20 20 22  s the result.  "
5a10: 7e 2f 50 41 54 54 45 52 4e 2f 22 20 6d 65 61 6e  ~/PATTERN/" mean
5a20: 73 0a 20 20 20 20 20 20 20 20 23 20 74 68 65 20  s.        # the 
5a30: 72 65 67 75 6c 61 72 20 65 78 70 72 65 73 73 69  regular expressi
5a40: 6f 6e 20 6d 75 73 74 20 6e 6f 74 20 6d 61 74 63  on must not matc
5a50: 68 2e 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b  h..        if {[
5a60: 73 74 72 69 6e 67 20 69 6e 64 65 78 20 24 65 78  string index $ex
5a70: 70 65 63 74 65 64 20 30 5d 3d 3d 22 7e 22 7d 20  pected 0]=="~"} 
5a80: 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  {.          set 
5a90: 72 65 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65  re [string range
5aa0: 20 24 65 78 70 65 63 74 65 64 20 32 20 65 6e 64   $expected 2 end
5ab0: 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20 69 66  -1].          if
5ac0: 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20   {[string index 
5ad0: 24 72 65 20 30 5d 3d 3d 22 2a 22 7d 20 7b 0a 20  $re 0]=="*"} {. 
5ae0: 20 20 20 20 20 20 20 20 20 20 20 23 20 49 66 20             # If 
5af0: 74 68 65 20 72 65 67 75 6c 61 72 20 65 78 70 72  the regular expr
5b00: 65 73 73 69 6f 6e 20 62 65 67 69 6e 73 20 77 69  ession begins wi
5b10: 74 68 20 2a 20 74 68 65 6e 20 74 72 65 61 74 20  th * then treat 
5b20: 69 74 20 61 73 20 61 20 67 6c 6f 62 20 69 6e 73  it as a glob ins
5b30: 74 65 61 64 0a 20 20 20 20 20 20 20 20 20 20 20  tead.           
5b40: 20 73 65 74 20 6f 6b 20 5b 73 74 72 69 6e 67 20   set ok [string 
5b50: 6d 61 74 63 68 20 24 72 65 20 24 72 65 73 75 6c  match $re $resul
5b60: 74 5d 0a 20 20 20 20 20 20 20 20 20 20 7d 20 65  t].          } e
5b70: 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20 20  lse {.          
5b80: 20 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67    set re [string
5b90: 20 6d 61 70 20 7b 23 20 7b 5b 2d 30 2d 39 2e 5d   map {# {[-0-9.]
5ba0: 2b 7d 7d 20 24 72 65 5d 0a 20 20 20 20 20 20 20  +}} $re].       
5bb0: 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 72 65 67       set ok [reg
5bc0: 65 78 70 20 24 72 65 20 24 72 65 73 75 6c 74 5d  exp $re $result]
5bd0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
5be0: 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 65         set ok [e
5bf0: 78 70 72 20 7b 21 24 6f 6b 7d 5d 0a 20 20 20 20  xpr {!$ok}].    
5c00: 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 73      } elseif {[s
5c10: 74 72 69 6e 67 20 69 6e 64 65 78 20 24 65 78 70  tring index $exp
5c20: 65 63 74 65 64 20 30 5d 3d 3d 22 23 22 7d 20 7b  ected 0]=="#"} {
5c30: 0a 20 20 20 20 20 20 20 20 20 20 23 20 4e 75 6d  .          # Num
5c40: 65 72 69 63 20 72 61 6e 67 65 20 76 61 6c 75 65  eric range value
5c50: 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 20 20 45 61   comparison.  Ea
5c60: 63 68 20 74 65 72 6d 20 6f 66 20 74 68 65 20 24  ch term of the $
5c70: 72 65 73 75 6c 74 20 69 73 20 6d 61 74 63 68 65  result is matche
5c80: 64 0a 20 20 20 20 20 20 20 20 20 20 23 20 61 67  d.          # ag
5c90: 61 69 6e 73 74 20 6f 6e 65 20 74 65 72 6d 20 6f  ainst one term o
5ca0: 66 20 24 65 78 70 65 63 74 2e 20 20 42 6f 74 68  f $expect.  Both
5cb0: 20 24 72 65 73 75 6c 74 20 61 6e 64 20 24 65 78   $result and $ex
5cc0: 70 65 63 74 65 64 20 74 65 72 6d 73 20 6d 75 73  pected terms mus
5cd0: 74 20 62 65 0a 20 20 20 20 20 20 20 20 20 20 23  t be.          #
5ce0: 20 6e 75 6d 65 72 69 63 2e 20 20 54 68 65 20 76   numeric.  The v
5cf0: 61 6c 75 65 73 20 6d 75 73 74 20 6d 61 74 63 68  alues must match
5d00: 20 77 69 74 68 69 6e 20 31 30 25 2e 20 20 4f 72   within 10%.  Or
5d10: 20 69 66 20 24 65 78 70 65 63 74 65 64 20 69 73   if $expected is
5d20: 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20 20 20   of the.        
5d30: 20 20 23 20 66 6f 72 6d 20 41 2e 2e 42 20 74 68    # form A..B th
5d40: 65 6e 20 74 68 65 20 24 72 65 73 75 6c 74 20 74  en the $result t
5d50: 65 72 6d 20 6d 75 73 74 20 62 65 20 62 65 74 77  erm must be betw
5d60: 65 65 6e 20 41 20 61 6e 64 20 42 2e 0a 20 20 20  een A and B..   
5d70: 20 20 20 20 20 20 20 73 65 74 20 65 32 20 5b 73         set e2 [s
5d80: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70  tring range $exp
5d90: 65 63 74 65 64 20 32 20 65 6e 64 2d 31 5d 0a 20  ected 2 end-1]. 
5da0: 20 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68           foreach
5db0: 20 69 20 24 72 65 73 75 6c 74 20 6a 20 24 65 32   i $result j $e2
5dc0: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69   {.            i
5dd0: 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 28 2d 3f  f {[regexp {^(-?
5de0: 5c 64 2b 29 5c 2e 5c 2e 28 2d 3f 5c 64 29 24 7d  \d+)\.\.(-?\d)$}
5df0: 20 24 6a 20 61 6c 6c 20 41 20 42 5d 7d 20 7b 0a   $j all A B]} {.
5e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65                se
5e10: 74 20 6f 6b 20 5b 65 78 70 72 20 7b 24 69 2b 30  t ok [expr {$i+0
5e20: 3e 3d 24 41 20 26 26 20 24 69 2b 30 3c 3d 24 42  >=$A && $i+0<=$B
5e30: 7d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  }].            }
5e40: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
5e50: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 65 78        set ok [ex
5e60: 70 72 20 7b 24 69 2b 30 3e 3d 30 2e 39 2a 24 6a  pr {$i+0>=0.9*$j
5e70: 20 26 26 20 24 69 2b 30 3c 3d 31 2e 31 2a 24 6a   && $i+0<=1.1*$j
5e80: 7d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  }].            }
5e90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
5ea0: 7b 21 24 6f 6b 7d 20 62 72 65 61 6b 0a 20 20 20  {!$ok} break.   
5eb0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
5ec0: 20 20 20 69 66 20 7b 24 6f 6b 20 26 26 20 5b 6c     if {$ok && [l
5ed0: 6c 65 6e 67 74 68 20 24 72 65 73 75 6c 74 5d 21  length $result]!
5ee0: 3d 5b 6c 6c 65 6e 67 74 68 20 24 65 32 5d 7d 20  =[llength $e2]} 
5ef0: 7b 73 65 74 20 6f 6b 20 30 7d 0a 20 20 20 20 20  {set ok 0}.     
5f00: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
5f10: 20 20 20 20 20 20 73 65 74 20 72 65 20 5b 73 74        set re [st
5f20: 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70 65  ring range $expe
5f30: 63 74 65 64 20 31 20 65 6e 64 2d 31 5d 0a 20 20  cted 1 end-1].  
5f40: 20 20 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72          if {[str
5f50: 69 6e 67 20 69 6e 64 65 78 20 24 72 65 20 30 5d  ing index $re 0]
5f60: 3d 3d 22 2a 22 7d 20 7b 0a 20 20 20 20 20 20 20  =="*"} {.       
5f70: 20 20 20 20 20 23 20 49 66 20 74 68 65 20 72 65       # If the re
5f80: 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f 6e  gular expression
5f90: 20 62 65 67 69 6e 73 20 77 69 74 68 20 2a 20 74   begins with * t
5fa0: 68 65 6e 20 74 72 65 61 74 20 69 74 20 61 73 20  hen treat it as 
5fb0: 61 20 67 6c 6f 62 20 69 6e 73 74 65 61 64 0a 20  a glob instead. 
5fc0: 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f             set o
5fd0: 6b 20 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20  k [string match 
5fe0: 24 72 65 20 24 72 65 73 75 6c 74 5d 0a 20 20 20  $re $result].   
5ff0: 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a         } else {.
6000: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
6010: 72 65 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b  re [string map {
6020: 23 20 7b 5b 2d 30 2d 39 2e 5d 2b 7d 7d 20 24 72  # {[-0-9.]+}} $r
6030: 65 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  e].            s
6040: 65 74 20 6f 6b 20 5b 72 65 67 65 78 70 20 24 72  et ok [regexp $r
6050: 65 20 24 72 65 73 75 6c 74 5d 0a 20 20 20 20 20  e $result].     
6060: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
6070: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 69 66 20  .      } elseif 
6080: 7b 5b 72 65 67 65 78 70 20 7b 5e 7e 3f 5c 2a 2e  {[regexp {^~?\*.
6090: 2a 5c 2a 24 7d 20 24 65 78 70 65 63 74 65 64 5d  *\*$} $expected]
60a0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20 22 65  } {.        # "e
60b0: 78 70 65 63 74 65 64 22 20 69 73 20 6f 66 20 74  xpected" is of t
60c0: 68 65 20 66 6f 72 6d 20 22 2a 47 4c 4f 42 2a 22  he form "*GLOB*"
60d0: 20 74 68 65 6e 20 74 68 65 20 72 65 73 75 6c 74   then the result
60e0: 20 69 66 20 63 6f 72 72 65 63 74 20 69 66 0a 20   if correct if. 
60f0: 20 20 20 20 20 20 20 23 20 67 6c 6f 62 20 70 61         # glob pa
6100: 74 74 65 72 6e 20 47 4c 4f 42 20 6d 61 74 63 68  ttern GLOB match
6110: 65 73 20 74 68 65 20 72 65 73 75 6c 74 2e 20 20  es the result.  
6120: 22 7e 2f 47 4c 4f 42 2f 22 20 6d 65 61 6e 73 0a  "~/GLOB/" means.
6130: 20 20 20 20 20 20 20 20 23 20 74 68 65 20 67 6c          # the gl
6140: 6f 62 20 6d 75 73 74 20 6e 6f 74 20 6d 61 74 63  ob must not matc
6150: 68 2e 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b  h..        if {[
6160: 73 74 72 69 6e 67 20 69 6e 64 65 78 20 24 65 78  string index $ex
6170: 70 65 63 74 65 64 20 30 5d 3d 3d 22 7e 22 7d 20  pected 0]=="~"} 
6180: 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  {.          set 
6190: 65 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  e [string range 
61a0: 24 65 78 70 65 63 74 65 64 20 31 20 65 6e 64 5d  $expected 1 end]
61b0: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f  .          set o
61c0: 6b 20 5b 65 78 70 72 20 7b 21 5b 73 74 72 69 6e  k [expr {![strin
61d0: 67 20 6d 61 74 63 68 20 24 65 20 24 72 65 73 75  g match $e $resu
61e0: 6c 74 5d 7d 5d 0a 20 20 20 20 20 20 20 20 7d 20  lt]}].        } 
61f0: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20  else {.         
6200: 20 73 65 74 20 6f 6b 20 5b 73 74 72 69 6e 67 20   set ok [string 
6210: 6d 61 74 63 68 20 24 65 78 70 65 63 74 65 64 20  match $expected 
6220: 24 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20  $result].       
6230: 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20   }.      } else 
6240: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b  {.        set ok
6250: 20 5b 65 78 70 72 20 7b 5b 73 74 72 69 6e 67 20   [expr {[string 
6260: 63 6f 6d 70 61 72 65 20 24 72 65 73 75 6c 74 20  compare $result 
6270: 24 65 78 70 65 63 74 65 64 5d 3d 3d 30 7d 5d 0a  $expected]==0}].
6280: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
6290: 20 7b 21 24 6f 6b 7d 20 7b 0a 20 20 20 20 20 20   {!$ok} {.      
62a0: 20 20 23 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65    # if {![info e
62b0: 78 69 73 74 73 20 3a 3a 74 65 73 74 70 72 65 66  xists ::testpref
62c0: 69 78 5d 20 7c 7c 20 24 3a 3a 74 65 73 74 70 72  ix] || $::testpr
62d0: 65 66 69 78 20 65 71 20 22 22 7d 20 7b 0a 20 20  efix eq ""} {.  
62e0: 20 20 20 20 20 20 23 20 20 20 65 72 72 6f 72 20        #   error 
62f0: 22 6e 6f 20 74 65 73 74 20 70 72 65 66 69 78 22  "no test prefix"
6300: 0a 20 20 20 20 20 20 20 20 23 20 7d 0a 20 20 20  .        # }.   
6310: 20 20 20 20 20 6f 75 74 70 75 74 31 20 22 22 0a       output1 "".
6320: 20 20 20 20 20 20 20 20 6f 75 74 70 75 74 32 20          output2 
6330: 22 21 20 24 6e 61 6d 65 20 65 78 70 65 63 74 65  "! $name expecte
6340: 64 3a 20 5c 5b 24 65 78 70 65 63 74 65 64 5c 5d  d: \[$expected\]
6350: 5c 6e 21 20 24 6e 61 6d 65 20 67 6f 74 3a 20 20  \n! $name got:  
6360: 20 20 20 20 5c 5b 24 72 65 73 75 6c 74 5c 5d 22      \[$result\]"
6370: 0a 20 20 20 20 20 20 20 20 66 61 69 6c 5f 74 65  .        fail_te
6380: 73 74 20 24 6e 61 6d 65 0a 20 20 20 20 20 20 7d  st $name.      }
6390: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
63a0: 6f 75 74 70 75 74 31 20 22 20 4f 6b 22 0a 20 20  output1 " Ok".  
63b0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20      }.    }.  } 
63c0: 65 6c 73 65 20 7b 0a 20 20 20 20 6f 75 74 70 75  else {.    outpu
63d0: 74 31 20 22 20 4f 6d 69 74 74 65 64 22 0a 20 20  t1 " Omitted".  
63e0: 20 20 6f 6d 69 74 5f 74 65 73 74 20 24 6e 61 6d    omit_test $nam
63f0: 65 20 22 70 61 74 74 65 72 6e 20 6d 69 73 6d 61  e "pattern misma
6400: 74 63 68 22 20 30 0a 20 20 7d 0a 20 20 66 6c 75  tch" 0.  }.  flu
6410: 73 68 20 73 74 64 6f 75 74 0a 7d 0a 0a 70 72 6f  sh stdout.}..pro
6420: 63 20 64 75 6d 70 62 79 74 65 73 20 7b 73 7d 20  c dumpbytes {s} 
6430: 7b 0a 20 20 73 65 74 20 72 20 22 22 0a 20 20 66  {.  set r "".  f
6440: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
6450: 20 3c 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74   < [string lengt
6460: 68 20 24 73 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  h $s]} {incr i} 
6470: 7b 0a 20 20 20 20 69 66 20 7b 24 69 20 3e 20 30  {.    if {$i > 0
6480: 7d 20 7b 61 70 70 65 6e 64 20 72 20 22 20 22 7d  } {append r " "}
6490: 0a 20 20 20 20 61 70 70 65 6e 64 20 72 20 5b 66  .    append r [f
64a0: 6f 72 6d 61 74 20 25 30 32 58 20 5b 73 63 61 6e  ormat %02X [scan
64b0: 20 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 24   [string index $
64c0: 73 20 24 69 5d 20 25 63 5d 5d 0a 20 20 7d 0a 20  s $i] %c]].  }. 
64d0: 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 70 72   return $r.}..pr
64e0: 6f 63 20 63 61 74 63 68 63 6d 64 20 7b 64 62 20  oc catchcmd {db 
64f0: 7b 63 6d 64 20 22 22 7d 7d 20 7b 0a 20 20 67 6c  {cmd ""}} {.  gl
6500: 6f 62 61 6c 20 43 4c 49 0a 20 20 73 65 74 20 6f  obal CLI.  set o
6510: 75 74 20 5b 6f 70 65 6e 20 63 6d 64 73 2e 74 78  ut [open cmds.tx
6520: 74 20 77 5d 0a 20 20 70 75 74 73 20 24 6f 75 74  t w].  puts $out
6530: 20 24 63 6d 64 0a 20 20 63 6c 6f 73 65 20 24 6f   $cmd.  close $o
6540: 75 74 0a 20 20 73 65 74 20 6c 69 6e 65 20 22 65  ut.  set line "e
6550: 78 65 63 20 24 43 4c 49 20 24 64 62 20 3c 20 63  xec $CLI $db < c
6560: 6d 64 73 2e 74 78 74 22 0a 20 20 73 65 74 20 72  mds.txt".  set r
6570: 63 20 5b 63 61 74 63 68 20 7b 20 65 76 61 6c 20  c [catch { eval 
6580: 24 6c 69 6e 65 20 7d 20 6d 73 67 5d 0a 20 20 6c  $line } msg].  l
6590: 69 73 74 20 24 72 63 20 24 6d 73 67 0a 7d 0a 0a  ist $rc $msg.}..
65a0: 70 72 6f 63 20 63 61 74 63 68 63 6d 64 65 78 20  proc catchcmdex 
65b0: 7b 64 62 20 7b 63 6d 64 20 22 22 7d 7d 20 7b 0a  {db {cmd ""}} {.
65c0: 20 20 67 6c 6f 62 61 6c 20 43 4c 49 0a 20 20 73    global CLI.  s
65d0: 65 74 20 6f 75 74 20 5b 6f 70 65 6e 20 63 6d 64  et out [open cmd
65e0: 73 2e 74 78 74 20 77 5d 0a 20 20 66 63 6f 6e 66  s.txt w].  fconf
65f0: 69 67 75 72 65 20 24 6f 75 74 20 2d 65 6e 63 6f  igure $out -enco
6600: 64 69 6e 67 20 62 69 6e 61 72 79 20 2d 74 72 61  ding binary -tra
6610: 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a  nslation binary.
6620: 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e    puts -nonewlin
6630: 65 20 24 6f 75 74 20 24 63 6d 64 0a 20 20 63 6c  e $out $cmd.  cl
6640: 6f 73 65 20 24 6f 75 74 0a 20 20 73 65 74 20 6c  ose $out.  set l
6650: 69 6e 65 20 22 65 78 65 63 20 2d 6b 65 65 70 6e  ine "exec -keepn
6660: 65 77 6c 69 6e 65 20 2d 2d 20 24 43 4c 49 20 24  ewline -- $CLI $
6670: 64 62 20 3c 20 63 6d 64 73 2e 74 78 74 22 0a 20  db < cmds.txt". 
6680: 20 73 65 74 20 63 68 61 6e 73 20 5b 6c 69 73 74   set chans [list
6690: 20 73 74 64 69 6e 20 73 74 64 6f 75 74 20 73 74   stdin stdout st
66a0: 64 65 72 72 5d 0a 20 20 66 6f 72 65 61 63 68 20  derr].  foreach 
66b0: 63 68 61 6e 20 24 63 68 61 6e 73 20 7b 0a 20 20  chan $chans {.  
66c0: 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20    catch {.      
66d0: 73 65 74 20 6d 6f 64 65 73 28 24 63 68 61 6e 29  set modes($chan)
66e0: 20 5b 66 63 6f 6e 66 69 67 75 72 65 20 24 63 68   [fconfigure $ch
66f0: 61 6e 5d 0a 20 20 20 20 20 20 66 63 6f 6e 66 69  an].      fconfi
6700: 67 75 72 65 20 24 63 68 61 6e 20 2d 65 6e 63 6f  gure $chan -enco
6710: 64 69 6e 67 20 62 69 6e 61 72 79 20 2d 74 72 61  ding binary -tra
6720: 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 20  nslation binary 
6730: 2d 62 75 66 66 65 72 69 6e 67 20 6e 6f 6e 65 0a  -buffering none.
6740: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20      }.  }.  set 
6750: 72 63 20 5b 63 61 74 63 68 20 7b 20 65 76 61 6c  rc [catch { eval
6760: 20 24 6c 69 6e 65 20 7d 20 6d 73 67 5d 0a 20 20   $line } msg].  
6770: 66 6f 72 65 61 63 68 20 63 68 61 6e 20 24 63 68  foreach chan $ch
6780: 61 6e 73 20 7b 0a 20 20 20 20 63 61 74 63 68 20  ans {.    catch 
6790: 7b 0a 20 20 20 20 20 20 65 76 61 6c 20 66 63 6f  {.      eval fco
67a0: 6e 66 69 67 75 72 65 20 5b 6c 69 73 74 20 24 63  nfigure [list $c
67b0: 68 61 6e 5d 20 24 6d 6f 64 65 73 28 24 63 68 61  han] $modes($cha
67c0: 6e 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 23  n).    }.  }.  #
67d0: 20 70 75 74 73 20 5b 64 75 6d 70 62 79 74 65 73   puts [dumpbytes
67e0: 20 24 6d 73 67 5d 0a 20 20 6c 69 73 74 20 24 72   $msg].  list $r
67f0: 63 20 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20 66  c $msg.}..proc f
6800: 69 6c 65 70 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a  ilepath_normaliz
6810: 65 20 7b 70 7d 20 7b 0a 20 20 23 20 74 65 73 74  e {p} {.  # test
6820: 20 63 61 73 65 73 20 73 68 6f 75 6c 64 20 62 65   cases should be
6830: 20 77 72 69 74 74 65 6e 20 74 6f 20 61 73 73 75   written to assu
6840: 6d 65 20 22 75 6e 69 78 22 2d 6c 69 6b 65 20 66  me "unix"-like f
6850: 69 6c 65 20 70 61 74 68 73 0a 20 20 69 66 20 7b  ile paths.  if {
6860: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
6870: 70 6c 61 74 66 6f 72 6d 29 21 3d 22 75 6e 69 78  platform)!="unix
6880: 22 7d 20 7b 0a 20 20 20 20 23 20 6c 72 65 76 65  "} {.    # lreve
6890: 72 73 65 2a 32 20 61 73 20 61 20 68 61 63 6b 20  rse*2 as a hack 
68a0: 74 6f 20 72 65 6d 6f 76 65 20 61 6e 79 20 75 6e  to remove any un
68b0: 6e 65 65 64 65 64 20 7b 7d 20 61 66 74 65 72 20  needed {} after 
68c0: 74 68 65 20 73 74 72 69 6e 67 20 6d 61 70 0a 20  the string map. 
68d0: 20 20 20 6c 72 65 76 65 72 73 65 20 5b 6c 72 65     lreverse [lre
68e0: 76 65 72 73 65 20 5b 73 74 72 69 6e 67 20 6d 61  verse [string ma
68f0: 70 20 7b 5c 5c 20 2f 7d 20 5b 72 65 67 73 75 62  p {\\ /} [regsub
6900: 20 2d 6e 6f 63 61 73 65 20 2d 61 6c 6c 20 7b 5b   -nocase -all {[
6910: 61 2d 7a 5d 3a 5b 2f 5c 5c 5d 2b 7d 20 24 70 20  a-z]:[/\\]+} $p 
6920: 7b 2f 7d 5d 5d 5d 0a 20 20 7d 20 7b 0a 20 20 20  {/}]]].  } {.   
6930: 20 73 65 74 20 70 0a 20 20 7d 0a 7d 0a 70 72 6f   set p.  }.}.pro
6940: 63 20 64 6f 5f 66 69 6c 65 70 61 74 68 5f 74 65  c do_filepath_te
6950: 73 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70  st {name cmd exp
6960: 65 63 74 65 64 7d 20 7b 0a 20 20 75 70 6c 65 76  ected} {.  uplev
6970: 65 6c 20 5b 6c 69 73 74 20 64 6f 5f 74 65 73 74  el [list do_test
6980: 20 24 6e 61 6d 65 20 5b 0a 20 20 20 20 73 75 62   $name [.    sub
6990: 73 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b  st -nocommands {
69a0: 20 66 69 6c 65 70 61 74 68 5f 6e 6f 72 6d 61 6c   filepath_normal
69b0: 69 7a 65 20 5b 20 24 63 6d 64 20 5d 20 7d 0a 20  ize [ $cmd ] }. 
69c0: 20 5d 20 5b 66 69 6c 65 70 61 74 68 5f 6e 6f 72   ] [filepath_nor
69d0: 6d 61 6c 69 7a 65 20 24 65 78 70 65 63 74 65 64  malize $expected
69e0: 5d 5d 0a 7d 0a 0a 70 72 6f 63 20 72 65 61 6c 6e  ]].}..proc realn
69f0: 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20 7b 72 7d  um_normalize {r}
6a00: 20 7b 0a 20 20 23 20 64 69 66 66 65 72 65 6e 74   {.  # different
6a10: 20 54 43 4c 20 76 65 72 73 69 6f 6e 73 20 64 69   TCL versions di
6a20: 73 70 6c 61 79 20 66 6c 6f 61 74 69 6e 67 20 70  splay floating p
6a30: 6f 69 6e 74 20 76 61 6c 75 65 73 20 64 69 66 66  oint values diff
6a40: 65 72 65 6e 74 6c 79 2e 0a 20 20 73 74 72 69 6e  erently..  strin
6a50: 67 20 6d 61 70 20 7b 31 2e 23 49 4e 46 20 69 6e  g map {1.#INF in
6a60: 66 20 49 6e 66 20 69 6e 66 20 2e 30 65 20 65 7d  f Inf inf .0e e}
6a70: 20 5b 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 28   [regsub -all {(
6a80: 65 5b 2b 2d 5d 29 30 2b 7d 20 24 72 20 7b 5c 31  e[+-])0+} $r {\1
6a90: 7d 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 72 65 61  }].}.proc do_rea
6aa0: 6c 6e 75 6d 5f 74 65 73 74 20 7b 6e 61 6d 65 20  lnum_test {name 
6ab0: 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b 0a  cmd expected} {.
6ac0: 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20    uplevel [list 
6ad0: 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 0a  do_test $name [.
6ae0: 20 20 20 20 73 75 62 73 74 20 2d 6e 6f 63 6f 6d      subst -nocom
6af0: 6d 61 6e 64 73 20 7b 20 72 65 61 6c 6e 75 6d 5f  mands { realnum_
6b00: 6e 6f 72 6d 61 6c 69 7a 65 20 5b 20 24 63 6d 64  normalize [ $cmd
6b10: 20 5d 20 7d 0a 20 20 5d 20 5b 72 65 61 6c 6e 75   ] }.  ] [realnu
6b20: 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20 24 65 78 70  m_normalize $exp
6b30: 65 63 74 65 64 5d 5d 0a 7d 0a 0a 70 72 6f 63 20  ected]].}..proc 
6b40: 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 7b 76 61  fix_testname {va
6b50: 72 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61 72  rname} {.  upvar
6b60: 20 24 76 61 72 6e 61 6d 65 20 74 65 73 74 6e 61   $varname testna
6b70: 6d 65 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65  me.  if {[info e
6b80: 78 69 73 74 73 20 3a 3a 74 65 73 74 70 72 65 66  xists ::testpref
6b90: 69 78 5d 0a 20 20 20 26 26 20 5b 73 74 72 69 6e  ix].   && [strin
6ba0: 67 20 69 73 20 64 69 67 69 74 20 5b 73 74 72 69  g is digit [stri
6bb0: 6e 67 20 72 61 6e 67 65 20 24 74 65 73 74 6e 61  ng range $testna
6bc0: 6d 65 20 30 20 30 5d 5d 0a 20 20 7d 20 7b 0a 20  me 0 0]].  } {. 
6bd0: 20 20 20 73 65 74 20 74 65 73 74 6e 61 6d 65 20     set testname 
6be0: 22 24 7b 3a 3a 74 65 73 74 70 72 65 66 69 78 7d  "${::testprefix}
6bf0: 2d 24 74 65 73 74 6e 61 6d 65 22 0a 20 20 7d 0a  -$testname".  }.
6c00: 7d 0a 0a 70 72 6f 63 20 6e 6f 72 6d 61 6c 69 7a  }..proc normaliz
6c10: 65 5f 6c 69 73 74 20 7b 4c 7d 20 7b 0a 20 20 73  e_list {L} {.  s
6c20: 65 74 20 4c 32 20 5b 6c 69 73 74 5d 0a 20 20 66  et L2 [list].  f
6c30: 6f 72 65 61 63 68 20 6c 20 24 4c 20 7b 6c 61 70  oreach l $L {lap
6c40: 70 65 6e 64 20 4c 32 20 24 6c 7d 0a 20 20 73 65  pend L2 $l}.  se
6c50: 74 20 4c 32 0a 7d 0a 0a 23 20 45 69 74 68 65 72  t L2.}..# Either
6c60: 3a 0a 23 0a 23 20 20 20 64 6f 5f 65 78 65 63 73  :.#.#   do_execs
6c70: 71 6c 5f 74 65 73 74 20 54 45 53 54 4e 41 4d 45  ql_test TESTNAME
6c80: 20 53 51 4c 20 3f 52 45 53 3f 0a 23 20 20 20 64   SQL ?RES?.#   d
6c90: 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 2d  o_execsql_test -
6ca0: 64 62 20 44 42 20 54 45 53 54 4e 41 4d 45 20 53  db DB TESTNAME S
6cb0: 51 4c 20 3f 52 45 53 3f 0a 23 0a 70 72 6f 63 20  QL ?RES?.#.proc 
6cc0: 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20  do_execsql_test 
6cd0: 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 64  {args} {.  set d
6ce0: 62 20 64 62 0a 20 20 69 66 20 7b 5b 6c 69 6e 64  b db.  if {[lind
6cf0: 65 78 20 24 61 72 67 73 20 30 5d 3d 3d 22 2d 64  ex $args 0]=="-d
6d00: 62 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 64 62  b"} {.    set db
6d10: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 31   [lindex $args 1
6d20: 5d 0a 20 20 20 20 73 65 74 20 61 72 67 73 20 5b  ].    set args [
6d30: 6c 72 61 6e 67 65 20 24 61 72 67 73 20 32 20 65  lrange $args 2 e
6d40: 6e 64 5d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 5b  nd].  }..  if {[
6d50: 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 3d 3d  llength $args]==
6d60: 32 7d 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68  2} {.    foreach
6d70: 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 7d 20   {testname sql} 
6d80: 24 61 72 67 73 20 7b 7d 0a 20 20 20 20 73 65 74  $args {}.    set
6d90: 20 72 65 73 75 6c 74 20 22 22 0a 20 20 7d 20 65   result "".  } e
6da0: 6c 73 65 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20  lseif {[llength 
6db0: 24 61 72 67 73 5d 3d 3d 33 7d 20 7b 0a 20 20 20  $args]==3} {.   
6dc0: 20 66 6f 72 65 61 63 68 20 7b 74 65 73 74 6e 61   foreach {testna
6dd0: 6d 65 20 73 71 6c 20 72 65 73 75 6c 74 7d 20 24  me sql result} $
6de0: 61 72 67 73 20 7b 7d 0a 0a 20 20 20 20 23 20 57  args {}..    # W
6df0: 69 74 68 20 73 6f 6d 65 20 76 65 72 73 69 6f 6e  ith some version
6e00: 73 20 6f 66 20 54 63 6c 20 6f 6e 20 77 69 6e 64  s of Tcl on wind
6e10: 6f 77 73 2c 20 69 66 20 24 72 65 73 75 6c 74 20  ows, if $result 
6e20: 69 73 20 61 6c 6c 20 77 68 69 74 65 73 70 61 63  is all whitespac
6e30: 65 20 62 75 74 0a 20 20 20 20 23 20 63 6f 6e 74  e but.    # cont
6e40: 61 69 6e 73 20 73 6f 6d 65 20 43 52 2f 4c 46 20  ains some CR/LF 
6e50: 63 68 61 72 61 63 74 65 72 73 2c 20 74 68 65 20  characters, the 
6e60: 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 75 6c 74  [list {*}$result
6e70: 5d 20 62 65 6c 6f 77 20 72 65 74 75 72 6e 73 20  ] below returns 
6e80: 61 0a 20 20 20 20 23 20 63 6f 70 79 20 6f 66 20  a.    # copy of 
6e90: 24 72 65 73 75 6c 74 20 69 6e 73 74 65 61 64 20  $result instead 
6ea0: 6f 66 20 61 20 7a 65 72 6f 20 6c 65 6e 67 74 68  of a zero length
6eb0: 20 73 74 72 69 6e 67 2e 20 4e 6f 74 20 63 6c 65   string. Not cle
6ec0: 61 72 20 65 78 61 63 74 6c 79 20 77 68 79 0a 20  ar exactly why. 
6ed0: 20 20 20 23 20 74 68 69 73 20 69 73 2e 20 54 68     # this is. Th
6ee0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 61  e following is a
6ef0: 20 77 6f 72 6b 61 72 6f 75 6e 64 2e 0a 20 20 20   workaround..   
6f00: 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 72   if {[llength $r
6f10: 65 73 75 6c 74 5d 3d 3d 30 7d 20 7b 20 73 65 74  esult]==0} { set
6f20: 20 72 65 73 75 6c 74 20 22 22 20 7d 0a 20 20 7d   result "" }.  }
6f30: 20 65 6c 73 65 20 7b 0a 20 20 20 20 65 72 72 6f   else {.    erro
6f40: 72 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 7b  r [string trim {
6f50: 0a 20 20 20 20 20 20 77 72 6f 6e 67 20 23 20 61  .      wrong # a
6f60: 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 22  rgs: should be "
6f70: 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20  do_execsql_test 
6f80: 3f 2d 64 62 20 44 42 3f 20 74 65 73 74 6e 61 6d  ?-db DB? testnam
6f90: 65 20 73 71 6c 20 3f 72 65 73 75 6c 74 3f 22 0a  e sql ?result?".
6fa0: 20 20 20 20 7d 5d 0a 20 20 7d 0a 0a 20 20 66 69      }].  }..  fi
6fb0: 78 5f 74 65 73 74 6e 61 6d 65 20 74 65 73 74 6e  x_testname testn
6fc0: 61 6d 65 0a 0a 20 20 75 70 6c 65 76 65 6c 20 64  ame..  uplevel d
6fd0: 6f 5f 74 65 73 74 20 20 20 20 20 20 20 20 20 20  o_test          
6fe0: 20 20 20 20 20 20 20 5c 0a 20 20 20 20 20 20 5b         \.      [
6ff0: 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d 20  list $testname] 
7000: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
7010: 20 20 20 5b 6c 69 73 74 20 22 65 78 65 63 73 71     [list "execsq
7020: 6c 20 7b 24 73 71 6c 7d 20 24 64 62 22 5d 20 5c  l {$sql} $db"] \
7030: 0a 20 20 20 20 20 20 5b 6c 69 73 74 20 5b 6c 69  .      [list [li
7040: 73 74 20 7b 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a  st {*}$result]].
7050: 7d 0a 0a 70 72 6f 63 20 64 6f 5f 63 61 74 63 68  }..proc do_catch
7060: 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61  sql_test {testna
7070: 6d 65 20 73 71 6c 20 72 65 73 75 6c 74 7d 20 7b  me sql result} {
7080: 0a 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20  .  fix_testname 
7090: 74 65 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76  testname.  uplev
70a0: 65 6c 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74  el do_test [list
70b0: 20 24 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73   $testname] [lis
70c0: 74 20 22 63 61 74 63 68 73 71 6c 20 7b 24 73 71  t "catchsql {$sq
70d0: 6c 7d 22 5d 20 5b 6c 69 73 74 20 24 72 65 73 75  l}"] [list $resu
70e0: 6c 74 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 74 69  lt].}.proc do_ti
70f0: 6d 65 64 5f 65 78 65 63 73 71 6c 5f 74 65 73 74  med_execsql_test
7100: 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 7b   {testname sql {
7110: 72 65 73 75 6c 74 20 7b 7d 7d 7d 20 7b 0a 20 20  result {}}} {.  
7120: 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 74 65 73  fix_testname tes
7130: 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76 65 6c 20  tname.  uplevel 
7140: 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74 20 24 74  do_test [list $t
7150: 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73 74 20 22  estname] [list "
7160: 65 78 65 63 73 71 6c 5f 74 69 6d 65 64 20 7b 24  execsql_timed {$
7170: 73 71 6c 7d 22 5d 5c 0a 20 20 20 20 20 20 20 20  sql}"]\.        
7180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7190: 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 73 74             [list
71a0: 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 75 6c   [list {*}$resul
71b0: 74 5d 5d 0a 7d 0a 0a 23 20 52 75 6e 20 61 6e 20  t]].}..# Run an 
71c0: 45 58 50 4c 41 49 4e 20 51 55 45 52 59 20 50 4c  EXPLAIN QUERY PL
71d0: 41 4e 20 24 73 71 6c 20 69 6e 20 64 61 74 61 62  AN $sql in datab
71e0: 61 73 65 20 22 64 62 22 2e 20 20 54 68 65 6e 20  ase "db".  Then 
71f0: 72 65 77 72 69 74 65 20 74 68 65 20 6f 75 74 70  rewrite the outp
7200: 75 74 0a 23 20 61 73 20 61 6e 20 41 53 43 49 49  ut.# as an ASCII
7210: 2d 61 72 74 20 67 72 61 70 68 20 61 6e 64 20 72  -art graph and r
7220: 65 74 75 72 6e 20 61 20 73 74 72 69 6e 67 20 74  eturn a string t
7230: 68 61 74 20 69 73 20 74 68 61 74 20 67 72 61 70  hat is that grap
7240: 68 2e 0a 23 0a 23 20 48 65 78 61 64 65 63 69 6d  h..#.# Hexadecim
7250: 61 6c 20 6c 69 74 65 72 61 6c 73 20 69 6e 20 74  al literals in t
7260: 68 65 20 6f 75 74 70 75 74 20 74 65 78 74 20 61  he output text a
7270: 72 65 20 63 6f 6e 76 65 72 74 65 64 20 69 6e 74  re converted int
7280: 6f 20 22 78 78 78 78 78 78 22 20 73 69 6e 63 65  o "xxxxxx" since
7290: 20 74 68 6f 73 65 0a 23 20 6c 69 74 65 72 61 6c   those.# literal
72a0: 73 20 61 72 65 20 70 6f 69 6e 74 65 72 20 76 61  s are pointer va
72b0: 6c 75 65 73 20 74 68 61 74 20 6d 69 67 68 74 20  lues that might 
72c0: 76 65 72 79 20 66 72 6f 6d 20 6f 6e 65 20 72 75  very from one ru
72d0: 6e 20 6f 66 20 74 68 65 20 74 65 73 74 20 74 6f  n of the test to
72e0: 20 74 68 65 0a 23 20 6e 65 78 74 2c 20 79 65 74   the.# next, yet
72f0: 20 77 65 20 77 61 6e 74 20 74 68 65 20 6f 75 74   we want the out
7300: 70 75 74 20 74 6f 20 62 65 20 63 6f 6e 73 69 73  put to be consis
7310: 74 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 71 75 65  tent..#.proc que
7320: 72 79 5f 70 6c 61 6e 5f 67 72 61 70 68 20 7b 73  ry_plan_graph {s
7330: 71 6c 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20  ql} {.  db eval 
7340: 22 45 58 50 4c 41 49 4e 20 51 55 45 52 59 20 50  "EXPLAIN QUERY P
7350: 4c 41 4e 20 24 73 71 6c 22 20 7b 0a 20 20 20 20  LAN $sql" {.    
7360: 73 65 74 20 64 78 28 24 69 64 29 20 24 64 65 74  set dx($id) $det
7370: 61 69 6c 0a 20 20 20 20 6c 61 70 70 65 6e 64 20  ail.    lappend 
7380: 63 78 28 24 70 61 72 65 6e 74 29 20 24 69 64 0a  cx($parent) $id.
7390: 20 20 7d 0a 20 20 73 65 74 20 61 20 22 5c 6e 20    }.  set a "\n 
73a0: 20 51 55 45 52 59 20 50 4c 41 4e 5c 6e 22 0a 20   QUERY PLAN\n". 
73b0: 20 61 70 70 65 6e 64 20 61 20 5b 61 70 70 65 6e   append a [appen
73c0: 64 5f 67 72 61 70 68 20 22 20 20 22 20 64 78 20  d_graph "  " dx 
73d0: 63 78 20 30 5d 0a 20 20 72 65 67 73 75 62 20 2d  cx 0].  regsub -
73e0: 61 6c 6c 20 7b 20 30 78 5b 41 2d 46 30 2d 39 5d  all { 0x[A-F0-9]
73f0: 2b 5c 79 7d 20 24 61 20 7b 20 78 78 78 78 78 78  +\y} $a { xxxxxx
7400: 7d 20 61 0a 20 20 72 65 67 73 75 62 20 2d 61 6c  } a.  regsub -al
7410: 6c 20 7b 28 4d 41 54 45 52 49 41 4c 49 5a 45 7c  l {(MATERIALIZE|
7420: 43 4f 2d 52 4f 55 54 49 4e 45 7c 53 55 42 51 55  CO-ROUTINE|SUBQU
7430: 45 52 59 29 20 5c 64 2b 5c 79 7d 20 24 61 20 7b  ERY) \d+\y} $a {
7440: 5c 31 20 78 78 78 78 78 78 7d 20 61 0a 20 20 72  \1 xxxxxx} a.  r
7450: 65 74 75 72 6e 20 24 61 0a 7d 0a 0a 23 20 48 65  eturn $a.}..# He
7460: 6c 70 65 72 20 72 6f 75 74 69 6e 65 20 66 6f 72  lper routine for
7470: 20 5b 71 75 65 72 79 5f 70 6c 61 6e 5f 67 72 61   [query_plan_gra
7480: 70 68 20 53 51 4c 5d 3a 0a 23 0a 23 20 4f 75 74  ph SQL]:.#.# Out
7490: 70 75 74 20 72 6f 77 73 20 6f 66 20 74 68 65 20  put rows of the 
74a0: 67 72 61 70 68 20 74 68 61 74 20 61 72 65 20 63  graph that are c
74b0: 68 69 6c 64 72 65 6e 20 6f 66 20 24 6c 65 76 65  hildren of $leve
74c0: 6c 2e 0a 23 0a 23 20 20 20 70 72 65 66 69 78 3a  l..#.#   prefix:
74d0: 20 20 50 72 65 70 65 6e 64 20 74 6f 20 65 76 65    Prepend to eve
74e0: 72 79 20 6f 75 74 70 75 74 20 6c 69 6e 65 0a 23  ry output line.#
74f0: 0a 23 20 20 20 64 78 6e 61 6d 65 3a 20 20 4e 61  .#   dxname:  Na
7500: 6d 65 20 6f 66 20 61 6e 20 61 72 72 61 79 20 76  me of an array v
7510: 61 72 69 61 62 6c 65 20 74 68 61 74 20 73 74 6f  ariable that sto
7520: 72 65 73 20 74 65 78 74 20 64 65 73 63 72 69 62  res text describ
7530: 65 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 54  e.#            T
7540: 68 65 20 64 65 73 63 72 69 70 74 69 6f 6e 20 66  he description f
7550: 6f 72 20 24 69 64 20 69 73 20 24 64 78 28 24 69  or $id is $dx($i
7560: 64 29 0a 23 0a 23 20 20 20 63 78 6e 61 6d 65 3a  d).#.#   cxname:
7570: 20 20 4e 61 6d 65 20 6f 66 20 61 6e 20 61 72 72    Name of an arr
7580: 61 79 20 76 61 72 69 61 62 6c 65 20 68 6f 6c 64  ay variable hold
7590: 69 6e 67 20 63 68 69 6c 64 72 65 6e 20 6f 66 20  ing children of 
75a0: 69 74 65 6d 2e 0a 23 20 20 20 20 20 20 20 20 20  item..#         
75b0: 20 20 20 43 68 69 6c 64 72 65 6e 20 6f 66 20 24     Children of $
75c0: 69 64 20 61 72 65 20 24 63 78 28 24 69 64 29 0a  id are $cx($id).
75d0: 23 0a 23 20 20 20 6c 65 76 65 6c 3a 20 20 20 52  #.#   level:   R
75e0: 65 6e 64 65 72 20 61 6c 6c 20 6c 69 6e 65 73 20  ender all lines 
75f0: 74 68 61 74 20 61 72 65 20 63 68 69 6c 64 72 65  that are childre
7600: 6e 20 6f 66 20 24 6c 65 76 65 6c 0a 23 20 0a 70  n of $level.# .p
7610: 72 6f 63 20 61 70 70 65 6e 64 5f 67 72 61 70 68  roc append_graph
7620: 20 7b 70 72 65 66 69 78 20 64 78 6e 61 6d 65 20   {prefix dxname 
7630: 63 78 6e 61 6d 65 20 6c 65 76 65 6c 7d 20 7b 0a  cxname level} {.
7640: 20 20 75 70 76 61 72 20 24 64 78 6e 61 6d 65 20    upvar $dxname 
7650: 64 78 20 24 63 78 6e 61 6d 65 20 63 78 0a 20 20  dx $cxname cx.  
7660: 73 65 74 20 61 20 22 22 0a 20 20 73 65 74 20 78  set a "".  set x
7670: 20 24 63 78 28 24 6c 65 76 65 6c 29 0a 20 20 73   $cx($level).  s
7680: 65 74 20 6e 20 5b 6c 6c 65 6e 67 74 68 20 24 78  et n [llength $x
7690: 5d 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30  ].  for {set i 0
76a0: 7d 20 7b 24 69 3c 24 6e 7d 20 7b 69 6e 63 72 20  } {$i<$n} {incr 
76b0: 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 69 64 20  i} {.    set id 
76c0: 5b 6c 69 6e 64 65 78 20 24 78 20 24 69 5d 0a 20  [lindex $x $i]. 
76d0: 20 20 20 69 66 20 7b 24 69 3d 3d 24 6e 2d 31 7d     if {$i==$n-1}
76e0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 70 31 20   {.      set p1 
76f0: 22 60 2d 2d 22 0a 20 20 20 20 20 20 73 65 74 20  "`--".      set 
7700: 70 32 20 22 20 20 20 22 0a 20 20 20 20 7d 20 65  p2 "   ".    } e
7710: 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20  lse {.      set 
7720: 70 31 20 22 7c 2d 2d 22 0a 20 20 20 20 20 20 73  p1 "|--".      s
7730: 65 74 20 70 32 20 22 7c 20 20 22 0a 20 20 20 20  et p2 "|  ".    
7740: 7d 0a 20 20 20 20 61 70 70 65 6e 64 20 61 20 24  }.    append a $
7750: 70 72 65 66 69 78 24 70 31 24 64 78 28 24 69 64  prefix$p1$dx($id
7760: 29 5c 6e 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66  )\n.    if {[inf
7770: 6f 20 65 78 69 73 74 73 20 63 78 28 24 69 64 29  o exists cx($id)
7780: 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70 70 65 6e  ]} {.      appen
7790: 64 20 61 20 5b 61 70 70 65 6e 64 5f 67 72 61 70  d a [append_grap
77a0: 68 20 22 24 70 72 65 66 69 78 24 70 32 22 20 64  h "$prefix$p2" d
77b0: 78 20 63 78 20 24 69 64 5d 0a 20 20 20 20 7d 0a  x cx $id].    }.
77c0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 61 0a    }.  return $a.
77d0: 7d 0a 0a 23 20 44 6f 20 61 6e 20 45 58 50 4c 41  }..# Do an EXPLA
77e0: 49 4e 20 51 55 45 52 59 20 50 4c 41 4e 20 74 65  IN QUERY PLAN te
77f0: 73 74 20 6f 6e 20 69 6e 70 75 74 20 24 73 71 6c  st on input $sql
7800: 20 77 69 74 68 20 65 78 70 65 63 74 65 64 20 72   with expected r
7810: 65 73 75 6c 74 73 20 24 72 65 73 0a 23 0a 23 20  esults $res.#.# 
7820: 49 66 20 24 72 65 73 20 62 65 67 69 6e 73 20 77  If $res begins w
7830: 69 74 68 20 61 20 22 5c 73 2b 51 55 45 52 59 20  ith a "\s+QUERY 
7840: 50 4c 41 4e 5c 6e 22 20 74 68 65 6e 20 69 74 20  PLAN\n" then it 
7850: 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65  is assumed to be
7860: 20 74 68 65 20 0a 23 20 63 6f 6d 70 6c 65 74 65   the .# complete
7870: 20 67 72 61 70 68 20 77 68 69 63 68 20 6d 75 73   graph which mus
7880: 74 20 6d 61 74 63 68 20 74 68 65 20 6f 75 74 70  t match the outp
7890: 75 74 20 6f 66 20 5b 71 75 65 72 79 5f 70 6c 61  ut of [query_pla
78a0: 6e 5f 67 72 61 70 68 20 24 73 71 6c 5d 0a 23 20  n_graph $sql].# 
78b0: 65 78 61 63 74 6c 79 2e 0a 23 0a 23 20 49 66 20  exactly..#.# If 
78c0: 24 72 65 73 20 64 6f 65 73 20 6e 6f 74 20 62 65  $res does not be
78d0: 67 69 6e 20 77 69 74 68 20 22 5c 73 2b 51 55 45  gin with "\s+QUE
78e0: 52 59 20 50 4c 41 4e 5c 6e 22 20 74 68 65 6e 20  RY PLAN\n" then 
78f0: 74 61 6b 65 20 69 74 20 69 73 20 61 20 73 74 72  take it is a str
7900: 69 6e 67 0a 23 20 74 68 61 74 20 6d 75 73 74 20  ing.# that must 
7910: 62 65 20 66 6f 75 6e 64 20 73 6f 6d 65 77 68 65  be found somewhe
7920: 72 65 20 69 6e 20 74 68 65 20 71 75 65 72 79 20  re in the query 
7930: 70 6c 61 6e 20 6f 75 74 70 75 74 2e 0a 23 0a 70  plan output..#.p
7940: 72 6f 63 20 64 6f 5f 65 71 70 5f 74 65 73 74 20  roc do_eqp_test 
7950: 7b 6e 61 6d 65 20 73 71 6c 20 72 65 73 7d 20 7b  {name sql res} {
7960: 0a 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b  .  if {[regexp {
7970: 5e 5c 73 2b 51 55 45 52 59 20 50 4c 41 4e 5c 6e  ^\s+QUERY PLAN\n
7980: 7d 20 24 72 65 73 5d 7d 20 7b 0a 20 20 20 20 75  } $res]} {.    u
7990: 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 24  plevel do_test $
79a0: 6e 61 6d 65 20 5b 6c 69 73 74 20 5b 6c 69 73 74  name [list [list
79b0: 20 71 75 65 72 79 5f 70 6c 61 6e 5f 67 72 61 70   query_plan_grap
79c0: 68 20 24 73 71 6c 5d 5d 20 5b 6c 69 73 74 20 24  h $sql]] [list $
79d0: 72 65 73 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  res].  } else {.
79e0: 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20      if {[string 
79f0: 69 6e 64 65 78 20 24 72 65 73 20 30 5d 21 3d 22  index $res 0]!="
7a00: 2f 22 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  /"} {.      set 
7a10: 72 65 73 20 22 2f 2a 24 72 65 73 2a 2f 22 0a 20  res "/*$res*/". 
7a20: 20 20 20 7d 0a 20 20 20 20 75 70 6c 65 76 65 6c     }.    uplevel
7a30: 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74   do_execsql_test
7a40: 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20 22 45 58   $name [list "EX
7a50: 50 4c 41 49 4e 20 51 55 45 52 59 20 50 4c 41 4e  PLAIN QUERY PLAN
7a60: 20 24 73 71 6c 22 5d 20 5b 6c 69 73 74 20 24 72   $sql"] [list $r
7a70: 65 73 5d 0a 20 20 7d 0a 7d 0a 0a 0a 23 2d 2d 2d  es].  }.}...#---
7a80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7a90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7aa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7ab0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7ac0: 2d 2d 2d 2d 2d 2d 0a 23 20 20 20 55 73 61 67 65  ------.#   Usage
7ad0: 3a 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74  : do_select_test
7ae0: 73 20 50 52 45 46 49 58 20 3f 53 57 49 54 43 48  s PREFIX ?SWITCH
7af0: 45 53 3f 20 54 45 53 54 4c 49 53 54 0a 23 0a 23  ES? TESTLIST.#.#
7b00: 20 57 68 65 72 65 20 73 77 69 74 63 68 65 73 20   Where switches 
7b10: 61 72 65 3a 0a 23 0a 23 20 20 20 2d 65 72 72 6f  are:.#.#   -erro
7b20: 72 66 6f 72 6d 61 74 20 46 4d 54 53 54 52 49 4e  rformat FMTSTRIN
7b30: 47 0a 23 20 20 20 2d 63 6f 75 6e 74 0a 23 20 20  G.#   -count.#  
7b40: 20 2d 71 75 65 72 79 20 53 51 4c 0a 23 20 20 20   -query SQL.#   
7b50: 2d 74 63 6c 71 75 65 72 79 20 54 43 4c 0a 23 20  -tclquery TCL.# 
7b60: 20 20 2d 72 65 70 61 69 72 20 54 43 4c 0a 23 0a    -repair TCL.#.
7b70: 70 72 6f 63 20 64 6f 5f 73 65 6c 65 63 74 5f 74  proc do_select_t
7b80: 65 73 74 73 20 7b 70 72 65 66 69 78 20 61 72 67  ests {prefix arg
7b90: 73 7d 20 7b 0a 0a 20 20 73 65 74 20 74 65 73 74  s} {..  set test
7ba0: 6c 69 73 74 20 5b 6c 69 6e 64 65 78 20 24 61 72  list [lindex $ar
7bb0: 67 73 20 65 6e 64 5d 0a 20 20 73 65 74 20 73 77  gs end].  set sw
7bc0: 69 74 63 68 65 73 20 5b 6c 72 61 6e 67 65 20 24  itches [lrange $
7bd0: 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 0a 0a 20  args 0 end-1].. 
7be0: 20 73 65 74 20 65 72 72 66 6d 74 20 22 22 0a 20   set errfmt "". 
7bf0: 20 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79 20 30   set countonly 0
7c00: 0a 20 20 73 65 74 20 74 63 6c 71 75 65 72 79 20  .  set tclquery 
7c10: 22 22 0a 20 20 73 65 74 20 72 65 70 61 69 72 20  "".  set repair 
7c20: 22 22 0a 0a 20 20 66 6f 72 20 7b 73 65 74 20 69  ""..  for {set i
7c30: 20 30 7d 20 7b 24 69 20 3c 20 5b 6c 6c 65 6e 67   0} {$i < [lleng
7c40: 74 68 20 24 73 77 69 74 63 68 65 73 5d 7d 20 7b  th $switches]} {
7c50: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 73 65  incr i} {.    se
7c60: 74 20 73 20 5b 6c 69 6e 64 65 78 20 24 73 77 69  t s [lindex $swi
7c70: 74 63 68 65 73 20 24 69 5d 0a 20 20 20 20 73 65  tches $i].    se
7c80: 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  t n [string leng
7c90: 74 68 20 24 73 5d 0a 20 20 20 20 69 66 20 7b 24  th $s].    if {$
7ca0: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
7cb0: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
7cc0: 20 24 73 20 22 2d 71 75 65 72 79 22 5d 7d 20 7b   $s "-query"]} {
7cd0: 0a 20 20 20 20 20 20 73 65 74 20 74 63 6c 71 75  .      set tclqu
7ce0: 65 72 79 20 5b 6c 69 73 74 20 65 78 65 63 73 71  ery [list execsq
7cf0: 6c 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63  l [lindex $switc
7d00: 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 5d 0a 20  hes [incr i]]]. 
7d10: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e     } elseif {$n>
7d20: 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71  =2 && [string eq
7d30: 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24  ual -length $n $
7d40: 73 20 22 2d 74 63 6c 71 75 65 72 79 22 5d 7d 20  s "-tclquery"]} 
7d50: 7b 0a 20 20 20 20 20 20 73 65 74 20 74 63 6c 71  {.      set tclq
7d60: 75 65 72 79 20 5b 6c 69 6e 64 65 78 20 24 73 77  uery [lindex $sw
7d70: 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d  itches [incr i]]
7d80: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
7d90: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
7da0: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
7db0: 20 24 73 20 22 2d 65 72 72 6f 72 66 6f 72 6d 61   $s "-errorforma
7dc0: 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  t"]} {.      set
7dd0: 20 65 72 72 66 6d 74 20 5b 6c 69 6e 64 65 78 20   errfmt [lindex 
7de0: 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20  $switches [incr 
7df0: 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66  i]].    } elseif
7e00: 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69   {$n>=2 && [stri
7e10: 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68  ng equal -length
7e20: 20 24 6e 20 24 73 20 22 2d 72 65 70 61 69 72 22   $n $s "-repair"
7e30: 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 72  ]} {.      set r
7e40: 65 70 61 69 72 20 5b 6c 69 6e 64 65 78 20 24 73  epair [lindex $s
7e50: 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d  witches [incr i]
7e60: 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b  ].    } elseif {
7e70: 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67  $n>=2 && [string
7e80: 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24   equal -length $
7e90: 6e 20 24 73 20 22 2d 63 6f 75 6e 74 22 5d 7d 20  n $s "-count"]} 
7ea0: 7b 0a 20 20 20 20 20 20 73 65 74 20 63 6f 75 6e  {.      set coun
7eb0: 74 6f 6e 6c 79 20 31 0a 20 20 20 20 7d 20 65 6c  tonly 1.    } el
7ec0: 73 65 20 7b 0a 20 20 20 20 20 20 65 72 72 6f 72  se {.      error
7ed0: 20 22 75 6e 6b 6e 6f 77 6e 20 73 77 69 74 63 68   "unknown switch
7ee0: 3a 20 24 73 22 0a 20 20 20 20 7d 0a 20 20 7d 0a  : $s".    }.  }.
7ef0: 0a 20 20 69 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c  .  if {$countonl
7f00: 79 20 26 26 20 24 65 72 72 66 6d 74 21 3d 22 22  y && $errfmt!=""
7f10: 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 43  } {.    error "C
7f20: 61 6e 6e 6f 74 20 75 73 65 20 2d 63 6f 75 6e 74  annot use -count
7f30: 20 61 6e 64 20 2d 65 72 72 6f 72 66 6f 72 6d 61   and -errorforma
7f40: 74 20 74 6f 67 65 74 68 65 72 22 0a 20 20 7d 0a  t together".  }.
7f50: 20 20 73 65 74 20 6e 54 65 73 74 6c 69 73 74 20    set nTestlist 
7f60: 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73 74 6c 69  [llength $testli
7f70: 73 74 5d 0a 20 20 69 66 20 7b 24 6e 54 65 73 74  st].  if {$nTest
7f80: 6c 69 73 74 25 33 20 7c 7c 20 24 6e 54 65 73 74  list%3 || $nTest
7f90: 6c 69 73 74 3d 3d 30 20 7d 20 7b 0a 20 20 20 20  list==0 } {.    
7fa0: 65 72 72 6f 72 20 22 53 45 4c 45 43 54 20 74 65  error "SELECT te
7fb0: 73 74 20 6c 69 73 74 20 63 6f 6e 74 61 69 6e 73  st list contains
7fc0: 20 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73 74 6c   [llength $testl
7fd0: 69 73 74 5d 20 65 6c 65 6d 65 6e 74 73 22 0a 20  ist] elements". 
7fe0: 20 7d 0a 0a 20 20 65 76 61 6c 20 24 72 65 70 61   }..  eval $repa
7ff0: 69 72 0a 20 20 66 6f 72 65 61 63 68 20 7b 74 6e  ir.  foreach {tn
8000: 20 73 71 6c 20 72 65 73 7d 20 24 74 65 73 74 6c   sql res} $testl
8010: 69 73 74 20 7b 0a 20 20 20 20 69 66 20 7b 24 74  ist {.    if {$t
8020: 63 6c 71 75 65 72 79 20 21 3d 20 22 22 7d 20 7b  clquery != ""} {
8030: 0a 20 20 20 20 20 20 65 78 65 63 73 71 6c 20 24  .      execsql $
8040: 73 71 6c 0a 20 20 20 20 20 20 75 70 6c 65 76 65  sql.      upleve
8050: 6c 20 64 6f 5f 74 65 73 74 20 24 7b 70 72 65 66  l do_test ${pref
8060: 69 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20 24 74  ix}.$tn [list $t
8070: 63 6c 71 75 65 72 79 5d 20 5b 6c 69 73 74 20 5b  clquery] [list [
8080: 6c 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20  list {*}$res]]. 
8090: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 63 6f     } elseif {$co
80a0: 75 6e 74 6f 6e 6c 79 7d 20 7b 0a 20 20 20 20 20  untonly} {.     
80b0: 20 73 65 74 20 6e 52 6f 77 20 30 0a 20 20 20 20   set nRow 0.    
80c0: 20 20 64 62 20 65 76 61 6c 20 24 73 71 6c 20 7b    db eval $sql {
80d0: 69 6e 63 72 20 6e 52 6f 77 7d 0a 20 20 20 20 20  incr nRow}.     
80e0: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74   uplevel do_test
80f0: 20 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e 20 5b   ${prefix}.$tn [
8100: 6c 69 73 74 20 5b 6c 69 73 74 20 73 65 74 20 7b  list [list set {
8110: 7d 20 24 6e 52 6f 77 5d 5d 20 5b 6c 69 73 74 20  } $nRow]] [list 
8120: 24 72 65 73 5d 0a 20 20 20 20 7d 20 65 6c 73 65  $res].    } else
8130: 69 66 20 7b 24 65 72 72 66 6d 74 3d 3d 22 22 7d  if {$errfmt==""}
8140: 20 7b 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c   {.      uplevel
8150: 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74   do_execsql_test
8160: 20 24 7b 70 72 65 66 69 78 7d 2e 24 7b 74 6e 7d   ${prefix}.${tn}
8170: 20 5b 6c 69 73 74 20 24 73 71 6c 5d 20 5b 6c 69   [list $sql] [li
8180: 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73  st [list {*}$res
8190: 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  ]].    } else {.
81a0: 20 20 20 20 20 20 73 65 74 20 72 65 73 20 5b 6c        set res [l
81b0: 69 73 74 20 31 20 5b 73 74 72 69 6e 67 20 74 72  ist 1 [string tr
81c0: 69 6d 20 5b 66 6f 72 6d 61 74 20 24 65 72 72 66  im [format $errf
81d0: 6d 74 20 7b 2a 7d 24 72 65 73 5d 5d 5d 0a 20 20  mt {*}$res]]].  
81e0: 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 63      uplevel do_c
81f0: 61 74 63 68 73 71 6c 5f 74 65 73 74 20 24 7b 70  atchsql_test ${p
8200: 72 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69  refix}.${tn} [li
8210: 73 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74 20 24  st $sql] [list $
8220: 72 65 73 5d 0a 20 20 20 20 7d 0a 20 20 20 20 65  res].    }.    e
8230: 76 61 6c 20 24 72 65 70 61 69 72 0a 20 20 7d 0a  val $repair.  }.
8240: 0a 7d 0a 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f  .}..proc delete_
8250: 61 6c 6c 5f 64 61 74 61 20 7b 7d 20 7b 0a 20 20  all_data {} {.  
8260: 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  db eval {SELECT 
8270: 74 62 6c 5f 6e 61 6d 65 20 41 53 20 74 20 46 52  tbl_name AS t FR
8280: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
8290: 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74   WHERE type = 't
82a0: 61 62 6c 65 27 7d 20 7b 0a 20 20 20 20 64 62 20  able'} {.    db 
82b0: 65 76 61 6c 20 22 44 45 4c 45 54 45 20 46 52 4f  eval "DELETE FRO
82c0: 4d 20 27 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b  M '[string map {
82d0: 27 20 27 27 7d 20 24 74 5d 27 22 0a 20 20 7d 0a  ' ''} $t]'".  }.
82e0: 7d 0a 0a 23 20 52 75 6e 20 61 6e 20 53 51 4c 20  }..# Run an SQL 
82f0: 73 63 72 69 70 74 2e 0a 23 20 52 65 74 75 72 6e  script..# Return
8300: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d   the number of m
8310: 69 63 72 6f 73 65 63 6f 6e 64 73 20 70 65 72 20  icroseconds per 
8320: 73 74 61 74 65 6d 65 6e 74 2e 0a 23 0a 70 72 6f  statement..#.pro
8330: 63 20 73 70 65 65 64 5f 74 72 69 61 6c 20 7b 6e  c speed_trial {n
8340: 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e 69 74  ame numstmt unit
8350: 73 20 73 71 6c 7d 20 7b 0a 20 20 6f 75 74 70 75  s sql} {.  outpu
8360: 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66  t2 -nonewline [f
8370: 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20  ormat {%-21.21s 
8380: 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c  } $name...].  fl
8390: 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74  ush stdout.  set
83a0: 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 73 71   speed [time {sq
83b0: 6c 69 74 65 33 5f 65 78 65 63 5f 6e 72 20 64 62  lite3_exec_nr db
83c0: 20 24 73 71 6c 7d 5d 0a 20 20 73 65 74 20 74 6d   $sql}].  set tm
83d0: 20 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64 20   [lindex $speed 
83e0: 30 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d 3d 20  0].  if {$tm == 
83f0: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74  0} {.    set rat
8400: 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 73 20 22  e [format %20s "
8410: 6d 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73 65 20  many"].  } else 
8420: 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b  {.    set rate [
8430: 66 6f 72 6d 61 74 20 25 32 30 2e 35 66 20 5b 65  format %20.5f [e
8440: 78 70 72 20 7b 31 30 30 30 30 30 30 2e 30 2a 24  xpr {1000000.0*$
8450: 6e 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20  numstmt/$tm}]]. 
8460: 20 7d 0a 20 20 73 65 74 20 75 32 20 24 75 6e 69   }.  set u2 $uni
8470: 74 73 2f 73 0a 20 20 6f 75 74 70 75 74 32 20 5b  ts/s.  output2 [
8480: 66 6f 72 6d 61 74 20 7b 25 31 32 64 20 75 53 20  format {%12d uS 
8490: 25 73 20 25 73 7d 20 24 74 6d 20 24 72 61 74 65  %s %s} $tm $rate
84a0: 20 24 75 32 5d 0a 20 20 67 6c 6f 62 61 6c 20 74   $u2].  global t
84b0: 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20  otal_time.  set 
84c0: 74 6f 74 61 6c 5f 74 69 6d 65 20 5b 65 78 70 72  total_time [expr
84d0: 20 7b 24 74 6f 74 61 6c 5f 74 69 6d 65 2b 24 74   {$total_time+$t
84e0: 6d 7d 5d 0a 20 20 6c 61 70 70 65 6e 64 20 3a 3a  m}].  lappend ::
84f0: 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65  speed_trial_time
8500: 73 20 24 6e 61 6d 65 20 24 74 6d 0a 7d 0a 70 72  s $name $tm.}.pr
8510: 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 74  oc speed_trial_t
8520: 63 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74  cl {name numstmt
8530: 20 75 6e 69 74 73 20 73 63 72 69 70 74 7d 20 7b   units script} {
8540: 0a 20 20 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65  .  output2 -none
8550: 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25  wline [format {%
8560: 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e  -21.21s } $name.
8570: 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73 74 64 6f  ..].  flush stdo
8580: 75 74 0a 20 20 73 65 74 20 73 70 65 65 64 20 5b  ut.  set speed [
8590: 74 69 6d 65 20 7b 65 76 61 6c 20 24 73 63 72 69  time {eval $scri
85a0: 70 74 7d 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c  pt}].  set tm [l
85b0: 69 6e 64 65 78 20 24 73 70 65 65 64 20 30 5d 0a  index $speed 0].
85c0: 20 20 69 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20    if {$tm == 0} 
85d0: 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b  {.    set rate [
85e0: 66 6f 72 6d 61 74 20 25 32 30 73 20 22 6d 61 6e  format %20s "man
85f0: 79 22 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  y"].  } else {. 
8600: 20 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72     set rate [for
8610: 6d 61 74 20 25 32 30 2e 35 66 20 5b 65 78 70 72  mat %20.5f [expr
8620: 20 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d   {1000000.0*$num
8630: 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a  stmt/$tm}]].  }.
8640: 20 20 73 65 74 20 75 32 20 24 75 6e 69 74 73 2f    set u2 $units/
8650: 73 0a 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72  s.  output2 [for
8660: 6d 61 74 20 7b 25 31 32 64 20 75 53 20 25 73 20  mat {%12d uS %s 
8670: 25 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24 75  %s} $tm $rate $u
8680: 32 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61  2].  global tota
8690: 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74  l_time.  set tot
86a0: 61 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b 24  al_time [expr {$
86b0: 74 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d  total_time+$tm}]
86c0: 0a 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73 70 65  .  lappend ::spe
86d0: 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 24  ed_trial_times $
86e0: 6e 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f 63 20  name $tm.}.proc 
86f0: 73 70 65 65 64 5f 74 72 69 61 6c 5f 69 6e 69 74  speed_trial_init
8700: 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62   {name} {.  glob
8710: 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20  al total_time.  
8720: 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20 30  set total_time 0
8730: 0a 20 20 73 65 74 20 3a 3a 73 70 65 65 64 5f 74  .  set ::speed_t
8740: 72 69 61 6c 5f 74 69 6d 65 73 20 5b 6c 69 73 74  rial_times [list
8750: 5d 0a 20 20 73 71 6c 69 74 65 33 20 76 65 72 73  ].  sqlite3 vers
8760: 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 73 65  db :memory:.  se
8770: 74 20 76 65 72 73 20 5b 76 65 72 73 64 62 20 6f  t vers [versdb o
8780: 6e 65 20 7b 53 45 4c 45 43 54 20 73 71 6c 69 74  ne {SELECT sqlit
8790: 65 5f 73 6f 75 72 63 65 5f 69 64 28 29 7d 5d 0a  e_source_id()}].
87a0: 20 20 76 65 72 73 64 62 20 63 6c 6f 73 65 0a 20    versdb close. 
87b0: 20 6f 75 74 70 75 74 32 20 22 53 51 4c 69 74 65   output2 "SQLite
87c0: 20 24 76 65 72 73 22 0a 7d 0a 70 72 6f 63 20 73   $vers".}.proc s
87d0: 70 65 65 64 5f 74 72 69 61 6c 5f 73 75 6d 6d 61  peed_trial_summa
87e0: 72 79 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c  ry {name} {.  gl
87f0: 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a  obal total_time.
8800: 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d 61    output2 [forma
8810: 74 20 7b 25 2d 32 31 2e 32 31 73 20 25 31 32 64  t {%-21.21s %12d
8820: 20 75 53 20 54 4f 54 41 4c 7d 20 24 6e 61 6d 65   uS TOTAL} $name
8830: 20 24 74 6f 74 61 6c 5f 74 69 6d 65 5d 0a 0a 20   $total_time].. 
8840: 20 69 66 20 7b 20 30 20 7d 20 7b 0a 20 20 20 20   if { 0 } {.    
8850: 73 71 6c 69 74 65 33 20 76 65 72 73 64 62 20 3a  sqlite3 versdb :
8860: 6d 65 6d 6f 72 79 3a 0a 20 20 20 20 73 65 74 20  memory:.    set 
8870: 76 65 72 73 20 5b 6c 69 6e 64 65 78 20 5b 76 65  vers [lindex [ve
8880: 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45 43 54  rsdb one {SELECT
8890: 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69   sqlite_source_i
88a0: 64 28 29 7d 5d 20 30 5d 0a 20 20 20 20 76 65 72  d()}] 0].    ver
88b0: 73 64 62 20 63 6c 6f 73 65 0a 20 20 20 20 6f 75  sdb close.    ou
88c0: 74 70 75 74 32 20 22 43 52 45 41 54 45 20 54 41  tput2 "CREATE TA
88d0: 42 4c 45 20 49 46 20 4e 4f 54 20 45 58 49 53 54  BLE IF NOT EXIST
88e0: 53 20 74 69 6d 65 28 76 65 72 73 69 6f 6e 2c 20  S time(version, 
88f0: 73 63 72 69 70 74 2c 20 74 65 73 74 2c 20 75 73  script, test, us
8900: 29 3b 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20  );".    foreach 
8910: 7b 74 65 73 74 20 75 73 7d 20 24 3a 3a 73 70 65  {test us} $::spe
8920: 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 7b  ed_trial_times {
8930: 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22  .      output2 "
8940: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 69 6d 65  INSERT INTO time
8950: 20 56 41 4c 55 45 53 28 27 24 76 65 72 73 27 2c   VALUES('$vers',
8960: 20 27 24 6e 61 6d 65 27 2c 20 27 24 74 65 73 74   '$name', '$test
8970: 27 2c 20 24 75 73 29 3b 22 0a 20 20 20 20 7d 0a  ', $us);".    }.
8980: 20 20 7d 0a 7d 0a 0a 23 20 52 75 6e 20 74 68 69    }.}..# Run thi
8990: 73 20 72 6f 75 74 69 6e 65 20 6c 61 73 74 0a 23  s routine last.#
89a0: 0a 70 72 6f 63 20 66 69 6e 69 73 68 5f 74 65 73  .proc finish_tes
89b0: 74 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b  t {} {.  catch {
89c0: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  db close}.  catc
89d0: 68 20 7b 64 62 31 20 63 6c 6f 73 65 7d 0a 20 20  h {db1 close}.  
89e0: 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65  catch {db2 close
89f0: 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20 63  }.  catch {db3 c
8a00: 6c 6f 73 65 7d 0a 20 20 69 66 20 7b 30 3d 3d 5b  lose}.  if {0==[
8a10: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c  info exists ::SL
8a20: 41 56 45 5d 7d 20 7b 20 66 69 6e 61 6c 69 7a 65  AVE]} { finalize
8a30: 5f 74 65 73 74 69 6e 67 20 7d 0a 7d 0a 70 72 6f  _testing }.}.pro
8a40: 63 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69  c finalize_testi
8a50: 6e 67 20 7b 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c  ng {} {.  global
8a60: 20 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c   sqlite_open_fil
8a70: 65 5f 63 6f 75 6e 74 0a 0a 20 20 73 65 74 20 6f  e_count..  set o
8a80: 6d 69 74 4c 69 73 74 20 5b 73 65 74 5f 74 65 73  mitList [set_tes
8a90: 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c  t_counter omit_l
8aa0: 69 73 74 5d 0a 0a 20 20 63 61 74 63 68 20 7b 64  ist]..  catch {d
8ab0: 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
8ac0: 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
8ad0: 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d  atch {db3 close}
8ae0: 0a 0a 20 20 76 66 73 5f 75 6e 6c 69 6e 6b 5f 74  ..  vfs_unlink_t
8af0: 65 73 74 0a 20 20 73 71 6c 69 74 65 33 20 64 62  est.  sqlite3 db
8b00: 20 7b 7d 0a 20 20 23 20 73 71 6c 69 74 65 33 5f   {}.  # sqlite3_
8b10: 63 6c 65 61 72 5f 74 73 64 5f 6d 65 6d 64 65 62  clear_tsd_memdeb
8b20: 75 67 0a 20 20 64 62 20 63 6c 6f 73 65 0a 20 20  ug.  db close.  
8b30: 73 71 6c 69 74 65 33 5f 72 65 73 65 74 5f 61 75  sqlite3_reset_au
8b40: 74 6f 5f 65 78 74 65 6e 73 69 6f 6e 0a 0a 20 20  to_extension..  
8b50: 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68 65 61  sqlite3_soft_hea
8b60: 70 5f 6c 69 6d 69 74 20 30 0a 20 20 73 65 74 20  p_limit 0.  set 
8b70: 6e 54 65 73 74 20 5b 69 6e 63 72 5f 6e 74 65 73  nTest [incr_ntes
8b80: 74 5d 0a 20 20 73 65 74 20 6e 45 72 72 20 5b 73  t].  set nErr [s
8b90: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
8ba0: 65 72 72 6f 72 73 5d 0a 0a 20 20 73 65 74 20 6e  errors]..  set n
8bb0: 4b 6e 6f 77 6e 20 30 0a 20 20 69 66 20 7b 5b 66  Known 0.  if {[f
8bc0: 69 6c 65 20 72 65 61 64 61 62 6c 65 20 6b 6e 6f  ile readable kno
8bd0: 77 6e 2d 70 72 6f 62 6c 65 6d 73 2e 74 78 74 5d  wn-problems.txt]
8be0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 64 20 5b  } {.    set fd [
8bf0: 6f 70 65 6e 20 6b 6e 6f 77 6e 2d 70 72 6f 62 6c  open known-probl
8c00: 65 6d 73 2e 74 78 74 5d 0a 20 20 20 20 73 65 74  ems.txt].    set
8c10: 20 63 6f 6e 74 65 6e 74 20 5b 72 65 61 64 20 24   content [read $
8c20: 66 64 5d 0a 20 20 20 20 63 6c 6f 73 65 20 24 66  fd].    close $f
8c30: 64 0a 20 20 20 20 66 6f 72 65 61 63 68 20 78 20  d.    foreach x 
8c40: 24 63 6f 6e 74 65 6e 74 20 7b 73 65 74 20 6b 6e  $content {set kn
8c50: 6f 77 6e 5f 65 72 72 6f 72 28 24 78 29 20 31 7d  own_error($x) 1}
8c60: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 78 20 5b  .    foreach x [
8c70: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
8c80: 20 66 61 69 6c 5f 6c 69 73 74 5d 20 7b 0a 20 20   fail_list] {.  
8c90: 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78      if {[info ex
8ca0: 69 73 74 73 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72  ists known_error
8cb0: 28 24 78 29 5d 7d 20 7b 69 6e 63 72 20 6e 4b 6e  ($x)]} {incr nKn
8cc0: 6f 77 6e 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  own}.    }.  }. 
8cd0: 20 69 66 20 7b 24 6e 4b 6e 6f 77 6e 3e 30 7d 20   if {$nKnown>0} 
8ce0: 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 5b  {.    output2 "[
8cf0: 65 78 70 72 20 7b 24 6e 45 72 72 2d 24 6e 4b 6e  expr {$nErr-$nKn
8d00: 6f 77 6e 7d 5d 20 6e 65 77 20 65 72 72 6f 72 73  own}] new errors
8d10: 20 61 6e 64 20 24 6e 4b 6e 6f 77 6e 20 6b 6e 6f   and $nKnown kno
8d20: 77 6e 20 65 72 72 6f 72 73 5c 0a 20 20 20 20 20  wn errors\.     
8d30: 20 20 20 20 6f 75 74 20 6f 66 20 24 6e 54 65 73      out of $nTes
8d40: 74 20 74 65 73 74 73 22 0a 20 20 7d 20 65 6c 73  t tests".  } els
8d50: 65 20 7b 0a 20 20 20 20 73 65 74 20 63 70 75 69  e {.    set cpui
8d60: 6e 66 6f 20 7b 7d 0a 20 20 20 20 69 66 20 7b 5b  nfo {}.    if {[
8d70: 63 61 74 63 68 20 7b 65 78 65 63 20 68 6f 73 74  catch {exec host
8d80: 6e 61 6d 65 7d 20 68 6e 61 6d 65 5d 3d 3d 30 7d  name} hname]==0}
8d90: 20 7b 73 65 74 20 63 70 75 69 6e 66 6f 20 5b 73   {set cpuinfo [s
8da0: 74 72 69 6e 67 20 74 72 69 6d 20 24 68 6e 61 6d  tring trim $hnam
8db0: 65 5d 7d 0a 20 20 20 20 61 70 70 65 6e 64 20 63  e]}.    append c
8dc0: 70 75 69 6e 66 6f 20 22 20 24 3a 3a 74 63 6c 5f  puinfo " $::tcl_
8dd0: 70 6c 61 74 66 6f 72 6d 28 6f 73 29 22 0a 20 20  platform(os)".  
8de0: 20 20 61 70 70 65 6e 64 20 63 70 75 69 6e 66 6f    append cpuinfo
8df0: 20 22 20 5b 65 78 70 72 20 7b 24 3a 3a 74 63 6c   " [expr {$::tcl
8e00: 5f 70 6c 61 74 66 6f 72 6d 28 70 6f 69 6e 74 65  _platform(pointe
8e10: 72 53 69 7a 65 29 2a 38 7d 5d 2d 62 69 74 22 0a  rSize)*8}]-bit".
8e20: 20 20 20 20 61 70 70 65 6e 64 20 63 70 75 69 6e      append cpuin
8e30: 66 6f 20 22 20 5b 73 74 72 69 6e 67 20 6d 61 70  fo " [string map
8e40: 20 7b 45 20 2d 65 7d 20 24 3a 3a 74 63 6c 5f 70   {E -e} $::tcl_p
8e50: 6c 61 74 66 6f 72 6d 28 62 79 74 65 4f 72 64 65  latform(byteOrde
8e60: 72 29 5d 22 0a 20 20 20 20 6f 75 74 70 75 74 32  r)]".    output2
8e70: 20 22 53 51 4c 69 74 65 20 5b 73 71 6c 69 74 65   "SQLite [sqlite
8e80: 33 20 2d 73 6f 75 72 63 65 69 64 5d 22 0a 20 20  3 -sourceid]".  
8e90: 20 20 6f 75 74 70 75 74 32 20 22 24 6e 45 72 72    output2 "$nErr
8ea0: 20 65 72 72 6f 72 73 20 6f 75 74 20 6f 66 20 24   errors out of $
8eb0: 6e 54 65 73 74 20 74 65 73 74 73 20 6f 6e 20 24  nTest tests on $
8ec0: 63 70 75 69 6e 66 6f 22 0a 20 20 7d 0a 20 20 69  cpuinfo".  }.  i
8ed0: 66 20 7b 24 6e 45 72 72 3e 24 6e 4b 6e 6f 77 6e  f {$nErr>$nKnown
8ee0: 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20  } {.    output2 
8ef0: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 21 46 61 69  -nonewline "!Fai
8f00: 6c 75 72 65 73 20 6f 6e 20 74 68 65 73 65 20 74  lures on these t
8f10: 65 73 74 73 3a 22 0a 20 20 20 20 66 6f 72 65 61  ests:".    forea
8f20: 63 68 20 78 20 5b 73 65 74 5f 74 65 73 74 5f 63  ch x [set_test_c
8f30: 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73 74  ounter fail_list
8f40: 5d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 21 5b  ] {.      if {![
8f50: 69 6e 66 6f 20 65 78 69 73 74 73 20 6b 6e 6f 77  info exists know
8f60: 6e 5f 65 72 72 6f 72 28 24 78 29 5d 7d 20 7b 6f  n_error($x)]} {o
8f70: 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e  utput2 -nonewlin
8f80: 65 20 22 20 24 78 22 7d 0a 20 20 20 20 7d 0a 20  e " $x"}.    }. 
8f90: 20 20 20 6f 75 74 70 75 74 32 20 22 22 0a 20 20     output2 "".  
8fa0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 77 61 72 6e  }.  foreach warn
8fb0: 69 6e 67 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  ing [set_test_co
8fc0: 75 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73 74 5d  unter warn_list]
8fd0: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22   {.    output2 "
8fe0: 57 61 72 6e 69 6e 67 3a 20 24 77 61 72 6e 69 6e  Warning: $warnin
8ff0: 67 22 0a 20 20 7d 0a 20 20 72 75 6e 5f 74 68 72  g".  }.  run_thr
9000: 65 61 64 5f 74 65 73 74 73 20 31 0a 20 20 69 66  ead_tests 1.  if
9010: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 6f 6d 69 74   {[llength $omit
9020: 4c 69 73 74 5d 3e 30 7d 20 7b 0a 20 20 20 20 6f  List]>0} {.    o
9030: 75 74 70 75 74 32 20 22 4f 6d 69 74 74 65 64 20  utput2 "Omitted 
9040: 74 65 73 74 20 63 61 73 65 73 3a 22 0a 20 20 20  test cases:".   
9050: 20 73 65 74 20 70 72 65 63 20 7b 7d 0a 20 20 20   set prec {}.   
9060: 20 66 6f 72 65 61 63 68 20 7b 72 65 63 7d 20 5b   foreach {rec} [
9070: 6c 73 6f 72 74 20 24 6f 6d 69 74 4c 69 73 74 5d  lsort $omitList]
9080: 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 24 72 65   {.      if {$re
9090: 63 3d 3d 24 70 72 65 63 7d 20 63 6f 6e 74 69 6e  c==$prec} contin
90a0: 75 65 0a 20 20 20 20 20 20 73 65 74 20 70 72 65  ue.      set pre
90b0: 63 20 24 72 65 63 0a 20 20 20 20 20 20 6f 75 74  c $rec.      out
90c0: 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 2e 20  put2 [format {. 
90d0: 20 25 2d 31 32 73 20 25 73 7d 20 5b 6c 69 6e 64   %-12s %s} [lind
90e0: 65 78 20 24 72 65 63 20 30 5d 20 5b 6c 69 6e 64  ex $rec 0] [lind
90f0: 65 78 20 24 72 65 63 20 31 5d 5d 0a 20 20 20 20  ex $rec 1]].    
9100: 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 45 72  }.  }.  if {$nEr
9110: 72 3e 30 20 26 26 20 21 5b 77 6f 72 6b 69 6e 67  r>0 && ![working
9120: 5f 36 34 62 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20  _64bit_int]} {. 
9130: 20 20 20 6f 75 74 70 75 74 32 20 22 2a 2a 2a 2a     output2 "****
9140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9170: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a  **************".
9180: 20 20 20 20 6f 75 74 70 75 74 32 20 22 4e 2e 42      output2 "N.B
9190: 2e 3a 20 20 54 68 65 20 76 65 72 73 69 6f 6e 20  .:  The version 
91a0: 6f 66 20 54 43 4c 20 74 68 61 74 20 79 6f 75 20  of TCL that you 
91b0: 75 73 65 64 20 74 6f 20 62 75 69 6c 64 20 74 68  used to build th
91c0: 69 73 20 74 65 73 74 20 68 61 72 6e 65 73 73 22  is test harness"
91d0: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 69 73  .    output2 "is
91e0: 20 64 65 66 65 63 74 69 76 65 20 69 6e 20 74 68   defective in th
91f0: 61 74 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 73  at it does not s
9200: 75 70 70 6f 72 74 20 36 34 2d 62 69 74 20 69 6e  upport 64-bit in
9210: 74 65 67 65 72 73 2e 20 20 53 6f 6d 65 20 6f 72  tegers.  Some or
9220: 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 61  ".    output2 "a
9230: 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74 20 66  ll of the test f
9240: 61 69 6c 75 72 65 73 20 61 62 6f 76 65 20 6d 69  ailures above mi
9250: 67 68 74 20 62 65 20 61 20 72 65 73 75 6c 74 20  ght be a result 
9260: 66 72 6f 6d 20 74 68 69 73 20 64 65 66 65 63 74  from this defect
9270: 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 69  ".    output2 "i
9280: 6e 20 79 6f 75 72 20 54 43 4c 20 62 75 69 6c 64  n your TCL build
9290: 2e 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22  .".    output2 "
92a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
92b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
92c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
92d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
92e0: 2a 2a 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24 3a  **".  }.  if {$:
92f0: 3a 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e 61  :cmdlinearg(bina
9300: 72 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76 66  rylog)} {.    vf
9310: 73 6c 6f 67 20 66 69 6e 61 6c 69 7a 65 20 62 69  slog finalize bi
9320: 6e 61 72 79 6c 6f 67 0a 20 20 7d 0a 20 20 69 66  narylog.  }.  if
9330: 20 7b 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66   {$sqlite_open_f
9340: 69 6c 65 5f 63 6f 75 6e 74 7d 20 7b 0a 20 20 20  ile_count} {.   
9350: 20 6f 75 74 70 75 74 32 20 22 24 73 71 6c 69 74   output2 "$sqlit
9360: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
9370: 74 20 66 69 6c 65 73 20 77 65 72 65 20 6c 65 66  t files were lef
9380: 74 20 6f 70 65 6e 22 0a 20 20 20 20 69 6e 63 72  t open".    incr
9390: 20 6e 45 72 72 0a 20 20 7d 0a 20 20 69 66 20 7b   nErr.  }.  if {
93a0: 5b 6c 69 6e 64 65 78 20 5b 73 71 6c 69 74 65 33  [lindex [sqlite3
93b0: 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53  _status SQLITE_S
93c0: 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55  TATUS_MALLOC_COU
93d0: 4e 54 20 30 5d 20 31 5d 3e 30 20 7c 7c 0a 20 20  NT 0] 1]>0 ||.  
93e0: 20 20 20 20 20 20 20 20 20 20 20 20 5b 73 71 6c              [sql
93f0: 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64  ite3_memory_used
9400: 5d 3e 30 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75  ]>0} {.    outpu
9410: 74 32 20 22 55 6e 66 72 65 65 64 20 6d 65 6d 6f  t2 "Unfreed memo
9420: 72 79 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d  ry: [sqlite3_mem
9430: 6f 72 79 5f 75 73 65 64 5d 20 62 79 74 65 73 20  ory_used] bytes 
9440: 69 6e 5c 0a 20 20 20 20 20 20 20 20 20 5b 6c 69  in\.         [li
9450: 6e 64 65 78 20 5b 73 71 6c 69 74 65 33 5f 73 74  ndex [sqlite3_st
9460: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
9470: 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20  US_MALLOC_COUNT 
9480: 30 5d 20 31 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e  0] 1] allocation
9490: 73 22 0a 20 20 20 20 69 6e 63 72 20 6e 45 72 72  s".    incr nErr
94a0: 0a 20 20 20 20 69 66 63 61 70 61 62 6c 65 20 6d  .    ifcapable m
94b0: 65 6d 35 7c 7c 28 6d 65 6d 33 26 26 64 65 62 75  em5||(mem3&&debu
94c0: 67 29 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75  g) {.      outpu
94d0: 74 32 20 22 57 72 69 74 69 6e 67 20 75 6e 66 72  t2 "Writing unfr
94e0: 65 65 64 20 6d 65 6d 6f 72 79 20 6c 6f 67 20 74  eed memory log t
94f0: 6f 20 5c 22 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78  o \"./memleak.tx
9500: 74 5c 22 22 0a 20 20 20 20 20 20 73 71 6c 69 74  t\"".      sqlit
9510: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70  e3_memdebug_dump
9520: 20 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 0a 20   ./memleak.txt. 
9530: 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a     }.  } else {.
9540: 20 20 20 20 6f 75 74 70 75 74 32 20 22 41 6c 6c      output2 "All
9550: 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69   memory allocati
9560: 6f 6e 73 20 66 72 65 65 64 20 2d 20 6e 6f 20 6c  ons freed - no l
9570: 65 61 6b 73 22 0a 20 20 20 20 69 66 63 61 70 61  eaks".    ifcapa
9580: 62 6c 65 20 6d 65 6d 35 20 7b 0a 20 20 20 20 20  ble mem5 {.     
9590: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
95a0: 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 75 73 61 67  g_dump ./memusag
95b0: 65 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d 0a  e.txt.    }.  }.
95c0: 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73 0a    show_memstats.
95d0: 20 20 6f 75 74 70 75 74 32 20 22 4d 61 78 69 6d    output2 "Maxim
95e0: 75 6d 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a  um memory usage:
95f0: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79   [sqlite3_memory
9600: 5f 68 69 67 68 77 61 74 65 72 20 31 5d 20 62 79  _highwater 1] by
9610: 74 65 73 22 0a 20 20 6f 75 74 70 75 74 32 20 22  tes".  output2 "
9620: 43 75 72 72 65 6e 74 20 6d 65 6d 6f 72 79 20 75  Current memory u
9630: 73 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f 6d  sage: [sqlite3_m
9640: 65 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72 5d  emory_highwater]
9650: 20 62 79 74 65 73 22 0a 20 20 69 66 20 7b 5b 69   bytes".  if {[i
9660: 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20 73 71 6c  nfo commands sql
9670: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6d 61  ite3_memdebug_ma
9680: 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20 6e 65 20 22  lloc_count] ne "
9690: 22 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  "} {.    output2
96a0: 20 22 4e 75 6d 62 65 72 20 6f 66 20 6d 61 6c 6c   "Number of mall
96b0: 6f 63 28 29 20 20 3a 20 5b 73 71 6c 69 74 65 33  oc()  : [sqlite3
96c0: 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63  _memdebug_malloc
96d0: 5f 63 6f 75 6e 74 5d 20 63 61 6c 6c 73 22 0a 20  _count] calls". 
96e0: 20 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c   }.  if {$::cmdl
96f0: 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61  inearg(malloctra
9700: 63 65 29 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75  ce)} {.    outpu
9710: 74 32 20 22 57 72 69 74 69 6e 67 20 6d 61 6c 6c  t2 "Writing mall
9720: 6f 63 73 2e 74 63 6c 2e 2e 2e 22 0a 20 20 20 20  ocs.tcl...".    
9730: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c  memdebug_log_sql
9740: 20 6d 61 6c 6c 6f 63 73 2e 74 63 6c 0a 20 20 20   mallocs.tcl.   
9750: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
9760: 67 5f 6c 6f 67 20 73 74 6f 70 0a 20 20 20 20 73  g_log stop.    s
9770: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
9780: 6c 6f 67 20 63 6c 65 61 72 0a 20 20 20 20 69 66  log clear.    if
9790: 20 7b 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72   {[sqlite3_memor
97a0: 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20 20 20  y_used]>0} {.   
97b0: 20 20 20 6f 75 74 70 75 74 32 20 22 57 72 69 74     output2 "Writ
97c0: 69 6e 67 20 6c 65 61 6b 73 2e 74 63 6c 2e 2e 2e  ing leaks.tcl...
97d0: 22 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ".      sqlite3_
97e0: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 79 6e  memdebug_log syn
97f0: 63 0a 20 20 20 20 20 20 6d 65 6d 64 65 62 75 67  c.      memdebug
9800: 5f 6c 6f 67 5f 73 71 6c 20 6c 65 61 6b 73 2e 74  _log_sql leaks.t
9810: 63 6c 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66  cl.    }.  }.  f
9820: 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d  oreach f [glob -
9830: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e  nocomplain test.
9840: 64 62 2d 2a 2d 6a 6f 75 72 6e 61 6c 5d 20 7b 0a  db-*-journal] {.
9850: 20 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20      forcedelete 
9860: 24 66 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68  $f.  }.  foreach
9870: 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70   f [glob -nocomp
9880: 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d 6d 6a 2a  lain test.db-mj*
9890: 5d 20 7b 0a 20 20 20 20 66 6f 72 63 65 64 65 6c  ] {.    forcedel
98a0: 65 74 65 20 24 66 0a 20 20 7d 0a 20 20 65 78 69  ete $f.  }.  exi
98b0: 74 20 5b 65 78 70 72 20 7b 24 6e 45 72 72 3e 30  t [expr {$nErr>0
98c0: 7d 5d 0a 7d 0a 0a 23 20 44 69 73 70 6c 61 79 20  }].}..# Display 
98d0: 6d 65 6d 6f 72 79 20 73 74 61 74 69 73 74 69 63  memory statistic
98e0: 73 20 66 6f 72 20 61 6e 61 6c 79 73 69 73 20 61  s for analysis a
98f0: 6e 64 20 64 65 62 75 67 67 69 6e 67 20 70 75 72  nd debugging pur
9900: 70 6f 73 65 73 2e 0a 23 0a 70 72 6f 63 20 73 68  poses..#.proc sh
9910: 6f 77 5f 6d 65 6d 73 74 61 74 73 20 7b 7d 20 7b  ow_memstats {} {
9920: 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65  .  set x [sqlite
9930: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
9940: 53 54 41 54 55 53 5f 4d 45 4d 4f 52 59 5f 55 53  STATUS_MEMORY_US
9950: 45 44 20 30 5d 0a 20 20 73 65 74 20 79 20 5b 73  ED 0].  set y [s
9960: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
9970: 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c  LITE_STATUS_MALL
9980: 4f 43 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74  OC_SIZE 0].  set
9990: 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f   val [format {no
99a0: 77 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64  w %10d  max %10d
99b0: 20 20 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d    max-size %10d}
99c0: 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   \.             
99d0: 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b   [lindex $x 1] [
99e0: 6c 69 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69  lindex $x 2] [li
99f0: 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f 75  ndex $y 2]].  ou
9a00: 74 70 75 74 31 20 22 4d 65 6d 6f 72 79 20 75 73  tput1 "Memory us
9a10: 65 64 3a 20 20 20 20 20 20 20 20 20 20 24 76 61  ed:          $va
9a20: 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69  l".  set x [sqli
9a30: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
9a40: 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f  E_STATUS_MALLOC_
9a50: 43 4f 55 4e 54 20 30 5d 0a 20 20 73 65 74 20 76  COUNT 0].  set v
9a60: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
9a70: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20  %10d  max %10d} 
9a80: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
9a90: 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 6f  index $x 2]].  o
9aa0: 75 74 70 75 74 31 20 22 41 6c 6c 6f 63 61 74 69  utput1 "Allocati
9ab0: 6f 6e 20 63 6f 75 6e 74 3a 20 20 20 20 20 24 76  on count:     $v
9ac0: 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c  al".  set x [sql
9ad0: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
9ae0: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
9af0: 43 48 45 5f 55 53 45 44 20 30 5d 0a 20 20 73 65  CHE_USED 0].  se
9b00: 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  t y [sqlite3_sta
9b10: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
9b20: 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a 45  S_PAGECACHE_SIZE
9b30: 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66   0].  set val [f
9b40: 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20  ormat {now %10d 
9b50: 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d 73   max %10d  max-s
9b60: 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20 20  ize %10d} \.    
9b70: 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65            [linde
9b80: 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20  x $x 1] [lindex 
9b90: 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79  $x 2] [lindex $y
9ba0: 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74 31 20 22   2]].  output1 "
9bb0: 50 61 67 65 2d 63 61 63 68 65 20 75 73 65 64 3a  Page-cache used:
9bc0: 20 20 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65        $val".  se
9bd0: 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  t x [sqlite3_sta
9be0: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
9bf0: 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  S_PAGECACHE_OVER
9c00: 46 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 76 61  FLOW 0].  set va
9c10: 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25  l [format {now %
9c20: 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b  10d  max %10d} [
9c30: 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69  lindex $x 1] [li
9c40: 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 6f 75  ndex $x 2]].  ou
9c50: 74 70 75 74 31 20 22 50 61 67 65 2d 63 61 63 68  tput1 "Page-cach
9c60: 65 20 6f 76 65 72 66 6c 6f 77 3a 20 20 24 76 61  e overflow:  $va
9c70: 6c 22 0a 20 20 69 66 63 61 70 61 62 6c 65 20 79  l".  ifcapable y
9c80: 79 74 72 61 63 6b 6d 61 78 73 74 61 63 6b 64 65  ytrackmaxstackde
9c90: 70 74 68 20 7b 0a 20 20 20 20 73 65 74 20 78 20  pth {.    set x 
9ca0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
9cb0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
9cc0: 52 53 45 52 5f 53 54 41 43 4b 20 30 5d 0a 20 20  RSER_STACK 0].  
9cd0: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
9ce0: 74 20 7b 20 20 20 20 20 20 20 20 20 20 20 20 20  t {             
9cf0: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
9d00: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 20 20 6f  dex $x 2]].    o
9d10: 75 74 70 75 74 32 20 22 50 61 72 73 65 72 20 73  utput2 "Parser s
9d20: 74 61 63 6b 20 64 65 70 74 68 3a 20 20 20 20 24  tack depth:    $
9d30: 76 61 6c 22 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20  val".  }.}..# A 
9d40: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65  procedure to exe
9d50: 63 75 74 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20  cute SQL.#.proc 
9d60: 65 78 65 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62  execsql {sql {db
9d70: 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73   db}} {.  # puts
9d80: 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20   "SQL = $sql".  
9d90: 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64  uplevel [list $d
9da0: 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 70  b eval $sql].}.p
9db0: 72 6f 63 20 65 78 65 63 73 71 6c 5f 74 69 6d 65  roc execsql_time
9dc0: 64 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20  d {sql {db db}} 
9dd0: 7b 0a 20 20 73 65 74 20 74 6d 20 5b 74 69 6d 65  {.  set tm [time
9de0: 20 7b 0a 20 20 20 20 73 65 74 20 78 20 5b 75 70   {.    set x [up
9df0: 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20  level [list $db 
9e00: 65 76 61 6c 20 24 73 71 6c 5d 5d 0a 20 20 7d 20  eval $sql]].  } 
9e10: 31 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e  1].  set tm [lin
9e20: 64 65 78 20 24 74 6d 20 30 5d 0a 20 20 6f 75 74  dex $tm 0].  out
9e30: 70 75 74 31 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  put1 -nonewline 
9e40: 22 20 28 5b 65 78 70 72 20 7b 24 74 6d 2a 30 2e  " ([expr {$tm*0.
9e50: 30 30 31 7d 5d 6d 73 29 20 22 0a 20 20 73 65 74  001}]ms) ".  set
9e60: 20 78 0a 7d 0a 0a 23 20 45 78 65 63 75 74 65 20   x.}..# Execute 
9e70: 53 51 4c 20 61 6e 64 20 63 61 74 63 68 20 65 78  SQL and catch ex
9e80: 63 65 70 74 69 6f 6e 73 2e 0a 23 0a 70 72 6f 63  ceptions..#.proc
9e90: 20 63 61 74 63 68 73 71 6c 20 7b 73 71 6c 20 7b   catchsql {sql {
9ea0: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75  db db}} {.  # pu
9eb0: 74 73 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a  ts "SQL = $sql".
9ec0: 20 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 5b    set r [catch [
9ed0: 6c 69 73 74 20 75 70 6c 65 76 65 6c 20 5b 6c 69  list uplevel [li
9ee0: 73 74 20 24 64 62 20 65 76 61 6c 20 24 73 71 6c  st $db eval $sql
9ef0: 5d 5d 20 6d 73 67 5d 0a 20 20 6c 61 70 70 65 6e  ]] msg].  lappen
9f00: 64 20 72 20 24 6d 73 67 0a 20 20 72 65 74 75 72  d r $msg.  retur
9f10: 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20  n $r.}..# Do an 
9f20: 56 44 42 45 20 63 6f 64 65 20 64 75 6d 70 20 6f  VDBE code dump o
9f30: 6e 20 74 68 65 20 53 51 4c 20 67 69 76 65 6e 0a  n the SQL given.
9f40: 23 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 20 7b  #.proc explain {
9f50: 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20  sql {db db}} {. 
9f60: 20 6f 75 74 70 75 74 32 20 22 22 0a 20 20 6f 75   output2 "".  ou
9f70: 74 70 75 74 32 20 22 61 64 64 72 20 20 6f 70 63  tput2 "addr  opc
9f80: 6f 64 65 20 20 20 20 20 20 20 20 70 31 20 20 20  ode        p1   
9f90: 20 20 20 70 32 20 20 20 20 20 20 70 33 20 20 20     p2      p3   
9fa0: 20 20 20 70 34 20 20 20 20 20 20 20 20 20 20 20     p4           
9fb0: 20 20 20 20 70 35 20 20 23 22 0a 20 20 6f 75 74      p5  #".  out
9fc0: 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d  put2 "----  ----
9fd0: 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  --------  ------
9fe0: 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d    ------  ------
9ff0: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
a000: 2d 20 20 2d 2d 20 20 2d 22 0a 20 20 24 64 62 20  -  --  -".  $db 
a010: 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73  eval "explain $s
a020: 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 6f 75 74  ql" {} {.    out
a030: 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 2d  put2 [format {%-
a040: 34 64 20 20 25 2d 31 32 2e 31 32 73 20 20 25 2d  4d  %-12.12s  %-
a050: 36 64 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20  6d  %-6d  %-6d  
a060: 25 20 2d 31 37 73 20 25 73 20 20 25 73 7d 20 5c  % -17s %s  %s} \
a070: 0a 20 20 20 20 20 20 24 61 64 64 72 20 24 6f 70  .      $addr $op
a080: 63 6f 64 65 20 24 70 31 20 24 70 32 20 24 70 33  code $p1 $p2 $p3
a090: 20 24 70 34 20 24 70 35 20 24 63 6f 6d 6d 65 6e   $p4 $p5 $commen
a0a0: 74 0a 20 20 20 20 5d 0a 20 20 7d 0a 7d 0a 0a 70  t.    ].  }.}..p
a0b0: 72 6f 63 20 65 78 70 6c 61 69 6e 5f 69 20 7b 73  roc explain_i {s
a0c0: 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  ql {db db}} {.  
a0d0: 6f 75 74 70 75 74 32 20 22 22 0a 20 20 6f 75 74  output2 "".  out
a0e0: 70 75 74 32 20 22 61 64 64 72 20 20 6f 70 63 6f  put2 "addr  opco
a0f0: 64 65 20 20 20 20 20 20 20 20 70 31 20 20 20 20  de        p1    
a100: 20 20 70 32 20 20 20 20 20 20 70 33 20 20 20 20    p2      p3    
a110: 20 20 70 34 20 20 20 20 20 20 20 20 20 20 20 20    p4            
a120: 20 20 20 20 70 35 20 20 23 22 0a 20 20 6f 75 74      p5  #".  out
a130: 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d  put2 "----  ----
a140: 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  --------  ------
a150: 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d    ------  ------
a160: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
a170: 2d 2d 20 20 2d 2d 20 20 2d 22 0a 0a 0a 20 20 23  --  --  -"...  #
a180: 20 53 65 74 20 75 70 20 63 6f 6c 6f 72 73 20 66   Set up colors f
a190: 6f 72 20 74 68 65 20 64 69 66 66 65 72 65 6e 74  or the different
a1a0: 20 6f 70 63 6f 64 65 73 2e 20 53 63 68 65 6d 65   opcodes. Scheme
a1b0: 20 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a   is as follows:.
a1c0: 20 20 23 0a 20 20 23 20 20 20 52 65 64 3a 20 20    #.  #   Red:  
a1d0: 20 4f 70 63 6f 64 65 73 20 74 68 61 74 20 77 72   Opcodes that wr
a1e0: 69 74 65 20 74 6f 20 61 20 62 2d 74 72 65 65 2e  ite to a b-tree.
a1f0: 0a 20 20 23 20 20 20 42 6c 75 65 3a 20 20 4f 70  .  #   Blue:  Op
a200: 63 6f 64 65 73 20 74 68 61 74 20 72 65 70 6f 73  codes that repos
a210: 69 74 69 6f 6e 20 6f 72 20 73 65 65 6b 20 61 20  ition or seek a 
a220: 63 75 72 73 6f 72 2e 20 0a 20 20 23 20 20 20 47  cursor. .  #   G
a230: 72 65 65 6e 3a 20 54 68 65 20 52 65 73 75 6c 74  reen: The Result
a240: 52 6f 77 20 6f 70 63 6f 64 65 2e 0a 20 20 23 0a  Row opcode..  #.
a250: 20 20 69 66 20 7b 20 5b 63 61 74 63 68 20 7b 66    if { [catch {f
a260: 63 6f 6e 66 69 67 75 72 65 20 73 74 64 6f 75 74  configure stdout
a270: 20 2d 6d 6f 64 65 7d 5d 3d 3d 30 20 7d 20 7b 0a   -mode}]==0 } {.
a280: 20 20 20 20 73 65 74 20 52 20 22 5c 30 33 33 5c      set R "\033\
a290: 5b 33 31 3b 31 6d 22 20 20 20 20 20 20 20 20 3b  [31;1m"        ;
a2a0: 23 20 52 65 64 20 66 67 0a 20 20 20 20 73 65 74  # Red fg.    set
a2b0: 20 47 20 22 5c 30 33 33 5c 5b 33 32 3b 31 6d 22   G "\033\[32;1m"
a2c0: 20 20 20 20 20 20 20 20 3b 23 20 47 72 65 65 6e          ;# Green
a2d0: 20 66 67 0a 20 20 20 20 73 65 74 20 42 20 22 5c   fg.    set B "\
a2e0: 30 33 33 5c 5b 33 34 3b 31 6d 22 20 20 20 20 20  033\[34;1m"     
a2f0: 20 20 20 3b 23 20 52 65 64 20 66 67 0a 20 20 20     ;# Red fg.   
a300: 20 73 65 74 20 44 20 22 5c 30 33 33 5c 5b 33 39   set D "\033\[39
a310: 3b 30 6d 22 20 20 20 20 20 20 20 20 3b 23 20 44  ;0m"        ;# D
a320: 65 66 61 75 6c 74 20 66 67 0a 20 20 7d 20 65 6c  efault fg.  } el
a330: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 52 20 22  se {.    set R "
a340: 22 0a 20 20 20 20 73 65 74 20 47 20 22 22 0a 20  ".    set G "". 
a350: 20 20 20 73 65 74 20 42 20 22 22 0a 20 20 20 20     set B "".    
a360: 73 65 74 20 44 20 22 22 0a 20 20 7d 0a 20 20 66  set D "".  }.  f
a370: 6f 72 65 61 63 68 20 6f 70 63 6f 64 65 20 7b 0a  oreach opcode {.
a380: 20 20 20 20 20 20 53 65 65 6b 20 53 65 65 6b 47        Seek SeekG
a390: 45 20 53 65 65 6b 47 54 20 53 65 65 6b 4c 45 20  E SeekGT SeekLE 
a3a0: 53 65 65 6b 4c 54 20 4e 6f 74 46 6f 75 6e 64 20  SeekLT NotFound 
a3b0: 4c 61 73 74 20 52 65 77 69 6e 64 0a 20 20 20 20  Last Rewind.    
a3c0: 20 20 4e 6f 43 6f 6e 66 6c 69 63 74 20 4e 65 78    NoConflict Nex
a3d0: 74 20 50 72 65 76 20 56 4e 65 78 74 20 56 50 72  t Prev VNext VPr
a3e0: 65 76 20 56 46 69 6c 74 65 72 0a 20 20 20 20 20  ev VFilter.     
a3f0: 20 53 6f 72 74 65 72 53 6f 72 74 20 53 6f 72 74   SorterSort Sort
a400: 65 72 4e 65 78 74 20 4e 65 78 74 49 66 4f 70 65  erNext NextIfOpe
a410: 6e 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74 20  n.  } {.    set 
a420: 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 24  color($opcode) $
a430: 42 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  B.  }.  foreach 
a440: 6f 70 63 6f 64 65 20 7b 52 65 73 75 6c 74 52 6f  opcode {ResultRo
a450: 77 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6c  w} {.    set col
a460: 6f 72 28 24 6f 70 63 6f 64 65 29 20 24 47 0a 20  or($opcode) $G. 
a470: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 6f 70 63   }.  foreach opc
a480: 6f 64 65 20 7b 49 64 78 49 6e 73 65 72 74 20 49  ode {IdxInsert I
a490: 6e 73 65 72 74 20 44 65 6c 65 74 65 20 49 64 78  nsert Delete Idx
a4a0: 44 65 6c 65 74 65 7d 20 7b 0a 20 20 20 20 73 65  Delete} {.    se
a4b0: 74 20 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29  t color($opcode)
a4c0: 20 24 52 0a 20 20 7d 0a 0a 20 20 73 65 74 20 62   $R.  }..  set b
a4d0: 53 65 65 6e 47 6f 74 6f 20 30 0a 20 20 24 64 62  SeenGoto 0.  $db
a4e0: 20 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24   eval "explain $
a4f0: 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 73 65  sql" {} {.    se
a500: 74 20 78 28 24 61 64 64 72 29 20 30 0a 20 20 20  t x($addr) 0.   
a510: 20 73 65 74 20 6f 70 28 24 61 64 64 72 29 20 24   set op($addr) $
a520: 6f 70 63 6f 64 65 0a 0a 20 20 20 20 69 66 20 7b  opcode..    if {
a530: 24 6f 70 63 6f 64 65 20 3d 3d 20 22 47 6f 74 6f  $opcode == "Goto
a540: 22 20 26 26 20 28 24 62 53 65 65 6e 47 6f 74 6f  " && ($bSeenGoto
a550: 3d 3d 30 20 7c 7c 20 28 24 70 32 20 3e 20 24 61  ==0 || ($p2 > $a
a560: 64 64 72 2b 31 30 29 29 7d 20 7b 0a 20 20 20 20  ddr+10))} {.    
a570: 20 20 73 65 74 20 6c 69 6e 65 62 72 65 61 6b 28    set linebreak(
a580: 24 70 32 29 20 31 0a 20 20 20 20 20 20 73 65 74  $p2) 1.      set
a590: 20 62 53 65 65 6e 47 6f 74 6f 20 31 0a 20 20 20   bSeenGoto 1.   
a5a0: 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63   }..    if {$opc
a5b0: 6f 64 65 3d 3d 22 4f 6e 63 65 22 7d 20 7b 0a 20  ode=="Once"} {. 
a5c0: 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20       for {set i 
a5d0: 24 61 64 64 72 7d 20 7b 24 69 3c 24 70 32 7d 20  $addr} {$i<$p2} 
a5e0: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
a5f0: 20 20 20 73 65 74 20 73 74 61 72 28 24 69 29 20     set star($i) 
a600: 24 61 64 64 72 0a 20 20 20 20 20 20 7d 0a 20 20  $addr.      }.  
a610: 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70    }..    if {$op
a620: 63 6f 64 65 3d 3d 22 4e 65 78 74 22 20 20 7c 7c  code=="Next"  ||
a630: 20 24 6f 70 63 6f 64 65 3d 3d 22 50 72 65 76 22   $opcode=="Prev"
a640: 20 0a 20 20 20 20 20 7c 7c 20 24 6f 70 63 6f 64   .     || $opcod
a650: 65 3d 3d 22 56 4e 65 78 74 22 20 7c 7c 20 24 6f  e=="VNext" || $o
a660: 70 63 6f 64 65 3d 3d 22 56 50 72 65 76 22 0a 20  pcode=="VPrev". 
a670: 20 20 20 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d      || $opcode==
a680: 22 53 6f 72 74 65 72 4e 65 78 74 22 20 7c 7c 20  "SorterNext" || 
a690: 24 6f 70 63 6f 64 65 3d 3d 22 4e 65 78 74 49 66  $opcode=="NextIf
a6a0: 4f 70 65 6e 22 0a 20 20 20 20 7d 20 7b 0a 20 20  Open".    } {.  
a6b0: 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 24      for {set i $
a6c0: 70 32 7d 20 7b 24 69 3c 24 61 64 64 72 7d 20 7b  p2} {$i<$addr} {
a6d0: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20  incr i} {.      
a6e0: 20 20 69 6e 63 72 20 78 28 24 69 29 20 32 0a 20    incr x($i) 2. 
a6f0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
a700: 20 20 69 66 20 7b 24 6f 70 63 6f 64 65 20 3d 3d    if {$opcode ==
a710: 20 22 47 6f 74 6f 22 20 26 26 20 24 70 32 3c 24   "Goto" && $p2<$
a720: 61 64 64 72 20 26 26 20 24 6f 70 28 24 70 32 29  addr && $op($p2)
a730: 3d 3d 22 59 69 65 6c 64 22 7d 20 7b 0a 20 20 20  =="Yield"} {.   
a740: 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 5b 65     for {set i [e
a750: 78 70 72 20 24 70 32 2b 31 5d 7d 20 7b 24 69 3c  xpr $p2+1]} {$i<
a760: 24 61 64 64 72 7d 20 7b 69 6e 63 72 20 69 7d 20  $addr} {incr i} 
a770: 7b 0a 20 20 20 20 20 20 20 20 69 6e 63 72 20 78  {.        incr x
a780: 28 24 69 29 20 32 0a 20 20 20 20 20 20 7d 0a 20  ($i) 2.      }. 
a790: 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f     }..    if {$o
a7a0: 70 63 6f 64 65 20 3d 3d 20 22 48 61 6c 74 22 20  pcode == "Halt" 
a7b0: 26 26 20 24 63 6f 6d 6d 65 6e 74 20 3d 3d 20 22  && $comment == "
a7c0: 45 6e 64 20 6f 66 20 63 6f 72 6f 75 74 69 6e 65  End of coroutine
a7d0: 22 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6c  "} {.      set l
a7e0: 69 6e 65 62 72 65 61 6b 28 5b 65 78 70 72 20 24  inebreak([expr $
a7f0: 61 64 64 72 2b 31 5d 29 20 31 0a 20 20 20 20 7d  addr+1]) 1.    }
a800: 0a 20 20 7d 0a 0a 20 20 24 64 62 20 65 76 61 6c  .  }..  $db eval
a810: 20 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20   "explain $sql" 
a820: 7b 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 69 6e  {} {.    if {[in
a830: 66 6f 20 65 78 69 73 74 73 20 6c 69 6e 65 62 72  fo exists linebr
a840: 65 61 6b 28 24 61 64 64 72 29 5d 7d 20 7b 0a 20  eak($addr)]} {. 
a850: 20 20 20 20 20 6f 75 74 70 75 74 32 20 22 22 0a       output2 "".
a860: 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 49 20      }.    set I 
a870: 5b 73 74 72 69 6e 67 20 72 65 70 65 61 74 20 22  [string repeat "
a880: 20 22 20 24 78 28 24 61 64 64 72 29 5d 0a 0a 20   " $x($addr)].. 
a890: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
a8a0: 73 74 73 20 73 74 61 72 28 24 61 64 64 72 29 5d  sts star($addr)]
a8b0: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 69 69  } {.      set ii
a8c0: 20 5b 65 78 70 72 20 24 78 28 24 73 74 61 72 28   [expr $x($star(
a8d0: 24 61 64 64 72 29 29 5d 0a 20 20 20 20 20 20 61  $addr))].      a
a8e0: 70 70 65 6e 64 20 49 20 22 20 20 22 0a 20 20 20  ppend I "  ".   
a8f0: 20 20 20 73 65 74 20 49 20 5b 73 74 72 69 6e 67     set I [string
a900: 20 72 65 70 6c 61 63 65 20 24 49 20 24 69 69 20   replace $I $ii 
a910: 24 69 69 20 2a 5d 0a 20 20 20 20 7d 0a 0a 20 20  $ii *].    }..  
a920: 20 20 73 65 74 20 63 6f 6c 20 22 22 0a 20 20 20    set col "".   
a930: 20 63 61 74 63 68 20 7b 20 73 65 74 20 63 6f 6c   catch { set col
a940: 20 24 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29   $color($opcode)
a950: 20 7d 0a 0a 20 20 20 20 6f 75 74 70 75 74 32 20   }..    output2 
a960: 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25  [format {%-4d  %
a970: 73 25 73 25 2d 31 32 2e 31 32 73 25 73 20 20 25  s%s%-12.12s%s  %
a980: 2d 36 64 20 20 25 2d 36 64 20 20 25 2d 36 64 20  -6d  %-6d  %-6d 
a990: 20 25 20 2d 31 37 73 20 25 73 20 20 25 73 7d 20   % -17s %s  %s} 
a9a0: 5c 0a 20 20 20 20 20 20 24 61 64 64 72 20 24 49  \.      $addr $I
a9b0: 20 24 63 6f 6c 20 24 6f 70 63 6f 64 65 20 24 44   $col $opcode $D
a9c0: 20 24 70 31 20 24 70 32 20 24 70 33 20 24 70 34   $p1 $p2 $p3 $p4
a9d0: 20 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20   $p5 $comment.  
a9e0: 20 20 5d 0a 20 20 7d 0a 20 20 6f 75 74 70 75 74    ].  }.  output
a9f0: 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d  2 "----  -------
aa00: 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d  -----  ------  -
aa10: 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d  -----  ------  -
aa20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20  --------------- 
aa30: 20 2d 2d 20 20 2d 22 0a 7d 0a 0a 23 20 53 68 6f   --  -".}..# Sho
aa40: 77 20 74 68 65 20 56 44 42 45 20 70 72 6f 67 72  w the VDBE progr
aa50: 61 6d 20 66 6f 72 20 61 6e 20 53 51 4c 20 73 74  am for an SQL st
aa60: 61 74 65 6d 65 6e 74 20 62 75 74 20 6f 6d 69 74  atement but omit
aa70: 20 74 68 65 20 54 72 61 63 65 0a 23 20 6f 70 63   the Trace.# opc
aa80: 6f 64 65 20 61 74 20 74 68 65 20 62 65 67 69 6e  ode at the begin
aa90: 6e 69 6e 67 2e 20 20 54 68 69 73 20 70 72 6f 63  ning.  This proc
aaa0: 65 64 75 72 65 20 63 61 6e 20 62 65 20 75 73 65  edure can be use
aab0: 64 20 74 6f 20 70 72 6f 76 65 0a 23 20 74 68 61  d to prove.# tha
aac0: 74 20 64 69 66 66 65 72 65 6e 74 20 53 51 4c 20  t different SQL 
aad0: 73 74 61 74 65 6d 65 6e 74 73 20 67 65 6e 65 72  statements gener
aae0: 61 74 65 20 65 78 61 63 74 6c 79 20 74 68 65 20  ate exactly the 
aaf0: 73 61 6d 65 20 56 44 42 45 20 63 6f 64 65 2e 0a  same VDBE code..
ab00: 23 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 5f 6e  #.proc explain_n
ab10: 6f 5f 74 72 61 63 65 20 7b 73 71 6c 7d 20 7b 0a  o_trace {sql} {.
ab20: 20 20 73 65 74 20 74 72 20 5b 64 62 20 65 76 61    set tr [db eva
ab30: 6c 20 22 45 58 50 4c 41 49 4e 20 24 73 71 6c 22  l "EXPLAIN $sql"
ab40: 5d 0a 20 20 72 65 74 75 72 6e 20 5b 6c 72 61 6e  ].  return [lran
ab50: 67 65 20 24 74 72 20 37 20 65 6e 64 5d 0a 7d 0a  ge $tr 7 end].}.
ab60: 0a 23 20 41 6e 6f 74 68 65 72 20 70 72 6f 63 65  .# Another proce
ab70: 64 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20  dure to execute 
ab80: 53 51 4c 2e 20 20 54 68 69 73 20 6f 6e 65 20 69  SQL.  This one i
ab90: 6e 63 6c 75 64 65 73 20 74 68 65 20 66 69 65 6c  ncludes the fiel
aba0: 64 0a 23 20 6e 61 6d 65 73 20 69 6e 20 74 68 65  d.# names in the
abb0: 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a   returned list..
abc0: 23 0a 70 72 6f 63 20 65 78 65 63 73 71 6c 32 20  #.proc execsql2 
abd0: 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 72 65  {sql} {.  set re
abe0: 73 75 6c 74 20 7b 7d 0a 20 20 64 62 20 65 76 61  sult {}.  db eva
abf0: 6c 20 24 73 71 6c 20 64 61 74 61 20 7b 0a 20 20  l $sql data {.  
ac00: 20 20 66 6f 72 65 61 63 68 20 66 20 24 64 61 74    foreach f $dat
ac10: 61 28 2a 29 20 7b 0a 20 20 20 20 20 20 6c 61 70  a(*) {.      lap
ac20: 70 65 6e 64 20 72 65 73 75 6c 74 20 24 66 20 24  pend result $f $
ac30: 64 61 74 61 28 24 66 29 0a 20 20 20 20 7d 0a 20  data($f).    }. 
ac40: 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73   }.  return $res
ac50: 75 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 61 20 74  ult.}..# Use a t
ac60: 65 6d 70 6f 72 61 72 79 20 69 6e 2d 6d 65 6d 6f  emporary in-memo
ac70: 72 79 20 64 61 74 61 62 61 73 65 20 74 6f 20 65  ry database to e
ac80: 78 65 63 75 74 65 20 53 51 4c 20 73 74 61 74 65  xecute SQL state
ac90: 6d 65 6e 74 73 0a 23 0a 70 72 6f 63 20 6d 65 6d  ments.#.proc mem
aca0: 64 62 73 71 6c 20 7b 73 71 6c 7d 20 7b 0a 20 20  dbsql {sql} {.  
acb0: 73 71 6c 69 74 65 33 20 6d 65 6d 64 62 20 3a 6d  sqlite3 memdb :m
acc0: 65 6d 6f 72 79 3a 0a 20 20 73 65 74 20 72 65 73  emory:.  set res
acd0: 75 6c 74 20 5b 6d 65 6d 64 62 20 65 76 61 6c 20  ult [memdb eval 
ace0: 24 73 71 6c 5d 0a 20 20 6d 65 6d 64 62 20 63 6c  $sql].  memdb cl
acf0: 6f 73 65 0a 20 20 72 65 74 75 72 6e 20 24 72 65  ose.  return $re
ad00: 73 75 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 74 68  sult.}..# Use th
ad10: 65 20 6e 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20 41  e non-callback A
ad20: 50 49 20 74 6f 20 65 78 65 63 75 74 65 20 6d 75  PI to execute mu
ad30: 6c 74 69 70 6c 65 20 53 51 4c 20 73 74 61 74 65  ltiple SQL state
ad40: 6d 65 6e 74 73 0a 23 0a 70 72 6f 63 20 73 74 65  ments.#.proc ste
ad50: 70 73 71 6c 20 7b 64 62 70 74 72 20 73 71 6c 7d  psql {dbptr sql}
ad60: 20 7b 0a 20 20 73 65 74 20 73 71 6c 20 5b 73 74   {.  set sql [st
ad70: 72 69 6e 67 20 74 72 69 6d 20 24 73 71 6c 5d 0a  ring trim $sql].
ad80: 20 20 73 65 74 20 72 20 30 0a 20 20 77 68 69 6c    set r 0.  whil
ad90: 65 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74  e {[string lengt
ada0: 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20  h $sql]>0} {.   
adb0: 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c   if {[catch {sql
adc0: 69 74 65 33 5f 70 72 65 70 61 72 65 20 24 64 62  ite3_prepare $db
add0: 70 74 72 20 24 73 71 6c 20 2d 31 20 73 71 6c 74  ptr $sql -1 sqlt
ade0: 61 69 6c 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20 20  ail} vm]} {.    
adf0: 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31    return [list 1
ae00: 20 24 76 6d 5d 0a 20 20 20 20 7d 0a 20 20 20 20   $vm].    }.    
ae10: 73 65 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20  set sql [string 
ae20: 74 72 69 6d 20 24 73 71 6c 74 61 69 6c 5d 0a 23  trim $sqltail].#
ae30: 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69      while {[sqli
ae40: 74 65 5f 73 74 65 70 20 24 76 6d 20 4e 20 56 41  te_step $vm N VA
ae50: 4c 20 43 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f  L COL]=="SQLITE_
ae60: 52 4f 57 22 7d 20 7b 0a 23 20 20 20 20 20 20 66  ROW"} {.#      f
ae70: 6f 72 65 61 63 68 20 76 20 24 56 41 4c 20 7b 6c  oreach v $VAL {l
ae80: 61 70 70 65 6e 64 20 72 20 24 76 7d 0a 23 20 20  append r $v}.#  
ae90: 20 20 7d 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b    }.    while {[
aea0: 73 71 6c 69 74 65 33 5f 73 74 65 70 20 24 76 6d  sqlite3_step $vm
aeb0: 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d  ]=="SQLITE_ROW"}
aec0: 20 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65   {.      for {se
aed0: 74 20 69 20 30 7d 20 7b 24 69 3c 5b 73 71 6c 69  t i 0} {$i<[sqli
aee0: 74 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 20 24  te3_data_count $
aef0: 76 6d 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a  vm]} {incr i} {.
af00: 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20          lappend 
af10: 72 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r [sqlite3_colum
af20: 6e 5f 74 65 78 74 20 24 76 6d 20 24 69 5d 0a 20  n_text $vm $i]. 
af30: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
af40: 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c   if {[catch {sql
af50: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 76  ite3_finalize $v
af60: 6d 7d 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20  m} errmsg]} {.  
af70: 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74      return [list
af80: 20 31 20 24 65 72 72 6d 73 67 5d 0a 20 20 20 20   1 $errmsg].    
af90: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  }.  }.  return $
afa0: 72 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 69 6e 74  r.}..# Do an int
afb0: 65 67 72 69 74 79 20 63 68 65 63 6b 20 6f 66 20  egrity check of 
afc0: 74 68 65 20 65 6e 74 69 72 65 20 64 61 74 61 62  the entire datab
afd0: 61 73 65 0a 23 0a 70 72 6f 63 20 69 6e 74 65 67  ase.#.proc integ
afe0: 72 69 74 79 5f 63 68 65 63 6b 20 7b 6e 61 6d 65  rity_check {name
aff0: 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66   {db db}} {.  if
b000: 63 61 70 61 62 6c 65 20 69 6e 74 65 67 72 69 74  capable integrit
b010: 79 63 6b 20 7b 0a 20 20 20 20 64 6f 5f 74 65 73  yck {.    do_tes
b020: 74 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20 65 78  t $name [list ex
b030: 65 63 73 71 6c 20 7b 50 52 41 47 4d 41 20 69 6e  ecsql {PRAGMA in
b040: 74 65 67 72 69 74 79 5f 63 68 65 63 6b 7d 20 24  tegrity_check} $
b050: 64 62 5d 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a  db] {ok}.  }.}..
b060: 23 20 43 68 65 63 6b 20 74 68 65 20 65 78 74 65  # Check the exte
b070: 6e 64 65 64 20 65 72 72 6f 72 20 63 6f 64 65 0a  nded error code.
b080: 23 0a 70 72 6f 63 20 76 65 72 69 66 79 5f 65 78  #.proc verify_ex
b090: 5f 65 72 72 63 6f 64 65 20 7b 6e 61 6d 65 20 65  _errcode {name e
b0a0: 78 70 65 63 74 65 64 20 7b 64 62 20 64 62 7d 7d  xpected {db db}}
b0b0: 20 7b 0a 20 20 64 6f 5f 74 65 73 74 20 24 6e 61   {.  do_test $na
b0c0: 6d 65 20 5b 6c 69 73 74 20 73 71 6c 69 74 65 33  me [list sqlite3
b0d0: 5f 65 78 74 65 6e 64 65 64 5f 65 72 72 63 6f 64  _extended_errcod
b0e0: 65 20 24 64 62 5d 20 24 65 78 70 65 63 74 65 64  e $db] $expected
b0f0: 0a 7d 0a 0a 0a 23 20 52 65 74 75 72 6e 20 74 72  .}...# Return tr
b100: 75 65 20 69 66 20 74 68 65 20 53 51 4c 20 73 74  ue if the SQL st
b110: 61 74 65 6d 65 6e 74 20 70 61 73 73 65 64 20 61  atement passed a
b120: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
b130: 75 6d 65 6e 74 20 75 73 65 73 20 61 0a 23 20 73  ument uses a.# s
b140: 74 61 74 65 6d 65 6e 74 20 74 72 61 6e 73 61 63  tatement transac
b150: 74 69 6f 6e 2e 0a 23 0a 70 72 6f 63 20 73 71 6c  tion..#.proc sql
b160: 5f 75 73 65 73 5f 73 74 6d 74 20 7b 64 62 20 73  _uses_stmt {db s
b170: 71 6c 7d 20 7b 0a 20 20 73 65 74 20 73 74 6d 74  ql} {.  set stmt
b180: 20 5b 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72   [sqlite3_prepar
b190: 65 20 24 64 62 20 24 73 71 6c 20 2d 31 20 64 75  e $db $sql -1 du
b1a0: 6d 6d 79 5d 0a 20 20 73 65 74 20 75 73 65 73 20  mmy].  set uses 
b1b0: 5b 75 73 65 73 5f 73 74 6d 74 5f 6a 6f 75 72 6e  [uses_stmt_journ
b1c0: 61 6c 20 24 73 74 6d 74 5d 0a 20 20 73 71 6c 69  al $stmt].  sqli
b1d0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 73 74  te3_finalize $st
b1e0: 6d 74 0a 20 20 72 65 74 75 72 6e 20 24 75 73 65  mt.  return $use
b1f0: 73 0a 7d 0a 0a 70 72 6f 63 20 66 69 78 5f 69 66  s.}..proc fix_if
b200: 63 61 70 61 62 6c 65 5f 65 78 70 72 20 7b 65 78  capable_expr {ex
b210: 70 72 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20  pr} {.  set ret 
b220: 22 22 0a 20 20 73 65 74 20 73 74 61 74 65 20 30  "".  set state 0
b230: 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d  .  for {set i 0}
b240: 20 7b 24 69 20 3c 20 5b 73 74 72 69 6e 67 20 6c   {$i < [string l
b250: 65 6e 67 74 68 20 24 65 78 70 72 5d 7d 20 7b 69  ength $expr]} {i
b260: 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 73 65 74  ncr i} {.    set
b270: 20 63 68 61 72 20 5b 73 74 72 69 6e 67 20 72 61   char [string ra
b280: 6e 67 65 20 24 65 78 70 72 20 24 69 20 24 69 5d  nge $expr $i $i]
b290: 0a 20 20 20 20 73 65 74 20 6e 65 77 73 74 61 74  .    set newstat
b2a0: 65 20 5b 65 78 70 72 20 7b 5b 73 74 72 69 6e 67  e [expr {[string
b2b0: 20 69 73 20 61 6c 6e 75 6d 20 24 63 68 61 72 5d   is alnum $char]
b2c0: 20 7c 7c 20 24 63 68 61 72 20 65 71 20 22 5f 22   || $char eq "_"
b2d0: 7d 5d 0a 20 20 20 20 69 66 20 7b 24 6e 65 77 73  }].    if {$news
b2e0: 74 61 74 65 20 26 26 20 21 24 73 74 61 74 65 7d  tate && !$state}
b2f0: 20 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20   {.      append 
b300: 72 65 74 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f  ret {$::sqlite_o
b310: 70 74 69 6f 6e 73 28 7d 0a 20 20 20 20 7d 0a 20  ptions(}.    }. 
b320: 20 20 20 69 66 20 7b 21 24 6e 65 77 73 74 61 74     if {!$newstat
b330: 65 20 26 26 20 24 73 74 61 74 65 7d 20 7b 0a 20  e && $state} {. 
b340: 20 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20       append ret 
b350: 29 0a 20 20 20 20 7d 0a 20 20 20 20 61 70 70 65  ).    }.    appe
b360: 6e 64 20 72 65 74 20 24 63 68 61 72 0a 20 20 20  nd ret $char.   
b370: 20 73 65 74 20 73 74 61 74 65 20 24 6e 65 77 73   set state $news
b380: 74 61 74 65 0a 20 20 7d 0a 20 20 69 66 20 7b 24  tate.  }.  if {$
b390: 73 74 61 74 65 7d 20 7b 61 70 70 65 6e 64 20 72  state} {append r
b3a0: 65 74 20 29 7d 0a 20 20 72 65 74 75 72 6e 20 24  et )}.  return $
b3b0: 72 65 74 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 73  ret.}..# Returns
b3c0: 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68 65   non-zero if the
b3d0: 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 61 72   capabilities ar
b3e0: 65 20 70 72 65 73 65 6e 74 3b 20 7a 65 72 6f 20  e present; zero 
b3f0: 6f 74 68 65 72 77 69 73 65 2e 0a 23 0a 70 72 6f  otherwise..#.pro
b400: 63 20 63 61 70 61 62 6c 65 20 7b 65 78 70 72 7d  c capable {expr}
b410: 20 7b 0a 20 20 73 65 74 20 65 20 5b 66 69 78 5f   {.  set e [fix_
b420: 69 66 63 61 70 61 62 6c 65 5f 65 78 70 72 20 24  ifcapable_expr $
b430: 65 78 70 72 5d 3b 20 72 65 74 75 72 6e 20 5b 65  expr]; return [e
b440: 78 70 72 20 28 24 65 29 5d 0a 7d 0a 0a 23 20 45  xpr ($e)].}..# E
b450: 76 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c 65 61  valuate a boolea
b460: 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 6f 66 20  n expression of 
b470: 63 61 70 61 62 69 6c 69 74 69 65 73 2e 20 20 49  capabilities.  I
b480: 66 20 74 72 75 65 2c 20 65 78 65 63 75 74 65 20  f true, execute 
b490: 74 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f 6d 69  the.# code.  Omi
b4a0: 74 20 74 68 65 20 63 6f 64 65 20 69 66 20 66 61  t the code if fa
b4b0: 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66 63 61  lse..#.proc ifca
b4c0: 70 61 62 6c 65 20 7b 65 78 70 72 20 63 6f 64 65  pable {expr code
b4d0: 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c 73 65   {else ""} {else
b4e0: 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20 23 72  code ""}} {.  #r
b4f0: 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61 2d 7a  egsub -all {[a-z
b500: 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20 7b 24  _0-9]+} $expr {$
b510: 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73  ::sqlite_options
b520: 28 26 29 7d 20 65 32 0a 20 20 73 65 74 20 65 32  (&)} e2.  set e2
b530: 20 5b 66 69 78 5f 69 66 63 61 70 61 62 6c 65 5f   [fix_ifcapable_
b540: 65 78 70 72 20 24 65 78 70 72 5d 0a 20 20 69 66  expr $expr].  if
b550: 20 28 24 65 32 29 20 7b 0a 20 20 20 20 73 65 74   ($e2) {.    set
b560: 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c 65 76   c [catch {uplev
b570: 65 6c 20 31 20 24 63 6f 64 65 7d 20 72 5d 0a 20  el 1 $code} r]. 
b580: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
b590: 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c 65  t c [catch {uple
b5a0: 76 65 6c 20 31 20 24 65 6c 73 65 63 6f 64 65 7d  vel 1 $elsecode}
b5b0: 20 72 5d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   r].  }.  return
b5c0: 20 2d 63 6f 64 65 20 24 63 20 24 72 0a 7d 0a 0a   -code $c $r.}..
b5d0: 23 20 54 68 69 73 20 70 72 6f 63 20 65 78 65 63  # This proc exec
b5e0: 73 20 61 20 73 65 70 65 72 61 74 65 20 70 72 6f  s a seperate pro
b5f0: 63 65 73 73 20 74 68 61 74 20 63 72 61 73 68 65  cess that crashe
b600: 73 20 6d 69 64 77 61 79 20 74 68 72 6f 75 67 68  s midway through
b610: 20 65 78 65 63 75 74 69 6e 67 0a 23 20 74 68 65   executing.# the
b620: 20 53 51 4c 20 73 63 72 69 70 74 20 24 73 71 6c   SQL script $sql
b630: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74 65 73   on database tes
b640: 74 2e 64 62 2e 0a 23 0a 23 20 54 68 65 20 63 72  t.db..#.# The cr
b650: 61 73 68 20 6f 63 63 75 72 73 20 64 75 72 69 6e  ash occurs durin
b660: 67 20 61 20 73 79 6e 63 28 29 20 6f 66 20 66 69  g a sync() of fi
b670: 6c 65 20 24 63 72 61 73 68 66 69 6c 65 2e 20 57  le $crashfile. W
b680: 68 65 6e 20 74 68 65 20 63 72 61 73 68 0a 23 20  hen the crash.# 
b690: 6f 63 63 75 72 73 20 61 20 72 61 6e 64 6f 6d 20  occurs a random 
b6a0: 73 75 62 73 65 74 20 6f 66 20 61 6c 6c 20 75 6e  subset of all un
b6b0: 73 79 6e 63 65 64 20 77 72 69 74 65 73 20 6d 61  synced writes ma
b6c0: 64 65 20 62 79 20 74 68 65 20 70 72 6f 63 65 73  de by the proces
b6d0: 73 20 61 72 65 0a 23 20 77 72 69 74 74 65 6e 20  s are.# written 
b6e0: 69 6e 74 6f 20 74 68 65 20 66 69 6c 65 73 20 6f  into the files o
b6f0: 6e 20 64 69 73 6b 2e 20 41 72 67 75 6d 65 6e 74  n disk. Argument
b700: 20 24 63 72 61 73 68 64 65 6c 61 79 20 69 6e 64   $crashdelay ind
b710: 69 63 61 74 65 73 20 74 68 65 0a 23 20 6e 75 6d  icates the.# num
b720: 62 65 72 20 6f 66 20 66 69 6c 65 20 73 79 6e 63  ber of file sync
b730: 73 20 74 6f 20 77 61 69 74 20 62 65 66 6f 72 65  s to wait before
b740: 20 63 72 61 73 68 69 6e 67 2e 0a 23 0a 23 20 54   crashing..#.# T
b750: 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20  he return value 
b760: 69 73 20 61 20 6c 69 73 74 20 6f 66 20 74 77 6f  is a list of two
b770: 20 65 6c 65 6d 65 6e 74 73 2e 20 54 68 65 20 66   elements. The f
b780: 69 72 73 74 20 65 6c 65 6d 65 6e 74 20 69 73 20  irst element is 
b790: 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20 69 6e 64  a.# boolean, ind
b7a0: 69 63 61 74 69 6e 67 20 77 68 65 74 68 65 72 20  icating whether 
b7b0: 6f 72 20 6e 6f 74 20 74 68 65 20 70 72 6f 63 65  or not the proce
b7c0: 73 73 20 61 63 74 75 61 6c 6c 79 20 63 72 61 73  ss actually cras
b7d0: 68 65 64 20 6f 72 0a 23 20 72 65 70 6f 72 74 65  hed or.# reporte
b7e0: 64 20 73 6f 6d 65 20 6f 74 68 65 72 20 65 72 72  d some other err
b7f0: 6f 72 2e 20 54 68 65 20 73 65 63 6f 6e 64 20 65  or. The second e
b800: 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 72 65  lement in the re
b810: 74 75 72 6e 65 64 20 6c 69 73 74 20 69 73 20 74  turned list is t
b820: 68 65 0a 23 20 65 72 72 6f 72 20 6d 65 73 73 61  he.# error messa
b830: 67 65 2e 20 54 68 69 73 20 69 73 20 22 63 68 69  ge. This is "chi
b840: 6c 64 20 70 72 6f 63 65 73 73 20 65 78 69 74 65  ld process exite
b850: 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 20 69 66  d abnormally" if
b860: 20 74 68 65 20 63 72 61 73 68 0a 23 20 6f 63 63   the crash.# occ
b870: 75 72 72 65 64 2e 0a 23 0a 23 20 20 20 63 72 61  urred..#.#   cra
b880: 73 68 73 71 6c 20 2d 64 65 6c 61 79 20 43 52 41  shsql -delay CRA
b890: 53 48 44 45 4c 41 59 20 2d 66 69 6c 65 20 43 52  SHDELAY -file CR
b8a0: 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f 63 6b 73  ASHFILE ?-blocks
b8b0: 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45 3f 20 24  ize BLOCKSIZE? $
b8c0: 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72 61 73 68  sql.#.proc crash
b8d0: 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a 0a 20 20  sql {args} {..  
b8e0: 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22 22  set blocksize ""
b8f0: 0a 20 20 73 65 74 20 63 72 61 73 68 64 65 6c 61  .  set crashdela
b900: 79 20 31 0a 20 20 73 65 74 20 70 72 6e 67 73 65  y 1.  set prngse
b910: 65 64 20 30 0a 20 20 73 65 74 20 6f 70 65 6e 64  ed 0.  set opend
b920: 62 20 7b 20 73 71 6c 69 74 65 33 20 64 62 20 74  b { sqlite3 db t
b930: 65 73 74 2e 64 62 20 2d 76 66 73 20 63 72 61 73  est.db -vfs cras
b940: 68 20 7d 0a 20 20 73 65 74 20 74 63 6c 62 6f 64  h }.  set tclbod
b950: 79 20 7b 7d 0a 20 20 73 65 74 20 63 72 61 73 68  y {}.  set crash
b960: 66 69 6c 65 20 22 22 0a 20 20 73 65 74 20 64 63  file "".  set dc
b970: 20 22 22 0a 20 20 73 65 74 20 64 66 6c 74 76 66   "".  set dfltvf
b980: 73 20 30 0a 20 20 73 65 74 20 73 71 6c 20 5b 6c  s 0.  set sql [l
b990: 69 6e 64 65 78 20 24 61 72 67 73 20 65 6e 64 5d  index $args end]
b9a0: 0a 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 69 20  ..  for {set ii 
b9b0: 30 7d 20 7b 24 69 69 20 3c 20 5b 6c 6c 65 6e 67  0} {$ii < [lleng
b9c0: 74 68 20 24 61 72 67 73 5d 2d 31 7d 20 7b 69 6e  th $args]-1} {in
b9d0: 63 72 20 69 69 20 32 7d 20 7b 0a 20 20 20 20 73  cr ii 2} {.    s
b9e0: 65 74 20 7a 20 5b 6c 69 6e 64 65 78 20 24 61 72  et z [lindex $ar
b9f0: 67 73 20 24 69 69 5d 0a 20 20 20 20 73 65 74 20  gs $ii].    set 
ba00: 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68  n [string length
ba10: 20 24 7a 5d 0a 20 20 20 20 73 65 74 20 7a 32 20   $z].    set z2 
ba20: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 5b 65  [lindex $args [e
ba30: 78 70 72 20 24 69 69 2b 31 5d 5d 0a 0a 20 20 20  xpr $ii+1]]..   
ba40: 20 69 66 20 20 20 20 20 7b 24 6e 3e 31 20 26 26   if     {$n>1 &&
ba50: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
ba60: 7a 20 2d 64 65 6c 61 79 5d 3d 3d 30 7d 20 20 20  z -delay]==0}   
ba70: 20 20 7b 73 65 74 20 63 72 61 73 68 64 65 6c 61    {set crashdela
ba80: 79 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73  y $z2} \.    els
ba90: 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74  eif {$n>1 && [st
baa0: 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 6f  ring first $z -o
bab0: 70 65 6e 64 62 5d 3d 3d 30 7d 20 20 20 20 7b 73  pendb]==0}    {s
bac0: 65 74 20 6f 70 65 6e 64 62 20 24 7a 32 7d 20 5c  et opendb $z2} \
bad0: 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e  .    elseif {$n>
bae0: 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72  1 && [string fir
baf0: 73 74 20 24 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d  st $z -seed]==0}
bb00: 20 20 20 20 20 20 7b 73 65 74 20 70 72 6e 67 73        {set prngs
bb10: 65 65 64 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65  eed $z2} \.    e
bb20: 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b  lseif {$n>1 && [
bb30: 73 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20  string first $z 
bb40: 2d 66 69 6c 65 5d 3d 3d 30 7d 20 20 20 20 20 20  -file]==0}      
bb50: 7b 73 65 74 20 63 72 61 73 68 66 69 6c 65 20 24  {set crashfile $
bb60: 7a 32 7d 20 20 5c 0a 20 20 20 20 65 6c 73 65 69  z2}  \.    elsei
bb70: 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69  f {$n>1 && [stri
bb80: 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 74 63 6c  ng first $z -tcl
bb90: 62 6f 64 79 5d 3d 3d 30 7d 20 20 20 7b 73 65 74  body]==0}   {set
bba0: 20 74 63 6c 62 6f 64 79 20 24 7a 32 7d 20 20 5c   tclbody $z2}  \
bbb0: 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e  .    elseif {$n>
bbc0: 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72  1 && [string fir
bbd0: 73 74 20 24 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65  st $z -blocksize
bbe0: 5d 3d 3d 30 7d 20 7b 73 65 74 20 62 6c 6f 63 6b  ]==0} {set block
bbf0: 73 69 7a 65 20 22 2d 73 20 24 7a 32 22 20 7d 20  size "-s $z2" } 
bc00: 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e  \.    elseif {$n
bc10: 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69  >1 && [string fi
bc20: 72 73 74 20 24 7a 20 2d 63 68 61 72 61 63 74 65  rst $z -characte
bc30: 72 69 73 74 69 63 73 5d 3d 3d 30 7d 20 7b 73 65  ristics]==0} {se
bc40: 74 20 64 63 20 22 2d 63 20 7b 24 7a 32 7d 22 20  t dc "-c {$z2}" 
bc50: 7d 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24  }\.    elseif {$
bc60: 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66  n>1 && [string f
bc70: 69 72 73 74 20 24 7a 20 2d 64 66 6c 74 76 66 73  irst $z -dfltvfs
bc80: 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 66 6c 74 76  ]==0} {set dfltv
bc90: 66 73 20 24 7a 32 20 7d 5c 0a 20 20 20 20 65 6c  fs $z2 }\.    el
bca0: 73 65 20 20 20 7b 20 65 72 72 6f 72 20 22 55 6e  se   { error "Un
bcb0: 72 65 63 6f 67 6e 69 7a 65 64 20 6f 70 74 69 6f  recognized optio
bcc0: 6e 3a 20 24 7a 22 20 7d 0a 20 20 7d 0a 0a 20 20  n: $z" }.  }..  
bcd0: 69 66 20 7b 24 63 72 61 73 68 66 69 6c 65 20 65  if {$crashfile e
bce0: 71 20 22 22 7d 20 7b 0a 20 20 20 20 65 72 72 6f  q ""} {.    erro
bcf0: 72 20 22 43 6f 6d 70 75 6c 73 6f 72 79 20 6f 70  r "Compulsory op
bd00: 74 69 6f 6e 20 2d 66 69 6c 65 20 6d 69 73 73 69  tion -file missi
bd10: 6e 67 22 0a 20 20 7d 0a 0a 20 20 23 20 24 63 72  ng".  }..  # $cr
bd20: 61 73 68 66 69 6c 65 20 67 65 74 73 20 63 6f 6d  ashfile gets com
bd30: 70 61 72 65 64 20 74 6f 20 74 68 65 20 6e 61 74  pared to the nat
bd40: 69 76 65 20 66 69 6c 65 6e 61 6d 65 20 69 6e 0a  ive filename in.
bd50: 20 20 23 20 63 66 53 79 6e 63 28 29 2c 20 77 68    # cfSync(), wh
bd60: 69 63 68 20 63 61 6e 20 62 65 20 64 69 66 66 65  ich can be diffe
bd70: 72 65 6e 74 20 74 68 65 6e 20 77 68 61 74 20 54  rent then what T
bd80: 43 4c 20 75 73 65 73 20 62 79 0a 20 20 23 20 64  CL uses by.  # d
bd90: 65 66 61 75 6c 74 2c 20 73 6f 20 68 65 72 65 20  efault, so here 
bda0: 77 65 20 66 6f 72 63 65 20 69 74 20 74 6f 20 74  we force it to t
bdb0: 68 65 20 22 6e 61 74 69 76 65 6e 61 6d 65 22 20  he "nativename" 
bdc0: 66 6f 72 6d 61 74 2e 0a 20 20 73 65 74 20 63 66  format..  set cf
bdd0: 69 6c 65 20 5b 73 74 72 69 6e 67 20 6d 61 70 20  ile [string map 
bde0: 7b 5c 5c 20 5c 5c 5c 5c 7d 20 5b 66 69 6c 65 20  {\\ \\\\} [file 
bdf0: 6e 61 74 69 76 65 6e 61 6d 65 20 5b 66 69 6c 65  nativename [file
be00: 20 6a 6f 69 6e 20 5b 67 65 74 5f 70 77 64 5d 20   join [get_pwd] 
be10: 24 63 72 61 73 68 66 69 6c 65 5d 5d 5d 0a 0a 20  $crashfile]]].. 
be20: 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 63 72 61   set f [open cra
be30: 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70 75 74 73  sh.tcl w].  puts
be40: 20 24 66 20 22 73 71 6c 69 74 65 33 5f 63 72 61   $f "sqlite3_cra
be50: 73 68 5f 65 6e 61 62 6c 65 20 31 20 24 64 66 6c  sh_enable 1 $dfl
be60: 74 76 66 73 22 0a 20 20 70 75 74 73 20 24 66 20  tvfs".  puts $f 
be70: 22 73 71 6c 69 74 65 33 5f 63 72 61 73 68 70 61  "sqlite3_crashpa
be80: 72 61 6d 73 20 24 62 6c 6f 63 6b 73 69 7a 65 20  rams $blocksize 
be90: 24 64 63 20 24 63 72 61 73 68 64 65 6c 61 79 20  $dc $crashdelay 
bea0: 24 63 66 69 6c 65 22 0a 20 20 70 75 74 73 20 24  $cfile".  puts $
beb0: 66 20 22 73 71 6c 69 74 65 33 5f 74 65 73 74 5f  f "sqlite3_test_
bec0: 63 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f  control_pending_
bed0: 62 79 74 65 20 24 3a 3a 73 71 6c 69 74 65 5f 70  byte $::sqlite_p
bee0: 65 6e 64 69 6e 67 5f 62 79 74 65 22 0a 0a 20 20  ending_byte"..  
bef0: 23 20 54 68 69 73 20 62 6c 6f 63 6b 20 73 65 74  # This block set
bf00: 73 20 74 68 65 20 63 61 63 68 65 20 73 69 7a 65  s the cache size
bf10: 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 64 61 74   of the main dat
bf20: 61 62 61 73 65 20 74 6f 20 31 30 0a 20 20 23 20  abase to 10.  # 
bf30: 70 61 67 65 73 2e 20 54 68 69 73 20 69 73 20 64  pages. This is d
bf40: 6f 6e 65 20 69 6e 20 63 61 73 65 20 74 68 65 20  one in case the 
bf50: 62 75 69 6c 64 20 69 73 20 63 6f 6e 66 69 67 75  build is configu
bf60: 72 65 64 20 74 6f 20 6f 6d 69 74 0a 20 20 23 20  red to omit.  # 
bf70: 22 50 52 41 47 4d 41 20 63 61 63 68 65 5f 73 69  "PRAGMA cache_si
bf80: 7a 65 22 2e 0a 20 20 69 66 20 7b 24 6f 70 65 6e  ze"..  if {$open
bf90: 64 62 21 3d 22 22 7d 20 7b 0a 20 20 20 20 70 75  db!=""} {.    pu
bfa0: 74 73 20 24 66 20 24 6f 70 65 6e 64 62 20 0a 20  ts $f $opendb . 
bfb0: 20 20 20 70 75 74 73 20 24 66 20 7b 64 62 20 65     puts $f {db e
bfc0: 76 61 6c 20 7b 53 45 4c 45 43 54 20 2a 20 46 52  val {SELECT * FR
bfd0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
bfe0: 3b 7d 7d 0a 20 20 20 20 70 75 74 73 20 24 66 20  ;}}.    puts $f 
bff0: 7b 73 65 74 20 62 74 20 5b 62 74 72 65 65 5f 66  {set bt [btree_f
c000: 72 6f 6d 5f 64 62 20 64 62 5d 7d 0a 20 20 20 20  rom_db db]}.    
c010: 70 75 74 73 20 24 66 20 7b 62 74 72 65 65 5f 73  puts $f {btree_s
c020: 65 74 5f 63 61 63 68 65 5f 73 69 7a 65 20 24 62  et_cache_size $b
c030: 74 20 31 30 7d 0a 20 20 7d 0a 0a 20 20 69 66 20  t 10}.  }..  if 
c040: 7b 24 70 72 6e 67 73 65 65 64 7d 20 7b 0a 20 20  {$prngseed} {.  
c050: 20 20 73 65 74 20 73 65 65 64 20 5b 65 78 70 72    set seed [expr
c060: 20 7b 24 70 72 6e 67 73 65 65 64 25 31 30 30 30   {$prngseed%1000
c070: 37 2b 31 7d 5d 0a 20 20 20 20 23 20 70 75 74 73  7+1}].    # puts
c080: 20 73 65 65 64 3d 24 73 65 65 64 0a 20 20 20 20   seed=$seed.    
c090: 70 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c  puts $f "db eval
c0a0: 20 7b 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62   {SELECT randomb
c0b0: 6c 6f 62 28 24 73 65 65 64 29 7d 22 0a 20 20 7d  lob($seed)}".  }
c0c0: 0a 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20  ..  if {[string 
c0d0: 6c 65 6e 67 74 68 20 24 74 63 6c 62 6f 64 79 5d  length $tclbody]
c0e0: 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24  >0} {.    puts $
c0f0: 66 20 24 74 63 6c 62 6f 64 79 0a 20 20 7d 0a 20  f $tclbody.  }. 
c100: 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e   if {[string len
c110: 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20  gth $sql]>0} {. 
c120: 20 20 20 70 75 74 73 20 24 66 20 22 64 62 20 65     puts $f "db e
c130: 76 61 6c 20 7b 22 0a 20 20 20 20 70 75 74 73 20  val {".    puts 
c140: 24 66 20 20 20 22 24 73 71 6c 22 0a 20 20 20 20  $f   "$sql".    
c150: 70 75 74 73 20 24 66 20 22 7d 22 0a 20 20 7d 0a  puts $f "}".  }.
c160: 20 20 63 6c 6f 73 65 20 24 66 0a 20 20 73 65 74    close $f.  set
c170: 20 72 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20   r [catch {.    
c180: 65 78 65 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f  exec [info nameo
c190: 66 65 78 65 63 5d 20 63 72 61 73 68 2e 74 63 6c  fexec] crash.tcl
c1a0: 20 3e 40 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73   >@stdout.  } ms
c1b0: 67 5d 0a 0a 20 20 23 20 57 69 6e 64 6f 77 73 2f  g]..  # Windows/
c1c0: 41 63 74 69 76 65 53 74 61 74 65 20 54 43 4c 20  ActiveState TCL 
c1d0: 72 65 74 75 72 6e 73 20 61 20 73 6c 69 67 68 74  returns a slight
c1e0: 6c 79 20 64 69 66 66 65 72 65 6e 74 0a 20 20 23  ly different.  #
c1f0: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e 20   error message. 
c200: 20 57 65 20 6d 61 70 20 74 68 61 74 20 74 6f 20   We map that to 
c210: 74 68 65 20 65 78 70 65 63 74 65 64 20 6d 65 73  the expected mes
c220: 73 61 67 65 0a 20 20 23 20 73 6f 20 74 68 61 74  sage.  # so that
c230: 20 77 65 20 64 6f 6e 27 74 20 68 61 76 65 20 74   we don't have t
c240: 6f 20 63 68 61 6e 67 65 20 61 6c 6c 20 6f 66 20  o change all of 
c250: 74 68 65 20 74 65 73 74 0a 20 20 23 20 63 61 73  the test.  # cas
c260: 65 73 2e 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c  es..  if {$::tcl
c270: 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f  _platform(platfo
c280: 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d 20  rm)=="windows"} 
c290: 7b 0a 20 20 20 20 69 66 20 7b 24 6d 73 67 3d 3d  {.    if {$msg==
c2a0: 22 63 68 69 6c 64 20 6b 69 6c 6c 65 64 3a 20 75  "child killed: u
c2b0: 6e 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c 22 7d 20  nknown signal"} 
c2c0: 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 73 67 20  {.      set msg 
c2d0: 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65  "child process e
c2e0: 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79  xited abnormally
c2f0: 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 6c  ".    }.  }..  l
c300: 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a 7d 0a  append r $msg.}.
c310: 0a 23 20 20 20 63 72 61 73 68 5f 6f 6e 5f 77 72  .#   crash_on_wr
c320: 69 74 65 20 3f 2d 64 65 76 63 68 61 72 20 44 45  ite ?-devchar DE
c330: 56 43 48 41 52 3f 20 43 52 41 53 48 44 45 4c 41  VCHAR? CRASHDELA
c340: 59 20 53 51 4c 0a 23 0a 70 72 6f 63 20 63 72 61  Y SQL.#.proc cra
c350: 73 68 5f 6f 6e 5f 77 72 69 74 65 20 7b 61 72 67  sh_on_write {arg
c360: 73 7d 20 7b 0a 0a 20 20 73 65 74 20 6e 41 72 67  s} {..  set nArg
c370: 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d   [llength $args]
c380: 0a 20 20 69 66 20 7b 24 6e 41 72 67 3c 32 20 7c  .  if {$nArg<2 |
c390: 7c 20 24 6e 41 72 67 25 32 7d 20 7b 0a 20 20 20  | $nArg%2} {.   
c3a0: 20 65 72 72 6f 72 20 22 62 61 64 20 61 72 67 73   error "bad args
c3b0: 3a 20 24 61 72 67 73 22 0a 20 20 7d 0a 20 20 73  : $args".  }.  s
c3c0: 65 74 20 7a 53 71 6c 20 5b 6c 69 6e 64 65 78 20  et zSql [lindex 
c3d0: 24 61 72 67 73 20 65 6e 64 5d 0a 20 20 73 65 74  $args end].  set
c3e0: 20 6e 44 65 6c 61 79 20 5b 6c 69 6e 64 65 78 20   nDelay [lindex 
c3f0: 24 61 72 67 73 20 65 6e 64 2d 31 5d 0a 0a 20 20  $args end-1]..  
c400: 73 65 74 20 64 65 76 63 68 61 72 20 7b 7d 0a 20  set devchar {}. 
c410: 20 66 6f 72 20 7b 73 65 74 20 69 69 20 30 7d 20   for {set ii 0} 
c420: 7b 24 69 69 20 3c 20 24 6e 41 72 67 2d 32 7d 20  {$ii < $nArg-2} 
c430: 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b 0a 20 20  {incr ii 2} {.  
c440: 20 20 73 65 74 20 6f 70 74 20 5b 6c 69 6e 64 65    set opt [linde
c450: 78 20 24 61 72 67 73 20 24 69 69 5d 0a 20 20 20  x $args $ii].   
c460: 20 73 77 69 74 63 68 20 2d 2d 20 5b 6c 69 6e 64   switch -- [lind
c470: 65 78 20 24 61 72 67 73 20 24 69 69 5d 20 7b 0a  ex $args $ii] {.
c480: 20 20 20 20 20 20 2d 64 65 76 63 68 61 72 20 7b        -devchar {
c490: 0a 20 20 20 20 20 20 20 20 73 65 74 20 64 65 76  .        set dev
c4a0: 63 68 61 72 20 5b 6c 69 6e 64 65 78 20 24 61 72  char [lindex $ar
c4b0: 67 73 20 5b 65 78 70 72 20 24 69 69 2b 31 5d 5d  gs [expr $ii+1]]
c4c0: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
c4d0: 64 65 66 61 75 6c 74 20 7b 20 65 72 72 6f 72 20  default { error 
c4e0: 22 75 6e 72 65 63 6f 67 6e 69 7a 65 64 20 6f 70  "unrecognized op
c4f0: 74 69 6f 6e 3a 20 24 6f 70 74 22 20 7d 0a 20 20  tion: $opt" }.  
c500: 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74 20 66    }.  }..  set f
c510: 20 5b 6f 70 65 6e 20 63 72 61 73 68 2e 74 63 6c   [open crash.tcl
c520: 20 77 5d 0a 20 20 70 75 74 73 20 24 66 20 22 73   w].  puts $f "s
c530: 71 6c 69 74 65 33 5f 63 72 61 73 68 5f 6f 6e 5f  qlite3_crash_on_
c540: 77 72 69 74 65 20 24 6e 44 65 6c 61 79 22 0a 20  write $nDelay". 
c550: 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74 65   puts $f "sqlite
c560: 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f 6c 5f 70  3_test_control_p
c570: 65 6e 64 69 6e 67 5f 62 79 74 65 20 24 3a 3a 73  ending_byte $::s
c580: 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62 79  qlite_pending_by
c590: 74 65 22 0a 20 20 70 75 74 73 20 24 66 20 22 73  te".  puts $f "s
c5a0: 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64  qlite3 db test.d
c5b0: 62 20 2d 76 66 73 20 77 72 69 74 65 63 72 61 73  b -vfs writecras
c5c0: 68 22 0a 20 20 70 75 74 73 20 24 66 20 22 64 62  h".  puts $f "db
c5d0: 20 65 76 61 6c 20 7b 24 7a 53 71 6c 7d 22 0a 20   eval {$zSql}". 
c5e0: 20 70 75 74 73 20 24 66 20 22 73 65 74 20 7b 7d   puts $f "set {}
c5f0: 20 7b 7d 22 0a 0a 20 20 63 6c 6f 73 65 20 24 66   {}"..  close $f
c600: 0a 20 20 73 65 74 20 72 20 5b 63 61 74 63 68 20  .  set r [catch 
c610: 7b 0a 20 20 20 20 65 78 65 63 20 5b 69 6e 66 6f  {.    exec [info
c620: 20 6e 61 6d 65 6f 66 65 78 65 63 5d 20 63 72 61   nameofexec] cra
c630: 73 68 2e 74 63 6c 20 3e 40 73 74 64 6f 75 74 0a  sh.tcl >@stdout.
c640: 20 20 7d 20 6d 73 67 5d 0a 0a 20 20 23 20 57 69    } msg]..  # Wi
c650: 6e 64 6f 77 73 2f 41 63 74 69 76 65 53 74 61 74  ndows/ActiveStat
c660: 65 20 54 43 4c 20 72 65 74 75 72 6e 73 20 61 20  e TCL returns a 
c670: 73 6c 69 67 68 74 6c 79 20 64 69 66 66 65 72 65  slightly differe
c680: 6e 74 0a 20 20 23 20 65 72 72 6f 72 20 6d 65 73  nt.  # error mes
c690: 73 61 67 65 2e 20 20 57 65 20 6d 61 70 20 74 68  sage.  We map th
c6a0: 61 74 20 74 6f 20 74 68 65 20 65 78 70 65 63 74  at to the expect
c6b0: 65 64 20 6d 65 73 73 61 67 65 0a 20 20 23 20 73  ed message.  # s
c6c0: 6f 20 74 68 61 74 20 77 65 20 64 6f 6e 27 74 20  o that we don't 
c6d0: 68 61 76 65 20 74 6f 20 63 68 61 6e 67 65 20 61  have to change a
c6e0: 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74 0a 20  ll of the test. 
c6f0: 20 23 20 63 61 73 65 73 2e 0a 20 20 69 66 20 7b   # cases..  if {
c700: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
c710: 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 77 69 6e 64  platform)=="wind
c720: 6f 77 73 22 7d 20 7b 0a 20 20 20 20 69 66 20 7b  ows"} {.    if {
c730: 24 6d 73 67 3d 3d 22 63 68 69 6c 64 20 6b 69 6c  $msg=="child kil
c740: 6c 65 64 3a 20 75 6e 6b 6e 6f 77 6e 20 73 69 67  led: unknown sig
c750: 6e 61 6c 22 7d 20 7b 0a 20 20 20 20 20 20 73 65  nal"} {.      se
c760: 74 20 6d 73 67 20 22 63 68 69 6c 64 20 70 72 6f  t msg "child pro
c770: 63 65 73 73 20 65 78 69 74 65 64 20 61 62 6e 6f  cess exited abno
c780: 72 6d 61 6c 6c 79 22 0a 20 20 20 20 7d 0a 20 20  rmally".    }.  
c790: 7d 0a 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24  }..  lappend r $
c7a0: 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20 72 75 6e 5f  msg.}..proc run_
c7b0: 69 6f 65 72 72 5f 70 72 65 70 20 7b 7d 20 7b 0a  ioerr_prep {} {.
c7c0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
c7d0: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
c7e0: 30 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c  0.  catch {db cl
c7f0: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
c800: 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  2 close}.  catch
c810: 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65   {forcedelete te
c820: 73 74 2e 64 62 7d 0a 20 20 63 61 74 63 68 20 7b  st.db}.  catch {
c830: 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74  forcedelete test
c840: 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 63  .db-journal}.  c
c850: 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65 74  atch {forcedelet
c860: 65 20 74 65 73 74 32 2e 64 62 7d 0a 20 20 63 61  e test2.db}.  ca
c870: 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65 74 65  tch {forcedelete
c880: 20 74 65 73 74 32 2e 64 62 2d 6a 6f 75 72 6e 61   test2.db-journa
c890: 6c 7d 0a 20 20 73 65 74 20 3a 3a 44 42 20 5b 73  l}.  set ::DB [s
c8a0: 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64  qlite3 db test.d
c8b0: 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65  b; sqlite3_conne
c8c0: 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62  ction_pointer db
c8d0: 5d 0a 20 20 73 71 6c 69 74 65 33 5f 65 78 74 65  ].  sqlite3_exte
c8e0: 6e 64 65 64 5f 72 65 73 75 6c 74 5f 63 6f 64 65  nded_result_code
c8f0: 73 20 24 3a 3a 44 42 20 24 3a 3a 69 6f 65 72 72  s $::DB $::ioerr
c900: 6f 70 74 73 28 2d 65 72 63 29 0a 20 20 69 66 20  opts(-erc).  if 
c910: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
c920: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 70 72  ioerropts(-tclpr
c930: 65 70 29 5d 7d 20 7b 0a 20 20 20 20 65 76 61 6c  ep)]} {.    eval
c940: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74   $::ioerropts(-t
c950: 63 6c 70 72 65 70 29 0a 20 20 7d 0a 20 20 69 66  clprep).  }.  if
c960: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
c970: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 70  :ioerropts(-sqlp
c980: 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 65 78 65  rep)]} {.    exe
c990: 63 73 71 6c 20 24 3a 3a 69 6f 65 72 72 6f 70 74  csql $::ioerropt
c9a0: 73 28 2d 73 71 6c 70 72 65 70 29 0a 20 20 7d 0a  s(-sqlprep).  }.
c9b0: 20 20 65 78 70 72 20 30 0a 7d 0a 0a 23 20 55 73    expr 0.}..# Us
c9c0: 61 67 65 3a 20 64 6f 5f 69 6f 65 72 72 5f 74 65  age: do_ioerr_te
c9d0: 73 74 20 3c 74 65 73 74 20 6e 75 6d 62 65 72 3e  st <test number>
c9e0: 20 3c 6f 70 74 69 6f 6e 73 2e 2e 2e 3e 0a 23 0a   <options...>.#.
c9f0: 23 20 54 68 69 73 20 70 72 6f 63 20 69 73 20 75  # This proc is u
ca00: 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  sed to implement
ca10: 20 74 65 73 74 20 63 61 73 65 73 20 74 68 61 74   test cases that
ca20: 20 63 68 65 63 6b 20 74 68 61 74 20 49 4f 20 65   check that IO e
ca30: 72 72 6f 72 73 0a 23 20 61 72 65 20 63 6f 72 72  rrors.# are corr
ca40: 65 63 74 6c 79 20 68 61 6e 64 6c 65 64 2e 20 54  ectly handled. T
ca50: 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
ca60: 74 2c 20 3c 74 65 73 74 20 6e 75 6d 62 65 72 3e  t, <test number>
ca70: 2c 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72 0a  , is an integer.
ca80: 23 20 75 73 65 64 20 74 6f 20 6e 61 6d 65 20 74  # used to name t
ca90: 68 65 20 74 65 73 74 73 20 65 78 65 63 75 74 65  he tests execute
caa0: 64 20 62 79 20 74 68 69 73 20 70 72 6f 63 2e 20  d by this proc. 
cab0: 4f 70 74 69 6f 6e 73 20 61 72 65 20 61 73 20 66  Options are as f
cac0: 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20 20 20 20  ollows:.#.#     
cad0: 2d 74 63 6c 70 72 65 70 20 20 20 20 20 20 20 20  -tclprep        
cae0: 20 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20    TCL script to 
caf0: 72 75 6e 20 74 6f 20 70 72 65 70 61 72 65 20 74  run to prepare t
cb00: 65 73 74 2e 0a 23 20 20 20 20 20 2d 73 71 6c 70  est..#     -sqlp
cb10: 72 65 70 20 20 20 20 20 20 20 20 20 20 53 51 4c  rep          SQL
cb20: 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74   script to run t
cb30: 6f 20 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a  o prepare test..
cb40: 23 20 20 20 20 20 2d 74 63 6c 62 6f 64 79 20 20  #     -tclbody  
cb50: 20 20 20 20 20 20 20 20 54 43 4c 20 73 63 72 69          TCL scri
cb60: 70 74 20 74 6f 20 72 75 6e 20 77 69 74 68 20 49  pt to run with I
cb70: 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c 61 74 69  O error simulati
cb80: 6f 6e 2e 0a 23 20 20 20 20 20 2d 73 71 6c 62 6f  on..#     -sqlbo
cb90: 64 79 20 20 20 20 20 20 20 20 20 20 54 43 4c 20  dy          TCL 
cba0: 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69  script to run wi
cbb0: 74 68 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75  th IO error simu
cbc0: 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 65  lation..#     -e
cbd0: 78 63 6c 75 64 65 20 20 20 20 20 20 20 20 20 20  xclude          
cbe0: 4c 69 73 74 20 6f 66 20 27 4e 27 20 76 61 6c 75  List of 'N' valu
cbf0: 65 73 20 6e 6f 74 20 74 6f 20 74 65 73 74 2e 0a  es not to test..
cc00: 23 20 20 20 20 20 2d 65 72 63 20 20 20 20 20 20  #     -erc      
cc10: 20 20 20 20 20 20 20 20 55 73 65 20 65 78 74 65          Use exte
cc20: 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65  nded result code
cc30: 73 0a 23 20 20 20 20 20 2d 70 65 72 73 69 73 74  s.#     -persist
cc40: 20 20 20 20 20 20 20 20 20 20 4d 61 6b 65 20 73            Make s
cc50: 69 6d 75 6c 61 74 65 64 20 49 2f 4f 20 65 72 72  imulated I/O err
cc60: 6f 72 73 20 70 65 72 73 69 73 74 65 6e 74 0a 23  ors persistent.#
cc70: 20 20 20 20 20 2d 73 74 61 72 74 20 20 20 20 20       -start     
cc80: 20 20 20 20 20 20 20 56 61 6c 75 65 20 6f 66 20         Value of 
cc90: 27 4e 27 20 74 6f 20 62 65 67 69 6e 20 77 69 74  'N' to begin wit
cca0: 68 20 28 64 65 66 61 75 6c 74 20 31 29 0a 23 0a  h (default 1).#.
ccb0: 23 20 20 20 20 20 2d 63 6b 73 75 6d 20 20 20 20  #     -cksum    
ccc0: 20 20 20 20 20 20 20 20 42 6f 6f 6c 65 61 6e 2e          Boolean.
ccd0: 20 49 66 20 74 72 75 65 2c 20 74 65 73 74 20 74   If true, test t
cce0: 68 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65  hat the database
ccf0: 20 64 6f 65 73 0a 23 20 20 20 20 20 20 20 20 20   does.#         
cd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 6f                no
cd10: 74 20 63 68 61 6e 67 65 20 64 75 72 69 6e 67 20  t change during 
cd20: 74 68 65 20 65 78 65 63 75 74 69 6f 6e 20 6f 66  the execution of
cd30: 20 74 68 65 20 74 65 73 74 20 63 61 73 65 2e 0a   the test case..
cd40: 23 0a 70 72 6f 63 20 64 6f 5f 69 6f 65 72 72 5f  #.proc do_ioerr_
cd50: 74 65 73 74 20 7b 74 65 73 74 6e 61 6d 65 20 61  test {testname a
cd60: 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 3a 3a  rgs} {..  set ::
cd70: 69 6f 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74  ioerropts(-start
cd80: 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  ) 1.  set ::ioer
cd90: 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 20 30 0a  ropts(-cksum) 0.
cda0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
cdb0: 73 28 2d 65 72 63 29 20 30 0a 20 20 73 65 74 20  s(-erc) 0.  set 
cdc0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75  ::ioerropts(-cou
cdd0: 6e 74 29 20 31 30 30 30 30 30 30 30 30 0a 20 20  nt) 100000000.  
cde0: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  set ::ioerropts(
cdf0: 2d 70 65 72 73 69 73 74 29 20 31 0a 20 20 73 65  -persist) 1.  se
ce00: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  t ::ioerropts(-c
ce10: 6b 72 65 66 63 6f 75 6e 74 29 20 30 0a 20 20 73  krefcount) 0.  s
ce20: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
ce30: 72 65 73 74 6f 72 65 70 72 6e 67 29 20 31 0a 20  restoreprng) 1. 
ce40: 20 61 72 72 61 79 20 73 65 74 20 3a 3a 69 6f 65   array set ::ioe
ce50: 72 72 6f 70 74 73 20 24 61 72 67 73 0a 0a 20 20  rropts $args..  
ce60: 23 20 54 45 4d 50 4f 52 41 52 59 3a 20 46 6f 72  # TEMPORARY: For
ce70: 20 33 2e 35 2e 39 2c 20 64 69 73 61 62 6c 65 20   3.5.9, disable 
ce80: 74 65 73 74 69 6e 67 20 6f 66 20 65 78 74 65 6e  testing of exten
ce90: 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 73  ded result codes
cea0: 2e 20 54 68 65 72 65 20 61 72 65 0a 20 20 23 20  . There are.  # 
ceb0: 61 20 63 6f 75 70 6c 65 20 6f 66 20 6f 62 73 63  a couple of obsc
cec0: 75 72 65 20 49 4f 20 65 72 72 6f 72 73 20 74 68  ure IO errors th
ced0: 61 74 20 64 6f 20 6e 6f 74 20 72 65 74 75 72 6e  at do not return
cee0: 20 74 68 65 6d 2e 0a 20 20 73 65 74 20 3a 3a 69   them..  set ::i
cef0: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 20 30  oerropts(-erc) 0
cf00: 0a 0a 20 20 23 20 43 72 65 61 74 65 20 61 20 73  ..  # Create a s
cf10: 69 6e 67 6c 65 20 54 43 4c 20 73 63 72 69 70 74  ingle TCL script
cf20: 20 66 72 6f 6d 20 74 68 65 20 54 43 4c 20 61 6e   from the TCL an
cf30: 64 20 53 51 4c 20 73 70 65 63 69 66 69 65 64 0a  d SQL specified.
cf40: 20 20 23 20 61 73 20 74 68 65 20 62 6f 64 79 20    # as the body 
cf50: 6f 66 20 74 68 65 20 74 65 73 74 2e 0a 20 20 73  of the test..  s
cf60: 65 74 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  et ::ioerrorbody
cf70: 20 7b 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20   {}.  if {[info 
cf80: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
cf90: 74 73 28 2d 74 63 6c 62 6f 64 79 29 5d 7d 20 7b  ts(-tclbody)]} {
cfa0: 0a 20 20 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f  .    append ::io
cfb0: 65 72 72 6f 72 62 6f 64 79 20 22 24 3a 3a 69 6f  errorbody "$::io
cfc0: 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79  erropts(-tclbody
cfd0: 29 5c 6e 22 0a 20 20 7d 0a 20 20 69 66 20 7b 5b  )\n".  }.  if {[
cfe0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f  info exists ::io
cff0: 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79  erropts(-sqlbody
d000: 29 5d 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64  )]} {.    append
d010: 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22   ::ioerrorbody "
d020: 64 62 20 65 76 61 6c 20 7b 24 3a 3a 69 6f 65 72  db eval {$::ioer
d030: 72 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79 29 7d  ropts(-sqlbody)}
d040: 22 0a 20 20 7d 0a 0a 20 20 73 61 76 65 5f 70 72  ".  }..  save_pr
d050: 6e 67 5f 73 74 61 74 65 0a 20 20 69 66 20 7b 24  ng_state.  if {$
d060: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73  ::ioerropts(-cks
d070: 75 6d 29 7d 20 7b 0a 20 20 20 20 72 75 6e 5f 69  um)} {.    run_i
d080: 6f 65 72 72 5f 70 72 65 70 0a 20 20 20 20 65 76  oerr_prep.    ev
d090: 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 72 62 6f 64  al $::ioerrorbod
d0a0: 79 0a 20 20 20 20 73 65 74 20 3a 3a 67 6f 6f 64  y.    set ::good
d0b0: 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20  cksum [cksum].  
d0c0: 7d 0a 0a 20 20 73 65 74 20 3a 3a 67 6f 20 31 0a  }..  set ::go 1.
d0d0: 20 20 23 72 65 73 65 74 5f 70 72 6e 67 5f 73 74    #reset_prng_st
d0e0: 61 74 65 0a 20 20 66 6f 72 20 7b 73 65 74 20 6e  ate.  for {set n
d0f0: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73   $::ioerropts(-s
d100: 74 61 72 74 29 7d 20 7b 24 3a 3a 67 6f 7d 20 7b  tart)} {$::go} {
d110: 69 6e 63 72 20 6e 7d 20 7b 0a 20 20 20 20 73 65  incr n} {.    se
d120: 74 20 3a 3a 54 4e 20 24 6e 0a 20 20 20 20 69 6e  t ::TN $n.    in
d130: 63 72 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  cr ::ioerropts(-
d140: 63 6f 75 6e 74 29 20 2d 31 0a 20 20 20 20 69 66  count) -1.    if
d150: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
d160: 63 6f 75 6e 74 29 3c 30 7d 20 62 72 65 61 6b 0a  count)<0} break.
d170: 0a 20 20 20 20 23 20 53 6b 69 70 20 74 68 69 73  .    # Skip this
d180: 20 49 4f 20 65 72 72 6f 72 20 69 66 20 69 74 20   IO error if it 
d190: 77 61 73 20 73 70 65 63 69 66 69 65 64 20 77 69  was specified wi
d1a0: 74 68 20 74 68 65 20 22 2d 65 78 63 6c 75 64 65  th the "-exclude
d1b0: 22 20 6f 70 74 69 6f 6e 2e 0a 20 20 20 20 69 66  " option..    if
d1c0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
d1d0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78 63 6c  :ioerropts(-excl
d1e0: 75 64 65 29 5d 7d 20 7b 0a 20 20 20 20 20 20 69  ude)]} {.      i
d1f0: 66 20 7b 5b 6c 73 65 61 72 63 68 20 24 3a 3a 69  f {[lsearch $::i
d200: 6f 65 72 72 6f 70 74 73 28 2d 65 78 63 6c 75 64  oerropts(-exclud
d210: 65 29 20 24 6e 5d 21 3d 2d 31 7d 20 63 6f 6e 74  e) $n]!=-1} cont
d220: 69 6e 75 65 0a 20 20 20 20 7d 0a 20 20 20 20 69  inue.    }.    i
d230: 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  f {$::ioerropts(
d240: 2d 72 65 73 74 6f 72 65 70 72 6e 67 29 7d 20 7b  -restoreprng)} {
d250: 0a 20 20 20 20 20 20 72 65 73 74 6f 72 65 5f 70  .      restore_p
d260: 72 6e 67 5f 73 74 61 74 65 0a 20 20 20 20 7d 0a  rng_state.    }.
d270: 0a 20 20 20 20 23 20 44 65 6c 65 74 65 20 74 68  .    # Delete th
d280: 65 20 66 69 6c 65 73 20 74 65 73 74 2e 64 62 20  e files test.db 
d290: 61 6e 64 20 74 65 73 74 32 2e 64 62 2c 20 74 68  and test2.db, th
d2a0: 65 6e 20 65 78 65 63 75 74 65 20 74 68 65 20 54  en execute the T
d2b0: 43 4c 20 61 6e 64 0a 20 20 20 20 23 20 53 51 4c  CL and.    # SQL
d2c0: 20 28 69 6e 20 74 68 61 74 20 6f 72 64 65 72 29   (in that order)
d2d0: 20 74 6f 20 70 72 65 70 61 72 65 20 66 6f 72 20   to prepare for 
d2e0: 74 68 65 20 74 65 73 74 20 63 61 73 65 2e 0a 20  the test case.. 
d2f0: 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74     do_test $test
d300: 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a 20 20 20 20  name.$n.1 {.    
d310: 20 20 72 75 6e 5f 69 6f 65 72 72 5f 70 72 65 70    run_ioerr_prep
d320: 0a 20 20 20 20 7d 20 7b 30 7d 0a 0a 20 20 20 20  .    } {0}..    
d330: 23 20 52 65 61 64 20 74 68 65 20 27 63 68 65 63  # Read the 'chec
d340: 6b 73 75 6d 27 20 6f 66 20 74 68 65 20 64 61 74  ksum' of the dat
d350: 61 62 61 73 65 2e 0a 20 20 20 20 69 66 20 7b 24  abase..    if {$
d360: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73  ::ioerropts(-cks
d370: 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  um)} {.      set
d380: 20 3a 3a 63 68 65 63 6b 73 75 6d 20 5b 63 6b 73   ::checksum [cks
d390: 75 6d 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23  um].    }..    #
d3a0: 20 53 65 74 20 74 68 65 20 4e 74 68 20 49 4f 20   Set the Nth IO 
d3b0: 65 72 72 6f 72 20 74 6f 20 66 61 69 6c 2e 0a 20  error to fail.. 
d3c0: 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74     do_test $test
d3d0: 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73 75 62 73 74  name.$n.2 [subst
d3e0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73   {.      set ::s
d3f0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
d400: 65 72 73 69 73 74 20 24 3a 3a 69 6f 65 72 72 6f  ersist $::ioerro
d410: 70 74 73 28 2d 70 65 72 73 69 73 74 29 0a 20 20  pts(-persist).  
d420: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
d430: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e  _io_error_pendin
d440: 67 20 24 6e 0a 20 20 20 20 7d 5d 20 24 6e 0a 0a  g $n.    }] $n..
d450: 20 20 20 20 23 20 45 78 65 63 75 74 65 20 74 68      # Execute th
d460: 65 20 54 43 4c 20 73 63 72 69 70 74 20 63 72 65  e TCL script cre
d470: 61 74 65 64 20 66 6f 72 20 74 68 65 20 62 6f 64  ated for the bod
d480: 79 20 6f 66 20 74 68 69 73 20 74 65 73 74 2e 20  y of this test. 
d490: 49 66 0a 20 20 20 20 23 20 61 74 20 6c 65 61 73  If.    # at leas
d4a0: 74 20 4e 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e  t N IO operation
d4b0: 73 20 70 65 72 66 6f 72 6d 65 64 20 62 79 20 53  s performed by S
d4c0: 51 4c 69 74 65 20 61 73 20 61 20 72 65 73 75 6c  QLite as a resul
d4d0: 74 20 6f 66 0a 20 20 20 20 23 20 74 68 65 20 73  t of.    # the s
d4e0: 63 72 69 70 74 2c 20 74 68 65 20 4e 74 68 20 77  cript, the Nth w
d4f0: 69 6c 6c 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f  ill fail..    do
d500: 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e  _test $testname.
d510: 24 6e 2e 33 20 7b 0a 20 20 20 20 20 20 73 65 74  $n.3 {.      set
d520: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
d530: 6f 72 5f 68 69 74 20 30 0a 20 20 20 20 20 20 73  or_hit 0.      s
d540: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  et ::sqlite_io_e
d550: 72 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a 20  rror_hardhit 0. 
d560: 20 20 20 20 20 73 65 74 20 72 20 5b 63 61 74 63       set r [catc
d570: 68 20 24 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  h $::ioerrorbody
d580: 20 6d 73 67 5d 0a 20 20 20 20 20 20 73 65 74 20   msg].      set 
d590: 3a 3a 65 72 72 73 65 65 6e 20 24 72 0a 20 20 20  ::errseen $r.   
d5a0: 20 20 20 73 65 74 20 72 63 20 5b 73 71 6c 69 74     set rc [sqlit
d5b0: 65 33 5f 65 72 72 63 6f 64 65 20 24 3a 3a 44 42  e3_errcode $::DB
d5c0: 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 69  ].      if {$::i
d5d0: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 7d 20  oerropts(-erc)} 
d5e0: 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 77  {.        # If w
d5f0: 65 20 61 72 65 20 69 6e 20 65 78 74 65 6e 64 65  e are in extende
d600: 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f  d result code mo
d610: 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 61 6c  de, make sure al
d620: 6c 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20 20  l of the.       
d630: 20 23 20 49 4f 45 52 52 73 20 77 65 20 67 65 74   # IOERRs we get
d640: 20 62 61 63 6b 20 72 65 61 6c 6c 79 20 64 6f 20   back really do 
d650: 68 61 76 65 20 74 68 65 69 72 20 65 78 74 65 6e  have their exten
d660: 64 65 64 20 63 6f 64 65 20 76 61 6c 75 65 73 2e  ded code values.
d670: 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 61 6e  .        # If an
d680: 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74   extended result
d690: 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65   code is returne
d6a0: 64 2c 20 74 68 65 20 73 71 6c 69 74 65 33 5f 65  d, the sqlite3_e
d6b0: 72 72 63 6f 64 65 0a 20 20 20 20 20 20 20 20 23  rrcode.        #
d6c0: 20 54 43 4c 63 6f 6d 6d 61 6e 64 20 77 69 6c 6c   TCLcommand will
d6d0: 20 72 65 74 75 72 6e 20 61 20 73 74 72 69 6e 67   return a string
d6e0: 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 20 20 53   of the form:  S
d6f0: 51 4c 49 54 45 5f 49 4f 45 52 52 2b 6e 6e 6e 6e  QLITE_IOERR+nnnn
d700: 0a 20 20 20 20 20 20 20 20 23 20 77 68 65 72 65  .        # where
d710: 20 6e 6e 6e 6e 20 69 73 20 61 20 6e 75 6d 62 65   nnnn is a numbe
d720: 72 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72  r.        if {[r
d730: 65 67 65 78 70 20 7b 5e 53 51 4c 49 54 45 5f 49  egexp {^SQLITE_I
d740: 4f 45 52 52 7d 20 24 72 63 5d 20 26 26 20 21 5b  OERR} $rc] && ![
d750: 72 65 67 65 78 70 20 7b 49 4f 45 52 52 5c 2b 5c  regexp {IOERR\+\
d760: 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20 20  d} $rc]} {.     
d770: 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63 0a       return $rc.
d780: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
d790: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
d7a0: 20 23 20 49 66 20 77 65 20 61 72 65 20 6e 6f 74   # If we are not
d7b0: 20 69 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73   in extended res
d7c0: 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20 6d  ult code mode, m
d7d0: 61 6b 65 20 73 75 72 65 20 6e 6f 0a 20 20 20 20  ake sure no.    
d7e0: 20 20 20 20 23 20 65 78 74 65 6e 64 65 64 20 65      # extended e
d7f0: 72 72 6f 72 20 63 6f 64 65 73 20 61 72 65 20 72  rror codes are r
d800: 65 74 75 72 6e 65 64 2e 0a 20 20 20 20 20 20 20  eturned..       
d810: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5c 2b   if {[regexp {\+
d820: 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20  \d} $rc]} {.    
d830: 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63        return $rc
d840: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
d850: 20 7d 0a 20 20 20 20 20 20 23 20 54 68 65 20 74   }.      # The t
d860: 65 73 74 20 72 65 70 65 61 74 73 20 61 73 20 6c  est repeats as l
d870: 6f 6e 67 20 61 73 20 24 3a 3a 67 6f 20 69 73 20  ong as $::go is 
d880: 6e 6f 6e 2d 7a 65 72 6f 2e 20 20 24 3a 3a 67 6f  non-zero.  $::go
d890: 20 73 74 61 72 74 73 20 6f 75 74 0a 20 20 20 20   starts out.    
d8a0: 20 20 23 20 61 73 20 31 2e 20 20 57 68 65 6e 20    # as 1.  When 
d8b0: 61 20 74 65 73 74 20 72 75 6e 73 20 74 6f 20 63  a test runs to c
d8c0: 6f 6d 70 6c 65 74 69 6f 6e 20 77 69 74 68 6f 75  ompletion withou
d8d0: 74 20 68 69 74 74 69 6e 67 20 61 6e 20 49 2f 4f  t hitting an I/O
d8e0: 0a 20 20 20 20 20 20 23 20 65 72 72 6f 72 2c 20  .      # error, 
d8f0: 74 68 61 74 20 6d 65 61 6e 73 20 74 68 65 72 65  that means there
d900: 20 69 73 20 6e 6f 20 70 6f 69 6e 74 20 69 6e 20   is no point in 
d910: 63 6f 6e 74 69 6e 75 69 6e 67 20 77 69 74 68 20  continuing with 
d920: 74 68 69 73 20 74 65 73 74 0a 20 20 20 20 20 20  this test.      
d930: 23 20 63 61 73 65 20 73 6f 20 73 65 74 20 24 3a  # case so set $:
d940: 3a 67 6f 20 74 6f 20 7a 65 72 6f 2e 0a 20 20 20  :go to zero..   
d950: 20 20 20 23 0a 20 20 20 20 20 20 69 66 20 7b 24     #.      if {$
d960: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
d970: 72 5f 70 65 6e 64 69 6e 67 3e 30 7d 20 7b 0a 20  r_pending>0} {. 
d980: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 67 6f 20         set ::go 
d990: 30 0a 20 20 20 20 20 20 20 20 73 65 74 20 71 20  0.        set q 
d9a0: 30 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a  0.        set ::
d9b0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
d9c0: 70 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 20 20  pending 0.      
d9d0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
d9e0: 20 73 65 74 20 71 20 31 0a 20 20 20 20 20 20 7d   set q 1.      }
d9f0: 0a 0a 20 20 20 20 20 20 73 65 74 20 73 20 5b 65  ..      set s [e
da00: 78 70 72 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f  xpr $::sqlite_io
da10: 5f 65 72 72 6f 72 5f 68 69 74 3d 3d 30 5d 0a 20  _error_hit==0]. 
da20: 20 20 20 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69       if {$::sqli
da30: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3e  te_io_error_hit>
da40: 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72  $::sqlite_io_err
da50: 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 72  or_hardhit && $r
da60: 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  ==0} {.        s
da70: 65 74 20 72 20 31 0a 20 20 20 20 20 20 7d 0a 20  et r 1.      }. 
da80: 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74       set ::sqlit
da90: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30  e_io_error_hit 0
daa0: 0a 0a 20 20 20 20 20 20 23 20 4f 6e 65 20 6f 66  ..      # One of
dab0: 20 74 77 6f 20 74 68 69 6e 67 73 20 6d 75 73 74   two things must
dac0: 20 68 61 76 65 20 68 61 70 70 65 6e 65 64 2e 20   have happened. 
dad0: 65 69 74 68 65 72 0a 20 20 20 20 20 20 23 20 20  either.      #  
dae0: 20 31 2e 20 20 57 65 20 6e 65 76 65 72 20 68 69   1.  We never hi
daf0: 74 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 61  t the IO error a
db00: 6e 64 20 74 68 65 20 53 51 4c 20 72 65 74 75 72  nd the SQL retur
db10: 6e 65 64 20 4f 4b 0a 20 20 20 20 20 20 23 20 20  ned OK.      #  
db20: 20 32 2e 20 20 41 6e 20 49 4f 20 65 72 72 6f 72   2.  An IO error
db30: 20 77 61 73 20 68 69 74 20 61 6e 64 20 74 68 65   was hit and the
db40: 20 53 51 4c 20 66 61 69 6c 65 64 0a 20 20 20 20   SQL failed.    
db50: 20 20 23 0a 20 20 20 20 20 20 23 70 75 74 73 20    #.      #puts 
db60: 22 73 3d 24 73 20 72 3d 24 72 20 71 3d 24 71 22  "s=$s r=$r q=$q"
db70: 0a 20 20 20 20 20 20 65 78 70 72 20 7b 20 28 24  .      expr { ($
db80: 73 20 26 26 20 21 24 72 20 26 26 20 21 24 71 29  s && !$r && !$q)
db90: 20 7c 7c 20 28 21 24 73 20 26 26 20 24 72 20 26   || (!$s && $r &
dba0: 26 20 24 71 29 20 7d 0a 20 20 20 20 7d 20 7b 31  & $q) }.    } {1
dbb0: 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  }..    set ::sql
dbc0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74  ite_io_error_hit
dbd0: 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c   0.    set ::sql
dbe0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
dbf0: 64 69 6e 67 20 30 0a 0a 20 20 20 20 23 20 43 68  ding 0..    # Ch
dc00: 65 63 6b 20 74 68 61 74 20 6e 6f 20 70 61 67 65  eck that no page
dc10: 20 72 65 66 65 72 65 6e 63 65 73 20 77 65 72 65   references were
dc20: 20 6c 65 61 6b 65 64 2e 20 54 68 65 72 65 20 73   leaked. There s
dc30: 68 6f 75 6c 64 20 62 65 0a 20 20 20 20 23 20 61  hould be.    # a
dc40: 20 73 69 6e 67 6c 65 20 72 65 66 65 72 65 6e 63   single referenc
dc50: 65 20 69 66 20 74 68 65 72 65 20 69 73 20 73 74  e if there is st
dc60: 69 6c 6c 20 61 6e 20 61 63 74 69 76 65 20 74 72  ill an active tr
dc70: 61 6e 73 61 63 74 69 6f 6e 2c 0a 20 20 20 20 23  ansaction,.    #
dc80: 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65 72 77 69   or zero otherwi
dc90: 73 65 2e 0a 20 20 20 20 23 0a 20 20 20 20 23 20  se..    #.    # 
dca0: 55 50 44 41 54 45 3a 20 49 66 20 74 68 65 20 49  UPDATE: If the I
dcb0: 4f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20 61  O error occurs a
dcc0: 66 74 65 72 20 61 20 27 42 45 47 49 4e 27 20 62  fter a 'BEGIN' b
dcd0: 75 74 20 62 65 66 6f 72 65 20 61 6e 79 0a 20 20  ut before any.  
dce0: 20 20 23 20 6c 6f 63 6b 73 20 61 72 65 20 65 73    # locks are es
dcf0: 74 61 62 6c 69 73 68 65 64 20 6f 6e 20 64 61 74  tablished on dat
dd00: 61 62 61 73 65 20 66 69 6c 65 73 20 28 69 2e 65  abase files (i.e
dd10: 2e 20 69 66 20 74 68 65 20 65 72 72 6f 72 0a 20  . if the error. 
dd20: 20 20 20 23 20 6f 63 63 75 72 73 20 77 68 69 6c     # occurs whil
dd30: 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20  e attempting to 
dd40: 64 65 74 65 63 74 20 61 20 68 6f 74 2d 6a 6f 75  detect a hot-jou
dd50: 72 6e 61 6c 20 66 69 6c 65 29 2c 20 74 68 65 6e  rnal file), then
dd60: 0a 20 20 20 20 23 20 74 68 65 72 65 20 6d 61 79  .    # there may
dd70: 20 30 20 70 61 67 65 20 72 65 66 65 72 65 6e 63   0 page referenc
dd80: 65 73 20 61 6e 64 20 61 6e 20 61 63 74 69 76 65  es and an active
dd90: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 61 63 63   transaction acc
dda0: 6f 72 64 69 6e 67 0a 20 20 20 20 23 20 74 6f 20  ording.    # to 
ddb0: 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61 75 74  [sqlite3_get_aut
ddc0: 6f 63 6f 6d 6d 69 74 5d 2e 0a 20 20 20 20 23 0a  ocommit]..    #.
ddd0: 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26      if {$::go &&
dde0: 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72   $::sqlite_io_er
ddf0: 72 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24  ror_hardhit && $
de00: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72  ::ioerropts(-ckr
de10: 65 66 63 6f 75 6e 74 29 7d 20 7b 0a 20 20 20 20  efcount)} {.    
de20: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
de30: 61 6d 65 2e 24 6e 2e 34 20 7b 0a 20 20 20 20 20  ame.$n.4 {.     
de40: 20 20 20 73 65 74 20 62 74 20 5b 62 74 72 65 65     set bt [btree
de50: 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a 20 20 20  _from_db db].   
de60: 20 20 20 20 20 64 62 5f 65 6e 74 65 72 20 64 62       db_enter db
de70: 0a 20 20 20 20 20 20 20 20 61 72 72 61 79 20 73  .        array s
de80: 65 74 20 73 74 61 74 73 20 5b 62 74 72 65 65 5f  et stats [btree_
de90: 70 61 67 65 72 5f 73 74 61 74 73 20 24 62 74 5d  pager_stats $bt]
dea0: 0a 20 20 20 20 20 20 20 20 64 62 5f 6c 65 61 76  .        db_leav
deb0: 65 20 64 62 0a 20 20 20 20 20 20 20 20 73 65 74  e db.        set
dec0: 20 6e 52 65 66 20 24 73 74 61 74 73 28 72 65 66   nRef $stats(ref
ded0: 29 0a 20 20 20 20 20 20 20 20 65 78 70 72 20 7b  ).        expr {
dee0: 24 6e 52 65 66 20 3d 3d 20 30 20 7c 7c 20 28 5b  $nRef == 0 || ([
def0: 73 71 6c 69 74 65 33 5f 67 65 74 5f 61 75 74 6f  sqlite3_get_auto
df00: 63 6f 6d 6d 69 74 20 64 62 5d 3d 3d 30 20 26 26  commit db]==0 &&
df10: 20 24 6e 52 65 66 20 3d 3d 20 31 29 7d 0a 20 20   $nRef == 1)}.  
df20: 20 20 20 20 7d 20 7b 31 7d 0a 20 20 20 20 7d 0a      } {1}.    }.
df30: 0a 20 20 20 20 23 20 49 66 20 74 68 65 72 65 20  .    # If there 
df40: 69 73 20 61 6e 20 6f 70 65 6e 20 64 61 74 61 62  is an open datab
df50: 61 73 65 20 68 61 6e 64 6c 65 20 61 6e 64 20 6e  ase handle and n
df60: 6f 20 6f 70 65 6e 20 74 72 61 6e 73 61 63 74 69  o open transacti
df70: 6f 6e 2c 0a 20 20 20 20 23 20 61 6e 64 20 74 68  on,.    # and th
df80: 65 20 70 61 67 65 72 20 69 73 20 6e 6f 74 20 72  e pager is not r
df90: 75 6e 6e 69 6e 67 20 69 6e 20 65 78 63 6c 75 73  unning in exclus
dfa0: 69 76 65 2d 6c 6f 63 6b 69 6e 67 20 6d 6f 64 65  ive-locking mode
dfb0: 2c 0a 20 20 20 20 23 20 63 68 65 63 6b 20 74 68  ,.    # check th
dfc0: 61 74 20 74 68 65 20 70 61 67 65 72 20 69 73 20  at the pager is 
dfd0: 69 6e 20 22 75 6e 6c 6f 63 6b 65 64 22 20 73 74  in "unlocked" st
dfe0: 61 74 65 2e 20 54 68 65 6f 72 65 74 69 63 61 6c  ate. Theoretical
dff0: 6c 79 2c 0a 20 20 20 20 23 20 69 66 20 61 20 63  ly,.    # if a c
e000: 61 6c 6c 20 74 6f 20 78 55 6e 6c 6f 63 6b 28 29  all to xUnlock()
e010: 20 66 61 69 6c 65 64 20 64 75 65 20 74 6f 20 61   failed due to a
e020: 6e 20 49 4f 20 65 72 72 6f 72 20 74 68 65 20 75  n IO error the u
e030: 6e 64 65 72 6c 79 69 6e 67 0a 20 20 20 20 23 20  nderlying.    # 
e040: 66 69 6c 65 20 6d 61 79 20 73 74 69 6c 6c 20 62  file may still b
e050: 65 20 6c 6f 63 6b 65 64 2e 0a 20 20 20 20 23 0a  e locked..    #.
e060: 20 20 20 20 69 66 63 61 70 61 62 6c 65 20 70 72      ifcapable pr
e070: 61 67 6d 61 20 7b 0a 20 20 20 20 20 20 69 66 20  agma {.      if 
e080: 7b 20 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73  { [info commands
e090: 20 64 62 5d 20 6e 65 20 22 22 0a 20 20 20 20 20   db] ne "".     
e0a0: 20 20 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70     && $::ioerrop
e0b0: 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29 0a  ts(-ckrefcount).
e0c0: 20 20 20 20 20 20 20 20 26 26 20 5b 64 62 20 6f          && [db o
e0d0: 6e 65 20 7b 70 72 61 67 6d 61 20 6c 6f 63 6b 69  ne {pragma locki
e0e0: 6e 67 5f 6d 6f 64 65 7d 5d 20 65 71 20 22 6e 6f  ng_mode}] eq "no
e0f0: 72 6d 61 6c 22 0a 20 20 20 20 20 20 20 20 26 26  rmal".        &&
e100: 20 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61 75   [sqlite3_get_au
e110: 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 0a 20 20 20  tocommit db].   
e120: 20 20 20 7d 20 7b 0a 20 20 20 20 20 20 20 20 64     } {.        d
e130: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
e140: 2e 24 6e 2e 35 20 7b 0a 20 20 20 20 20 20 20 20  .$n.5 {.        
e150: 20 20 73 65 74 20 62 74 20 5b 62 74 72 65 65 5f    set bt [btree_
e160: 66 72 6f 6d 5f 64 62 20 64 62 5d 0a 20 20 20 20  from_db db].    
e170: 20 20 20 20 20 20 64 62 5f 65 6e 74 65 72 20 64        db_enter d
e180: 62 0a 20 20 20 20 20 20 20 20 20 20 61 72 72 61  b.          arra
e190: 79 20 73 65 74 20 73 74 61 74 73 20 5b 62 74 72  y set stats [btr
e1a0: 65 65 5f 70 61 67 65 72 5f 73 74 61 74 73 20 24  ee_pager_stats $
e1b0: 62 74 5d 0a 20 20 20 20 20 20 20 20 20 20 64 62  bt].          db
e1c0: 5f 6c 65 61 76 65 20 64 62 0a 20 20 20 20 20 20  _leave db.      
e1d0: 20 20 20 20 73 65 74 20 73 74 61 74 73 28 73 74      set stats(st
e1e0: 61 74 65 29 0a 20 20 20 20 20 20 20 20 7d 20 30  ate).        } 0
e1f0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
e200: 20 20 20 20 23 20 49 66 20 61 6e 20 49 4f 20 65      # If an IO e
e210: 72 72 6f 72 20 6f 63 63 75 72 72 65 64 2c 20 74  rror occurred, t
e220: 68 65 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d  hen the checksum
e230: 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
e240: 20 73 68 6f 75 6c 64 0a 20 20 20 20 23 20 62 65   should.    # be
e250: 20 74 68 65 20 73 61 6d 65 20 61 73 20 62 65 66   the same as bef
e260: 6f 72 65 20 74 68 65 20 73 63 72 69 70 74 20 74  ore the script t
e270: 68 61 74 20 63 61 75 73 65 64 20 74 68 65 20 49  hat caused the I
e280: 4f 20 65 72 72 6f 72 20 77 61 73 20 72 75 6e 2e  O error was run.
e290: 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b 24  .    #.    if {$
e2a0: 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71 6c 69 74  ::go && $::sqlit
e2b0: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68  e_io_error_hardh
e2c0: 69 74 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70  it && $::ioerrop
e2d0: 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20  ts(-cksum)} {.  
e2e0: 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73      do_test $tes
e2f0: 74 6e 61 6d 65 2e 24 6e 2e 36 20 7b 0a 20 20 20  tname.$n.6 {.   
e300: 20 20 20 20 20 63 61 74 63 68 20 7b 64 62 20 63       catch {db c
e310: 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20 20 63 61  lose}.        ca
e320: 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a  tch {db2 close}.
e330: 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a 44 42          set ::DB
e340: 20 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65 73   [sqlite3 db tes
e350: 74 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f  t.db; sqlite3_co
e360: 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72  nnection_pointer
e370: 20 64 62 5d 0a 20 20 20 20 20 20 20 20 73 65 74   db].        set
e380: 20 6e 6f 77 63 6b 73 75 6d 20 5b 63 6b 73 75 6d   nowcksum [cksum
e390: 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20 72 65  ].        set re
e3a0: 73 20 5b 65 78 70 72 20 7b 24 6e 6f 77 63 6b 73  s [expr {$nowcks
e3b0: 75 6d 3d 3d 24 3a 3a 63 68 65 63 6b 73 75 6d 20  um==$::checksum 
e3c0: 7c 7c 20 24 6e 6f 77 63 6b 73 75 6d 3d 3d 24 3a  || $nowcksum==$:
e3d0: 3a 67 6f 6f 64 63 6b 73 75 6d 7d 5d 0a 20 20 20  :goodcksum}].   
e3e0: 20 20 20 20 20 69 66 20 7b 24 72 65 73 3d 3d 30       if {$res==0
e3f0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 6f 75  } {.          ou
e400: 74 70 75 74 32 20 22 6e 6f 77 3d 24 6e 6f 77 63  tput2 "now=$nowc
e410: 6b 73 75 6d 22 0a 20 20 20 20 20 20 20 20 20 20  ksum".          
e420: 6f 75 74 70 75 74 32 20 22 74 68 65 3d 24 3a 3a  output2 "the=$::
e430: 63 68 65 63 6b 73 75 6d 22 0a 20 20 20 20 20 20  checksum".      
e440: 20 20 20 20 6f 75 74 70 75 74 32 20 22 66 77 64      output2 "fwd
e450: 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75 6d 22 0a 20  =$::goodcksum". 
e460: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
e470: 20 73 65 74 20 72 65 73 0a 20 20 20 20 20 20 7d   set res.      }
e480: 20 31 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 65   1.    }..    se
e490: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
e4a0: 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a 20 20  ror_hardhit 0.  
e4b0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
e4c0: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
e4d0: 30 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  0.    if {[info 
e4e0: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
e4f0: 74 73 28 2d 63 6c 65 61 6e 75 70 29 5d 7d 20 7b  ts(-cleanup)]} {
e500: 0a 20 20 20 20 20 20 63 61 74 63 68 20 24 3a 3a  .      catch $::
e510: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e  ioerropts(-clean
e520: 75 70 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  up).    }.  }.  
e530: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
e540: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a  error_pending 0.
e550: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
e560: 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20  o_error_persist 
e570: 30 0a 20 20 75 6e 73 65 74 20 3a 3a 69 6f 65 72  0.  unset ::ioer
e580: 72 6f 70 74 73 0a 7d 0a 0a 23 20 52 65 74 75 72  ropts.}..# Retur
e590: 6e 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73  n a checksum bas
e5a0: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e  ed on the conten
e5b0: 74 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 64  ts of the main d
e5c0: 61 74 61 62 61 73 65 20 61 73 73 6f 63 69 61 74  atabase associat
e5d0: 65 64 0a 23 20 77 69 74 68 20 63 6f 6e 6e 65 63  ed.# with connec
e5e0: 74 69 6f 6e 20 24 64 62 0a 23 0a 70 72 6f 63 20  tion $db.#.proc 
e5f0: 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20  cksum {{db db}} 
e600: 7b 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64 62  {.  set txt [$db
e610: 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45   eval {.      SE
e620: 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79 70 65 2c  LECT name, type,
e630: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
e640: 5f 6d 61 73 74 65 72 20 6f 72 64 65 72 20 62 79  _master order by
e650: 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e 0a 20 20 66   name.  }]\n.  f
e660: 6f 72 65 61 63 68 20 74 62 6c 20 5b 24 64 62 20  oreach tbl [$db 
e670: 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c  eval {.      SEL
e680: 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71  ECT name FROM sq
e690: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
e6a0: 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27 20 6f  E type='table' o
e6b0: 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d  rder by name.  }
e6c0: 5d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74  ] {.    append t
e6d0: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45  xt [$db eval "SE
e6e0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c  LECT * FROM $tbl
e6f0: 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66 6f 72 65 61  "]\n.  }.  forea
e700: 63 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c 74  ch prag {default
e710: 5f 73 79 6e 63 68 72 6f 6e 6f 75 73 20 64 65 66  _synchronous def
e720: 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d  ault_cache_size}
e730: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78   {.    append tx
e740: 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76 61  t $prag-[$db eva
e750: 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61 67 22  l "PRAGMA $prag"
e760: 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65 74 20 63 6b  ]\n.  }.  set ck
e770: 73 75 6d 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  sum [string leng
e780: 74 68 20 24 74 78 74 5d 2d 5b 6d 64 35 20 24 74  th $txt]-[md5 $t
e790: 78 74 5d 0a 20 20 23 20 70 75 74 73 20 24 63 6b  xt].  # puts $ck
e7a0: 73 75 6d 2d 5b 66 69 6c 65 20 73 69 7a 65 20 74  sum-[file size t
e7b0: 65 73 74 2e 64 62 5d 0a 20 20 72 65 74 75 72 6e  est.db].  return
e7c0: 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23 20 47 65 6e   $cksum.}..# Gen
e7d0: 65 72 61 74 65 20 61 20 63 68 65 63 6b 73 75 6d  erate a checksum
e7e0: 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f   based on the co
e7f0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 6d 61  ntents of the ma
e800: 69 6e 20 61 6e 64 20 74 65 6d 70 20 74 61 62 6c  in and temp tabl
e810: 65 73 0a 23 20 64 61 74 61 62 61 73 65 20 24 64  es.# database $d
e820: 62 2e 20 49 66 20 74 68 65 20 63 68 65 63 6b 73  b. If the checks
e830: 75 6d 20 6f 66 20 74 77 6f 20 64 61 74 61 62 61  um of two databa
e840: 73 65 73 20 69 73 20 74 68 65 20 73 61 6d 65 2c  ses is the same,
e850: 20 61 6e 64 20 74 68 65 0a 23 20 69 6e 74 65 67   and the.# integ
e860: 72 69 74 79 2d 63 68 65 63 6b 20 70 61 73 73 65  rity-check passe
e870: 73 20 66 6f 72 20 62 6f 74 68 2c 20 74 68 65 20  s for both, the 
e880: 74 77 6f 20 64 61 74 61 62 61 73 65 73 20 61 72  two databases ar
e890: 65 20 69 64 65 6e 74 69 63 61 6c 2e 0a 23 0a 70  e identical..#.p
e8a0: 72 6f 63 20 61 6c 6c 63 6b 73 75 6d 20 7b 7b 64  roc allcksum {{d
e8b0: 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 72  b db}} {.  set r
e8c0: 65 74 20 5b 6c 69 73 74 5d 0a 20 20 69 66 63 61  et [list].  ifca
e8d0: 70 61 62 6c 65 20 74 65 6d 70 64 62 20 7b 0a 20  pable tempdb {. 
e8e0: 20 20 20 73 65 74 20 73 71 6c 20 7b 0a 20 20 20     set sql {.   
e8f0: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
e900: 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ROM sqlite_maste
e910: 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27  r WHERE type = '
e920: 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20  table' UNION.   
e930: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
e940: 52 4f 4d 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f  ROM sqlite_temp_
e950: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
e960: 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f  e = 'table' UNIO
e970: 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27  N.      SELECT '
e980: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20 55  sqlite_master' U
e990: 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43  NION.      SELEC
e9a0: 54 20 27 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d  T 'sqlite_temp_m
e9b0: 61 73 74 65 72 27 20 4f 52 44 45 52 20 42 59 20  aster' ORDER BY 
e9c0: 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  1.    }.  } else
e9d0: 20 7b 0a 20 20 20 20 73 65 74 20 73 71 6c 20 7b   {.    set sql {
e9e0: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
e9f0: 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  me FROM sqlite_m
ea00: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
ea10: 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e   = 'table' UNION
ea20: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27 73  .      SELECT 's
ea30: 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20 4f 52  qlite_master' OR
ea40: 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d 0a 20  DER BY 1.    }. 
ea50: 20 7d 0a 20 20 73 65 74 20 74 62 6c 6c 69 73 74   }.  set tbllist
ea60: 20 5b 24 64 62 20 65 76 61 6c 20 24 73 71 6c 5d   [$db eval $sql]
ea70: 0a 20 20 73 65 74 20 74 78 74 20 7b 7d 0a 20 20  .  set txt {}.  
ea80: 66 6f 72 65 61 63 68 20 74 62 6c 20 24 74 62 6c  foreach tbl $tbl
ea90: 6c 69 73 74 20 7b 0a 20 20 20 20 61 70 70 65 6e  list {.    appen
eaa0: 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20  d txt [$db eval 
eab0: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24  "SELECT * FROM $
eac0: 74 62 6c 22 5d 0a 20 20 7d 0a 20 20 66 6f 72 65  tbl"].  }.  fore
ead0: 61 63 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c  ach prag {defaul
eae0: 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d 20 7b 0a  t_cache_size} {.
eaf0: 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 24      append txt $
eb00: 70 72 61 67 2d 5b 24 64 62 20 65 76 61 6c 20 22  prag-[$db eval "
eb10: 50 52 41 47 4d 41 20 24 70 72 61 67 22 5d 5c 6e  PRAGMA $prag"]\n
eb20: 0a 20 20 7d 0a 20 20 23 20 70 75 74 73 20 74 78  .  }.  # puts tx
eb30: 74 3d 24 74 78 74 0a 20 20 72 65 74 75 72 6e 20  t=$txt.  return 
eb40: 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 23 20  [md5 $txt].}..# 
eb50: 47 65 6e 65 72 61 74 65 20 61 20 63 68 65 63 6b  Generate a check
eb60: 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65  sum based on the
eb70: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 20 73   contents of a s
eb80: 69 6e 67 6c 65 20 64 61 74 61 62 61 73 65 20 77  ingle database w
eb90: 69 74 68 0a 23 20 61 20 64 61 74 61 62 61 73 65  ith.# a database
eba0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20 20 54 68   connection.  Th
ebb0: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 64 61  e name of the da
ebc0: 74 61 62 61 73 65 20 69 73 20 24 64 62 6e 61 6d  tabase is $dbnam
ebd0: 65 2e 0a 23 20 45 78 61 6d 70 6c 65 73 20 6f 66  e..# Examples of
ebe0: 20 24 64 62 6e 61 6d 65 20 61 72 65 20 22 74 65   $dbname are "te
ebf0: 6d 70 22 20 6f 72 20 22 6d 61 69 6e 22 2e 0a 23  mp" or "main"..#
ec00: 0a 70 72 6f 63 20 64 62 63 6b 73 75 6d 20 7b 64  .proc dbcksum {d
ec10: 62 20 64 62 6e 61 6d 65 7d 20 7b 0a 20 20 69 66  b dbname} {.  if
ec20: 20 7b 24 64 62 6e 61 6d 65 3d 3d 22 74 65 6d 70   {$dbname=="temp
ec30: 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 6d 61 73  "} {.    set mas
ec40: 74 65 72 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f  ter sqlite_temp_
ec50: 6d 61 73 74 65 72 0a 20 20 7d 20 65 6c 73 65 20  master.  } else 
ec60: 7b 0a 20 20 20 20 73 65 74 20 6d 61 73 74 65 72  {.    set master
ec70: 20 24 64 62 6e 61 6d 65 2e 73 71 6c 69 74 65 5f   $dbname.sqlite_
ec80: 6d 61 73 74 65 72 0a 20 20 7d 0a 20 20 73 65 74  master.  }.  set
ec90: 20 61 6c 6c 74 61 62 20 5b 24 64 62 20 65 76 61   alltab [$db eva
eca0: 6c 20 22 53 45 4c 45 43 54 20 6e 61 6d 65 20 46  l "SELECT name F
ecb0: 52 4f 4d 20 24 6d 61 73 74 65 72 20 57 48 45 52  ROM $master WHER
ecc0: 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27 22 5d  E type='table'"]
ecd0: 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64 62 20  .  set txt [$db 
ece0: 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46  eval "SELECT * F
ecf0: 52 4f 4d 20 24 6d 61 73 74 65 72 22 5d 5c 6e 0a  ROM $master"]\n.
ed00: 20 20 66 6f 72 65 61 63 68 20 74 61 62 20 24 61    foreach tab $a
ed10: 6c 6c 74 61 62 20 7b 0a 20 20 20 20 61 70 70 65  lltab {.    appe
ed20: 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c  nd txt [$db eval
ed30: 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   "SELECT * FROM 
ed40: 24 64 62 6e 61 6d 65 2e 24 74 61 62 22 5d 5c 6e  $dbname.$tab"]\n
ed50: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 5b 6d  .  }.  return [m
ed60: 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 70 72 6f 63  d5 $txt].}..proc
ed70: 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71   memdebug_log_sq
ed80: 6c 20 7b 66 69 6c 65 6e 61 6d 65 7d 20 7b 0a 0a  l {filename} {..
ed90: 20 20 73 65 74 20 64 61 74 61 20 5b 73 71 6c 69    set data [sqli
eda0: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67  te3_memdebug_log
edb0: 20 64 75 6d 70 5d 0a 20 20 73 65 74 20 6e 46 72   dump].  set nFr
edc0: 61 6d 65 20 5b 65 78 70 72 20 5b 6c 6c 65 6e 67  ame [expr [lleng
edd0: 74 68 20 5b 6c 69 6e 64 65 78 20 24 64 61 74 61  th [lindex $data
ede0: 20 30 5d 5d 2d 32 5d 0a 20 20 69 66 20 7b 24 6e   0]]-2].  if {$n
edf0: 46 72 61 6d 65 20 3c 20 30 7d 20 7b 20 72 65 74  Frame < 0} { ret
ee00: 75 72 6e 20 22 22 20 7d 0a 0a 20 20 73 65 74 20  urn "" }..  set 
ee10: 64 61 74 61 62 61 73 65 20 74 65 6d 70 0a 0a 20  database temp.. 
ee20: 20 73 65 74 20 74 62 6c 20 22 43 52 45 41 54 45   set tbl "CREATE
ee30: 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73   TABLE ${databas
ee40: 65 7d 2e 6d 61 6c 6c 6f 63 28 7a 54 65 73 74 2c  e}.malloc(zTest,
ee50: 20 6e 43 61 6c 6c 2c 20 6e 42 79 74 65 2c 20 6c   nCall, nByte, l
ee60: 53 74 61 63 6b 29 3b 22 0a 0a 20 20 73 65 74 20  Stack);"..  set 
ee70: 73 71 6c 20 22 22 0a 20 20 66 6f 72 65 61 63 68  sql "".  foreach
ee80: 20 65 20 24 64 61 74 61 20 7b 0a 20 20 20 20 73   e $data {.    s
ee90: 65 74 20 6e 43 61 6c 6c 20 5b 6c 69 6e 64 65 78  et nCall [lindex
eea0: 20 24 65 20 30 5d 0a 20 20 20 20 73 65 74 20 6e   $e 0].    set n
eeb0: 42 79 74 65 20 5b 6c 69 6e 64 65 78 20 24 65 20  Byte [lindex $e 
eec0: 31 5d 0a 20 20 20 20 73 65 74 20 6c 53 74 61 63  1].    set lStac
eed0: 6b 20 5b 6c 72 61 6e 67 65 20 24 65 20 32 20 65  k [lrange $e 2 e
eee0: 6e 64 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73  nd].    append s
eef0: 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20  ql "INSERT INTO 
ef00: 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c 6c  ${database}.mall
ef10: 6f 63 20 56 41 4c 55 45 53 22 0a 20 20 20 20 61  oc VALUES".    a
ef20: 70 70 65 6e 64 20 73 71 6c 20 22 28 27 74 65 73  ppend sql "('tes
ef30: 74 27 2c 20 24 6e 43 61 6c 6c 2c 20 24 6e 42 79  t', $nCall, $nBy
ef40: 74 65 2c 20 27 24 6c 53 74 61 63 6b 27 29 3b 5c  te, '$lStack');\
ef50: 6e 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66  n".    foreach f
ef60: 20 24 6c 53 74 61 63 6b 20 7b 0a 20 20 20 20 20   $lStack {.     
ef70: 20 73 65 74 20 66 72 61 6d 65 73 28 24 66 29 20   set frames($f) 
ef80: 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73  1.    }.  }..  s
ef90: 65 74 20 74 62 6c 32 20 22 43 52 45 41 54 45 20  et tbl2 "CREATE 
efa0: 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65  TABLE ${database
efb0: 7d 2e 66 72 61 6d 65 28 66 72 61 6d 65 20 49 4e  }.frame(frame IN
efc0: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45  TEGER PRIMARY KE
efd0: 59 2c 20 6c 69 6e 65 29 3b 5c 6e 22 0a 20 20 73  Y, line);\n".  s
efe0: 65 74 20 74 62 6c 33 20 22 43 52 45 41 54 45 20  et tbl3 "CREATE 
eff0: 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65  TABLE ${database
f000: 7d 2e 66 69 6c 65 28 6e 61 6d 65 20 50 52 49 4d  }.file(name PRIM
f010: 41 52 59 20 4b 45 59 2c 20 63 6f 6e 74 65 6e 74  ARY KEY, content
f020: 29 3b 5c 6e 22 0a 0a 20 20 66 6f 72 65 61 63 68  );\n"..  foreach
f030: 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20   f [array names 
f040: 66 72 61 6d 65 73 5d 20 7b 0a 20 20 20 20 73 65  frames] {.    se
f050: 74 20 61 64 64 72 20 5b 66 6f 72 6d 61 74 20 25  t addr [format %
f060: 78 20 24 66 5d 0a 20 20 20 20 73 65 74 20 63 6d  x $f].    set cm
f070: 64 20 22 61 64 64 72 32 6c 69 6e 65 20 2d 65 20  d "addr2line -e 
f080: 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63  [info nameofexec
f090: 5d 20 24 61 64 64 72 22 0a 20 20 20 20 73 65 74  ] $addr".    set
f0a0: 20 6c 69 6e 65 20 5b 65 76 61 6c 20 65 78 65 63   line [eval exec
f0b0: 20 24 63 6d 64 5d 0a 20 20 20 20 61 70 70 65 6e   $cmd].    appen
f0c0: 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e  d sql "INSERT IN
f0d0: 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66  TO ${database}.f
f0e0: 72 61 6d 65 20 56 41 4c 55 45 53 28 24 66 2c 20  rame VALUES($f, 
f0f0: 27 24 6c 69 6e 65 27 29 3b 5c 6e 22 0a 0a 20 20  '$line');\n"..  
f100: 20 20 73 65 74 20 66 69 6c 65 20 5b 6c 69 6e 64    set file [lind
f110: 65 78 20 5b 73 70 6c 69 74 20 24 6c 69 6e 65 20  ex [split $line 
f120: 3a 5d 20 30 5d 0a 20 20 20 20 73 65 74 20 66 69  :] 0].    set fi
f130: 6c 65 73 28 24 66 69 6c 65 29 20 31 0a 20 20 7d  les($file) 1.  }
f140: 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 61  ..  foreach f [a
f150: 72 72 61 79 20 6e 61 6d 65 73 20 66 69 6c 65 73  rray names files
f160: 5d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6e 74  ] {.    set cont
f170: 65 6e 74 73 20 22 22 0a 20 20 20 20 63 61 74 63  ents "".    catc
f180: 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66 64  h {.      set fd
f190: 20 5b 6f 70 65 6e 20 24 66 5d 0a 20 20 20 20 20   [open $f].     
f1a0: 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 5b 72   set contents [r
f1b0: 65 61 64 20 24 66 64 5d 0a 20 20 20 20 20 20 63  ead $fd].      c
f1c0: 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 7d 0a 20  lose $fd.    }. 
f1d0: 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20     set contents 
f1e0: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27  [string map {' '
f1f0: 27 7d 20 24 63 6f 6e 74 65 6e 74 73 5d 0a 20 20  '} $contents].  
f200: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e    append sql "IN
f210: 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61  SERT INTO ${data
f220: 62 61 73 65 7d 2e 66 69 6c 65 20 56 41 4c 55 45  base}.file VALUE
f230: 53 28 27 24 66 27 2c 20 27 24 63 6f 6e 74 65 6e  S('$f', '$conten
f240: 74 73 27 29 3b 5c 6e 22 0a 20 20 7d 0a 0a 20 20  ts');\n".  }..  
f250: 73 65 74 20 65 73 63 61 70 65 64 20 22 42 45 47  set escaped "BEG
f260: 49 4e 3b 20 24 7b 74 62 6c 7d 24 7b 74 62 6c 32  IN; ${tbl}${tbl2
f270: 7d 24 7b 74 62 6c 33 7d 24 7b 73 71 6c 7d 20 3b  }${tbl3}${sql} ;
f280: 20 43 4f 4d 4d 49 54 3b 22 0a 20 20 73 65 74 20   COMMIT;".  set 
f290: 65 73 63 61 70 65 64 20 5b 73 74 72 69 6e 67 20  escaped [string 
f2a0: 6d 61 70 20 5b 6c 69 73 74 20 22 7b 22 20 22 5c  map [list "{" "\
f2b0: 5c 7b 22 20 22 7d 22 20 22 5c 5c 7d 22 5d 20 24  \{" "}" "\\}"] $
f2c0: 65 73 63 61 70 65 64 5d 20 0a 0a 20 20 73 65 74  escaped] ..  set
f2d0: 20 66 64 20 5b 6f 70 65 6e 20 24 66 69 6c 65 6e   fd [open $filen
f2e0: 61 6d 65 20 77 5d 0a 20 20 70 75 74 73 20 24 66  ame w].  puts $f
f2f0: 64 20 22 73 65 74 20 42 55 49 4c 54 49 4e 20 7b  d "set BUILTIN {
f300: 22 0a 20 20 70 75 74 73 20 24 66 64 20 24 65 73  ".  puts $fd $es
f310: 63 61 70 65 64 0a 20 20 70 75 74 73 20 24 66 64  caped.  puts $fd
f320: 20 22 7d 22 0a 20 20 70 75 74 73 20 24 66 64 20   "}".  puts $fd 
f330: 7b 73 65 74 20 42 55 49 4c 54 49 4e 20 5b 73 74  {set BUILTIN [st
f340: 72 69 6e 67 20 6d 61 70 20 5b 6c 69 73 74 20 22  ring map [list "
f350: 5c 5c 7b 22 20 22 7b 22 20 22 5c 5c 7d 22 20 22  \\{" "{" "\\}" "
f360: 7d 22 5d 20 24 42 55 49 4c 54 49 4e 5d 7d 0a 20  }"] $BUILTIN]}. 
f370: 20 73 65 74 20 6d 74 76 20 5b 6f 70 65 6e 20 24   set mtv [open $
f380: 3a 3a 74 65 73 74 64 69 72 2f 6d 61 6c 6c 6f 63  ::testdir/malloc
f390: 74 72 61 63 65 76 69 65 77 65 72 2e 74 63 6c 5d  traceviewer.tcl]
f3a0: 0a 20 20 73 65 74 20 74 78 74 20 5b 72 65 61 64  .  set txt [read
f3b0: 20 24 6d 74 76 5d 0a 20 20 63 6c 6f 73 65 20 24   $mtv].  close $
f3c0: 6d 74 76 0a 20 20 70 75 74 73 20 24 66 64 20 24  mtv.  puts $fd $
f3d0: 74 78 74 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a  txt.  close $fd.
f3e0: 7d 0a 0a 23 20 44 72 6f 70 20 61 6c 6c 20 74 61  }..# Drop all ta
f3f0: 62 6c 65 73 20 69 6e 20 64 61 74 61 62 61 73 65  bles in database
f400: 20 5b 64 62 5d 0a 70 72 6f 63 20 64 72 6f 70 5f   [db].proc drop_
f410: 61 6c 6c 5f 74 61 62 6c 65 73 20 7b 7b 64 62 20  all_tables {{db 
f420: 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61 62  db}} {.  ifcapab
f430: 6c 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65  le trigger&&fore
f440: 69 67 6e 6b 65 79 20 7b 0a 20 20 20 20 73 65 74  ignkey {.    set
f450: 20 70 6b 20 5b 24 64 62 20 6f 6e 65 20 22 50 52   pk [$db one "PR
f460: 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79  AGMA foreign_key
f470: 73 22 5d 0a 20 20 20 20 24 64 62 20 65 76 61 6c  s"].    $db eval
f480: 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67 6e   "PRAGMA foreign
f490: 5f 6b 65 79 73 20 3d 20 4f 46 46 22 0a 20 20 7d  _keys = OFF".  }
f4a0: 0a 20 20 66 6f 72 65 61 63 68 20 7b 69 64 78 20  .  foreach {idx 
f4b0: 6e 61 6d 65 20 66 69 6c 65 7d 20 5b 64 62 20 65  name file} [db e
f4c0: 76 61 6c 20 7b 50 52 41 47 4d 41 20 64 61 74 61  val {PRAGMA data
f4d0: 62 61 73 65 5f 6c 69 73 74 7d 5d 20 7b 0a 20 20  base_list}] {.  
f4e0: 20 20 69 66 20 7b 24 69 64 78 3d 3d 31 7d 20 7b    if {$idx==1} {
f4f0: 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74 65  .      set maste
f500: 72 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61  r sqlite_temp_ma
f510: 73 74 65 72 0a 20 20 20 20 7d 20 65 6c 73 65 20  ster.    } else 
f520: 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74  {.      set mast
f530: 65 72 20 24 6e 61 6d 65 2e 73 71 6c 69 74 65 5f  er $name.sqlite_
f540: 6d 61 73 74 65 72 0a 20 20 20 20 7d 0a 20 20 20  master.    }.   
f550: 20 66 6f 72 65 61 63 68 20 7b 74 20 74 79 70 65   foreach {t type
f560: 7d 20 5b 24 64 62 20 65 76 61 6c 20 22 0a 20 20  } [$db eval ".  
f570: 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c      SELECT name,
f580: 20 74 79 70 65 20 46 52 4f 4d 20 24 6d 61 73 74   type FROM $mast
f590: 65 72 0a 20 20 20 20 20 20 57 48 45 52 45 20 74  er.      WHERE t
f5a0: 79 70 65 20 49 4e 28 27 74 61 62 6c 65 27 2c 20  ype IN('table', 
f5b0: 27 76 69 65 77 27 29 20 41 4e 44 20 6e 61 6d 65  'view') AND name
f5c0: 20 4e 4f 54 20 4c 49 4b 45 20 27 73 71 6c 69 74   NOT LIKE 'sqlit
f5d0: 65 58 5f 25 27 20 45 53 43 41 50 45 20 27 58 27  eX_%' ESCAPE 'X'
f5e0: 0a 20 20 20 20 22 5d 20 7b 0a 20 20 20 20 20 20  .    "] {.      
f5f0: 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20 24  $db eval "DROP $
f600: 74 79 70 65 20 5c 22 24 74 5c 22 22 0a 20 20 20  type \"$t\"".   
f610: 20 7d 0a 20 20 7d 0a 20 20 69 66 63 61 70 61 62   }.  }.  ifcapab
f620: 6c 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65  le trigger&&fore
f630: 69 67 6e 6b 65 79 20 7b 0a 20 20 20 20 24 64 62  ignkey {.    $db
f640: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66 6f   eval "PRAGMA fo
f650: 72 65 69 67 6e 5f 6b 65 79 73 20 3d 20 24 70 6b  reign_keys = $pk
f660: 22 0a 20 20 7d 0a 7d 0a 0a 23 20 44 72 6f 70 20  ".  }.}..# Drop 
f670: 61 6c 6c 20 61 75 78 69 6c 69 61 72 79 20 69 6e  all auxiliary in
f680: 64 65 78 65 73 20 66 72 6f 6d 20 74 68 65 20 6d  dexes from the m
f690: 61 69 6e 20 64 61 74 61 62 61 73 65 20 6f 70 65  ain database ope
f6a0: 6e 65 64 20 62 79 20 68 61 6e 64 6c 65 20 5b 64  ned by handle [d
f6b0: 62 5d 2e 0a 23 0a 70 72 6f 63 20 64 72 6f 70 5f  b]..#.proc drop_
f6c0: 61 6c 6c 5f 69 6e 64 65 78 65 73 20 7b 7b 64 62  all_indexes {{db
f6d0: 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 4c 20   db}} {.  set L 
f6e0: 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20  [$db eval {.    
f6f0: 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d  SELECT name FROM
f700: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
f710: 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65 78  HERE type='index
f720: 27 20 41 4e 44 20 73 71 6c 20 4c 49 4b 45 20 27  ' AND sql LIKE '
f730: 63 72 65 61 74 65 25 27 0a 20 20 7d 5d 0a 20 20  create%'.  }].  
f740: 66 6f 72 65 61 63 68 20 69 64 78 20 24 4c 20 7b  foreach idx $L {
f750: 20 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20   $db eval "DROP 
f760: 49 4e 44 45 58 20 24 69 64 78 22 20 7d 0a 7d 0a  INDEX $idx" }.}.
f770: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
f780: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
f790: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
f7a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
f7b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 49  ------------.# I
f7c0: 66 20 61 20 74 65 73 74 20 73 63 72 69 70 74 20  f a test script 
f7d0: 69 73 20 65 78 65 63 75 74 65 64 20 77 69 74 68  is executed with
f7e0: 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
f7f0: 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65 29   $::G(perm:name)
f800: 20 73 65 74 20 74 6f 0a 23 20 22 77 61 6c 22 2c   set to.# "wal",
f810: 20 74 68 65 6e 20 74 68 65 20 74 65 73 74 73 20   then the tests 
f820: 61 72 65 20 72 75 6e 20 69 6e 20 57 41 4c 20 6d  are run in WAL m
f830: 6f 64 65 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ode. Otherwise, 
f840: 74 68 65 79 20 73 68 6f 75 6c 64 20 62 65 20 72  they should be r
f850: 75 6e 0a 23 20 69 6e 20 72 6f 6c 6c 62 61 63 6b  un.# in rollback
f860: 20 6d 6f 64 65 2e 20 54 68 65 20 66 6f 6c 6c 6f   mode. The follo
f870: 77 69 6e 67 20 54 63 6c 20 70 72 6f 63 73 20 61  wing Tcl procs a
f880: 72 65 20 75 73 65 64 20 74 6f 20 6d 61 6b 65 20  re used to make 
f890: 74 68 69 73 20 6c 65 73 73 0a 23 20 69 6e 74 72  this less.# intr
f8a0: 75 73 69 76 65 3a 0a 23 0a 23 20 20 20 77 61 6c  usive:.#.#   wal
f8b0: 5f 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64  _set_journal_mod
f8c0: 65 20 3f 44 42 3f 0a 23 0a 23 20 20 20 20 20 49  e ?DB?.#.#     I
f8d0: 66 20 72 75 6e 6e 69 6e 67 20 61 20 57 41 4c 20  f running a WAL 
f8e0: 74 65 73 74 2c 20 65 78 65 63 75 74 65 20 22 50  test, execute "P
f8f0: 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f  RAGMA journal_mo
f900: 64 65 20 3d 20 77 61 6c 22 20 75 73 69 6e 67 0a  de = wal" using.
f910: 23 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f 6e  #     connection
f920: 20 68 61 6e 64 6c 65 20 44 42 2e 20 4f 74 68 65   handle DB. Othe
f930: 72 77 69 73 65 2c 20 74 68 69 73 20 63 6f 6d 6d  rwise, this comm
f940: 61 6e 64 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  and is a no-op..
f950: 23 0a 23 20 20 20 77 61 6c 5f 63 68 65 63 6b 5f  #.#   wal_check_
f960: 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 54 45 53  journal_mode TES
f970: 54 4e 41 4d 45 20 3f 44 42 3f 0a 23 0a 23 20 20  TNAME ?DB?.#.#  
f980: 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20 61 20     If running a 
f990: 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63 75 74  WAL test, execut
f9a0: 65 20 61 20 74 65 73 74 73 20 63 61 73 65 20 74  e a tests case t
f9b0: 68 61 74 20 66 61 69 6c 73 20 69 66 20 74 68 65  hat fails if the
f9c0: 20 6d 61 69 6e 0a 23 20 20 20 20 20 64 61 74 61   main.#     data
f9d0: 62 61 73 65 20 66 6f 72 20 63 6f 6e 6e 65 63 74  base for connect
f9e0: 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42 20 69 73  ion handle DB is
f9f0: 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 61   not currently a
fa00: 20 57 41 4c 20 64 61 74 61 62 61 73 65 2e 0a 23   WAL database..#
fa10: 20 20 20 20 20 4f 74 68 65 72 77 69 73 65 20 28       Otherwise (
fa20: 69 66 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20 61  if not running a
fa30: 20 57 41 4c 20 70 65 72 6d 75 74 61 74 69 6f 6e   WAL permutation
fa40: 29 20 74 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f  ) this is a no-o
fa50: 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f 69 73 5f  p..#.#   wal_is_
fa60: 77 61 6c 5f 6d 6f 64 65 0a 23 0a 23 20 20 20 20  wal_mode.#.#    
fa70: 20 52 65 74 75 72 6e 73 20 74 72 75 65 20 69 66   Returns true if
fa80: 20 74 68 69 73 20 74 65 73 74 20 73 68 6f 75 6c   this test shoul
fa90: 64 20 62 65 20 72 75 6e 20 69 6e 20 57 41 4c 20  d be run in WAL 
faa0: 6d 6f 64 65 2e 20 46 61 6c 73 65 20 6f 74 68 65  mode. False othe
fab0: 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63 20 77 61  rwise..#.proc wa
fac0: 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 20 7b 7d  l_is_wal_mode {}
fad0: 20 7b 0a 20 20 65 78 70 72 20 7b 5b 70 65 72 6d   {.  expr {[perm
fae0: 75 74 61 74 69 6f 6e 5d 20 65 71 20 22 77 61 6c  utation] eq "wal
faf0: 22 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f 73 65  "}.}.proc wal_se
fb00: 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b  t_journal_mode {
fb10: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 20  {db db}} {.  if 
fb20: 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f  { [wal_is_wal_mo
fb30: 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24 64 62 20  de] } {.    $db 
fb40: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6a 6f 75  eval "PRAGMA jou
fb50: 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c 22  rnal_mode = WAL"
fb60: 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f  .  }.}.proc wal_
fb70: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
fb80: 64 65 20 7b 74 65 73 74 6e 61 6d 65 20 7b 64 62  de {testname {db
fb90: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 20 7b 20 5b   db}} {.  if { [
fba0: 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d  wal_is_wal_mode]
fbb0: 20 7d 20 7b 0a 20 20 20 20 24 64 62 20 65 76 61   } {.    $db eva
fbc0: 6c 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f  l { SELECT * FRO
fbd0: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
fbe0: 7d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74  }.    do_test $t
fbf0: 65 73 74 6e 61 6d 65 20 5b 6c 69 73 74 20 24 64  estname [list $d
fc00: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6d  b eval "PRAGMA m
fc10: 61 69 6e 2e 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65  ain.journal_mode
fc20: 22 5d 20 7b 77 61 6c 7d 0a 20 20 7d 0a 7d 0a 0a  "] {wal}.  }.}..
fc30: 70 72 6f 63 20 77 61 6c 5f 69 73 5f 63 61 70 61  proc wal_is_capa
fc40: 62 6c 65 20 7b 7d 20 7b 0a 20 20 69 66 63 61 70  ble {} {.  ifcap
fc50: 61 62 6c 65 20 21 77 61 6c 20 7b 20 72 65 74 75  able !wal { retu
fc60: 72 6e 20 30 20 7d 0a 20 20 69 66 20 7b 5b 70 65  rn 0 }.  if {[pe
fc70: 72 6d 75 74 61 74 69 6f 6e 5d 3d 3d 22 6a 6f 75  rmutation]=="jou
fc80: 72 6e 61 6c 74 65 73 74 22 7d 20 7b 20 72 65 74  rnaltest"} { ret
fc90: 75 72 6e 20 30 20 7d 0a 20 20 72 65 74 75 72 6e  urn 0 }.  return
fca0: 20 31 0a 7d 0a 0a 70 72 6f 63 20 70 65 72 6d 75   1.}..proc permu
fcb0: 74 61 74 69 6f 6e 20 7b 7d 20 7b 0a 20 20 73 65  tation {} {.  se
fcc0: 74 20 70 65 72 6d 20 22 22 0a 20 20 63 61 74 63  t perm "".  catc
fcd0: 68 20 7b 73 65 74 20 70 65 72 6d 20 24 3a 3a 47  h {set perm $::G
fce0: 28 70 65 72 6d 3a 6e 61 6d 65 29 7d 0a 20 20 73  (perm:name)}.  s
fcf0: 65 74 20 70 65 72 6d 0a 7d 0a 70 72 6f 63 20 70  et perm.}.proc p
fd00: 72 65 73 71 6c 20 7b 7d 20 7b 0a 20 20 73 65 74  resql {} {.  set
fd10: 20 70 72 65 73 71 6c 20 22 22 0a 20 20 63 61 74   presql "".  cat
fd20: 63 68 20 7b 73 65 74 20 70 72 65 73 71 6c 20 24  ch {set presql $
fd30: 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c 29  ::G(perm:presql)
fd40: 7d 0a 20 20 73 65 74 20 70 72 65 73 71 6c 0a 7d  }.  set presql.}
fd50: 0a 0a 70 72 6f 63 20 69 73 71 75 69 63 6b 20 7b  ..proc isquick {
fd60: 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 30 0a  } {.  set ret 0.
fd70: 20 20 63 61 74 63 68 20 7b 73 65 74 20 72 65 74    catch {set ret
fd80: 20 24 3a 3a 47 28 69 73 71 75 69 63 6b 29 7d 0a   $::G(isquick)}.
fd90: 20 20 73 65 74 20 72 65 74 0a 7d 0a 0a 23 2d 2d    set ret.}..#--
fda0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fdb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fdc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fdd0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fde0: 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72 6f 63 20 73  -------.#.proc s
fdf0: 6c 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70 74  lave_test_script
fe00: 20 7b 73 63 72 69 70 74 7d 20 7b 0a 0a 20 20 23   {script} {..  #
fe10: 20 43 72 65 61 74 65 20 74 68 65 20 69 6e 74 65   Create the inte
fe20: 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f 20  rpreter used to 
fe30: 72 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  run the test scr
fe40: 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 63 72  ipt..  interp cr
fe50: 65 61 74 65 20 74 69 6e 74 65 72 70 0a 0a 20 20  eate tinterp..  
fe60: 23 20 50 6f 70 75 6c 61 74 65 20 73 6f 6d 65 20  # Populate some 
fe70: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  global variables
fe80: 20 74 68 61 74 20 74 65 73 74 65 72 2e 74 63 6c   that tester.tcl
fe90: 20 65 78 70 65 63 74 73 20 74 6f 20 73 65 65 2e   expects to see.
fea0: 0a 20 20 66 6f 72 65 61 63 68 20 7b 76 61 72 20  .  foreach {var 
feb0: 76 61 6c 75 65 7d 20 5b 6c 69 73 74 20 20 20 20  value} [list    
fec0: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
fed0: 3a 3a 61 72 67 76 30 20 24 3a 3a 61 72 67 76 30  ::argv0 $::argv0
fee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fef0: 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72 67       \.    ::arg
ff00: 76 20 20 7b 7d 20 20 20 20 20 20 20 20 20 20 20  v  {}           
ff10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ff20: 5c 0a 20 20 20 20 3a 3a 53 4c 41 56 45 20 31 20  \.    ::SLAVE 1 
ff30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ff40: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 5d             \.  ]
ff50: 20 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 65 76   {.    interp ev
ff60: 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73 74  al tinterp [list
ff70: 20 73 65 74 20 24 76 61 72 20 24 76 61 6c 75 65   set $var $value
ff80: 5d 0a 20 20 7d 0a 0a 20 20 23 20 49 66 20 6f 75  ].  }..  # If ou
ff90: 74 70 75 74 20 69 73 20 62 65 69 6e 67 20 63 6f  tput is being co
ffa0: 70 69 65 64 20 69 6e 74 6f 20 61 20 66 69 6c 65  pied into a file
ffb0: 2c 20 73 68 61 72 65 20 74 68 65 20 66 69 6c 65  , share the file
ffc0: 2d 64 65 73 63 72 69 70 74 6f 72 20 77 69 74 68  -descriptor with
ffd0: 0a 20 20 23 20 74 68 65 20 69 6e 74 65 72 70 72  .  # the interpr
ffe0: 65 74 65 72 2e 0a 20 20 69 66 20 7b 5b 69 6e 66  eter..  if {[inf
fff0: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6f 75 74  o exists ::G(out
10000 70 75 74 5f 66 64 29 5d 7d 20 7b 0a 20 20 20 20  put_fd)]} {.    
10010 69 6e 74 65 72 70 20 73 68 61 72 65 20 7b 7d 20  interp share {} 
10020 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 20  $::G(output_fd) 
10030 74 69 6e 74 65 72 70 0a 20 20 7d 0a 0a 20 20 23  tinterp.  }..  #
10040 20 54 68 65 20 61 6c 69 61 73 20 75 73 65 64 20   The alias used 
10050 74 6f 20 61 63 63 65 73 73 20 74 68 65 20 67 6c  to access the gl
10060 6f 62 61 6c 20 74 65 73 74 20 63 6f 75 6e 74 65  obal test counte
10070 72 73 2e 0a 20 20 74 69 6e 74 65 72 70 20 61 6c  rs..  tinterp al
10080 69 61 73 20 73 65 74 5f 74 65 73 74 5f 63 6f 75  ias set_test_cou
10090 6e 74 65 72 20 73 65 74 5f 74 65 73 74 5f 63 6f  nter set_test_co
100a0 75 6e 74 65 72 0a 0a 20 20 23 20 53 65 74 20 75  unter..  # Set u
100b0 70 20 74 68 65 20 3a 3a 63 6d 64 6c 69 6e 65 61  p the ::cmdlinea
100c0 72 67 20 61 72 72 61 79 20 69 6e 20 74 68 65 20  rg array in the 
100d0 73 6c 61 76 65 2e 0a 20 20 69 6e 74 65 72 70 20  slave..  interp 
100e0 65 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69  eval tinterp [li
100f0 73 74 20 61 72 72 61 79 20 73 65 74 20 3a 3a 63  st array set ::c
10100 6d 64 6c 69 6e 65 61 72 67 20 5b 61 72 72 61 79  mdlinearg [array
10110 20 67 65 74 20 3a 3a 63 6d 64 6c 69 6e 65 61 72   get ::cmdlinear
10120 67 5d 5d 0a 0a 20 20 23 20 53 65 74 20 75 70 20  g]]..  # Set up 
10130 74 68 65 20 3a 3a 47 20 61 72 72 61 79 20 69 6e  the ::G array in
10140 20 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69 6e   the slave..  in
10150 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72  terp eval tinter
10160 70 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73 65  p [list array se
10170 74 20 3a 3a 47 20 5b 61 72 72 61 79 20 67 65 74  t ::G [array get
10180 20 3a 3a 47 5d 5d 0a 0a 20 20 23 20 4c 6f 61 64   ::G]]..  # Load
10190 20 74 68 65 20 76 61 72 69 6f 75 73 20 74 65 73   the various tes
101a0 74 20 69 6e 74 65 72 66 61 63 65 73 20 69 6d 70  t interfaces imp
101b0 6c 65 6d 65 6e 74 65 64 20 69 6e 20 43 2e 0a 20  lemented in C.. 
101c0 20 6c 6f 61 64 5f 74 65 73 74 66 69 78 74 75 72   load_testfixtur
101d0 65 5f 65 78 74 65 6e 73 69 6f 6e 73 20 74 69 6e  e_extensions tin
101e0 74 65 72 70 0a 0a 20 20 23 20 52 75 6e 20 74 68  terp..  # Run th
101f0 65 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20  e test script.. 
10200 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e   interp eval tin
10210 74 65 72 70 20 24 73 63 72 69 70 74 0a 0a 20 20  terp $script..  
10220 23 20 43 68 65 63 6b 20 69 66 20 74 68 65 20 69  # Check if the i
10230 6e 74 65 72 70 72 65 74 65 72 20 63 61 6c 6c 20  nterpreter call 
10240 5b 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74  [run_thread_test
10250 73 5d 0a 20 20 69 66 20 7b 20 5b 69 6e 74 65 72  s].  if { [inter
10260 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20 7b  p eval tinterp {
10270 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72 75  info exists ::ru
10280 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63  n_thread_tests_c
10290 61 6c 6c 65 64 7d 5d 20 7d 20 7b 0a 20 20 20 20  alled}] } {.    
102a0 73 65 74 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64  set ::run_thread
102b0 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 20 31 0a  _tests_called 1.
102c0 20 20 7d 0a 0a 20 20 23 20 44 65 6c 65 74 65 20    }..  # Delete 
102d0 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72 20  the interpreter 
102e0 75 73 65 64 20 74 6f 20 72 75 6e 20 74 68 65 20  used to run the 
102f0 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20 69  test script..  i
10300 6e 74 65 72 70 20 64 65 6c 65 74 65 20 74 69 6e  nterp delete tin
10310 74 65 72 70 0a 7d 0a 0a 70 72 6f 63 20 73 6c 61  terp.}..proc sla
10320 76 65 5f 74 65 73 74 5f 66 69 6c 65 20 7b 7a 46  ve_test_file {zF
10330 69 6c 65 7d 20 7b 0a 20 20 73 65 74 20 74 61 69  ile} {.  set tai
10340 6c 20 5b 66 69 6c 65 20 74 61 69 6c 20 24 7a 46  l [file tail $zF
10350 69 6c 65 5d 0a 0a 20 20 69 66 20 7b 5b 69 6e 66  ile]..  if {[inf
10360 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73 74 61  o exists ::G(sta
10370 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 5d  rt:permutation)]
10380 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 70 65 72  } {.    if {[per
10390 6d 75 74 61 74 69 6f 6e 5d 20 21 3d 20 24 3a 3a  mutation] != $::
103a0 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74  G(start:permutat
103b0 69 6f 6e 29 7d 20 72 65 74 75 72 6e 0a 20 20 20  ion)} return.   
103c0 20 75 6e 73 65 74 20 3a 3a 47 28 73 74 61 72 74   unset ::G(start
103d0 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 0a 20 20  :permutation).  
103e0 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  }.  if {[info ex
103f0 69 73 74 73 20 3a 3a 47 28 73 74 61 72 74 3a 66  ists ::G(start:f
10400 69 6c 65 29 5d 7d 20 7b 0a 20 20 20 20 69 66 20  ile)]} {.    if 
10410 7b 24 74 61 69 6c 20 21 3d 20 24 3a 3a 47 28 73  {$tail != $::G(s
10420 74 61 72 74 3a 66 69 6c 65 29 20 26 26 20 24 74  tart:file) && $t
10430 61 69 6c 21 3d 22 24 3a 3a 47 28 73 74 61 72 74  ail!="$::G(start
10440 3a 66 69 6c 65 29 2e 74 65 73 74 22 7d 20 72 65  :file).test"} re
10450 74 75 72 6e 0a 20 20 20 20 75 6e 73 65 74 20 3a  turn.    unset :
10460 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 0a 20  :G(start:file). 
10470 20 7d 0a 0a 20 20 23 20 52 65 6d 65 6d 62 65 72   }..  # Remember
10480 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68   the value of th
10490 65 20 73 68 61 72 65 64 2d 63 61 63 68 65 20 73  e shared-cache s
104a0 65 74 74 69 6e 67 2e 20 53 6f 20 74 68 61 74 20  etting. So that 
104b0 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65 0a 20  it is possible. 
104c0 20 23 20 74 6f 20 63 68 65 63 6b 20 61 66 74 65   # to check afte
104d0 72 77 61 72 64 73 20 74 68 61 74 20 69 74 20 77  rwards that it w
104e0 61 73 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64 20  as not modified 
104f0 62 79 20 74 68 65 20 74 65 73 74 20 73 63 72 69  by the test scri
10500 70 74 2e 0a 20 20 23 0a 20 20 69 66 63 61 70 61  pt..  #.  ifcapa
10510 62 6c 65 20 73 68 61 72 65 64 5f 63 61 63 68 65  ble shared_cache
10520 20 7b 20 73 65 74 20 73 63 73 20 5b 73 71 6c 69   { set scs [sqli
10530 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65  te3_enable_share
10540 64 5f 63 61 63 68 65 5d 20 7d 0a 0a 20 20 23 20  d_cache] }..  # 
10550 52 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  Run the test scr
10560 69 70 74 20 69 6e 20 61 20 73 6c 61 76 65 20 69  ipt in a slave i
10570 6e 74 65 72 70 72 65 74 65 72 2e 0a 20 20 23 0a  nterpreter..  #.
10580 20 20 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c    unset -nocompl
10590 61 69 6e 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64  ain ::run_thread
105a0 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 0a 20 20  _tests_called.  
105b0 72 65 73 65 74 5f 70 72 6e 67 5f 73 74 61 74 65  reset_prng_state
105c0 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f  .  set ::sqlite_
105d0 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20  open_file_count 
105e0 30 0a 20 20 73 65 74 20 74 69 6d 65 20 5b 74 69  0.  set time [ti
105f0 6d 65 20 7b 20 73 6c 61 76 65 5f 74 65 73 74 5f  me { slave_test_
10600 73 63 72 69 70 74 20 5b 6c 69 73 74 20 73 6f 75  script [list sou
10610 72 63 65 20 24 7a 46 69 6c 65 5d 20 7d 5d 0a 20  rce $zFile] }]. 
10620 20 73 65 74 20 6d 73 20 5b 65 78 70 72 20 5b 6c   set ms [expr [l
10630 69 6e 64 65 78 20 24 74 69 6d 65 20 30 5d 20 2f  index $time 0] /
10640 20 31 30 30 30 5d 0a 0a 20 20 23 20 54 65 73 74   1000]..  # Test
10650 20 74 68 61 74 20 61 6c 6c 20 66 69 6c 65 73 20   that all files 
10660 6f 70 65 6e 65 64 20 62 79 20 74 68 65 20 74 65  opened by the te
10670 73 74 20 73 63 72 69 70 74 20 77 65 72 65 20 63  st script were c
10680 6c 6f 73 65 64 2e 20 4f 6d 69 74 20 74 68 69 73  losed. Omit this
10690 0a 20 20 23 20 69 66 20 74 68 65 20 74 65 73 74  .  # if the test
106a0 20 73 63 72 69 70 74 20 68 61 73 20 22 74 68 72   script has "thr
106b0 65 61 64 22 20 69 6e 20 69 74 73 20 6e 61 6d 65  ead" in its name
106c0 2e 20 54 68 65 20 6f 70 65 6e 20 66 69 6c 65 20  . The open file 
106d0 63 6f 75 6e 74 65 72 0a 20 20 23 20 69 73 20 6e  counter.  # is n
106e0 6f 74 20 74 68 72 65 61 64 2d 73 61 66 65 2e 0a  ot thread-safe..
106f0 20 20 23 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20    #.  if {[info 
10700 65 78 69 73 74 73 20 3a 3a 72 75 6e 5f 74 68 72  exists ::run_thr
10710 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64  ead_tests_called
10720 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 64 6f 5f 74  ]==0} {.    do_t
10730 65 73 74 20 24 7b 74 61 69 6c 7d 2d 63 6c 6f 73  est ${tail}-clos
10740 65 61 6c 6c 66 69 6c 65 73 20 7b 20 65 78 70 72  eallfiles { expr
10750 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e   {$::sqlite_open
10760 5f 66 69 6c 65 5f 63 6f 75 6e 74 3e 30 7d 20 7d  _file_count>0} }
10770 20 7b 30 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a   {0}.  }.  set :
10780 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c  :sqlite_open_fil
10790 65 5f 63 6f 75 6e 74 20 30 0a 0a 20 20 23 20 54  e_count 0..  # T
107a0 65 73 74 20 74 68 61 74 20 74 68 65 20 67 6c 6f  est that the glo
107b0 62 61 6c 20 22 73 68 61 72 65 64 2d 63 61 63 68  bal "shared-cach
107c0 65 22 20 73 65 74 74 69 6e 67 20 77 61 73 20 6e  e" setting was n
107d0 6f 74 20 61 6c 74 65 72 65 64 20 62 79 0a 20 20  ot altered by.  
107e0 23 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  # the test scrip
107f0 74 2e 0a 20 20 23 0a 20 20 69 66 63 61 70 61 62  t..  #.  ifcapab
10800 6c 65 20 73 68 61 72 65 64 5f 63 61 63 68 65 20  le shared_cache 
10810 7b 0a 20 20 20 20 73 65 74 20 72 65 73 20 5b 65  {.    set res [e
10820 78 70 72 20 7b 5b 73 71 6c 69 74 65 33 5f 65 6e  xpr {[sqlite3_en
10830 61 62 6c 65 5f 73 68 61 72 65 64 5f 63 61 63 68  able_shared_cach
10840 65 5d 20 3d 3d 20 24 73 63 73 7d 5d 0a 20 20 20  e] == $scs}].   
10850 20 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c 7d   do_test ${tail}
10860 2d 73 68 61 72 65 64 63 61 63 68 65 73 65 74 74  -sharedcachesett
10870 69 6e 67 20 5b 6c 69 73 74 20 73 65 74 20 7b 7d  ing [list set {}
10880 20 24 72 65 73 5d 20 31 0a 20 20 7d 0a 0a 20 20   $res] 1.  }..  
10890 23 20 41 64 64 20 73 6f 6d 65 20 69 6e 66 6f 20  # Add some info 
108a0 74 6f 20 74 68 65 20 6f 75 74 70 75 74 2e 0a 20  to the output.. 
108b0 20 23 0a 20 20 6f 75 74 70 75 74 32 20 22 54 69   #.  output2 "Ti
108c0 6d 65 3a 20 24 74 61 69 6c 20 24 6d 73 20 6d 73  me: $tail $ms ms
108d0 22 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74  ".  show_memstat
108e0 73 0a 7d 0a 0a 23 20 4f 70 65 6e 20 61 20 6e 65  s.}..# Open a ne
108f0 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6f 6e 20  w connection on 
10900 64 61 74 61 62 61 73 65 20 74 65 73 74 2e 64 62  database test.db
10910 20 61 6e 64 20 65 78 65 63 75 74 65 20 74 68 65   and execute the
10920 20 53 51 4c 20 73 63 72 69 70 74 0a 23 20 73 75   SQL script.# su
10930 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67  pplied as an arg
10940 75 6d 65 6e 74 2e 20 42 65 66 6f 72 65 20 72 65  ument. Before re
10950 74 75 72 6e 69 6e 67 2c 20 63 6c 6f 73 65 20 74  turning, close t
10960 68 65 20 6e 65 77 20 63 6f 6e 65 63 74 69 6f 6e  he new conection
10970 20 61 6e 64 0a 23 20 72 65 73 74 6f 72 65 20 74   and.# restore t
10980 68 65 20 34 20 62 79 74 65 20 66 69 65 6c 64 73  he 4 byte fields
10990 20 73 74 61 72 74 69 6e 67 20 61 74 20 68 65 61   starting at hea
109a0 64 65 72 20 6f 66 66 73 65 74 73 20 32 38 2c 20  der offsets 28, 
109b0 39 32 20 61 6e 64 20 39 36 0a 23 20 74 6f 20 74  92 and 96.# to t
109c0 68 65 20 76 61 6c 75 65 73 20 74 68 65 79 20 68  he values they h
109d0 65 6c 64 20 62 65 66 6f 72 65 20 74 68 65 20 53  eld before the S
109e0 51 4c 20 77 61 73 20 65 78 65 63 75 74 65 64 2e  QL was executed.
109f0 20 54 68 69 73 20 73 69 6d 75 6c 61 74 65 73 0a   This simulates.
10a00 23 20 61 20 77 72 69 74 65 20 62 79 20 61 20 70  # a write by a p
10a10 72 65 2d 33 2e 37 2e 30 20 63 6c 69 65 6e 74 2e  re-3.7.0 client.
10a20 0a 23 0a 70 72 6f 63 20 73 71 6c 33 36 32 33 31  .#.proc sql36231
10a30 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 42   {sql} {.  set B
10a40 20 5b 68 65 78 69 6f 5f 72 65 61 64 20 74 65 73   [hexio_read tes
10a50 74 2e 64 62 20 39 32 20 38 5d 0a 20 20 73 65 74  t.db 92 8].  set
10a60 20 41 20 5b 68 65 78 69 6f 5f 72 65 61 64 20 74   A [hexio_read t
10a70 65 73 74 2e 64 62 20 32 38 20 34 5d 0a 20 20 73  est.db 28 4].  s
10a80 71 6c 69 74 65 33 20 64 62 33 36 32 33 31 20 74  qlite3 db36231 t
10a90 65 73 74 2e 64 62 0a 20 20 63 61 74 63 68 20 7b  est.db.  catch {
10aa0 20 64 62 33 36 32 33 31 20 66 75 6e 63 20 61 5f   db36231 func a_
10ab0 73 74 72 69 6e 67 20 61 5f 73 74 72 69 6e 67 20  string a_string 
10ac0 7d 0a 20 20 65 78 65 63 73 71 6c 20 24 73 71 6c  }.  execsql $sql
10ad0 20 64 62 33 36 32 33 31 0a 20 20 64 62 33 36 32   db36231.  db362
10ae0 33 31 20 63 6c 6f 73 65 0a 20 20 68 65 78 69 6f  31 close.  hexio
10af0 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62 20 32  _write test.db 2
10b00 38 20 24 41 0a 20 20 68 65 78 69 6f 5f 77 72 69  8 $A.  hexio_wri
10b10 74 65 20 74 65 73 74 2e 64 62 20 39 32 20 24 42  te test.db 92 $B
10b20 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d 0a 0a  .  return "".}..
10b30 70 72 6f 63 20 64 62 5f 73 61 76 65 20 7b 7d 20  proc db_save {} 
10b40 7b 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  {.  foreach f [g
10b50 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
10b60 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b 20 66  sv_test.db*] { f
10b70 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20 7d 0a  orcedelete $f }.
10b80 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f    foreach f [glo
10b90 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65  b -nocomplain te
10ba0 73 74 2e 64 62 2a 5d 20 7b 0a 20 20 20 20 73 65  st.db*] {.    se
10bb0 74 20 66 32 20 22 73 76 5f 24 66 22 0a 20 20 20  t f2 "sv_$f".   
10bc0 20 66 6f 72 63 65 63 6f 70 79 20 24 66 20 24 66   forcecopy $f $f
10bd0 32 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 62 5f  2.  }.}.proc db_
10be0 73 61 76 65 5f 61 6e 64 5f 63 6c 6f 73 65 20 7b  save_and_close {
10bf0 7d 20 7b 0a 20 20 64 62 5f 73 61 76 65 0a 20 20  } {.  db_save.  
10c00 63 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65  catch { db close
10c10 20 7d 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d   }.  return "".}
10c20 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f 72 65  .proc db_restore
10c30 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20   {} {.  foreach 
10c40 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
10c50 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b 20  ain test.db*] { 
10c60 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20 7d  forcedelete $f }
10c70 0a 20 20 66 6f 72 65 61 63 68 20 66 32 20 5b 67  .  foreach f2 [g
10c80 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
10c90 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b 0a 20  sv_test.db*] {. 
10ca0 20 20 20 73 65 74 20 66 20 5b 73 74 72 69 6e 67     set f [string
10cb0 20 72 61 6e 67 65 20 24 66 32 20 33 20 65 6e 64   range $f2 3 end
10cc0 5d 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79 20  ].    forcecopy 
10cd0 24 66 32 20 24 66 0a 20 20 7d 0a 7d 0a 70 72 6f  $f2 $f.  }.}.pro
10ce0 63 20 64 62 5f 72 65 73 74 6f 72 65 5f 61 6e 64  c db_restore_and
10cf0 5f 72 65 6f 70 65 6e 20 7b 7b 64 62 66 69 6c 65  _reopen {{dbfile
10d00 20 74 65 73 74 2e 64 62 7d 7d 20 7b 0a 20 20 63   test.db}} {.  c
10d10 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65 20  atch { db close 
10d20 7d 0a 20 20 64 62 5f 72 65 73 74 6f 72 65 0a 20  }.  db_restore. 
10d30 20 73 71 6c 69 74 65 33 20 64 62 20 24 64 62 66   sqlite3 db $dbf
10d40 69 6c 65 0a 7d 0a 70 72 6f 63 20 64 62 5f 64 65  ile.}.proc db_de
10d50 6c 65 74 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20  lete_and_reopen 
10d60 7b 7b 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d  {{file test.db}}
10d70 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20   {.  catch { db 
10d80 63 6c 6f 73 65 20 7d 0a 20 20 66 6f 72 65 61 63  close }.  foreac
10d90 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
10da0 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20  plain test.db*] 
10db0 7b 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66  { forcedelete $f
10dc0 20 7d 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20   }.  sqlite3 db 
10dd0 24 66 69 6c 65 0a 7d 0a 0a 23 20 43 6c 6f 73 65  $file.}..# Close
10de0 20 61 6e 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 73   any connections
10df0 20 6e 61 6d 65 64 20 5b 64 62 5d 2c 20 5b 64 62   named [db], [db
10e00 32 5d 20 6f 72 20 5b 64 62 33 5d 2e 20 54 68 65  2] or [db3]. The
10e10 6e 20 75 73 65 20 73 71 6c 69 74 65 33 5f 63 6f  n use sqlite3_co
10e20 6e 66 69 67 0a 23 20 74 6f 20 63 6f 6e 66 69 67  nfig.# to config
10e30 75 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ure the size of 
10e40 74 68 65 20 50 41 47 45 43 41 43 48 45 20 61 6c  the PAGECACHE al
10e50 6c 6f 63 61 74 69 6f 6e 20 75 73 69 6e 67 20 74  location using t
10e60 68 65 20 70 61 72 61 6d 65 74 65 72 73 0a 23 20  he parameters.# 
10e70 70 72 6f 76 69 64 65 64 20 74 6f 20 74 68 69 73  provided to this
10e80 20 63 6f 6d 6d 61 6e 64 2e 20 53 61 76 65 20 74   command. Save t
10e90 68 65 20 6f 6c 64 20 50 41 47 45 43 41 43 48 45  he old PAGECACHE
10ea0 20 70 61 72 61 6d 65 74 65 72 73 20 69 6e 20 61   parameters in a
10eb0 20 67 6c 6f 62 61 6c 20 0a 23 20 76 61 72 69 61   global .# varia
10ec0 62 6c 65 20 73 6f 20 74 68 61 74 20 5b 74 65 73  ble so that [tes
10ed0 74 5f 72 65 73 74 6f 72 65 5f 63 6f 6e 66 69 67  t_restore_config
10ee0 5f 70 61 67 65 63 61 63 68 65 5d 20 63 61 6e 20  _pagecache] can 
10ef0 72 65 73 74 6f 72 65 20 74 68 65 20 70 72 65 76  restore the prev
10f00 69 6f 75 73 0a 23 20 63 6f 6e 66 69 67 75 72 61  ious.# configura
10f10 74 69 6f 6e 2e 0a 23 0a 23 20 42 65 66 6f 72 65  tion..#.# Before
10f20 20 72 65 74 75 72 6e 69 6e 67 2c 20 72 65 6f 70   returning, reop
10f30 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64  en connection [d
10f40 62 5d 20 6f 6e 20 66 69 6c 65 20 74 65 73 74 2e  b] on file test.
10f50 64 62 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f  db..#.proc test_
10f60 73 65 74 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63  set_config_pagec
10f70 61 63 68 65 20 7b 73 7a 20 6e 50 67 7d 20 7b 0a  ache {sz nPg} {.
10f80 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73    catch {db clos
10f90 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20  e}.  catch {db2 
10fa0 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b  close}.  catch {
10fb0 64 62 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 73 71  db3 close}..  sq
10fc0 6c 69 74 65 33 5f 73 68 75 74 64 6f 77 6e 0a 20  lite3_shutdown. 
10fd0 20 73 65 74 20 3a 3a 6f 6c 64 5f 70 61 67 65 63   set ::old_pagec
10fe0 61 63 68 65 5f 63 6f 6e 66 69 67 20 5b 73 71 6c  ache_config [sql
10ff0 69 74 65 33 5f 63 6f 6e 66 69 67 5f 70 61 67 65  ite3_config_page
11000 63 61 63 68 65 20 24 73 7a 20 24 6e 50 67 5d 0a  cache $sz $nPg].
11010 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61    sqlite3_initia
11020 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74 61  lize.  autoinsta
11030 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e  ll_test_function
11040 73 0a 20 20 72 65 73 65 74 5f 64 62 0a 7d 0a 0a  s.  reset_db.}..
11050 23 20 43 6c 6f 73 65 20 61 6e 79 20 63 6f 6e 6e  # Close any conn
11060 65 63 74 69 6f 6e 73 20 6e 61 6d 65 64 20 5b 64  ections named [d
11070 62 5d 2c 20 5b 64 62 32 5d 20 6f 72 20 5b 64 62  b], [db2] or [db
11080 33 5d 2e 20 54 68 65 6e 20 75 73 65 20 73 71 6c  3]. Then use sql
11090 69 74 65 33 5f 63 6f 6e 66 69 67 0a 23 20 74 6f  ite3_config.# to
110a0 20 63 6f 6e 66 69 67 75 72 65 20 74 68 65 20 73   configure the s
110b0 69 7a 65 20 6f 66 20 74 68 65 20 50 41 47 45 43  ize of the PAGEC
110c0 41 43 48 45 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  ACHE allocation 
110d0 74 6f 20 74 68 65 20 73 69 7a 65 20 73 61 76 65  to the size save
110e0 64 20 69 6e 0a 23 20 74 68 65 20 67 6c 6f 62 61  d in.# the globa
110f0 6c 20 76 61 72 69 61 62 6c 65 20 62 79 20 61 6e  l variable by an
11100 20 65 61 72 6c 69 65 72 20 63 61 6c 6c 20 74 6f   earlier call to
11110 20 5b 74 65 73 74 5f 73 65 74 5f 63 6f 6e 66 69   [test_set_confi
11120 67 5f 70 61 67 65 63 61 63 68 65 5d 2e 0a 23 0a  g_pagecache]..#.
11130 23 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69  # Before returni
11140 6e 67 2c 20 72 65 6f 70 65 6e 20 63 6f 6e 6e 65  ng, reopen conne
11150 63 74 69 6f 6e 20 5b 64 62 5d 20 6f 6e 20 66 69  ction [db] on fi
11160 6c 65 20 74 65 73 74 2e 64 62 2e 0a 23 0a 70 72  le test.db..#.pr
11170 6f 63 20 74 65 73 74 5f 72 65 73 74 6f 72 65 5f  oc test_restore_
11180 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65  config_pagecache
11190 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64   {} {.  catch {d
111a0 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
111b0 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
111c0 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d  atch {db3 close}
111d0 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  ..  sqlite3_shut
111e0 64 6f 77 6e 0a 20 20 65 76 61 6c 20 73 71 6c 69  down.  eval sqli
111f0 74 65 33 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63  te3_config_pagec
11200 61 63 68 65 20 24 3a 3a 6f 6c 64 5f 70 61 67 65  ache $::old_page
11210 63 61 63 68 65 5f 63 6f 6e 66 69 67 0a 20 20 75  cache_config.  u
11220 6e 73 65 74 20 3a 3a 6f 6c 64 5f 70 61 67 65 63  nset ::old_pagec
11230 61 63 68 65 5f 63 6f 6e 66 69 67 20 0a 20 20 73  ache_config .  s
11240 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a  qlite3_initializ
11250 65 0a 20 20 61 75 74 6f 69 6e 73 74 61 6c 6c 5f  e.  autoinstall_
11260 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e 73 0a 20  test_functions. 
11270 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74   sqlite3 db test
11280 2e 64 62 0a 7d 0a 0a 70 72 6f 63 20 74 65 73 74  .db.}..proc test
11290 5f 62 69 6e 61 72 79 5f 6e 61 6d 65 20 7b 6e 6d  _binary_name {nm
112a0 7d 20 7b 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c  } {.  if {$::tcl
112b0 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f  _platform(platfo
112c0 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d 20  rm)=="windows"} 
112d0 7b 0a 20 20 20 20 73 65 74 20 72 65 74 20 22 24  {.    set ret "$
112e0 6e 6d 2e 65 78 65 22 0a 20 20 7d 20 65 6c 73 65  nm.exe".  } else
112f0 20 7b 0a 20 20 20 20 73 65 74 20 72 65 74 20 24   {.    set ret $
11300 6e 6d 0a 20 20 7d 0a 20 20 66 69 6c 65 20 6e 6f  nm.  }.  file no
11310 72 6d 61 6c 69 7a 65 20 5b 66 69 6c 65 20 6a 6f  rmalize [file jo
11320 69 6e 20 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67  in $::cmdlinearg
11330 28 54 45 53 54 46 49 58 54 55 52 45 5f 48 4f 4d  (TESTFIXTURE_HOM
11340 45 29 20 24 72 65 74 5d 0a 7d 0a 0a 70 72 6f 63  E) $ret].}..proc
11350 20 74 65 73 74 5f 66 69 6e 64 5f 62 69 6e 61 72   test_find_binar
11360 79 20 7b 6e 6d 7d 20 7b 0a 20 20 73 65 74 20 72  y {nm} {.  set r
11370 65 74 20 5b 74 65 73 74 5f 62 69 6e 61 72 79 5f  et [test_binary_
11380 6e 61 6d 65 20 24 6e 6d 5d 0a 20 20 69 66 20 7b  name $nm].  if {
11390 21 5b 66 69 6c 65 20 65 78 65 63 75 74 61 62 6c  ![file executabl
113a0 65 20 24 72 65 74 5d 7d 20 7b 0a 20 20 20 20 66  e $ret]} {.    f
113b0 69 6e 69 73 68 5f 74 65 73 74 0a 20 20 20 20 72  inish_test.    r
113c0 65 74 75 72 6e 20 22 22 0a 20 20 7d 0a 20 20 72  eturn "".  }.  r
113d0 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23 20  eturn $ret.}..# 
113e0 46 69 6e 64 20 74 68 65 20 6e 61 6d 65 20 6f 66  Find the name of
113f0 20 74 68 65 20 27 73 68 65 6c 6c 27 20 65 78 65   the 'shell' exe
11400 63 75 74 61 62 6c 65 20 28 65 2e 67 2e 20 22 73  cutable (e.g. "s
11410 71 6c 69 74 65 33 2e 65 78 65 22 29 20 74 6f 20  qlite3.exe") to 
11420 75 73 65 20 66 6f 72 0a 23 20 74 68 65 20 74 65  use for.# the te
11430 73 74 73 20 69 6e 20 73 68 65 6c 6c 5b 31 2d 35  sts in shell[1-5
11440 5d 2e 74 65 73 74 2e 20 49 66 20 6e 6f 20 73 75  ].test. If no su
11450 63 68 20 65 78 65 63 75 74 61 62 6c 65 20 63 61  ch executable ca
11460 6e 20 62 65 20 66 6f 75 6e 64 2c 20 69 6e 76 6f  n be found, invo
11470 6b 65 0a 23 20 5b 66 69 6e 69 73 68 5f 74 65 73  ke.# [finish_tes
11480 74 20 3b 20 72 65 74 75 72 6e 5d 20 69 6e 20 74  t ; return] in t
11490 68 65 20 63 61 6c 6c 65 72 73 20 63 6f 6e 74 65  he callers conte
114a0 78 74 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f  xt..#.proc test_
114b0 66 69 6e 64 5f 63 6c 69 20 7b 7d 20 7b 0a 20 20  find_cli {} {.  
114c0 73 65 74 20 70 72 6f 67 20 5b 74 65 73 74 5f 66  set prog [test_f
114d0 69 6e 64 5f 62 69 6e 61 72 79 20 73 71 6c 69 74  ind_binary sqlit
114e0 65 33 5d 0a 20 20 69 66 20 7b 24 70 72 6f 67 3d  e3].  if {$prog=
114f0 3d 22 22 7d 20 7b 20 72 65 74 75 72 6e 20 2d 63  =""} { return -c
11500 6f 64 65 20 72 65 74 75 72 6e 20 7d 0a 20 20 72  ode return }.  r
11510 65 74 75 72 6e 20 24 70 72 6f 67 0a 7d 0a 0a 23  eturn $prog.}..#
11520 20 46 69 6e 64 20 74 68 65 20 6e 61 6d 65 20 6f   Find the name o
11530 66 20 74 68 65 20 27 73 71 6c 64 69 66 66 27 20  f the 'sqldiff' 
11540 65 78 65 63 75 74 61 62 6c 65 20 28 65 2e 67 2e  executable (e.g.
11550 20 22 73 71 6c 69 74 65 33 2e 65 78 65 22 29 20   "sqlite3.exe") 
11560 74 6f 20 75 73 65 20 66 6f 72 0a 23 20 74 68 65  to use for.# the
11570 20 74 65 73 74 73 20 69 6e 20 73 71 6c 64 69 66   tests in sqldif
11580 66 20 74 65 73 74 73 2e 20 49 66 20 6e 6f 20 73  f tests. If no s
11590 75 63 68 20 65 78 65 63 75 74 61 62 6c 65 20 63  uch executable c
115a0 61 6e 20 62 65 20 66 6f 75 6e 64 2c 20 69 6e 76  an be found, inv
115b0 6f 6b 65 0a 23 20 5b 66 69 6e 69 73 68 5f 74 65  oke.# [finish_te
115c0 73 74 20 3b 20 72 65 74 75 72 6e 5d 20 69 6e 20  st ; return] in 
115d0 74 68 65 20 63 61 6c 6c 65 72 73 20 63 6f 6e 74  the callers cont
115e0 65 78 74 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74  ext..#.proc test
115f0 5f 66 69 6e 64 5f 73 71 6c 64 69 66 66 20 7b 7d  _find_sqldiff {}
11600 20 7b 0a 20 20 73 65 74 20 70 72 6f 67 20 5b 74   {.  set prog [t
11610 65 73 74 5f 66 69 6e 64 5f 62 69 6e 61 72 79 20  est_find_binary 
11620 73 71 6c 64 69 66 66 5d 0a 20 20 69 66 20 7b 24  sqldiff].  if {$
11630 70 72 6f 67 3d 3d 22 22 7d 20 7b 20 72 65 74 75  prog==""} { retu
11640 72 6e 20 2d 63 6f 64 65 20 72 65 74 75 72 6e 20  rn -code return 
11650 7d 0a 20 20 72 65 74 75 72 6e 20 24 70 72 6f 67  }.  return $prog
11660 0a 7d 0a 0a 23 20 43 61 6c 6c 20 73 71 6c 69 74  .}..# Call sqlit
11670 65 33 5f 65 78 70 61 6e 64 65 64 5f 73 71 6c 28  e3_expanded_sql(
11680 29 20 6f 6e 20 61 6c 6c 20 73 74 61 74 65 6d 65  ) on all stateme
11690 6e 74 73 20 61 73 73 6f 63 69 61 74 65 64 20 77  nts associated w
116a0 69 74 68 20 64 61 74 61 62 61 73 65 0a 23 20 63  ith database.# c
116b0 6f 6e 6e 65 63 74 69 6f 6e 20 24 64 62 2e 20 54  onnection $db. T
116c0 68 69 73 20 73 6f 6d 65 74 69 6d 65 73 20 66 69  his sometimes fi
116d0 6e 64 73 20 75 73 65 2d 61 66 74 65 72 2d 66 72  nds use-after-fr
116e0 65 65 20 62 75 67 73 20 69 66 20 72 75 6e 20 77  ee bugs if run w
116f0 69 74 68 0a 23 20 76 61 6c 67 72 69 6e 64 20 6f  ith.# valgrind o
11700 72 20 61 64 64 72 65 73 73 2d 73 61 6e 69 74 69  r address-saniti
11710 7a 65 72 2e 0a 70 72 6f 63 20 65 78 70 61 6e 64  zer..proc expand
11720 5f 61 6c 6c 5f 73 71 6c 20 7b 64 62 7d 20 7b 0a  _all_sql {db} {.
11730 20 20 73 65 74 20 73 74 6d 74 20 22 22 0a 20 20    set stmt "".  
11740 77 68 69 6c 65 20 7b 5b 73 65 74 20 73 74 6d 74  while {[set stmt
11750 20 5b 73 71 6c 69 74 65 33 5f 6e 65 78 74 5f 73   [sqlite3_next_s
11760 74 6d 74 20 24 64 62 20 24 73 74 6d 74 5d 5d 21  tmt $db $stmt]]!
11770 3d 22 22 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74  =""} {.    sqlit
11780 65 33 5f 65 78 70 61 6e 64 65 64 5f 73 71 6c 20  e3_expanded_sql 
11790 24 73 74 6d 74 0a 20 20 7d 0a 7d 0a 0a 0a 23 20  $stmt.  }.}...# 
117a0 49 66 20 74 68 65 20 6c 69 62 72 61 72 79 20 69  If the library i
117b0 73 20 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20  s compiled with 
117c0 74 68 65 20 53 51 4c 49 54 45 5f 44 45 46 41 55  the SQLITE_DEFAU
117d0 4c 54 5f 41 55 54 4f 56 41 43 55 55 4d 20 6d 61  LT_AUTOVACUUM ma
117e0 63 72 6f 20 73 65 74 0a 23 20 74 6f 20 6e 6f 6e  cro set.# to non
117f0 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 73 65 74 20  -zero, then set 
11800 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  the global varia
11810 62 6c 65 20 24 41 55 54 4f 56 41 43 55 55 4d 20  ble $AUTOVACUUM 
11820 74 6f 20 31 2e 0a 73 65 74 20 41 55 54 4f 56 41  to 1..set AUTOVA
11830 43 55 55 4d 20 24 73 71 6c 69 74 65 5f 6f 70 74  CUUM $sqlite_opt
11840 69 6f 6e 73 28 64 65 66 61 75 6c 74 5f 61 75 74  ions(default_aut
11850 6f 76 61 63 75 75 6d 29 0a 0a 23 20 4d 61 6b 65  ovacuum)..# Make
11860 20 73 75 72 65 20 74 68 65 20 46 54 53 20 65 6e   sure the FTS en
11870 68 61 6e 63 65 64 20 71 75 65 72 79 20 73 79 6e  hanced query syn
11880 74 61 78 20 69 73 20 64 69 73 61 62 6c 65 64 2e  tax is disabled.
11890 0a 73 65 74 20 73 71 6c 69 74 65 5f 66 74 73 33  .set sqlite_fts3
118a0 5f 65 6e 61 62 6c 65 5f 70 61 72 65 6e 74 68 65  _enable_parenthe
118b0 73 65 73 20 30 0a 0a 23 20 44 75 72 69 6e 67 20  ses 0..# During 
118c0 74 65 73 74 69 6e 67 2c 20 61 73 73 75 6d 65 20  testing, assume 
118d0 74 68 61 74 20 61 6c 6c 20 64 61 74 61 62 61 73  that all databas
118e0 65 20 66 69 6c 65 73 20 61 72 65 20 77 65 6c 6c  e files are well
118f0 2d 66 6f 72 6d 65 64 2e 20 20 54 68 65 0a 23 20  -formed.  The.# 
11900 66 65 77 20 74 65 73 74 20 63 61 73 65 73 20 74  few test cases t
11910 68 61 74 20 64 65 6c 69 62 65 72 61 74 65 6c 79  hat deliberately
11920 20 63 6f 72 72 75 70 74 20 64 61 74 61 62 61 73   corrupt databas
11930 65 20 66 69 6c 65 73 20 73 68 6f 75 6c 64 20 72  e files should r
11940 65 73 63 69 6e 64 20 0a 23 20 74 68 69 73 20 73  escind .# this s
11950 65 74 74 69 6e 67 20 62 79 20 69 6e 76 6f 6b 69  etting by invoki
11960 6e 67 20 22 64 61 74 61 62 61 73 65 5f 63 61 6e  ng "database_can
11970 5f 62 65 5f 63 6f 72 72 75 70 74 22 0a 23 0a 64  _be_corrupt".#.d
11980 61 74 61 62 61 73 65 5f 6e 65 76 65 72 5f 63 6f  atabase_never_co
11990 72 72 75 70 74 0a 0a 73 6f 75 72 63 65 20 24 74  rrupt..source $t
119a0 65 73 74 64 69 72 2f 74 68 72 65 61 64 5f 63 6f  estdir/thread_co
119b0 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f 75 72 63 65 20  mmon.tcl.source 
119c0 24 74 65 73 74 64 69 72 2f 6d 61 6c 6c 6f 63 5f  $testdir/malloc_
119d0 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a                 common.tcl.