/ Hex Artifact Content
Login

Artifact 64ac253a411db1af7649438f674213a45876ca70609570310a8652edf23e5d77:


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 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 63 6f  ..  if {[info co
4540: 6d 6d 61 6e 64 73 20 76 64 62 65 5f 63 6f 76 65  mmands vdbe_cove
4550: 72 61 67 65 5d 21 3d 22 22 7d 20 7b 0a 20 20 20  rage]!=""} {.   
4560: 20 76 64 62 65 5f 63 6f 76 65 72 61 67 65 20 73   vdbe_coverage s
4570: 74 61 72 74 0a 20 20 7d 0a 7d 0a 0a 23 20 55 70  tart.  }.}..# Up
4580: 64 61 74 65 20 74 68 65 20 73 6f 66 74 2d 68 65  date the soft-he
4590: 61 70 2d 6c 69 6d 69 74 20 65 61 63 68 20 74 69  ap-limit each ti
45a0: 6d 65 20 74 68 69 73 20 73 63 72 69 70 74 20 69  me this script i
45b0: 73 20 72 75 6e 2e 20 49 6e 20 74 68 61 74 0a 23  s run. In that.#
45c0: 20 77 61 79 20 69 66 20 61 6e 20 69 6e 64 69 76   way if an indiv
45d0: 69 64 75 61 6c 20 74 65 73 74 20 66 69 6c 65 20  idual test file 
45e0: 63 68 61 6e 67 65 73 20 74 68 65 20 73 6f 66 74  changes the soft
45f0: 2d 68 65 61 70 2d 6c 69 6d 69 74 2c 20 69 74 0a  -heap-limit, it.
4600: 23 20 77 69 6c 6c 20 62 65 20 72 65 73 65 74 20  # will be reset 
4610: 61 74 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  at the start of 
4620: 74 68 65 20 6e 65 78 74 20 74 65 73 74 20 66 69  the next test fi
4630: 6c 65 2e 0a 23 0a 73 71 6c 69 74 65 33 5f 73 6f  le..#.sqlite3_so
4640: 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20 24 63  ft_heap_limit $c
4650: 6d 64 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68  mdlinearg(soft-h
4660: 65 61 70 2d 6c 69 6d 69 74 29 0a 0a 23 20 43 72  eap-limit)..# Cr
4670: 65 61 74 65 20 61 20 74 65 73 74 20 64 61 74 61  eate a test data
4680: 62 61 73 65 0a 23 0a 70 72 6f 63 20 72 65 73 65  base.#.proc rese
4690: 74 5f 64 62 20 7b 7d 20 7b 0a 20 20 63 61 74 63  t_db {} {.  catc
46a0: 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66  h {db close}.  f
46b0: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e  orcedelete test.
46c0: 64 62 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65  db.  forcedelete
46d0: 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c   test.db-journal
46e0: 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 74  .  forcedelete t
46f0: 65 73 74 2e 64 62 2d 77 61 6c 0a 20 20 73 71 6c  est.db-wal.  sql
4700: 69 74 65 33 20 64 62 20 2e 2f 74 65 73 74 2e 64  ite3 db ./test.d
4710: 62 0a 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71  b.  set ::DB [sq
4720: 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e  lite3_connection
4730: 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 69  _pointer db].  i
4740: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
4750: 3a 3a 53 45 54 55 50 5f 53 51 4c 5d 7d 20 7b 0a  ::SETUP_SQL]} {.
4760: 20 20 20 20 64 62 20 65 76 61 6c 20 24 3a 3a 53      db eval $::S
4770: 45 54 55 50 5f 53 51 4c 0a 20 20 7d 0a 7d 0a 72  ETUP_SQL.  }.}.r
4780: 65 73 65 74 5f 64 62 0a 0a 23 20 41 62 6f 72 74  eset_db..# Abort
4790: 20 65 61 72 6c 79 20 69 66 20 74 68 69 73 20 73   early if this s
47a0: 63 72 69 70 74 20 68 61 73 20 62 65 65 6e 20 72  cript has been r
47b0: 75 6e 20 62 65 66 6f 72 65 2e 0a 23 0a 69 66 20  un before..#.if 
47c0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 54 43  {[info exists TC
47d0: 28 63 6f 75 6e 74 29 5d 7d 20 72 65 74 75 72 6e  (count)]} return
47e0: 0a 0a 23 20 4d 61 6b 65 20 73 75 72 65 20 6d 65  ..# Make sure me
47f0: 6d 6f 72 79 20 73 74 61 74 69 73 74 69 63 73 20  mory statistics 
4800: 61 72 65 20 65 6e 61 62 6c 65 64 2e 0a 23 0a 73  are enabled..#.s
4810: 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 5f 6d 65  qlite3_config_me
4820: 6d 73 74 61 74 75 73 20 31 0a 0a 23 20 49 6e 69  mstatus 1..# Ini
4830: 74 69 61 6c 69 7a 65 20 74 68 65 20 74 65 73 74  tialize the test
4840: 20 63 6f 75 6e 74 65 72 73 20 61 6e 64 20 73 65   counters and se
4850: 74 20 75 70 20 63 6f 6d 6d 61 6e 64 73 20 74 6f  t up commands to
4860: 20 61 63 63 65 73 73 20 74 68 65 6d 2e 0a 23 20   access them..# 
4870: 4f 72 2c 20 69 66 20 74 68 69 73 20 69 73 20 61  Or, if this is a
4880: 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74   slave interpret
4890: 65 72 2c 20 73 65 74 20 75 70 20 61 6c 69 61 73  er, set up alias
48a0: 65 73 20 74 6f 20 77 72 69 74 65 20 74 68 65 0a  es to write the.
48b0: 23 20 63 6f 75 6e 74 65 72 73 20 69 6e 20 74 68  # counters in th
48c0: 65 20 70 61 72 65 6e 74 20 69 6e 74 65 72 70 72  e parent interpr
48d0: 65 74 65 72 2e 0a 23 0a 69 66 20 7b 30 3d 3d 5b  eter..#.if {0==[
48e0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c  info exists ::SL
48f0: 41 56 45 5d 7d 20 7b 0a 20 20 73 65 74 20 54 43  AVE]} {.  set TC
4900: 28 65 72 72 6f 72 73 29 20 20 20 20 30 0a 20 20  (errors)    0.  
4910: 73 65 74 20 54 43 28 63 6f 75 6e 74 29 20 20 20  set TC(count)   
4920: 20 20 30 0a 20 20 73 65 74 20 54 43 28 66 61 69    0.  set TC(fai
4930: 6c 5f 6c 69 73 74 29 20 5b 6c 69 73 74 5d 0a 20  l_list) [list]. 
4940: 20 73 65 74 20 54 43 28 6f 6d 69 74 5f 6c 69 73   set TC(omit_lis
4950: 74 29 20 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20  t) [list].  set 
4960: 54 43 28 77 61 72 6e 5f 6c 69 73 74 29 20 5b 6c  TC(warn_list) [l
4970: 69 73 74 5d 0a 0a 20 20 70 72 6f 63 20 73 65 74  ist]..  proc set
4980: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 7b 63  _test_counter {c
4990: 6f 75 6e 74 65 72 20 61 72 67 73 7d 20 7b 0a 20  ounter args} {. 
49a0: 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20     if {[llength 
49b0: 24 61 72 67 73 5d 7d 20 7b 0a 20 20 20 20 20 20  $args]} {.      
49c0: 73 65 74 20 3a 3a 54 43 28 24 63 6f 75 6e 74 65  set ::TC($counte
49d0: 72 29 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73  r) [lindex $args
49e0: 20 30 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65   0].    }.    se
49f0: 74 20 3a 3a 54 43 28 24 63 6f 75 6e 74 65 72 29  t ::TC($counter)
4a00: 0a 20 20 7d 0a 7d 0a 0a 23 20 52 65 63 6f 72 64  .  }.}..# Record
4a10: 20 74 68 65 20 66 61 63 74 20 74 68 61 74 20 61   the fact that a
4a20: 20 73 65 71 75 65 6e 63 65 20 6f 66 20 74 65 73   sequence of tes
4a30: 74 73 20 77 65 72 65 20 6f 6d 69 74 74 65 64 2e  ts were omitted.
4a40: 0a 23 0a 70 72 6f 63 20 6f 6d 69 74 5f 74 65 73  .#.proc omit_tes
4a50: 74 20 7b 6e 61 6d 65 20 72 65 61 73 6f 6e 20 7b  t {name reason {
4a60: 61 70 70 65 6e 64 20 31 7d 7d 20 7b 0a 20 20 73  append 1}} {.  s
4a70: 65 74 20 6f 6d 69 74 4c 69 73 74 20 5b 73 65 74  et omitList [set
4a80: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d  _test_counter om
4a90: 69 74 5f 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24  it_list].  if {$
4aa0: 61 70 70 65 6e 64 7d 20 7b 0a 20 20 20 20 6c 61  append} {.    la
4ab0: 70 70 65 6e 64 20 6f 6d 69 74 4c 69 73 74 20 5b  ppend omitList [
4ac0: 6c 69 73 74 20 24 6e 61 6d 65 20 24 72 65 61 73  list $name $reas
4ad0: 6f 6e 5d 0a 20 20 7d 0a 20 20 73 65 74 5f 74 65  on].  }.  set_te
4ae0: 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f  st_counter omit_
4af0: 6c 69 73 74 20 24 6f 6d 69 74 4c 69 73 74 0a 7d  list $omitList.}
4b00: 0a 0a 23 20 52 65 63 6f 72 64 20 74 68 65 20 66  ..# Record the f
4b10: 61 63 74 20 74 68 61 74 20 61 20 74 65 73 74 20  act that a test 
4b20: 66 61 69 6c 65 64 2e 0a 23 0a 70 72 6f 63 20 66  failed..#.proc f
4b30: 61 69 6c 5f 74 65 73 74 20 7b 6e 61 6d 65 7d 20  ail_test {name} 
4b40: 7b 0a 20 20 73 65 74 20 66 20 5b 73 65 74 5f 74  {.  set f [set_t
4b50: 65 73 74 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c  est_counter fail
4b60: 5f 6c 69 73 74 5d 0a 20 20 6c 61 70 70 65 6e 64  _list].  lappend
4b70: 20 66 20 24 6e 61 6d 65 0a 20 20 73 65 74 5f 74   f $name.  set_t
4b80: 65 73 74 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c  est_counter fail
4b90: 5f 6c 69 73 74 20 24 66 0a 20 20 73 65 74 5f 74  _list $f.  set_t
4ba0: 65 73 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f  est_counter erro
4bb0: 72 73 20 5b 65 78 70 72 20 5b 73 65 74 5f 74 65  rs [expr [set_te
4bc0: 73 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72  st_counter error
4bd0: 73 5d 20 2b 20 31 5d 0a 0a 20 20 73 65 74 20 6e  s] + 1]..  set n
4be0: 46 61 69 6c 20 5b 73 65 74 5f 74 65 73 74 5f 63  Fail [set_test_c
4bf0: 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a 20  ounter errors]. 
4c00: 20 69 66 20 7b 24 6e 46 61 69 6c 3e 3d 24 3a 3a   if {$nFail>=$::
4c10: 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 78 65 72  cmdlinearg(maxer
4c20: 72 6f 72 29 7d 20 7b 0a 20 20 20 20 6f 75 74 70  ror)} {.    outp
4c30: 75 74 32 20 22 2a 2a 2a 20 47 69 76 69 6e 67 20  ut2 "*** Giving 
4c40: 75 70 2e 2e 2e 22 0a 20 20 20 20 66 69 6e 61 6c  up...".    final
4c50: 69 7a 65 5f 74 65 73 74 69 6e 67 0a 20 20 7d 0a  ize_testing.  }.
4c60: 7d 0a 0a 23 20 52 65 6d 65 6d 62 65 72 20 61 20  }..# Remember a 
4c70: 77 61 72 6e 69 6e 67 20 6d 65 73 73 61 67 65 20  warning message 
4c80: 74 6f 20 62 65 20 64 69 73 70 6c 61 79 65 64 20  to be displayed 
4c90: 61 74 20 74 68 65 20 63 6f 6e 63 6c 75 73 69 6f  at the conclusio
4ca0: 6e 20 6f 66 20 61 6c 6c 20 74 65 73 74 69 6e 67  n of all testing
4cb0: 0a 23 0a 70 72 6f 63 20 77 61 72 6e 69 6e 67 20  .#.proc warning 
4cc0: 7b 6d 73 67 20 7b 61 70 70 65 6e 64 20 31 7d 7d  {msg {append 1}}
4cd0: 20 7b 0a 20 20 6f 75 74 70 75 74 32 20 22 57 61   {.  output2 "Wa
4ce0: 72 6e 69 6e 67 3a 20 24 6d 73 67 22 0a 20 20 73  rning: $msg".  s
4cf0: 65 74 20 77 61 72 6e 4c 69 73 74 20 5b 73 65 74  et warnList [set
4d00: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 77 61  _test_counter wa
4d10: 72 6e 5f 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24  rn_list].  if {$
4d20: 61 70 70 65 6e 64 7d 20 7b 0a 20 20 20 20 6c 61  append} {.    la
4d30: 70 70 65 6e 64 20 77 61 72 6e 4c 69 73 74 20 24  ppend warnList $
4d40: 6d 73 67 0a 20 20 7d 0a 20 20 73 65 74 5f 74 65  msg.  }.  set_te
4d50: 73 74 5f 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f  st_counter warn_
4d60: 6c 69 73 74 20 24 77 61 72 6e 4c 69 73 74 0a 7d  list $warnList.}
4d70: 0a 0a 0a 23 20 49 6e 63 72 65 6d 65 6e 74 20 74  ...# Increment t
4d80: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 65 73  he number of tes
4d90: 74 73 20 72 75 6e 0a 23 0a 70 72 6f 63 20 69 6e  ts run.#.proc in
4da0: 63 72 5f 6e 74 65 73 74 20 7b 7d 20 7b 0a 20 20  cr_ntest {} {.  
4db0: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
4dc0: 20 63 6f 75 6e 74 20 5b 65 78 70 72 20 5b 73 65   count [expr [se
4dd0: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 63  t_test_counter c
4de0: 6f 75 6e 74 5d 20 2b 20 31 5d 0a 7d 0a 0a 23 20  ount] + 1].}..# 
4df0: 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 2d  Return true if -
4e00: 2d 76 65 72 62 6f 73 65 3d 31 20 77 61 73 20 73  -verbose=1 was s
4e10: 70 65 63 69 66 69 65 64 20 6f 6e 20 74 68 65 20  pecified on the 
4e20: 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 2e 20 4f 74  command line. Ot
4e30: 68 65 72 77 69 73 65 2c 0a 23 20 72 65 74 75 72  herwise,.# retur
4e40: 6e 20 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20  n false..#.proc 
4e50: 76 65 72 62 6f 73 65 20 7b 7d 20 7b 0a 20 20 72  verbose {} {.  r
4e60: 65 74 75 72 6e 20 24 3a 3a 63 6d 64 6c 69 6e 65  eturn $::cmdline
4e70: 61 72 67 28 76 65 72 62 6f 73 65 29 0a 7d 0a 0a  arg(verbose).}..
4e80: 23 20 55 73 65 20 74 68 65 20 66 6f 6c 6c 6f 77  # Use the follow
4e90: 69 6e 67 20 63 6f 6d 6d 61 6e 64 73 20 69 6e 73  ing commands ins
4ea0: 74 65 61 64 20 6f 66 20 5b 70 75 74 73 5d 20 66  tead of [puts] f
4eb0: 6f 72 20 74 65 73 74 20 6f 75 74 70 75 74 20 77  or test output w
4ec0: 69 74 68 69 6e 0a 23 20 74 68 69 73 20 66 69 6c  ithin.# this fil
4ed0: 65 2e 20 54 65 73 74 20 73 63 72 69 70 74 73 20  e. Test scripts 
4ee0: 63 61 6e 20 73 74 69 6c 6c 20 75 73 65 20 72 65  can still use re
4ef0: 67 75 6c 61 72 20 5b 70 75 74 73 5d 2c 20 77 68  gular [puts], wh
4f00: 69 63 68 20 69 73 20 64 69 72 65 63 74 65 64 0a  ich is directed.
4f10: 23 20 74 6f 20 73 74 64 6f 75 74 20 61 6e 64 2c  # to stdout and,
4f20: 20 69 66 20 6f 6e 65 20 69 73 20 6f 70 65 6e 2c   if one is open,
4f30: 20 74 68 65 20 2d 2d 6f 75 74 70 75 74 20 66 69   the --output fi
4f40: 6c 65 2e 0a 23 0a 23 20 6f 75 74 70 75 74 31 3a  le..#.# output1:
4f50: 20 6f 75 74 70 75 74 20 74 68 61 74 20 73 68 6f   output that sho
4f60: 75 6c 64 20 62 65 20 70 72 69 6e 74 65 64 20 69  uld be printed i
4f70: 66 20 2d 2d 76 65 72 62 6f 73 65 3d 31 20 77 61  f --verbose=1 wa
4f80: 73 20 73 70 65 63 69 66 69 65 64 2e 0a 23 20 6f  s specified..# o
4f90: 75 74 70 75 74 32 3a 20 6f 75 74 70 75 74 20 74  utput2: 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 75 6e 63 6f 6e 64 69 74 69 6f  inted unconditio
4fc0: 6e 61 6c 6c 79 2e 0a 23 20 6f 75 74 70 75 74 32  nally..# output2
4fd0: 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f 73 65 3a 20  _if_no_verbose: 
4fe0: 6f 75 74 70 75 74 20 74 68 61 74 20 73 68 6f 75  output that shou
4ff0: 6c 64 20 62 65 20 70 72 69 6e 74 65 64 20 6f 6e  ld be printed on
5000: 6c 79 20 69 66 20 2d 2d 76 65 72 62 6f 73 65 3d  ly if --verbose=
5010: 30 2e 0a 23 0a 70 72 6f 63 20 6f 75 74 70 75 74  0..#.proc output
5020: 31 20 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65 74  1 {args} {.  set
5030: 20 76 20 5b 76 65 72 62 6f 73 65 5d 0a 20 20 69   v [verbose].  i
5040: 66 20 7b 24 76 3d 3d 31 7d 20 7b 0a 20 20 20 20  f {$v==1} {.    
5050: 75 70 6c 65 76 65 6c 20 6f 75 74 70 75 74 32 20  uplevel output2 
5060: 24 61 72 67 73 0a 20 20 7d 20 65 6c 73 65 69 66  $args.  } elseif
5070: 20 7b 24 76 3d 3d 32 7d 20 7b 0a 20 20 20 20 75   {$v==2} {.    u
5080: 70 6c 65 76 65 6c 20 70 75 74 73 20 5b 6c 72 61  plevel puts [lra
5090: 6e 67 65 20 24 61 72 67 73 20 30 20 65 6e 64 2d  nge $args 0 end-
50a0: 31 5d 20 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66  1] $::G(output_f
50b0: 64 29 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73  d) [lrange $args
50c0: 20 65 6e 64 20 65 6e 64 5d 0a 20 20 7d 0a 7d 0a   end end].  }.}.
50d0: 70 72 6f 63 20 6f 75 74 70 75 74 32 20 7b 61 72  proc output2 {ar
50e0: 67 73 7d 20 7b 0a 20 20 73 65 74 20 6e 41 72 67  gs} {.  set nArg
50f0: 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d   [llength $args]
5100: 0a 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73 20  .  uplevel puts 
5110: 24 61 72 67 73 0a 7d 0a 70 72 6f 63 20 6f 75 74  $args.}.proc out
5120: 70 75 74 32 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f  put2_if_no_verbo
5130: 73 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65  se {args} {.  se
5140: 74 20 76 20 5b 76 65 72 62 6f 73 65 5d 0a 20 20  t v [verbose].  
5150: 69 66 20 7b 24 76 3d 3d 30 7d 20 7b 0a 20 20 20  if {$v==0} {.   
5160: 20 75 70 6c 65 76 65 6c 20 6f 75 74 70 75 74 32   uplevel output2
5170: 20 24 61 72 67 73 0a 20 20 7d 20 65 6c 73 65 69   $args.  } elsei
5180: 66 20 7b 24 76 3d 3d 32 7d 20 7b 0a 20 20 20 20  f {$v==2} {.    
5190: 75 70 6c 65 76 65 6c 20 70 75 74 73 20 5b 6c 72  uplevel puts [lr
51a0: 61 6e 67 65 20 24 61 72 67 73 20 30 20 65 6e 64  ange $args 0 end
51b0: 2d 31 5d 20 73 74 64 6f 75 74 20 5b 6c 72 61 6e  -1] stdout [lran
51c0: 67 65 20 24 61 72 67 73 20 65 6e 64 20 65 6e 64  ge $args end end
51d0: 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 4f 76 65 72 72  ].  }.}..# Overr
51e0: 69 64 65 20 74 68 65 20 5b 70 75 74 73 5d 20 63  ide the [puts] c
51f0: 6f 6d 6d 61 6e 64 20 73 6f 20 74 68 61 74 20 69  ommand so that i
5200: 66 20 6e 6f 20 63 68 61 6e 6e 65 6c 20 69 73 20  f no channel is 
5210: 65 78 70 6c 69 63 69 74 6c 79 20 0a 23 20 73 70  explicitly .# sp
5220: 65 63 69 66 69 65 64 20 74 68 65 20 73 74 72 69  ecified the stri
5230: 6e 67 20 69 73 20 77 72 69 74 74 65 6e 20 74 6f  ng is written to
5240: 20 62 6f 74 68 20 73 74 64 6f 75 74 20 61 6e 64   both stdout and
5250: 20 74 6f 20 74 68 65 20 66 69 6c 65 20 0a 23 20   to the file .# 
5260: 73 70 65 63 69 66 69 65 64 20 62 79 20 22 2d 2d  specified by "--
5270: 6f 75 74 70 75 74 3d 22 2c 20 69 66 20 61 6e 79  output=", if any
5280: 2e 0a 23 0a 70 72 6f 63 20 70 75 74 73 5f 6f 76  ..#.proc puts_ov
5290: 65 72 72 69 64 65 20 7b 61 72 67 73 7d 20 7b 0a  erride {args} {.
52a0: 20 20 73 65 74 20 6e 41 72 67 20 5b 6c 6c 65 6e    set nArg [llen
52b0: 67 74 68 20 24 61 72 67 73 5d 0a 20 20 69 66 20  gth $args].  if 
52c0: 7b 24 6e 41 72 67 3d 3d 31 20 7c 7c 20 28 24 6e  {$nArg==1 || ($n
52d0: 41 72 67 3d 3d 32 20 26 26 20 5b 73 74 72 69 6e  Arg==2 && [strin
52e0: 67 20 66 69 72 73 74 20 5b 6c 69 6e 64 65 78 20  g first [lindex 
52f0: 24 61 72 67 73 20 30 5d 20 2d 6e 6f 6e 65 77 6c  $args 0] -nonewl
5300: 69 6e 65 5d 3d 3d 30 29 7d 20 7b 0a 20 20 20 20  ine]==0)} {.    
5310: 75 70 6c 65 76 65 6c 20 70 75 74 73 5f 6f 72 69  uplevel puts_ori
5320: 67 69 6e 61 6c 20 24 61 72 67 73 0a 20 20 20 20  ginal $args.    
5330: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
5340: 20 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 5d   ::G(output_fd)]
5350: 7d 20 7b 0a 20 20 20 20 20 20 75 70 6c 65 76 65  } {.      upleve
5360: 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67 65 20 24  l puts [lrange $
5370: 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 20 24 3a  args 0 end-1] $:
5380: 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 20 5b 6c  :G(output_fd) [l
5390: 72 61 6e 67 65 20 24 61 72 67 73 20 65 6e 64 20  range $args end 
53a0: 65 6e 64 5d 0a 20 20 20 20 7d 0a 20 20 7d 20 65  end].    }.  } e
53b0: 6c 73 65 20 7b 0a 20 20 20 20 23 20 41 20 63 68  lse {.    # A ch
53c0: 61 6e 6e 65 6c 20 77 61 73 20 65 78 70 6c 69 63  annel was explic
53d0: 69 74 6c 79 20 73 70 65 63 69 66 69 65 64 2e 0a  itly specified..
53e0: 20 20 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73      uplevel puts
53f0: 5f 6f 72 69 67 69 6e 61 6c 20 24 61 72 67 73 0a  _original $args.
5400: 20 20 7d 0a 7d 0a 72 65 6e 61 6d 65 20 70 75 74    }.}.rename put
5410: 73 20 70 75 74 73 5f 6f 72 69 67 69 6e 61 6c 0a  s puts_original.
5420: 70 72 6f 63 20 70 75 74 73 20 7b 61 72 67 73 7d  proc puts {args}
5430: 20 7b 20 75 70 6c 65 76 65 6c 20 70 75 74 73 5f   { uplevel puts_
5440: 6f 76 65 72 72 69 64 65 20 24 61 72 67 73 20 7d  override $args }
5450: 0a 0a 0a 23 20 49 6e 76 6f 6b 65 20 74 68 65 20  ...# Invoke the 
5460: 64 6f 5f 74 65 73 74 20 70 72 6f 63 65 64 75 72  do_test procedur
5470: 65 20 74 6f 20 72 75 6e 20 61 20 73 69 6e 67 6c  e to run a singl
5480: 65 20 74 65 73 74 0a 23 0a 23 20 54 68 65 20 24  e test.#.# The $
5490: 65 78 70 65 63 74 65 64 20 70 61 72 61 6d 65 74  expected paramet
54a0: 65 72 20 69 73 20 74 68 65 20 65 78 70 65 63 74  er is the expect
54b0: 65 64 20 72 65 73 75 6c 74 2e 20 20 54 68 65 20  ed result.  The 
54c0: 72 65 73 75 6c 74 20 69 73 20 74 68 65 20 72 65  result is the re
54d0: 74 75 72 6e 0a 23 20 76 61 6c 75 65 20 66 72 6f  turn.# value fro
54e0: 6d 20 74 68 65 20 6c 61 73 74 20 54 43 4c 20 63  m the last TCL c
54f0: 6f 6d 6d 61 6e 64 20 69 6e 20 24 63 6d 64 2e 0a  ommand in $cmd..
5500: 23 0a 23 20 4e 6f 72 6d 61 6c 6c 79 2c 20 24 65  #.# Normally, $e
5510: 78 70 65 63 74 65 64 20 6d 75 73 74 20 6d 61 74  xpected must mat
5520: 63 68 20 65 78 61 63 74 6c 79 2e 20 20 42 75 74  ch exactly.  But
5530: 20 69 66 20 24 65 78 70 65 63 74 65 64 20 69 73   if $expected is
5540: 20 6f 66 20 74 68 65 20 66 6f 72 6d 0a 23 20 22   of the form.# "
5550: 2f 72 65 67 65 78 70 2f 22 20 74 68 65 6e 20 72  /regexp/" then r
5560: 65 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f  egular expressio
5570: 6e 20 6d 61 74 63 68 69 6e 67 20 69 73 20 75 73  n matching is us
5580: 65 64 2e 20 20 49 66 20 24 65 78 70 65 63 74 65  ed.  If $expecte
5590: 64 20 69 73 0a 23 20 22 7e 2f 72 65 67 65 78 70  d is.# "~/regexp
55a0: 2f 22 20 74 68 65 6e 20 74 68 65 20 72 65 67 75  /" then the regu
55b0: 6c 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 6d  lar expression m
55c0: 75 73 74 20 4e 4f 54 20 6d 61 74 63 68 2e 20 20  ust NOT match.  
55d0: 49 66 20 24 65 78 70 65 63 74 65 64 20 69 73 0a  If $expected is.
55e0: 23 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 22 23  # of the form "#
55f0: 2f 76 61 6c 75 65 2d 6c 69 73 74 2f 22 20 74 68  /value-list/" th
5600: 65 6e 20 65 61 63 68 20 74 65 72 6d 20 69 6e 20  en each term in 
5610: 76 61 6c 75 65 2d 6c 69 73 74 20 6d 75 73 74 20  value-list must 
5620: 62 65 20 6e 75 6d 65 72 69 63 0a 23 20 61 6e 64  be numeric.# and
5630: 20 6d 75 73 74 20 61 70 70 72 6f 78 69 6d 61 74   must approximat
5640: 65 6c 79 20 6d 61 74 63 68 20 74 68 65 20 63 6f  ely match the co
5650: 72 72 65 73 70 6f 6e 64 69 6e 67 20 6e 75 6d 65  rresponding nume
5660: 72 69 63 20 74 65 72 6d 20 69 6e 20 24 72 65 73  ric term in $res
5670: 75 6c 74 2e 0a 23 20 56 61 6c 75 65 73 20 6d 75  ult..# Values mu
5680: 73 74 20 6d 61 74 63 68 20 77 69 74 68 69 6e 20  st match within 
5690: 31 30 25 2e 20 20 4f 72 20 69 66 20 74 68 65 20  10%.  Or if the 
56a0: 24 65 78 70 65 63 74 65 64 20 74 65 72 6d 20 69  $expected term i
56b0: 73 20 41 2e 2e 42 20 74 68 65 6e 20 74 68 65 0a  s A..B then the.
56c0: 23 20 24 72 65 73 75 6c 74 20 74 65 72 6d 20 6d  # $result term m
56d0: 75 73 74 20 62 65 20 69 6e 20 62 65 74 77 65 65  ust be in betwee
56e0: 6e 20 41 20 61 6e 64 20 42 2e 0a 23 0a 70 72 6f  n A and B..#.pro
56f0: 63 20 64 6f 5f 74 65 73 74 20 7b 6e 61 6d 65 20  c do_test {name 
5700: 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b 0a  cmd expected} {.
5710: 20 20 67 6c 6f 62 61 6c 20 61 72 67 76 20 63 6d    global argv cm
5720: 64 6c 69 6e 65 61 72 67 0a 0a 20 20 66 69 78 5f  dlinearg..  fix_
5730: 74 65 73 74 6e 61 6d 65 20 6e 61 6d 65 0a 0a 20  testname name.. 
5740: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
5750: 67 5f 73 65 74 74 69 74 6c 65 20 24 6e 61 6d 65  g_settitle $name
5760: 0a 0a 23 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74  ..#  if {[llengt
5770: 68 20 24 61 72 67 76 5d 3d 3d 30 7d 20 7b 0a 23  h $argv]==0} {.#
5780: 20 20 20 20 73 65 74 20 67 6f 20 31 0a 23 20 20      set go 1.#  
5790: 7d 20 65 6c 73 65 20 7b 0a 23 20 20 20 20 73 65  } else {.#    se
57a0: 74 20 67 6f 20 30 0a 23 20 20 20 20 66 6f 72 65  t go 0.#    fore
57b0: 61 63 68 20 70 61 74 74 65 72 6e 20 24 61 72 67  ach pattern $arg
57c0: 76 20 7b 0a 23 20 20 20 20 20 20 69 66 20 7b 5b  v {.#      if {[
57d0: 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 70 61  string match $pa
57e0: 74 74 65 72 6e 20 24 6e 61 6d 65 5d 7d 20 7b 0a  ttern $name]} {.
57f0: 23 20 20 20 20 20 20 20 20 73 65 74 20 67 6f 20  #        set go 
5800: 31 0a 23 20 20 20 20 20 20 20 20 62 72 65 61 6b  1.#        break
5810: 0a 23 20 20 20 20 20 20 7d 0a 23 20 20 20 20 7d  .#      }.#    }
5820: 0a 23 20 20 7d 0a 0a 20 20 69 66 20 7b 5b 69 6e  .#  }..  if {[in
5830: 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65  fo exists ::G(pe
5840: 72 6d 3a 70 72 65 66 69 78 29 5d 7d 20 7b 0a 20  rm:prefix)]} {. 
5850: 20 20 20 73 65 74 20 6e 61 6d 65 20 22 24 3a 3a     set name "$::
5860: 47 28 70 65 72 6d 3a 70 72 65 66 69 78 29 24 6e  G(perm:prefix)$n
5870: 61 6d 65 22 0a 20 20 7d 0a 0a 20 20 69 6e 63 72  ame".  }..  incr
5880: 5f 6e 74 65 73 74 0a 20 20 6f 75 74 70 75 74 31  _ntest.  output1
5890: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d   -nonewline $nam
58a0: 65 2e 2e 2e 0a 20 20 66 6c 75 73 68 20 73 74 64  e....  flush std
58b0: 6f 75 74 0a 0a 20 20 69 66 20 7b 21 5b 69 6e 66  out..  if {![inf
58c0: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6d 61 74  o exists ::G(mat
58d0: 63 68 29 5d 20 7c 7c 20 5b 73 74 72 69 6e 67 20  ch)] || [string 
58e0: 6d 61 74 63 68 20 24 3a 3a 47 28 6d 61 74 63 68  match $::G(match
58f0: 29 20 24 6e 61 6d 65 5d 7d 20 7b 0a 20 20 20 20  ) $name]} {.    
5900: 69 66 20 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65  if {[catch {uple
5910: 76 65 6c 20 23 30 20 22 24 63 6d 64 3b 5c 6e 22  vel #0 "$cmd;\n"
5920: 7d 20 72 65 73 75 6c 74 5d 7d 20 7b 0a 20 20 20  } result]} {.   
5930: 20 20 20 6f 75 74 70 75 74 32 5f 69 66 5f 6e 6f     output2_if_no
5940: 5f 76 65 72 62 6f 73 65 20 2d 6e 6f 6e 65 77 6c  _verbose -nonewl
5950: 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 20  ine $name....   
5960: 20 20 20 6f 75 74 70 75 74 32 20 22 5c 6e 45 72     output2 "\nEr
5970: 72 6f 72 3a 20 24 72 65 73 75 6c 74 22 0a 20 20  ror: $result".  
5980: 20 20 20 20 66 61 69 6c 5f 74 65 73 74 20 24 6e      fail_test $n
5990: 61 6d 65 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  ame.    } else {
59a0: 0a 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65  .      if {[rege
59b0: 78 70 20 7b 5e 5b 7e 23 5d 3f 2f 2e 2a 2f 24 7d  xp {^[~#]?/.*/$}
59c0: 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20   $expected]} {. 
59d0: 20 20 20 20 20 20 20 23 20 22 65 78 70 65 63 74         # "expect
59e0: 65 64 22 20 69 73 20 6f 66 20 74 68 65 20 66 6f  ed" is of the fo
59f0: 72 6d 20 22 2f 50 41 54 54 45 52 4e 2f 22 20 74  rm "/PATTERN/" t
5a00: 68 65 6e 20 74 68 65 20 72 65 73 75 6c 74 20 69  hen the result i
5a10: 66 20 63 6f 72 72 65 63 74 20 69 66 0a 20 20 20  f correct if.   
5a20: 20 20 20 20 20 23 20 72 65 67 75 6c 61 72 20 65       # regular e
5a30: 78 70 72 65 73 73 69 6f 6e 20 50 41 54 54 45 52  xpression PATTER
5a40: 4e 20 6d 61 74 63 68 65 73 20 74 68 65 20 72 65  N matches the re
5a50: 73 75 6c 74 2e 20 20 22 7e 2f 50 41 54 54 45 52  sult.  "~/PATTER
5a60: 4e 2f 22 20 6d 65 61 6e 73 0a 20 20 20 20 20 20  N/" means.      
5a70: 20 20 23 20 74 68 65 20 72 65 67 75 6c 61 72 20    # the regular 
5a80: 65 78 70 72 65 73 73 69 6f 6e 20 6d 75 73 74 20  expression must 
5a90: 6e 6f 74 20 6d 61 74 63 68 2e 0a 20 20 20 20 20  not match..     
5aa0: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 69     if {[string i
5ab0: 6e 64 65 78 20 24 65 78 70 65 63 74 65 64 20 30  ndex $expected 0
5ac0: 5d 3d 3d 22 7e 22 7d 20 7b 0a 20 20 20 20 20 20  ]=="~"} {.      
5ad0: 20 20 20 20 73 65 74 20 72 65 20 5b 73 74 72 69      set re [stri
5ae0: 6e 67 20 72 61 6e 67 65 20 24 65 78 70 65 63 74  ng range $expect
5af0: 65 64 20 32 20 65 6e 64 2d 31 5d 0a 20 20 20 20  ed 2 end-1].    
5b00: 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e        if {[strin
5b10: 67 20 69 6e 64 65 78 20 24 72 65 20 30 5d 3d 3d  g index $re 0]==
5b20: 22 2a 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  "*"} {.         
5b30: 20 20 20 23 20 49 66 20 74 68 65 20 72 65 67 75     # If the regu
5b40: 6c 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 62  lar expression b
5b50: 65 67 69 6e 73 20 77 69 74 68 20 2a 20 74 68 65  egins with * the
5b60: 6e 20 74 72 65 61 74 20 69 74 20 61 73 20 61 20  n treat it as a 
5b70: 67 6c 6f 62 20 69 6e 73 74 65 61 64 0a 20 20 20  glob instead.   
5b80: 20 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20           set ok 
5b90: 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 72  [string match $r
5ba0: 65 20 24 72 65 73 75 6c 74 5d 0a 20 20 20 20 20  e $result].     
5bb0: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
5bc0: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 72 65            set re
5bd0: 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 23 20   [string map {# 
5be0: 7b 5b 2d 30 2d 39 2e 5d 2b 7d 7d 20 24 72 65 5d  {[-0-9.]+}} $re]
5bf0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74  .            set
5c00: 20 6f 6b 20 5b 72 65 67 65 78 70 20 24 72 65 20   ok [regexp $re 
5c10: 24 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20  $result].       
5c20: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 73     }.          s
5c30: 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b 21 24 6f  et ok [expr {!$o
5c40: 6b 7d 5d 0a 20 20 20 20 20 20 20 20 7d 20 65 6c  k}].        } el
5c50: 73 65 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e  seif {[string in
5c60: 64 65 78 20 24 65 78 70 65 63 74 65 64 20 30 5d  dex $expected 0]
5c70: 3d 3d 22 23 22 7d 20 7b 0a 20 20 20 20 20 20 20  =="#"} {.       
5c80: 20 20 20 23 20 4e 75 6d 65 72 69 63 20 72 61 6e     # Numeric ran
5c90: 67 65 20 76 61 6c 75 65 20 63 6f 6d 70 61 72 69  ge value compari
5ca0: 73 6f 6e 2e 20 20 45 61 63 68 20 74 65 72 6d 20  son.  Each term 
5cb0: 6f 66 20 74 68 65 20 24 72 65 73 75 6c 74 20 69  of the $result i
5cc0: 73 20 6d 61 74 63 68 65 64 0a 20 20 20 20 20 20  s matched.      
5cd0: 20 20 20 20 23 20 61 67 61 69 6e 73 74 20 6f 6e      # against on
5ce0: 65 20 74 65 72 6d 20 6f 66 20 24 65 78 70 65 63  e term of $expec
5cf0: 74 2e 20 20 42 6f 74 68 20 24 72 65 73 75 6c 74  t.  Both $result
5d00: 20 61 6e 64 20 24 65 78 70 65 63 74 65 64 20 74   and $expected t
5d10: 65 72 6d 73 20 6d 75 73 74 20 62 65 0a 20 20 20  erms must be.   
5d20: 20 20 20 20 20 20 20 23 20 6e 75 6d 65 72 69 63         # numeric
5d30: 2e 20 20 54 68 65 20 76 61 6c 75 65 73 20 6d 75  .  The values mu
5d40: 73 74 20 6d 61 74 63 68 20 77 69 74 68 69 6e 20  st match within 
5d50: 31 30 25 2e 20 20 4f 72 20 69 66 20 24 65 78 70  10%.  Or if $exp
5d60: 65 63 74 65 64 20 69 73 20 6f 66 20 74 68 65 0a  ected is of the.
5d70: 20 20 20 20 20 20 20 20 20 20 23 20 66 6f 72 6d            # form
5d80: 20 41 2e 2e 42 20 74 68 65 6e 20 74 68 65 20 24   A..B then the $
5d90: 72 65 73 75 6c 74 20 74 65 72 6d 20 6d 75 73 74  result term must
5da0: 20 62 65 20 62 65 74 77 65 65 6e 20 41 20 61 6e   be between A an
5db0: 64 20 42 2e 0a 20 20 20 20 20 20 20 20 20 20 73  d B..          s
5dc0: 65 74 20 65 32 20 5b 73 74 72 69 6e 67 20 72 61  et e2 [string ra
5dd0: 6e 67 65 20 24 65 78 70 65 63 74 65 64 20 32 20  nge $expected 2 
5de0: 65 6e 64 2d 31 5d 0a 20 20 20 20 20 20 20 20 20  end-1].         
5df0: 20 66 6f 72 65 61 63 68 20 69 20 24 72 65 73 75   foreach i $resu
5e00: 6c 74 20 6a 20 24 65 32 20 7b 0a 20 20 20 20 20  lt j $e2 {.     
5e10: 20 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65         if {[rege
5e20: 78 70 20 7b 5e 28 2d 3f 5c 64 2b 29 5c 2e 5c 2e  xp {^(-?\d+)\.\.
5e30: 28 2d 3f 5c 64 29 24 7d 20 24 6a 20 61 6c 6c 20  (-?\d)$} $j all 
5e40: 41 20 42 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20  A B]} {.        
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 24 41 20 26 26 20  pr {$i+0>=$A && 
5e70: 24 69 2b 30 3c 3d 24 42 7d 5d 0a 20 20 20 20 20  $i+0<=$B}].     
5e80: 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a         } else {.
5e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65                se
5ea0: 74 20 6f 6b 20 5b 65 78 70 72 20 7b 24 69 2b 30  t ok [expr {$i+0
5eb0: 3e 3d 30 2e 39 2a 24 6a 20 26 26 20 24 69 2b 30  >=0.9*$j && $i+0
5ec0: 3c 3d 31 2e 31 2a 24 6a 7d 5d 0a 20 20 20 20 20  <=1.1*$j}].     
5ed0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
5ee0: 20 20 20 20 20 69 66 20 7b 21 24 6f 6b 7d 20 62       if {!$ok} b
5ef0: 72 65 61 6b 0a 20 20 20 20 20 20 20 20 20 20 7d  reak.          }
5f00: 0a 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 24  .          if {$
5f10: 6f 6b 20 26 26 20 5b 6c 6c 65 6e 67 74 68 20 24  ok && [llength $
5f20: 72 65 73 75 6c 74 5d 21 3d 5b 6c 6c 65 6e 67 74  result]!=[llengt
5f30: 68 20 24 65 32 5d 7d 20 7b 73 65 74 20 6f 6b 20  h $e2]} {set ok 
5f40: 30 7d 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73  0}.        } els
5f50: 65 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65  e {.          se
5f60: 74 20 72 65 20 5b 73 74 72 69 6e 67 20 72 61 6e  t re [string ran
5f70: 67 65 20 24 65 78 70 65 63 74 65 64 20 31 20 65  ge $expected 1 e
5f80: 6e 64 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20  nd-1].          
5f90: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65  if {[string inde
5fa0: 78 20 24 72 65 20 30 5d 3d 3d 22 2a 22 7d 20 7b  x $re 0]=="*"} {
5fb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 49  .            # I
5fc0: 66 20 74 68 65 20 72 65 67 75 6c 61 72 20 65 78  f the regular ex
5fd0: 70 72 65 73 73 69 6f 6e 20 62 65 67 69 6e 73 20  pression begins 
5fe0: 77 69 74 68 20 2a 20 74 68 65 6e 20 74 72 65 61  with * then trea
5ff0: 74 20 69 74 20 61 73 20 61 20 67 6c 6f 62 20 69  t it as a glob i
6000: 6e 73 74 65 61 64 0a 20 20 20 20 20 20 20 20 20  nstead.         
6010: 20 20 20 73 65 74 20 6f 6b 20 5b 73 74 72 69 6e     set ok [strin
6020: 67 20 6d 61 74 63 68 20 24 72 65 20 24 72 65 73  g match $re $res
6030: 75 6c 74 5d 0a 20 20 20 20 20 20 20 20 20 20 7d  ult].          }
6040: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
6050: 20 20 20 20 73 65 74 20 72 65 20 5b 73 74 72 69      set re [stri
6060: 6e 67 20 6d 61 70 20 7b 23 20 7b 5b 2d 30 2d 39  ng map {# {[-0-9
6070: 2e 5d 2b 7d 7d 20 24 72 65 5d 0a 20 20 20 20 20  .]+}} $re].     
6080: 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 72         set ok [r
6090: 65 67 65 78 70 20 24 72 65 20 24 72 65 73 75 6c  egexp $re $resul
60a0: 74 5d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  t].          }. 
60b0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
60c0: 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70   elseif {[regexp
60d0: 20 7b 5e 7e 3f 5c 2a 2e 2a 5c 2a 24 7d 20 24 65   {^~?\*.*\*$} $e
60e0: 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20 20 20 20  xpected]} {.    
60f0: 20 20 20 20 23 20 22 65 78 70 65 63 74 65 64 22      # "expected"
6100: 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20   is of the form 
6110: 22 2a 47 4c 4f 42 2a 22 20 74 68 65 6e 20 74 68  "*GLOB*" then th
6120: 65 20 72 65 73 75 6c 74 20 69 66 20 63 6f 72 72  e result if corr
6130: 65 63 74 20 69 66 0a 20 20 20 20 20 20 20 20 23  ect if.        #
6140: 20 67 6c 6f 62 20 70 61 74 74 65 72 6e 20 47 4c   glob pattern GL
6150: 4f 42 20 6d 61 74 63 68 65 73 20 74 68 65 20 72  OB matches the r
6160: 65 73 75 6c 74 2e 20 20 22 7e 2f 47 4c 4f 42 2f  esult.  "~/GLOB/
6170: 22 20 6d 65 61 6e 73 0a 20 20 20 20 20 20 20 20  " means.        
6180: 23 20 74 68 65 20 67 6c 6f 62 20 6d 75 73 74 20  # the glob must 
6190: 6e 6f 74 20 6d 61 74 63 68 2e 0a 20 20 20 20 20  not match..     
61a0: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 69     if {[string i
61b0: 6e 64 65 78 20 24 65 78 70 65 63 74 65 64 20 30  ndex $expected 0
61c0: 5d 3d 3d 22 7e 22 7d 20 7b 0a 20 20 20 20 20 20  ]=="~"} {.      
61d0: 20 20 20 20 73 65 74 20 65 20 5b 73 74 72 69 6e      set e [strin
61e0: 67 20 72 61 6e 67 65 20 24 65 78 70 65 63 74 65  g range $expecte
61f0: 64 20 31 20 65 6e 64 5d 0a 20 20 20 20 20 20 20  d 1 end].       
6200: 20 20 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20     set ok [expr 
6210: 7b 21 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20  {![string match 
6220: 24 65 20 24 72 65 73 75 6c 74 5d 7d 5d 0a 20 20  $e $result]}].  
6230: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
6240: 20 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20           set ok 
6250: 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 65  [string match $e
6260: 78 70 65 63 74 65 64 20 24 72 65 73 75 6c 74 5d  xpected $result]
6270: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
6280: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
6290: 20 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b    set ok [expr {
62a0: 5b 73 74 72 69 6e 67 20 63 6f 6d 70 61 72 65 20  [string compare 
62b0: 24 72 65 73 75 6c 74 20 24 65 78 70 65 63 74 65  $result $expecte
62c0: 64 5d 3d 3d 30 7d 5d 0a 20 20 20 20 20 20 7d 0a  d]==0}].      }.
62d0: 20 20 20 20 20 20 69 66 20 7b 21 24 6f 6b 7d 20        if {!$ok} 
62e0: 7b 0a 20 20 20 20 20 20 20 20 23 20 69 66 20 7b  {.        # if {
62f0: 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  ![info exists ::
6300: 74 65 73 74 70 72 65 66 69 78 5d 20 7c 7c 20 24  testprefix] || $
6310: 3a 3a 74 65 73 74 70 72 65 66 69 78 20 65 71 20  ::testprefix eq 
6320: 22 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20  ""} {.        # 
6330: 20 20 65 72 72 6f 72 20 22 6e 6f 20 74 65 73 74    error "no test
6340: 20 70 72 65 66 69 78 22 0a 20 20 20 20 20 20 20   prefix".       
6350: 20 23 20 7d 0a 20 20 20 20 20 20 20 20 6f 75 74   # }.        out
6360: 70 75 74 31 20 22 22 0a 20 20 20 20 20 20 20 20  put1 "".        
6370: 6f 75 74 70 75 74 32 20 22 21 20 24 6e 61 6d 65  output2 "! $name
6380: 20 65 78 70 65 63 74 65 64 3a 20 5c 5b 24 65 78   expected: \[$ex
6390: 70 65 63 74 65 64 5c 5d 5c 6e 21 20 24 6e 61 6d  pected\]\n! $nam
63a0: 65 20 67 6f 74 3a 20 20 20 20 20 20 5c 5b 24 72  e got:      \[$r
63b0: 65 73 75 6c 74 5c 5d 22 0a 20 20 20 20 20 20 20  esult\]".       
63c0: 20 66 61 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65   fail_test $name
63d0: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  .      } else {.
63e0: 20 20 20 20 20 20 20 20 6f 75 74 70 75 74 31 20          output1 
63f0: 22 20 4f 6b 22 0a 20 20 20 20 20 20 7d 0a 20 20  " Ok".      }.  
6400: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
6410: 20 20 20 6f 75 74 70 75 74 31 20 22 20 4f 6d 69     output1 " Omi
6420: 74 74 65 64 22 0a 20 20 20 20 6f 6d 69 74 5f 74  tted".    omit_t
6430: 65 73 74 20 24 6e 61 6d 65 20 22 70 61 74 74 65  est $name "patte
6440: 72 6e 20 6d 69 73 6d 61 74 63 68 22 20 30 0a 20  rn mismatch" 0. 
6450: 20 7d 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75   }.  flush stdou
6460: 74 0a 7d 0a 0a 70 72 6f 63 20 64 75 6d 70 62 79  t.}..proc dumpby
6470: 74 65 73 20 7b 73 7d 20 7b 0a 20 20 73 65 74 20  tes {s} {.  set 
6480: 72 20 22 22 0a 20 20 66 6f 72 20 7b 73 65 74 20  r "".  for {set 
6490: 69 20 30 7d 20 7b 24 69 20 3c 20 5b 73 74 72 69  i 0} {$i < [stri
64a0: 6e 67 20 6c 65 6e 67 74 68 20 24 73 5d 7d 20 7b  ng length $s]} {
64b0: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 69 66  incr i} {.    if
64c0: 20 7b 24 69 20 3e 20 30 7d 20 7b 61 70 70 65 6e   {$i > 0} {appen
64d0: 64 20 72 20 22 20 22 7d 0a 20 20 20 20 61 70 70  d r " "}.    app
64e0: 65 6e 64 20 72 20 5b 66 6f 72 6d 61 74 20 25 30  end r [format %0
64f0: 32 58 20 5b 73 63 61 6e 20 5b 73 74 72 69 6e 67  2X [scan [string
6500: 20 69 6e 64 65 78 20 24 73 20 24 69 5d 20 25 63   index $s $i] %c
6510: 5d 5d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  ]].  }.  return 
6520: 24 72 0a 7d 0a 0a 70 72 6f 63 20 63 61 74 63 68  $r.}..proc catch
6530: 63 6d 64 20 7b 64 62 20 7b 63 6d 64 20 22 22 7d  cmd {db {cmd ""}
6540: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 43 4c 49  } {.  global CLI
6550: 0a 20 20 73 65 74 20 6f 75 74 20 5b 6f 70 65 6e  .  set out [open
6560: 20 63 6d 64 73 2e 74 78 74 20 77 5d 0a 20 20 70   cmds.txt w].  p
6570: 75 74 73 20 24 6f 75 74 20 24 63 6d 64 0a 20 20  uts $out $cmd.  
6580: 63 6c 6f 73 65 20 24 6f 75 74 0a 20 20 73 65 74  close $out.  set
6590: 20 6c 69 6e 65 20 22 65 78 65 63 20 24 43 4c 49   line "exec $CLI
65a0: 20 24 64 62 20 3c 20 63 6d 64 73 2e 74 78 74 22   $db < cmds.txt"
65b0: 0a 20 20 73 65 74 20 72 63 20 5b 63 61 74 63 68  .  set rc [catch
65c0: 20 7b 20 65 76 61 6c 20 24 6c 69 6e 65 20 7d 20   { eval $line } 
65d0: 6d 73 67 5d 0a 20 20 6c 69 73 74 20 24 72 63 20  msg].  list $rc 
65e0: 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20 63 61 74  $msg.}..proc cat
65f0: 63 68 63 6d 64 65 78 20 7b 64 62 20 7b 63 6d 64  chcmdex {db {cmd
6600: 20 22 22 7d 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c   ""}} {.  global
6610: 20 43 4c 49 0a 20 20 73 65 74 20 6f 75 74 20 5b   CLI.  set out [
6620: 6f 70 65 6e 20 63 6d 64 73 2e 74 78 74 20 77 5d  open cmds.txt w]
6630: 0a 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 6f  .  fconfigure $o
6640: 75 74 20 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e  ut -encoding bin
6650: 61 72 79 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e  ary -translation
6660: 20 62 69 6e 61 72 79 0a 20 20 70 75 74 73 20 2d   binary.  puts -
6670: 6e 6f 6e 65 77 6c 69 6e 65 20 24 6f 75 74 20 24  nonewline $out $
6680: 63 6d 64 0a 20 20 63 6c 6f 73 65 20 24 6f 75 74  cmd.  close $out
6690: 0a 20 20 73 65 74 20 6c 69 6e 65 20 22 65 78 65  .  set line "exe
66a0: 63 20 2d 6b 65 65 70 6e 65 77 6c 69 6e 65 20 2d  c -keepnewline -
66b0: 2d 20 24 43 4c 49 20 24 64 62 20 3c 20 63 6d 64  - $CLI $db < cmd
66c0: 73 2e 74 78 74 22 0a 20 20 73 65 74 20 63 68 61  s.txt".  set cha
66d0: 6e 73 20 5b 6c 69 73 74 20 73 74 64 69 6e 20 73  ns [list stdin s
66e0: 74 64 6f 75 74 20 73 74 64 65 72 72 5d 0a 20 20  tdout stderr].  
66f0: 66 6f 72 65 61 63 68 20 63 68 61 6e 20 24 63 68  foreach chan $ch
6700: 61 6e 73 20 7b 0a 20 20 20 20 63 61 74 63 68 20  ans {.    catch 
6710: 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 6f 64 65  {.      set mode
6720: 73 28 24 63 68 61 6e 29 20 5b 66 63 6f 6e 66 69  s($chan) [fconfi
6730: 67 75 72 65 20 24 63 68 61 6e 5d 0a 20 20 20 20  gure $chan].    
6740: 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 63 68    fconfigure $ch
6750: 61 6e 20 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e  an -encoding bin
6760: 61 72 79 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e  ary -translation
6770: 20 62 69 6e 61 72 79 20 2d 62 75 66 66 65 72 69   binary -bufferi
6780: 6e 67 20 6e 6f 6e 65 0a 20 20 20 20 7d 0a 20 20  ng none.    }.  
6790: 7d 0a 20 20 73 65 74 20 72 63 20 5b 63 61 74 63  }.  set rc [catc
67a0: 68 20 7b 20 65 76 61 6c 20 24 6c 69 6e 65 20 7d  h { eval $line }
67b0: 20 6d 73 67 5d 0a 20 20 66 6f 72 65 61 63 68 20   msg].  foreach 
67c0: 63 68 61 6e 20 24 63 68 61 6e 73 20 7b 0a 20 20  chan $chans {.  
67d0: 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20    catch {.      
67e0: 65 76 61 6c 20 66 63 6f 6e 66 69 67 75 72 65 20  eval fconfigure 
67f0: 5b 6c 69 73 74 20 24 63 68 61 6e 5d 20 24 6d 6f  [list $chan] $mo
6800: 64 65 73 28 24 63 68 61 6e 29 0a 20 20 20 20 7d  des($chan).    }
6810: 0a 20 20 7d 0a 20 20 23 20 70 75 74 73 20 5b 64  .  }.  # puts [d
6820: 75 6d 70 62 79 74 65 73 20 24 6d 73 67 5d 0a 20  umpbytes $msg]. 
6830: 20 6c 69 73 74 20 24 72 63 20 24 6d 73 67 0a 7d   list $rc $msg.}
6840: 0a 0a 70 72 6f 63 20 66 69 6c 65 70 61 74 68 5f  ..proc filepath_
6850: 6e 6f 72 6d 61 6c 69 7a 65 20 7b 70 7d 20 7b 0a  normalize {p} {.
6860: 20 20 23 20 74 65 73 74 20 63 61 73 65 73 20 73    # test cases s
6870: 68 6f 75 6c 64 20 62 65 20 77 72 69 74 74 65 6e  hould be written
6880: 20 74 6f 20 61 73 73 75 6d 65 20 22 75 6e 69 78   to assume "unix
6890: 22 2d 6c 69 6b 65 20 66 69 6c 65 20 70 61 74 68  "-like file path
68a0: 73 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70  s.  if {$::tcl_p
68b0: 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d  latform(platform
68c0: 29 21 3d 22 75 6e 69 78 22 7d 20 7b 0a 20 20 20  )!="unix"} {.   
68d0: 20 23 20 6c 72 65 76 65 72 73 65 2a 32 20 61 73   # lreverse*2 as
68e0: 20 61 20 68 61 63 6b 20 74 6f 20 72 65 6d 6f 76   a hack to remov
68f0: 65 20 61 6e 79 20 75 6e 6e 65 65 64 65 64 20 7b  e any unneeded {
6900: 7d 20 61 66 74 65 72 20 74 68 65 20 73 74 72 69  } after the stri
6910: 6e 67 20 6d 61 70 0a 20 20 20 20 6c 72 65 76 65  ng map.    lreve
6920: 72 73 65 20 5b 6c 72 65 76 65 72 73 65 20 5b 73  rse [lreverse [s
6930: 74 72 69 6e 67 20 6d 61 70 20 7b 5c 5c 20 2f 7d  tring map {\\ /}
6940: 20 5b 72 65 67 73 75 62 20 2d 6e 6f 63 61 73 65   [regsub -nocase
6950: 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5d 3a 5b 2f 5c   -all {[a-z]:[/\
6960: 5c 5d 2b 7d 20 24 70 20 7b 2f 7d 5d 5d 5d 0a 20  \]+} $p {/}]]]. 
6970: 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 70 0a 20   } {.    set p. 
6980: 20 7d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 66 69 6c   }.}.proc do_fil
6990: 65 70 61 74 68 5f 74 65 73 74 20 7b 6e 61 6d 65  epath_test {name
69a0: 20 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b   cmd expected} {
69b0: 0a 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74  .  uplevel [list
69c0: 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b   do_test $name [
69d0: 0a 20 20 20 20 73 75 62 73 74 20 2d 6e 6f 63 6f  .    subst -noco
69e0: 6d 6d 61 6e 64 73 20 7b 20 66 69 6c 65 70 61 74  mmands { filepat
69f0: 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 5b 20 24 63  h_normalize [ $c
6a00: 6d 64 20 5d 20 7d 0a 20 20 5d 20 5b 66 69 6c 65  md ] }.  ] [file
6a10: 70 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 24  path_normalize $
6a20: 65 78 70 65 63 74 65 64 5d 5d 0a 7d 0a 0a 70 72  expected]].}..pr
6a30: 6f 63 20 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61  oc realnum_norma
6a40: 6c 69 7a 65 20 7b 72 7d 20 7b 0a 20 20 23 20 64  lize {r} {.  # d
6a50: 69 66 66 65 72 65 6e 74 20 54 43 4c 20 76 65 72  ifferent TCL ver
6a60: 73 69 6f 6e 73 20 64 69 73 70 6c 61 79 20 66 6c  sions display fl
6a70: 6f 61 74 69 6e 67 20 70 6f 69 6e 74 20 76 61 6c  oating point val
6a80: 75 65 73 20 64 69 66 66 65 72 65 6e 74 6c 79 2e  ues differently.
6a90: 0a 20 20 73 74 72 69 6e 67 20 6d 61 70 20 7b 31  .  string map {1
6aa0: 2e 23 49 4e 46 20 69 6e 66 20 49 6e 66 20 69 6e  .#INF inf Inf in
6ab0: 66 20 2e 30 65 20 65 7d 20 5b 72 65 67 73 75 62  f .0e e} [regsub
6ac0: 20 2d 61 6c 6c 20 7b 28 65 5b 2b 2d 5d 29 30 2b   -all {(e[+-])0+
6ad0: 7d 20 24 72 20 7b 5c 31 7d 5d 0a 7d 0a 70 72 6f  } $r {\1}].}.pro
6ae0: 63 20 64 6f 5f 72 65 61 6c 6e 75 6d 5f 74 65 73  c do_realnum_tes
6af0: 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70 65  t {name cmd expe
6b00: 63 74 65 64 7d 20 7b 0a 20 20 75 70 6c 65 76 65  cted} {.  upleve
6b10: 6c 20 5b 6c 69 73 74 20 64 6f 5f 74 65 73 74 20  l [list do_test 
6b20: 24 6e 61 6d 65 20 5b 0a 20 20 20 20 73 75 62 73  $name [.    subs
6b30: 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b 20  t -nocommands { 
6b40: 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a  realnum_normaliz
6b50: 65 20 5b 20 24 63 6d 64 20 5d 20 7d 0a 20 20 5d  e [ $cmd ] }.  ]
6b60: 20 5b 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c   [realnum_normal
6b70: 69 7a 65 20 24 65 78 70 65 63 74 65 64 5d 5d 0a  ize $expected]].
6b80: 7d 0a 0a 70 72 6f 63 20 66 69 78 5f 74 65 73 74  }..proc fix_test
6b90: 6e 61 6d 65 20 7b 76 61 72 6e 61 6d 65 7d 20 7b  name {varname} {
6ba0: 0a 20 20 75 70 76 61 72 20 24 76 61 72 6e 61 6d  .  upvar $varnam
6bb0: 65 20 74 65 73 74 6e 61 6d 65 0a 20 20 69 66 20  e testname.  if 
6bc0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
6bd0: 74 65 73 74 70 72 65 66 69 78 5d 0a 20 20 20 26  testprefix].   &
6be0: 26 20 5b 73 74 72 69 6e 67 20 69 73 20 64 69 67  & [string is dig
6bf0: 69 74 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65  it [string range
6c00: 20 24 74 65 73 74 6e 61 6d 65 20 30 20 30 5d 5d   $testname 0 0]]
6c10: 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 74  .  } {.    set t
6c20: 65 73 74 6e 61 6d 65 20 22 24 7b 3a 3a 74 65 73  estname "${::tes
6c30: 74 70 72 65 66 69 78 7d 2d 24 74 65 73 74 6e 61  tprefix}-$testna
6c40: 6d 65 22 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20  me".  }.}..proc 
6c50: 6e 6f 72 6d 61 6c 69 7a 65 5f 6c 69 73 74 20 7b  normalize_list {
6c60: 4c 7d 20 7b 0a 20 20 73 65 74 20 4c 32 20 5b 6c  L} {.  set L2 [l
6c70: 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 6c  ist].  foreach l
6c80: 20 24 4c 20 7b 6c 61 70 70 65 6e 64 20 4c 32 20   $L {lappend L2 
6c90: 24 6c 7d 0a 20 20 73 65 74 20 4c 32 0a 7d 0a 0a  $l}.  set L2.}..
6ca0: 23 20 45 69 74 68 65 72 3a 0a 23 0a 23 20 20 20  # Either:.#.#   
6cb0: 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20  do_execsql_test 
6cc0: 54 45 53 54 4e 41 4d 45 20 53 51 4c 20 3f 52 45  TESTNAME SQL ?RE
6cd0: 53 3f 0a 23 20 20 20 64 6f 5f 65 78 65 63 73 71  S?.#   do_execsq
6ce0: 6c 5f 74 65 73 74 20 2d 64 62 20 44 42 20 54 45  l_test -db DB TE
6cf0: 53 54 4e 41 4d 45 20 53 51 4c 20 3f 52 45 53 3f  STNAME SQL ?RES?
6d00: 0a 23 0a 70 72 6f 63 20 64 6f 5f 65 78 65 63 73  .#.proc do_execs
6d10: 71 6c 5f 74 65 73 74 20 7b 61 72 67 73 7d 20 7b  ql_test {args} {
6d20: 0a 20 20 73 65 74 20 64 62 20 64 62 0a 20 20 69  .  set db db.  i
6d30: 66 20 7b 5b 6c 69 6e 64 65 78 20 24 61 72 67 73  f {[lindex $args
6d40: 20 30 5d 3d 3d 22 2d 64 62 22 7d 20 7b 0a 20 20   0]=="-db"} {.  
6d50: 20 20 73 65 74 20 64 62 20 5b 6c 69 6e 64 65 78    set db [lindex
6d60: 20 24 61 72 67 73 20 31 5d 0a 20 20 20 20 73 65   $args 1].    se
6d70: 74 20 61 72 67 73 20 5b 6c 72 61 6e 67 65 20 24  t args [lrange $
6d80: 61 72 67 73 20 32 20 65 6e 64 5d 0a 20 20 7d 0a  args 2 end].  }.
6d90: 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20  .  if {[llength 
6da0: 24 61 72 67 73 5d 3d 3d 32 7d 20 7b 0a 20 20 20  $args]==2} {.   
6db0: 20 66 6f 72 65 61 63 68 20 7b 74 65 73 74 6e 61   foreach {testna
6dc0: 6d 65 20 73 71 6c 7d 20 24 61 72 67 73 20 7b 7d  me sql} $args {}
6dd0: 0a 20 20 20 20 73 65 74 20 72 65 73 75 6c 74 20  .    set result 
6de0: 22 22 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b  "".  } elseif {[
6df0: 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 3d 3d  llength $args]==
6e00: 33 7d 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68  3} {.    foreach
6e10: 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 72   {testname sql r
6e20: 65 73 75 6c 74 7d 20 24 61 72 67 73 20 7b 7d 0a  esult} $args {}.
6e30: 0a 20 20 20 20 23 20 57 69 74 68 20 73 6f 6d 65  .    # With some
6e40: 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 54 63 6c   versions of Tcl
6e50: 20 6f 6e 20 77 69 6e 64 6f 77 73 2c 20 69 66 20   on windows, if 
6e60: 24 72 65 73 75 6c 74 20 69 73 20 61 6c 6c 20 77  $result is all w
6e70: 68 69 74 65 73 70 61 63 65 20 62 75 74 0a 20 20  hitespace but.  
6e80: 20 20 23 20 63 6f 6e 74 61 69 6e 73 20 73 6f 6d    # contains som
6e90: 65 20 43 52 2f 4c 46 20 63 68 61 72 61 63 74 65  e CR/LF characte
6ea0: 72 73 2c 20 74 68 65 20 5b 6c 69 73 74 20 7b 2a  rs, the [list {*
6eb0: 7d 24 72 65 73 75 6c 74 5d 20 62 65 6c 6f 77 20  }$result] below 
6ec0: 72 65 74 75 72 6e 73 20 61 0a 20 20 20 20 23 20  returns a.    # 
6ed0: 63 6f 70 79 20 6f 66 20 24 72 65 73 75 6c 74 20  copy of $result 
6ee0: 69 6e 73 74 65 61 64 20 6f 66 20 61 20 7a 65 72  instead of a zer
6ef0: 6f 20 6c 65 6e 67 74 68 20 73 74 72 69 6e 67 2e  o length string.
6f00: 20 4e 6f 74 20 63 6c 65 61 72 20 65 78 61 63 74   Not clear exact
6f10: 6c 79 20 77 68 79 0a 20 20 20 20 23 20 74 68 69  ly why.    # thi
6f20: 73 20 69 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77  s is. The follow
6f30: 69 6e 67 20 69 73 20 61 20 77 6f 72 6b 61 72 6f  ing is a workaro
6f40: 75 6e 64 2e 0a 20 20 20 20 69 66 20 7b 5b 6c 6c  und..    if {[ll
6f50: 65 6e 67 74 68 20 24 72 65 73 75 6c 74 5d 3d 3d  ength $result]==
6f60: 30 7d 20 7b 20 73 65 74 20 72 65 73 75 6c 74 20  0} { set result 
6f70: 22 22 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  "" }.  } else {.
6f80: 20 20 20 20 65 72 72 6f 72 20 5b 73 74 72 69 6e      error [strin
6f90: 67 20 74 72 69 6d 20 7b 0a 20 20 20 20 20 20 77  g trim {.      w
6fa0: 72 6f 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f  rong # args: sho
6fb0: 75 6c 64 20 62 65 20 22 64 6f 5f 65 78 65 63 73  uld be "do_execs
6fc0: 71 6c 5f 74 65 73 74 20 3f 2d 64 62 20 44 42 3f  ql_test ?-db DB?
6fd0: 20 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 3f 72   testname sql ?r
6fe0: 65 73 75 6c 74 3f 22 0a 20 20 20 20 7d 5d 0a 20  esult?".    }]. 
6ff0: 20 7d 0a 0a 20 20 66 69 78 5f 74 65 73 74 6e 61   }..  fix_testna
7000: 6d 65 20 74 65 73 74 6e 61 6d 65 0a 0a 20 20 75  me testname..  u
7010: 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 20  plevel do_test  
7020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
7030: 0a 20 20 20 20 20 20 5b 6c 69 73 74 20 24 74 65  .      [list $te
7040: 73 74 6e 61 6d 65 5d 20 20 20 20 20 20 20 20 20  stname]         
7050: 20 20 20 5c 0a 20 20 20 20 20 20 5b 6c 69 73 74     \.      [list
7060: 20 22 65 78 65 63 73 71 6c 20 7b 24 73 71 6c 7d   "execsql {$sql}
7070: 20 24 64 62 22 5d 20 5c 0a 20 20 20 20 20 20 5b   $db"] \.      [
7080: 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72  list [list {*}$r
7090: 65 73 75 6c 74 5d 5d 0a 7d 0a 0a 70 72 6f 63 20  esult]].}..proc 
70a0: 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74  do_catchsql_test
70b0: 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 72   {testname sql r
70c0: 65 73 75 6c 74 7d 20 7b 0a 20 20 66 69 78 5f 74  esult} {.  fix_t
70d0: 65 73 74 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65  estname testname
70e0: 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65  .  uplevel do_te
70f0: 73 74 20 5b 6c 69 73 74 20 24 74 65 73 74 6e 61  st [list $testna
7100: 6d 65 5d 20 5b 6c 69 73 74 20 22 63 61 74 63 68  me] [list "catch
7110: 73 71 6c 20 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69  sql {$sql}"] [li
7120: 73 74 20 24 72 65 73 75 6c 74 5d 0a 7d 0a 70 72  st $result].}.pr
7130: 6f 63 20 64 6f 5f 74 69 6d 65 64 5f 65 78 65 63  oc do_timed_exec
7140: 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61  sql_test {testna
7150: 6d 65 20 73 71 6c 20 7b 72 65 73 75 6c 74 20 7b  me sql {result {
7160: 7d 7d 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73 74  }}} {.  fix_test
7170: 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20  name testname.  
7180: 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20  uplevel do_test 
7190: 5b 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d  [list $testname]
71a0: 20 5b 6c 69 73 74 20 22 65 78 65 63 73 71 6c 5f   [list "execsql_
71b0: 74 69 6d 65 64 20 7b 24 73 71 6c 7d 22 5d 5c 0a  timed {$sql}"]\.
71c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71e0: 20 20 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 7b     [list [list {
71f0: 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a 7d 0a 0a 23  *}$result]].}..#
7200: 20 52 75 6e 20 61 6e 20 45 58 50 4c 41 49 4e 20   Run an EXPLAIN 
7210: 51 55 45 52 59 20 50 4c 41 4e 20 24 73 71 6c 20  QUERY PLAN $sql 
7220: 69 6e 20 64 61 74 61 62 61 73 65 20 22 64 62 22  in database "db"
7230: 2e 20 20 54 68 65 6e 20 72 65 77 72 69 74 65 20  .  Then rewrite 
7240: 74 68 65 20 6f 75 74 70 75 74 0a 23 20 61 73 20  the output.# as 
7250: 61 6e 20 41 53 43 49 49 2d 61 72 74 20 67 72 61  an ASCII-art gra
7260: 70 68 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20  ph and return a 
7270: 73 74 72 69 6e 67 20 74 68 61 74 20 69 73 20 74  string that is t
7280: 68 61 74 20 67 72 61 70 68 2e 0a 23 0a 23 20 48  hat graph..#.# H
7290: 65 78 61 64 65 63 69 6d 61 6c 20 6c 69 74 65 72  exadecimal liter
72a0: 61 6c 73 20 69 6e 20 74 68 65 20 6f 75 74 70 75  als in the outpu
72b0: 74 20 74 65 78 74 20 61 72 65 20 63 6f 6e 76 65  t text are conve
72c0: 72 74 65 64 20 69 6e 74 6f 20 22 78 78 78 78 78  rted into "xxxxx
72d0: 78 22 20 73 69 6e 63 65 20 74 68 6f 73 65 0a 23  x" since those.#
72e0: 20 6c 69 74 65 72 61 6c 73 20 61 72 65 20 70 6f   literals are po
72f0: 69 6e 74 65 72 20 76 61 6c 75 65 73 20 74 68 61  inter values tha
7300: 74 20 6d 69 67 68 74 20 76 65 72 79 20 66 72 6f  t might very fro
7310: 6d 20 6f 6e 65 20 72 75 6e 20 6f 66 20 74 68 65  m one run of the
7320: 20 74 65 73 74 20 74 6f 20 74 68 65 0a 23 20 6e   test to the.# n
7330: 65 78 74 2c 20 79 65 74 20 77 65 20 77 61 6e 74  ext, yet we want
7340: 20 74 68 65 20 6f 75 74 70 75 74 20 74 6f 20 62   the output to b
7350: 65 20 63 6f 6e 73 69 73 74 65 6e 74 2e 0a 23 0a  e consistent..#.
7360: 70 72 6f 63 20 71 75 65 72 79 5f 70 6c 61 6e 5f  proc query_plan_
7370: 67 72 61 70 68 20 7b 73 71 6c 7d 20 7b 0a 20 20  graph {sql} {.  
7380: 64 62 20 65 76 61 6c 20 22 45 58 50 4c 41 49 4e  db eval "EXPLAIN
7390: 20 51 55 45 52 59 20 50 4c 41 4e 20 24 73 71 6c   QUERY PLAN $sql
73a0: 22 20 7b 0a 20 20 20 20 73 65 74 20 64 78 28 24  " {.    set dx($
73b0: 69 64 29 20 24 64 65 74 61 69 6c 0a 20 20 20 20  id) $detail.    
73c0: 6c 61 70 70 65 6e 64 20 63 78 28 24 70 61 72 65  lappend cx($pare
73d0: 6e 74 29 20 24 69 64 0a 20 20 7d 0a 20 20 73 65  nt) $id.  }.  se
73e0: 74 20 61 20 22 5c 6e 20 20 51 55 45 52 59 20 50  t a "\n  QUERY P
73f0: 4c 41 4e 5c 6e 22 0a 20 20 61 70 70 65 6e 64 20  LAN\n".  append 
7400: 61 20 5b 61 70 70 65 6e 64 5f 67 72 61 70 68 20  a [append_graph 
7410: 22 20 20 22 20 64 78 20 63 78 20 30 5d 0a 20 20  "  " dx cx 0].  
7420: 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 20 30 78  regsub -all { 0x
7430: 5b 41 2d 46 30 2d 39 5d 2b 5c 79 7d 20 24 61 20  [A-F0-9]+\y} $a 
7440: 7b 20 78 78 78 78 78 78 7d 20 61 0a 20 20 72 65  { xxxxxx} a.  re
7450: 67 73 75 62 20 2d 61 6c 6c 20 7b 28 4d 41 54 45  gsub -all {(MATE
7460: 52 49 41 4c 49 5a 45 7c 43 4f 2d 52 4f 55 54 49  RIALIZE|CO-ROUTI
7470: 4e 45 7c 53 55 42 51 55 45 52 59 29 20 5c 64 2b  NE|SUBQUERY) \d+
7480: 5c 79 7d 20 24 61 20 7b 5c 31 20 78 78 78 78 78  \y} $a {\1 xxxxx
7490: 78 7d 20 61 0a 20 20 72 65 74 75 72 6e 20 24 61  x} a.  return $a
74a0: 0a 7d 0a 0a 23 20 48 65 6c 70 65 72 20 72 6f 75  .}..# Helper rou
74b0: 74 69 6e 65 20 66 6f 72 20 5b 71 75 65 72 79 5f  tine for [query_
74c0: 70 6c 61 6e 5f 67 72 61 70 68 20 53 51 4c 5d 3a  plan_graph SQL]:
74d0: 0a 23 0a 23 20 4f 75 74 70 75 74 20 72 6f 77 73  .#.# Output rows
74e0: 20 6f 66 20 74 68 65 20 67 72 61 70 68 20 74 68   of the graph th
74f0: 61 74 20 61 72 65 20 63 68 69 6c 64 72 65 6e 20  at are children 
7500: 6f 66 20 24 6c 65 76 65 6c 2e 0a 23 0a 23 20 20  of $level..#.#  
7510: 20 70 72 65 66 69 78 3a 20 20 50 72 65 70 65 6e   prefix:  Prepen
7520: 64 20 74 6f 20 65 76 65 72 79 20 6f 75 74 70 75  d to every outpu
7530: 74 20 6c 69 6e 65 0a 23 0a 23 20 20 20 64 78 6e  t line.#.#   dxn
7540: 61 6d 65 3a 20 20 4e 61 6d 65 20 6f 66 20 61 6e  ame:  Name of an
7550: 20 61 72 72 61 79 20 76 61 72 69 61 62 6c 65 20   array variable 
7560: 74 68 61 74 20 73 74 6f 72 65 73 20 74 65 78 74  that stores text
7570: 20 64 65 73 63 72 69 62 65 0a 23 20 20 20 20 20   describe.#     
7580: 20 20 20 20 20 20 20 54 68 65 20 64 65 73 63 72         The descr
7590: 69 70 74 69 6f 6e 20 66 6f 72 20 24 69 64 20 69  iption for $id i
75a0: 73 20 24 64 78 28 24 69 64 29 0a 23 0a 23 20 20  s $dx($id).#.#  
75b0: 20 63 78 6e 61 6d 65 3a 20 20 4e 61 6d 65 20 6f   cxname:  Name o
75c0: 66 20 61 6e 20 61 72 72 61 79 20 76 61 72 69 61  f an array varia
75d0: 62 6c 65 20 68 6f 6c 64 69 6e 67 20 63 68 69 6c  ble holding chil
75e0: 64 72 65 6e 20 6f 66 20 69 74 65 6d 2e 0a 23 20  dren of item..# 
75f0: 20 20 20 20 20 20 20 20 20 20 20 43 68 69 6c 64             Child
7600: 72 65 6e 20 6f 66 20 24 69 64 20 61 72 65 20 24  ren of $id are $
7610: 63 78 28 24 69 64 29 0a 23 0a 23 20 20 20 6c 65  cx($id).#.#   le
7620: 76 65 6c 3a 20 20 20 52 65 6e 64 65 72 20 61 6c  vel:   Render al
7630: 6c 20 6c 69 6e 65 73 20 74 68 61 74 20 61 72 65  l lines that are
7640: 20 63 68 69 6c 64 72 65 6e 20 6f 66 20 24 6c 65   children of $le
7650: 76 65 6c 0a 23 20 0a 70 72 6f 63 20 61 70 70 65  vel.# .proc appe
7660: 6e 64 5f 67 72 61 70 68 20 7b 70 72 65 66 69 78  nd_graph {prefix
7670: 20 64 78 6e 61 6d 65 20 63 78 6e 61 6d 65 20 6c   dxname cxname l
7680: 65 76 65 6c 7d 20 7b 0a 20 20 75 70 76 61 72 20  evel} {.  upvar 
7690: 24 64 78 6e 61 6d 65 20 64 78 20 24 63 78 6e 61  $dxname dx $cxna
76a0: 6d 65 20 63 78 0a 20 20 73 65 74 20 61 20 22 22  me cx.  set a ""
76b0: 0a 20 20 73 65 74 20 78 20 24 63 78 28 24 6c 65  .  set x $cx($le
76c0: 76 65 6c 29 0a 20 20 73 65 74 20 6e 20 5b 6c 6c  vel).  set n [ll
76d0: 65 6e 67 74 68 20 24 78 5d 0a 20 20 66 6f 72 20  ength $x].  for 
76e0: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 24 6e  {set i 0} {$i<$n
76f0: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
7700: 20 73 65 74 20 69 64 20 5b 6c 69 6e 64 65 78 20   set id [lindex 
7710: 24 78 20 24 69 5d 0a 20 20 20 20 69 66 20 7b 24  $x $i].    if {$
7720: 69 3d 3d 24 6e 2d 31 7d 20 7b 0a 20 20 20 20 20  i==$n-1} {.     
7730: 20 73 65 74 20 70 31 20 22 60 2d 2d 22 0a 20 20   set p1 "`--".  
7740: 20 20 20 20 73 65 74 20 70 32 20 22 20 20 20 22      set p2 "   "
7750: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
7760: 20 20 20 20 73 65 74 20 70 31 20 22 7c 2d 2d 22      set p1 "|--"
7770: 0a 20 20 20 20 20 20 73 65 74 20 70 32 20 22 7c  .      set p2 "|
7780: 20 20 22 0a 20 20 20 20 7d 0a 20 20 20 20 61 70    ".    }.    ap
7790: 70 65 6e 64 20 61 20 24 70 72 65 66 69 78 24 70  pend a $prefix$p
77a0: 31 24 64 78 28 24 69 64 29 5c 6e 0a 20 20 20 20  1$dx($id)\n.    
77b0: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
77c0: 20 63 78 28 24 69 64 29 5d 7d 20 7b 0a 20 20 20   cx($id)]} {.   
77d0: 20 20 20 61 70 70 65 6e 64 20 61 20 5b 61 70 70     append a [app
77e0: 65 6e 64 5f 67 72 61 70 68 20 22 24 70 72 65 66  end_graph "$pref
77f0: 69 78 24 70 32 22 20 64 78 20 63 78 20 24 69 64  ix$p2" dx cx $id
7800: 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ].    }.  }.  re
7810: 74 75 72 6e 20 24 61 0a 7d 0a 0a 23 20 44 6f 20  turn $a.}..# Do 
7820: 61 6e 20 45 58 50 4c 41 49 4e 20 51 55 45 52 59  an EXPLAIN QUERY
7830: 20 50 4c 41 4e 20 74 65 73 74 20 6f 6e 20 69 6e   PLAN test on in
7840: 70 75 74 20 24 73 71 6c 20 77 69 74 68 20 65 78  put $sql with ex
7850: 70 65 63 74 65 64 20 72 65 73 75 6c 74 73 20 24  pected results $
7860: 72 65 73 0a 23 0a 23 20 49 66 20 24 72 65 73 20  res.#.# If $res 
7870: 62 65 67 69 6e 73 20 77 69 74 68 20 61 20 22 5c  begins with a "\
7880: 73 2b 51 55 45 52 59 20 50 4c 41 4e 5c 6e 22 20  s+QUERY PLAN\n" 
7890: 74 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d  then it is assum
78a0: 65 64 20 74 6f 20 62 65 20 74 68 65 20 0a 23 20  ed to be the .# 
78b0: 63 6f 6d 70 6c 65 74 65 20 67 72 61 70 68 20 77  complete graph w
78c0: 68 69 63 68 20 6d 75 73 74 20 6d 61 74 63 68 20  hich must match 
78d0: 74 68 65 20 6f 75 74 70 75 74 20 6f 66 20 5b 71  the output of [q
78e0: 75 65 72 79 5f 70 6c 61 6e 5f 67 72 61 70 68 20  uery_plan_graph 
78f0: 24 73 71 6c 5d 0a 23 20 65 78 61 63 74 6c 79 2e  $sql].# exactly.
7900: 0a 23 0a 23 20 49 66 20 24 72 65 73 20 64 6f 65  .#.# If $res doe
7910: 73 20 6e 6f 74 20 62 65 67 69 6e 20 77 69 74 68  s not begin with
7920: 20 22 5c 73 2b 51 55 45 52 59 20 50 4c 41 4e 5c   "\s+QUERY PLAN\
7930: 6e 22 20 74 68 65 6e 20 74 61 6b 65 20 69 74 20  n" then take it 
7940: 69 73 20 61 20 73 74 72 69 6e 67 0a 23 20 74 68  is a string.# th
7950: 61 74 20 6d 75 73 74 20 62 65 20 66 6f 75 6e 64  at must be found
7960: 20 73 6f 6d 65 77 68 65 72 65 20 69 6e 20 74 68   somewhere in th
7970: 65 20 71 75 65 72 79 20 70 6c 61 6e 20 6f 75 74  e query plan out
7980: 70 75 74 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 65  put..#.proc do_e
7990: 71 70 5f 74 65 73 74 20 7b 6e 61 6d 65 20 73 71  qp_test {name sq
79a0: 6c 20 72 65 73 7d 20 7b 0a 20 20 69 66 20 7b 5b  l res} {.  if {[
79b0: 72 65 67 65 78 70 20 7b 5e 5c 73 2b 51 55 45 52  regexp {^\s+QUER
79c0: 59 20 50 4c 41 4e 5c 6e 7d 20 24 72 65 73 5d 7d  Y PLAN\n} $res]}
79d0: 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c 20 64   {.    uplevel d
79e0: 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 6c 69  o_test $name [li
79f0: 73 74 20 5b 6c 69 73 74 20 71 75 65 72 79 5f 70  st [list query_p
7a00: 6c 61 6e 5f 67 72 61 70 68 20 24 73 71 6c 5d 5d  lan_graph $sql]]
7a10: 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20 7d   [list $res].  }
7a20: 20 65 6c 73 65 20 7b 0a 20 20 20 20 69 66 20 7b   else {.    if {
7a30: 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 24 72  [string index $r
7a40: 65 73 20 30 5d 21 3d 22 2f 22 7d 20 7b 0a 20 20  es 0]!="/"} {.  
7a50: 20 20 20 20 73 65 74 20 72 65 73 20 22 2f 2a 24      set res "/*$
7a60: 72 65 73 2a 2f 22 0a 20 20 20 20 7d 0a 20 20 20  res*/".    }.   
7a70: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63   uplevel do_exec
7a80: 73 71 6c 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b  sql_test $name [
7a90: 6c 69 73 74 20 22 45 58 50 4c 41 49 4e 20 51 55  list "EXPLAIN QU
7aa0: 45 52 59 20 50 4c 41 4e 20 24 73 71 6c 22 5d 20  ERY PLAN $sql"] 
7ab0: 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20 7d 0a  [list $res].  }.
7ac0: 7d 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  }...#-----------
7ad0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7ae0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7af0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7b00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23  --------------.#
7b10: 20 20 20 55 73 61 67 65 3a 20 64 6f 5f 73 65 6c     Usage: do_sel
7b20: 65 63 74 5f 74 65 73 74 73 20 50 52 45 46 49 58  ect_tests PREFIX
7b30: 20 3f 53 57 49 54 43 48 45 53 3f 20 54 45 53 54   ?SWITCHES? TEST
7b40: 4c 49 53 54 0a 23 0a 23 20 57 68 65 72 65 20 73  LIST.#.# Where s
7b50: 77 69 74 63 68 65 73 20 61 72 65 3a 0a 23 0a 23  witches are:.#.#
7b60: 20 20 20 2d 65 72 72 6f 72 66 6f 72 6d 61 74 20     -errorformat 
7b70: 46 4d 54 53 54 52 49 4e 47 0a 23 20 20 20 2d 63  FMTSTRING.#   -c
7b80: 6f 75 6e 74 0a 23 20 20 20 2d 71 75 65 72 79 20  ount.#   -query 
7b90: 53 51 4c 0a 23 20 20 20 2d 74 63 6c 71 75 65 72  SQL.#   -tclquer
7ba0: 79 20 54 43 4c 0a 23 20 20 20 2d 72 65 70 61 69  y TCL.#   -repai
7bb0: 72 20 54 43 4c 0a 23 0a 70 72 6f 63 20 64 6f 5f  r TCL.#.proc do_
7bc0: 73 65 6c 65 63 74 5f 74 65 73 74 73 20 7b 70 72  select_tests {pr
7bd0: 65 66 69 78 20 61 72 67 73 7d 20 7b 0a 0a 20 20  efix args} {..  
7be0: 73 65 74 20 74 65 73 74 6c 69 73 74 20 5b 6c 69  set testlist [li
7bf0: 6e 64 65 78 20 24 61 72 67 73 20 65 6e 64 5d 0a  ndex $args end].
7c00: 20 20 73 65 74 20 73 77 69 74 63 68 65 73 20 5b    set switches [
7c10: 6c 72 61 6e 67 65 20 24 61 72 67 73 20 30 20 65  lrange $args 0 e
7c20: 6e 64 2d 31 5d 0a 0a 20 20 73 65 74 20 65 72 72  nd-1]..  set err
7c30: 66 6d 74 20 22 22 0a 20 20 73 65 74 20 63 6f 75  fmt "".  set cou
7c40: 6e 74 6f 6e 6c 79 20 30 0a 20 20 73 65 74 20 74  ntonly 0.  set t
7c50: 63 6c 71 75 65 72 79 20 22 22 0a 20 20 73 65 74  clquery "".  set
7c60: 20 72 65 70 61 69 72 20 22 22 0a 0a 20 20 66 6f   repair ""..  fo
7c70: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20  r {set i 0} {$i 
7c80: 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 73 77 69 74  < [llength $swit
7c90: 63 68 65 73 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  ches]} {incr i} 
7ca0: 7b 0a 20 20 20 20 73 65 74 20 73 20 5b 6c 69 6e  {.    set s [lin
7cb0: 64 65 78 20 24 73 77 69 74 63 68 65 73 20 24 69  dex $switches $i
7cc0: 5d 0a 20 20 20 20 73 65 74 20 6e 20 5b 73 74 72  ].    set n [str
7cd0: 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 5d 0a 20  ing length $s]. 
7ce0: 20 20 20 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20     if {$n>=2 && 
7cf0: 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c  [string equal -l
7d00: 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 71 75  ength $n $s "-qu
7d10: 65 72 79 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73  ery"]} {.      s
7d20: 65 74 20 74 63 6c 71 75 65 72 79 20 5b 6c 69 73  et tclquery [lis
7d30: 74 20 65 78 65 63 73 71 6c 20 5b 6c 69 6e 64 65  t execsql [linde
7d40: 78 20 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63  x $switches [inc
7d50: 72 20 69 5d 5d 5d 0a 20 20 20 20 7d 20 65 6c 73  r i]]].    } els
7d60: 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73  eif {$n>=2 && [s
7d70: 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e  tring equal -len
7d80: 67 74 68 20 24 6e 20 24 73 20 22 2d 74 63 6c 71  gth $n $s "-tclq
7d90: 75 65 72 79 22 5d 7d 20 7b 0a 20 20 20 20 20 20  uery"]} {.      
7da0: 73 65 74 20 74 63 6c 71 75 65 72 79 20 5b 6c 69  set tclquery [li
7db0: 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20 5b  ndex $switches [
7dc0: 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20 65  incr i]].    } e
7dd0: 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20  lseif {$n>=2 && 
7de0: 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c  [string equal -l
7df0: 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 65 72  ength $n $s "-er
7e00: 72 6f 72 66 6f 72 6d 61 74 22 5d 7d 20 7b 0a 20  rorformat"]} {. 
7e10: 20 20 20 20 20 73 65 74 20 65 72 72 66 6d 74 20       set errfmt 
7e20: 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68 65  [lindex $switche
7e30: 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20  s [incr i]].    
7e40: 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20  } elseif {$n>=2 
7e50: 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c  && [string equal
7e60: 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22   -length $n $s "
7e70: 2d 72 65 70 61 69 72 22 5d 7d 20 7b 0a 20 20 20  -repair"]} {.   
7e80: 20 20 20 73 65 74 20 72 65 70 61 69 72 20 5b 6c     set repair [l
7e90: 69 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20  index $switches 
7ea0: 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20  [incr i]].    } 
7eb0: 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26  elseif {$n>=2 &&
7ec0: 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d   [string equal -
7ed0: 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 63  length $n $s "-c
7ee0: 6f 75 6e 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20  ount"]} {.      
7ef0: 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79 20 31 0a  set countonly 1.
7f00: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
7f10: 20 20 20 65 72 72 6f 72 20 22 75 6e 6b 6e 6f 77     error "unknow
7f20: 6e 20 73 77 69 74 63 68 3a 20 24 73 22 0a 20 20  n switch: $s".  
7f30: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24    }.  }..  if {$
7f40: 63 6f 75 6e 74 6f 6e 6c 79 20 26 26 20 24 65 72  countonly && $er
7f50: 72 66 6d 74 21 3d 22 22 7d 20 7b 0a 20 20 20 20  rfmt!=""} {.    
7f60: 65 72 72 6f 72 20 22 43 61 6e 6e 6f 74 20 75 73  error "Cannot us
7f70: 65 20 2d 63 6f 75 6e 74 20 61 6e 64 20 2d 65 72  e -count and -er
7f80: 72 6f 72 66 6f 72 6d 61 74 20 74 6f 67 65 74 68  rorformat togeth
7f90: 65 72 22 0a 20 20 7d 0a 20 20 73 65 74 20 6e 54  er".  }.  set nT
7fa0: 65 73 74 6c 69 73 74 20 5b 6c 6c 65 6e 67 74 68  estlist [llength
7fb0: 20 24 74 65 73 74 6c 69 73 74 5d 0a 20 20 69 66   $testlist].  if
7fc0: 20 7b 24 6e 54 65 73 74 6c 69 73 74 25 33 20 7c   {$nTestlist%3 |
7fd0: 7c 20 24 6e 54 65 73 74 6c 69 73 74 3d 3d 30 20  | $nTestlist==0 
7fe0: 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 53  } {.    error "S
7ff0: 45 4c 45 43 54 20 74 65 73 74 20 6c 69 73 74 20  ELECT test list 
8000: 63 6f 6e 74 61 69 6e 73 20 5b 6c 6c 65 6e 67 74  contains [llengt
8010: 68 20 24 74 65 73 74 6c 69 73 74 5d 20 65 6c 65  h $testlist] ele
8020: 6d 65 6e 74 73 22 0a 20 20 7d 0a 0a 20 20 65 76  ments".  }..  ev
8030: 61 6c 20 24 72 65 70 61 69 72 0a 20 20 66 6f 72  al $repair.  for
8040: 65 61 63 68 20 7b 74 6e 20 73 71 6c 20 72 65 73  each {tn sql res
8050: 7d 20 24 74 65 73 74 6c 69 73 74 20 7b 0a 20 20  } $testlist {.  
8060: 20 20 69 66 20 7b 24 74 63 6c 71 75 65 72 79 20    if {$tclquery 
8070: 21 3d 20 22 22 7d 20 7b 0a 20 20 20 20 20 20 65  != ""} {.      e
8080: 78 65 63 73 71 6c 20 24 73 71 6c 0a 20 20 20 20  xecsql $sql.    
8090: 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73    uplevel do_tes
80a0: 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e 20  t ${prefix}.$tn 
80b0: 5b 6c 69 73 74 20 24 74 63 6c 71 75 65 72 79 5d  [list $tclquery]
80c0: 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d   [list [list {*}
80d0: 24 72 65 73 5d 5d 0a 20 20 20 20 7d 20 65 6c 73  $res]].    } els
80e0: 65 69 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c 79 7d  eif {$countonly}
80f0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6e 52 6f   {.      set nRo
8100: 77 20 30 0a 20 20 20 20 20 20 64 62 20 65 76 61  w 0.      db eva
8110: 6c 20 24 73 71 6c 20 7b 69 6e 63 72 20 6e 52 6f  l $sql {incr nRo
8120: 77 7d 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c  w}.      uplevel
8130: 20 64 6f 5f 74 65 73 74 20 24 7b 70 72 65 66 69   do_test ${prefi
8140: 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20 5b 6c 69  x}.$tn [list [li
8150: 73 74 20 73 65 74 20 7b 7d 20 24 6e 52 6f 77 5d  st set {} $nRow]
8160: 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20  ] [list $res].  
8170: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 65 72 72    } elseif {$err
8180: 66 6d 74 3d 3d 22 22 7d 20 7b 0a 20 20 20 20 20  fmt==""} {.     
8190: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63   uplevel do_exec
81a0: 73 71 6c 5f 74 65 73 74 20 24 7b 70 72 65 66 69  sql_test ${prefi
81b0: 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69 73 74 20 24  x}.${tn} [list $
81c0: 73 71 6c 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74  sql] [list [list
81d0: 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20 20 20 20 7d   {*}$res]].    }
81e0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65   else {.      se
81f0: 74 20 72 65 73 20 5b 6c 69 73 74 20 31 20 5b 73  t res [list 1 [s
8200: 74 72 69 6e 67 20 74 72 69 6d 20 5b 66 6f 72 6d  tring trim [form
8210: 61 74 20 24 65 72 72 66 6d 74 20 7b 2a 7d 24 72  at $errfmt {*}$r
8220: 65 73 5d 5d 5d 0a 20 20 20 20 20 20 75 70 6c 65  es]]].      uple
8230: 76 65 6c 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f  vel do_catchsql_
8240: 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24  test ${prefix}.$
8250: 7b 74 6e 7d 20 5b 6c 69 73 74 20 24 73 71 6c 5d  {tn} [list $sql]
8260: 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20 20   [list $res].   
8270: 20 7d 0a 20 20 20 20 65 76 61 6c 20 24 72 65 70   }.    eval $rep
8280: 61 69 72 0a 20 20 7d 0a 0a 7d 0a 0a 70 72 6f 63  air.  }..}..proc
8290: 20 64 65 6c 65 74 65 5f 61 6c 6c 5f 64 61 74 61   delete_all_data
82a0: 20 7b 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20   {} {.  db eval 
82b0: 7b 53 45 4c 45 43 54 20 74 62 6c 5f 6e 61 6d 65  {SELECT tbl_name
82c0: 20 41 53 20 74 20 46 52 4f 4d 20 73 71 6c 69 74   AS t FROM sqlit
82d0: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  e_master WHERE t
82e0: 79 70 65 20 3d 20 27 74 61 62 6c 65 27 7d 20 7b  ype = 'table'} {
82f0: 0a 20 20 20 20 64 62 20 65 76 61 6c 20 22 44 45  .    db eval "DE
8300: 4c 45 54 45 20 46 52 4f 4d 20 27 5b 73 74 72 69  LETE FROM '[stri
8310: 6e 67 20 6d 61 70 20 7b 27 20 27 27 7d 20 24 74  ng map {' ''} $t
8320: 5d 27 22 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75 6e  ]'".  }.}..# Run
8330: 20 61 6e 20 53 51 4c 20 73 63 72 69 70 74 2e 0a   an SQL script..
8340: 23 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d  # Return the num
8350: 62 65 72 20 6f 66 20 6d 69 63 72 6f 73 65 63 6f  ber of microseco
8360: 6e 64 73 20 70 65 72 20 73 74 61 74 65 6d 65 6e  nds per statemen
8370: 74 2e 0a 23 0a 70 72 6f 63 20 73 70 65 65 64 5f  t..#.proc speed_
8380: 74 72 69 61 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73  trial {name nums
8390: 74 6d 74 20 75 6e 69 74 73 20 73 71 6c 7d 20 7b  tmt units sql} {
83a0: 0a 20 20 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65  .  output2 -none
83b0: 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25  wline [format {%
83c0: 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e  -21.21s } $name.
83d0: 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73 74 64 6f  ..].  flush stdo
83e0: 75 74 0a 20 20 73 65 74 20 73 70 65 65 64 20 5b  ut.  set speed [
83f0: 74 69 6d 65 20 7b 73 71 6c 69 74 65 33 5f 65 78  time {sqlite3_ex
8400: 65 63 5f 6e 72 20 64 62 20 24 73 71 6c 7d 5d 0a  ec_nr db $sql}].
8410: 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78    set tm [lindex
8420: 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69 66 20   $speed 0].  if 
8430: 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20  {$tm == 0} {.   
8440: 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61   set rate [forma
8450: 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20  t %20s "many"]. 
8460: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
8470: 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25  t rate [format %
8480: 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31 30 30  20.5f [expr {100
8490: 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f  0000.0*$numstmt/
84a0: 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74  $tm}]].  }.  set
84b0: 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20 6f   u2 $units/s.  o
84c0: 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b  utput2 [format {
84d0: 25 31 32 64 20 75 53 20 25 73 20 25 73 7d 20 24  %12d uS %s %s} $
84e0: 74 6d 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20  tm $rate $u2].  
84f0: 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d  global total_tim
8500: 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69  e.  set total_ti
8510: 6d 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c  me [expr {$total
8520: 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61  _time+$tm}].  la
8530: 70 70 65 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72  ppend ::speed_tr
8540: 69 61 6c 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20  ial_times $name 
8550: 24 74 6d 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64  $tm.}.proc speed
8560: 5f 74 72 69 61 6c 5f 74 63 6c 20 7b 6e 61 6d 65  _trial_tcl {name
8570: 20 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73   numstmt units s
8580: 63 72 69 70 74 7d 20 7b 0a 20 20 6f 75 74 70 75  cript} {.  outpu
8590: 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66  t2 -nonewline [f
85a0: 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20  ormat {%-21.21s 
85b0: 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c  } $name...].  fl
85c0: 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74  ush stdout.  set
85d0: 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 65 76   speed [time {ev
85e0: 61 6c 20 24 73 63 72 69 70 74 7d 5d 0a 20 20 73  al $script}].  s
85f0: 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24 73  et tm [lindex $s
8600: 70 65 65 64 20 30 5d 0a 20 20 69 66 20 7b 24 74  peed 0].  if {$t
8610: 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20 20 73 65  m == 0} {.    se
8620: 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25  t rate [format %
8630: 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20 20 7d 20  20s "many"].  } 
8640: 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 72  else {.    set r
8650: 61 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 2e  ate [format %20.
8660: 35 66 20 5b 65 78 70 72 20 7b 31 30 30 30 30 30  5f [expr {100000
8670: 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f 24 74 6d  0.0*$numstmt/$tm
8680: 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74 20 75 32  }]].  }.  set u2
8690: 20 24 75 6e 69 74 73 2f 73 0a 20 20 6f 75 74 70   $units/s.  outp
86a0: 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32  ut2 [format {%12
86b0: 64 20 75 53 20 25 73 20 25 73 7d 20 24 74 6d 20  d uS %s %s} $tm 
86c0: 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f  $rate $u2].  glo
86d0: 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20  bal total_time. 
86e0: 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20   set total_time 
86f0: 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69  [expr {$total_ti
8700: 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70 70 65  me+$tm}].  lappe
8710: 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  nd ::speed_trial
8720: 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20 24 74 6d  _times $name $tm
8730: 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72  .}.proc speed_tr
8740: 69 61 6c 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20  ial_init {name} 
8750: 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  {.  global total
8760: 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61  _time.  set tota
8770: 6c 5f 74 69 6d 65 20 30 0a 20 20 73 65 74 20 3a  l_time 0.  set :
8780: 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d  :speed_trial_tim
8790: 65 73 20 5b 6c 69 73 74 5d 0a 20 20 73 71 6c 69  es [list].  sqli
87a0: 74 65 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f  te3 versdb :memo
87b0: 72 79 3a 0a 20 20 73 65 74 20 76 65 72 73 20 5b  ry:.  set vers [
87c0: 76 65 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45  versdb one {SELE
87d0: 43 54 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65  CT sqlite_source
87e0: 5f 69 64 28 29 7d 5d 0a 20 20 76 65 72 73 64 62  _id()}].  versdb
87f0: 20 63 6c 6f 73 65 0a 20 20 6f 75 74 70 75 74 32   close.  output2
8800: 20 22 53 51 4c 69 74 65 20 24 76 65 72 73 22 0a   "SQLite $vers".
8810: 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69  }.proc speed_tri
8820: 61 6c 5f 73 75 6d 6d 61 72 79 20 7b 6e 61 6d 65  al_summary {name
8830: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74  } {.  global tot
8840: 61 6c 5f 74 69 6d 65 0a 20 20 6f 75 74 70 75 74  al_time.  output
8850: 32 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e  2 [format {%-21.
8860: 32 31 73 20 25 31 32 64 20 75 53 20 54 4f 54 41  21s %12d uS TOTA
8870: 4c 7d 20 24 6e 61 6d 65 20 24 74 6f 74 61 6c 5f  L} $name $total_
8880: 74 69 6d 65 5d 0a 0a 20 20 69 66 20 7b 20 30 20  time]..  if { 0 
8890: 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 20  } {.    sqlite3 
88a0: 76 65 72 73 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a  versdb :memory:.
88b0: 20 20 20 20 73 65 74 20 76 65 72 73 20 5b 6c 69      set vers [li
88c0: 6e 64 65 78 20 5b 76 65 72 73 64 62 20 6f 6e 65  ndex [versdb one
88d0: 20 7b 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f   {SELECT sqlite_
88e0: 73 6f 75 72 63 65 5f 69 64 28 29 7d 5d 20 30 5d  source_id()}] 0]
88f0: 0a 20 20 20 20 76 65 72 73 64 62 20 63 6c 6f 73  .    versdb clos
8900: 65 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 43  e.    output2 "C
8910: 52 45 41 54 45 20 54 41 42 4c 45 20 49 46 20 4e  REATE TABLE IF N
8920: 4f 54 20 45 58 49 53 54 53 20 74 69 6d 65 28 76  OT EXISTS time(v
8930: 65 72 73 69 6f 6e 2c 20 73 63 72 69 70 74 2c 20  ersion, script, 
8940: 74 65 73 74 2c 20 75 73 29 3b 22 0a 20 20 20 20  test, us);".    
8950: 66 6f 72 65 61 63 68 20 7b 74 65 73 74 20 75 73  foreach {test us
8960: 7d 20 24 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  } $::speed_trial
8970: 5f 74 69 6d 65 73 20 7b 0a 20 20 20 20 20 20 6f  _times {.      o
8980: 75 74 70 75 74 32 20 22 49 4e 53 45 52 54 20 49  utput2 "INSERT I
8990: 4e 54 4f 20 74 69 6d 65 20 56 41 4c 55 45 53 28  NTO time VALUES(
89a0: 27 24 76 65 72 73 27 2c 20 27 24 6e 61 6d 65 27  '$vers', '$name'
89b0: 2c 20 27 24 74 65 73 74 27 2c 20 24 75 73 29 3b  , '$test', $us);
89c0: 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 23  ".    }.  }.}..#
89d0: 20 52 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e   Run this routin
89e0: 65 20 6c 61 73 74 0a 23 0a 70 72 6f 63 20 66 69  e last.#.proc fi
89f0: 6e 69 73 68 5f 74 65 73 74 20 7b 7d 20 7b 0a 20  nish_test {} {. 
8a00: 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65   catch {db close
8a10: 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 31 20 63  }.  catch {db1 c
8a20: 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64  lose}.  catch {d
8a30: 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  b2 close}.  catc
8a40: 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 20 20  h {db3 close}.  
8a50: 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69  if {0==[info exi
8a60: 73 74 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 20  sts ::SLAVE]} { 
8a70: 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67  finalize_testing
8a80: 20 7d 0a 7d 0a 70 72 6f 63 20 66 69 6e 61 6c 69   }.}.proc finali
8a90: 7a 65 5f 74 65 73 74 69 6e 67 20 7b 7d 20 7b 0a  ze_testing {} {.
8aa0: 20 20 67 6c 6f 62 61 6c 20 73 71 6c 69 74 65 5f    global sqlite_
8ab0: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a  open_file_count.
8ac0: 0a 20 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20  .  set omitList 
8ad0: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
8ae0: 72 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 0a 20 20  r omit_list]..  
8af0: 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d  catch {db close}
8b00: 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c  .  catch {db2 cl
8b10: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
8b20: 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 76 66 73 5f  3 close}..  vfs_
8b30: 75 6e 6c 69 6e 6b 5f 74 65 73 74 0a 20 20 73 71  unlink_test.  sq
8b40: 6c 69 74 65 33 20 64 62 20 7b 7d 0a 20 20 23 20  lite3 db {}.  # 
8b50: 73 71 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74 73  sqlite3_clear_ts
8b60: 64 5f 6d 65 6d 64 65 62 75 67 0a 20 20 64 62 20  d_memdebug.  db 
8b70: 63 6c 6f 73 65 0a 20 20 73 71 6c 69 74 65 33 5f  close.  sqlite3_
8b80: 72 65 73 65 74 5f 61 75 74 6f 5f 65 78 74 65 6e  reset_auto_exten
8b90: 73 69 6f 6e 0a 0a 20 20 73 71 6c 69 74 65 33 5f  sion..  sqlite3_
8ba0: 73 6f 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20  soft_heap_limit 
8bb0: 30 0a 20 20 73 65 74 20 6e 54 65 73 74 20 5b 69  0.  set nTest [i
8bc0: 6e 63 72 5f 6e 74 65 73 74 5d 0a 20 20 73 65 74  ncr_ntest].  set
8bd0: 20 6e 45 72 72 20 5b 73 65 74 5f 74 65 73 74 5f   nErr [set_test_
8be0: 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a  counter errors].
8bf0: 0a 20 20 73 65 74 20 6e 4b 6e 6f 77 6e 20 30 0a  .  set nKnown 0.
8c00: 20 20 69 66 20 7b 5b 66 69 6c 65 20 72 65 61 64    if {[file read
8c10: 61 62 6c 65 20 6b 6e 6f 77 6e 2d 70 72 6f 62 6c  able known-probl
8c20: 65 6d 73 2e 74 78 74 5d 7d 20 7b 0a 20 20 20 20  ems.txt]} {.    
8c30: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 6b 6e 6f  set fd [open kno
8c40: 77 6e 2d 70 72 6f 62 6c 65 6d 73 2e 74 78 74 5d  wn-problems.txt]
8c50: 0a 20 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74  .    set content
8c60: 20 5b 72 65 61 64 20 24 66 64 5d 0a 20 20 20 20   [read $fd].    
8c70: 63 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 66 6f  close $fd.    fo
8c80: 72 65 61 63 68 20 78 20 24 63 6f 6e 74 65 6e 74  reach x $content
8c90: 20 7b 73 65 74 20 6b 6e 6f 77 6e 5f 65 72 72 6f   {set known_erro
8ca0: 72 28 24 78 29 20 31 7d 0a 20 20 20 20 66 6f 72  r($x) 1}.    for
8cb0: 65 61 63 68 20 78 20 5b 73 65 74 5f 74 65 73 74  each x [set_test
8cc0: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
8cd0: 73 74 5d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b  st] {.      if {
8ce0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 6b 6e 6f  [info exists kno
8cf0: 77 6e 5f 65 72 72 6f 72 28 24 78 29 5d 7d 20 7b  wn_error($x)]} {
8d00: 69 6e 63 72 20 6e 4b 6e 6f 77 6e 7d 0a 20 20 20  incr nKnown}.   
8d10: 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 4b   }.  }.  if {$nK
8d20: 6e 6f 77 6e 3e 30 7d 20 7b 0a 20 20 20 20 6f 75  nown>0} {.    ou
8d30: 74 70 75 74 32 20 22 5b 65 78 70 72 20 7b 24 6e  tput2 "[expr {$n
8d40: 45 72 72 2d 24 6e 4b 6e 6f 77 6e 7d 5d 20 6e 65  Err-$nKnown}] ne
8d50: 77 20 65 72 72 6f 72 73 20 61 6e 64 20 24 6e 4b  w errors and $nK
8d60: 6e 6f 77 6e 20 6b 6e 6f 77 6e 20 65 72 72 6f 72  nown known error
8d70: 73 5c 0a 20 20 20 20 20 20 20 20 20 6f 75 74 20  s\.         out 
8d80: 6f 66 20 24 6e 54 65 73 74 20 74 65 73 74 73 22  of $nTest tests"
8d90: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
8da0: 73 65 74 20 63 70 75 69 6e 66 6f 20 7b 7d 0a 20  set cpuinfo {}. 
8db0: 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 65     if {[catch {e
8dc0: 78 65 63 20 68 6f 73 74 6e 61 6d 65 7d 20 68 6e  xec hostname} hn
8dd0: 61 6d 65 5d 3d 3d 30 7d 20 7b 73 65 74 20 63 70  ame]==0} {set cp
8de0: 75 69 6e 66 6f 20 5b 73 74 72 69 6e 67 20 74 72  uinfo [string tr
8df0: 69 6d 20 24 68 6e 61 6d 65 5d 7d 0a 20 20 20 20  im $hname]}.    
8e00: 61 70 70 65 6e 64 20 63 70 75 69 6e 66 6f 20 22  append cpuinfo "
8e10: 20 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d   $::tcl_platform
8e20: 28 6f 73 29 22 0a 20 20 20 20 61 70 70 65 6e 64  (os)".    append
8e30: 20 63 70 75 69 6e 66 6f 20 22 20 5b 65 78 70 72   cpuinfo " [expr
8e40: 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72   {$::tcl_platfor
8e50: 6d 28 70 6f 69 6e 74 65 72 53 69 7a 65 29 2a 38  m(pointerSize)*8
8e60: 7d 5d 2d 62 69 74 22 0a 20 20 20 20 61 70 70 65  }]-bit".    appe
8e70: 6e 64 20 63 70 75 69 6e 66 6f 20 22 20 5b 73 74  nd cpuinfo " [st
8e80: 72 69 6e 67 20 6d 61 70 20 7b 45 20 2d 65 7d 20  ring map {E -e} 
8e90: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
8ea0: 62 79 74 65 4f 72 64 65 72 29 5d 22 0a 20 20 20  byteOrder)]".   
8eb0: 20 6f 75 74 70 75 74 32 20 22 53 51 4c 69 74 65   output2 "SQLite
8ec0: 20 5b 73 71 6c 69 74 65 33 20 2d 73 6f 75 72 63   [sqlite3 -sourc
8ed0: 65 69 64 5d 22 0a 20 20 20 20 6f 75 74 70 75 74  eid]".    output
8ee0: 32 20 22 24 6e 45 72 72 20 65 72 72 6f 72 73 20  2 "$nErr errors 
8ef0: 6f 75 74 20 6f 66 20 24 6e 54 65 73 74 20 74 65  out of $nTest te
8f00: 73 74 73 20 6f 6e 20 24 63 70 75 69 6e 66 6f 22  sts on $cpuinfo"
8f10: 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72  .  }.  if {$nErr
8f20: 3e 24 6e 4b 6e 6f 77 6e 7d 20 7b 0a 20 20 20 20  >$nKnown} {.    
8f30: 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69  output2 -nonewli
8f40: 6e 65 20 22 21 46 61 69 6c 75 72 65 73 20 6f 6e  ne "!Failures on
8f50: 20 74 68 65 73 65 20 74 65 73 74 73 3a 22 0a 20   these tests:". 
8f60: 20 20 20 66 6f 72 65 61 63 68 20 78 20 5b 73 65     foreach x [se
8f70: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66  t_test_counter f
8f80: 61 69 6c 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20  ail_list] {.    
8f90: 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69    if {![info exi
8fa0: 73 74 73 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28  sts known_error(
8fb0: 24 78 29 5d 7d 20 7b 6f 75 74 70 75 74 32 20 2d  $x)]} {output2 -
8fc0: 6e 6f 6e 65 77 6c 69 6e 65 20 22 20 24 78 22 7d  nonewline " $x"}
8fd0: 0a 20 20 20 20 7d 0a 20 20 20 20 6f 75 74 70 75  .    }.    outpu
8fe0: 74 32 20 22 22 0a 20 20 7d 0a 20 20 66 6f 72 65  t2 "".  }.  fore
8ff0: 61 63 68 20 77 61 72 6e 69 6e 67 20 5b 73 65 74  ach warning [set
9000: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 77 61  _test_counter wa
9010: 72 6e 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20 6f  rn_list] {.    o
9020: 75 74 70 75 74 32 20 22 57 61 72 6e 69 6e 67 3a  utput2 "Warning:
9030: 20 24 77 61 72 6e 69 6e 67 22 0a 20 20 7d 0a 20   $warning".  }. 
9040: 20 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74   run_thread_test
9050: 73 20 31 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  s 1.  if {[lleng
9060: 74 68 20 24 6f 6d 69 74 4c 69 73 74 5d 3e 30 7d  th $omitList]>0}
9070: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22   {.    output2 "
9080: 4f 6d 69 74 74 65 64 20 74 65 73 74 20 63 61 73  Omitted test cas
9090: 65 73 3a 22 0a 20 20 20 20 73 65 74 20 70 72 65  es:".    set pre
90a0: 63 20 7b 7d 0a 20 20 20 20 66 6f 72 65 61 63 68  c {}.    foreach
90b0: 20 7b 72 65 63 7d 20 5b 6c 73 6f 72 74 20 24 6f   {rec} [lsort $o
90c0: 6d 69 74 4c 69 73 74 5d 20 7b 0a 20 20 20 20 20  mitList] {.     
90d0: 20 69 66 20 7b 24 72 65 63 3d 3d 24 70 72 65 63   if {$rec==$prec
90e0: 7d 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20  } continue.     
90f0: 20 73 65 74 20 70 72 65 63 20 24 72 65 63 0a 20   set prec $rec. 
9100: 20 20 20 20 20 6f 75 74 70 75 74 32 20 5b 66 6f       output2 [fo
9110: 72 6d 61 74 20 7b 2e 20 20 25 2d 31 32 73 20 25  rmat {.  %-12s %
9120: 73 7d 20 5b 6c 69 6e 64 65 78 20 24 72 65 63 20  s} [lindex $rec 
9130: 30 5d 20 5b 6c 69 6e 64 65 78 20 24 72 65 63 20  0] [lindex $rec 
9140: 31 5d 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  1]].    }.  }.  
9150: 69 66 20 7b 24 6e 45 72 72 3e 30 20 26 26 20 21  if {$nErr>0 && !
9160: 5b 77 6f 72 6b 69 6e 67 5f 36 34 62 69 74 5f 69  [working_64bit_i
9170: 6e 74 5d 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75  nt]} {.    outpu
9180: 74 32 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  t2 "************
9190: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
91a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
91b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
91c0: 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20 6f 75 74 70  ******".    outp
91d0: 75 74 32 20 22 4e 2e 42 2e 3a 20 20 54 68 65 20  ut2 "N.B.:  The 
91e0: 76 65 72 73 69 6f 6e 20 6f 66 20 54 43 4c 20 74  version of TCL t
91f0: 68 61 74 20 79 6f 75 20 75 73 65 64 20 74 6f 20  hat you used to 
9200: 62 75 69 6c 64 20 74 68 69 73 20 74 65 73 74 20  build this test 
9210: 68 61 72 6e 65 73 73 22 0a 20 20 20 20 6f 75 74  harness".    out
9220: 70 75 74 32 20 22 69 73 20 64 65 66 65 63 74 69  put2 "is defecti
9230: 76 65 20 69 6e 20 74 68 61 74 20 69 74 20 64 6f  ve in that it do
9240: 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 36  es not support 6
9250: 34 2d 62 69 74 20 69 6e 74 65 67 65 72 73 2e 20  4-bit integers. 
9260: 20 53 6f 6d 65 20 6f 72 22 0a 20 20 20 20 6f 75   Some or".    ou
9270: 74 70 75 74 32 20 22 61 6c 6c 20 6f 66 20 74 68  tput2 "all of th
9280: 65 20 74 65 73 74 20 66 61 69 6c 75 72 65 73 20  e test failures 
9290: 61 62 6f 76 65 20 6d 69 67 68 74 20 62 65 20 61  above might be a
92a0: 20 72 65 73 75 6c 74 20 66 72 6f 6d 20 74 68 69   result from thi
92b0: 73 20 64 65 66 65 63 74 22 0a 20 20 20 20 6f 75  s defect".    ou
92c0: 74 70 75 74 32 20 22 69 6e 20 79 6f 75 72 20 54  tput2 "in your T
92d0: 43 4c 20 62 75 69 6c 64 2e 22 0a 20 20 20 20 6f  CL build.".    o
92e0: 75 74 70 75 74 32 20 22 2a 2a 2a 2a 2a 2a 2a 2a  utput2 "********
92f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9300: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 7d 0a  **********".  }.
9330: 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65    if {$::cmdline
9340: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20  arg(binarylog)} 
9350: 7b 0a 20 20 20 20 76 66 73 6c 6f 67 20 66 69 6e  {.    vfslog fin
9360: 61 6c 69 7a 65 20 62 69 6e 61 72 79 6c 6f 67 0a  alize binarylog.
9370: 20 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c 69 74    }.  if {$sqlit
9380: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
9390: 74 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  t} {.    output2
93a0: 20 22 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66   "$sqlite_open_f
93b0: 69 6c 65 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20  ile_count files 
93c0: 77 65 72 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a  were left open".
93d0: 20 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20      incr nErr.  
93e0: 7d 0a 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20  }.  if {[lindex 
93f0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
9400: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41  SQLITE_STATUS_MA
9410: 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d  LLOC_COUNT 0] 1]
9420: 3e 30 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20  >0 ||.          
9430: 20 20 20 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d      [sqlite3_mem
9440: 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20  ory_used]>0} {. 
9450: 20 20 20 6f 75 74 70 75 74 32 20 22 55 6e 66 72     output2 "Unfr
9460: 65 65 64 20 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c  eed memory: [sql
9470: 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64  ite3_memory_used
9480: 5d 20 62 79 74 65 73 20 69 6e 5c 0a 20 20 20 20  ] bytes in\.    
9490: 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 5b 73 71       [lindex [sq
94a0: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
94b0: 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f  ITE_STATUS_MALLO
94c0: 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d 20 61 6c  C_COUNT 0] 1] al
94d0: 6c 6f 63 61 74 69 6f 6e 73 22 0a 20 20 20 20 69  locations".    i
94e0: 6e 63 72 20 6e 45 72 72 0a 20 20 20 20 69 66 63  ncr nErr.    ifc
94f0: 61 70 61 62 6c 65 20 6d 65 6d 35 7c 7c 28 6d 65  apable mem5||(me
9500: 6d 33 26 26 64 65 62 75 67 29 20 7b 0a 20 20 20  m3&&debug) {.   
9510: 20 20 20 6f 75 74 70 75 74 32 20 22 57 72 69 74     output2 "Writ
9520: 69 6e 67 20 75 6e 66 72 65 65 64 20 6d 65 6d 6f  ing unfreed memo
9530: 72 79 20 6c 6f 67 20 74 6f 20 5c 22 2e 2f 6d 65  ry log to \"./me
9540: 6d 6c 65 61 6b 2e 74 78 74 5c 22 22 0a 20 20 20  mleak.txt\"".   
9550: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
9560: 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 6c 65  bug_dump ./memle
9570: 61 6b 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d  ak.txt.    }.  }
9580: 20 65 6c 73 65 20 7b 0a 20 20 20 20 6f 75 74 70   else {.    outp
9590: 75 74 32 20 22 41 6c 6c 20 6d 65 6d 6f 72 79 20  ut2 "All memory 
95a0: 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 72 65 65  allocations free
95b0: 64 20 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a 20 20  d - no leaks".  
95c0: 20 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 35    ifcapable mem5
95d0: 20 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33   {.      sqlite3
95e0: 5f 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e  _memdebug_dump .
95f0: 2f 6d 65 6d 75 73 61 67 65 2e 74 78 74 0a 20 20  /memusage.txt.  
9600: 20 20 7d 0a 20 20 7d 0a 20 20 73 68 6f 77 5f 6d    }.  }.  show_m
9610: 65 6d 73 74 61 74 73 0a 20 20 6f 75 74 70 75 74  emstats.  output
9620: 32 20 22 4d 61 78 69 6d 75 6d 20 6d 65 6d 6f 72  2 "Maximum memor
9630: 79 20 75 73 61 67 65 3a 20 5b 73 71 6c 69 74 65  y usage: [sqlite
9640: 33 5f 6d 65 6d 6f 72 79 5f 68 69 67 68 77 61 74  3_memory_highwat
9650: 65 72 20 31 5d 20 62 79 74 65 73 22 0a 20 20 6f  er 1] bytes".  o
9660: 75 74 70 75 74 32 20 22 43 75 72 72 65 6e 74 20  utput2 "Current 
9670: 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a 20 5b 73  memory usage: [s
9680: 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 68 69  qlite3_memory_hi
9690: 67 68 77 61 74 65 72 5d 20 62 79 74 65 73 22 0a  ghwater] bytes".
96a0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 63 6f 6d 6d    if {[info comm
96b0: 61 6e 64 73 20 73 71 6c 69 74 65 33 5f 6d 65 6d  ands sqlite3_mem
96c0: 64 65 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75  debug_malloc_cou
96d0: 6e 74 5d 20 6e 65 20 22 22 7d 20 7b 0a 20 20 20  nt] ne ""} {.   
96e0: 20 6f 75 74 70 75 74 32 20 22 4e 75 6d 62 65 72   output2 "Number
96f0: 20 6f 66 20 6d 61 6c 6c 6f 63 28 29 20 20 3a 20   of malloc()  : 
9700: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75  [sqlite3_memdebu
9710: 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20  g_malloc_count] 
9720: 63 61 6c 6c 73 22 0a 20 20 7d 0a 20 20 69 66 20  calls".  }.  if 
9730: 7b 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 6d  {$::cmdlinearg(m
9740: 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20  alloctrace)} {. 
9750: 20 20 20 6f 75 74 70 75 74 32 20 22 57 72 69 74     output2 "Writ
9760: 69 6e 67 20 6d 61 6c 6c 6f 63 73 2e 74 63 6c 2e  ing mallocs.tcl.
9770: 2e 2e 22 0a 20 20 20 20 6d 65 6d 64 65 62 75 67  ..".    memdebug
9780: 5f 6c 6f 67 5f 73 71 6c 20 6d 61 6c 6c 6f 63 73  _log_sql mallocs
9790: 2e 74 63 6c 0a 20 20 20 20 73 71 6c 69 74 65 33  .tcl.    sqlite3
97a0: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74  _memdebug_log st
97b0: 6f 70 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  op.    sqlite3_m
97c0: 65 6d 64 65 62 75 67 5f 6c 6f 67 20 63 6c 65 61  emdebug_log clea
97d0: 72 0a 20 20 20 20 69 66 20 7b 5b 73 71 6c 69 74  r.    if {[sqlit
97e0: 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e  e3_memory_used]>
97f0: 30 7d 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75  0} {.      outpu
9800: 74 32 20 22 57 72 69 74 69 6e 67 20 6c 65 61 6b  t2 "Writing leak
9810: 73 2e 74 63 6c 2e 2e 2e 22 0a 20 20 20 20 20 20  s.tcl...".      
9820: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
9830: 5f 6c 6f 67 20 73 79 6e 63 0a 20 20 20 20 20 20  _log sync.      
9840: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c  memdebug_log_sql
9850: 20 6c 65 61 6b 73 2e 74 63 6c 0a 20 20 20 20 7d   leaks.tcl.    }
9860: 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f  .  }.  if {[info
9870: 20 63 6f 6d 6d 61 6e 64 73 20 76 64 62 65 5f 63   commands vdbe_c
9880: 6f 76 65 72 61 67 65 5d 21 3d 22 22 7d 20 7b 0a  overage]!=""} {.
9890: 20 20 20 20 76 64 62 65 5f 63 6f 76 65 72 61 67      vdbe_coverag
98a0: 65 5f 72 65 70 6f 72 74 0a 20 20 7d 0a 20 20 66  e_report.  }.  f
98b0: 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d  oreach f [glob -
98c0: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e  nocomplain test.
98d0: 64 62 2d 2a 2d 6a 6f 75 72 6e 61 6c 5d 20 7b 0a  db-*-journal] {.
98e0: 20 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20      forcedelete 
98f0: 24 66 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68  $f.  }.  foreach
9900: 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70   f [glob -nocomp
9910: 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d 6d 6a 2a  lain test.db-mj*
9920: 5d 20 7b 0a 20 20 20 20 66 6f 72 63 65 64 65 6c  ] {.    forcedel
9930: 65 74 65 20 24 66 0a 20 20 7d 0a 20 20 65 78 69  ete $f.  }.  exi
9940: 74 20 5b 65 78 70 72 20 7b 24 6e 45 72 72 3e 30  t [expr {$nErr>0
9950: 7d 5d 0a 7d 0a 0a 70 72 6f 63 20 76 64 62 65 5f  }].}..proc vdbe_
9960: 63 6f 76 65 72 61 67 65 5f 72 65 70 6f 72 74 20  coverage_report 
9970: 7b 7d 20 7b 0a 20 20 70 75 74 73 20 22 57 72 69  {} {.  puts "Wri
9980: 74 69 6e 67 20 76 64 62 65 20 63 6f 76 65 72 61  ting vdbe covera
9990: 67 65 20 72 65 70 6f 72 74 20 74 6f 20 76 64 62  ge report to vdb
99a0: 65 5f 63 6f 76 65 72 61 67 65 2e 74 78 74 22 0a  e_coverage.txt".
99b0: 20 20 73 65 74 20 6c 53 72 63 20 5b 6c 69 73 74    set lSrc [list
99c0: 5d 0a 20 20 73 65 74 20 69 4c 69 6e 65 20 30 0a  ].  set iLine 0.
99d0: 20 20 69 66 20 7b 5b 66 69 6c 65 20 65 78 69 73    if {[file exis
99e0: 74 73 20 2e 2e 2f 73 71 6c 69 74 65 33 2e 63 5d  ts ../sqlite3.c]
99f0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 64 20 5b  } {.    set fd [
9a00: 6f 70 65 6e 20 2e 2e 2f 73 71 6c 69 74 65 33 2e  open ../sqlite3.
9a10: 63 5d 0a 20 20 20 20 73 65 74 20 69 4c 69 6e 65  c].    set iLine
9a20: 0a 20 20 20 20 77 68 69 6c 65 20 7b 20 21 5b 65  .    while { ![e
9a30: 6f 66 20 24 66 64 5d 20 7d 20 7b 0a 20 20 20 20  of $fd] } {.    
9a40: 20 20 73 65 74 20 6c 69 6e 65 20 5b 67 65 74 73    set line [gets
9a50: 20 24 66 64 5d 0a 20 20 20 20 20 20 69 6e 63 72   $fd].      incr
9a60: 20 69 4c 69 6e 65 0a 20 20 20 20 20 20 69 66 20   iLine.      if 
9a70: 7b 5b 72 65 67 65 78 70 20 7b 5e 2f 5c 2a 2a 20  {[regexp {^/\** 
9a80: 42 65 67 69 6e 20 66 69 6c 65 20 28 2e 2a 5c 2e  Begin file (.*\.
9a90: 63 29 20 5c 2a 2a 2f 7d 20 24 6c 69 6e 65 20 2d  c) \**/} $line -
9aa0: 3e 20 66 69 6c 65 5d 7d 20 7b 0a 20 20 20 20 20  > file]} {.     
9ab0: 20 20 20 6c 61 70 70 65 6e 64 20 6c 53 72 63 20     lappend lSrc 
9ac0: 5b 6c 69 73 74 20 24 69 4c 69 6e 65 20 24 66 69  [list $iLine $fi
9ad0: 6c 65 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  le].      }.    
9ae0: 7d 0a 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a  }.    close $fd.
9af0: 20 20 7d 0a 20 20 73 65 74 20 66 64 20 5b 6f 70    }.  set fd [op
9b00: 65 6e 20 76 64 62 65 5f 63 6f 76 65 72 61 67 65  en vdbe_coverage
9b10: 2e 74 78 74 20 77 5d 0a 20 20 66 6f 72 65 61 63  .txt w].  foreac
9b20: 68 20 6d 69 73 73 20 5b 76 64 62 65 5f 63 6f 76  h miss [vdbe_cov
9b30: 65 72 61 67 65 20 72 65 70 6f 72 74 5d 20 7b 0a  erage report] {.
9b40: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 6c 69 6e      foreach {lin
9b50: 65 20 62 72 61 6e 63 68 20 6e 65 76 65 72 7d 20  e branch never} 
9b60: 24 6d 69 73 73 20 7b 7d 0a 20 20 20 20 73 65 74  $miss {}.    set
9b70: 20 6e 65 78 74 66 69 6c 65 20 22 22 0a 20 20 20   nextfile "".   
9b80: 20 77 68 69 6c 65 20 7b 5b 6c 6c 65 6e 67 74 68   while {[llength
9b90: 20 24 6c 53 72 63 5d 3e 30 20 26 26 20 5b 6c 69   $lSrc]>0 && [li
9ba0: 6e 64 65 78 20 24 6c 53 72 63 20 30 20 30 5d 20  ndex $lSrc 0 0] 
9bb0: 3c 20 24 6c 69 6e 65 7d 20 7b 0a 20 20 20 20 20  < $line} {.     
9bc0: 20 73 65 74 20 6e 65 78 74 66 69 6c 65 20 5b 6c   set nextfile [l
9bd0: 69 6e 64 65 78 20 24 6c 53 72 63 20 30 20 31 5d  index $lSrc 0 1]
9be0: 0a 20 20 20 20 20 20 73 65 74 20 6c 53 72 63 20  .      set lSrc 
9bf0: 5b 6c 72 61 6e 67 65 20 24 6c 53 72 63 20 31 20  [lrange $lSrc 1 
9c00: 65 6e 64 5d 0a 20 20 20 20 7d 0a 20 20 20 20 69  end].    }.    i
9c10: 66 20 7b 24 6e 65 78 74 66 69 6c 65 20 21 3d 20  f {$nextfile != 
9c20: 22 22 7d 20 7b 0a 20 20 20 20 20 20 70 75 74 73  ""} {.      puts
9c30: 20 24 66 64 20 22 22 0a 20 20 20 20 20 20 70 75   $fd "".      pu
9c40: 74 73 20 24 66 64 20 22 23 23 23 20 24 6e 65 78  ts $fd "### $nex
9c50: 74 66 69 6c 65 20 23 23 23 22 0a 20 20 20 20 7d  tfile ###".    }
9c60: 0a 20 20 20 20 70 75 74 73 20 24 66 64 20 22 56  .    puts $fd "V
9c70: 64 62 65 20 62 72 61 6e 63 68 20 24 6c 69 6e 65  dbe branch $line
9c80: 3a 20 6e 65 76 65 72 20 24 6e 65 76 65 72 20 28  : never $never (
9c90: 70 61 74 68 20 24 62 72 61 6e 63 68 29 22 0a 20  path $branch)". 
9ca0: 20 7d 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 7d   }.  close $fd.}
9cb0: 0a 0a 23 20 44 69 73 70 6c 61 79 20 6d 65 6d 6f  ..# Display memo
9cc0: 72 79 20 73 74 61 74 69 73 74 69 63 73 20 66 6f  ry statistics fo
9cd0: 72 20 61 6e 61 6c 79 73 69 73 20 61 6e 64 20 64  r analysis and d
9ce0: 65 62 75 67 67 69 6e 67 20 70 75 72 70 6f 73 65  ebugging purpose
9cf0: 73 2e 0a 23 0a 70 72 6f 63 20 73 68 6f 77 5f 6d  s..#.proc show_m
9d00: 65 6d 73 74 61 74 73 20 7b 7d 20 7b 0a 20 20 73  emstats {} {.  s
9d10: 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74  et x [sqlite3_st
9d20: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
9d30: 55 53 5f 4d 45 4d 4f 52 59 5f 55 53 45 44 20 30  US_MEMORY_USED 0
9d40: 5d 0a 20 20 73 65 74 20 79 20 5b 73 71 6c 69 74  ].  set y [sqlit
9d50: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
9d60: 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 53  _STATUS_MALLOC_S
9d70: 49 5a 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c  IZE 0].  set val
9d80: 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31   [format {now %1
9d90: 30 64 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61  0d  max %10d  ma
9da0: 78 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20  x-size %10d} \. 
9db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69               [li
9dc0: 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64  ndex $x 1] [lind
9dd0: 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78  ex $x 2] [lindex
9de0: 20 24 79 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74   $y 2]].  output
9df0: 31 20 22 4d 65 6d 6f 72 79 20 75 73 65 64 3a 20  1 "Memory used: 
9e00: 20 20 20 20 20 20 20 20 20 24 76 61 6c 22 0a 20           $val". 
9e10: 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f   set x [sqlite3_
9e20: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
9e30: 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e  ATUS_MALLOC_COUN
9e40: 54 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b  T 0].  set val [
9e50: 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64  format {now %10d
9e60: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
9e70: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
9e80: 78 20 24 78 20 32 5d 5d 0a 20 20 6f 75 74 70 75  x $x 2]].  outpu
9e90: 74 31 20 22 41 6c 6c 6f 63 61 74 69 6f 6e 20 63  t1 "Allocation c
9ea0: 6f 75 6e 74 3a 20 20 20 20 20 24 76 61 6c 22 0a  ount:     $val".
9eb0: 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33    set x [sqlite3
9ec0: 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53  _status SQLITE_S
9ed0: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
9ee0: 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20 79 20  USED 0].  set y 
9ef0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
9f00: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
9f10: 47 45 43 41 43 48 45 5f 53 49 5a 45 20 30 5d 0a  GECACHE_SIZE 0].
9f20: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
9f30: 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78  t {now %10d  max
9f40: 20 25 31 30 64 20 20 6d 61 78 2d 73 69 7a 65 20   %10d  max-size 
9f50: 25 31 30 64 7d 20 5c 0a 20 20 20 20 20 20 20 20  %10d} \.        
9f60: 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 78        [lindex $x
9f70: 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32   1] [lindex $x 2
9f80: 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d 5d  ] [lindex $y 2]]
9f90: 0a 20 20 6f 75 74 70 75 74 31 20 22 50 61 67 65  .  output1 "Page
9fa0: 2d 63 61 63 68 65 20 75 73 65 64 3a 20 20 20 20  -cache used:    
9fb0: 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20    $val".  set x 
9fc0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
9fd0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
9fe0: 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57  GECACHE_OVERFLOW
9ff0: 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66   0].  set val [f
a000: 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20  ormat {now %10d 
a010: 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e 64   max %10d} [lind
a020: 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78  ex $x 1] [lindex
a030: 20 24 78 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74   $x 2]].  output
a040: 31 20 22 50 61 67 65 2d 63 61 63 68 65 20 6f 76  1 "Page-cache ov
a050: 65 72 66 6c 6f 77 3a 20 20 24 76 61 6c 22 0a 20  erflow:  $val". 
a060: 20 69 66 63 61 70 61 62 6c 65 20 79 79 74 72 61   ifcapable yytra
a070: 63 6b 6d 61 78 73 74 61 63 6b 64 65 70 74 68 20  ckmaxstackdepth 
a080: 7b 0a 20 20 20 20 73 65 74 20 78 20 5b 73 71 6c  {.    set x [sql
a090: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
a0a0: 54 45 5f 53 54 41 54 55 53 5f 50 41 52 53 45 52  TE_STATUS_PARSER
a0b0: 5f 53 54 41 43 4b 20 30 5d 0a 20 20 20 20 73 65  _STACK 0].    se
a0c0: 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 20  t val [format { 
a0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 61                ma
a0e0: 78 20 25 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20  x %10d} [lindex 
a0f0: 24 78 20 32 5d 5d 0a 20 20 20 20 6f 75 74 70 75  $x 2]].    outpu
a100: 74 32 20 22 50 61 72 73 65 72 20 73 74 61 63 6b  t2 "Parser stack
a110: 20 64 65 70 74 68 3a 20 20 20 20 24 76 61 6c 22   depth:    $val"
a120: 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20 70 72 6f 63  .  }.}..# A proc
a130: 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74 65  edure to execute
a140: 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65 63   SQL.#.proc exec
a150: 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d  sql {sql {db db}
a160: 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51  } {.  # puts "SQ
a170: 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c 65  L = $sql".  uple
a180: 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76  vel [list $db ev
a190: 61 6c 20 24 73 71 6c 5d 0a 7d 0a 70 72 6f 63 20  al $sql].}.proc 
a1a0: 65 78 65 63 73 71 6c 5f 74 69 6d 65 64 20 7b 73  execsql_timed {s
a1b0: 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  ql {db db}} {.  
a1c0: 73 65 74 20 74 6d 20 5b 74 69 6d 65 20 7b 0a 20  set tm [time {. 
a1d0: 20 20 20 73 65 74 20 78 20 5b 75 70 6c 65 76 65     set x [upleve
a1e0: 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c  l [list $db eval
a1f0: 20 24 73 71 6c 5d 5d 0a 20 20 7d 20 31 5d 0a 20   $sql]].  } 1]. 
a200: 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20   set tm [lindex 
a210: 24 74 6d 20 30 5d 0a 20 20 6f 75 74 70 75 74 31  $tm 0].  output1
a220: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 20 28 5b   -nonewline " ([
a230: 65 78 70 72 20 7b 24 74 6d 2a 30 2e 30 30 31 7d  expr {$tm*0.001}
a240: 5d 6d 73 29 20 22 0a 20 20 73 65 74 20 78 0a 7d  ]ms) ".  set x.}
a250: 0a 0a 23 20 45 78 65 63 75 74 65 20 53 51 4c 20  ..# Execute SQL 
a260: 61 6e 64 20 63 61 74 63 68 20 65 78 63 65 70 74  and catch except
a270: 69 6f 6e 73 2e 0a 23 0a 70 72 6f 63 20 63 61 74  ions..#.proc cat
a280: 63 68 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64  chsql {sql {db d
a290: 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22  b}} {.  # puts "
a2a0: 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 73 65  SQL = $sql".  se
a2b0: 74 20 72 20 5b 63 61 74 63 68 20 5b 6c 69 73 74  t r [catch [list
a2c0: 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24   uplevel [list $
a2d0: 64 62 20 65 76 61 6c 20 24 73 71 6c 5d 5d 20 6d  db eval $sql]] m
a2e0: 73 67 5d 0a 20 20 6c 61 70 70 65 6e 64 20 72 20  sg].  lappend r 
a2f0: 24 6d 73 67 0a 20 20 72 65 74 75 72 6e 20 24 72  $msg.  return $r
a300: 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 56 44 42 45  .}..# Do an VDBE
a310: 20 63 6f 64 65 20 64 75 6d 70 20 6f 6e 20 74 68   code dump on th
a320: 65 20 53 51 4c 20 67 69 76 65 6e 0a 23 0a 70 72  e SQL given.#.pr
a330: 6f 63 20 65 78 70 6c 61 69 6e 20 7b 73 71 6c 20  oc explain {sql 
a340: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 6f 75 74  {db db}} {.  out
a350: 70 75 74 32 20 22 22 0a 20 20 6f 75 74 70 75 74  put2 "".  output
a360: 32 20 22 61 64 64 72 20 20 6f 70 63 6f 64 65 20  2 "addr  opcode 
a370: 20 20 20 20 20 20 20 70 31 20 20 20 20 20 20 70         p1      p
a380: 32 20 20 20 20 20 20 70 33 20 20 20 20 20 20 70  2      p3      p
a390: 34 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  4               
a3a0: 70 35 20 20 23 22 0a 20 20 6f 75 74 70 75 74 32  p5  #".  output2
a3b0: 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d   "----  --------
a3c0: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
a3d0: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
a3e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d  -------------  -
a3f0: 2d 20 20 2d 22 0a 20 20 24 64 62 20 65 76 61 6c  -  -".  $db eval
a400: 20 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20   "explain $sql" 
a410: 7b 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  {} {.    output2
a420: 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20   [format {%-4d  
a430: 25 2d 31 32 2e 31 32 73 20 20 25 2d 36 64 20 20  %-12.12s  %-6d  
a440: 25 2d 36 64 20 20 25 2d 36 64 20 20 25 20 2d 31  %-6d  %-6d  % -1
a450: 37 73 20 25 73 20 20 25 73 7d 20 5c 0a 20 20 20  7s %s  %s} \.   
a460: 20 20 20 24 61 64 64 72 20 24 6f 70 63 6f 64 65     $addr $opcode
a470: 20 24 70 31 20 24 70 32 20 24 70 33 20 24 70 34   $p1 $p2 $p3 $p4
a480: 20 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20   $p5 $comment.  
a490: 20 20 5d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20    ].  }.}..proc 
a4a0: 65 78 70 6c 61 69 6e 5f 69 20 7b 73 71 6c 20 7b  explain_i {sql {
a4b0: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 6f 75 74 70  db db}} {.  outp
a4c0: 75 74 32 20 22 22 0a 20 20 6f 75 74 70 75 74 32  ut2 "".  output2
a4d0: 20 22 61 64 64 72 20 20 6f 70 63 6f 64 65 20 20   "addr  opcode  
a4e0: 20 20 20 20 20 20 70 31 20 20 20 20 20 20 70 32        p1      p2
a4f0: 20 20 20 20 20 20 70 33 20 20 20 20 20 20 70 34        p3      p4
a500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a510: 70 35 20 20 23 22 0a 20 20 6f 75 74 70 75 74 32  p5  #".  output2
a520: 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d   "----  --------
a530: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
a540: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
a550: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20  --------------  
a560: 2d 2d 20 20 2d 22 0a 0a 0a 20 20 23 20 53 65 74  --  -"...  # Set
a570: 20 75 70 20 63 6f 6c 6f 72 73 20 66 6f 72 20 74   up colors for t
a580: 68 65 20 64 69 66 66 65 72 65 6e 74 20 6f 70 63  he different opc
a590: 6f 64 65 73 2e 20 53 63 68 65 6d 65 20 69 73 20  odes. Scheme is 
a5a0: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20 20 23 0a  as follows:.  #.
a5b0: 20 20 23 20 20 20 52 65 64 3a 20 20 20 4f 70 63    #   Red:   Opc
a5c0: 6f 64 65 73 20 74 68 61 74 20 77 72 69 74 65 20  odes that write 
a5d0: 74 6f 20 61 20 62 2d 74 72 65 65 2e 0a 20 20 23  to a b-tree..  #
a5e0: 20 20 20 42 6c 75 65 3a 20 20 4f 70 63 6f 64 65     Blue:  Opcode
a5f0: 73 20 74 68 61 74 20 72 65 70 6f 73 69 74 69 6f  s that repositio
a600: 6e 20 6f 72 20 73 65 65 6b 20 61 20 63 75 72 73  n or seek a curs
a610: 6f 72 2e 20 0a 20 20 23 20 20 20 47 72 65 65 6e  or. .  #   Green
a620: 3a 20 54 68 65 20 52 65 73 75 6c 74 52 6f 77 20  : The ResultRow 
a630: 6f 70 63 6f 64 65 2e 0a 20 20 23 0a 20 20 69 66  opcode..  #.  if
a640: 20 7b 20 5b 63 61 74 63 68 20 7b 66 63 6f 6e 66   { [catch {fconf
a650: 69 67 75 72 65 20 73 74 64 6f 75 74 20 2d 6d 6f  igure stdout -mo
a660: 64 65 7d 5d 3d 3d 30 20 7d 20 7b 0a 20 20 20 20  de}]==0 } {.    
a670: 73 65 74 20 52 20 22 5c 30 33 33 5c 5b 33 31 3b  set R "\033\[31;
a680: 31 6d 22 20 20 20 20 20 20 20 20 3b 23 20 52 65  1m"        ;# Re
a690: 64 20 66 67 0a 20 20 20 20 73 65 74 20 47 20 22  d fg.    set G "
a6a0: 5c 30 33 33 5c 5b 33 32 3b 31 6d 22 20 20 20 20  \033\[32;1m"    
a6b0: 20 20 20 20 3b 23 20 47 72 65 65 6e 20 66 67 0a      ;# Green fg.
a6c0: 20 20 20 20 73 65 74 20 42 20 22 5c 30 33 33 5c      set B "\033\
a6d0: 5b 33 34 3b 31 6d 22 20 20 20 20 20 20 20 20 3b  [34;1m"        ;
a6e0: 23 20 52 65 64 20 66 67 0a 20 20 20 20 73 65 74  # Red fg.    set
a6f0: 20 44 20 22 5c 30 33 33 5c 5b 33 39 3b 30 6d 22   D "\033\[39;0m"
a700: 20 20 20 20 20 20 20 20 3b 23 20 44 65 66 61 75          ;# Defau
a710: 6c 74 20 66 67 0a 20 20 7d 20 65 6c 73 65 20 7b  lt fg.  } else {
a720: 0a 20 20 20 20 73 65 74 20 52 20 22 22 0a 20 20  .    set R "".  
a730: 20 20 73 65 74 20 47 20 22 22 0a 20 20 20 20 73    set G "".    s
a740: 65 74 20 42 20 22 22 0a 20 20 20 20 73 65 74 20  et B "".    set 
a750: 44 20 22 22 0a 20 20 7d 0a 20 20 66 6f 72 65 61  D "".  }.  forea
a760: 63 68 20 6f 70 63 6f 64 65 20 7b 0a 20 20 20 20  ch opcode {.    
a770: 20 20 53 65 65 6b 20 53 65 65 6b 47 45 20 53 65    Seek SeekGE Se
a780: 65 6b 47 54 20 53 65 65 6b 4c 45 20 53 65 65 6b  ekGT SeekLE Seek
a790: 4c 54 20 4e 6f 74 46 6f 75 6e 64 20 4c 61 73 74  LT NotFound Last
a7a0: 20 52 65 77 69 6e 64 0a 20 20 20 20 20 20 4e 6f   Rewind.      No
a7b0: 43 6f 6e 66 6c 69 63 74 20 4e 65 78 74 20 50 72  Conflict Next Pr
a7c0: 65 76 20 56 4e 65 78 74 20 56 50 72 65 76 20 56  ev VNext VPrev V
a7d0: 46 69 6c 74 65 72 0a 20 20 20 20 20 20 53 6f 72  Filter.      Sor
a7e0: 74 65 72 53 6f 72 74 20 53 6f 72 74 65 72 4e 65  terSort SorterNe
a7f0: 78 74 20 4e 65 78 74 49 66 4f 70 65 6e 0a 20 20  xt NextIfOpen.  
a800: 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6c 6f  } {.    set colo
a810: 72 28 24 6f 70 63 6f 64 65 29 20 24 42 0a 20 20  r($opcode) $B.  
a820: 7d 0a 20 20 66 6f 72 65 61 63 68 20 6f 70 63 6f  }.  foreach opco
a830: 64 65 20 7b 52 65 73 75 6c 74 52 6f 77 7d 20 7b  de {ResultRow} {
a840: 0a 20 20 20 20 73 65 74 20 63 6f 6c 6f 72 28 24  .    set color($
a850: 6f 70 63 6f 64 65 29 20 24 47 0a 20 20 7d 0a 20  opcode) $G.  }. 
a860: 20 66 6f 72 65 61 63 68 20 6f 70 63 6f 64 65 20   foreach opcode 
a870: 7b 49 64 78 49 6e 73 65 72 74 20 49 6e 73 65 72  {IdxInsert Inser
a880: 74 20 44 65 6c 65 74 65 20 49 64 78 44 65 6c 65  t Delete IdxDele
a890: 74 65 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f  te} {.    set co
a8a0: 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 24 52 0a  lor($opcode) $R.
a8b0: 20 20 7d 0a 0a 20 20 73 65 74 20 62 53 65 65 6e    }..  set bSeen
a8c0: 47 6f 74 6f 20 30 0a 20 20 24 64 62 20 65 76 61  Goto 0.  $db eva
a8d0: 6c 20 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22  l "explain $sql"
a8e0: 20 7b 7d 20 7b 0a 20 20 20 20 73 65 74 20 78 28   {} {.    set x(
a8f0: 24 61 64 64 72 29 20 30 0a 20 20 20 20 73 65 74  $addr) 0.    set
a900: 20 6f 70 28 24 61 64 64 72 29 20 24 6f 70 63 6f   op($addr) $opco
a910: 64 65 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63  de..    if {$opc
a920: 6f 64 65 20 3d 3d 20 22 47 6f 74 6f 22 20 26 26  ode == "Goto" &&
a930: 20 28 24 62 53 65 65 6e 47 6f 74 6f 3d 3d 30 20   ($bSeenGoto==0 
a940: 7c 7c 20 28 24 70 32 20 3e 20 24 61 64 64 72 2b  || ($p2 > $addr+
a950: 31 30 29 29 7d 20 7b 0a 20 20 20 20 20 20 73 65  10))} {.      se
a960: 74 20 6c 69 6e 65 62 72 65 61 6b 28 24 70 32 29  t linebreak($p2)
a970: 20 31 0a 20 20 20 20 20 20 73 65 74 20 62 53 65   1.      set bSe
a980: 65 6e 47 6f 74 6f 20 31 0a 20 20 20 20 7d 0a 0a  enGoto 1.    }..
a990: 20 20 20 20 69 66 20 7b 24 6f 70 63 6f 64 65 3d      if {$opcode=
a9a0: 3d 22 4f 6e 63 65 22 7d 20 7b 0a 20 20 20 20 20  ="Once"} {.     
a9b0: 20 66 6f 72 20 7b 73 65 74 20 69 20 24 61 64 64   for {set i $add
a9c0: 72 7d 20 7b 24 69 3c 24 70 32 7d 20 7b 69 6e 63  r} {$i<$p2} {inc
a9d0: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  r i} {.        s
a9e0: 65 74 20 73 74 61 72 28 24 69 29 20 24 61 64 64  et star($i) $add
a9f0: 72 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  r.      }.    }.
aa00: 0a 20 20 20 20 69 66 20 7b 24 6f 70 63 6f 64 65  .    if {$opcode
aa10: 3d 3d 22 4e 65 78 74 22 20 20 7c 7c 20 24 6f 70  =="Next"  || $op
aa20: 63 6f 64 65 3d 3d 22 50 72 65 76 22 20 0a 20 20  code=="Prev" .  
aa30: 20 20 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22     || $opcode=="
aa40: 56 4e 65 78 74 22 20 7c 7c 20 24 6f 70 63 6f 64  VNext" || $opcod
aa50: 65 3d 3d 22 56 50 72 65 76 22 0a 20 20 20 20 20  e=="VPrev".     
aa60: 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22 53 6f 72  || $opcode=="Sor
aa70: 74 65 72 4e 65 78 74 22 20 7c 7c 20 24 6f 70 63  terNext" || $opc
aa80: 6f 64 65 3d 3d 22 4e 65 78 74 49 66 4f 70 65 6e  ode=="NextIfOpen
aa90: 22 0a 20 20 20 20 7d 20 7b 0a 20 20 20 20 20 20  ".    } {.      
aaa0: 66 6f 72 20 7b 73 65 74 20 69 20 24 70 32 7d 20  for {set i $p2} 
aab0: 7b 24 69 3c 24 61 64 64 72 7d 20 7b 69 6e 63 72  {$i<$addr} {incr
aac0: 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 69 6e   i} {.        in
aad0: 63 72 20 78 28 24 69 29 20 32 0a 20 20 20 20 20  cr x($i) 2.     
aae0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66   }.    }..    if
aaf0: 20 7b 24 6f 70 63 6f 64 65 20 3d 3d 20 22 47 6f   {$opcode == "Go
ab00: 74 6f 22 20 26 26 20 24 70 32 3c 24 61 64 64 72  to" && $p2<$addr
ab10: 20 26 26 20 24 6f 70 28 24 70 32 29 3d 3d 22 59   && $op($p2)=="Y
ab20: 69 65 6c 64 22 7d 20 7b 0a 20 20 20 20 20 20 66  ield"} {.      f
ab30: 6f 72 20 7b 73 65 74 20 69 20 5b 65 78 70 72 20  or {set i [expr 
ab40: 24 70 32 2b 31 5d 7d 20 7b 24 69 3c 24 61 64 64  $p2+1]} {$i<$add
ab50: 72 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  r} {incr i} {.  
ab60: 20 20 20 20 20 20 69 6e 63 72 20 78 28 24 69 29        incr x($i)
ab70: 20 32 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   2.      }.    }
ab80: 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63 6f 64  ..    if {$opcod
ab90: 65 20 3d 3d 20 22 48 61 6c 74 22 20 26 26 20 24  e == "Halt" && $
aba0: 63 6f 6d 6d 65 6e 74 20 3d 3d 20 22 45 6e 64 20  comment == "End 
abb0: 6f 66 20 63 6f 72 6f 75 74 69 6e 65 22 7d 20 7b  of coroutine"} {
abc0: 0a 20 20 20 20 20 20 73 65 74 20 6c 69 6e 65 62  .      set lineb
abd0: 72 65 61 6b 28 5b 65 78 70 72 20 24 61 64 64 72  reak([expr $addr
abe0: 2b 31 5d 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d  +1]) 1.    }.  }
abf0: 0a 0a 20 20 24 64 62 20 65 76 61 6c 20 22 65 78  ..  $db eval "ex
ac00: 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b 7d 20 7b  plain $sql" {} {
ac10: 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65  .    if {[info e
ac20: 78 69 73 74 73 20 6c 69 6e 65 62 72 65 61 6b 28  xists linebreak(
ac30: 24 61 64 64 72 29 5d 7d 20 7b 0a 20 20 20 20 20  $addr)]} {.     
ac40: 20 6f 75 74 70 75 74 32 20 22 22 0a 20 20 20 20   output2 "".    
ac50: 7d 0a 20 20 20 20 73 65 74 20 49 20 5b 73 74 72  }.    set I [str
ac60: 69 6e 67 20 72 65 70 65 61 74 20 22 20 22 20 24  ing repeat " " $
ac70: 78 28 24 61 64 64 72 29 5d 0a 0a 20 20 20 20 69  x($addr)]..    i
ac80: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
ac90: 73 74 61 72 28 24 61 64 64 72 29 5d 7d 20 7b 0a  star($addr)]} {.
aca0: 20 20 20 20 20 20 73 65 74 20 69 69 20 5b 65 78        set ii [ex
acb0: 70 72 20 24 78 28 24 73 74 61 72 28 24 61 64 64  pr $x($star($add
acc0: 72 29 29 5d 0a 20 20 20 20 20 20 61 70 70 65 6e  r))].      appen
acd0: 64 20 49 20 22 20 20 22 0a 20 20 20 20 20 20 73  d I "  ".      s
ace0: 65 74 20 49 20 5b 73 74 72 69 6e 67 20 72 65 70  et I [string rep
acf0: 6c 61 63 65 20 24 49 20 24 69 69 20 24 69 69 20  lace $I $ii $ii 
ad00: 2a 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 65  *].    }..    se
ad10: 74 20 63 6f 6c 20 22 22 0a 20 20 20 20 63 61 74  t col "".    cat
ad20: 63 68 20 7b 20 73 65 74 20 63 6f 6c 20 24 63 6f  ch { set col $co
ad30: 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 7d 0a 0a  lor($opcode) }..
ad40: 20 20 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72      output2 [for
ad50: 6d 61 74 20 7b 25 2d 34 64 20 20 25 73 25 73 25  mat {%-4d  %s%s%
ad60: 2d 31 32 2e 31 32 73 25 73 20 20 25 2d 36 64 20  -12.12s%s  %-6d 
ad70: 20 25 2d 36 64 20 20 25 2d 36 64 20 20 25 20 2d   %-6d  %-6d  % -
ad80: 31 37 73 20 25 73 20 20 25 73 7d 20 5c 0a 20 20  17s %s  %s} \.  
ad90: 20 20 20 20 24 61 64 64 72 20 24 49 20 24 63 6f      $addr $I $co
ada0: 6c 20 24 6f 70 63 6f 64 65 20 24 44 20 24 70 31  l $opcode $D $p1
adb0: 20 24 70 32 20 24 70 33 20 24 70 34 20 24 70 35   $p2 $p3 $p4 $p5
adc0: 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 5d 0a   $comment.    ].
add0: 20 20 7d 0a 20 20 6f 75 74 70 75 74 32 20 22 2d    }.  output2 "-
ade0: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ---  -----------
adf0: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
ae00: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
ae10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20  -----------  -- 
ae20: 20 2d 22 0a 7d 0a 0a 23 20 53 68 6f 77 20 74 68   -".}..# Show th
ae30: 65 20 56 44 42 45 20 70 72 6f 67 72 61 6d 20 66  e VDBE program f
ae40: 6f 72 20 61 6e 20 53 51 4c 20 73 74 61 74 65 6d  or an SQL statem
ae50: 65 6e 74 20 62 75 74 20 6f 6d 69 74 20 74 68 65  ent but omit the
ae60: 20 54 72 61 63 65 0a 23 20 6f 70 63 6f 64 65 20   Trace.# opcode 
ae70: 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67  at the beginning
ae80: 2e 20 20 54 68 69 73 20 70 72 6f 63 65 64 75 72  .  This procedur
ae90: 65 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f  e can be used to
aea0: 20 70 72 6f 76 65 0a 23 20 74 68 61 74 20 64 69   prove.# that di
aeb0: 66 66 65 72 65 6e 74 20 53 51 4c 20 73 74 61 74  fferent SQL stat
aec0: 65 6d 65 6e 74 73 20 67 65 6e 65 72 61 74 65 20  ements generate 
aed0: 65 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65  exactly the same
aee0: 20 56 44 42 45 20 63 6f 64 65 2e 0a 23 0a 70 72   VDBE code..#.pr
aef0: 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f 5f 74 72  oc explain_no_tr
af00: 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65  ace {sql} {.  se
af10: 74 20 74 72 20 5b 64 62 20 65 76 61 6c 20 22 45  t tr [db eval "E
af20: 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d 0a 20 20  XPLAIN $sql"].  
af30: 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67 65 20 24  return [lrange $
af40: 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a 23 20 41  tr 7 end].}..# A
af50: 6e 6f 74 68 65 72 20 70 72 6f 63 65 64 75 72 65  nother procedure
af60: 20 74 6f 20 65 78 65 63 75 74 65 20 53 51 4c 2e   to execute SQL.
af70: 20 20 54 68 69 73 20 6f 6e 65 20 69 6e 63 6c 75    This one inclu
af80: 64 65 73 20 74 68 65 20 66 69 65 6c 64 0a 23 20  des the field.# 
af90: 6e 61 6d 65 73 20 69 6e 20 74 68 65 20 72 65 74  names in the ret
afa0: 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23 0a 70 72  urned list..#.pr
afb0: 6f 63 20 65 78 65 63 73 71 6c 32 20 7b 73 71 6c  oc execsql2 {sql
afc0: 7d 20 7b 0a 20 20 73 65 74 20 72 65 73 75 6c 74  } {.  set result
afd0: 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c 20 24 73   {}.  db eval $s
afe0: 71 6c 20 64 61 74 61 20 7b 0a 20 20 20 20 66 6f  ql data {.    fo
aff0: 72 65 61 63 68 20 66 20 24 64 61 74 61 28 2a 29  reach f $data(*)
b000: 20 7b 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64   {.      lappend
b010: 20 72 65 73 75 6c 74 20 24 66 20 24 64 61 74 61   result $f $data
b020: 28 24 66 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  ($f).    }.  }. 
b030: 20 72 65 74 75 72 6e 20 24 72 65 73 75 6c 74 0a   return $result.
b040: 7d 0a 0a 23 20 55 73 65 20 61 20 74 65 6d 70 6f  }..# Use a tempo
b050: 72 61 72 79 20 69 6e 2d 6d 65 6d 6f 72 79 20 64  rary in-memory d
b060: 61 74 61 62 61 73 65 20 74 6f 20 65 78 65 63 75  atabase to execu
b070: 74 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  te SQL statement
b080: 73 0a 23 0a 70 72 6f 63 20 6d 65 6d 64 62 73 71  s.#.proc memdbsq
b090: 6c 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 71 6c 69  l {sql} {.  sqli
b0a0: 74 65 33 20 6d 65 6d 64 62 20 3a 6d 65 6d 6f 72  te3 memdb :memor
b0b0: 79 3a 0a 20 20 73 65 74 20 72 65 73 75 6c 74 20  y:.  set result 
b0c0: 5b 6d 65 6d 64 62 20 65 76 61 6c 20 24 73 71 6c  [memdb eval $sql
b0d0: 5d 0a 20 20 6d 65 6d 64 62 20 63 6c 6f 73 65 0a  ].  memdb close.
b0e0: 20 20 72 65 74 75 72 6e 20 24 72 65 73 75 6c 74    return $result
b0f0: 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65 20 6e 6f  .}..# Use the no
b100: 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49 20 74  n-callback API t
b110: 6f 20 65 78 65 63 75 74 65 20 6d 75 6c 74 69 70  o execute multip
b120: 6c 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  le SQL statement
b130: 73 0a 23 0a 70 72 6f 63 20 73 74 65 70 73 71 6c  s.#.proc stepsql
b140: 20 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b 0a 20   {dbptr sql} {. 
b150: 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69 6e 67   set sql [string
b160: 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20 73 65   trim $sql].  se
b170: 74 20 72 20 30 0a 20 20 77 68 69 6c 65 20 7b 5b  t r 0.  while {[
b180: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73  string length $s
b190: 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69 66 20  ql]>0} {.    if 
b1a0: 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33  {[catch {sqlite3
b1b0: 5f 70 72 65 70 61 72 65 20 24 64 62 70 74 72 20  _prepare $dbptr 
b1c0: 24 73 71 6c 20 2d 31 20 73 71 6c 74 61 69 6c 7d  $sql -1 sqltail}
b1d0: 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20 72 65   vm]} {.      re
b1e0: 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24 76 6d  turn [list 1 $vm
b1f0: 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20  ].    }.    set 
b200: 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72 69 6d  sql [string trim
b210: 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20 20 20   $sqltail].#    
b220: 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65 5f 73  while {[sqlite_s
b230: 74 65 70 20 24 76 6d 20 4e 20 56 41 4c 20 43 4f  tep $vm N VAL CO
b240: 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22  L]=="SQLITE_ROW"
b250: 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f 72 65 61  } {.#      forea
b260: 63 68 20 76 20 24 56 41 4c 20 7b 6c 61 70 70 65  ch v $VAL {lappe
b270: 6e 64 20 72 20 24 76 7d 0a 23 20 20 20 20 7d 0a  nd r $v}.#    }.
b280: 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69      while {[sqli
b290: 74 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d 3d 22  te3_step $vm]=="
b2a0: 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 20  SQLITE_ROW"} {. 
b2b0: 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20       for {set i 
b2c0: 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65 33 5f  0} {$i<[sqlite3_
b2d0: 64 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d 5d 7d  data_count $vm]}
b2e0: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
b2f0: 20 20 20 20 6c 61 70 70 65 6e 64 20 72 20 5b 73      lappend r [s
b300: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65  qlite3_column_te
b310: 78 74 20 24 76 6d 20 24 69 5d 0a 20 20 20 20 20  xt $vm $i].     
b320: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20   }.    }.    if 
b330: 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33  {[catch {sqlite3
b340: 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d 20 65  _finalize $vm} e
b350: 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20 20 20  rrmsg]} {.      
b360: 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24  return [list 1 $
b370: 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a 20 20  errmsg].    }.  
b380: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a  }.  return $r.}.
b390: 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67 72 69  .# Do an integri
b3a0: 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68 65 20  ty check of the 
b3b0: 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65 0a  entire database.
b3c0: 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69 74 79  #.proc integrity
b3d0: 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20 7b 64 62  _check {name {db
b3e0: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61   db}} {.  ifcapa
b3f0: 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20  ble integrityck 
b400: 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e  {.    do_test $n
b410: 61 6d 65 20 5b 6c 69 73 74 20 65 78 65 63 73 71  ame [list execsq
b420: 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72  l {PRAGMA integr
b430: 69 74 79 5f 63 68 65 63 6b 7d 20 24 64 62 5d 20  ity_check} $db] 
b440: 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 43 68  {ok}.  }.}..# Ch
b450: 65 63 6b 20 74 68 65 20 65 78 74 65 6e 64 65 64  eck the extended
b460: 20 65 72 72 6f 72 20 63 6f 64 65 0a 23 0a 70 72   error code.#.pr
b470: 6f 63 20 76 65 72 69 66 79 5f 65 78 5f 65 72 72  oc verify_ex_err
b480: 63 6f 64 65 20 7b 6e 61 6d 65 20 65 78 70 65 63  code {name expec
b490: 74 65 64 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20  ted {db db}} {. 
b4a0: 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b   do_test $name [
b4b0: 6c 69 73 74 20 73 71 6c 69 74 65 33 5f 65 78 74  list sqlite3_ext
b4c0: 65 6e 64 65 64 5f 65 72 72 63 6f 64 65 20 24 64  ended_errcode $d
b4d0: 62 5d 20 24 65 78 70 65 63 74 65 64 0a 7d 0a 0a  b] $expected.}..
b4e0: 0a 23 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  .# Return true i
b4f0: 66 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  f the SQL statem
b500: 65 6e 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ent passed as th
b510: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
b520: 74 20 75 73 65 73 20 61 0a 23 20 73 74 61 74 65  t uses a.# state
b530: 6d 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f 6e  ment transaction
b540: 2e 0a 23 0a 70 72 6f 63 20 73 71 6c 5f 75 73 65  ..#.proc sql_use
b550: 73 5f 73 74 6d 74 20 7b 64 62 20 73 71 6c 7d 20  s_stmt {db sql} 
b560: 7b 0a 20 20 73 65 74 20 73 74 6d 74 20 5b 73 71  {.  set stmt [sq
b570: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 20 24 64  lite3_prepare $d
b580: 62 20 24 73 71 6c 20 2d 31 20 64 75 6d 6d 79 5d  b $sql -1 dummy]
b590: 0a 20 20 73 65 74 20 75 73 65 73 20 5b 75 73 65  .  set uses [use
b5a0: 73 5f 73 74 6d 74 5f 6a 6f 75 72 6e 61 6c 20 24  s_stmt_journal $
b5b0: 73 74 6d 74 5d 0a 20 20 73 71 6c 69 74 65 33 5f  stmt].  sqlite3_
b5c0: 66 69 6e 61 6c 69 7a 65 20 24 73 74 6d 74 0a 20  finalize $stmt. 
b5d0: 20 72 65 74 75 72 6e 20 24 75 73 65 73 0a 7d 0a   return $uses.}.
b5e0: 0a 70 72 6f 63 20 66 69 78 5f 69 66 63 61 70 61  .proc fix_ifcapa
b5f0: 62 6c 65 5f 65 78 70 72 20 7b 65 78 70 72 7d 20  ble_expr {expr} 
b600: 7b 0a 20 20 73 65 74 20 72 65 74 20 22 22 0a 20  {.  set ret "". 
b610: 20 73 65 74 20 73 74 61 74 65 20 30 0a 20 20 66   set state 0.  f
b620: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
b630: 20 3c 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74   < [string lengt
b640: 68 20 24 65 78 70 72 5d 7d 20 7b 69 6e 63 72 20  h $expr]} {incr 
b650: 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 68 61  i} {.    set cha
b660: 72 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  r [string range 
b670: 24 65 78 70 72 20 24 69 20 24 69 5d 0a 20 20 20  $expr $i $i].   
b680: 20 73 65 74 20 6e 65 77 73 74 61 74 65 20 5b 65   set newstate [e
b690: 78 70 72 20 7b 5b 73 74 72 69 6e 67 20 69 73 20  xpr {[string is 
b6a0: 61 6c 6e 75 6d 20 24 63 68 61 72 5d 20 7c 7c 20  alnum $char] || 
b6b0: 24 63 68 61 72 20 65 71 20 22 5f 22 7d 5d 0a 20  $char eq "_"}]. 
b6c0: 20 20 20 69 66 20 7b 24 6e 65 77 73 74 61 74 65     if {$newstate
b6d0: 20 26 26 20 21 24 73 74 61 74 65 7d 20 7b 0a 20   && !$state} {. 
b6e0: 20 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20       append ret 
b6f0: 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f  {$::sqlite_optio
b700: 6e 73 28 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69  ns(}.    }.    i
b710: 66 20 7b 21 24 6e 65 77 73 74 61 74 65 20 26 26  f {!$newstate &&
b720: 20 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20   $state} {.     
b730: 20 61 70 70 65 6e 64 20 72 65 74 20 29 0a 20 20   append ret ).  
b740: 20 20 7d 0a 20 20 20 20 61 70 70 65 6e 64 20 72    }.    append r
b750: 65 74 20 24 63 68 61 72 0a 20 20 20 20 73 65 74  et $char.    set
b760: 20 73 74 61 74 65 20 24 6e 65 77 73 74 61 74 65   state $newstate
b770: 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73 74 61 74  .  }.  if {$stat
b780: 65 7d 20 7b 61 70 70 65 6e 64 20 72 65 74 20 29  e} {append ret )
b790: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 74 0a  }.  return $ret.
b7a0: 7d 0a 0a 23 20 52 65 74 75 72 6e 73 20 6e 6f 6e  }..# Returns non
b7b0: 2d 7a 65 72 6f 20 69 66 20 74 68 65 20 63 61 70  -zero if the cap
b7c0: 61 62 69 6c 69 74 69 65 73 20 61 72 65 20 70 72  abilities are pr
b7d0: 65 73 65 6e 74 3b 20 7a 65 72 6f 20 6f 74 68 65  esent; zero othe
b7e0: 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63 20 63 61  rwise..#.proc ca
b7f0: 70 61 62 6c 65 20 7b 65 78 70 72 7d 20 7b 0a 20  pable {expr} {. 
b800: 20 73 65 74 20 65 20 5b 66 69 78 5f 69 66 63 61   set e [fix_ifca
b810: 70 61 62 6c 65 5f 65 78 70 72 20 24 65 78 70 72  pable_expr $expr
b820: 5d 3b 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20  ]; return [expr 
b830: 28 24 65 29 5d 0a 7d 0a 0a 23 20 45 76 61 6c 75  ($e)].}..# Evalu
b840: 61 74 65 20 61 20 62 6f 6f 6c 65 61 6e 20 65 78  ate a boolean ex
b850: 70 72 65 73 73 69 6f 6e 20 6f 66 20 63 61 70 61  pression of capa
b860: 62 69 6c 69 74 69 65 73 2e 20 20 49 66 20 74 72  bilities.  If tr
b870: 75 65 2c 20 65 78 65 63 75 74 65 20 74 68 65 0a  ue, execute the.
b880: 23 20 63 6f 64 65 2e 20 20 4f 6d 69 74 20 74 68  # code.  Omit th
b890: 65 20 63 6f 64 65 20 69 66 20 66 61 6c 73 65 2e  e code if false.
b8a0: 0a 23 0a 70 72 6f 63 20 69 66 63 61 70 61 62 6c  .#.proc ifcapabl
b8b0: 65 20 7b 65 78 70 72 20 63 6f 64 65 20 7b 65 6c  e {expr code {el
b8c0: 73 65 20 22 22 7d 20 7b 65 6c 73 65 63 6f 64 65  se ""} {elsecode
b8d0: 20 22 22 7d 7d 20 7b 0a 20 20 23 72 65 67 73 75   ""}} {.  #regsu
b8e0: 62 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5f 30 2d 39  b -all {[a-z_0-9
b8f0: 5d 2b 7d 20 24 65 78 70 72 20 7b 24 3a 3a 73 71  ]+} $expr {$::sq
b900: 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 26 29 7d  lite_options(&)}
b910: 20 65 32 0a 20 20 73 65 74 20 65 32 20 5b 66 69   e2.  set e2 [fi
b920: 78 5f 69 66 63 61 70 61 62 6c 65 5f 65 78 70 72  x_ifcapable_expr
b930: 20 24 65 78 70 72 5d 0a 20 20 69 66 20 28 24 65   $expr].  if ($e
b940: 32 29 20 7b 0a 20 20 20 20 73 65 74 20 63 20 5b  2) {.    set c [
b950: 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 31  catch {uplevel 1
b960: 20 24 63 6f 64 65 7d 20 72 5d 0a 20 20 7d 20 65   $code} r].  } e
b970: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 63 20  lse {.    set c 
b980: 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20  [catch {uplevel 
b990: 31 20 24 65 6c 73 65 63 6f 64 65 7d 20 72 5d 0a  1 $elsecode} r].
b9a0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2d 63 6f    }.  return -co
b9b0: 64 65 20 24 63 20 24 72 0a 7d 0a 0a 23 20 54 68  de $c $r.}..# Th
b9c0: 69 73 20 70 72 6f 63 20 65 78 65 63 73 20 61 20  is proc execs a 
b9d0: 73 65 70 65 72 61 74 65 20 70 72 6f 63 65 73 73  seperate process
b9e0: 20 74 68 61 74 20 63 72 61 73 68 65 73 20 6d 69   that crashes mi
b9f0: 64 77 61 79 20 74 68 72 6f 75 67 68 20 65 78 65  dway through exe
ba00: 63 75 74 69 6e 67 0a 23 20 74 68 65 20 53 51 4c  cuting.# the SQL
ba10: 20 73 63 72 69 70 74 20 24 73 71 6c 20 6f 6e 20   script $sql on 
ba20: 64 61 74 61 62 61 73 65 20 74 65 73 74 2e 64 62  database test.db
ba30: 2e 0a 23 0a 23 20 54 68 65 20 63 72 61 73 68 20  ..#.# The crash 
ba40: 6f 63 63 75 72 73 20 64 75 72 69 6e 67 20 61 20  occurs during a 
ba50: 73 79 6e 63 28 29 20 6f 66 20 66 69 6c 65 20 24  sync() of file $
ba60: 63 72 61 73 68 66 69 6c 65 2e 20 57 68 65 6e 20  crashfile. When 
ba70: 74 68 65 20 63 72 61 73 68 0a 23 20 6f 63 63 75  the crash.# occu
ba80: 72 73 20 61 20 72 61 6e 64 6f 6d 20 73 75 62 73  rs a random subs
ba90: 65 74 20 6f 66 20 61 6c 6c 20 75 6e 73 79 6e 63  et of all unsync
baa0: 65 64 20 77 72 69 74 65 73 20 6d 61 64 65 20 62  ed writes made b
bab0: 79 20 74 68 65 20 70 72 6f 63 65 73 73 20 61 72  y the process ar
bac0: 65 0a 23 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  e.# written into
bad0: 20 74 68 65 20 66 69 6c 65 73 20 6f 6e 20 64 69   the files on di
bae0: 73 6b 2e 20 41 72 67 75 6d 65 6e 74 20 24 63 72  sk. Argument $cr
baf0: 61 73 68 64 65 6c 61 79 20 69 6e 64 69 63 61 74  ashdelay indicat
bb00: 65 73 20 74 68 65 0a 23 20 6e 75 6d 62 65 72 20  es the.# number 
bb10: 6f 66 20 66 69 6c 65 20 73 79 6e 63 73 20 74 6f  of file syncs to
bb20: 20 77 61 69 74 20 62 65 66 6f 72 65 20 63 72 61   wait before cra
bb30: 73 68 69 6e 67 2e 0a 23 0a 23 20 54 68 65 20 72  shing..#.# The r
bb40: 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 61  eturn value is a
bb50: 20 6c 69 73 74 20 6f 66 20 74 77 6f 20 65 6c 65   list of two ele
bb60: 6d 65 6e 74 73 2e 20 54 68 65 20 66 69 72 73 74  ments. The first
bb70: 20 65 6c 65 6d 65 6e 74 20 69 73 20 61 0a 23 20   element is a.# 
bb80: 62 6f 6f 6c 65 61 6e 2c 20 69 6e 64 69 63 61 74  boolean, indicat
bb90: 69 6e 67 20 77 68 65 74 68 65 72 20 6f 72 20 6e  ing whether or n
bba0: 6f 74 20 74 68 65 20 70 72 6f 63 65 73 73 20 61  ot the process a
bbb0: 63 74 75 61 6c 6c 79 20 63 72 61 73 68 65 64 20  ctually crashed 
bbc0: 6f 72 0a 23 20 72 65 70 6f 72 74 65 64 20 73 6f  or.# reported so
bbd0: 6d 65 20 6f 74 68 65 72 20 65 72 72 6f 72 2e 20  me other error. 
bbe0: 54 68 65 20 73 65 63 6f 6e 64 20 65 6c 65 6d 65  The second eleme
bbf0: 6e 74 20 69 6e 20 74 68 65 20 72 65 74 75 72 6e  nt in the return
bc00: 65 64 20 6c 69 73 74 20 69 73 20 74 68 65 0a 23  ed list is the.#
bc10: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e 20   error message. 
bc20: 54 68 69 73 20 69 73 20 22 63 68 69 6c 64 20 70  This is "child p
bc30: 72 6f 63 65 73 73 20 65 78 69 74 65 64 20 61 62  rocess exited ab
bc40: 6e 6f 72 6d 61 6c 6c 79 22 20 69 66 20 74 68 65  normally" if the
bc50: 20 63 72 61 73 68 0a 23 20 6f 63 63 75 72 72 65   crash.# occurre
bc60: 64 2e 0a 23 0a 23 20 20 20 63 72 61 73 68 73 71  d..#.#   crashsq
bc70: 6c 20 2d 64 65 6c 61 79 20 43 52 41 53 48 44 45  l -delay CRASHDE
bc80: 4c 41 59 20 2d 66 69 6c 65 20 43 52 41 53 48 46  LAY -file CRASHF
bc90: 49 4c 45 20 3f 2d 62 6c 6f 63 6b 73 69 7a 65 20  ILE ?-blocksize 
bca0: 42 4c 4f 43 4b 53 49 5a 45 3f 20 24 73 71 6c 0a  BLOCKSIZE? $sql.
bcb0: 23 0a 70 72 6f 63 20 63 72 61 73 68 73 71 6c 20  #.proc crashsql 
bcc0: 7b 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20  {args} {..  set 
bcd0: 62 6c 6f 63 6b 73 69 7a 65 20 22 22 0a 20 20 73  blocksize "".  s
bce0: 65 74 20 63 72 61 73 68 64 65 6c 61 79 20 31 0a  et crashdelay 1.
bcf0: 20 20 73 65 74 20 70 72 6e 67 73 65 65 64 20 30    set prngseed 0
bd00: 0a 20 20 73 65 74 20 6f 70 65 6e 64 62 20 7b 20  .  set opendb { 
bd10: 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e  sqlite3 db test.
bd20: 64 62 20 2d 76 66 73 20 63 72 61 73 68 20 7d 0a  db -vfs crash }.
bd30: 20 20 73 65 74 20 74 63 6c 62 6f 64 79 20 7b 7d    set tclbody {}
bd40: 0a 20 20 73 65 74 20 63 72 61 73 68 66 69 6c 65  .  set crashfile
bd50: 20 22 22 0a 20 20 73 65 74 20 64 63 20 22 22 0a   "".  set dc "".
bd60: 20 20 73 65 74 20 64 66 6c 74 76 66 73 20 30 0a    set dfltvfs 0.
bd70: 20 20 73 65 74 20 73 71 6c 20 5b 6c 69 6e 64 65    set sql [linde
bd80: 78 20 24 61 72 67 73 20 65 6e 64 5d 0a 0a 20 20  x $args end]..  
bd90: 66 6f 72 20 7b 73 65 74 20 69 69 20 30 7d 20 7b  for {set ii 0} {
bda0: 24 69 69 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24  $ii < [llength $
bdb0: 61 72 67 73 5d 2d 31 7d 20 7b 69 6e 63 72 20 69  args]-1} {incr i
bdc0: 69 20 32 7d 20 7b 0a 20 20 20 20 73 65 74 20 7a  i 2} {.    set z
bdd0: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 24   [lindex $args $
bde0: 69 69 5d 0a 20 20 20 20 73 65 74 20 6e 20 5b 73  ii].    set n [s
bdf0: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 7a 5d  tring length $z]
be00: 0a 20 20 20 20 73 65 74 20 7a 32 20 5b 6c 69 6e  .    set z2 [lin
be10: 64 65 78 20 24 61 72 67 73 20 5b 65 78 70 72 20  dex $args [expr 
be20: 24 69 69 2b 31 5d 5d 0a 0a 20 20 20 20 69 66 20  $ii+1]]..    if 
be30: 20 20 20 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74      {$n>1 && [st
be40: 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 64  ring first $z -d
be50: 65 6c 61 79 5d 3d 3d 30 7d 20 20 20 20 20 7b 73  elay]==0}     {s
be60: 65 74 20 63 72 61 73 68 64 65 6c 61 79 20 24 7a  et crashdelay $z
be70: 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20  2} \.    elseif 
be80: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
be90: 20 66 69 72 73 74 20 24 7a 20 2d 6f 70 65 6e 64   first $z -opend
bea0: 62 5d 3d 3d 30 7d 20 20 20 20 7b 73 65 74 20 6f  b]==0}    {set o
beb0: 70 65 6e 64 62 20 24 7a 32 7d 20 5c 0a 20 20 20  pendb $z2} \.   
bec0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
bed0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
bee0: 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20 20 20  z -seed]==0}    
bef0: 20 20 7b 73 65 74 20 70 72 6e 67 73 65 65 64 20    {set prngseed 
bf00: 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69  $z2} \.    elsei
bf10: 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69  f {$n>1 && [stri
bf20: 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66 69 6c  ng first $z -fil
bf30: 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65 74  e]==0}      {set
bf40: 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32 7d 20   crashfile $z2} 
bf50: 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24   \.    elseif {$
bf60: 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66  n>1 && [string f
bf70: 69 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f 64 79  irst $z -tclbody
bf80: 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74 63 6c  ]==0}   {set tcl
bf90: 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20 20 20  body $z2}  \.   
bfa0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
bfb0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
bfc0: 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30  z -blocksize]==0
bfd0: 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  } {set blocksize
bfe0: 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a 20 20   "-s $z2" } \.  
bff0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
c000: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
c010: 24 7a 20 2d 63 68 61 72 61 63 74 65 72 69 73 74  $z -characterist
c020: 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 63  ics]==0} {set dc
c030: 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 5c 0a 20   "-c {$z2}" }\. 
c040: 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20     elseif {$n>1 
c050: 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74  && [string first
c060: 20 24 7a 20 2d 64 66 6c 74 76 66 73 5d 3d 3d 30   $z -dfltvfs]==0
c070: 7d 20 7b 73 65 74 20 64 66 6c 74 76 66 73 20 24  } {set dfltvfs $
c080: 7a 32 20 7d 5c 0a 20 20 20 20 65 6c 73 65 20 20  z2 }\.    else  
c090: 20 7b 20 65 72 72 6f 72 20 22 55 6e 72 65 63 6f   { error "Unreco
c0a0: 67 6e 69 7a 65 64 20 6f 70 74 69 6f 6e 3a 20 24  gnized option: $
c0b0: 7a 22 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b  z" }.  }..  if {
c0c0: 24 63 72 61 73 68 66 69 6c 65 20 65 71 20 22 22  $crashfile eq ""
c0d0: 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 43  } {.    error "C
c0e0: 6f 6d 70 75 6c 73 6f 72 79 20 6f 70 74 69 6f 6e  ompulsory option
c0f0: 20 2d 66 69 6c 65 20 6d 69 73 73 69 6e 67 22 0a   -file missing".
c100: 20 20 7d 0a 0a 20 20 23 20 24 63 72 61 73 68 66    }..  # $crashf
c110: 69 6c 65 20 67 65 74 73 20 63 6f 6d 70 61 72 65  ile gets compare
c120: 64 20 74 6f 20 74 68 65 20 6e 61 74 69 76 65 20  d to the native 
c130: 66 69 6c 65 6e 61 6d 65 20 69 6e 0a 20 20 23 20  filename in.  # 
c140: 63 66 53 79 6e 63 28 29 2c 20 77 68 69 63 68 20  cfSync(), which 
c150: 63 61 6e 20 62 65 20 64 69 66 66 65 72 65 6e 74  can be different
c160: 20 74 68 65 6e 20 77 68 61 74 20 54 43 4c 20 75   then what TCL u
c170: 73 65 73 20 62 79 0a 20 20 23 20 64 65 66 61 75  ses by.  # defau
c180: 6c 74 2c 20 73 6f 20 68 65 72 65 20 77 65 20 66  lt, so here we f
c190: 6f 72 63 65 20 69 74 20 74 6f 20 74 68 65 20 22  orce it to the "
c1a0: 6e 61 74 69 76 65 6e 61 6d 65 22 20 66 6f 72 6d  nativename" form
c1b0: 61 74 2e 0a 20 20 73 65 74 20 63 66 69 6c 65 20  at..  set cfile 
c1c0: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 5c 5c 20  [string map {\\ 
c1d0: 5c 5c 5c 5c 7d 20 5b 66 69 6c 65 20 6e 61 74 69  \\\\} [file nati
c1e0: 76 65 6e 61 6d 65 20 5b 66 69 6c 65 20 6a 6f 69  vename [file joi
c1f0: 6e 20 5b 67 65 74 5f 70 77 64 5d 20 24 63 72 61  n [get_pwd] $cra
c200: 73 68 66 69 6c 65 5d 5d 5d 0a 0a 20 20 73 65 74  shfile]]]..  set
c210: 20 66 20 5b 6f 70 65 6e 20 63 72 61 73 68 2e 74   f [open crash.t
c220: 63 6c 20 77 5d 0a 20 20 70 75 74 73 20 24 66 20  cl w].  puts $f 
c230: 22 73 71 6c 69 74 65 33 5f 63 72 61 73 68 5f 65  "sqlite3_crash_e
c240: 6e 61 62 6c 65 20 31 20 24 64 66 6c 74 76 66 73  nable 1 $dfltvfs
c250: 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 71 6c  ".  puts $f "sql
c260: 69 74 65 33 5f 63 72 61 73 68 70 61 72 61 6d 73  ite3_crashparams
c270: 20 24 62 6c 6f 63 6b 73 69 7a 65 20 24 64 63 20   $blocksize $dc 
c280: 24 63 72 61 73 68 64 65 6c 61 79 20 24 63 66 69  $crashdelay $cfi
c290: 6c 65 22 0a 20 20 70 75 74 73 20 24 66 20 22 73  le".  puts $f "s
c2a0: 71 6c 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74  qlite3_test_cont
c2b0: 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65  rol_pending_byte
c2c0: 20 24 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69   $::sqlite_pendi
c2d0: 6e 67 5f 62 79 74 65 22 0a 0a 20 20 23 20 54 68  ng_byte"..  # Th
c2e0: 69 73 20 62 6c 6f 63 6b 20 73 65 74 73 20 74 68  is block sets th
c2f0: 65 20 63 61 63 68 65 20 73 69 7a 65 20 6f 66 20  e cache size of 
c300: 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
c310: 65 20 74 6f 20 31 30 0a 20 20 23 20 70 61 67 65  e to 10.  # page
c320: 73 2e 20 54 68 69 73 20 69 73 20 64 6f 6e 65 20  s. This is done 
c330: 69 6e 20 63 61 73 65 20 74 68 65 20 62 75 69 6c  in case the buil
c340: 64 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64 20  d is configured 
c350: 74 6f 20 6f 6d 69 74 0a 20 20 23 20 22 50 52 41  to omit.  # "PRA
c360: 47 4d 41 20 63 61 63 68 65 5f 73 69 7a 65 22 2e  GMA cache_size".
c370: 0a 20 20 69 66 20 7b 24 6f 70 65 6e 64 62 21 3d  .  if {$opendb!=
c380: 22 22 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24  ""} {.    puts $
c390: 66 20 24 6f 70 65 6e 64 62 20 0a 20 20 20 20 70  f $opendb .    p
c3a0: 75 74 73 20 24 66 20 7b 64 62 20 65 76 61 6c 20  uts $f {db eval 
c3b0: 7b 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73  {SELECT * FROM s
c3c0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a  qlite_master;}}.
c3d0: 20 20 20 20 70 75 74 73 20 24 66 20 7b 73 65 74      puts $f {set
c3e0: 20 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f   bt [btree_from_
c3f0: 64 62 20 64 62 5d 7d 0a 20 20 20 20 70 75 74 73  db db]}.    puts
c400: 20 24 66 20 7b 62 74 72 65 65 5f 73 65 74 5f 63   $f {btree_set_c
c410: 61 63 68 65 5f 73 69 7a 65 20 24 62 74 20 31 30  ache_size $bt 10
c420: 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24 70 72  }.  }..  if {$pr
c430: 6e 67 73 65 65 64 7d 20 7b 0a 20 20 20 20 73 65  ngseed} {.    se
c440: 74 20 73 65 65 64 20 5b 65 78 70 72 20 7b 24 70  t seed [expr {$p
c450: 72 6e 67 73 65 65 64 25 31 30 30 30 37 2b 31 7d  rngseed%10007+1}
c460: 5d 0a 20 20 20 20 23 20 70 75 74 73 20 73 65 65  ].    # puts see
c470: 64 3d 24 73 65 65 64 0a 20 20 20 20 70 75 74 73  d=$seed.    puts
c480: 20 24 66 20 22 64 62 20 65 76 61 6c 20 7b 53 45   $f "db eval {SE
c490: 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  LECT randomblob(
c4a0: 24 73 65 65 64 29 7d 22 0a 20 20 7d 0a 0a 20 20  $seed)}".  }..  
c4b0: 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67  if {[string leng
c4c0: 74 68 20 24 74 63 6c 62 6f 64 79 5d 3e 30 7d 20  th $tclbody]>0} 
c4d0: 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20 24 74  {.    puts $f $t
c4e0: 63 6c 62 6f 64 79 0a 20 20 7d 0a 20 20 69 66 20  clbody.  }.  if 
c4f0: 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  {[string length 
c500: 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 70  $sql]>0} {.    p
c510: 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c 20  uts $f "db eval 
c520: 7b 22 0a 20 20 20 20 70 75 74 73 20 24 66 20 20  {".    puts $f  
c530: 20 22 24 73 71 6c 22 0a 20 20 20 20 70 75 74 73   "$sql".    puts
c540: 20 24 66 20 22 7d 22 0a 20 20 7d 0a 20 20 63 6c   $f "}".  }.  cl
c550: 6f 73 65 20 24 66 0a 20 20 73 65 74 20 72 20 5b  ose $f.  set r [
c560: 63 61 74 63 68 20 7b 0a 20 20 20 20 65 78 65 63  catch {.    exec
c570: 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65   [info nameofexe
c580: 63 5d 20 63 72 61 73 68 2e 74 63 6c 20 3e 40 73  c] crash.tcl >@s
c590: 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67 5d 0a 0a  tdout.  } msg]..
c5a0: 20 20 23 20 57 69 6e 64 6f 77 73 2f 41 63 74 69    # Windows/Acti
c5b0: 76 65 53 74 61 74 65 20 54 43 4c 20 72 65 74 75  veState TCL retu
c5c0: 72 6e 73 20 61 20 73 6c 69 67 68 74 6c 79 20 64  rns a slightly d
c5d0: 69 66 66 65 72 65 6e 74 0a 20 20 23 20 65 72 72  ifferent.  # err
c5e0: 6f 72 20 6d 65 73 73 61 67 65 2e 20 20 57 65 20  or message.  We 
c5f0: 6d 61 70 20 74 68 61 74 20 74 6f 20 74 68 65 20  map that to the 
c600: 65 78 70 65 63 74 65 64 20 6d 65 73 73 61 67 65  expected message
c610: 0a 20 20 23 20 73 6f 20 74 68 61 74 20 77 65 20  .  # so that we 
c620: 64 6f 6e 27 74 20 68 61 76 65 20 74 6f 20 63 68  don't have to ch
c630: 61 6e 67 65 20 61 6c 6c 20 6f 66 20 74 68 65 20  ange all of the 
c640: 74 65 73 74 0a 20 20 23 20 63 61 73 65 73 2e 0a  test.  # cases..
c650: 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61    if {$::tcl_pla
c660: 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 3d  tform(platform)=
c670: 3d 22 77 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20  ="windows"} {.  
c680: 20 20 69 66 20 7b 24 6d 73 67 3d 3d 22 63 68 69    if {$msg=="chi
c690: 6c 64 20 6b 69 6c 6c 65 64 3a 20 75 6e 6b 6e 6f  ld killed: unkno
c6a0: 77 6e 20 73 69 67 6e 61 6c 22 7d 20 7b 0a 20 20  wn signal"} {.  
c6b0: 20 20 20 20 73 65 74 20 6d 73 67 20 22 63 68 69      set msg "chi
c6c0: 6c 64 20 70 72 6f 63 65 73 73 20 65 78 69 74 65  ld process exite
c6d0: 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 0a 20 20  d abnormally".  
c6e0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 6c 61 70 70 65    }.  }..  lappe
c6f0: 6e 64 20 72 20 24 6d 73 67 0a 7d 0a 0a 23 20 20  nd r $msg.}..#  
c700: 20 63 72 61 73 68 5f 6f 6e 5f 77 72 69 74 65 20   crash_on_write 
c710: 3f 2d 64 65 76 63 68 61 72 20 44 45 56 43 48 41  ?-devchar DEVCHA
c720: 52 3f 20 43 52 41 53 48 44 45 4c 41 59 20 53 51  R? CRASHDELAY SQ
c730: 4c 0a 23 0a 70 72 6f 63 20 63 72 61 73 68 5f 6f  L.#.proc crash_o
c740: 6e 5f 77 72 69 74 65 20 7b 61 72 67 73 7d 20 7b  n_write {args} {
c750: 0a 0a 20 20 73 65 74 20 6e 41 72 67 20 5b 6c 6c  ..  set nArg [ll
c760: 65 6e 67 74 68 20 24 61 72 67 73 5d 0a 20 20 69  ength $args].  i
c770: 66 20 7b 24 6e 41 72 67 3c 32 20 7c 7c 20 24 6e  f {$nArg<2 || $n
c780: 41 72 67 25 32 7d 20 7b 0a 20 20 20 20 65 72 72  Arg%2} {.    err
c790: 6f 72 20 22 62 61 64 20 61 72 67 73 3a 20 24 61  or "bad args: $a
c7a0: 72 67 73 22 0a 20 20 7d 0a 20 20 73 65 74 20 7a  rgs".  }.  set z
c7b0: 53 71 6c 20 5b 6c 69 6e 64 65 78 20 24 61 72 67  Sql [lindex $arg
c7c0: 73 20 65 6e 64 5d 0a 20 20 73 65 74 20 6e 44 65  s end].  set nDe
c7d0: 6c 61 79 20 5b 6c 69 6e 64 65 78 20 24 61 72 67  lay [lindex $arg
c7e0: 73 20 65 6e 64 2d 31 5d 0a 0a 20 20 73 65 74 20  s end-1]..  set 
c7f0: 64 65 76 63 68 61 72 20 7b 7d 0a 20 20 66 6f 72  devchar {}.  for
c800: 20 7b 73 65 74 20 69 69 20 30 7d 20 7b 24 69 69   {set ii 0} {$ii
c810: 20 3c 20 24 6e 41 72 67 2d 32 7d 20 7b 69 6e 63   < $nArg-2} {inc
c820: 72 20 69 69 20 32 7d 20 7b 0a 20 20 20 20 73 65  r ii 2} {.    se
c830: 74 20 6f 70 74 20 5b 6c 69 6e 64 65 78 20 24 61  t opt [lindex $a
c840: 72 67 73 20 24 69 69 5d 0a 20 20 20 20 73 77 69  rgs $ii].    swi
c850: 74 63 68 20 2d 2d 20 5b 6c 69 6e 64 65 78 20 24  tch -- [lindex $
c860: 61 72 67 73 20 24 69 69 5d 20 7b 0a 20 20 20 20  args $ii] {.    
c870: 20 20 2d 64 65 76 63 68 61 72 20 7b 0a 20 20 20    -devchar {.   
c880: 20 20 20 20 20 73 65 74 20 64 65 76 63 68 61 72       set devchar
c890: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 5b   [lindex $args [
c8a0: 65 78 70 72 20 24 69 69 2b 31 5d 5d 0a 20 20 20  expr $ii+1]].   
c8b0: 20 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61     }..      defa
c8c0: 75 6c 74 20 7b 20 65 72 72 6f 72 20 22 75 6e 72  ult { error "unr
c8d0: 65 63 6f 67 6e 69 7a 65 64 20 6f 70 74 69 6f 6e  ecognized option
c8e0: 3a 20 24 6f 70 74 22 20 7d 0a 20 20 20 20 7d 0a  : $opt" }.    }.
c8f0: 20 20 7d 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70    }..  set f [op
c900: 65 6e 20 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a  en crash.tcl w].
c910: 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74    puts $f "sqlit
c920: 65 33 5f 63 72 61 73 68 5f 6f 6e 5f 77 72 69 74  e3_crash_on_writ
c930: 65 20 24 6e 44 65 6c 61 79 22 0a 20 20 70 75 74  e $nDelay".  put
c940: 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f 74 65  s $f "sqlite3_te
c950: 73 74 5f 63 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69  st_control_pendi
c960: 6e 67 5f 62 79 74 65 20 24 3a 3a 73 71 6c 69 74  ng_byte $::sqlit
c970: 65 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 22 0a  e_pending_byte".
c980: 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74    puts $f "sqlit
c990: 65 33 20 64 62 20 74 65 73 74 2e 64 62 20 2d 76  e3 db test.db -v
c9a0: 66 73 20 77 72 69 74 65 63 72 61 73 68 22 0a 20  fs writecrash". 
c9b0: 20 70 75 74 73 20 24 66 20 22 64 62 20 65 76 61   puts $f "db eva
c9c0: 6c 20 7b 24 7a 53 71 6c 7d 22 0a 20 20 70 75 74  l {$zSql}".  put
c9d0: 73 20 24 66 20 22 73 65 74 20 7b 7d 20 7b 7d 22  s $f "set {} {}"
c9e0: 0a 0a 20 20 63 6c 6f 73 65 20 24 66 0a 20 20 73  ..  close $f.  s
c9f0: 65 74 20 72 20 5b 63 61 74 63 68 20 7b 0a 20 20  et r [catch {.  
ca00: 20 20 65 78 65 63 20 5b 69 6e 66 6f 20 6e 61 6d    exec [info nam
ca10: 65 6f 66 65 78 65 63 5d 20 63 72 61 73 68 2e 74  eofexec] crash.t
ca20: 63 6c 20 3e 40 73 74 64 6f 75 74 0a 20 20 7d 20  cl >@stdout.  } 
ca30: 6d 73 67 5d 0a 0a 20 20 23 20 57 69 6e 64 6f 77  msg]..  # Window
ca40: 73 2f 41 63 74 69 76 65 53 74 61 74 65 20 54 43  s/ActiveState TC
ca50: 4c 20 72 65 74 75 72 6e 73 20 61 20 73 6c 69 67  L returns a slig
ca60: 68 74 6c 79 20 64 69 66 66 65 72 65 6e 74 0a 20  htly different. 
ca70: 20 23 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65   # error message
ca80: 2e 20 20 57 65 20 6d 61 70 20 74 68 61 74 20 74  .  We map that t
ca90: 6f 20 74 68 65 20 65 78 70 65 63 74 65 64 20 6d  o the expected m
caa0: 65 73 73 61 67 65 0a 20 20 23 20 73 6f 20 74 68  essage.  # so th
cab0: 61 74 20 77 65 20 64 6f 6e 27 74 20 68 61 76 65  at we don't have
cac0: 20 74 6f 20 63 68 61 6e 67 65 20 61 6c 6c 20 6f   to change all o
cad0: 66 20 74 68 65 20 74 65 73 74 0a 20 20 23 20 63  f the test.  # c
cae0: 61 73 65 73 2e 0a 20 20 69 66 20 7b 24 3a 3a 74  ases..  if {$::t
caf0: 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74  cl_platform(plat
cb00: 66 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22  form)=="windows"
cb10: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24 6d 73 67  } {.    if {$msg
cb20: 3d 3d 22 63 68 69 6c 64 20 6b 69 6c 6c 65 64 3a  =="child killed:
cb30: 20 75 6e 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c 22   unknown signal"
cb40: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 73  } {.      set ms
cb50: 67 20 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73  g "child process
cb60: 20 65 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c   exited abnormal
cb70: 6c 79 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ly".    }.  }.. 
cb80: 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a   lappend r $msg.
cb90: 7d 0a 0a 70 72 6f 63 20 72 75 6e 5f 69 6f 65 72  }..proc run_ioer
cba0: 72 5f 70 72 65 70 20 7b 7d 20 7b 0a 20 20 73 65  r_prep {} {.  se
cbb0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
cbc0: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20  ror_pending 0.  
cbd0: 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d  catch {db close}
cbe0: 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c  .  catch {db2 cl
cbf0: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 66 6f  ose}.  catch {fo
cc00: 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64  rcedelete test.d
cc10: 62 7d 0a 20 20 63 61 74 63 68 20 7b 66 6f 72 63  b}.  catch {forc
cc20: 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62 2d  edelete test.db-
cc30: 6a 6f 75 72 6e 61 6c 7d 0a 20 20 63 61 74 63 68  journal}.  catch
cc40: 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65   {forcedelete te
cc50: 73 74 32 2e 64 62 7d 0a 20 20 63 61 74 63 68 20  st2.db}.  catch 
cc60: 7b 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73  {forcedelete tes
cc70: 74 32 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20  t2.db-journal}. 
cc80: 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74   set ::DB [sqlit
cc90: 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73  e3 db test.db; s
cca0: 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f  qlite3_connectio
ccb0: 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20  n_pointer db].  
ccc0: 73 71 6c 69 74 65 33 5f 65 78 74 65 6e 64 65 64  sqlite3_extended
ccd0: 5f 72 65 73 75 6c 74 5f 63 6f 64 65 73 20 24 3a  _result_codes $:
cce0: 3a 44 42 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  :DB $::ioerropts
ccf0: 28 2d 65 72 63 29 0a 20 20 69 66 20 7b 5b 69 6e  (-erc).  if {[in
cd00: 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72  fo exists ::ioer
cd10: 72 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29 5d  ropts(-tclprep)]
cd20: 7d 20 7b 0a 20 20 20 20 65 76 61 6c 20 24 3a 3a  } {.    eval $::
cd30: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 70 72  ioerropts(-tclpr
cd40: 65 70 29 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69  ep).  }.  if {[i
cd50: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65  nfo exists ::ioe
cd60: 72 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70 29  rropts(-sqlprep)
cd70: 5d 7d 20 7b 0a 20 20 20 20 65 78 65 63 73 71 6c  ]} {.    execsql
cd80: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73   $::ioerropts(-s
cd90: 71 6c 70 72 65 70 29 0a 20 20 7d 0a 20 20 65 78  qlprep).  }.  ex
cda0: 70 72 20 30 0a 7d 0a 0a 23 20 55 73 61 67 65 3a  pr 0.}..# Usage:
cdb0: 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 3c   do_ioerr_test <
cdc0: 74 65 73 74 20 6e 75 6d 62 65 72 3e 20 3c 6f 70  test number> <op
cdd0: 74 69 6f 6e 73 2e 2e 2e 3e 0a 23 0a 23 20 54 68  tions...>.#.# Th
cde0: 69 73 20 70 72 6f 63 20 69 73 20 75 73 65 64 20  is proc is used 
cdf0: 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 74 65 73  to implement tes
ce00: 74 20 63 61 73 65 73 20 74 68 61 74 20 63 68 65  t cases that che
ce10: 63 6b 20 74 68 61 74 20 49 4f 20 65 72 72 6f 72  ck that IO error
ce20: 73 0a 23 20 61 72 65 20 63 6f 72 72 65 63 74 6c  s.# are correctl
ce30: 79 20 68 61 6e 64 6c 65 64 2e 20 54 68 65 20 66  y handled. The f
ce40: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2c 20 3c  irst argument, <
ce50: 74 65 73 74 20 6e 75 6d 62 65 72 3e 2c 20 69 73  test number>, is
ce60: 20 61 6e 20 69 6e 74 65 67 65 72 0a 23 20 75 73   an integer.# us
ce70: 65 64 20 74 6f 20 6e 61 6d 65 20 74 68 65 20 74  ed to name the t
ce80: 65 73 74 73 20 65 78 65 63 75 74 65 64 20 62 79  ests executed by
ce90: 20 74 68 69 73 20 70 72 6f 63 2e 20 4f 70 74 69   this proc. Opti
cea0: 6f 6e 73 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f  ons are as follo
ceb0: 77 73 3a 0a 23 0a 23 20 20 20 20 20 2d 74 63 6c  ws:.#.#     -tcl
cec0: 70 72 65 70 20 20 20 20 20 20 20 20 20 20 54 43  prep          TC
ced0: 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20  L script to run 
cee0: 74 6f 20 70 72 65 70 61 72 65 20 74 65 73 74 2e  to prepare test.
cef0: 0a 23 20 20 20 20 20 2d 73 71 6c 70 72 65 70 20  .#     -sqlprep 
cf00: 20 20 20 20 20 20 20 20 20 53 51 4c 20 73 63 72           SQL scr
cf10: 69 70 74 20 74 6f 20 72 75 6e 20 74 6f 20 70 72  ipt to run to pr
cf20: 65 70 61 72 65 20 74 65 73 74 2e 0a 23 20 20 20  epare test..#   
cf30: 20 20 2d 74 63 6c 62 6f 64 79 20 20 20 20 20 20    -tclbody      
cf40: 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20 74      TCL script t
cf50: 6f 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65 72  o run with IO er
cf60: 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a  ror simulation..
cf70: 23 20 20 20 20 20 2d 73 71 6c 62 6f 64 79 20 20  #     -sqlbody  
cf80: 20 20 20 20 20 20 20 20 54 43 4c 20 73 63 72 69          TCL scri
cf90: 70 74 20 74 6f 20 72 75 6e 20 77 69 74 68 20 49  pt to run with I
cfa0: 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c 61 74 69  O error simulati
cfb0: 6f 6e 2e 0a 23 20 20 20 20 20 2d 65 78 63 6c 75  on..#     -exclu
cfc0: 64 65 20 20 20 20 20 20 20 20 20 20 4c 69 73 74  de          List
cfd0: 20 6f 66 20 27 4e 27 20 76 61 6c 75 65 73 20 6e   of 'N' values n
cfe0: 6f 74 20 74 6f 20 74 65 73 74 2e 0a 23 20 20 20  ot to test..#   
cff0: 20 20 2d 65 72 63 20 20 20 20 20 20 20 20 20 20    -erc          
d000: 20 20 20 20 55 73 65 20 65 78 74 65 6e 64 65 64      Use extended
d010: 20 72 65 73 75 6c 74 20 63 6f 64 65 73 0a 23 20   result codes.# 
d020: 20 20 20 20 2d 70 65 72 73 69 73 74 20 20 20 20      -persist    
d030: 20 20 20 20 20 20 4d 61 6b 65 20 73 69 6d 75 6c        Make simul
d040: 61 74 65 64 20 49 2f 4f 20 65 72 72 6f 72 73 20  ated I/O errors 
d050: 70 65 72 73 69 73 74 65 6e 74 0a 23 20 20 20 20  persistent.#    
d060: 20 2d 73 74 61 72 74 20 20 20 20 20 20 20 20 20   -start         
d070: 20 20 20 56 61 6c 75 65 20 6f 66 20 27 4e 27 20     Value of 'N' 
d080: 74 6f 20 62 65 67 69 6e 20 77 69 74 68 20 28 64  to begin with (d
d090: 65 66 61 75 6c 74 20 31 29 0a 23 0a 23 20 20 20  efault 1).#.#   
d0a0: 20 20 2d 63 6b 73 75 6d 20 20 20 20 20 20 20 20    -cksum        
d0b0: 20 20 20 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20      Boolean. If 
d0c0: 74 72 75 65 2c 20 74 65 73 74 20 74 68 61 74 20  true, test that 
d0d0: 74 68 65 20 64 61 74 61 62 61 73 65 20 64 6f 65  the database doe
d0e0: 73 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20  s.#             
d0f0: 20 20 20 20 20 20 20 20 20 20 6e 6f 74 20 63 68            not ch
d100: 61 6e 67 65 20 64 75 72 69 6e 67 20 74 68 65 20  ange during the 
d110: 65 78 65 63 75 74 69 6f 6e 20 6f 66 20 74 68 65  execution of the
d120: 20 74 65 73 74 20 63 61 73 65 2e 0a 23 0a 70 72   test case..#.pr
d130: 6f 63 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74  oc do_ioerr_test
d140: 20 7b 74 65 73 74 6e 61 6d 65 20 61 72 67 73 7d   {testname args}
d150: 20 7b 0a 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72   {..  set ::ioer
d160: 72 6f 70 74 73 28 2d 73 74 61 72 74 29 20 31 0a  ropts(-start) 1.
d170: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
d180: 73 28 2d 63 6b 73 75 6d 29 20 30 0a 20 20 73 65  s(-cksum) 0.  se
d190: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65  t ::ioerropts(-e
d1a0: 72 63 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f  rc) 0.  set ::io
d1b0: 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20  erropts(-count) 
d1c0: 31 30 30 30 30 30 30 30 30 0a 20 20 73 65 74 20  100000000.  set 
d1d0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70 65 72  ::ioerropts(-per
d1e0: 73 69 73 74 29 20 31 0a 20 20 73 65 74 20 3a 3a  sist) 1.  set ::
d1f0: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72 65 66  ioerropts(-ckref
d200: 63 6f 75 6e 74 29 20 30 0a 20 20 73 65 74 20 3a  count) 0.  set :
d210: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 72 65 73 74  :ioerropts(-rest
d220: 6f 72 65 70 72 6e 67 29 20 31 0a 20 20 61 72 72  oreprng) 1.  arr
d230: 61 79 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  ay set ::ioerrop
d240: 74 73 20 24 61 72 67 73 0a 0a 20 20 23 20 54 45  ts $args..  # TE
d250: 4d 50 4f 52 41 52 59 3a 20 46 6f 72 20 33 2e 35  MPORARY: For 3.5
d260: 2e 39 2c 20 64 69 73 61 62 6c 65 20 74 65 73 74  .9, disable test
d270: 69 6e 67 20 6f 66 20 65 78 74 65 6e 64 65 64 20  ing of extended 
d280: 72 65 73 75 6c 74 20 63 6f 64 65 73 2e 20 54 68  result codes. Th
d290: 65 72 65 20 61 72 65 0a 20 20 23 20 61 20 63 6f  ere are.  # a co
d2a0: 75 70 6c 65 20 6f 66 20 6f 62 73 63 75 72 65 20  uple of obscure 
d2b0: 49 4f 20 65 72 72 6f 72 73 20 74 68 61 74 20 64  IO errors that d
d2c0: 6f 20 6e 6f 74 20 72 65 74 75 72 6e 20 74 68 65  o not return the
d2d0: 6d 2e 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72  m..  set ::ioerr
d2e0: 6f 70 74 73 28 2d 65 72 63 29 20 30 0a 0a 20 20  opts(-erc) 0..  
d2f0: 23 20 43 72 65 61 74 65 20 61 20 73 69 6e 67 6c  # Create a singl
d300: 65 20 54 43 4c 20 73 63 72 69 70 74 20 66 72 6f  e TCL script fro
d310: 6d 20 74 68 65 20 54 43 4c 20 61 6e 64 20 53 51  m the TCL and SQ
d320: 4c 20 73 70 65 63 69 66 69 65 64 0a 20 20 23 20  L specified.  # 
d330: 61 73 20 74 68 65 20 62 6f 64 79 20 6f 66 20 74  as the body of t
d340: 68 65 20 74 65 73 74 2e 0a 20 20 73 65 74 20 3a  he test..  set :
d350: 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 7b 7d 0a  :ioerrorbody {}.
d360: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
d370: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
d380: 74 63 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20  tclbody)]} {.   
d390: 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f   append ::ioerro
d3a0: 72 62 6f 64 79 20 22 24 3a 3a 69 6f 65 72 72 6f  rbody "$::ioerro
d3b0: 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5c 6e 22  pts(-tclbody)\n"
d3c0: 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f  .  }.  if {[info
d3d0: 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f   exists ::ioerro
d3e0: 70 74 73 28 2d 73 71 6c 62 6f 64 79 29 5d 7d 20  pts(-sqlbody)]} 
d3f0: 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 3a 3a 69  {.    append ::i
d400: 6f 65 72 72 6f 72 62 6f 64 79 20 22 64 62 20 65  oerrorbody "db e
d410: 76 61 6c 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74  val {$::ioerropt
d420: 73 28 2d 73 71 6c 62 6f 64 79 29 7d 22 0a 20 20  s(-sqlbody)}".  
d430: 7d 0a 0a 20 20 73 61 76 65 5f 70 72 6e 67 5f 73  }..  save_prng_s
d440: 74 61 74 65 0a 20 20 69 66 20 7b 24 3a 3a 69 6f  tate.  if {$::io
d450: 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d  erropts(-cksum)}
d460: 20 7b 0a 20 20 20 20 72 75 6e 5f 69 6f 65 72 72   {.    run_ioerr
d470: 5f 70 72 65 70 0a 20 20 20 20 65 76 61 6c 20 24  _prep.    eval $
d480: 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 0a 20 20  ::ioerrorbody.  
d490: 20 20 73 65 74 20 3a 3a 67 6f 6f 64 63 6b 73 75    set ::goodcksu
d4a0: 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 7d 0a 0a 20  m [cksum].  }.. 
d4b0: 20 73 65 74 20 3a 3a 67 6f 20 31 0a 20 20 23 72   set ::go 1.  #r
d4c0: 65 73 65 74 5f 70 72 6e 67 5f 73 74 61 74 65 0a  eset_prng_state.
d4d0: 20 20 66 6f 72 20 7b 73 65 74 20 6e 20 24 3a 3a    for {set n $::
d4e0: 69 6f 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74  ioerropts(-start
d4f0: 29 7d 20 7b 24 3a 3a 67 6f 7d 20 7b 69 6e 63 72  )} {$::go} {incr
d500: 20 6e 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a   n} {.    set ::
d510: 54 4e 20 24 6e 0a 20 20 20 20 69 6e 63 72 20 3a  TN $n.    incr :
d520: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e  :ioerropts(-coun
d530: 74 29 20 2d 31 0a 20 20 20 20 69 66 20 7b 24 3a  t) -1.    if {$:
d540: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e  :ioerropts(-coun
d550: 74 29 3c 30 7d 20 62 72 65 61 6b 0a 0a 20 20 20  t)<0} break..   
d560: 20 23 20 53 6b 69 70 20 74 68 69 73 20 49 4f 20   # Skip this IO 
d570: 65 72 72 6f 72 20 69 66 20 69 74 20 77 61 73 20  error if it was 
d580: 73 70 65 63 69 66 69 65 64 20 77 69 74 68 20 74  specified with t
d590: 68 65 20 22 2d 65 78 63 6c 75 64 65 22 20 6f 70  he "-exclude" op
d5a0: 74 69 6f 6e 2e 0a 20 20 20 20 69 66 20 7b 5b 69  tion..    if {[i
d5b0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65  nfo exists ::ioe
d5c0: 72 72 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29  rropts(-exclude)
d5d0: 5d 7d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b  ]} {.      if {[
d5e0: 6c 73 65 61 72 63 68 20 24 3a 3a 69 6f 65 72 72  lsearch $::ioerr
d5f0: 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29 20 24  opts(-exclude) $
d600: 6e 5d 21 3d 2d 31 7d 20 63 6f 6e 74 69 6e 75 65  n]!=-1} continue
d610: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24  .    }.    if {$
d620: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 72 65 73  ::ioerropts(-res
d630: 74 6f 72 65 70 72 6e 67 29 7d 20 7b 0a 20 20 20  toreprng)} {.   
d640: 20 20 20 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f     restore_prng_
d650: 73 74 61 74 65 0a 20 20 20 20 7d 0a 0a 20 20 20  state.    }..   
d660: 20 23 20 44 65 6c 65 74 65 20 74 68 65 20 66 69   # Delete the fi
d670: 6c 65 73 20 74 65 73 74 2e 64 62 20 61 6e 64 20  les test.db and 
d680: 74 65 73 74 32 2e 64 62 2c 20 74 68 65 6e 20 65  test2.db, then e
d690: 78 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 61  xecute the TCL a
d6a0: 6e 64 0a 20 20 20 20 23 20 53 51 4c 20 28 69 6e  nd.    # SQL (in
d6b0: 20 74 68 61 74 20 6f 72 64 65 72 29 20 74 6f 20   that order) to 
d6c0: 70 72 65 70 61 72 65 20 66 6f 72 20 74 68 65 20  prepare for the 
d6d0: 74 65 73 74 20 63 61 73 65 2e 0a 20 20 20 20 64  test case..    d
d6e0: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
d6f0: 2e 24 6e 2e 31 20 7b 0a 20 20 20 20 20 20 72 75  .$n.1 {.      ru
d700: 6e 5f 69 6f 65 72 72 5f 70 72 65 70 0a 20 20 20  n_ioerr_prep.   
d710: 20 7d 20 7b 30 7d 0a 0a 20 20 20 20 23 20 52 65   } {0}..    # Re
d720: 61 64 20 74 68 65 20 27 63 68 65 63 6b 73 75 6d  ad the 'checksum
d730: 27 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  ' of the databas
d740: 65 2e 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f  e..    if {$::io
d750: 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d  erropts(-cksum)}
d760: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 63   {.      set ::c
d770: 68 65 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a  hecksum [cksum].
d780: 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 53 65 74      }..    # Set
d790: 20 74 68 65 20 4e 74 68 20 49 4f 20 65 72 72 6f   the Nth IO erro
d7a0: 72 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 64  r to fail..    d
d7b0: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
d7c0: 2e 24 6e 2e 32 20 5b 73 75 62 73 74 20 7b 0a 20  .$n.2 [subst {. 
d7d0: 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74       set ::sqlit
d7e0: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69  e_io_error_persi
d7f0: 73 74 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  st $::ioerropts(
d800: 2d 70 65 72 73 69 73 74 29 0a 20 20 20 20 20 20  -persist).      
d810: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
d820: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 24 6e  error_pending $n
d830: 0a 20 20 20 20 7d 5d 20 24 6e 0a 0a 20 20 20 20  .    }] $n..    
d840: 23 20 45 78 65 63 75 74 65 20 74 68 65 20 54 43  # Execute the TC
d850: 4c 20 73 63 72 69 70 74 20 63 72 65 61 74 65 64  L script created
d860: 20 66 6f 72 20 74 68 65 20 62 6f 64 79 20 6f 66   for the body of
d870: 20 74 68 69 73 20 74 65 73 74 2e 20 49 66 0a 20   this test. If. 
d880: 20 20 20 23 20 61 74 20 6c 65 61 73 74 20 4e 20     # at least N 
d890: 49 4f 20 6f 70 65 72 61 74 69 6f 6e 73 20 70 65  IO operations pe
d8a0: 72 66 6f 72 6d 65 64 20 62 79 20 53 51 4c 69 74  rformed by SQLit
d8b0: 65 20 61 73 20 61 20 72 65 73 75 6c 74 20 6f 66  e as a result of
d8c0: 0a 20 20 20 20 23 20 74 68 65 20 73 63 72 69 70  .    # the scrip
d8d0: 74 2c 20 74 68 65 20 4e 74 68 20 77 69 6c 6c 20  t, the Nth will 
d8e0: 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73  fail..    do_tes
d8f0: 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 33  t $testname.$n.3
d900: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73   {.      set ::s
d910: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
d920: 69 74 20 30 0a 20 20 20 20 20 20 73 65 74 20 3a  it 0.      set :
d930: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
d940: 5f 68 61 72 64 68 69 74 20 30 0a 20 20 20 20 20  _hardhit 0.     
d950: 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 24 3a   set r [catch $:
d960: 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 6d 73 67  :ioerrorbody msg
d970: 5d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 65 72  ].      set ::er
d980: 72 73 65 65 6e 20 24 72 0a 20 20 20 20 20 20 73  rseen $r.      s
d990: 65 74 20 72 63 20 5b 73 71 6c 69 74 65 33 5f 65  et rc [sqlite3_e
d9a0: 72 72 63 6f 64 65 20 24 3a 3a 44 42 5d 0a 20 20  rrcode $::DB].  
d9b0: 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72      if {$::ioerr
d9c0: 6f 70 74 73 28 2d 65 72 63 29 7d 20 7b 0a 20 20  opts(-erc)} {.  
d9d0: 20 20 20 20 20 20 23 20 49 66 20 77 65 20 61 72        # If we ar
d9e0: 65 20 69 6e 20 65 78 74 65 6e 64 65 64 20 72 65  e in extended re
d9f0: 73 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20  sult code mode, 
da00: 6d 61 6b 65 20 73 75 72 65 20 61 6c 6c 20 6f 66  make sure all of
da10: 20 74 68 65 0a 20 20 20 20 20 20 20 20 23 20 49   the.        # I
da20: 4f 45 52 52 73 20 77 65 20 67 65 74 20 62 61 63  OERRs we get bac
da30: 6b 20 72 65 61 6c 6c 79 20 64 6f 20 68 61 76 65  k really do have
da40: 20 74 68 65 69 72 20 65 78 74 65 6e 64 65 64 20   their extended 
da50: 63 6f 64 65 20 76 61 6c 75 65 73 2e 0a 20 20 20  code values..   
da60: 20 20 20 20 20 23 20 49 66 20 61 6e 20 65 78 74       # If an ext
da70: 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64  ended result cod
da80: 65 20 69 73 20 72 65 74 75 72 6e 65 64 2c 20 74  e is returned, t
da90: 68 65 20 73 71 6c 69 74 65 33 5f 65 72 72 63 6f  he sqlite3_errco
daa0: 64 65 0a 20 20 20 20 20 20 20 20 23 20 54 43 4c  de.        # TCL
dab0: 63 6f 6d 6d 61 6e 64 20 77 69 6c 6c 20 72 65 74  command will ret
dac0: 75 72 6e 20 61 20 73 74 72 69 6e 67 20 6f 66 20  urn a string of 
dad0: 74 68 65 20 66 6f 72 6d 3a 20 20 53 51 4c 49 54  the form:  SQLIT
dae0: 45 5f 49 4f 45 52 52 2b 6e 6e 6e 6e 0a 20 20 20  E_IOERR+nnnn.   
daf0: 20 20 20 20 20 23 20 77 68 65 72 65 20 6e 6e 6e       # where nnn
db00: 6e 20 69 73 20 61 20 6e 75 6d 62 65 72 0a 20 20  n is a number.  
db10: 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78        if {[regex
db20: 70 20 7b 5e 53 51 4c 49 54 45 5f 49 4f 45 52 52  p {^SQLITE_IOERR
db30: 7d 20 24 72 63 5d 20 26 26 20 21 5b 72 65 67 65  } $rc] && ![rege
db40: 78 70 20 7b 49 4f 45 52 52 5c 2b 5c 64 7d 20 24  xp {IOERR\+\d} $
db50: 72 63 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  rc]} {.         
db60: 20 72 65 74 75 72 6e 20 24 72 63 0a 20 20 20 20   return $rc.    
db70: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c      }.      } el
db80: 73 65 20 7b 0a 20 20 20 20 20 20 20 20 23 20 49  se {.        # I
db90: 66 20 77 65 20 61 72 65 20 6e 6f 74 20 69 6e 20  f we are not in 
dba0: 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20  extended result 
dbb0: 63 6f 64 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20  code mode, make 
dbc0: 73 75 72 65 20 6e 6f 0a 20 20 20 20 20 20 20 20  sure no.        
dbd0: 23 20 65 78 74 65 6e 64 65 64 20 65 72 72 6f 72  # extended error
dbe0: 20 63 6f 64 65 73 20 61 72 65 20 72 65 74 75 72   codes are retur
dbf0: 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 69 66 20  ned..        if 
dc00: 7b 5b 72 65 67 65 78 70 20 7b 5c 2b 5c 64 7d 20  {[regexp {\+\d} 
dc10: 24 72 63 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20  $rc]} {.        
dc20: 20 20 72 65 74 75 72 6e 20 24 72 63 0a 20 20 20    return $rc.   
dc30: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
dc40: 20 20 20 20 20 23 20 54 68 65 20 74 65 73 74 20       # The test 
dc50: 72 65 70 65 61 74 73 20 61 73 20 6c 6f 6e 67 20  repeats as long 
dc60: 61 73 20 24 3a 3a 67 6f 20 69 73 20 6e 6f 6e 2d  as $::go is non-
dc70: 7a 65 72 6f 2e 20 20 24 3a 3a 67 6f 20 73 74 61  zero.  $::go sta
dc80: 72 74 73 20 6f 75 74 0a 20 20 20 20 20 20 23 20  rts out.      # 
dc90: 61 73 20 31 2e 20 20 57 68 65 6e 20 61 20 74 65  as 1.  When a te
dca0: 73 74 20 72 75 6e 73 20 74 6f 20 63 6f 6d 70 6c  st runs to compl
dcb0: 65 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 68 69  etion without hi
dcc0: 74 74 69 6e 67 20 61 6e 20 49 2f 4f 0a 20 20 20  tting an I/O.   
dcd0: 20 20 20 23 20 65 72 72 6f 72 2c 20 74 68 61 74     # error, that
dce0: 20 6d 65 61 6e 73 20 74 68 65 72 65 20 69 73 20   means there is 
dcf0: 6e 6f 20 70 6f 69 6e 74 20 69 6e 20 63 6f 6e 74  no point in cont
dd00: 69 6e 75 69 6e 67 20 77 69 74 68 20 74 68 69 73  inuing with this
dd10: 20 74 65 73 74 0a 20 20 20 20 20 20 23 20 63 61   test.      # ca
dd20: 73 65 20 73 6f 20 73 65 74 20 24 3a 3a 67 6f 20  se so set $::go 
dd30: 74 6f 20 7a 65 72 6f 2e 0a 20 20 20 20 20 20 23  to zero..      #
dd40: 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 73 71  .      if {$::sq
dd50: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65  lite_io_error_pe
dd60: 6e 64 69 6e 67 3e 30 7d 20 7b 0a 20 20 20 20 20  nding>0} {.     
dd70: 20 20 20 73 65 74 20 3a 3a 67 6f 20 30 0a 20 20     set ::go 0.  
dd80: 20 20 20 20 20 20 73 65 74 20 71 20 30 0a 20 20        set q 0.  
dd90: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
dda0: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64  te_io_error_pend
ddb0: 69 6e 67 20 30 0a 20 20 20 20 20 20 7d 20 65 6c  ing 0.      } el
ddc0: 73 65 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74  se {.        set
ddd0: 20 71 20 31 0a 20 20 20 20 20 20 7d 0a 0a 20 20   q 1.      }..  
dde0: 20 20 20 20 73 65 74 20 73 20 5b 65 78 70 72 20      set s [expr 
ddf0: 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72  $::sqlite_io_err
de00: 6f 72 5f 68 69 74 3d 3d 30 5d 0a 20 20 20 20 20  or_hit==0].     
de10: 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69   if {$::sqlite_i
de20: 6f 5f 65 72 72 6f 72 5f 68 69 74 3e 24 3a 3a 73  o_error_hit>$::s
de30: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
de40: 61 72 64 68 69 74 20 26 26 20 24 72 3d 3d 30 7d  ardhit && $r==0}
de50: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 72   {.        set r
de60: 20 31 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   1.      }.     
de70: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
de80: 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 0a 20 20  _error_hit 0..  
de90: 20 20 20 20 23 20 4f 6e 65 20 6f 66 20 74 77 6f      # One of two
dea0: 20 74 68 69 6e 67 73 20 6d 75 73 74 20 68 61 76   things must hav
deb0: 65 20 68 61 70 70 65 6e 65 64 2e 20 65 69 74 68  e happened. eith
dec0: 65 72 0a 20 20 20 20 20 20 23 20 20 20 31 2e 20  er.      #   1. 
ded0: 20 57 65 20 6e 65 76 65 72 20 68 69 74 20 74 68   We never hit th
dee0: 65 20 49 4f 20 65 72 72 6f 72 20 61 6e 64 20 74  e IO error and t
def0: 68 65 20 53 51 4c 20 72 65 74 75 72 6e 65 64 20  he SQL returned 
df00: 4f 4b 0a 20 20 20 20 20 20 23 20 20 20 32 2e 20  OK.      #   2. 
df10: 20 41 6e 20 49 4f 20 65 72 72 6f 72 20 77 61 73   An IO error was
df20: 20 68 69 74 20 61 6e 64 20 74 68 65 20 53 51 4c   hit and the SQL
df30: 20 66 61 69 6c 65 64 0a 20 20 20 20 20 20 23 0a   failed.      #.
df40: 20 20 20 20 20 20 23 70 75 74 73 20 22 73 3d 24        #puts "s=$
df50: 73 20 72 3d 24 72 20 71 3d 24 71 22 0a 20 20 20  s r=$r q=$q".   
df60: 20 20 20 65 78 70 72 20 7b 20 28 24 73 20 26 26     expr { ($s &&
df70: 20 21 24 72 20 26 26 20 21 24 71 29 20 7c 7c 20   !$r && !$q) || 
df80: 28 21 24 73 20 26 26 20 24 72 20 26 26 20 24 71  (!$s && $r && $q
df90: 29 20 7d 0a 20 20 20 20 7d 20 7b 31 7d 0a 0a 20  ) }.    } {1}.. 
dfa0: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
dfb0: 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 20  io_error_hit 0. 
dfc0: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
dfd0: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
dfe0: 20 30 0a 0a 20 20 20 20 23 20 43 68 65 63 6b 20   0..    # Check 
dff0: 74 68 61 74 20 6e 6f 20 70 61 67 65 20 72 65 66  that no page ref
e000: 65 72 65 6e 63 65 73 20 77 65 72 65 20 6c 65 61  erences were lea
e010: 6b 65 64 2e 20 54 68 65 72 65 20 73 68 6f 75 6c  ked. There shoul
e020: 64 20 62 65 0a 20 20 20 20 23 20 61 20 73 69 6e  d be.    # a sin
e030: 67 6c 65 20 72 65 66 65 72 65 6e 63 65 20 69 66  gle reference if
e040: 20 74 68 65 72 65 20 69 73 20 73 74 69 6c 6c 20   there is still 
e050: 61 6e 20 61 63 74 69 76 65 20 74 72 61 6e 73 61  an active transa
e060: 63 74 69 6f 6e 2c 0a 20 20 20 20 23 20 6f 72 20  ction,.    # or 
e070: 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a  zero otherwise..
e080: 20 20 20 20 23 0a 20 20 20 20 23 20 55 50 44 41      #.    # UPDA
e090: 54 45 3a 20 49 66 20 74 68 65 20 49 4f 20 65 72  TE: If the IO er
e0a0: 72 6f 72 20 6f 63 63 75 72 73 20 61 66 74 65 72  ror occurs after
e0b0: 20 61 20 27 42 45 47 49 4e 27 20 62 75 74 20 62   a 'BEGIN' but b
e0c0: 65 66 6f 72 65 20 61 6e 79 0a 20 20 20 20 23 20  efore any.    # 
e0d0: 6c 6f 63 6b 73 20 61 72 65 20 65 73 74 61 62 6c  locks are establ
e0e0: 69 73 68 65 64 20 6f 6e 20 64 61 74 61 62 61 73  ished on databas
e0f0: 65 20 66 69 6c 65 73 20 28 69 2e 65 2e 20 69 66  e files (i.e. if
e100: 20 74 68 65 20 65 72 72 6f 72 0a 20 20 20 20 23   the error.    #
e110: 20 6f 63 63 75 72 73 20 77 68 69 6c 65 20 61 74   occurs while at
e120: 74 65 6d 70 74 69 6e 67 20 74 6f 20 64 65 74 65  tempting to dete
e130: 63 74 20 61 20 68 6f 74 2d 6a 6f 75 72 6e 61 6c  ct a hot-journal
e140: 20 66 69 6c 65 29 2c 20 74 68 65 6e 0a 20 20 20   file), then.   
e150: 20 23 20 74 68 65 72 65 20 6d 61 79 20 30 20 70   # there may 0 p
e160: 61 67 65 20 72 65 66 65 72 65 6e 63 65 73 20 61  age references a
e170: 6e 64 20 61 6e 20 61 63 74 69 76 65 20 74 72 61  nd an active tra
e180: 6e 73 61 63 74 69 6f 6e 20 61 63 63 6f 72 64 69  nsaction accordi
e190: 6e 67 0a 20 20 20 20 23 20 74 6f 20 5b 73 71 6c  ng.    # to [sql
e1a0: 69 74 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d  ite3_get_autocom
e1b0: 6d 69 74 5d 2e 0a 20 20 20 20 23 0a 20 20 20 20  mit]..    #.    
e1c0: 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a  if {$::go && $::
e1d0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
e1e0: 68 61 72 64 68 69 74 20 26 26 20 24 3a 3a 69 6f  hardhit && $::io
e1f0: 65 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f  erropts(-ckrefco
e200: 75 6e 74 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f  unt)} {.      do
e210: 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e  _test $testname.
e220: 24 6e 2e 34 20 7b 0a 20 20 20 20 20 20 20 20 73  $n.4 {.        s
e230: 65 74 20 62 74 20 5b 62 74 72 65 65 5f 66 72 6f  et bt [btree_fro
e240: 6d 5f 64 62 20 64 62 5d 0a 20 20 20 20 20 20 20  m_db db].       
e250: 20 64 62 5f 65 6e 74 65 72 20 64 62 0a 20 20 20   db_enter db.   
e260: 20 20 20 20 20 61 72 72 61 79 20 73 65 74 20 73       array set s
e270: 74 61 74 73 20 5b 62 74 72 65 65 5f 70 61 67 65  tats [btree_page
e280: 72 5f 73 74 61 74 73 20 24 62 74 5d 0a 20 20 20  r_stats $bt].   
e290: 20 20 20 20 20 64 62 5f 6c 65 61 76 65 20 64 62       db_leave db
e2a0: 0a 20 20 20 20 20 20 20 20 73 65 74 20 6e 52 65  .        set nRe
e2b0: 66 20 24 73 74 61 74 73 28 72 65 66 29 0a 20 20  f $stats(ref).  
e2c0: 20 20 20 20 20 20 65 78 70 72 20 7b 24 6e 52 65        expr {$nRe
e2d0: 66 20 3d 3d 20 30 20 7c 7c 20 28 5b 73 71 6c 69  f == 0 || ([sqli
e2e0: 74 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d  te3_get_autocomm
e2f0: 69 74 20 64 62 5d 3d 3d 30 20 26 26 20 24 6e 52  it db]==0 && $nR
e300: 65 66 20 3d 3d 20 31 29 7d 0a 20 20 20 20 20 20  ef == 1)}.      
e310: 7d 20 7b 31 7d 0a 20 20 20 20 7d 0a 0a 20 20 20  } {1}.    }..   
e320: 20 23 20 49 66 20 74 68 65 72 65 20 69 73 20 61   # If there is a
e330: 6e 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20  n open database 
e340: 68 61 6e 64 6c 65 20 61 6e 64 20 6e 6f 20 6f 70  handle and no op
e350: 65 6e 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 0a  en transaction,.
e360: 20 20 20 20 23 20 61 6e 64 20 74 68 65 20 70 61      # and the pa
e370: 67 65 72 20 69 73 20 6e 6f 74 20 72 75 6e 6e 69  ger is not runni
e380: 6e 67 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d  ng in exclusive-
e390: 6c 6f 63 6b 69 6e 67 20 6d 6f 64 65 2c 0a 20 20  locking mode,.  
e3a0: 20 20 23 20 63 68 65 63 6b 20 74 68 61 74 20 74    # check that t
e3b0: 68 65 20 70 61 67 65 72 20 69 73 20 69 6e 20 22  he pager is in "
e3c0: 75 6e 6c 6f 63 6b 65 64 22 20 73 74 61 74 65 2e  unlocked" state.
e3d0: 20 54 68 65 6f 72 65 74 69 63 61 6c 6c 79 2c 0a   Theoretically,.
e3e0: 20 20 20 20 23 20 69 66 20 61 20 63 61 6c 6c 20      # if a call 
e3f0: 74 6f 20 78 55 6e 6c 6f 63 6b 28 29 20 66 61 69  to xUnlock() fai
e400: 6c 65 64 20 64 75 65 20 74 6f 20 61 6e 20 49 4f  led due to an IO
e410: 20 65 72 72 6f 72 20 74 68 65 20 75 6e 64 65 72   error the under
e420: 6c 79 69 6e 67 0a 20 20 20 20 23 20 66 69 6c 65  lying.    # file
e430: 20 6d 61 79 20 73 74 69 6c 6c 20 62 65 20 6c 6f   may still be lo
e440: 63 6b 65 64 2e 0a 20 20 20 20 23 0a 20 20 20 20  cked..    #.    
e450: 69 66 63 61 70 61 62 6c 65 20 70 72 61 67 6d 61  ifcapable pragma
e460: 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 20 5b 69   {.      if { [i
e470: 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20 64 62 5d  nfo commands db]
e480: 20 6e 65 20 22 22 0a 20 20 20 20 20 20 20 20 26   ne "".        &
e490: 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  & $::ioerropts(-
e4a0: 63 6b 72 65 66 63 6f 75 6e 74 29 0a 20 20 20 20  ckrefcount).    
e4b0: 20 20 20 20 26 26 20 5b 64 62 20 6f 6e 65 20 7b      && [db one {
e4c0: 70 72 61 67 6d 61 20 6c 6f 63 6b 69 6e 67 5f 6d  pragma locking_m
e4d0: 6f 64 65 7d 5d 20 65 71 20 22 6e 6f 72 6d 61 6c  ode}] eq "normal
e4e0: 22 0a 20 20 20 20 20 20 20 20 26 26 20 5b 73 71  ".        && [sq
e4f0: 6c 69 74 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f  lite3_get_autoco
e500: 6d 6d 69 74 20 64 62 5d 0a 20 20 20 20 20 20 7d  mmit db].      }
e510: 20 7b 0a 20 20 20 20 20 20 20 20 64 6f 5f 74 65   {.        do_te
e520: 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e  st $testname.$n.
e530: 35 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65  5 {.          se
e540: 74 20 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d  t bt [btree_from
e550: 5f 64 62 20 64 62 5d 0a 20 20 20 20 20 20 20 20  _db db].        
e560: 20 20 64 62 5f 65 6e 74 65 72 20 64 62 0a 20 20    db_enter db.  
e570: 20 20 20 20 20 20 20 20 61 72 72 61 79 20 73 65          array se
e580: 74 20 73 74 61 74 73 20 5b 62 74 72 65 65 5f 70  t stats [btree_p
e590: 61 67 65 72 5f 73 74 61 74 73 20 24 62 74 5d 0a  ager_stats $bt].
e5a0: 20 20 20 20 20 20 20 20 20 20 64 62 5f 6c 65 61            db_lea
e5b0: 76 65 20 64 62 0a 20 20 20 20 20 20 20 20 20 20  ve db.          
e5c0: 73 65 74 20 73 74 61 74 73 28 73 74 61 74 65 29  set stats(state)
e5d0: 0a 20 20 20 20 20 20 20 20 7d 20 30 0a 20 20 20  .        } 0.   
e5e0: 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
e5f0: 23 20 49 66 20 61 6e 20 49 4f 20 65 72 72 6f 72  # If an IO error
e600: 20 6f 63 63 75 72 72 65 64 2c 20 74 68 65 6e 20   occurred, then 
e610: 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 66 20  the checksum of 
e620: 74 68 65 20 64 61 74 61 62 61 73 65 20 73 68 6f  the database sho
e630: 75 6c 64 0a 20 20 20 20 23 20 62 65 20 74 68 65  uld.    # be the
e640: 20 73 61 6d 65 20 61 73 20 62 65 66 6f 72 65 20   same as before 
e650: 74 68 65 20 73 63 72 69 70 74 20 74 68 61 74 20  the script that 
e660: 63 61 75 73 65 64 20 74 68 65 20 49 4f 20 65 72  caused the IO er
e670: 72 6f 72 20 77 61 73 20 72 75 6e 2e 0a 20 20 20  ror was run..   
e680: 20 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f   #.    if {$::go
e690: 20 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f   && $::sqlite_io
e6a0: 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26  _error_hardhit &
e6b0: 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  & $::ioerropts(-
e6c0: 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20  cksum)} {.      
e6d0: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
e6e0: 65 2e 24 6e 2e 36 20 7b 0a 20 20 20 20 20 20 20  e.$n.6 {.       
e6f0: 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65   catch {db close
e700: 7d 0a 20 20 20 20 20 20 20 20 63 61 74 63 68 20  }.        catch 
e710: 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 20 20  {db2 close}.    
e720: 20 20 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71      set ::DB [sq
e730: 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62  lite3 db test.db
e740: 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63  ; sqlite3_connec
e750: 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d  tion_pointer db]
e760: 0a 20 20 20 20 20 20 20 20 73 65 74 20 6e 6f 77  .        set now
e770: 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20  cksum [cksum].  
e780: 20 20 20 20 20 20 73 65 74 20 72 65 73 20 5b 65        set res [e
e790: 78 70 72 20 7b 24 6e 6f 77 63 6b 73 75 6d 3d 3d  xpr {$nowcksum==
e7a0: 24 3a 3a 63 68 65 63 6b 73 75 6d 20 7c 7c 20 24  $::checksum || $
e7b0: 6e 6f 77 63 6b 73 75 6d 3d 3d 24 3a 3a 67 6f 6f  nowcksum==$::goo
e7c0: 64 63 6b 73 75 6d 7d 5d 0a 20 20 20 20 20 20 20  dcksum}].       
e7d0: 20 69 66 20 7b 24 72 65 73 3d 3d 30 7d 20 7b 0a   if {$res==0} {.
e7e0: 20 20 20 20 20 20 20 20 20 20 6f 75 74 70 75 74            output
e7f0: 32 20 22 6e 6f 77 3d 24 6e 6f 77 63 6b 73 75 6d  2 "now=$nowcksum
e800: 22 0a 20 20 20 20 20 20 20 20 20 20 6f 75 74 70  ".          outp
e810: 75 74 32 20 22 74 68 65 3d 24 3a 3a 63 68 65 63  ut2 "the=$::chec
e820: 6b 73 75 6d 22 0a 20 20 20 20 20 20 20 20 20 20  ksum".          
e830: 6f 75 74 70 75 74 32 20 22 66 77 64 3d 24 3a 3a  output2 "fwd=$::
e840: 67 6f 6f 64 63 6b 73 75 6d 22 0a 20 20 20 20 20  goodcksum".     
e850: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 73 65 74     }.        set
e860: 20 72 65 73 0a 20 20 20 20 20 20 7d 20 31 0a 20   res.      } 1. 
e870: 20 20 20 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a     }..    set ::
e880: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
e890: 68 61 72 64 68 69 74 20 30 0a 20 20 20 20 73 65  hardhit 0.    se
e8a0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
e8b0: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20  ror_pending 0.  
e8c0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
e8d0: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
e8e0: 63 6c 65 61 6e 75 70 29 5d 7d 20 7b 0a 20 20 20  cleanup)]} {.   
e8f0: 20 20 20 63 61 74 63 68 20 24 3a 3a 69 6f 65 72     catch $::ioer
e900: 72 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70 29 0a  ropts(-cleanup).
e910: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20      }.  }.  set 
e920: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
e930: 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 73 65  r_pending 0.  se
e940: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
e950: 72 6f 72 5f 70 65 72 73 69 73 74 20 30 0a 20 20  ror_persist 0.  
e960: 75 6e 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74  unset ::ioerropt
e970: 73 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 20 61 20  s.}..# Return a 
e980: 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f  checksum based o
e990: 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  n the contents o
e9a0: 66 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62  f the main datab
e9b0: 61 73 65 20 61 73 73 6f 63 69 61 74 65 64 0a 23  ase associated.#
e9c0: 20 77 69 74 68 20 63 6f 6e 6e 65 63 74 69 6f 6e   with connection
e9d0: 20 24 64 62 0a 23 0a 70 72 6f 63 20 63 6b 73 75   $db.#.proc cksu
e9e0: 6d 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  m {{db db}} {.  
e9f0: 73 65 74 20 74 78 74 20 5b 24 64 62 20 65 76 61  set txt [$db eva
ea00: 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l {.      SELECT
ea10: 20 6e 61 6d 65 2c 20 74 79 70 65 2c 20 73 71 6c   name, type, sql
ea20: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
ea30: 74 65 72 20 6f 72 64 65 72 20 62 79 20 6e 61 6d  ter order by nam
ea40: 65 0a 20 20 7d 5d 5c 6e 0a 20 20 66 6f 72 65 61  e.  }]\n.  forea
ea50: 63 68 20 74 62 6c 20 5b 24 64 62 20 65 76 61 6c  ch tbl [$db eval
ea60: 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20   {.      SELECT 
ea70: 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65  name FROM sqlite
ea80: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  _master WHERE ty
ea90: 70 65 3d 27 74 61 62 6c 65 27 20 6f 72 64 65 72  pe='table' order
eaa0: 20 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 20 7b 0a   by name.  }] {.
eab0: 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b      append txt [
eac0: 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54  $db eval "SELECT
ead0: 20 2a 20 46 52 4f 4d 20 24 74 62 6c 22 5d 5c 6e   * FROM $tbl"]\n
eae0: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 70  .  }.  foreach p
eaf0: 72 61 67 20 7b 64 65 66 61 75 6c 74 5f 73 79 6e  rag {default_syn
eb00: 63 68 72 6f 6e 6f 75 73 20 64 65 66 61 75 6c 74  chronous default
eb10: 5f 63 61 63 68 65 5f 73 69 7a 65 7d 20 7b 0a 20  _cache_size} {. 
eb20: 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 24 70     append txt $p
eb30: 72 61 67 2d 5b 24 64 62 20 65 76 61 6c 20 22 50  rag-[$db eval "P
eb40: 52 41 47 4d 41 20 24 70 72 61 67 22 5d 5c 6e 0a  RAGMA $prag"]\n.
eb50: 20 20 7d 0a 20 20 73 65 74 20 63 6b 73 75 6d 20    }.  set cksum 
eb60: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
eb70: 74 78 74 5d 2d 5b 6d 64 35 20 24 74 78 74 5d 0a  txt]-[md5 $txt].
eb80: 20 20 23 20 70 75 74 73 20 24 63 6b 73 75 6d 2d    # puts $cksum-
eb90: 5b 66 69 6c 65 20 73 69 7a 65 20 74 65 73 74 2e  [file size test.
eba0: 64 62 5d 0a 20 20 72 65 74 75 72 6e 20 24 63 6b  db].  return $ck
ebb0: 73 75 6d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74  sum.}..# Generat
ebc0: 65 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73  e a checksum bas
ebd0: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e  ed on the conten
ebe0: 74 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 61  ts of the main a
ebf0: 6e 64 20 74 65 6d 70 20 74 61 62 6c 65 73 0a 23  nd temp tables.#
ec00: 20 64 61 74 61 62 61 73 65 20 24 64 62 2e 20 49   database $db. I
ec10: 66 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f  f the checksum o
ec20: 66 20 74 77 6f 20 64 61 74 61 62 61 73 65 73 20  f two databases 
ec30: 69 73 20 74 68 65 20 73 61 6d 65 2c 20 61 6e 64  is the same, and
ec40: 20 74 68 65 0a 23 20 69 6e 74 65 67 72 69 74 79   the.# integrity
ec50: 2d 63 68 65 63 6b 20 70 61 73 73 65 73 20 66 6f  -check passes fo
ec60: 72 20 62 6f 74 68 2c 20 74 68 65 20 74 77 6f 20  r both, the two 
ec70: 64 61 74 61 62 61 73 65 73 20 61 72 65 20 69 64  databases are id
ec80: 65 6e 74 69 63 61 6c 2e 0a 23 0a 70 72 6f 63 20  entical..#.proc 
ec90: 61 6c 6c 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62  allcksum {{db db
eca0: 7d 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 5b  }} {.  set ret [
ecb0: 6c 69 73 74 5d 0a 20 20 69 66 63 61 70 61 62 6c  list].  ifcapabl
ecc0: 65 20 74 65 6d 70 64 62 20 7b 0a 20 20 20 20 73  e tempdb {.    s
ecd0: 65 74 20 73 71 6c 20 7b 0a 20 20 20 20 20 20 53  et sql {.      S
ece0: 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20  ELECT name FROM 
ecf0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
ed00: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
ed10: 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53  e' UNION.      S
ed20: 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20  ELECT name FROM 
ed30: 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74  sqlite_temp_mast
ed40: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
ed50: 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20  'table' UNION.  
ed60: 20 20 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69      SELECT 'sqli
ed70: 74 65 5f 6d 61 73 74 65 72 27 20 55 4e 49 4f 4e  te_master' UNION
ed80: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27 73  .      SELECT 's
ed90: 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65  qlite_temp_maste
eda0: 72 27 20 4f 52 44 45 52 20 42 59 20 31 0a 20 20  r' ORDER BY 1.  
edb0: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
edc0: 20 20 20 73 65 74 20 73 71 6c 20 7b 0a 20 20 20     set sql {.   
edd0: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
ede0: 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ROM sqlite_maste
edf0: 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27  r WHERE type = '
ee00: 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20  table' UNION.   
ee10: 20 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74     SELECT 'sqlit
ee20: 65 5f 6d 61 73 74 65 72 27 20 4f 52 44 45 52 20  e_master' ORDER 
ee30: 42 59 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  BY 1.    }.  }. 
ee40: 20 73 65 74 20 74 62 6c 6c 69 73 74 20 5b 24 64   set tbllist [$d
ee50: 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 20 20 73  b eval $sql].  s
ee60: 65 74 20 74 78 74 20 7b 7d 0a 20 20 66 6f 72 65  et txt {}.  fore
ee70: 61 63 68 20 74 62 6c 20 24 74 62 6c 6c 69 73 74  ach tbl $tbllist
ee80: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78   {.    append tx
ee90: 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c  t [$db eval "SEL
eea0: 45 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c 22  ECT * FROM $tbl"
eeb0: 5d 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  ].  }.  foreach 
eec0: 70 72 61 67 20 7b 64 65 66 61 75 6c 74 5f 63 61  prag {default_ca
eed0: 63 68 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20  che_size} {.    
eee0: 61 70 70 65 6e 64 20 74 78 74 20 24 70 72 61 67  append txt $prag
eef0: 2d 5b 24 64 62 20 65 76 61 6c 20 22 50 52 41 47  -[$db eval "PRAG
ef00: 4d 41 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d  MA $prag"]\n.  }
ef10: 0a 20 20 23 20 70 75 74 73 20 74 78 74 3d 24 74  .  # puts txt=$t
ef20: 78 74 0a 20 20 72 65 74 75 72 6e 20 5b 6d 64 35  xt.  return [md5
ef30: 20 24 74 78 74 5d 0a 7d 0a 0a 23 20 47 65 6e 65   $txt].}..# Gene
ef40: 72 61 74 65 20 61 20 63 68 65 63 6b 73 75 6d 20  rate a checksum 
ef50: 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e  based on the con
ef60: 74 65 6e 74 73 20 6f 66 20 61 20 73 69 6e 67 6c  tents of a singl
ef70: 65 20 64 61 74 61 62 61 73 65 20 77 69 74 68 0a  e database with.
ef80: 23 20 61 20 64 61 74 61 62 61 73 65 20 63 6f 6e  # a database con
ef90: 6e 65 63 74 69 6f 6e 2e 20 20 54 68 65 20 6e 61  nection.  The na
efa0: 6d 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  me of the databa
efb0: 73 65 20 69 73 20 24 64 62 6e 61 6d 65 2e 0a 23  se is $dbname..#
efc0: 20 45 78 61 6d 70 6c 65 73 20 6f 66 20 24 64 62   Examples of $db
efd0: 6e 61 6d 65 20 61 72 65 20 22 74 65 6d 70 22 20  name are "temp" 
efe0: 6f 72 20 22 6d 61 69 6e 22 2e 0a 23 0a 70 72 6f  or "main"..#.pro
eff0: 63 20 64 62 63 6b 73 75 6d 20 7b 64 62 20 64 62  c dbcksum {db db
f000: 6e 61 6d 65 7d 20 7b 0a 20 20 69 66 20 7b 24 64  name} {.  if {$d
f010: 62 6e 61 6d 65 3d 3d 22 74 65 6d 70 22 7d 20 7b  bname=="temp"} {
f020: 0a 20 20 20 20 73 65 74 20 6d 61 73 74 65 72 20  .    set master 
f030: 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74  sqlite_temp_mast
f040: 65 72 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  er.  } else {.  
f050: 20 20 73 65 74 20 6d 61 73 74 65 72 20 24 64 62    set master $db
f060: 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d 61 73 74  name.sqlite_mast
f070: 65 72 0a 20 20 7d 0a 20 20 73 65 74 20 61 6c 6c  er.  }.  set all
f080: 74 61 62 20 5b 24 64 62 20 65 76 61 6c 20 22 53  tab [$db eval "S
f090: 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20  ELECT name FROM 
f0a0: 24 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  $master WHERE ty
f0b0: 70 65 3d 27 74 61 62 6c 65 27 22 5d 0a 20 20 73  pe='table'"].  s
f0c0: 65 74 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c  et txt [$db eval
f0d0: 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   "SELECT * FROM 
f0e0: 24 6d 61 73 74 65 72 22 5d 5c 6e 0a 20 20 66 6f  $master"]\n.  fo
f0f0: 72 65 61 63 68 20 74 61 62 20 24 61 6c 6c 74 61  reach tab $allta
f100: 62 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74  b {.    append t
f110: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45  xt [$db eval "SE
f120: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 64 62 6e  LECT * FROM $dbn
f130: 61 6d 65 2e 24 74 61 62 22 5d 5c 6e 0a 20 20 7d  ame.$tab"]\n.  }
f140: 0a 20 20 72 65 74 75 72 6e 20 5b 6d 64 35 20 24  .  return [md5 $
f150: 74 78 74 5d 0a 7d 0a 0a 70 72 6f 63 20 6d 65 6d  txt].}..proc mem
f160: 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 20 7b 66  debug_log_sql {f
f170: 69 6c 65 6e 61 6d 65 7d 20 7b 0a 0a 20 20 73 65  ilename} {..  se
f180: 74 20 64 61 74 61 20 5b 73 71 6c 69 74 65 33 5f  t data [sqlite3_
f190: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 64 75 6d  memdebug_log dum
f1a0: 70 5d 0a 20 20 73 65 74 20 6e 46 72 61 6d 65 20  p].  set nFrame 
f1b0: 5b 65 78 70 72 20 5b 6c 6c 65 6e 67 74 68 20 5b  [expr [llength [
f1c0: 6c 69 6e 64 65 78 20 24 64 61 74 61 20 30 5d 5d  lindex $data 0]]
f1d0: 2d 32 5d 0a 20 20 69 66 20 7b 24 6e 46 72 61 6d  -2].  if {$nFram
f1e0: 65 20 3c 20 30 7d 20 7b 20 72 65 74 75 72 6e 20  e < 0} { return 
f1f0: 22 22 20 7d 0a 0a 20 20 73 65 74 20 64 61 74 61  "" }..  set data
f200: 62 61 73 65 20 74 65 6d 70 0a 0a 20 20 73 65 74  base temp..  set
f210: 20 74 62 6c 20 22 43 52 45 41 54 45 20 54 41 42   tbl "CREATE TAB
f220: 4c 45 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d  LE ${database}.m
f230: 61 6c 6c 6f 63 28 7a 54 65 73 74 2c 20 6e 43 61  alloc(zTest, nCa
f240: 6c 6c 2c 20 6e 42 79 74 65 2c 20 6c 53 74 61 63  ll, nByte, lStac
f250: 6b 29 3b 22 0a 0a 20 20 73 65 74 20 73 71 6c 20  k);"..  set sql 
f260: 22 22 0a 20 20 66 6f 72 65 61 63 68 20 65 20 24  "".  foreach e $
f270: 64 61 74 61 20 7b 0a 20 20 20 20 73 65 74 20 6e  data {.    set n
f280: 43 61 6c 6c 20 5b 6c 69 6e 64 65 78 20 24 65 20  Call [lindex $e 
f290: 30 5d 0a 20 20 20 20 73 65 74 20 6e 42 79 74 65  0].    set nByte
f2a0: 20 5b 6c 69 6e 64 65 78 20 24 65 20 31 5d 0a 20   [lindex $e 1]. 
f2b0: 20 20 20 73 65 74 20 6c 53 74 61 63 6b 20 5b 6c     set lStack [l
f2c0: 72 61 6e 67 65 20 24 65 20 32 20 65 6e 64 5d 0a  range $e 2 end].
f2d0: 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22      append sql "
f2e0: 49 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61  INSERT INTO ${da
f2f0: 74 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63 20 56  tabase}.malloc V
f300: 41 4c 55 45 53 22 0a 20 20 20 20 61 70 70 65 6e  ALUES".    appen
f310: 64 20 73 71 6c 20 22 28 27 74 65 73 74 27 2c 20  d sql "('test', 
f320: 24 6e 43 61 6c 6c 2c 20 24 6e 42 79 74 65 2c 20  $nCall, $nByte, 
f330: 27 24 6c 53 74 61 63 6b 27 29 3b 5c 6e 22 0a 20  '$lStack');\n". 
f340: 20 20 20 66 6f 72 65 61 63 68 20 66 20 24 6c 53     foreach f $lS
f350: 74 61 63 6b 20 7b 0a 20 20 20 20 20 20 73 65 74  tack {.      set
f360: 20 66 72 61 6d 65 73 28 24 66 29 20 31 0a 20 20   frames($f) 1.  
f370: 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74 20 74    }.  }..  set t
f380: 62 6c 32 20 22 43 52 45 41 54 45 20 54 41 42 4c  bl2 "CREATE TABL
f390: 45 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 72  E ${database}.fr
f3a0: 61 6d 65 28 66 72 61 6d 65 20 49 4e 54 45 47 45  ame(frame INTEGE
f3b0: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 6c  R PRIMARY KEY, l
f3c0: 69 6e 65 29 3b 5c 6e 22 0a 20 20 73 65 74 20 74  ine);\n".  set t
f3d0: 62 6c 33 20 22 43 52 45 41 54 45 20 54 41 42 4c  bl3 "CREATE TABL
f3e0: 45 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 69  E ${database}.fi
f3f0: 6c 65 28 6e 61 6d 65 20 50 52 49 4d 41 52 59 20  le(name PRIMARY 
f400: 4b 45 59 2c 20 63 6f 6e 74 65 6e 74 29 3b 5c 6e  KEY, content);\n
f410: 22 0a 0a 20 20 73 65 74 20 70 69 64 20 5b 70 69  "..  set pid [pi
f420: 64 5d 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20  d]..  foreach f 
f430: 5b 61 72 72 61 79 20 6e 61 6d 65 73 20 66 72 61  [array names fra
f440: 6d 65 73 5d 20 7b 0a 20 20 20 20 73 65 74 20 61  mes] {.    set a
f450: 64 64 72 20 5b 66 6f 72 6d 61 74 20 25 78 20 24  ddr [format %x $
f460: 66 5d 0a 20 20 20 20 73 65 74 20 63 6d 64 20 22  f].    set cmd "
f470: 65 75 2d 61 64 64 72 32 6c 69 6e 65 20 2d 2d 70  eu-addr2line --p
f480: 69 64 3d 24 70 69 64 20 24 61 64 64 72 22 0a 20  id=$pid $addr". 
f490: 20 20 20 73 65 74 20 6c 69 6e 65 20 5b 65 76 61     set line [eva
f4a0: 6c 20 65 78 65 63 20 24 63 6d 64 5d 0a 20 20 20  l exec $cmd].   
f4b0: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e 53   append sql "INS
f4c0: 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61 62  ERT INTO ${datab
f4d0: 61 73 65 7d 2e 66 72 61 6d 65 20 56 41 4c 55 45  ase}.frame VALUE
f4e0: 53 28 24 66 2c 20 27 24 6c 69 6e 65 27 29 3b 5c  S($f, '$line');\
f4f0: 6e 22 0a 0a 20 20 20 20 73 65 74 20 66 69 6c 65  n"..    set file
f500: 20 5b 6c 69 6e 64 65 78 20 5b 73 70 6c 69 74 20   [lindex [split 
f510: 24 6c 69 6e 65 20 3a 5d 20 30 5d 0a 20 20 20 20  $line :] 0].    
f520: 73 65 74 20 66 69 6c 65 73 28 24 66 69 6c 65 29  set files($file)
f530: 20 31 0a 20 20 7d 0a 0a 20 20 66 6f 72 65 61 63   1.  }..  foreac
f540: 68 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73  h f [array names
f550: 20 66 69 6c 65 73 5d 20 7b 0a 20 20 20 20 73 65   files] {.    se
f560: 74 20 63 6f 6e 74 65 6e 74 73 20 22 22 0a 20 20  t contents "".  
f570: 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20    catch {.      
f580: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66 5d  set fd [open $f]
f590: 0a 20 20 20 20 20 20 73 65 74 20 63 6f 6e 74 65  .      set conte
f5a0: 6e 74 73 20 5b 72 65 61 64 20 24 66 64 5d 0a 20  nts [read $fd]. 
f5b0: 20 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a 20       close $fd. 
f5c0: 20 20 20 7d 0a 20 20 20 20 73 65 74 20 63 6f 6e     }.    set con
f5d0: 74 65 6e 74 73 20 5b 73 74 72 69 6e 67 20 6d 61  tents [string ma
f5e0: 70 20 7b 27 20 27 27 7d 20 24 63 6f 6e 74 65 6e  p {' ''} $conten
f5f0: 74 73 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73  ts].    append s
f600: 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20  ql "INSERT INTO 
f610: 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 69 6c 65  ${database}.file
f620: 20 56 41 4c 55 45 53 28 27 24 66 27 2c 20 27 24   VALUES('$f', '$
f630: 63 6f 6e 74 65 6e 74 73 27 29 3b 5c 6e 22 0a 20  contents');\n". 
f640: 20 7d 0a 0a 20 20 73 65 74 20 65 73 63 61 70 65   }..  set escape
f650: 64 20 22 42 45 47 49 4e 3b 20 24 7b 74 62 6c 7d  d "BEGIN; ${tbl}
f660: 24 7b 74 62 6c 32 7d 24 7b 74 62 6c 33 7d 24 7b  ${tbl2}${tbl3}${
f670: 73 71 6c 7d 20 3b 20 43 4f 4d 4d 49 54 3b 22 0a  sql} ; COMMIT;".
f680: 20 20 73 65 74 20 65 73 63 61 70 65 64 20 5b 73    set escaped [s
f690: 74 72 69 6e 67 20 6d 61 70 20 5b 6c 69 73 74 20  tring map [list 
f6a0: 22 7b 22 20 22 5c 5c 7b 22 20 22 7d 22 20 22 5c  "{" "\\{" "}" "\
f6b0: 5c 7d 22 5d 20 24 65 73 63 61 70 65 64 5d 20 0a  \}"] $escaped] .
f6c0: 0a 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20  .  set fd [open 
f6d0: 24 66 69 6c 65 6e 61 6d 65 20 77 5d 0a 20 20 70  $filename w].  p
f6e0: 75 74 73 20 24 66 64 20 22 73 65 74 20 42 55 49  uts $fd "set BUI
f6f0: 4c 54 49 4e 20 7b 22 0a 20 20 70 75 74 73 20 24  LTIN {".  puts $
f700: 66 64 20 24 65 73 63 61 70 65 64 0a 20 20 70 75  fd $escaped.  pu
f710: 74 73 20 24 66 64 20 22 7d 22 0a 20 20 70 75 74  ts $fd "}".  put
f720: 73 20 24 66 64 20 7b 73 65 74 20 42 55 49 4c 54  s $fd {set BUILT
f730: 49 4e 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 5b  IN [string map [
f740: 6c 69 73 74 20 22 5c 5c 7b 22 20 22 7b 22 20 22  list "\\{" "{" "
f750: 5c 5c 7d 22 20 22 7d 22 5d 20 24 42 55 49 4c 54  \\}" "}"] $BUILT
f760: 49 4e 5d 7d 0a 20 20 73 65 74 20 6d 74 76 20 5b  IN]}.  set mtv [
f770: 6f 70 65 6e 20 24 3a 3a 74 65 73 74 64 69 72 2f  open $::testdir/
f780: 6d 61 6c 6c 6f 63 74 72 61 63 65 76 69 65 77 65  malloctraceviewe
f790: 72 2e 74 63 6c 5d 0a 20 20 73 65 74 20 74 78 74  r.tcl].  set txt
f7a0: 20 5b 72 65 61 64 20 24 6d 74 76 5d 0a 20 20 63   [read $mtv].  c
f7b0: 6c 6f 73 65 20 24 6d 74 76 0a 20 20 70 75 74 73  lose $mtv.  puts
f7c0: 20 24 66 64 20 24 74 78 74 0a 20 20 63 6c 6f 73   $fd $txt.  clos
f7d0: 65 20 24 66 64 0a 7d 0a 0a 23 20 44 72 6f 70 20  e $fd.}..# Drop 
f7e0: 61 6c 6c 20 74 61 62 6c 65 73 20 69 6e 20 64 61  all tables in da
f7f0: 74 61 62 61 73 65 20 5b 64 62 5d 0a 70 72 6f 63  tabase [db].proc
f800: 20 64 72 6f 70 5f 61 6c 6c 5f 74 61 62 6c 65 73   drop_all_tables
f810: 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69   {{db db}} {.  i
f820: 66 63 61 70 61 62 6c 65 20 74 72 69 67 67 65 72  fcapable trigger
f830: 26 26 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20  &&foreignkey {. 
f840: 20 20 20 73 65 74 20 70 6b 20 5b 24 64 62 20 6f     set pk [$db o
f850: 6e 65 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69  ne "PRAGMA forei
f860: 67 6e 5f 6b 65 79 73 22 5d 0a 20 20 20 20 24 64  gn_keys"].    $d
f870: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66  b eval "PRAGMA f
f880: 6f 72 65 69 67 6e 5f 6b 65 79 73 20 3d 20 4f 46  oreign_keys = OF
f890: 46 22 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68  F".  }.  foreach
f8a0: 20 7b 69 64 78 20 6e 61 6d 65 20 66 69 6c 65 7d   {idx name file}
f8b0: 20 5b 64 62 20 65 76 61 6c 20 7b 50 52 41 47 4d   [db eval {PRAGM
f8c0: 41 20 64 61 74 61 62 61 73 65 5f 6c 69 73 74 7d  A database_list}
f8d0: 5d 20 7b 0a 20 20 20 20 69 66 20 7b 24 69 64 78  ] {.    if {$idx
f8e0: 3d 3d 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  ==1} {.      set
f8f0: 20 6d 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74   master sqlite_t
f900: 65 6d 70 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d  emp_master.    }
f910: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65   else {.      se
f920: 74 20 6d 61 73 74 65 72 20 24 6e 61 6d 65 2e 73  t master $name.s
f930: 71 6c 69 74 65 5f 6d 61 73 74 65 72 0a 20 20 20  qlite_master.   
f940: 20 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b   }.    foreach {
f950: 74 20 74 79 70 65 7d 20 5b 24 64 62 20 65 76 61  t type} [$db eva
f960: 6c 20 22 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l ".      SELECT
f970: 20 6e 61 6d 65 2c 20 74 79 70 65 20 46 52 4f 4d   name, type FROM
f980: 20 24 6d 61 73 74 65 72 0a 20 20 20 20 20 20 57   $master.      W
f990: 48 45 52 45 20 74 79 70 65 20 49 4e 28 27 74 61  HERE type IN('ta
f9a0: 62 6c 65 27 2c 20 27 76 69 65 77 27 29 20 41 4e  ble', 'view') AN
f9b0: 44 20 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20  D name NOT LIKE 
f9c0: 27 73 71 6c 69 74 65 58 5f 25 27 20 45 53 43 41  'sqliteX_%' ESCA
f9d0: 50 45 20 27 58 27 0a 20 20 20 20 22 5d 20 7b 0a  PE 'X'.    "] {.
f9e0: 20 20 20 20 20 20 24 64 62 20 65 76 61 6c 20 22        $db eval "
f9f0: 44 52 4f 50 20 24 74 79 70 65 20 5c 22 24 74 5c  DROP $type \"$t\
fa00: 22 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  "".    }.  }.  i
fa10: 66 63 61 70 61 62 6c 65 20 74 72 69 67 67 65 72  fcapable trigger
fa20: 26 26 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20  &&foreignkey {. 
fa30: 20 20 20 24 64 62 20 65 76 61 6c 20 22 50 52 41     $db eval "PRA
fa40: 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73  GMA foreign_keys
fa50: 20 3d 20 24 70 6b 22 0a 20 20 7d 0a 7d 0a 0a 23   = $pk".  }.}..#
fa60: 20 44 72 6f 70 20 61 6c 6c 20 61 75 78 69 6c 69   Drop all auxili
fa70: 61 72 79 20 69 6e 64 65 78 65 73 20 66 72 6f 6d  ary indexes from
fa80: 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61   the main databa
fa90: 73 65 20 6f 70 65 6e 65 64 20 62 79 20 68 61 6e  se opened by han
faa0: 64 6c 65 20 5b 64 62 5d 2e 0a 23 0a 70 72 6f 63  dle [db]..#.proc
fab0: 20 64 72 6f 70 5f 61 6c 6c 5f 69 6e 64 65 78 65   drop_all_indexe
fac0: 73 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  s {{db db}} {.  
fad0: 73 65 74 20 4c 20 5b 24 64 62 20 65 76 61 6c 20  set L [$db eval 
fae0: 7b 0a 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d  {.    SELECT nam
faf0: 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  e FROM sqlite_ma
fb00: 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d  ster WHERE type=
fb10: 27 69 6e 64 65 78 27 20 41 4e 44 20 73 71 6c 20  'index' AND sql 
fb20: 4c 49 4b 45 20 27 63 72 65 61 74 65 25 27 0a 20  LIKE 'create%'. 
fb30: 20 7d 5d 0a 20 20 66 6f 72 65 61 63 68 20 69 64   }].  foreach id
fb40: 78 20 24 4c 20 7b 20 24 64 62 20 65 76 61 6c 20  x $L { $db eval 
fb50: 22 44 52 4f 50 20 49 4e 44 45 58 20 24 69 64 78  "DROP INDEX $idx
fb60: 22 20 7d 0a 7d 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  " }.}...#-------
fb70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fb80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fb90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fba0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
fbb0: 2d 2d 0a 23 20 49 66 20 61 20 74 65 73 74 20 73  --.# If a test s
fbc0: 63 72 69 70 74 20 69 73 20 65 78 65 63 75 74 65  cript is execute
fbd0: 64 20 77 69 74 68 20 67 6c 6f 62 61 6c 20 76 61  d with global va
fbe0: 72 69 61 62 6c 65 20 24 3a 3a 47 28 70 65 72 6d  riable $::G(perm
fbf0: 3a 6e 61 6d 65 29 20 73 65 74 20 74 6f 0a 23 20  :name) set to.# 
fc00: 22 77 61 6c 22 2c 20 74 68 65 6e 20 74 68 65 20  "wal", then the 
fc10: 74 65 73 74 73 20 61 72 65 20 72 75 6e 20 69 6e  tests are run in
fc20: 20 57 41 4c 20 6d 6f 64 65 2e 20 4f 74 68 65 72   WAL mode. Other
fc30: 77 69 73 65 2c 20 74 68 65 79 20 73 68 6f 75 6c  wise, they shoul
fc40: 64 20 62 65 20 72 75 6e 0a 23 20 69 6e 20 72 6f  d be run.# in ro
fc50: 6c 6c 62 61 63 6b 20 6d 6f 64 65 2e 20 54 68 65  llback mode. The
fc60: 20 66 6f 6c 6c 6f 77 69 6e 67 20 54 63 6c 20 70   following Tcl p
fc70: 72 6f 63 73 20 61 72 65 20 75 73 65 64 20 74 6f  rocs are used to
fc80: 20 6d 61 6b 65 20 74 68 69 73 20 6c 65 73 73 0a   make this less.
fc90: 23 20 69 6e 74 72 75 73 69 76 65 3a 0a 23 0a 23  # intrusive:.#.#
fca0: 20 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e     wal_set_journ
fcb0: 61 6c 5f 6d 6f 64 65 20 3f 44 42 3f 0a 23 0a 23  al_mode ?DB?.#.#
fcc0: 20 20 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20       If running 
fcd0: 61 20 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63  a WAL test, exec
fce0: 75 74 65 20 22 50 52 41 47 4d 41 20 6a 6f 75 72  ute "PRAGMA jour
fcf0: 6e 61 6c 5f 6d 6f 64 65 20 3d 20 77 61 6c 22 20  nal_mode = wal" 
fd00: 75 73 69 6e 67 0a 23 20 20 20 20 20 63 6f 6e 6e  using.#     conn
fd10: 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42  ection handle DB
fd20: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74 68 69  . Otherwise, thi
fd30: 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61 20 6e  s command is a n
fd40: 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f  o-op..#.#   wal_
fd50: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
fd60: 64 65 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f  de TESTNAME ?DB?
fd70: 0a 23 0a 23 20 20 20 20 20 49 66 20 72 75 6e 6e  .#.#     If runn
fd80: 69 6e 67 20 61 20 57 41 4c 20 74 65 73 74 2c 20  ing a WAL test, 
fd90: 65 78 65 63 75 74 65 20 61 20 74 65 73 74 73 20  execute a tests 
fda0: 63 61 73 65 20 74 68 61 74 20 66 61 69 6c 73 20  case that fails 
fdb0: 69 66 20 74 68 65 20 6d 61 69 6e 0a 23 20 20 20  if the main.#   
fdc0: 20 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 63    database for c
fdd0: 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65  onnection handle
fde0: 20 44 42 20 69 73 20 6e 6f 74 20 63 75 72 72 65   DB is not curre
fdf0: 6e 74 6c 79 20 61 20 57 41 4c 20 64 61 74 61 62  ntly a WAL datab
fe00: 61 73 65 2e 0a 23 20 20 20 20 20 4f 74 68 65 72  ase..#     Other
fe10: 77 69 73 65 20 28 69 66 20 6e 6f 74 20 72 75 6e  wise (if not run
fe20: 6e 69 6e 67 20 61 20 57 41 4c 20 70 65 72 6d 75  ning a WAL permu
fe30: 74 61 74 69 6f 6e 29 20 74 68 69 73 20 69 73 20  tation) this is 
fe40: 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77  a no-op..#.#   w
fe50: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23  al_is_wal_mode.#
fe60: 0a 23 20 20 20 20 20 52 65 74 75 72 6e 73 20 74  .#     Returns t
fe70: 72 75 65 20 69 66 20 74 68 69 73 20 74 65 73 74  rue if this test
fe80: 20 73 68 6f 75 6c 64 20 62 65 20 72 75 6e 20 69   should be run i
fe90: 6e 20 57 41 4c 20 6d 6f 64 65 2e 20 46 61 6c 73  n WAL mode. Fals
fea0: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 23 0a 70  e otherwise..#.p
feb0: 72 6f 63 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d  roc wal_is_wal_m
fec0: 6f 64 65 20 7b 7d 20 7b 0a 20 20 65 78 70 72 20  ode {} {.  expr 
fed0: 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20 65  {[permutation] e
fee0: 71 20 22 77 61 6c 22 7d 0a 7d 0a 70 72 6f 63 20  q "wal"}.}.proc 
fef0: 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f  wal_set_journal_
ff00: 6d 6f 64 65 20 7b 7b 64 62 20 64 62 7d 7d 20 7b  mode {{db db}} {
ff10: 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f  .  if { [wal_is_
ff20: 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20  wal_mode] } {.  
ff30: 20 20 24 64 62 20 65 76 61 6c 20 22 50 52 41 47    $db eval "PRAG
ff40: 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  MA journal_mode 
ff50: 3d 20 57 41 4c 22 0a 20 20 7d 0a 7d 0a 70 72 6f  = WAL".  }.}.pro
ff60: 63 20 77 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72  c wal_check_jour
ff70: 6e 61 6c 5f 6d 6f 64 65 20 7b 74 65 73 74 6e 61  nal_mode {testna
ff80: 6d 65 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  me {db db}} {.  
ff90: 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c  if { [wal_is_wal
ffa0: 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24  _mode] } {.    $
ffb0: 64 62 20 65 76 61 6c 20 7b 20 53 45 4c 45 43 54  db eval { SELECT
ffc0: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
ffd0: 61 73 74 65 72 20 7d 0a 20 20 20 20 64 6f 5f 74  aster }.    do_t
ffe0: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 20 5b 6c  est $testname [l
fff0: 69 73 74 20 24 64 62 20 65 76 61 6c 20 22 50 52  ist $db eval "PR
10000 41 47 4d 41 20 6d 61 69 6e 2e 6a 6f 75 72 6e 61  AGMA main.journa
10010 6c 5f 6d 6f 64 65 22 5d 20 7b 77 61 6c 7d 0a 20  l_mode"] {wal}. 
10020 20 7d 0a 7d 0a 0a 70 72 6f 63 20 77 61 6c 5f 69   }.}..proc wal_i
10030 73 5f 63 61 70 61 62 6c 65 20 7b 7d 20 7b 0a 20  s_capable {} {. 
10040 20 69 66 63 61 70 61 62 6c 65 20 21 77 61 6c 20   ifcapable !wal 
10050 7b 20 72 65 74 75 72 6e 20 30 20 7d 0a 20 20 69  { return 0 }.  i
10060 66 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d  f {[permutation]
10070 3d 3d 22 6a 6f 75 72 6e 61 6c 74 65 73 74 22 7d  =="journaltest"}
10080 20 7b 20 72 65 74 75 72 6e 20 30 20 7d 0a 20 20   { return 0 }.  
10090 72 65 74 75 72 6e 20 31 0a 7d 0a 0a 70 72 6f 63  return 1.}..proc
100a0 20 70 65 72 6d 75 74 61 74 69 6f 6e 20 7b 7d 20   permutation {} 
100b0 7b 0a 20 20 73 65 74 20 70 65 72 6d 20 22 22 0a  {.  set perm "".
100c0 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 65 72    catch {set per
100d0 6d 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65  m $::G(perm:name
100e0 29 7d 0a 20 20 73 65 74 20 70 65 72 6d 0a 7d 0a  )}.  set perm.}.
100f0 70 72 6f 63 20 70 72 65 73 71 6c 20 7b 7d 20 7b  proc presql {} {
10100 0a 20 20 73 65 74 20 70 72 65 73 71 6c 20 22 22  .  set presql ""
10110 0a 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 72  .  catch {set pr
10120 65 73 71 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70  esql $::G(perm:p
10130 72 65 73 71 6c 29 7d 0a 20 20 73 65 74 20 70 72  resql)}.  set pr
10140 65 73 71 6c 0a 7d 0a 0a 70 72 6f 63 20 69 73 71  esql.}..proc isq
10150 75 69 63 6b 20 7b 7d 20 7b 0a 20 20 73 65 74 20  uick {} {.  set 
10160 72 65 74 20 30 0a 20 20 63 61 74 63 68 20 7b 73  ret 0.  catch {s
10170 65 74 20 72 65 74 20 24 3a 3a 47 28 69 73 71 75  et ret $::G(isqu
10180 69 63 6b 29 7d 0a 20 20 73 65 74 20 72 65 74 0a  ick)}.  set ret.
10190 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  }..#------------
101a0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
101b0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
101c0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
101d0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a  -------------.#.
101e0 70 72 6f 63 20 73 6c 61 76 65 5f 74 65 73 74 5f  proc slave_test_
101f0 73 63 72 69 70 74 20 7b 73 63 72 69 70 74 7d 20  script {script} 
10200 7b 0a 0a 20 20 23 20 43 72 65 61 74 65 20 74 68  {..  # Create th
10210 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 75 73  e interpreter us
10220 65 64 20 74 6f 20 72 75 6e 20 74 68 65 20 74 65  ed to run the te
10230 73 74 20 73 63 72 69 70 74 2e 0a 20 20 69 6e 74  st script..  int
10240 65 72 70 20 63 72 65 61 74 65 20 74 69 6e 74 65  erp create tinte
10250 72 70 0a 0a 20 20 23 20 50 6f 70 75 6c 61 74 65  rp..  # Populate
10260 20 73 6f 6d 65 20 67 6c 6f 62 61 6c 20 76 61 72   some global var
10270 69 61 62 6c 65 73 20 74 68 61 74 20 74 65 73 74  iables that test
10280 65 72 2e 74 63 6c 20 65 78 70 65 63 74 73 20 74  er.tcl expects t
10290 6f 20 73 65 65 2e 0a 20 20 66 6f 72 65 61 63 68  o see..  foreach
102a0 20 7b 76 61 72 20 76 61 6c 75 65 7d 20 5b 6c 69   {var value} [li
102b0 73 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  st              
102c0 5c 0a 20 20 20 20 3a 3a 61 72 67 76 30 20 24 3a  \.    ::argv0 $:
102d0 3a 61 72 67 76 30 20 20 20 20 20 20 20 20 20 20  :argv0          
102e0 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
102f0 20 3a 3a 61 72 67 76 20 20 7b 7d 20 20 20 20 20   ::argv  {}     
10300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10310 20 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 53 4c        \.    ::SL
10320 41 56 45 20 31 20 20 20 20 20 20 20 20 20 20 20  AVE 1           
10330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10340 20 5c 0a 20 20 5d 20 7b 0a 20 20 20 20 69 6e 74   \.  ] {.    int
10350 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70  erp eval tinterp
10360 20 5b 6c 69 73 74 20 73 65 74 20 24 76 61 72 20   [list set $var 
10370 24 76 61 6c 75 65 5d 0a 20 20 7d 0a 0a 20 20 23  $value].  }..  #
10380 20 49 66 20 6f 75 74 70 75 74 20 69 73 20 62 65   If output is be
10390 69 6e 67 20 63 6f 70 69 65 64 20 69 6e 74 6f 20  ing copied into 
103a0 61 20 66 69 6c 65 2c 20 73 68 61 72 65 20 74 68  a file, share th
103b0 65 20 66 69 6c 65 2d 64 65 73 63 72 69 70 74 6f  e file-descripto
103c0 72 20 77 69 74 68 0a 20 20 23 20 74 68 65 20 69  r with.  # the i
103d0 6e 74 65 72 70 72 65 74 65 72 2e 0a 20 20 69 66  nterpreter..  if
103e0 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
103f0 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 5d 7d 20  :G(output_fd)]} 
10400 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 73 68 61  {.    interp sha
10410 72 65 20 7b 7d 20 24 3a 3a 47 28 6f 75 74 70 75  re {} $::G(outpu
10420 74 5f 66 64 29 20 74 69 6e 74 65 72 70 0a 20 20  t_fd) tinterp.  
10430 7d 0a 0a 20 20 23 20 54 68 65 20 61 6c 69 61 73  }..  # The alias
10440 20 75 73 65 64 20 74 6f 20 61 63 63 65 73 73 20   used to access 
10450 74 68 65 20 67 6c 6f 62 61 6c 20 74 65 73 74 20  the global test 
10460 63 6f 75 6e 74 65 72 73 2e 0a 20 20 74 69 6e 74  counters..  tint
10470 65 72 70 20 61 6c 69 61 73 20 73 65 74 5f 74 65  erp alias set_te
10480 73 74 5f 63 6f 75 6e 74 65 72 20 73 65 74 5f 74  st_counter set_t
10490 65 73 74 5f 63 6f 75 6e 74 65 72 0a 0a 20 20 23  est_counter..  #
104a0 20 53 65 74 20 75 70 20 74 68 65 20 3a 3a 63 6d   Set up the ::cm
104b0 64 6c 69 6e 65 61 72 67 20 61 72 72 61 79 20 69  dlinearg array i
104c0 6e 20 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69  n the slave..  i
104d0 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65  nterp eval tinte
104e0 72 70 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73  rp [list array s
104f0 65 74 20 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20  et ::cmdlinearg 
10500 5b 61 72 72 61 79 20 67 65 74 20 3a 3a 63 6d 64  [array get ::cmd
10510 6c 69 6e 65 61 72 67 5d 5d 0a 0a 20 20 23 20 53  linearg]]..  # S
10520 65 74 20 75 70 20 74 68 65 20 3a 3a 47 20 61 72  et up the ::G ar
10530 72 61 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65  ray in the slave
10540 2e 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20  ..  interp eval 
10550 74 69 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72  tinterp [list ar
10560 72 61 79 20 73 65 74 20 3a 3a 47 20 5b 61 72 72  ray set ::G [arr
10570 61 79 20 67 65 74 20 3a 3a 47 5d 5d 0a 0a 20 20  ay get ::G]]..  
10580 23 20 4c 6f 61 64 20 74 68 65 20 76 61 72 69 6f  # Load the vario
10590 75 73 20 74 65 73 74 20 69 6e 74 65 72 66 61 63  us test interfac
105a0 65 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 69  es implemented i
105b0 6e 20 43 2e 0a 20 20 6c 6f 61 64 5f 74 65 73 74  n C..  load_test
105c0 66 69 78 74 75 72 65 5f 65 78 74 65 6e 73 69 6f  fixture_extensio
105d0 6e 73 20 74 69 6e 74 65 72 70 0a 0a 20 20 23 20  ns tinterp..  # 
105e0 52 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  Run the test scr
105f0 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 65 76  ipt..  interp ev
10600 61 6c 20 74 69 6e 74 65 72 70 20 24 73 63 72 69  al tinterp $scri
10610 70 74 0a 0a 20 20 23 20 43 68 65 63 6b 20 69 66  pt..  # Check if
10620 20 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72   the interpreter
10630 20 63 61 6c 6c 20 5b 72 75 6e 5f 74 68 72 65 61   call [run_threa
10640 64 5f 74 65 73 74 73 5d 0a 20 20 69 66 20 7b 20  d_tests].  if { 
10650 5b 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e  [interp eval tin
10660 74 65 72 70 20 7b 69 6e 66 6f 20 65 78 69 73 74  terp {info exist
10670 73 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74  s ::run_thread_t
10680 65 73 74 73 5f 63 61 6c 6c 65 64 7d 5d 20 7d 20  ests_called}] } 
10690 7b 0a 20 20 20 20 73 65 74 20 3a 3a 72 75 6e 5f  {.    set ::run_
106a0 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c  thread_tests_cal
106b0 6c 65 64 20 31 0a 20 20 7d 0a 0a 20 20 23 20 44  led 1.  }..  # D
106c0 65 6c 65 74 65 20 74 68 65 20 69 6e 74 65 72 70  elete the interp
106d0 72 65 74 65 72 20 75 73 65 64 20 74 6f 20 72 75  reter used to ru
106e0 6e 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  n the test scrip
106f0 74 2e 0a 20 20 69 6e 74 65 72 70 20 64 65 6c 65  t..  interp dele
10700 74 65 20 74 69 6e 74 65 72 70 0a 7d 0a 0a 70 72  te tinterp.}..pr
10710 6f 63 20 73 6c 61 76 65 5f 74 65 73 74 5f 66 69  oc slave_test_fi
10720 6c 65 20 7b 7a 46 69 6c 65 7d 20 7b 0a 20 20 73  le {zFile} {.  s
10730 65 74 20 74 61 69 6c 20 5b 66 69 6c 65 20 74 61  et tail [file ta
10740 69 6c 20 24 7a 46 69 6c 65 5d 0a 0a 20 20 69 66  il $zFile]..  if
10750 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
10760 3a 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61  :G(start:permuta
10770 74 69 6f 6e 29 5d 7d 20 7b 0a 20 20 20 20 69 66  tion)]} {.    if
10780 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20   {[permutation] 
10790 21 3d 20 24 3a 3a 47 28 73 74 61 72 74 3a 70 65  != $::G(start:pe
107a0 72 6d 75 74 61 74 69 6f 6e 29 7d 20 72 65 74 75  rmutation)} retu
107b0 72 6e 0a 20 20 20 20 75 6e 73 65 74 20 3a 3a 47  rn.    unset ::G
107c0 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69  (start:permutati
107d0 6f 6e 29 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69  on).  }.  if {[i
107e0 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73  nfo exists ::G(s
107f0 74 61 72 74 3a 66 69 6c 65 29 5d 7d 20 7b 0a 20  tart:file)]} {. 
10800 20 20 20 69 66 20 7b 24 74 61 69 6c 20 21 3d 20     if {$tail != 
10810 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29  $::G(start:file)
10820 20 26 26 20 24 74 61 69 6c 21 3d 22 24 3a 3a 47   && $tail!="$::G
10830 28 73 74 61 72 74 3a 66 69 6c 65 29 2e 74 65 73  (start:file).tes
10840 74 22 7d 20 72 65 74 75 72 6e 0a 20 20 20 20 75  t"} return.    u
10850 6e 73 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 66  nset ::G(start:f
10860 69 6c 65 29 0a 20 20 7d 0a 0a 20 20 23 20 52 65  ile).  }..  # Re
10870 6d 65 6d 62 65 72 20 74 68 65 20 76 61 6c 75 65  member the value
10880 20 6f 66 20 74 68 65 20 73 68 61 72 65 64 2d 63   of the shared-c
10890 61 63 68 65 20 73 65 74 74 69 6e 67 2e 20 53 6f  ache setting. So
108a0 20 74 68 61 74 20 69 74 20 69 73 20 70 6f 73 73   that it is poss
108b0 69 62 6c 65 0a 20 20 23 20 74 6f 20 63 68 65 63  ible.  # to chec
108c0 6b 20 61 66 74 65 72 77 61 72 64 73 20 74 68 61  k afterwards tha
108d0 74 20 69 74 20 77 61 73 20 6e 6f 74 20 6d 6f 64  t it was not mod
108e0 69 66 69 65 64 20 62 79 20 74 68 65 20 74 65 73  ified by the tes
108f0 74 20 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20  t script..  #.  
10900 69 66 63 61 70 61 62 6c 65 20 73 68 61 72 65 64  ifcapable shared
10910 5f 63 61 63 68 65 20 7b 20 73 65 74 20 73 63 73  _cache { set scs
10920 20 5b 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65   [sqlite3_enable
10930 5f 73 68 61 72 65 64 5f 63 61 63 68 65 5d 20 7d  _shared_cache] }
10940 0a 0a 20 20 23 20 52 75 6e 20 74 68 65 20 74 65  ..  # Run the te
10950 73 74 20 73 63 72 69 70 74 20 69 6e 20 61 20 73  st script in a s
10960 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74 65 72  lave interpreter
10970 2e 0a 20 20 23 0a 20 20 75 6e 73 65 74 20 2d 6e  ..  #.  unset -n
10980 6f 63 6f 6d 70 6c 61 69 6e 20 3a 3a 72 75 6e 5f  ocomplain ::run_
10990 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c  thread_tests_cal
109a0 6c 65 64 0a 20 20 72 65 73 65 74 5f 70 72 6e 67  led.  reset_prng
109b0 5f 73 74 61 74 65 0a 20 20 73 65 74 20 3a 3a 73  _state.  set ::s
109c0 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f  qlite_open_file_
109d0 63 6f 75 6e 74 20 30 0a 20 20 73 65 74 20 74 69  count 0.  set ti
109e0 6d 65 20 5b 74 69 6d 65 20 7b 20 73 6c 61 76 65  me [time { slave
109f0 5f 74 65 73 74 5f 73 63 72 69 70 74 20 5b 6c 69  _test_script [li
10a00 73 74 20 73 6f 75 72 63 65 20 24 7a 46 69 6c 65  st source $zFile
10a10 5d 20 7d 5d 0a 20 20 73 65 74 20 6d 73 20 5b 65  ] }].  set ms [e
10a20 78 70 72 20 5b 6c 69 6e 64 65 78 20 24 74 69 6d  xpr [lindex $tim
10a30 65 20 30 5d 20 2f 20 31 30 30 30 5d 0a 0a 20 20  e 0] / 1000]..  
10a40 23 20 54 65 73 74 20 74 68 61 74 20 61 6c 6c 20  # Test that all 
10a50 66 69 6c 65 73 20 6f 70 65 6e 65 64 20 62 79 20  files opened by 
10a60 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 20  the test script 
10a70 77 65 72 65 20 63 6c 6f 73 65 64 2e 20 4f 6d 69  were closed. Omi
10a80 74 20 74 68 69 73 0a 20 20 23 20 69 66 20 74 68  t this.  # if th
10a90 65 20 74 65 73 74 20 73 63 72 69 70 74 20 68 61  e test script ha
10aa0 73 20 22 74 68 72 65 61 64 22 20 69 6e 20 69 74  s "thread" in it
10ab0 73 20 6e 61 6d 65 2e 20 54 68 65 20 6f 70 65 6e  s name. The open
10ac0 20 66 69 6c 65 20 63 6f 75 6e 74 65 72 0a 20 20   file counter.  
10ad0 23 20 69 73 20 6e 6f 74 20 74 68 72 65 61 64 2d  # is not thread-
10ae0 73 61 66 65 2e 0a 20 20 23 0a 20 20 69 66 20 7b  safe..  #.  if {
10af0 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72  [info exists ::r
10b00 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f  un_thread_tests_
10b10 63 61 6c 6c 65 64 5d 3d 3d 30 7d 20 7b 0a 20 20  called]==0} {.  
10b20 20 20 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c    do_test ${tail
10b30 7d 2d 63 6c 6f 73 65 61 6c 6c 66 69 6c 65 73 20  }-closeallfiles 
10b40 7b 20 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74  { expr {$::sqlit
10b50 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
10b60 74 3e 30 7d 20 7d 20 7b 30 7d 0a 20 20 7d 0a 20  t>0} } {0}.  }. 
10b70 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 6f 70   set ::sqlite_op
10b80 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 30 0a  en_file_count 0.
10b90 0a 20 20 23 20 54 65 73 74 20 74 68 61 74 20 74  .  # Test that t
10ba0 68 65 20 67 6c 6f 62 61 6c 20 22 73 68 61 72 65  he global "share
10bb0 64 2d 63 61 63 68 65 22 20 73 65 74 74 69 6e 67  d-cache" setting
10bc0 20 77 61 73 20 6e 6f 74 20 61 6c 74 65 72 65 64   was not altered
10bd0 20 62 79 0a 20 20 23 20 74 68 65 20 74 65 73 74   by.  # the test
10be0 20 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69   script..  #.  i
10bf0 66 63 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f  fcapable shared_
10c00 63 61 63 68 65 20 7b 0a 20 20 20 20 73 65 74 20  cache {.    set 
10c10 72 65 73 20 5b 65 78 70 72 20 7b 5b 73 71 6c 69  res [expr {[sqli
10c20 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65  te3_enable_share
10c30 64 5f 63 61 63 68 65 5d 20 3d 3d 20 24 73 63 73  d_cache] == $scs
10c40 7d 5d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  }].    do_test $
10c50 7b 74 61 69 6c 7d 2d 73 68 61 72 65 64 63 61 63  {tail}-sharedcac
10c60 68 65 73 65 74 74 69 6e 67 20 5b 6c 69 73 74 20  hesetting [list 
10c70 73 65 74 20 7b 7d 20 24 72 65 73 5d 20 31 0a 20  set {} $res] 1. 
10c80 20 7d 0a 0a 20 20 23 20 41 64 64 20 73 6f 6d 65   }..  # Add some
10c90 20 69 6e 66 6f 20 74 6f 20 74 68 65 20 6f 75 74   info to the out
10ca0 70 75 74 2e 0a 20 20 23 0a 20 20 6f 75 74 70 75  put..  #.  outpu
10cb0 74 32 20 22 54 69 6d 65 3a 20 24 74 61 69 6c 20  t2 "Time: $tail 
10cc0 24 6d 73 20 6d 73 22 0a 20 20 73 68 6f 77 5f 6d  $ms ms".  show_m
10cd0 65 6d 73 74 61 74 73 0a 7d 0a 0a 23 20 4f 70 65  emstats.}..# Ope
10ce0 6e 20 61 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69  n a new connecti
10cf0 6f 6e 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74  on on database t
10d00 65 73 74 2e 64 62 20 61 6e 64 20 65 78 65 63 75  est.db and execu
10d10 74 65 20 74 68 65 20 53 51 4c 20 73 63 72 69 70  te the SQL scrip
10d20 74 0a 23 20 73 75 70 70 6c 69 65 64 20 61 73 20  t.# supplied as 
10d30 61 6e 20 61 72 67 75 6d 65 6e 74 2e 20 42 65 66  an argument. Bef
10d40 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c 20 63  ore returning, c
10d50 6c 6f 73 65 20 74 68 65 20 6e 65 77 20 63 6f 6e  lose the new con
10d60 65 63 74 69 6f 6e 20 61 6e 64 0a 23 20 72 65 73  ection and.# res
10d70 74 6f 72 65 20 74 68 65 20 34 20 62 79 74 65 20  tore the 4 byte 
10d80 66 69 65 6c 64 73 20 73 74 61 72 74 69 6e 67 20  fields starting 
10d90 61 74 20 68 65 61 64 65 72 20 6f 66 66 73 65 74  at header offset
10da0 73 20 32 38 2c 20 39 32 20 61 6e 64 20 39 36 0a  s 28, 92 and 96.
10db0 23 20 74 6f 20 74 68 65 20 76 61 6c 75 65 73 20  # to the values 
10dc0 74 68 65 79 20 68 65 6c 64 20 62 65 66 6f 72 65  they held before
10dd0 20 74 68 65 20 53 51 4c 20 77 61 73 20 65 78 65   the SQL was exe
10de0 63 75 74 65 64 2e 20 54 68 69 73 20 73 69 6d 75  cuted. This simu
10df0 6c 61 74 65 73 0a 23 20 61 20 77 72 69 74 65 20  lates.# a write 
10e00 62 79 20 61 20 70 72 65 2d 33 2e 37 2e 30 20 63  by a pre-3.7.0 c
10e10 6c 69 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 71  lient..#.proc sq
10e20 6c 33 36 32 33 31 20 7b 73 71 6c 7d 20 7b 0a 20  l36231 {sql} {. 
10e30 20 73 65 74 20 42 20 5b 68 65 78 69 6f 5f 72 65   set B [hexio_re
10e40 61 64 20 74 65 73 74 2e 64 62 20 39 32 20 38 5d  ad test.db 92 8]
10e50 0a 20 20 73 65 74 20 41 20 5b 68 65 78 69 6f 5f  .  set A [hexio_
10e60 72 65 61 64 20 74 65 73 74 2e 64 62 20 32 38 20  read test.db 28 
10e70 34 5d 0a 20 20 73 71 6c 69 74 65 33 20 64 62 33  4].  sqlite3 db3
10e80 36 32 33 31 20 74 65 73 74 2e 64 62 0a 20 20 63  6231 test.db.  c
10e90 61 74 63 68 20 7b 20 64 62 33 36 32 33 31 20 66  atch { db36231 f
10ea0 75 6e 63 20 61 5f 73 74 72 69 6e 67 20 61 5f 73  unc a_string a_s
10eb0 74 72 69 6e 67 20 7d 0a 20 20 65 78 65 63 73 71  tring }.  execsq
10ec0 6c 20 24 73 71 6c 20 64 62 33 36 32 33 31 0a 20  l $sql db36231. 
10ed0 20 64 62 33 36 32 33 31 20 63 6c 6f 73 65 0a 20   db36231 close. 
10ee0 20 68 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73   hexio_write tes
10ef0 74 2e 64 62 20 32 38 20 24 41 0a 20 20 68 65 78  t.db 28 $A.  hex
10f00 69 6f 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62  io_write test.db
10f10 20 39 32 20 24 42 0a 20 20 72 65 74 75 72 6e 20   92 $B.  return 
10f20 22 22 0a 7d 0a 0a 70 72 6f 63 20 64 62 5f 73 61  "".}..proc db_sa
10f30 76 65 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63  ve {} {.  foreac
10f40 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
10f50 70 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62  plain sv_test.db
10f60 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65  *] { forcedelete
10f70 20 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68 20   $f }.  foreach 
10f80 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
10f90 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b 0a  ain test.db*] {.
10fa0 20 20 20 20 73 65 74 20 66 32 20 22 73 76 5f 24      set f2 "sv_$
10fb0 66 22 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79  f".    forcecopy
10fc0 20 24 66 20 24 66 32 0a 20 20 7d 0a 7d 0a 70 72   $f $f2.  }.}.pr
10fd0 6f 63 20 64 62 5f 73 61 76 65 5f 61 6e 64 5f 63  oc db_save_and_c
10fe0 6c 6f 73 65 20 7b 7d 20 7b 0a 20 20 64 62 5f 73  lose {} {.  db_s
10ff0 61 76 65 0a 20 20 63 61 74 63 68 20 7b 20 64 62  ave.  catch { db
11000 20 63 6c 6f 73 65 20 7d 0a 20 20 72 65 74 75 72   close }.  retur
11010 6e 20 22 22 0a 7d 0a 70 72 6f 63 20 64 62 5f 72  n "".}.proc db_r
11020 65 73 74 6f 72 65 20 7b 7d 20 7b 0a 20 20 66 6f  estore {} {.  fo
11030 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e  reach f [glob -n
11040 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64  ocomplain test.d
11050 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74  b*] { forcedelet
11060 65 20 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68  e $f }.  foreach
11070 20 66 32 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d   f2 [glob -nocom
11080 70 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62  plain sv_test.db
11090 2a 5d 20 7b 0a 20 20 20 20 73 65 74 20 66 20 5b  *] {.    set f [
110a0 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 66 32  string range $f2
110b0 20 33 20 65 6e 64 5d 0a 20 20 20 20 66 6f 72 63   3 end].    forc
110c0 65 63 6f 70 79 20 24 66 32 20 24 66 0a 20 20 7d  ecopy $f2 $f.  }
110d0 0a 7d 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f  .}.proc db_resto
110e0 72 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20 7b 7b  re_and_reopen {{
110f0 64 62 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d  dbfile test.db}}
11100 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20   {.  catch { db 
11110 63 6c 6f 73 65 20 7d 0a 20 20 64 62 5f 72 65 73  close }.  db_res
11120 74 6f 72 65 0a 20 20 73 71 6c 69 74 65 33 20 64  tore.  sqlite3 d
11130 62 20 24 64 62 66 69 6c 65 0a 7d 0a 70 72 6f 63  b $dbfile.}.proc
11140 20 64 62 5f 64 65 6c 65 74 65 5f 61 6e 64 5f 72   db_delete_and_r
11150 65 6f 70 65 6e 20 7b 7b 66 69 6c 65 20 74 65 73  eopen {{file tes
11160 74 2e 64 62 7d 7d 20 7b 0a 20 20 63 61 74 63 68  t.db}} {.  catch
11170 20 7b 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20   { db close }.  
11180 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20  foreach f [glob 
11190 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74  -nocomplain test
111a0 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c  .db*] { forcedel
111b0 65 74 65 20 24 66 20 7d 0a 20 20 73 71 6c 69 74  ete $f }.  sqlit
111c0 65 33 20 64 62 20 24 66 69 6c 65 0a 7d 0a 0a 23  e3 db $file.}..#
111d0 20 43 6c 6f 73 65 20 61 6e 79 20 63 6f 6e 6e 65   Close any conne
111e0 63 74 69 6f 6e 73 20 6e 61 6d 65 64 20 5b 64 62  ctions named [db
111f0 5d 2c 20 5b 64 62 32 5d 20 6f 72 20 5b 64 62 33  ], [db2] or [db3
11200 5d 2e 20 54 68 65 6e 20 75 73 65 20 73 71 6c 69  ]. Then use sqli
11210 74 65 33 5f 63 6f 6e 66 69 67 0a 23 20 74 6f 20  te3_config.# to 
11220 63 6f 6e 66 69 67 75 72 65 20 74 68 65 20 73 69  configure the si
11230 7a 65 20 6f 66 20 74 68 65 20 50 41 47 45 43 41  ze of the PAGECA
11240 43 48 45 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 75  CHE allocation u
11250 73 69 6e 67 20 74 68 65 20 70 61 72 61 6d 65 74  sing the paramet
11260 65 72 73 0a 23 20 70 72 6f 76 69 64 65 64 20 74  ers.# provided t
11270 6f 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 2e 20  o this command. 
11280 53 61 76 65 20 74 68 65 20 6f 6c 64 20 50 41 47  Save the old PAG
11290 45 43 41 43 48 45 20 70 61 72 61 6d 65 74 65 72  ECACHE parameter
112a0 73 20 69 6e 20 61 20 67 6c 6f 62 61 6c 20 0a 23  s in a global .#
112b0 20 76 61 72 69 61 62 6c 65 20 73 6f 20 74 68 61   variable so tha
112c0 74 20 5b 74 65 73 74 5f 72 65 73 74 6f 72 65 5f  t [test_restore_
112d0 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65  config_pagecache
112e0 5d 20 63 61 6e 20 72 65 73 74 6f 72 65 20 74 68  ] can restore th
112f0 65 20 70 72 65 76 69 6f 75 73 0a 23 20 63 6f 6e  e previous.# con
11300 66 69 67 75 72 61 74 69 6f 6e 2e 0a 23 0a 23 20  figuration..#.# 
11310 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  Before returning
11320 2c 20 72 65 6f 70 65 6e 20 63 6f 6e 6e 65 63 74  , reopen connect
11330 69 6f 6e 20 5b 64 62 5d 20 6f 6e 20 66 69 6c 65  ion [db] on file
11340 20 74 65 73 74 2e 64 62 2e 0a 23 0a 70 72 6f 63   test.db..#.proc
11350 20 74 65 73 74 5f 73 65 74 5f 63 6f 6e 66 69 67   test_set_config
11360 5f 70 61 67 65 63 61 63 68 65 20 7b 73 7a 20 6e  _pagecache {sz n
11370 50 67 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64  Pg} {.  catch {d
11380 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
11390 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
113a0 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d  atch {db3 close}
113b0 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  ..  sqlite3_shut
113c0 64 6f 77 6e 0a 20 20 73 65 74 20 3a 3a 6f 6c 64  down.  set ::old
113d0 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69  _pagecache_confi
113e0 67 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  g [sqlite3_confi
113f0 67 5f 70 61 67 65 63 61 63 68 65 20 24 73 7a 20  g_pagecache $sz 
11400 24 6e 50 67 5d 0a 20 20 73 71 6c 69 74 65 33 5f  $nPg].  sqlite3_
11410 69 6e 69 74 69 61 6c 69 7a 65 0a 20 20 61 75 74  initialize.  aut
11420 6f 69 6e 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75  oinstall_test_fu
11430 6e 63 74 69 6f 6e 73 0a 20 20 72 65 73 65 74 5f  nctions.  reset_
11440 64 62 0a 7d 0a 0a 23 20 43 6c 6f 73 65 20 61 6e  db.}..# Close an
11450 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 6e 61  y connections na
11460 6d 65 64 20 5b 64 62 5d 2c 20 5b 64 62 32 5d 20  med [db], [db2] 
11470 6f 72 20 5b 64 62 33 5d 2e 20 54 68 65 6e 20 75  or [db3]. Then u
11480 73 65 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  se sqlite3_confi
11490 67 0a 23 20 74 6f 20 63 6f 6e 66 69 67 75 72 65  g.# to configure
114a0 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
114b0 20 50 41 47 45 43 41 43 48 45 20 61 6c 6c 6f 63   PAGECACHE alloc
114c0 61 74 69 6f 6e 20 74 6f 20 74 68 65 20 73 69 7a  ation to the siz
114d0 65 20 73 61 76 65 64 20 69 6e 0a 23 20 74 68 65  e saved in.# the
114e0 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
114f0 20 62 79 20 61 6e 20 65 61 72 6c 69 65 72 20 63   by an earlier c
11500 61 6c 6c 20 74 6f 20 5b 74 65 73 74 5f 73 65 74  all to [test_set
11510 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68  _config_pagecach
11520 65 5d 2e 0a 23 0a 23 20 42 65 66 6f 72 65 20 72  e]..#.# Before r
11530 65 74 75 72 6e 69 6e 67 2c 20 72 65 6f 70 65 6e  eturning, reopen
11540 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64 62 5d   connection [db]
11550 20 6f 6e 20 66 69 6c 65 20 74 65 73 74 2e 64 62   on file test.db
11560 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 72 65  ..#.proc test_re
11570 73 74 6f 72 65 5f 63 6f 6e 66 69 67 5f 70 61 67  store_config_pag
11580 65 63 61 63 68 65 20 7b 7d 20 7b 0a 20 20 63 61  ecache {} {.  ca
11590 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
115a0 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
115b0 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20  e}.  catch {db3 
115c0 63 6c 6f 73 65 7d 0a 0a 20 20 73 71 6c 69 74 65  close}..  sqlite
115d0 33 5f 73 68 75 74 64 6f 77 6e 0a 20 20 65 76 61  3_shutdown.  eva
115e0 6c 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  l sqlite3_config
115f0 5f 70 61 67 65 63 61 63 68 65 20 24 3a 3a 6f 6c  _pagecache $::ol
11600 64 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66  d_pagecache_conf
11610 69 67 0a 20 20 75 6e 73 65 74 20 3a 3a 6f 6c 64  ig.  unset ::old
11620 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69  _pagecache_confi
11630 67 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69  g .  sqlite3_ini
11640 74 69 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e  tialize.  autoin
11650 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74  stall_test_funct
11660 69 6f 6e 73 0a 20 20 73 71 6c 69 74 65 33 20 64  ions.  sqlite3 d
11670 62 20 74 65 73 74 2e 64 62 0a 7d 0a 0a 70 72 6f  b test.db.}..pro
11680 63 20 74 65 73 74 5f 62 69 6e 61 72 79 5f 6e 61  c test_binary_na
11690 6d 65 20 7b 6e 6d 7d 20 7b 0a 20 20 69 66 20 7b  me {nm} {.  if {
116a0 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
116b0 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 77 69 6e 64  platform)=="wind
116c0 6f 77 73 22 7d 20 7b 0a 20 20 20 20 73 65 74 20  ows"} {.    set 
116d0 72 65 74 20 22 24 6e 6d 2e 65 78 65 22 0a 20 20  ret "$nm.exe".  
116e0 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
116f0 20 72 65 74 20 24 6e 6d 0a 20 20 7d 0a 20 20 66   ret $nm.  }.  f
11700 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 5b 66  ile normalize [f
11710 69 6c 65 20 6a 6f 69 6e 20 24 3a 3a 63 6d 64 6c  ile join $::cmdl
11720 69 6e 65 61 72 67 28 54 45 53 54 46 49 58 54 55  inearg(TESTFIXTU
11730 52 45 5f 48 4f 4d 45 29 20 24 72 65 74 5d 0a 7d  RE_HOME) $ret].}
11740 0a 0a 70 72 6f 63 20 74 65 73 74 5f 66 69 6e 64  ..proc test_find
11750 5f 62 69 6e 61 72 79 20 7b 6e 6d 7d 20 7b 0a 20  _binary {nm} {. 
11760 20 73 65 74 20 72 65 74 20 5b 74 65 73 74 5f 62   set ret [test_b
11770 69 6e 61 72 79 5f 6e 61 6d 65 20 24 6e 6d 5d 0a  inary_name $nm].
11780 20 20 69 66 20 7b 21 5b 66 69 6c 65 20 65 78 65    if {![file exe
11790 63 75 74 61 62 6c 65 20 24 72 65 74 5d 7d 20 7b  cutable $ret]} {
117a0 0a 20 20 20 20 66 69 6e 69 73 68 5f 74 65 73 74  .    finish_test
117b0 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 20  .    return "". 
117c0 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 74   }.  return $ret
117d0 0a 7d 0a 0a 23 20 46 69 6e 64 20 74 68 65 20 6e  .}..# Find the n
117e0 61 6d 65 20 6f 66 20 74 68 65 20 27 73 68 65 6c  ame of the 'shel
117f0 6c 27 20 65 78 65 63 75 74 61 62 6c 65 20 28 65  l' executable (e
11800 2e 67 2e 20 22 73 71 6c 69 74 65 33 2e 65 78 65  .g. "sqlite3.exe
11810 22 29 20 74 6f 20 75 73 65 20 66 6f 72 0a 23 20  ") to use for.# 
11820 74 68 65 20 74 65 73 74 73 20 69 6e 20 73 68 65  the tests in she
11830 6c 6c 5b 31 2d 35 5d 2e 74 65 73 74 2e 20 49 66  ll[1-5].test. If
11840 20 6e 6f 20 73 75 63 68 20 65 78 65 63 75 74 61   no such executa
11850 62 6c 65 20 63 61 6e 20 62 65 20 66 6f 75 6e 64  ble can be found
11860 2c 20 69 6e 76 6f 6b 65 0a 23 20 5b 66 69 6e 69  , invoke.# [fini
11870 73 68 5f 74 65 73 74 20 3b 20 72 65 74 75 72 6e  sh_test ; return
11880 5d 20 69 6e 20 74 68 65 20 63 61 6c 6c 65 72 73  ] in the callers
11890 20 63 6f 6e 74 65 78 74 2e 0a 23 0a 70 72 6f 63   context..#.proc
118a0 20 74 65 73 74 5f 66 69 6e 64 5f 63 6c 69 20 7b   test_find_cli {
118b0 7d 20 7b 0a 20 20 73 65 74 20 70 72 6f 67 20 5b  } {.  set prog [
118c0 74 65 73 74 5f 66 69 6e 64 5f 62 69 6e 61 72 79  test_find_binary
118d0 20 73 71 6c 69 74 65 33 5d 0a 20 20 69 66 20 7b   sqlite3].  if {
118e0 24 70 72 6f 67 3d 3d 22 22 7d 20 7b 20 72 65 74  $prog==""} { ret
118f0 75 72 6e 20 2d 63 6f 64 65 20 72 65 74 75 72 6e  urn -code return
11900 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 70 72 6f   }.  return $pro
11910 67 0a 7d 0a 0a 23 20 46 69 6e 64 20 74 68 65 20  g.}..# Find the 
11920 6e 61 6d 65 20 6f 66 20 74 68 65 20 27 73 71 6c  name of the 'sql
11930 64 69 66 66 27 20 65 78 65 63 75 74 61 62 6c 65  diff' executable
11940 20 28 65 2e 67 2e 20 22 73 71 6c 69 74 65 33 2e   (e.g. "sqlite3.
11950 65 78 65 22 29 20 74 6f 20 75 73 65 20 66 6f 72  exe") to use for
11960 0a 23 20 74 68 65 20 74 65 73 74 73 20 69 6e 20  .# the tests in 
11970 73 71 6c 64 69 66 66 20 74 65 73 74 73 2e 20 49  sqldiff tests. I
11980 66 20 6e 6f 20 73 75 63 68 20 65 78 65 63 75 74  f no such execut
11990 61 62 6c 65 20 63 61 6e 20 62 65 20 66 6f 75 6e  able can be foun
119a0 64 2c 20 69 6e 76 6f 6b 65 0a 23 20 5b 66 69 6e  d, invoke.# [fin
119b0 69 73 68 5f 74 65 73 74 20 3b 20 72 65 74 75 72  ish_test ; retur
119c0 6e 5d 20 69 6e 20 74 68 65 20 63 61 6c 6c 65 72  n] in the caller
119d0 73 20 63 6f 6e 74 65 78 74 2e 0a 23 0a 70 72 6f  s context..#.pro
119e0 63 20 74 65 73 74 5f 66 69 6e 64 5f 73 71 6c 64  c test_find_sqld
119f0 69 66 66 20 7b 7d 20 7b 0a 20 20 73 65 74 20 70  iff {} {.  set p
11a00 72 6f 67 20 5b 74 65 73 74 5f 66 69 6e 64 5f 62  rog [test_find_b
11a10 69 6e 61 72 79 20 73 71 6c 64 69 66 66 5d 0a 20  inary sqldiff]. 
11a20 20 69 66 20 7b 24 70 72 6f 67 3d 3d 22 22 7d 20   if {$prog==""} 
11a30 7b 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 72  { return -code r
11a40 65 74 75 72 6e 20 7d 0a 20 20 72 65 74 75 72 6e  eturn }.  return
11a50 20 24 70 72 6f 67 0a 7d 0a 0a 23 20 43 61 6c 6c   $prog.}..# Call
11a60 20 73 71 6c 69 74 65 33 5f 65 78 70 61 6e 64 65   sqlite3_expande
11a70 64 5f 73 71 6c 28 29 20 6f 6e 20 61 6c 6c 20 73  d_sql() on all s
11a80 74 61 74 65 6d 65 6e 74 73 20 61 73 73 6f 63 69  tatements associ
11a90 61 74 65 64 20 77 69 74 68 20 64 61 74 61 62 61  ated with databa
11aa0 73 65 0a 23 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  se.# connection 
11ab0 24 64 62 2e 20 54 68 69 73 20 73 6f 6d 65 74 69  $db. This someti
11ac0 6d 65 73 20 66 69 6e 64 73 20 75 73 65 2d 61 66  mes finds use-af
11ad0 74 65 72 2d 66 72 65 65 20 62 75 67 73 20 69 66  ter-free bugs if
11ae0 20 72 75 6e 20 77 69 74 68 0a 23 20 76 61 6c 67   run with.# valg
11af0 72 69 6e 64 20 6f 72 20 61 64 64 72 65 73 73 2d  rind or address-
11b00 73 61 6e 69 74 69 7a 65 72 2e 0a 70 72 6f 63 20  sanitizer..proc 
11b10 65 78 70 61 6e 64 5f 61 6c 6c 5f 73 71 6c 20 7b  expand_all_sql {
11b20 64 62 7d 20 7b 0a 20 20 73 65 74 20 73 74 6d 74  db} {.  set stmt
11b30 20 22 22 0a 20 20 77 68 69 6c 65 20 7b 5b 73 65   "".  while {[se
11b40 74 20 73 74 6d 74 20 5b 73 71 6c 69 74 65 33 5f  t stmt [sqlite3_
11b50 6e 65 78 74 5f 73 74 6d 74 20 24 64 62 20 24 73  next_stmt $db $s
11b60 74 6d 74 5d 5d 21 3d 22 22 7d 20 7b 0a 20 20 20  tmt]]!=""} {.   
11b70 20 73 71 6c 69 74 65 33 5f 65 78 70 61 6e 64 65   sqlite3_expande
11b80 64 5f 73 71 6c 20 24 73 74 6d 74 0a 20 20 7d 0a  d_sql $stmt.  }.
11b90 7d 0a 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62  }...# If the lib
11ba0 72 61 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64  rary is compiled
11bb0 20 77 69 74 68 20 74 68 65 20 53 51 4c 49 54 45   with the SQLITE
11bc0 5f 44 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43  _DEFAULT_AUTOVAC
11bd0 55 55 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20  UUM macro set.# 
11be0 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65  to non-zero, the
11bf0 6e 20 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c  n set the global
11c00 20 76 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56   variable $AUTOV
11c10 41 43 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20  ACUUM to 1..set 
11c20 41 55 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69  AUTOVACUUM $sqli
11c30 74 65 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75  te_options(defau
11c40 6c 74 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a  lt_autovacuum)..
11c50 23 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20  # Make sure the 
11c60 46 54 53 20 65 6e 68 61 6e 63 65 64 20 71 75 65  FTS enhanced que
11c70 72 79 20 73 79 6e 74 61 78 20 69 73 20 64 69 73  ry syntax is dis
11c80 61 62 6c 65 64 2e 0a 73 65 74 20 73 71 6c 69 74  abled..set sqlit
11c90 65 5f 66 74 73 33 5f 65 6e 61 62 6c 65 5f 70 61  e_fts3_enable_pa
11ca0 72 65 6e 74 68 65 73 65 73 20 30 0a 0a 23 20 44  rentheses 0..# D
11cb0 75 72 69 6e 67 20 74 65 73 74 69 6e 67 2c 20 61  uring testing, a
11cc0 73 73 75 6d 65 20 74 68 61 74 20 61 6c 6c 20 64  ssume that all d
11cd0 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 61 72  atabase files ar
11ce0 65 20 77 65 6c 6c 2d 66 6f 72 6d 65 64 2e 20 20  e well-formed.  
11cf0 54 68 65 0a 23 20 66 65 77 20 74 65 73 74 20 63  The.# few test c
11d00 61 73 65 73 20 74 68 61 74 20 64 65 6c 69 62 65  ases that delibe
11d10 72 61 74 65 6c 79 20 63 6f 72 72 75 70 74 20 64  rately corrupt d
11d20 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 73 68  atabase files sh
11d30 6f 75 6c 64 20 72 65 73 63 69 6e 64 20 0a 23 20  ould rescind .# 
11d40 74 68 69 73 20 73 65 74 74 69 6e 67 20 62 79 20  this setting by 
11d50 69 6e 76 6f 6b 69 6e 67 20 22 64 61 74 61 62 61  invoking "databa
11d60 73 65 5f 63 61 6e 5f 62 65 5f 63 6f 72 72 75 70  se_can_be_corrup
11d70 74 22 0a 23 0a 64 61 74 61 62 61 73 65 5f 6e 65  t".#.database_ne
11d80 76 65 72 5f 63 6f 72 72 75 70 74 0a 0a 73 6f 75  ver_corrupt..sou
11d90 72 63 65 20 24 74 65 73 74 64 69 72 2f 74 68 72  rce $testdir/thr
11da0 65 61 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73  ead_common.tcl.s
11db0 6f 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d  ource $testdir/m
11dc0 61 6c 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c  alloc_common.tcl
11dd0 0a                                               .