/ Hex Artifact Content
Login

Artifact 581f0185434daf7026ccede4c07e8d1479186ec5:


0000: 23 20 32 30 30 31 20 53 65 70 74 65 6d 62 65 72  # 2001 September
0010: 20 31 35 0a 23 0a 23 20 54 68 65 20 61 75 74 68   15.#.# The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 23 20 61 20 6c 65 67  place of.# a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23  is a blessing:.#
0080: 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 64 6f  .#    May you do
0090: 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76   good and not ev
00a0: 69 6c 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75  il..#    May you
00b0: 20 66 69 6e 64 20 66 6f 72 67 69 76 65 6e 65 73   find forgivenes
00c0: 73 20 66 6f 72 20 79 6f 75 72 73 65 6c 66 20 61  s for yourself a
00d0: 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 68 65 72  nd forgive other
00e0: 73 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20  s..#    May you 
00f0: 73 68 61 72 65 20 66 72 65 65 6c 79 2c 20 6e 65  share freely, ne
0100: 76 65 72 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20  ver taking more 
0110: 74 68 61 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23  than you give..#
0120: 0a 23 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .#**************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73  *********.# This
0170: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0180: 20 73 6f 6d 65 20 63 6f 6d 6d 6f 6e 20 54 43 4c   some common TCL
0190: 20 72 6f 75 74 69 6e 65 73 20 75 73 65 64 20 66   routines used f
01a0: 6f 72 20 72 65 67 72 65 73 73 69 6f 6e 0a 23 20  or regression.# 
01b0: 74 65 73 74 69 6e 67 20 74 68 65 20 53 51 4c 69  testing the SQLi
01c0: 74 65 20 6c 69 62 72 61 72 79 0a 23 0a 23 20 24  te library.#.# $
01d0: 49 64 3a 20 74 65 73 74 65 72 2e 74 63 6c 2c 76  Id: tester.tcl,v
01e0: 20 31 2e 31 34 33 20 32 30 30 39 2f 30 34 2f 30   1.143 2009/04/0
01f0: 39 20 30 31 3a 32 33 3a 34 39 20 64 72 68 20 45  9 01:23:49 drh E
0200: 78 70 20 24 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  xp $..#---------
0210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0240: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0250: 0a 23 20 54 68 65 20 63 6f 6d 6d 61 6e 64 73 20  .# The commands 
0260: 70 72 6f 76 69 64 65 64 20 62 79 20 74 68 65 20  provided by the 
0270: 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c  code in this fil
0280: 65 20 74 6f 20 68 65 6c 70 20 77 69 74 68 20 63  e to help with c
0290: 72 65 61 74 69 6e 67 0a 23 20 74 65 73 74 20 63  reating.# test c
02a0: 61 73 65 73 20 61 72 65 20 61 73 20 66 6f 6c 6c  ases are as foll
02b0: 6f 77 73 3a 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64  ows:.#.# Command
02c0: 73 20 74 6f 20 6d 61 6e 69 70 75 6c 61 74 65 20  s to manipulate 
02d0: 74 68 65 20 64 62 20 61 6e 64 20 74 68 65 20 66  the db and the f
02e0: 69 6c 65 2d 73 79 73 74 65 6d 20 61 74 20 61 20  ile-system at a 
02f0: 68 69 67 68 20 6c 65 76 65 6c 3a 0a 23 0a 23 20  high level:.#.# 
0300: 20 20 20 20 20 69 73 5f 72 65 6c 61 74 69 76 65       is_relative
0310: 5f 66 69 6c 65 0a 23 20 20 20 20 20 20 74 65 73  _file.#      tes
0320: 74 5f 70 77 64 0a 23 20 20 20 20 20 20 67 65 74  t_pwd.#      get
0330: 5f 70 77 64 0a 23 20 20 20 20 20 20 63 6f 70 79  _pwd.#      copy
0340: 5f 66 69 6c 65 20 20 20 20 20 20 20 20 20 20 20  _file           
0350: 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20 20 20 20     FROM TO.#    
0360: 20 20 64 65 6c 65 74 65 5f 66 69 6c 65 20 20 20    delete_file   
0370: 20 20 20 20 20 20 20 20 20 46 49 4c 45 4e 41 4d           FILENAM
0380: 45 0a 23 20 20 20 20 20 20 64 72 6f 70 5f 61 6c  E.#      drop_al
0390: 6c 5f 74 61 62 6c 65 73 20 20 20 20 20 20 20 20  l_tables        
03a0: 3f 44 42 3f 0a 23 20 20 20 20 20 20 64 72 6f 70  ?DB?.#      drop
03b0: 5f 61 6c 6c 5f 69 6e 64 65 78 65 73 20 20 20 20  _all_indexes    
03c0: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 66     ?DB?.#      f
03d0: 6f 72 63 65 63 6f 70 79 20 20 20 20 20 20 20 20  orcecopy        
03e0: 20 20 20 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20        FROM TO.# 
03f0: 20 20 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65       forcedelete
0400: 20 20 20 20 20 20 20 20 20 20 20 20 46 49 4c 45              FILE
0410: 4e 41 4d 45 0a 23 0a 23 20 54 65 73 74 20 74 68  NAME.#.# Test th
0420: 65 20 63 61 70 61 62 69 6c 69 74 79 20 6f 66 20  e capability of 
0430: 74 68 65 20 53 51 4c 69 74 65 20 76 65 72 73 69  the SQLite versi
0440: 6f 6e 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68  on built into th
0450: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 6f  e interpreter to
0460: 0a 23 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20  .# determine if 
0470: 61 20 73 70 65 63 69 66 69 63 20 74 65 73 74 20  a specific test 
0480: 63 61 6e 20 62 65 20 72 75 6e 3a 0a 23 0a 23 20  can be run:.#.# 
0490: 20 20 20 20 20 63 61 70 61 62 6c 65 20 20 20 20       capable    
04a0: 20 20 20 20 20 20 20 20 20 20 20 20 45 58 50 52              EXPR
04b0: 0a 23 20 20 20 20 20 20 69 66 63 61 70 61 62 6c  .#      ifcapabl
04c0: 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20 45  e              E
04d0: 58 50 52 0a 23 0a 23 20 43 61 6c 75 6c 61 74 65  XPR.#.# Calulate
04e0: 20 63 68 65 63 6b 73 75 6d 73 20 62 61 73 65 64   checksums based
04f0: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 63 6f 6e   on database con
0500: 74 65 6e 74 73 3a 0a 23 0a 23 20 20 20 20 20 20  tents:.#.#      
0510: 64 62 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20  dbcksum         
0520: 20 20 20 20 20 20 20 44 42 20 44 42 4e 41 4d 45         DB DBNAME
0530: 0a 23 20 20 20 20 20 20 61 6c 6c 63 6b 73 75 6d  .#      allcksum
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3f                 ?
0550: 44 42 3f 0a 23 20 20 20 20 20 20 63 6b 73 75 6d  DB?.#      cksum
0560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0570: 20 20 3f 44 42 3f 0a 23 0a 23 20 43 6f 6d 6d 61    ?DB?.#.# Comma
0580: 6e 64 73 20 74 6f 20 65 78 65 63 75 74 65 2f 65  nds to execute/e
0590: 78 70 6c 61 69 6e 20 53 51 4c 20 73 74 61 74 65  xplain SQL state
05a0: 6d 65 6e 74 73 3a 0a 23 0a 23 20 20 20 20 20 20  ments:.#.#      
05b0: 6d 65 6d 64 62 73 71 6c 20 20 20 20 20 20 20 20  memdbsql        
05c0: 20 20 20 20 20 20 20 53 51 4c 0a 23 20 20 20 20         SQL.#    
05d0: 20 20 73 74 65 70 73 71 6c 20 20 20 20 20 20 20    stepsql       
05e0: 20 20 20 20 20 20 20 20 20 44 42 20 53 51 4c 0a           DB SQL.
05f0: 23 20 20 20 20 20 20 65 78 65 63 73 71 6c 32 20  #      execsql2 
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
0610: 4c 0a 23 20 20 20 20 20 20 65 78 70 6c 61 69 6e  L.#      explain
0620: 5f 6e 6f 5f 74 72 61 63 65 20 20 20 20 20 20 20  _no_trace       
0630: 53 51 4c 0a 23 20 20 20 20 20 20 65 78 70 6c 61  SQL.#      expla
0640: 69 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20  in              
0650: 20 20 53 51 4c 20 3f 44 42 3f 0a 23 20 20 20 20    SQL ?DB?.#    
0660: 20 20 63 61 74 63 68 73 71 6c 20 20 20 20 20 20    catchsql      
0670: 20 20 20 20 20 20 20 20 20 53 51 4c 20 3f 44 42           SQL ?DB
0680: 3f 0a 23 20 20 20 20 20 20 65 78 65 63 73 71 6c  ?.#      execsql
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 53 51 4c 20 3f 44 42 3f 0a 23 0a 23 20 43 6f 6d  SQL ?DB?.#.# Com
06b0: 6d 61 6e 64 73 20 74 6f 20 72 75 6e 20 74 65 73  mands to run tes
06c0: 74 20 63 61 73 65 73 3a 0a 23 0a 23 20 20 20 20  t cases:.#.#    
06d0: 20 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20    do_ioerr_test 
06e0: 20 20 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d           TESTNAM
06f0: 45 20 41 52 47 53 2e 2e 2e 0a 23 20 20 20 20 20  E ARGS....#     
0700: 20 63 72 61 73 68 73 71 6c 20 20 20 20 20 20 20   crashsql       
0710: 20 20 20 20 20 20 20 20 41 52 47 53 2e 2e 2e 0a          ARGS....
0720: 23 20 20 20 20 20 20 69 6e 74 65 67 72 69 74 79  #      integrity
0730: 5f 63 68 65 63 6b 20 20 20 20 20 20 20 20 54 45  _check        TE
0740: 53 54 4e 41 4d 45 20 3f 44 42 3f 0a 23 20 20 20  STNAME ?DB?.#   
0750: 20 20 20 76 65 72 69 66 79 5f 65 78 5f 65 72 72     verify_ex_err
0760: 63 6f 64 65 20 20 20 20 20 20 54 45 53 54 4e 41  code      TESTNA
0770: 4d 45 20 45 58 50 45 43 54 45 44 20 3f 44 42 3f  ME EXPECTED ?DB?
0780: 0a 23 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20  .#      do_test 
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
07a0: 45 53 54 4e 41 4d 45 20 53 43 52 49 50 54 20 45  ESTNAME SCRIPT E
07b0: 58 50 45 43 54 45 44 0a 23 20 20 20 20 20 20 64  XPECTED.#      d
07c0: 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 20  o_execsql_test  
07d0: 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20 53        TESTNAME S
07e0: 51 4c 20 45 58 50 45 43 54 45 44 0a 23 20 20 20  QL EXPECTED.#   
07f0: 20 20 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74     do_catchsql_t
0800: 65 73 74 20 20 20 20 20 20 20 54 45 53 54 4e 41  est       TESTNA
0810: 4d 45 20 53 51 4c 20 45 58 50 45 43 54 45 44 0a  ME SQL EXPECTED.
0820: 23 20 20 20 20 20 20 64 6f 5f 74 69 6d 65 64 5f  #      do_timed_
0830: 65 78 65 63 73 71 6c 5f 74 65 73 74 20 20 54 45  execsql_test  TE
0840: 53 54 4e 41 4d 45 20 53 51 4c 20 45 58 50 45 43  STNAME SQL EXPEC
0850: 54 45 44 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73  TED.#.# Commands
0860: 20 70 72 6f 76 69 64 69 6e 67 20 61 20 6c 6f 77   providing a low
0870: 65 72 20 6c 65 76 65 6c 20 69 6e 74 65 72 66 61  er level interfa
0880: 63 65 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c  ce to the global
0890: 20 74 65 73 74 20 63 6f 75 6e 74 65 72 73 3a 0a   test counters:.
08a0: 23 0a 23 20 20 20 20 20 20 73 65 74 5f 74 65 73  #.#      set_tes
08b0: 74 5f 63 6f 75 6e 74 65 72 20 20 20 20 20 20 20  t_counter       
08c0: 43 4f 55 4e 54 45 52 20 3f 56 41 4c 55 45 3f 0a  COUNTER ?VALUE?.
08d0: 23 20 20 20 20 20 20 6f 6d 69 74 5f 74 65 73 74  #      omit_test
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 45                TE
08f0: 53 54 4e 41 4d 45 20 52 45 41 53 4f 4e 20 3f 41  STNAME REASON ?A
0900: 50 50 45 4e 44 3f 0a 23 20 20 20 20 20 20 66 61  PPEND?.#      fa
0910: 69 6c 5f 74 65 73 74 20 20 20 20 20 20 20 20 20  il_test         
0920: 20 20 20 20 20 54 45 53 54 4e 41 4d 45 0a 23 20       TESTNAME.# 
0930: 20 20 20 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a       incr_ntest.
0940: 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 72 75 6e 20  #.# Command run 
0950: 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61  at the end of ea
0960: 63 68 20 74 65 73 74 20 66 69 6c 65 3a 0a 23 0a  ch test file:.#.
0970: 23 20 20 20 20 20 20 66 69 6e 69 73 68 5f 74 65  #      finish_te
0980: 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20  st.#.# Commands 
0990: 74 6f 20 68 65 6c 70 20 63 72 65 61 74 65 20 74  to help create t
09a0: 65 73 74 20 66 69 6c 65 73 20 74 68 61 74 20 72  est files that r
09b0: 75 6e 20 77 69 74 68 20 74 68 65 20 22 57 41 4c  un with the "WAL
09c0: 22 20 61 6e 64 20 6f 74 68 65 72 0a 23 20 70 65  " and other.# pe
09d0: 72 6d 75 74 61 74 69 6f 6e 73 20 28 73 65 65 20  rmutations (see 
09e0: 66 69 6c 65 20 70 65 72 6d 75 74 61 74 69 6f 6e  file permutation
09f0: 73 2e 74 65 73 74 29 3a 0a 23 0a 23 20 20 20 20  s.test):.#.#    
0a00: 20 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64    wal_is_wal_mod
0a10: 65 0a 23 20 20 20 20 20 20 77 61 6c 5f 73 65 74  e.#      wal_set
0a20: 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 20 20  _journal_mode   
0a30: 3f 44 42 3f 0a 23 20 20 20 20 20 20 77 61 6c 5f  ?DB?.#      wal_
0a40: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
0a50: 64 65 20 54 45 53 54 4e 41 4d 45 3f 44 42 3f 0a  de TESTNAME?DB?.
0a60: 23 20 20 20 20 20 20 70 65 72 6d 75 74 61 74 69  #      permutati
0a70: 6f 6e 0a 23 20 20 20 20 20 20 70 72 65 73 71 6c  on.#      presql
0a80: 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 74 6f 20  .#.# Command to 
0a90: 74 65 73 74 20 77 68 65 74 68 65 72 20 6f 72 20  test whether or 
0aa0: 6e 6f 74 20 2d 2d 76 65 72 62 6f 73 65 3d 31 20  not --verbose=1 
0ab0: 77 61 73 20 73 70 65 63 69 66 69 65 64 20 6f 6e  was specified on
0ac0: 20 74 68 65 20 63 6f 6d 6d 61 6e 64 0a 23 20 6c   the command.# l
0ad0: 69 6e 65 20 28 72 65 74 75 72 6e 73 20 30 20 66  ine (returns 0 f
0ae0: 6f 72 20 6e 6f 74 2d 76 65 72 62 6f 73 65 2c 20  or not-verbose, 
0af0: 31 20 66 6f 72 20 76 65 72 62 6f 73 65 20 61 6e  1 for verbose an
0b00: 64 20 32 20 66 6f 72 20 22 76 65 72 62 6f 73 65  d 2 for "verbose
0b10: 20 69 6e 20 74 68 65 0a 23 20 6f 75 74 70 75 74   in the.# output
0b20: 20 66 69 6c 65 20 6f 6e 6c 79 22 29 2e 0a 23 0a   file only")..#.
0b30: 23 20 20 20 20 20 20 76 65 72 62 6f 73 65 0a 23  #      verbose.#
0b40: 0a 0a 23 20 53 65 74 20 74 68 65 20 70 72 65 63  ..# Set the prec
0b50: 69 73 69 6f 6e 20 6f 66 20 46 50 20 61 72 69 74  ision of FP arit
0b60: 68 6d 61 74 69 63 20 75 73 65 64 20 62 79 20 74  hmatic used by t
0b70: 68 65 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20  he interpreter. 
0b80: 41 6e 64 0a 23 20 63 6f 6e 66 69 67 75 72 65 20  And.# configure 
0b90: 53 51 4c 69 74 65 20 74 6f 20 74 61 6b 65 20 64  SQLite to take d
0ba0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 6c 6f 63  atabase file loc
0bb0: 6b 73 20 6f 6e 20 74 68 65 20 70 61 67 65 20 74  ks on the page t
0bc0: 68 61 74 20 62 65 67 69 6e 73 0a 23 20 36 34 4b  hat begins.# 64K
0bd0: 42 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  B into the datab
0be0: 61 73 65 20 66 69 6c 65 20 69 6e 73 74 65 61 64  ase file instead
0bf0: 20 6f 66 20 74 68 65 20 6f 6e 65 20 31 47 42 20   of the one 1GB 
0c00: 69 6e 2e 20 54 68 69 73 20 6d 65 61 6e 73 0a 23  in. This means.#
0c10: 20 74 68 65 20 63 6f 64 65 20 74 68 61 74 20 68   the code that h
0c20: 61 6e 64 6c 65 73 20 74 68 61 74 20 73 70 65 63  andles that spec
0c30: 69 61 6c 20 63 61 73 65 20 63 61 6e 20 62 65 20  ial case can be 
0c40: 74 65 73 74 65 64 20 77 69 74 68 6f 75 74 20 63  tested without c
0c50: 72 65 61 74 69 6e 67 0a 23 20 76 65 72 79 20 6c  reating.# very l
0c60: 61 72 67 65 20 64 61 74 61 62 61 73 65 20 66 69  arge database fi
0c70: 6c 65 73 2e 0a 23 0a 73 65 74 20 74 63 6c 5f 70  les..#.set tcl_p
0c80: 72 65 63 69 73 69 6f 6e 20 31 35 0a 73 71 6c 69  recision 15.sqli
0c90: 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f 6c  te3_test_control
0ca0: 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 30 78  _pending_byte 0x
0cb0: 30 30 31 30 30 30 30 0a 0a 0a 23 20 49 66 20 74  0010000...# If t
0cc0: 68 65 20 70 61 67 65 72 20 63 6f 64 65 63 20 69  he pager codec i
0cd0: 73 20 61 76 61 69 6c 61 62 6c 65 2c 20 63 72 65  s available, cre
0ce0: 61 74 65 20 61 20 77 72 61 70 70 65 72 20 66 6f  ate a wrapper fo
0cf0: 72 20 74 68 65 20 5b 73 71 6c 69 74 65 33 5d 0a  r the [sqlite3].
0d00: 23 20 63 6f 6d 6d 61 6e 64 20 74 68 61 74 20 61  # command that a
0d10: 70 70 65 6e 64 73 20 22 2d 6b 65 79 20 7b 78 79  ppends "-key {xy
0d20: 7a 7a 79 7d 22 20 74 6f 20 74 68 65 20 63 6f 6d  zzy}" to the com
0d30: 6d 61 6e 64 20 6c 69 6e 65 2e 20 69 2e 65 2e 20  mand line. i.e. 
0d40: 74 68 69 73 3a 0a 23 0a 23 20 20 20 20 20 73 71  this:.#.#     sq
0d50: 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62  lite3 db test.db
0d60: 0a 23 0a 23 20 62 65 63 6f 6d 65 73 0a 23 0a 23  .#.# becomes.#.#
0d70: 20 20 20 20 20 73 71 6c 69 74 65 33 20 64 62 20       sqlite3 db 
0d80: 74 65 73 74 2e 64 62 20 2d 6b 65 79 20 7b 78 79  test.db -key {xy
0d90: 7a 7a 79 7d 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f  zzy}.#.if {[info
0da0: 20 63 6f 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f   command sqlite_
0db0: 6f 72 69 67 5d 3d 3d 22 22 7d 20 7b 0a 20 20 72  orig]==""} {.  r
0dc0: 65 6e 61 6d 65 20 73 71 6c 69 74 65 33 20 73 71  ename sqlite3 sq
0dd0: 6c 69 74 65 5f 6f 72 69 67 0a 20 20 70 72 6f 63  lite_orig.  proc
0de0: 20 73 71 6c 69 74 65 33 20 7b 61 72 67 73 7d 20   sqlite3 {args} 
0df0: 7b 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  {.    if {[lleng
0e00: 74 68 20 24 61 72 67 73 5d 3e 3d 32 20 26 26 20  th $args]>=2 && 
0e10: 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 5b 6c  [string index [l
0e20: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 20 30  index $args 0] 0
0e30: 5d 21 3d 22 2d 22 7d 20 7b 0a 20 20 20 20 20 20  ]!="-"} {.      
0e40: 23 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69  # This command i
0e50: 73 20 6f 70 65 6e 69 6e 67 20 61 20 6e 65 77 20  s opening a new 
0e60: 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  database connect
0e70: 69 6f 6e 2e 0a 20 20 20 20 20 20 23 0a 20 20 20  ion..      #.   
0e80: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
0e90: 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a 73 71 6c  sts ::G(perm:sql
0ea0: 69 74 65 33 5f 61 72 67 73 29 5d 7d 20 7b 0a 20  ite3_args)]} {. 
0eb0: 20 20 20 20 20 20 20 73 65 74 20 61 72 67 73 20         set args 
0ec0: 5b 63 6f 6e 63 61 74 20 24 61 72 67 73 20 24 3a  [concat $args $:
0ed0: 3a 47 28 70 65 72 6d 3a 73 71 6c 69 74 65 33 5f  :G(perm:sqlite3_
0ee0: 61 72 67 73 29 5d 0a 20 20 20 20 20 20 7d 0a 20  args)].      }. 
0ef0: 20 20 20 20 20 69 66 20 7b 5b 73 71 6c 69 74 65       if {[sqlite
0f00: 5f 6f 72 69 67 20 2d 68 61 73 2d 63 6f 64 65 63  _orig -has-codec
0f10: 5d 20 26 26 20 21 5b 69 6e 66 6f 20 65 78 69 73  ] && ![info exis
0f20: 74 73 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f  ts ::do_not_use_
0f30: 63 6f 64 65 63 5d 7d 20 7b 0a 20 20 20 20 20 20  codec]} {.      
0f40: 20 20 6c 61 70 70 65 6e 64 20 61 72 67 73 20 2d    lappend args -
0f50: 6b 65 79 20 7b 78 79 7a 7a 79 7d 0a 20 20 20 20  key {xyzzy}.    
0f60: 20 20 7d 0a 0a 20 20 20 20 20 20 73 65 74 20 72    }..      set r
0f70: 65 73 20 5b 75 70 6c 65 76 65 6c 20 31 20 73 71  es [uplevel 1 sq
0f80: 6c 69 74 65 5f 6f 72 69 67 20 24 61 72 67 73 5d  lite_orig $args]
0f90: 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f  .      if {[info
0fa0: 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72 6d   exists ::G(perm
0fb0: 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a 20 20 20  :presql)]} {.   
0fc0: 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 61 72       [lindex $ar
0fd0: 67 73 20 30 5d 20 65 76 61 6c 20 24 3a 3a 47 28  gs 0] eval $::G(
0fe0: 70 65 72 6d 3a 70 72 65 73 71 6c 29 0a 20 20 20  perm:presql).   
0ff0: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b     }.      if {[
1000: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
1010: 70 65 72 6d 3a 64 62 63 6f 6e 66 69 67 29 5d 7d  perm:dbconfig)]}
1020: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a   {.        set :
1030: 3a 64 62 68 61 6e 64 6c 65 20 5b 6c 69 6e 64 65  :dbhandle [linde
1040: 78 20 24 61 72 67 73 20 30 5d 0a 20 20 20 20 20  x $args 0].     
1050: 20 20 20 75 70 6c 65 76 65 6c 20 23 30 20 24 3a     uplevel #0 $:
1060: 3a 47 28 70 65 72 6d 3a 64 62 63 6f 6e 66 69 67  :G(perm:dbconfig
1070: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ).      }.      
1080: 73 65 74 20 72 65 73 0a 20 20 20 20 7d 20 65 6c  set res.    } el
1090: 73 65 20 7b 0a 20 20 20 20 20 20 23 20 54 68 69  se {.      # Thi
10a0: 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 6e 6f 74  s command is not
10b0: 20 6f 70 65 6e 69 6e 67 20 61 20 6e 65 77 20 64   opening a new d
10c0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
10d0: 6f 6e 2e 20 50 61 73 73 20 74 68 65 0a 20 20 20  on. Pass the.   
10e0: 20 20 20 23 20 61 72 67 75 6d 65 6e 74 73 20 74     # arguments t
10f0: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 43 20  hrough to the C 
1100: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 61  implementation a
1110: 73 20 74 68 65 20 61 72 65 2e 0a 20 20 20 20 20  s the are..     
1120: 20 23 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c   #.      uplevel
1130: 20 31 20 73 71 6c 69 74 65 5f 6f 72 69 67 20 24   1 sqlite_orig $
1140: 61 72 67 73 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d  args.    }.  }.}
1150: 0a 0a 70 72 6f 63 20 67 65 74 46 69 6c 65 52 65  ..proc getFileRe
1160: 74 72 69 65 73 20 7b 7d 20 7b 0a 20 20 69 66 20  tries {} {.  if 
1170: 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a  {![info exists :
1180: 3a 47 28 66 69 6c 65 2d 72 65 74 72 69 65 73 29  :G(file-retries)
1190: 5d 7d 20 7b 0a 20 20 20 20 23 0a 20 20 20 20 23  ]} {.    #.    #
11a0: 20 4e 4f 54 45 3a 20 52 65 74 75 72 6e 20 74 68   NOTE: Return th
11b0: 65 20 64 65 66 61 75 6c 74 20 6e 75 6d 62 65 72  e default number
11c0: 20 6f 66 20 72 65 74 72 69 65 73 20 66 6f 72 20   of retries for 
11d0: 5b 66 69 6c 65 5d 20 6f 70 65 72 61 74 69 6f 6e  [file] operation
11e0: 73 2e 20 20 41 0a 20 20 20 20 23 20 20 20 20 20  s.  A.    #     
11f0: 20 20 76 61 6c 75 65 20 6f 66 20 7a 65 72 6f 20    value of zero 
1200: 6f 72 20 6c 65 73 73 20 68 65 72 65 20 6d 65 61  or less here mea
1210: 6e 73 20 22 64 69 73 61 62 6c 65 64 22 2e 0a 20  ns "disabled".. 
1220: 20 20 20 23 0a 20 20 20 20 72 65 74 75 72 6e 20     #.    return 
1230: 5b 65 78 70 72 20 7b 24 3a 3a 74 63 6c 5f 70 6c  [expr {$::tcl_pl
1240: 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29  atform(platform)
1250: 20 65 71 20 22 77 69 6e 64 6f 77 73 22 20 3f 20   eq "windows" ? 
1260: 35 30 20 3a 20 30 7d 5d 0a 20 20 7d 0a 20 20 72  50 : 0}].  }.  r
1270: 65 74 75 72 6e 20 24 3a 3a 47 28 66 69 6c 65 2d  eturn $::G(file-
1280: 72 65 74 72 69 65 73 29 0a 7d 0a 0a 70 72 6f 63  retries).}..proc
1290: 20 67 65 74 46 69 6c 65 52 65 74 72 79 44 65 6c   getFileRetryDel
12a0: 61 79 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 21 5b  ay {} {.  if {![
12b0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
12c0: 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79  file-retry-delay
12d0: 29 5d 7d 20 7b 0a 20 20 20 20 23 0a 20 20 20 20  )]} {.    #.    
12e0: 23 20 4e 4f 54 45 3a 20 52 65 74 75 72 6e 20 74  # NOTE: Return t
12f0: 68 65 20 64 65 66 61 75 6c 74 20 6e 75 6d 62 65  he default numbe
1300: 72 20 6f 66 20 6d 69 6c 6c 69 73 65 63 6f 6e 64  r of millisecond
1310: 73 20 74 6f 20 77 61 69 74 20 77 68 65 6e 20 72  s to wait when r
1320: 65 74 72 79 69 6e 67 0a 20 20 20 20 23 20 20 20  etrying.    #   
1330: 20 20 20 20 66 61 69 6c 65 64 20 5b 66 69 6c 65      failed [file
1340: 5d 20 6f 70 65 72 61 74 69 6f 6e 73 2e 20 20 41  ] operations.  A
1350: 20 76 61 6c 75 65 20 6f 66 20 7a 65 72 6f 20 6f   value of zero o
1360: 72 20 6c 65 73 73 20 6d 65 61 6e 73 20 22 64 6f  r less means "do
1370: 20 6e 6f 74 0a 20 20 20 20 23 20 20 20 20 20 20   not.    #      
1380: 20 77 61 69 74 22 2e 0a 20 20 20 20 23 0a 20 20   wait"..    #.  
1390: 20 20 72 65 74 75 72 6e 20 31 30 30 3b 20 23 20    return 100; # 
13a0: 54 4f 44 4f 3a 20 47 6f 6f 64 20 64 65 66 61 75  TODO: Good defau
13b0: 6c 74 3f 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  lt?.  }.  return
13c0: 20 24 3a 3a 47 28 66 69 6c 65 2d 72 65 74 72 79   $::G(file-retry
13d0: 2d 64 65 6c 61 79 29 0a 7d 0a 0a 23 20 52 65 74  -delay).}..# Ret
13e0: 75 72 6e 20 74 68 65 20 73 74 72 69 6e 67 20 72  urn the string r
13f0: 65 70 72 65 73 65 6e 74 69 6e 67 20 74 68 65 20  epresenting the 
1400: 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 75 72 72  name of the curr
1410: 65 6e 74 20 64 69 72 65 63 74 6f 72 79 2e 20 20  ent directory.  
1420: 4f 6e 0a 23 20 57 69 6e 64 6f 77 73 2c 20 74 68  On.# Windows, th
1430: 65 20 72 65 73 75 6c 74 20 69 73 20 22 6e 6f 72  e result is "nor
1440: 6d 61 6c 69 7a 65 64 22 20 74 6f 20 77 68 61 74  malized" to what
1450: 65 76 65 72 20 6f 75 72 20 70 61 72 65 6e 74 20  ever our parent 
1460: 63 6f 6d 6d 61 6e 64 20 73 68 65 6c 6c 0a 23 20  command shell.# 
1470: 69 73 20 75 73 69 6e 67 20 74 6f 20 70 72 65 76  is using to prev
1480: 65 6e 74 20 63 61 73 65 2d 6d 69 73 6d 61 74 63  ent case-mismatc
1490: 68 20 69 73 73 75 65 73 2e 0a 23 0a 70 72 6f 63  h issues..#.proc
14a0: 20 67 65 74 5f 70 77 64 20 7b 7d 20 7b 0a 20 20   get_pwd {} {.  
14b0: 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  if {$::tcl_platf
14c0: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 20 65 71  orm(platform) eq
14d0: 20 22 77 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20   "windows"} {.  
14e0: 20 20 23 0a 20 20 20 20 23 20 4e 4f 54 45 3a 20    #.    # NOTE: 
14f0: 43 61 6e 6e 6f 74 20 75 73 65 20 5b 66 69 6c 65  Cannot use [file
1500: 20 6e 6f 72 6d 61 6c 69 7a 65 5d 20 68 65 72 65   normalize] here
1510: 20 62 65 63 61 75 73 65 20 69 74 20 77 6f 75 6c   because it woul
1520: 64 20 61 6c 74 65 72 20 74 68 65 0a 20 20 20 20  d alter the.    
1530: 23 20 20 20 20 20 20 20 63 61 73 65 20 6f 66 20  #       case of 
1540: 74 68 65 20 72 65 73 75 6c 74 20 74 6f 20 77 68  the result to wh
1550: 61 74 20 54 63 6c 20 63 6f 6e 73 69 64 65 72 73  at Tcl considers
1560: 20 63 61 6e 6f 6e 69 63 61 6c 2c 20 77 68 69 63   canonical, whic
1570: 68 20 77 6f 75 6c 64 0a 20 20 20 20 23 20 20 20  h would.    #   
1580: 20 20 20 20 64 65 66 65 61 74 20 74 68 65 20 70      defeat the p
1590: 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20 70  urpose of this p
15a0: 72 6f 63 65 64 75 72 65 2e 0a 20 20 20 20 23 0a  rocedure..    #.
15b0: 20 20 20 20 72 65 74 75 72 6e 20 5b 73 74 72 69      return [stri
15c0: 6e 67 20 6d 61 70 20 5b 6c 69 73 74 20 5c 5c 20  ng map [list \\ 
15d0: 2f 5d 20 5c 0a 20 20 20 20 20 20 20 20 5b 73 74  /] \.        [st
15e0: 72 69 6e 67 20 74 72 69 6d 20 5b 65 78 65 63 20  ring trim [exec 
15f0: 2d 2d 20 24 3a 3a 65 6e 76 28 43 6f 6d 53 70 65  -- $::env(ComSpe
1600: 63 29 20 2f 63 20 65 63 68 6f 20 25 43 44 25 5d  c) /c echo %CD%]
1610: 5d 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  ]].  } else {.  
1620: 20 20 72 65 74 75 72 6e 20 5b 70 77 64 5d 0a 20    return [pwd]. 
1630: 20 7d 0a 7d 0a 0a 23 20 43 6f 70 79 20 66 69 6c   }.}..# Copy fil
1640: 65 20 24 66 72 6f 6d 20 69 6e 74 6f 20 24 74 6f  e $from into $to
1650: 2e 20 54 68 69 73 20 69 73 20 75 73 65 64 20 62  . This is used b
1660: 65 63 61 75 73 65 20 73 6f 6d 65 20 76 65 72 73  ecause some vers
1670: 69 6f 6e 73 20 6f 66 0a 23 20 54 43 4c 20 66 6f  ions of.# TCL fo
1680: 72 20 77 69 6e 64 6f 77 73 20 28 6e 6f 74 61 62  r windows (notab
1690: 6c 79 20 74 68 65 20 38 2e 34 2e 31 20 62 69 6e  ly the 8.4.1 bin
16a0: 61 72 79 20 70 61 63 6b 61 67 65 20 73 68 69 70  ary package ship
16b0: 70 65 64 20 77 69 74 68 20 74 68 65 0a 23 20 63  ped with the.# c
16c0: 75 72 72 65 6e 74 20 6d 69 6e 67 77 20 72 65 6c  urrent mingw rel
16d0: 65 61 73 65 29 20 68 61 76 65 20 61 20 62 72 6f  ease) have a bro
16e0: 6b 65 6e 20 22 66 69 6c 65 20 63 6f 70 79 22 20  ken "file copy" 
16f0: 63 6f 6d 6d 61 6e 64 2e 0a 23 0a 70 72 6f 63 20  command..#.proc 
1700: 63 6f 70 79 5f 66 69 6c 65 20 7b 66 72 6f 6d 20  copy_file {from 
1710: 74 6f 7d 20 7b 0a 20 20 64 6f 5f 63 6f 70 79 5f  to} {.  do_copy_
1720: 66 69 6c 65 20 66 61 6c 73 65 20 24 66 72 6f 6d  file false $from
1730: 20 24 74 6f 0a 7d 0a 0a 70 72 6f 63 20 66 6f 72   $to.}..proc for
1740: 63 65 63 6f 70 79 20 7b 66 72 6f 6d 20 74 6f 7d  cecopy {from to}
1750: 20 7b 0a 20 20 64 6f 5f 63 6f 70 79 5f 66 69 6c   {.  do_copy_fil
1760: 65 20 74 72 75 65 20 24 66 72 6f 6d 20 24 74 6f  e true $from $to
1770: 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 63 6f 70 79  .}..proc do_copy
1780: 5f 66 69 6c 65 20 7b 66 6f 72 63 65 20 66 72 6f  _file {force fro
1790: 6d 20 74 6f 7d 20 7b 0a 20 20 73 65 74 20 6e 52  m to} {.  set nR
17a0: 65 74 72 79 20 5b 67 65 74 46 69 6c 65 52 65 74  etry [getFileRet
17b0: 72 69 65 73 5d 20 20 20 20 20 3b 23 20 4d 61 78  ries]     ;# Max
17c0: 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 72  imum number of r
17d0: 65 74 72 69 65 73 2e 0a 20 20 73 65 74 20 6e 44  etries..  set nD
17e0: 65 6c 61 79 20 5b 67 65 74 46 69 6c 65 52 65 74  elay [getFileRet
17f0: 72 79 44 65 6c 61 79 5d 20 20 3b 23 20 44 65 6c  ryDelay]  ;# Del
1800: 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72 65 20  ay in ms before 
1810: 72 65 74 72 79 69 6e 67 2e 0a 0a 20 20 23 20 4f  retrying...  # O
1820: 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74  n windows, somet
1830: 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 66 69 6c  imes even a [fil
1840: 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 5d 20 63  e copy -force] c
1850: 61 6e 20 66 61 69 6c 2e 20 54 68 65 20 63 61 75  an fail. The cau
1860: 73 65 20 69 73 0a 20 20 23 20 75 73 75 61 6c 6c  se is.  # usuall
1870: 79 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22 20 2d  y "tag-alongs" -
1880: 20 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65 20 61   programs like a
1890: 6e 74 69 2d 76 69 72 75 73 20 73 6f 66 74 77 61  nti-virus softwa
18a0: 72 65 2c 20 61 75 74 6f 6d 61 74 69 63 20 62 61  re, automatic ba
18b0: 63 6b 75 70 0a 20 20 23 20 74 6f 6f 6c 73 20 61  ckup.  # tools a
18c0: 6e 64 20 76 61 72 69 6f 75 73 20 65 78 70 6c 6f  nd various explo
18d0: 72 65 72 20 65 78 74 65 6e 73 69 6f 6e 73 20 74  rer extensions t
18e0: 68 61 74 20 6b 65 65 70 20 61 20 66 69 6c 65 20  hat keep a file 
18f0: 6f 70 65 6e 20 61 20 6c 69 74 74 6c 65 20 6c 6f  open a little lo
1900: 6e 67 65 72 0a 20 20 23 20 74 68 61 6e 20 77 65  nger.  # than we
1910: 20 65 78 70 65 63 74 2c 20 63 61 75 73 69 6e 67   expect, causing
1920: 20 74 68 65 20 64 65 6c 65 74 65 20 74 6f 20 66   the delete to f
1930: 61 69 6c 2e 0a 20 20 23 0a 20 20 23 20 54 68 65  ail..  #.  # The
1940: 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20   solution is to 
1950: 77 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f  wait a short amo
1960: 75 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f  unt of time befo
1970: 72 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 20  re retrying the 
1980: 63 6f 70 79 2e 0a 20 20 23 0a 20 20 69 66 20 7b  copy..  #.  if {
1990: 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b 0a 20  $nRetry > 0} {. 
19a0: 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d     for {set i 0}
19b0: 20 7b 24 69 3c 24 6e 52 65 74 72 79 7d 20 7b 69   {$i<$nRetry} {i
19c0: 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 73  ncr i} {.      s
19d0: 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 0a 20  et rc [catch {. 
19e0: 20 20 20 20 20 20 20 69 66 20 7b 24 66 6f 72 63         if {$forc
19f0: 65 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 66  e} {.          f
1a00: 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 20  ile copy -force 
1a10: 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20 20 20  $from $to.      
1a20: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
1a30: 20 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20 24       file copy $
1a40: 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20 20 20 20  from $to.       
1a50: 20 7d 0a 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a   }.      } msg].
1a60: 20 20 20 20 20 20 69 66 20 7b 24 72 63 3d 3d 30        if {$rc==0
1a70: 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 69 66  } break.      if
1a80: 20 7b 24 6e 44 65 6c 61 79 20 3e 20 30 7d 20 7b   {$nDelay > 0} {
1a90: 20 61 66 74 65 72 20 24 6e 44 65 6c 61 79 20 7d   after $nDelay }
1aa0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24  .    }.    if {$
1ab0: 72 63 7d 20 7b 20 65 72 72 6f 72 20 24 6d 73 67  rc} { error $msg
1ac0: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
1ad0: 20 20 69 66 20 7b 24 66 6f 72 63 65 7d 20 7b 0a    if {$force} {.
1ae0: 20 20 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20        file copy 
1af0: 2d 66 6f 72 63 65 20 24 66 72 6f 6d 20 24 74 6f  -force $from $to
1b00: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
1b10: 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20 24 66      file copy $f
1b20: 72 6f 6d 20 24 74 6f 0a 20 20 20 20 7d 0a 20 20  rom $to.    }.  
1b30: 7d 0a 7d 0a 0a 23 20 43 68 65 63 6b 20 69 66 20  }.}..# Check if 
1b40: 61 20 66 69 6c 65 20 6e 61 6d 65 20 69 73 20 72  a file name is r
1b50: 65 6c 61 74 69 76 65 0a 23 0a 70 72 6f 63 20 69  elative.#.proc i
1b60: 73 5f 72 65 6c 61 74 69 76 65 5f 66 69 6c 65 20  s_relative_file 
1b70: 7b 20 66 69 6c 65 20 7d 20 7b 0a 20 20 72 65 74  { file } {.  ret
1b80: 75 72 6e 20 5b 65 78 70 72 20 7b 5b 66 69 6c 65  urn [expr {[file
1b90: 20 70 61 74 68 74 79 70 65 20 24 66 69 6c 65 5d   pathtype $file]
1ba0: 20 21 3d 20 22 61 62 73 6f 6c 75 74 65 22 7d 5d   != "absolute"}]
1bb0: 0a 7d 0a 0a 23 20 49 66 20 74 68 65 20 56 46 53  .}..# If the VFS
1bc0: 20 73 75 70 70 6f 72 74 73 20 75 73 69 6e 67 20   supports using 
1bd0: 74 68 65 20 63 75 72 72 65 6e 74 20 64 69 72 65  the current dire
1be0: 63 74 6f 72 79 2c 20 72 65 74 75 72 6e 73 20 5b  ctory, returns [
1bf0: 70 77 64 5d 3b 0a 23 20 6f 74 68 65 72 77 69 73  pwd];.# otherwis
1c00: 65 2c 20 69 74 20 72 65 74 75 72 6e 73 20 6f 6e  e, it returns on
1c10: 6c 79 20 74 68 65 20 70 72 6f 76 69 64 65 64 20  ly the provided 
1c20: 73 75 66 66 69 78 20 73 74 72 69 6e 67 20 28 77  suffix string (w
1c30: 68 69 63 68 20 69 73 0a 23 20 65 6d 70 74 79 20  hich is.# empty 
1c40: 62 79 20 64 65 66 61 75 6c 74 29 2e 0a 23 0a 70  by default)..#.p
1c50: 72 6f 63 20 74 65 73 74 5f 70 77 64 20 7b 20 61  roc test_pwd { a
1c60: 72 67 73 20 7d 20 7b 0a 20 20 69 66 20 7b 5b 6c  rgs } {.  if {[l
1c70: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3e 20  length $args] > 
1c80: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 75 66  0} {.    set suf
1c90: 66 69 78 31 20 5b 6c 69 6e 64 65 78 20 24 61 72  fix1 [lindex $ar
1ca0: 67 73 20 30 5d 0a 20 20 20 20 69 66 20 7b 5b 6c  gs 0].    if {[l
1cb0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3e 20  length $args] > 
1cc0: 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 73  1} {.      set s
1cd0: 75 66 66 69 78 32 20 5b 6c 69 6e 64 65 78 20 24  uffix2 [lindex $
1ce0: 61 72 67 73 20 31 5d 0a 20 20 20 20 7d 20 65 6c  args 1].    } el
1cf0: 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20 73  se {.      set s
1d00: 75 66 66 69 78 32 20 24 73 75 66 66 69 78 31 0a  uffix2 $suffix1.
1d10: 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b      }.  } else {
1d20: 0a 20 20 20 20 73 65 74 20 73 75 66 66 69 78 31  .    set suffix1
1d30: 20 22 22 3b 20 73 65 74 20 73 75 66 66 69 78 32   ""; set suffix2
1d40: 20 22 22 0a 20 20 7d 0a 20 20 69 66 63 61 70 61   "".  }.  ifcapa
1d50: 62 6c 65 20 63 75 72 64 69 72 20 7b 0a 20 20 20  ble curdir {.   
1d60: 20 72 65 74 75 72 6e 20 22 5b 67 65 74 5f 70 77   return "[get_pw
1d70: 64 5d 24 73 75 66 66 69 78 31 22 0a 20 20 7d 20  d]$suffix1".  } 
1d80: 65 6c 73 65 20 7b 0a 20 20 20 20 72 65 74 75 72  else {.    retur
1d90: 6e 20 24 73 75 66 66 69 78 32 0a 20 20 7d 0a 7d  n $suffix2.  }.}
1da0: 0a 0a 23 20 44 65 6c 65 74 65 20 61 20 66 69 6c  ..# Delete a fil
1db0: 65 20 6f 72 20 64 69 72 65 63 74 6f 72 79 0a 23  e or directory.#
1dc0: 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f 66 69 6c  .proc delete_fil
1dd0: 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 64 6f 5f  e {args} {.  do_
1de0: 64 65 6c 65 74 65 5f 66 69 6c 65 20 66 61 6c 73  delete_file fals
1df0: 65 20 7b 2a 7d 24 61 72 67 73 0a 7d 0a 0a 70 72  e {*}$args.}..pr
1e00: 6f 63 20 66 6f 72 63 65 64 65 6c 65 74 65 20 7b  oc forcedelete {
1e10: 61 72 67 73 7d 20 7b 0a 20 20 64 6f 5f 64 65 6c  args} {.  do_del
1e20: 65 74 65 5f 66 69 6c 65 20 74 72 75 65 20 7b 2a  ete_file true {*
1e30: 7d 24 61 72 67 73 0a 7d 0a 0a 70 72 6f 63 20 64  }$args.}..proc d
1e40: 6f 5f 64 65 6c 65 74 65 5f 66 69 6c 65 20 7b 66  o_delete_file {f
1e50: 6f 72 63 65 20 61 72 67 73 7d 20 7b 0a 20 20 73  orce args} {.  s
1e60: 65 74 20 6e 52 65 74 72 79 20 5b 67 65 74 46 69  et nRetry [getFi
1e70: 6c 65 52 65 74 72 69 65 73 5d 20 20 20 20 20 3b  leRetries]     ;
1e80: 23 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72  # Maximum number
1e90: 20 6f 66 20 72 65 74 72 69 65 73 2e 0a 20 20 73   of retries..  s
1ea0: 65 74 20 6e 44 65 6c 61 79 20 5b 67 65 74 46 69  et nDelay [getFi
1eb0: 6c 65 52 65 74 72 79 44 65 6c 61 79 5d 20 20 3b  leRetryDelay]  ;
1ec0: 23 20 44 65 6c 61 79 20 69 6e 20 6d 73 20 62 65  # Delay in ms be
1ed0: 66 6f 72 65 20 72 65 74 72 79 69 6e 67 2e 0a 0a  fore retrying...
1ee0: 20 20 66 6f 72 65 61 63 68 20 66 69 6c 65 6e 61    foreach filena
1ef0: 6d 65 20 24 61 72 67 73 20 7b 0a 20 20 20 20 23  me $args {.    #
1f00: 20 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d   On windows, som
1f10: 65 74 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 66  etimes even a [f
1f20: 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63  ile delete -forc
1f30: 65 5d 20 63 61 6e 20 66 61 69 6c 20 6a 75 73 74  e] can fail just
1f40: 20 61 66 74 65 72 0a 20 20 20 20 23 20 61 20 66   after.    # a f
1f50: 69 6c 65 20 69 73 20 63 6c 6f 73 65 64 2e 20 54  ile is closed. T
1f60: 68 65 20 63 61 75 73 65 20 69 73 20 75 73 75 61  he cause is usua
1f70: 6c 6c 79 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22  lly "tag-alongs"
1f80: 20 2d 20 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65   - programs like
1f90: 0a 20 20 20 20 23 20 61 6e 74 69 2d 76 69 72 75  .    # anti-viru
1fa0: 73 20 73 6f 66 74 77 61 72 65 2c 20 61 75 74 6f  s software, auto
1fb0: 6d 61 74 69 63 20 62 61 63 6b 75 70 20 74 6f 6f  matic backup too
1fc0: 6c 73 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65  ls and various e
1fd0: 78 70 6c 6f 72 65 72 0a 20 20 20 20 23 20 65 78  xplorer.    # ex
1fe0: 74 65 6e 73 69 6f 6e 73 20 74 68 61 74 20 6b 65  tensions that ke
1ff0: 65 70 20 61 20 66 69 6c 65 20 6f 70 65 6e 20 61  ep a file open a
2000: 20 6c 69 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74   little longer t
2010: 68 61 6e 20 77 65 20 65 78 70 65 63 74 2c 20 63  han we expect, c
2020: 61 75 73 69 6e 67 0a 20 20 20 20 23 20 74 68 65  ausing.    # the
2030: 20 64 65 6c 65 74 65 20 74 6f 20 66 61 69 6c 2e   delete to fail.
2040: 0a 20 20 20 20 23 0a 20 20 20 20 23 20 54 68 65  .    #.    # The
2050: 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20   solution is to 
2060: 77 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f  wait a short amo
2070: 75 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f  unt of time befo
2080: 72 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 0a  re retrying the.
2090: 20 20 20 20 23 20 64 65 6c 65 74 65 2e 0a 20 20      # delete..  
20a0: 20 20 23 0a 20 20 20 20 69 66 20 7b 24 6e 52 65    #.    if {$nRe
20b0: 74 72 79 20 3e 20 30 7d 20 7b 0a 20 20 20 20 20  try > 0} {.     
20c0: 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b   for {set i 0} {
20d0: 24 69 3c 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63  $i<$nRetry} {inc
20e0: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  r i} {.        s
20f0: 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 0a 20  et rc [catch {. 
2100: 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 66 6f           if {$fo
2110: 72 63 65 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  rce} {.         
2120: 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d     file delete -
2130: 66 6f 72 63 65 20 24 66 69 6c 65 6e 61 6d 65 0a  force $filename.
2140: 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65            } else
2150: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66   {.            f
2160: 69 6c 65 20 64 65 6c 65 74 65 20 24 66 69 6c 65  ile delete $file
2170: 6e 61 6d 65 0a 20 20 20 20 20 20 20 20 20 20 7d  name.          }
2180: 0a 20 20 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a  .        } msg].
2190: 20 20 20 20 20 20 20 20 69 66 20 7b 24 72 63 3d          if {$rc=
21a0: 3d 30 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20  =0} break.      
21b0: 20 20 69 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20    if {$nDelay > 
21c0: 30 7d 20 7b 20 61 66 74 65 72 20 24 6e 44 65 6c  0} { after $nDel
21d0: 61 79 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20  ay }.      }.   
21e0: 20 20 20 69 66 20 7b 24 72 63 7d 20 7b 20 65 72     if {$rc} { er
21f0: 72 6f 72 20 24 6d 73 67 20 7d 0a 20 20 20 20 7d  ror $msg }.    }
2200: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 69 66   else {.      if
2210: 20 7b 24 66 6f 72 63 65 7d 20 7b 0a 20 20 20 20   {$force} {.    
2220: 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20      file delete 
2230: 2d 66 6f 72 63 65 20 24 66 69 6c 65 6e 61 6d 65  -force $filename
2240: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  .      } else {.
2250: 20 20 20 20 20 20 20 20 66 69 6c 65 20 64 65 6c          file del
2260: 65 74 65 20 24 66 69 6c 65 6e 61 6d 65 0a 20 20  ete $filename.  
2270: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
2280: 7d 0a 0a 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c  }..if {$::tcl_pl
2290: 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29  atform(platform)
22a0: 20 65 71 20 22 77 69 6e 64 6f 77 73 22 7d 20 7b   eq "windows"} {
22b0: 0a 20 20 70 72 6f 63 20 64 6f 5f 72 65 6d 6f 76  .  proc do_remov
22c0: 65 5f 77 69 6e 33 32 5f 64 69 72 20 7b 61 72 67  e_win32_dir {arg
22d0: 73 7d 20 7b 0a 20 20 20 20 73 65 74 20 6e 52 65  s} {.    set nRe
22e0: 74 72 79 20 5b 67 65 74 46 69 6c 65 52 65 74 72  try [getFileRetr
22f0: 69 65 73 5d 20 20 20 20 20 3b 23 20 4d 61 78 69  ies]     ;# Maxi
2300: 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 72 65  mum number of re
2310: 74 72 69 65 73 2e 0a 20 20 20 20 73 65 74 20 6e  tries..    set n
2320: 44 65 6c 61 79 20 5b 67 65 74 46 69 6c 65 52 65  Delay [getFileRe
2330: 74 72 79 44 65 6c 61 79 5d 20 20 3b 23 20 44 65  tryDelay]  ;# De
2340: 6c 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72 65  lay in ms before
2350: 20 72 65 74 72 79 69 6e 67 2e 0a 0a 20 20 20 20   retrying...    
2360: 66 6f 72 65 61 63 68 20 64 69 72 4e 61 6d 65 20  foreach dirName 
2370: 24 61 72 67 73 20 7b 0a 20 20 20 20 20 20 23 20  $args {.      # 
2380: 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65  On windows, some
2390: 74 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 72 65  times even a [re
23a0: 6d 6f 76 65 5f 77 69 6e 33 32 5f 64 69 72 5d 20  move_win32_dir] 
23b0: 63 61 6e 20 66 61 69 6c 20 6a 75 73 74 20 61 66  can fail just af
23c0: 74 65 72 0a 20 20 20 20 20 20 23 20 61 20 64 69  ter.      # a di
23d0: 72 65 63 74 6f 72 79 20 69 73 20 65 6d 70 74 69  rectory is empti
23e0: 65 64 2e 20 54 68 65 20 63 61 75 73 65 20 69 73  ed. The cause is
23f0: 20 75 73 75 61 6c 6c 79 20 22 74 61 67 2d 61 6c   usually "tag-al
2400: 6f 6e 67 73 22 20 2d 20 70 72 6f 67 72 61 6d 73  ongs" - programs
2410: 0a 20 20 20 20 20 20 23 20 6c 69 6b 65 20 61 6e  .      # like an
2420: 74 69 2d 76 69 72 75 73 20 73 6f 66 74 77 61 72  ti-virus softwar
2430: 65 2c 20 61 75 74 6f 6d 61 74 69 63 20 62 61 63  e, automatic bac
2440: 6b 75 70 20 74 6f 6f 6c 73 20 61 6e 64 20 76 61  kup tools and va
2450: 72 69 6f 75 73 20 65 78 70 6c 6f 72 65 72 0a 20  rious explorer. 
2460: 20 20 20 20 20 23 20 65 78 74 65 6e 73 69 6f 6e       # extension
2470: 73 20 74 68 61 74 20 6b 65 65 70 20 61 20 66 69  s that keep a fi
2480: 6c 65 20 6f 70 65 6e 20 61 20 6c 69 74 74 6c 65  le open a little
2490: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 77 65 20   longer than we 
24a0: 65 78 70 65 63 74 2c 0a 20 20 20 20 20 20 23 20  expect,.      # 
24b0: 63 61 75 73 69 6e 67 20 74 68 65 20 64 65 6c 65  causing the dele
24c0: 74 65 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20  te to fail..    
24d0: 20 20 23 0a 20 20 20 20 20 20 23 20 54 68 65 20    #.      # The 
24e0: 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20 77  solution is to w
24f0: 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f 75  ait a short amou
2500: 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f 72  nt of time befor
2510: 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 0a 20  e retrying the. 
2520: 20 20 20 20 20 23 20 72 65 6d 6f 76 61 6c 2e 0a       # removal..
2530: 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 69 66        #.      if
2540: 20 7b 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b   {$nRetry > 0} {
2550: 0a 20 20 20 20 20 20 20 20 66 6f 72 20 7b 73 65  .        for {se
2560: 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 52  t i 0} {$i < $nR
2570: 65 74 72 79 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  etry} {incr i} {
2580: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 72  .          set r
2590: 63 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 20  c [catch {.     
25a0: 20 20 20 20 20 20 20 72 65 6d 6f 76 65 5f 77 69         remove_wi
25b0: 6e 33 32 5f 64 69 72 20 24 64 69 72 4e 61 6d 65  n32_dir $dirName
25c0: 0a 20 20 20 20 20 20 20 20 20 20 7d 20 6d 73 67  .          } msg
25d0: 5d 0a 20 20 20 20 20 20 20 20 20 20 69 66 20 7b  ].          if {
25e0: 24 72 63 20 3d 3d 20 30 7d 20 62 72 65 61 6b 0a  $rc == 0} break.
25f0: 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 6e            if {$n
2600: 44 65 6c 61 79 20 3e 20 30 7d 20 7b 20 61 66 74  Delay > 0} { aft
2610: 65 72 20 24 6e 44 65 6c 61 79 20 7d 0a 20 20 20  er $nDelay }.   
2620: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
2630: 66 20 7b 24 72 63 7d 20 7b 20 65 72 72 6f 72 20  f {$rc} { error 
2640: 24 6d 73 67 20 7d 0a 20 20 20 20 20 20 7d 20 65  $msg }.      } e
2650: 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 72 65  lse {.        re
2660: 6d 6f 76 65 5f 77 69 6e 33 32 5f 64 69 72 20 24  move_win32_dir $
2670: 64 69 72 4e 61 6d 65 0a 20 20 20 20 20 20 7d 0a  dirName.      }.
2680: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 72 6f      }.  }..  pro
2690: 63 20 64 6f 5f 64 65 6c 65 74 65 5f 77 69 6e 33  c do_delete_win3
26a0: 32 5f 66 69 6c 65 20 7b 61 72 67 73 7d 20 7b 0a  2_file {args} {.
26b0: 20 20 20 20 73 65 74 20 6e 52 65 74 72 79 20 5b      set nRetry [
26c0: 67 65 74 46 69 6c 65 52 65 74 72 69 65 73 5d 20  getFileRetries] 
26d0: 20 20 20 20 3b 23 20 4d 61 78 69 6d 75 6d 20 6e      ;# Maximum n
26e0: 75 6d 62 65 72 20 6f 66 20 72 65 74 72 69 65 73  umber of retries
26f0: 2e 0a 20 20 20 20 73 65 74 20 6e 44 65 6c 61 79  ..    set nDelay
2700: 20 5b 67 65 74 46 69 6c 65 52 65 74 72 79 44 65   [getFileRetryDe
2710: 6c 61 79 5d 20 20 3b 23 20 44 65 6c 61 79 20 69  lay]  ;# Delay i
2720: 6e 20 6d 73 20 62 65 66 6f 72 65 20 72 65 74 72  n ms before retr
2730: 79 69 6e 67 2e 0a 0a 20 20 20 20 66 6f 72 65 61  ying...    forea
2740: 63 68 20 66 69 6c 65 4e 61 6d 65 20 24 61 72 67  ch fileName $arg
2750: 73 20 7b 0a 20 20 20 20 20 20 23 20 4f 6e 20 77  s {.      # On w
2760: 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74 69 6d 65  indows, sometime
2770: 73 20 65 76 65 6e 20 61 20 5b 64 65 6c 65 74 65  s even a [delete
2780: 5f 77 69 6e 33 32 5f 66 69 6c 65 5d 20 63 61 6e  _win32_file] can
2790: 20 66 61 69 6c 20 6a 75 73 74 20 61 66 74 65 72   fail just after
27a0: 0a 20 20 20 20 20 20 23 20 61 20 66 69 6c 65 20  .      # a file 
27b0: 69 73 20 63 6c 6f 73 65 64 2e 20 54 68 65 20 63  is closed. The c
27c0: 61 75 73 65 20 69 73 20 75 73 75 61 6c 6c 79 20  ause is usually 
27d0: 22 74 61 67 2d 61 6c 6f 6e 67 73 22 20 2d 20 70  "tag-alongs" - p
27e0: 72 6f 67 72 61 6d 73 20 6c 69 6b 65 0a 20 20 20  rograms like.   
27f0: 20 20 20 23 20 61 6e 74 69 2d 76 69 72 75 73 20     # anti-virus 
2800: 73 6f 66 74 77 61 72 65 2c 20 61 75 74 6f 6d 61  software, automa
2810: 74 69 63 20 62 61 63 6b 75 70 20 74 6f 6f 6c 73  tic backup tools
2820: 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65 78 70   and various exp
2830: 6c 6f 72 65 72 0a 20 20 20 20 20 20 23 20 65 78  lorer.      # ex
2840: 74 65 6e 73 69 6f 6e 73 20 74 68 61 74 20 6b 65  tensions that ke
2850: 65 70 20 61 20 66 69 6c 65 20 6f 70 65 6e 20 61  ep a file open a
2860: 20 6c 69 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74   little longer t
2870: 68 61 6e 20 77 65 20 65 78 70 65 63 74 2c 0a 20  han we expect,. 
2880: 20 20 20 20 20 23 20 63 61 75 73 69 6e 67 20 74       # causing t
2890: 68 65 20 64 65 6c 65 74 65 20 74 6f 20 66 61 69  he delete to fai
28a0: 6c 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20  l..      #.     
28b0: 20 23 20 54 68 65 20 73 6f 6c 75 74 69 6f 6e 20   # The solution 
28c0: 69 73 20 74 6f 20 77 61 69 74 20 61 20 73 68 6f  is to wait a sho
28d0: 72 74 20 61 6d 6f 75 6e 74 20 6f 66 20 74 69 6d  rt amount of tim
28e0: 65 20 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e  e before retryin
28f0: 67 20 74 68 65 0a 20 20 20 20 20 20 23 20 64 65  g the.      # de
2900: 6c 65 74 65 2e 0a 20 20 20 20 20 20 23 0a 20 20  lete..      #.  
2910: 20 20 20 20 69 66 20 7b 24 6e 52 65 74 72 79 20      if {$nRetry 
2920: 3e 20 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  > 0} {.        f
2930: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
2940: 20 3c 20 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63   < $nRetry} {inc
2950: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  r i} {.         
2960: 20 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b   set rc [catch {
2970: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 65 6c  .            del
2980: 65 74 65 5f 77 69 6e 33 32 5f 66 69 6c 65 20 24  ete_win32_file $
2990: 66 69 6c 65 4e 61 6d 65 0a 20 20 20 20 20 20 20  fileName.       
29a0: 20 20 20 7d 20 6d 73 67 5d 0a 20 20 20 20 20 20     } msg].      
29b0: 20 20 20 20 69 66 20 7b 24 72 63 20 3d 3d 20 30      if {$rc == 0
29c0: 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  } break.        
29d0: 20 20 69 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20    if {$nDelay > 
29e0: 30 7d 20 7b 20 61 66 74 65 72 20 24 6e 44 65 6c  0} { after $nDel
29f0: 61 79 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20  ay }.        }. 
2a00: 20 20 20 20 20 20 20 69 66 20 7b 24 72 63 7d 20         if {$rc} 
2a10: 7b 20 65 72 72 6f 72 20 24 6d 73 67 20 7d 0a 20  { error $msg }. 
2a20: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
2a30: 20 20 20 20 20 20 64 65 6c 65 74 65 5f 77 69 6e        delete_win
2a40: 33 32 5f 66 69 6c 65 20 24 66 69 6c 65 4e 61 6d  32_file $fileNam
2a50: 65 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  e.      }.    }.
2a60: 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78 65 63    }.}..proc exec
2a70: 70 72 65 73 71 6c 20 7b 68 61 6e 64 6c 65 20 61  presql {handle a
2a80: 72 67 73 7d 20 7b 0a 20 20 74 72 61 63 65 20 72  rgs} {.  trace r
2a90: 65 6d 6f 76 65 20 65 78 65 63 75 74 69 6f 6e 20  emove execution 
2aa0: 24 68 61 6e 64 6c 65 20 65 6e 74 65 72 20 5b 6c  $handle enter [l
2ab0: 69 73 74 20 65 78 65 63 70 72 65 73 71 6c 20 24  ist execpresql $
2ac0: 68 61 6e 64 6c 65 5d 0a 20 20 69 66 20 7b 5b 69  handle].  if {[i
2ad0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70  nfo exists ::G(p
2ae0: 65 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a  erm:presql)]} {.
2af0: 20 20 20 20 24 68 61 6e 64 6c 65 20 65 76 61 6c      $handle eval
2b00: 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71   $::G(perm:presq
2b10: 6c 29 0a 20 20 7d 0a 7d 0a 0a 23 20 54 68 69 73  l).  }.}..# This
2b20: 20 63 6f 6d 6d 61 6e 64 20 73 68 6f 75 6c 64 20   command should 
2b30: 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20  be called after 
2b40: 6c 6f 61 64 69 6e 67 20 74 65 73 74 65 72 2e 74  loading tester.t
2b50: 63 6c 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a 23  cl from within.#
2b60: 20 61 6c 6c 20 74 65 73 74 20 73 63 72 69 70 74   all test script
2b70: 73 20 74 68 61 74 20 61 72 65 20 69 6e 63 6f 6d  s that are incom
2b80: 70 61 74 69 62 6c 65 20 77 69 74 68 20 65 6e 63  patible with enc
2b90: 72 79 70 74 69 6f 6e 20 63 6f 64 65 63 73 2e 0a  ryption codecs..
2ba0: 23 0a 70 72 6f 63 20 64 6f 5f 6e 6f 74 5f 75 73  #.proc do_not_us
2bb0: 65 5f 63 6f 64 65 63 20 7b 7d 20 7b 0a 20 20 73  e_codec {} {.  s
2bc0: 65 74 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f  et ::do_not_use_
2bd0: 63 6f 64 65 63 20 31 0a 20 20 72 65 73 65 74 5f  codec 1.  reset_
2be0: 64 62 0a 7d 0a 75 6e 73 65 74 20 2d 6e 6f 63 6f  db.}.unset -noco
2bf0: 6d 70 6c 61 69 6e 20 64 6f 5f 6e 6f 74 5f 75 73  mplain do_not_us
2c00: 65 5f 63 6f 64 65 63 0a 0a 23 20 52 65 74 75 72  e_codec..# Retur
2c10: 6e 20 74 72 75 65 20 69 66 20 74 68 65 20 22 72  n true if the "r
2c20: 65 73 65 72 76 65 64 5f 62 79 74 65 73 22 20 69  eserved_bytes" i
2c30: 6e 74 65 67 65 72 20 6f 6e 20 64 61 74 61 62 61  nteger on databa
2c40: 73 65 20 66 69 6c 65 73 20 69 73 20 6e 6f 6e 2d  se files is non-
2c50: 7a 65 72 6f 2e 0a 23 0a 70 72 6f 63 20 6e 6f 6e  zero..#.proc non
2c60: 7a 65 72 6f 5f 72 65 73 65 72 76 65 64 5f 62 79  zero_reserved_by
2c70: 74 65 73 20 7b 7d 20 7b 0a 20 20 72 65 74 75 72  tes {} {.  retur
2c80: 6e 20 5b 73 71 6c 69 74 65 33 20 2d 68 61 73 2d  n [sqlite3 -has-
2c90: 63 6f 64 65 63 5d 0a 7d 0a 0a 23 20 50 72 69 6e  codec].}..# Prin
2ca0: 74 20 61 20 48 45 4c 50 20 6d 65 73 73 61 67 65  t a HELP message
2cb0: 20 61 6e 64 20 65 78 69 74 0a 23 0a 70 72 6f 63   and exit.#.proc
2cc0: 20 70 72 69 6e 74 5f 68 65 6c 70 5f 61 6e 64 5f   print_help_and_
2cd0: 71 75 69 74 20 7b 7d 20 7b 0a 20 20 70 75 74 73  quit {} {.  puts
2ce0: 20 7b 4f 70 74 69 6f 6e 73 3a 0a 20 20 2d 2d 70   {Options:.  --p
2cf0: 61 75 73 65 20 20 20 20 20 20 20 20 20 20 20 20  ause            
2d00: 20 20 20 20 20 20 57 61 69 74 20 66 6f 72 20 75        Wait for u
2d10: 73 65 72 20 69 6e 70 75 74 20 62 65 66 6f 72 65  ser input before
2d20: 20 63 6f 6e 74 69 6e 75 69 6e 67 0a 20 20 2d 2d   continuing.  --
2d30: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d  soft-heap-limit=
2d40: 4e 20 20 20 20 20 20 53 65 74 20 74 68 65 20 73  N      Set the s
2d50: 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 20 74  oft-heap-limit t
2d60: 6f 20 4e 0a 20 20 2d 2d 6d 61 78 65 72 72 6f 72  o N.  --maxerror
2d70: 3d 4e 20 20 20 20 20 20 20 20 20 20 20 20 20 51  =N             Q
2d80: 75 69 74 20 61 66 74 65 72 20 4e 20 65 72 72 6f  uit after N erro
2d90: 72 73 0a 20 20 2d 2d 76 65 72 62 6f 73 65 3d 28  rs.  --verbose=(
2da0: 30 7c 31 29 20 20 20 20 20 20 20 20 20 20 43 6f  0|1)          Co
2db0: 6e 74 72 6f 6c 20 74 68 65 20 61 6d 6f 75 6e 74  ntrol the amount
2dc0: 20 6f 66 20 6f 75 74 70 75 74 2e 20 20 44 65 66   of output.  Def
2dd0: 61 75 6c 74 20 27 31 27 0a 20 20 2d 2d 6f 75 74  ault '1'.  --out
2de0: 70 75 74 3d 46 49 4c 45 20 20 20 20 20 20 20 20  put=FILE        
2df0: 20 20 20 20 73 65 74 20 2d 2d 76 65 72 62 6f 73      set --verbos
2e00: 65 3d 32 20 61 6e 64 20 6f 75 74 70 75 74 20 74  e=2 and output t
2e10: 6f 20 46 49 4c 45 2e 20 20 49 6d 70 6c 69 65 73  o FILE.  Implies
2e20: 20 2d 71 0a 20 20 2d 71 20 20 20 20 20 20 20 20   -q.  -q        
2e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
2e40: 68 6f 72 74 68 61 6e 64 20 66 6f 72 20 2d 2d 76  horthand for --v
2e50: 65 72 62 6f 73 65 3d 30 0a 20 20 2d 2d 68 65 6c  erbose=0.  --hel
2e60: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p               
2e70: 20 20 20 20 54 68 69 73 20 6d 65 73 73 61 67 65      This message
2e80: 0a 7d 0a 20 20 65 78 69 74 20 31 0a 7d 0a 0a 23  .}.  exit 1.}..#
2e90: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62   The following b
2ea0: 6c 6f 63 6b 20 6f 6e 6c 79 20 72 75 6e 73 20 74  lock only runs t
2eb0: 68 65 20 66 69 72 73 74 20 74 69 6d 65 20 74 68  he first time th
2ec0: 69 73 20 66 69 6c 65 20 69 73 20 73 6f 75 72 63  is file is sourc
2ed0: 65 64 2e 20 49 74 0a 23 20 64 6f 65 73 20 6e 6f  ed. It.# does no
2ee0: 74 20 72 75 6e 20 69 6e 20 73 6c 61 76 65 20 69  t run in slave i
2ef0: 6e 74 65 72 70 72 65 74 65 72 73 20 28 73 69 6e  nterpreters (sin
2f00: 63 65 20 74 68 65 20 3a 3a 63 6d 64 6c 69 6e 65  ce the ::cmdline
2f10: 61 72 67 20 61 72 72 61 79 20 69 73 0a 23 20 70  arg array is.# p
2f20: 6f 70 75 6c 61 74 65 64 20 62 65 66 6f 72 65 20  opulated before 
2f30: 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 20  the test script 
2f40: 69 73 20 72 75 6e 20 69 6e 20 73 6c 61 76 65 20  is run in slave 
2f50: 69 6e 74 65 72 70 72 65 74 65 72 73 29 2e 0a 23  interpreters)..#
2f60: 0a 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74  .if {[info exist
2f70: 73 20 63 6d 64 6c 69 6e 65 61 72 67 5d 3d 3d 30  s cmdlinearg]==0
2f80: 7d 20 7b 0a 0a 20 20 23 20 50 61 72 73 65 20 61  } {..  # Parse a
2f90: 6e 79 20 6f 70 74 69 6f 6e 73 20 73 70 65 63 69  ny options speci
2fa0: 66 69 65 64 20 69 6e 20 74 68 65 20 24 61 72 67  fied in the $arg
2fb0: 76 20 61 72 72 61 79 2e 20 54 68 69 73 20 73 63  v array. This sc
2fc0: 72 69 70 74 20 61 63 63 65 70 74 73 20 74 68 65  ript accepts the
2fd0: 0a 20 20 23 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f  .  # following o
2fe0: 70 74 69 6f 6e 73 3a 0a 20 20 23 0a 20 20 23 20  ptions:.  #.  # 
2ff0: 20 20 2d 2d 70 61 75 73 65 0a 20 20 23 20 20 20    --pause.  #   
3000: 2d 2d 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69  --soft-heap-limi
3010: 74 3d 4e 4e 0a 20 20 23 20 20 20 2d 2d 6d 61 78  t=NN.  #   --max
3020: 65 72 72 6f 72 3d 4e 4e 0a 20 20 23 20 20 20 2d  error=NN.  #   -
3030: 2d 6d 61 6c 6c 6f 63 74 72 61 63 65 3d 4e 0a 20  -malloctrace=N. 
3040: 20 23 20 20 20 2d 2d 62 61 63 6b 74 72 61 63 65   #   --backtrace
3050: 3d 4e 0a 20 20 23 20 20 20 2d 2d 62 69 6e 61 72  =N.  #   --binar
3060: 79 6c 6f 67 3d 4e 0a 20 20 23 20 20 20 2d 2d 73  ylog=N.  #   --s
3070: 6f 61 6b 3d 4e 0a 20 20 23 20 20 20 2d 2d 66 69  oak=N.  #   --fi
3080: 6c 65 2d 72 65 74 72 69 65 73 3d 4e 0a 20 20 23  le-retries=N.  #
3090: 20 20 20 2d 2d 66 69 6c 65 2d 72 65 74 72 79 2d     --file-retry-
30a0: 64 65 6c 61 79 3d 4e 0a 20 20 23 20 20 20 2d 2d  delay=N.  #   --
30b0: 73 74 61 72 74 3d 5b 24 70 65 72 6d 75 74 61 74  start=[$permutat
30c0: 69 6f 6e 3a 5d 24 74 65 73 74 66 69 6c 65 0a 20  ion:]$testfile. 
30d0: 20 23 20 20 20 2d 2d 6d 61 74 63 68 3d 24 70 61   #   --match=$pa
30e0: 74 74 65 72 6e 0a 20 20 23 20 20 20 2d 2d 76 65  ttern.  #   --ve
30f0: 72 62 6f 73 65 3d 24 76 61 6c 0a 20 20 23 20 20  rbose=$val.  #  
3100: 20 2d 2d 6f 75 74 70 75 74 3d 24 66 69 6c 65 6e   --output=$filen
3110: 61 6d 65 0a 20 20 23 20 20 20 2d 71 20 20 20 20  ame.  #   -q    
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3140: 20 20 52 65 64 75 63 65 20 6f 75 74 70 75 74 0a    Reduce output.
3150: 20 20 23 20 20 20 2d 2d 74 65 73 74 64 69 72 3d    #   --testdir=
3160: 24 64 69 72 20 20 20 20 20 20 20 20 20 20 20 20  $dir            
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 52 75                Ru
3180: 6e 20 74 65 73 74 73 20 69 6e 20 73 75 62 64 69  n tests in subdi
3190: 72 65 63 74 6f 72 79 20 24 64 69 72 0a 20 20 23  rectory $dir.  #
31a0: 20 20 20 2d 2d 68 65 6c 70 0a 20 20 23 0a 20 20     --help.  #.  
31b0: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 73  set cmdlinearg(s
31c0: 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 29 20  oft-heap-limit) 
31d0: 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69     0.  set cmdli
31e0: 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29 20  nearg(maxerror) 
31f0: 20 20 20 20 20 20 20 31 30 30 30 0a 20 20 73 65         1000.  se
3200: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c  t cmdlinearg(mal
3210: 6c 6f 63 74 72 61 63 65 29 20 20 20 20 20 20 20  loctrace)       
3220: 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65   0.  set cmdline
3230: 61 72 67 28 62 61 63 6b 74 72 61 63 65 29 20 20  arg(backtrace)  
3240: 20 20 20 20 20 20 20 31 30 0a 20 20 73 65 74 20         10.  set 
3250: 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72  cmdlinearg(binar
3260: 79 6c 6f 67 29 20 20 20 20 20 20 20 20 20 20 30  ylog)          0
3270: 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72  .  set cmdlinear
3280: 67 28 73 6f 61 6b 29 20 20 20 20 20 20 20 20 20  g(soak)         
3290: 20 20 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d        0.  set cm
32a0: 64 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65  dlinearg(file-re
32b0: 74 72 69 65 73 29 20 20 20 20 20 20 20 30 0a 20  tries)       0. 
32c0: 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28   set cmdlinearg(
32d0: 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79  file-retry-delay
32e0: 29 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c  )   0.  set cmdl
32f0: 69 6e 65 61 72 67 28 73 74 61 72 74 29 20 20 20  inearg(start)   
3300: 20 20 20 20 20 20 20 20 20 20 22 22 0a 20 20 73            "".  s
3310: 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61  et cmdlinearg(ma
3320: 74 63 68 29 20 20 20 20 20 20 20 20 20 20 20 20  tch)            
3330: 20 22 22 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e   "".  set cmdlin
3340: 65 61 72 67 28 76 65 72 62 6f 73 65 29 20 20 20  earg(verbose)   
3350: 20 20 20 20 20 20 20 20 22 22 0a 20 20 73 65 74          "".  set
3360: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75 74 70   cmdlinearg(outp
3370: 75 74 29 20 20 20 20 20 20 20 20 20 20 20 20 22  ut)            "
3380: 22 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61  ".  set cmdlinea
3390: 72 67 28 74 65 73 74 64 69 72 29 20 20 20 20 20  rg(testdir)     
33a0: 20 20 20 20 20 20 22 74 65 73 74 64 69 72 22 0a        "testdir".
33b0: 0a 20 20 73 65 74 20 6c 65 66 74 6f 76 65 72 20  .  set leftover 
33c0: 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68  [list].  foreach
33d0: 20 61 20 24 61 72 67 76 20 7b 0a 20 20 20 20 73   a $argv {.    s
33e0: 77 69 74 63 68 20 2d 72 65 67 65 78 70 20 2d 2d  witch -regexp --
33f0: 20 24 61 20 7b 0a 20 20 20 20 20 20 7b 5e 2d 2b   $a {.      {^-+
3400: 70 61 75 73 65 24 7d 20 7b 0a 20 20 20 20 20 20  pause$} {.      
3410: 20 20 23 20 57 61 69 74 20 66 6f 72 20 75 73 65    # Wait for use
3420: 72 20 69 6e 70 75 74 20 62 65 66 6f 72 65 20 63  r input before c
3430: 6f 6e 74 69 6e 75 69 6e 67 2e 20 54 68 69 73 20  ontinuing. This 
3440: 69 73 20 74 6f 20 67 69 76 65 20 74 68 65 20 75  is to give the u
3450: 73 65 72 20 61 6e 0a 20 20 20 20 20 20 20 20 23  ser an.        #
3460: 20 6f 70 70 6f 72 74 75 6e 69 74 79 20 74 6f 20   opportunity to 
3470: 63 6f 6e 6e 65 63 74 20 70 72 6f 66 69 6c 69 6e  connect profilin
3480: 67 20 74 6f 6f 6c 73 20 74 6f 20 74 68 65 20 70  g tools to the p
3490: 72 6f 63 65 73 73 2e 0a 20 20 20 20 20 20 20 20  rocess..        
34a0: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
34b0: 22 50 72 65 73 73 20 52 45 54 55 52 4e 20 74 6f  "Press RETURN to
34c0: 20 62 65 67 69 6e 2e 2e 2e 22 0a 20 20 20 20 20   begin...".     
34d0: 20 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a     flush stdout.
34e0: 20 20 20 20 20 20 20 20 67 65 74 73 20 73 74 64          gets std
34f0: 69 6e 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  in.      }.     
3500: 20 7b 5e 2d 2b 73 6f 66 74 2d 68 65 61 70 2d 6c   {^-+soft-heap-l
3510: 69 6d 69 74 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20  imit=.+$} {.    
3520: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d      foreach {dum
3530: 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f  my cmdlinearg(so
3540: 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 29 7d 20  ft-heap-limit)} 
3550: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
3560: 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  ak.      }.     
3570: 20 7b 5e 2d 2b 6d 61 78 65 72 72 6f 72 3d 2e 2b   {^-+maxerror=.+
3580: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
3590: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
35a0: 69 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29  inearg(maxerror)
35b0: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
35c0: 72 65 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20  reak.      }.   
35d0: 20 20 20 7b 5e 2d 2b 6d 61 6c 6c 6f 63 74 72 61     {^-+malloctra
35e0: 63 65 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  ce=.+$} {.      
35f0: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
3600: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c 6c   cmdlinearg(mall
3610: 6f 63 74 72 61 63 65 29 7d 20 5b 73 70 6c 69 74  octrace)} [split
3620: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20   $a =] break.   
3630: 20 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e       if {$cmdlin
3640: 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65  earg(malloctrace
3650: 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73  )} {.          s
3660: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
3670: 6c 6f 67 20 73 74 61 72 74 0a 20 20 20 20 20 20  log start.      
3680: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
3690: 20 20 7b 5e 2d 2b 62 61 63 6b 74 72 61 63 65 3d    {^-+backtrace=
36a0: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
36b0: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
36c0: 64 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61  dlinearg(backtra
36d0: 63 65 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ce)} [split $a =
36e0: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
36f0: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
3700: 5f 62 61 63 6b 74 72 61 63 65 20 24 63 6d 64 6c  _backtrace $cmdl
3710: 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61 63 65  inearg(backtrace
3720: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ).      }.      
3730: 7b 5e 2d 2b 62 69 6e 61 72 79 6c 6f 67 3d 2e 2b  {^-+binarylog=.+
3740: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
3750: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
3760: 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f 67  inearg(binarylog
3770: 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20  )} [split $a =] 
3780: 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 73 65  break.        se
3790: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e  t cmdlinearg(bin
37a0: 61 72 79 6c 6f 67 29 20 5b 66 69 6c 65 20 6e 6f  arylog) [file no
37b0: 72 6d 61 6c 69 7a 65 20 24 63 6d 64 6c 69 6e 65  rmalize $cmdline
37c0: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 5d 0a  arg(binarylog)].
37d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
37e0: 2d 2b 73 6f 61 6b 3d 2e 2b 24 7d 20 7b 0a 20 20  -+soak=.+$} {.  
37f0: 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64        foreach {d
3800: 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28  ummy cmdlinearg(
3810: 73 6f 61 6b 29 7d 20 5b 73 70 6c 69 74 20 24 61  soak)} [split $a
3820: 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20   =] break.      
3830: 20 20 73 65 74 20 3a 3a 47 28 69 73 73 6f 61 6b    set ::G(issoak
3840: 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f  ) $cmdlinearg(so
3850: 61 6b 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak).      }.    
3860: 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74 72 69    {^-+file-retri
3870: 65 73 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  es=.+$} {.      
3880: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
3890: 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c 65   cmdlinearg(file
38a0: 2d 72 65 74 72 69 65 73 29 7d 20 5b 73 70 6c 69  -retries)} [spli
38b0: 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20  t $a =] break.  
38c0: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 66 69        set ::G(fi
38d0: 6c 65 2d 72 65 74 72 69 65 73 29 20 24 63 6d 64  le-retries) $cmd
38e0: 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74  linearg(file-ret
38f0: 72 69 65 73 29 0a 20 20 20 20 20 20 7d 0a 20 20  ries).      }.  
3900: 20 20 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74      {^-+file-ret
3910: 72 79 2d 64 65 6c 61 79 3d 2e 2b 24 7d 20 7b 0a  ry-delay=.+$} {.
3920: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
3930: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
3940: 67 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c  g(file-retry-del
3950: 61 79 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ay)} [split $a =
3960: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
3970: 73 65 74 20 3a 3a 47 28 66 69 6c 65 2d 72 65 74  set ::G(file-ret
3980: 72 79 2d 64 65 6c 61 79 29 20 24 63 6d 64 6c 69  ry-delay) $cmdli
3990: 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72 79  nearg(file-retry
39a0: 2d 64 65 6c 61 79 29 0a 20 20 20 20 20 20 7d 0a  -delay).      }.
39b0: 20 20 20 20 20 20 7b 5e 2d 2b 73 74 61 72 74 3d        {^-+start=
39c0: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
39d0: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
39e0: 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29 7d  dlinearg(start)}
39f0: 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72   [split $a =] br
3a00: 65 61 6b 0a 0a 20 20 20 20 20 20 20 20 73 65 74  eak..        set
3a10: 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29   ::G(start:file)
3a20: 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 74 61   $cmdlinearg(sta
3a30: 72 74 29 0a 20 20 20 20 20 20 20 20 69 66 20 7b  rt).        if {
3a40: 5b 72 65 67 65 78 70 20 7b 28 2e 2a 29 3a 28 2e  [regexp {(.*):(.
3a50: 2a 29 7d 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  *)} $cmdlinearg(
3a60: 73 74 61 72 74 29 20 2d 3e 20 73 2e 70 65 72 6d  start) -> s.perm
3a70: 20 73 2e 66 69 6c 65 5d 7d 20 7b 0a 20 20 20 20   s.file]} {.    
3a80: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74        set ::G(st
3a90: 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29  art:permutation)
3aa0: 20 24 7b 73 2e 70 65 72 6d 7d 0a 20 20 20 20 20   ${s.perm}.     
3ab0: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74 61       set ::G(sta
3ac0: 72 74 3a 66 69 6c 65 29 20 20 20 20 20 20 20 20  rt:file)        
3ad0: 24 7b 73 2e 66 69 6c 65 7d 0a 20 20 20 20 20 20  ${s.file}.      
3ae0: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 20 7b    }.        if {
3af0: 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29  $::G(start:file)
3b00: 20 3d 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a   == ""} {unset :
3b10: 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 7d 0a  :G(start:file)}.
3b20: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
3b30: 2d 2b 6d 61 74 63 68 3d 2e 2b 24 7d 20 7b 0a 20  -+match=.+$} {. 
3b40: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
3b50: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
3b60: 28 6d 61 74 63 68 29 7d 20 5b 73 70 6c 69 74 20  (match)} [split 
3b70: 24 61 20 3d 5d 20 62 72 65 61 6b 0a 0a 20 20 20  $a =] break..   
3b80: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 6d 61 74       set ::G(mat
3b90: 63 68 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  ch) $cmdlinearg(
3ba0: 6d 61 74 63 68 29 0a 20 20 20 20 20 20 20 20 69  match).        i
3bb0: 66 20 7b 24 3a 3a 47 28 6d 61 74 63 68 29 20 3d  f {$::G(match) =
3bc0: 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a 3a 47  = ""} {unset ::G
3bd0: 28 6d 61 74 63 68 29 7d 0a 20 20 20 20 20 20 7d  (match)}.      }
3be0: 0a 0a 20 20 20 20 20 20 7b 5e 2d 2b 6f 75 74 70  ..      {^-+outp
3bf0: 75 74 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  ut=.+$} {.      
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 6f 75 74 70   cmdlinearg(outp
3c20: 75 74 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ut)} [split $a =
3c30: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
3c40: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 6f  set cmdlinearg(o
3c50: 75 74 70 75 74 29 20 5b 66 69 6c 65 20 6e 6f 72  utput) [file nor
3c60: 6d 61 6c 69 7a 65 20 24 63 6d 64 6c 69 6e 65 61  malize $cmdlinea
3c70: 72 67 28 6f 75 74 70 75 74 29 5d 0a 20 20 20 20  rg(output)].    
3c80: 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65      if {$cmdline
3c90: 61 72 67 28 76 65 72 62 6f 73 65 29 3d 3d 22 22  arg(verbose)==""
3ca0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65  } {.          se
3cb0: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 76 65 72  t cmdlinearg(ver
3cc0: 62 6f 73 65 29 20 32 0a 20 20 20 20 20 20 20 20  bose) 2.        
3cd0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
3ce0: 7b 5e 2d 2b 76 65 72 62 6f 73 65 3d 2e 2b 24 7d  {^-+verbose=.+$}
3cf0: 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61   {.        forea
3d00: 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e  ch {dummy cmdlin
3d10: 65 61 72 67 28 76 65 72 62 6f 73 65 29 7d 20 5b  earg(verbose)} [
3d20: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
3d30: 6b 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 63  k.        if {$c
3d40: 6d 64 6c 69 6e 65 61 72 67 28 76 65 72 62 6f 73  mdlinearg(verbos
3d50: 65 29 3d 3d 22 66 69 6c 65 22 7d 20 7b 0a 20 20  e)=="file"} {.  
3d60: 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64 6c          set cmdl
3d70: 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 20  inearg(verbose) 
3d80: 32 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65  2.        } else
3d90: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 73 20 62  if {[string is b
3da0: 6f 6f 6c 65 61 6e 20 2d 73 74 72 69 63 74 20 24  oolean -strict $
3db0: 63 6d 64 6c 69 6e 65 61 72 67 28 76 65 72 62 6f  cmdlinearg(verbo
3dc0: 73 65 29 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 20  se)]==0} {.     
3dd0: 20 20 20 20 20 65 72 72 6f 72 20 22 6f 70 74 69       error "opti
3de0: 6f 6e 20 2d 2d 76 65 72 62 6f 73 65 3d 20 6d 75  on --verbose= mu
3df0: 73 74 20 62 65 20 73 65 74 20 74 6f 20 61 20 62  st be set to a b
3e00: 6f 6f 6c 65 61 6e 20 6f 72 20 74 6f 20 5c 22 66  oolean or to \"f
3e10: 69 6c 65 5c 22 22 0a 20 20 20 20 20 20 20 20 7d  ile\"".        }
3e20: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
3e30: 5e 2d 2b 74 65 73 74 64 69 72 3d 2e 2a 24 7d 20  ^-+testdir=.*$} 
3e40: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
3e50: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
3e60: 61 72 67 28 74 65 73 74 64 69 72 29 7d 20 5b 73  arg(testdir)} [s
3e70: 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b  plit $a =] break
3e80: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
3e90: 2e 2a 68 65 6c 70 2e 2a 7d 20 7b 0a 20 20 20 20  .*help.*} {.    
3ea0: 20 20 20 20 20 70 72 69 6e 74 5f 68 65 6c 70 5f       print_help_
3eb0: 61 6e 64 5f 71 75 69 74 0a 20 20 20 20 20 20 7d  and_quit.      }
3ec0: 0a 20 20 20 20 20 20 7b 5e 2d 71 24 7d 20 7b 0a  .      {^-q$} {.
3ed0: 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64 6c          set cmdl
3ee0: 69 6e 65 61 72 67 28 6f 75 74 70 75 74 29 20 74  inearg(output) t
3ef0: 65 73 74 2d 6f 75 74 2e 74 78 74 0a 20 20 20 20  est-out.txt.    
3f00: 20 20 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61      set cmdlinea
3f10: 72 67 28 76 65 72 62 6f 73 65 29 20 32 0a 20 20  rg(verbose) 2.  
3f20: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66      }..      def
3f30: 61 75 6c 74 20 7b 0a 20 20 20 20 20 20 20 20 69  ault {.        i
3f40: 66 20 7b 5b 66 69 6c 65 20 74 61 69 6c 20 24 61  f {[file tail $a
3f50: 5d 3d 3d 24 61 7d 20 7b 0a 20 20 20 20 20 20 20  ]==$a} {.       
3f60: 20 20 20 6c 61 70 70 65 6e 64 20 6c 65 66 74 6f     lappend lefto
3f70: 76 65 72 20 24 61 0a 20 20 20 20 20 20 20 20 7d  ver $a.        }
3f80: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
3f90: 20 20 6c 61 70 70 65 6e 64 20 6c 65 66 74 6f 76    lappend leftov
3fa0: 65 72 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69  er [file normali
3fb0: 7a 65 20 24 61 5d 0a 20 20 20 20 20 20 20 20 7d  ze $a].        }
3fc0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3fd0: 20 7d 0a 20 20 73 65 74 20 74 65 73 74 64 69 72   }.  set testdir
3fe0: 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65   [file normalize
3ff0: 20 24 74 65 73 74 64 69 72 5d 0a 20 20 73 65 74   $testdir].  set
4000: 20 63 6d 64 6c 69 6e 65 61 72 67 28 54 45 53 54   cmdlinearg(TEST
4010: 46 49 58 54 55 52 45 5f 48 4f 4d 45 29 20 5b 70  FIXTURE_HOME) [p
4020: 77 64 5d 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e  wd].  set cmdlin
4030: 65 61 72 67 28 49 4e 46 4f 5f 53 43 52 49 50 54  earg(INFO_SCRIPT
4040: 29 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a  ) [file normaliz
4050: 65 20 5b 69 6e 66 6f 20 73 63 72 69 70 74 5d 5d  e [info script]]
4060: 0a 20 20 73 65 74 20 61 72 67 76 30 20 5b 66 69  .  set argv0 [fi
4070: 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 24 61 72  le normalize $ar
4080: 67 76 30 5d 0a 20 20 69 66 20 7b 24 63 6d 64 6c  gv0].  if {$cmdl
4090: 69 6e 65 61 72 67 28 74 65 73 74 64 69 72 29 21  inearg(testdir)!
40a0: 3d 22 22 7d 20 7b 0a 20 20 20 20 66 69 6c 65 20  =""} {.    file 
40b0: 6d 6b 64 69 72 20 24 63 6d 64 6c 69 6e 65 61 72  mkdir $cmdlinear
40c0: 67 28 74 65 73 74 64 69 72 29 0a 20 20 20 20 63  g(testdir).    c
40d0: 64 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 74 65  d $cmdlinearg(te
40e0: 73 74 64 69 72 29 0a 20 20 7d 0a 20 20 73 65 74  stdir).  }.  set
40f0: 20 61 72 67 76 20 24 6c 65 66 74 6f 76 65 72 0a   argv $leftover.
4100: 0a 20 20 23 20 49 6e 73 74 61 6c 6c 20 74 68 65  .  # Install the
4110: 20 6d 61 6c 6c 6f 63 20 6c 61 79 65 72 20 75 73   malloc layer us
4120: 65 64 20 74 6f 20 69 6e 6a 65 63 74 20 4f 4f 4d  ed to inject OOM
4130: 20 65 72 72 6f 72 73 2e 20 41 6e 64 20 74 68 65   errors. And the
4140: 20 27 61 75 74 6f 6d 61 74 69 63 27 0a 20 20 23   'automatic'.  #
4150: 20 65 78 74 65 6e 73 69 6f 6e 73 2e 20 54 68 69   extensions. Thi
4160: 73 20 6f 6e 6c 79 20 6e 65 65 64 73 20 74 6f 20  s only needs to 
4170: 62 65 20 64 6f 6e 65 20 6f 6e 63 65 20 66 6f 72  be done once for
4180: 20 74 68 65 20 70 72 6f 63 65 73 73 2e 0a 20 20   the process..  
4190: 23 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  #.  sqlite3_shut
41a0: 64 6f 77 6e 0a 20 20 69 6e 73 74 61 6c 6c 5f 6d  down.  install_m
41b0: 61 6c 6c 6f 63 5f 66 61 75 6c 74 73 69 6d 20 31  alloc_faultsim 1
41c0: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69  .  sqlite3_initi
41d0: 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74  alize.  autoinst
41e0: 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f  all_test_functio
41f0: 6e 73 0a 0a 20 20 23 20 49 66 20 74 68 65 20 2d  ns..  # If the -
4200: 2d 62 69 6e 61 72 79 6c 6f 67 20 6f 70 74 69 6f  -binarylog optio
4210: 6e 20 77 61 73 20 73 70 65 63 69 66 69 65 64 2c  n was specified,
4220: 20 63 72 65 61 74 65 20 74 68 65 20 6c 6f 67 67   create the logg
4230: 69 6e 67 20 56 46 53 2e 20 54 68 69 73 0a 20 20  ing VFS. This.  
4240: 23 20 63 61 6c 6c 20 69 6e 73 74 61 6c 6c 73 20  # call installs 
4250: 74 68 65 20 6e 65 77 20 56 46 53 20 61 73 20 74  the new VFS as t
4260: 68 65 20 64 65 66 61 75 6c 74 20 66 6f 72 20 61  he default for a
4270: 6c 6c 20 53 51 4c 69 74 65 20 63 6f 6e 6e 65 63  ll SQLite connec
4280: 74 69 6f 6e 73 2e 0a 20 20 23 0a 20 20 69 66 20  tions..  #.  if 
4290: 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e  {$cmdlinearg(bin
42a0: 61 72 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76  arylog)} {.    v
42b0: 66 73 6c 6f 67 20 6e 65 77 20 62 69 6e 61 72 79  fslog new binary
42c0: 6c 6f 67 20 7b 7d 20 76 66 73 6c 6f 67 2e 62 69  log {} vfslog.bi
42d0: 6e 0a 20 20 7d 0a 0a 20 20 23 20 53 65 74 20 74  n.  }..  # Set t
42e0: 68 65 20 62 61 63 6b 74 72 61 63 65 20 64 65 70  he backtrace dep
42f0: 74 68 2c 20 69 66 20 6d 61 6c 6c 6f 63 20 74 72  th, if malloc tr
4300: 61 63 69 6e 67 20 69 73 20 65 6e 61 62 6c 65 64  acing is enabled
4310: 2e 0a 20 20 23 0a 20 20 69 66 20 7b 24 63 6d 64  ..  #.  if {$cmd
4320: 6c 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72  linearg(malloctr
4330: 61 63 65 29 7d 20 7b 0a 20 20 20 20 73 71 6c 69  ace)} {.    sqli
4340: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63  te3_memdebug_bac
4350: 6b 74 72 61 63 65 20 24 63 6d 64 6c 69 6e 65 61  ktrace $cmdlinea
4360: 72 67 28 62 61 63 6b 74 72 61 63 65 29 0a 20 20  rg(backtrace).  
4370: 7d 0a 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e  }..  if {$cmdlin
4380: 65 61 72 67 28 6f 75 74 70 75 74 29 21 3d 22 22  earg(output)!=""
4390: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 43 6f  } {.    puts "Co
43a0: 70 79 69 6e 67 20 6f 75 74 70 75 74 20 74 6f 20  pying output to 
43b0: 66 69 6c 65 20 24 63 6d 64 6c 69 6e 65 61 72 67  file $cmdlinearg
43c0: 28 6f 75 74 70 75 74 29 22 0a 20 20 20 20 73 65  (output)".    se
43d0: 74 20 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29  t ::G(output_fd)
43e0: 20 5b 6f 70 65 6e 20 24 63 6d 64 6c 69 6e 65 61   [open $cmdlinea
43f0: 72 67 28 6f 75 74 70 75 74 29 20 77 5d 0a 20 20  rg(output) w].  
4400: 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 3a 3a    fconfigure $::
4410: 47 28 6f 75 74 70 75 74 5f 66 64 29 20 2d 62 75  G(output_fd) -bu
4420: 66 66 65 72 69 6e 67 20 6c 69 6e 65 0a 20 20 7d  ffering line.  }
4430: 0a 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65  ..  if {$cmdline
4440: 61 72 67 28 76 65 72 62 6f 73 65 29 3d 3d 22 22  arg(verbose)==""
4450: 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6d 64 6c  } {.    set cmdl
4460: 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 20  inearg(verbose) 
4470: 31 0a 20 20 7d 0a 7d 0a 0a 23 20 55 70 64 61 74  1.  }.}..# Updat
4480: 65 20 74 68 65 20 73 6f 66 74 2d 68 65 61 70 2d  e the soft-heap-
4490: 6c 69 6d 69 74 20 65 61 63 68 20 74 69 6d 65 20  limit each time 
44a0: 74 68 69 73 20 73 63 72 69 70 74 20 69 73 20 72  this script is r
44b0: 75 6e 2e 20 49 6e 20 74 68 61 74 0a 23 20 77 61  un. In that.# wa
44c0: 79 20 69 66 20 61 6e 20 69 6e 64 69 76 69 64 75  y if an individu
44d0: 61 6c 20 74 65 73 74 20 66 69 6c 65 20 63 68 61  al test file cha
44e0: 6e 67 65 73 20 74 68 65 20 73 6f 66 74 2d 68 65  nges the soft-he
44f0: 61 70 2d 6c 69 6d 69 74 2c 20 69 74 0a 23 20 77  ap-limit, it.# w
4500: 69 6c 6c 20 62 65 20 72 65 73 65 74 20 61 74 20  ill be reset at 
4510: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
4520: 20 6e 65 78 74 20 74 65 73 74 20 66 69 6c 65 2e   next test file.
4530: 0a 23 0a 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f  .#.sqlite3_soft_
4540: 68 65 61 70 5f 6c 69 6d 69 74 20 24 63 6d 64 6c  heap_limit $cmdl
4550: 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65 61 70  inearg(soft-heap
4560: 2d 6c 69 6d 69 74 29 0a 0a 23 20 43 72 65 61 74  -limit)..# Creat
4570: 65 20 61 20 74 65 73 74 20 64 61 74 61 62 61 73  e a test databas
4580: 65 0a 23 0a 70 72 6f 63 20 72 65 73 65 74 5f 64  e.#.proc reset_d
4590: 62 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b  b {} {.  catch {
45a0: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66 6f 72 63  db close}.  forc
45b0: 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62 0a  edelete test.db.
45c0: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65    forcedelete te
45d0: 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20  st.db-journal.  
45e0: 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74  forcedelete test
45f0: 2e 64 62 2d 77 61 6c 0a 20 20 73 71 6c 69 74 65  .db-wal.  sqlite
4600: 33 20 64 62 20 2e 2f 74 65 73 74 2e 64 62 0a 20  3 db ./test.db. 
4610: 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74   set ::DB [sqlit
4620: 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f  e3_connection_po
4630: 69 6e 74 65 72 20 64 62 5d 0a 20 20 69 66 20 7b  inter db].  if {
4640: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53  [info exists ::S
4650: 45 54 55 50 5f 53 51 4c 5d 7d 20 7b 0a 20 20 20  ETUP_SQL]} {.   
4660: 20 64 62 20 65 76 61 6c 20 24 3a 3a 53 45 54 55   db eval $::SETU
4670: 50 5f 53 51 4c 0a 20 20 7d 0a 7d 0a 72 65 73 65  P_SQL.  }.}.rese
4680: 74 5f 64 62 0a 0a 23 20 41 62 6f 72 74 20 65 61  t_db..# Abort ea
4690: 72 6c 79 20 69 66 20 74 68 69 73 20 73 63 72 69  rly if this scri
46a0: 70 74 20 68 61 73 20 62 65 65 6e 20 72 75 6e 20  pt has been run 
46b0: 62 65 66 6f 72 65 2e 0a 23 0a 69 66 20 7b 5b 69  before..#.if {[i
46c0: 6e 66 6f 20 65 78 69 73 74 73 20 54 43 28 63 6f  nfo exists TC(co
46d0: 75 6e 74 29 5d 7d 20 72 65 74 75 72 6e 0a 0a 23  unt)]} return..#
46e0: 20 4d 61 6b 65 20 73 75 72 65 20 6d 65 6d 6f 72   Make sure memor
46f0: 79 20 73 74 61 74 69 73 74 69 63 73 20 61 72 65  y statistics are
4700: 20 65 6e 61 62 6c 65 64 2e 0a 23 0a 73 71 6c 69   enabled..#.sqli
4710: 74 65 33 5f 63 6f 6e 66 69 67 5f 6d 65 6d 73 74  te3_config_memst
4720: 61 74 75 73 20 31 0a 0a 23 20 49 6e 69 74 69 61  atus 1..# Initia
4730: 6c 69 7a 65 20 74 68 65 20 74 65 73 74 20 63 6f  lize the test co
4740: 75 6e 74 65 72 73 20 61 6e 64 20 73 65 74 20 75  unters and set u
4750: 70 20 63 6f 6d 6d 61 6e 64 73 20 74 6f 20 61 63  p commands to ac
4760: 63 65 73 73 20 74 68 65 6d 2e 0a 23 20 4f 72 2c  cess them..# Or,
4770: 20 69 66 20 74 68 69 73 20 69 73 20 61 20 73 6c   if this is a sl
4780: 61 76 65 20 69 6e 74 65 72 70 72 65 74 65 72 2c  ave interpreter,
4790: 20 73 65 74 20 75 70 20 61 6c 69 61 73 65 73 20   set up aliases 
47a0: 74 6f 20 77 72 69 74 65 20 74 68 65 0a 23 20 63  to write the.# c
47b0: 6f 75 6e 74 65 72 73 20 69 6e 20 74 68 65 20 70  ounters in the p
47c0: 61 72 65 6e 74 20 69 6e 74 65 72 70 72 65 74 65  arent interprete
47d0: 72 2e 0a 23 0a 69 66 20 7b 30 3d 3d 5b 69 6e 66  r..#.if {0==[inf
47e0: 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c 41 56 45  o exists ::SLAVE
47f0: 5d 7d 20 7b 0a 20 20 73 65 74 20 54 43 28 65 72  ]} {.  set TC(er
4800: 72 6f 72 73 29 20 20 20 20 30 0a 20 20 73 65 74  rors)    0.  set
4810: 20 54 43 28 63 6f 75 6e 74 29 20 20 20 20 20 30   TC(count)     0
4820: 0a 20 20 73 65 74 20 54 43 28 66 61 69 6c 5f 6c  .  set TC(fail_l
4830: 69 73 74 29 20 5b 6c 69 73 74 5d 0a 20 20 73 65  ist) [list].  se
4840: 74 20 54 43 28 6f 6d 69 74 5f 6c 69 73 74 29 20  t TC(omit_list) 
4850: 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 54 43 28  [list].  set TC(
4860: 77 61 72 6e 5f 6c 69 73 74 29 20 5b 6c 69 73 74  warn_list) [list
4870: 5d 0a 0a 20 20 70 72 6f 63 20 73 65 74 5f 74 65  ]..  proc set_te
4880: 73 74 5f 63 6f 75 6e 74 65 72 20 7b 63 6f 75 6e  st_counter {coun
4890: 74 65 72 20 61 72 67 73 7d 20 7b 0a 20 20 20 20  ter args} {.    
48a0: 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72  if {[llength $ar
48b0: 67 73 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  gs]} {.      set
48c0: 20 3a 3a 54 43 28 24 63 6f 75 6e 74 65 72 29 20   ::TC($counter) 
48d0: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d  [lindex $args 0]
48e0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 3a  .    }.    set :
48f0: 3a 54 43 28 24 63 6f 75 6e 74 65 72 29 0a 20 20  :TC($counter).  
4900: 7d 0a 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74 68  }.}..# Record th
4910: 65 20 66 61 63 74 20 74 68 61 74 20 61 20 73 65  e fact that a se
4920: 71 75 65 6e 63 65 20 6f 66 20 74 65 73 74 73 20  quence of tests 
4930: 77 65 72 65 20 6f 6d 69 74 74 65 64 2e 0a 23 0a  were omitted..#.
4940: 70 72 6f 63 20 6f 6d 69 74 5f 74 65 73 74 20 7b  proc omit_test {
4950: 6e 61 6d 65 20 72 65 61 73 6f 6e 20 7b 61 70 70  name reason {app
4960: 65 6e 64 20 31 7d 7d 20 7b 0a 20 20 73 65 74 20  end 1}} {.  set 
4970: 6f 6d 69 74 4c 69 73 74 20 5b 73 65 74 5f 74 65  omitList [set_te
4980: 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f  st_counter omit_
4990: 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24 61 70 70  list].  if {$app
49a0: 65 6e 64 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65  end} {.    lappe
49b0: 6e 64 20 6f 6d 69 74 4c 69 73 74 20 5b 6c 69 73  nd omitList [lis
49c0: 74 20 24 6e 61 6d 65 20 24 72 65 61 73 6f 6e 5d  t $name $reason]
49d0: 0a 20 20 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f  .  }.  set_test_
49e0: 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73  counter omit_lis
49f0: 74 20 24 6f 6d 69 74 4c 69 73 74 0a 7d 0a 0a 23  t $omitList.}..#
4a00: 20 52 65 63 6f 72 64 20 74 68 65 20 66 61 63 74   Record the fact
4a10: 20 74 68 61 74 20 61 20 74 65 73 74 20 66 61 69   that a test fai
4a20: 6c 65 64 2e 0a 23 0a 70 72 6f 63 20 66 61 69 6c  led..#.proc fail
4a30: 5f 74 65 73 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20  _test {name} {. 
4a40: 20 73 65 74 20 66 20 5b 73 65 74 5f 74 65 73 74   set f [set_test
4a50: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
4a60: 73 74 5d 0a 20 20 6c 61 70 70 65 6e 64 20 66 20  st].  lappend f 
4a70: 24 6e 61 6d 65 0a 20 20 73 65 74 5f 74 65 73 74  $name.  set_test
4a80: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
4a90: 73 74 20 24 66 0a 20 20 73 65 74 5f 74 65 73 74  st $f.  set_test
4aa0: 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 20  _counter errors 
4ab0: 5b 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f  [expr [set_test_
4ac0: 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 20  counter errors] 
4ad0: 2b 20 31 5d 0a 0a 20 20 73 65 74 20 6e 46 61 69  + 1]..  set nFai
4ae0: 6c 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  l [set_test_coun
4af0: 74 65 72 20 65 72 72 6f 72 73 5d 0a 20 20 69 66  ter errors].  if
4b00: 20 7b 24 6e 46 61 69 6c 3e 3d 24 3a 3a 63 6d 64   {$nFail>=$::cmd
4b10: 6c 69 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72  linearg(maxerror
4b20: 29 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  )} {.    output2
4b30: 20 22 2a 2a 2a 20 47 69 76 69 6e 67 20 75 70 2e   "*** Giving up.
4b40: 2e 2e 22 0a 20 20 20 20 66 69 6e 61 6c 69 7a 65  ..".    finalize
4b50: 5f 74 65 73 74 69 6e 67 0a 20 20 7d 0a 7d 0a 0a  _testing.  }.}..
4b60: 23 20 52 65 6d 65 6d 62 65 72 20 61 20 77 61 72  # Remember a war
4b70: 6e 69 6e 67 20 6d 65 73 73 61 67 65 20 74 6f 20  ning message to 
4b80: 62 65 20 64 69 73 70 6c 61 79 65 64 20 61 74 20  be displayed at 
4b90: 74 68 65 20 63 6f 6e 63 6c 75 73 69 6f 6e 20 6f  the conclusion o
4ba0: 66 20 61 6c 6c 20 74 65 73 74 69 6e 67 0a 23 0a  f all testing.#.
4bb0: 70 72 6f 63 20 77 61 72 6e 69 6e 67 20 7b 6d 73  proc warning {ms
4bc0: 67 20 7b 61 70 70 65 6e 64 20 31 7d 7d 20 7b 0a  g {append 1}} {.
4bd0: 20 20 6f 75 74 70 75 74 32 20 22 57 61 72 6e 69    output2 "Warni
4be0: 6e 67 3a 20 24 6d 73 67 22 0a 20 20 73 65 74 20  ng: $msg".  set 
4bf0: 77 61 72 6e 4c 69 73 74 20 5b 73 65 74 5f 74 65  warnList [set_te
4c00: 73 74 5f 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f  st_counter warn_
4c10: 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24 61 70 70  list].  if {$app
4c20: 65 6e 64 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65  end} {.    lappe
4c30: 6e 64 20 77 61 72 6e 4c 69 73 74 20 24 6d 73 67  nd warnList $msg
4c40: 0a 20 20 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f  .  }.  set_test_
4c50: 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73  counter warn_lis
4c60: 74 20 24 77 61 72 6e 4c 69 73 74 0a 7d 0a 0a 0a  t $warnList.}...
4c70: 23 20 49 6e 63 72 65 6d 65 6e 74 20 74 68 65 20  # Increment the 
4c80: 6e 75 6d 62 65 72 20 6f 66 20 74 65 73 74 73 20  number of tests 
4c90: 72 75 6e 0a 23 0a 70 72 6f 63 20 69 6e 63 72 5f  run.#.proc incr_
4ca0: 6e 74 65 73 74 20 7b 7d 20 7b 0a 20 20 73 65 74  ntest {} {.  set
4cb0: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f  _test_counter co
4cc0: 75 6e 74 20 5b 65 78 70 72 20 5b 73 65 74 5f 74  unt [expr [set_t
4cd0: 65 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e  est_counter coun
4ce0: 74 5d 20 2b 20 31 5d 0a 7d 0a 0a 23 20 52 65 74  t] + 1].}..# Ret
4cf0: 75 72 6e 20 74 72 75 65 20 69 66 20 2d 2d 76 65  urn true if --ve
4d00: 72 62 6f 73 65 3d 31 20 77 61 73 20 73 70 65 63  rbose=1 was spec
4d10: 69 66 69 65 64 20 6f 6e 20 74 68 65 20 63 6f 6d  ified on the com
4d20: 6d 61 6e 64 20 6c 69 6e 65 2e 20 4f 74 68 65 72  mand line. Other
4d30: 77 69 73 65 2c 0a 23 20 72 65 74 75 72 6e 20 66  wise,.# return f
4d40: 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 76 65 72  alse..#.proc ver
4d50: 62 6f 73 65 20 7b 7d 20 7b 0a 20 20 72 65 74 75  bose {} {.  retu
4d60: 72 6e 20 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67  rn $::cmdlinearg
4d70: 28 76 65 72 62 6f 73 65 29 0a 7d 0a 0a 23 20 55  (verbose).}..# U
4d80: 73 65 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  se the following
4d90: 20 63 6f 6d 6d 61 6e 64 73 20 69 6e 73 74 65 61   commands instea
4da0: 64 20 6f 66 20 5b 70 75 74 73 5d 20 66 6f 72 20  d of [puts] for 
4db0: 74 65 73 74 20 6f 75 74 70 75 74 20 77 69 74 68  test output with
4dc0: 69 6e 0a 23 20 74 68 69 73 20 66 69 6c 65 2e 20  in.# this file. 
4dd0: 54 65 73 74 20 73 63 72 69 70 74 73 20 63 61 6e  Test scripts can
4de0: 20 73 74 69 6c 6c 20 75 73 65 20 72 65 67 75 6c   still use regul
4df0: 61 72 20 5b 70 75 74 73 5d 2c 20 77 68 69 63 68  ar [puts], which
4e00: 20 69 73 20 64 69 72 65 63 74 65 64 0a 23 20 74   is directed.# t
4e10: 6f 20 73 74 64 6f 75 74 20 61 6e 64 2c 20 69 66  o stdout and, if
4e20: 20 6f 6e 65 20 69 73 20 6f 70 65 6e 2c 20 74 68   one is open, th
4e30: 65 20 2d 2d 6f 75 74 70 75 74 20 66 69 6c 65 2e  e --output file.
4e40: 0a 23 0a 23 20 6f 75 74 70 75 74 31 3a 20 6f 75  .#.# output1: ou
4e50: 74 70 75 74 20 74 68 61 74 20 73 68 6f 75 6c 64  tput that should
4e60: 20 62 65 20 70 72 69 6e 74 65 64 20 69 66 20 2d   be printed if -
4e70: 2d 76 65 72 62 6f 73 65 3d 31 20 77 61 73 20 73  -verbose=1 was s
4e80: 70 65 63 69 66 69 65 64 2e 0a 23 20 6f 75 74 70  pecified..# outp
4e90: 75 74 32 3a 20 6f 75 74 70 75 74 20 74 68 61 74  ut2: output that
4ea0: 20 73 68 6f 75 6c 64 20 62 65 20 70 72 69 6e 74   should be print
4eb0: 65 64 20 75 6e 63 6f 6e 64 69 74 69 6f 6e 61 6c  ed unconditional
4ec0: 6c 79 2e 0a 23 20 6f 75 74 70 75 74 32 5f 69 66  ly..# output2_if
4ed0: 5f 6e 6f 5f 76 65 72 62 6f 73 65 3a 20 6f 75 74  _no_verbose: out
4ee0: 70 75 74 20 74 68 61 74 20 73 68 6f 75 6c 64 20  put that should 
4ef0: 62 65 20 70 72 69 6e 74 65 64 20 6f 6e 6c 79 20  be printed only 
4f00: 69 66 20 2d 2d 76 65 72 62 6f 73 65 3d 30 2e 0a  if --verbose=0..
4f10: 23 0a 70 72 6f 63 20 6f 75 74 70 75 74 31 20 7b  #.proc output1 {
4f20: 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 76 20  args} {.  set v 
4f30: 5b 76 65 72 62 6f 73 65 5d 0a 20 20 69 66 20 7b  [verbose].  if {
4f40: 24 76 3d 3d 31 7d 20 7b 0a 20 20 20 20 75 70 6c  $v==1} {.    upl
4f50: 65 76 65 6c 20 6f 75 74 70 75 74 32 20 24 61 72  evel output2 $ar
4f60: 67 73 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  gs.  } elseif {$
4f70: 76 3d 3d 32 7d 20 7b 0a 20 20 20 20 75 70 6c 65  v==2} {.    uple
4f80: 76 65 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67 65  vel puts [lrange
4f90: 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 20   $args 0 end-1] 
4fa0: 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 20  $::G(output_fd) 
4fb0: 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20 65 6e  [lrange $args en
4fc0: 64 20 65 6e 64 5d 0a 20 20 7d 0a 7d 0a 70 72 6f  d end].  }.}.pro
4fd0: 63 20 6f 75 74 70 75 74 32 20 7b 61 72 67 73 7d  c output2 {args}
4fe0: 20 7b 0a 20 20 73 65 74 20 6e 41 72 67 20 5b 6c   {.  set nArg [l
4ff0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 0a 20 20  length $args].  
5000: 75 70 6c 65 76 65 6c 20 70 75 74 73 20 24 61 72  uplevel puts $ar
5010: 67 73 0a 7d 0a 70 72 6f 63 20 6f 75 74 70 75 74  gs.}.proc output
5020: 32 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f 73 65 20  2_if_no_verbose 
5030: 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 76  {args} {.  set v
5040: 20 5b 76 65 72 62 6f 73 65 5d 0a 20 20 69 66 20   [verbose].  if 
5050: 7b 24 76 3d 3d 30 7d 20 7b 0a 20 20 20 20 75 70  {$v==0} {.    up
5060: 6c 65 76 65 6c 20 6f 75 74 70 75 74 32 20 24 61  level output2 $a
5070: 72 67 73 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b  rgs.  } elseif {
5080: 24 76 3d 3d 32 7d 20 7b 0a 20 20 20 20 75 70 6c  $v==2} {.    upl
5090: 65 76 65 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67  evel puts [lrang
50a0: 65 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d  e $args 0 end-1]
50b0: 20 73 74 64 6f 75 74 20 5b 6c 72 61 6e 67 65 20   stdout [lrange 
50c0: 24 61 72 67 73 20 65 6e 64 20 65 6e 64 5d 0a 20  $args end end]. 
50d0: 20 7d 0a 7d 0a 0a 23 20 4f 76 65 72 72 69 64 65   }.}..# Override
50e0: 20 74 68 65 20 5b 70 75 74 73 5d 20 63 6f 6d 6d   the [puts] comm
50f0: 61 6e 64 20 73 6f 20 74 68 61 74 20 69 66 20 6e  and so that if n
5100: 6f 20 63 68 61 6e 6e 65 6c 20 69 73 20 65 78 70  o channel is exp
5110: 6c 69 63 69 74 6c 79 20 0a 23 20 73 70 65 63 69  licitly .# speci
5120: 66 69 65 64 20 74 68 65 20 73 74 72 69 6e 67 20  fied the string 
5130: 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 62 6f  is written to bo
5140: 74 68 20 73 74 64 6f 75 74 20 61 6e 64 20 74 6f  th stdout and to
5150: 20 74 68 65 20 66 69 6c 65 20 0a 23 20 73 70 65   the file .# spe
5160: 63 69 66 69 65 64 20 62 79 20 22 2d 2d 6f 75 74  cified by "--out
5170: 70 75 74 3d 22 2c 20 69 66 20 61 6e 79 2e 0a 23  put=", if any..#
5180: 0a 70 72 6f 63 20 70 75 74 73 5f 6f 76 65 72 72  .proc puts_overr
5190: 69 64 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 73  ide {args} {.  s
51a0: 65 74 20 6e 41 72 67 20 5b 6c 6c 65 6e 67 74 68  et nArg [llength
51b0: 20 24 61 72 67 73 5d 0a 20 20 69 66 20 7b 24 6e   $args].  if {$n
51c0: 41 72 67 3d 3d 31 20 7c 7c 20 28 24 6e 41 72 67  Arg==1 || ($nArg
51d0: 3d 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 66  ==2 && [string f
51e0: 69 72 73 74 20 5b 6c 69 6e 64 65 78 20 24 61 72  irst [lindex $ar
51f0: 67 73 20 30 5d 20 2d 6e 6f 6e 65 77 6c 69 6e 65  gs 0] -nonewline
5200: 5d 3d 3d 30 29 7d 20 7b 0a 20 20 20 20 75 70 6c  ]==0)} {.    upl
5210: 65 76 65 6c 20 70 75 74 73 5f 6f 72 69 67 69 6e  evel puts_origin
5220: 61 6c 20 24 61 72 67 73 0a 20 20 20 20 69 66 20  al $args.    if 
5230: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
5240: 47 28 6f 75 74 70 75 74 5f 66 64 29 5d 7d 20 7b  G(output_fd)]} {
5250: 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 70  .      uplevel p
5260: 75 74 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67  uts [lrange $arg
5270: 73 20 30 20 65 6e 64 2d 31 5d 20 24 3a 3a 47 28  s 0 end-1] $::G(
5280: 6f 75 74 70 75 74 5f 66 64 29 20 5b 6c 72 61 6e  output_fd) [lran
5290: 67 65 20 24 61 72 67 73 20 65 6e 64 20 65 6e 64  ge $args end end
52a0: 5d 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  ].    }.  } else
52b0: 20 7b 0a 20 20 20 20 23 20 41 20 63 68 61 6e 6e   {.    # A chann
52c0: 65 6c 20 77 61 73 20 65 78 70 6c 69 63 69 74 6c  el was explicitl
52d0: 79 20 73 70 65 63 69 66 69 65 64 2e 0a 20 20 20  y specified..   
52e0: 20 75 70 6c 65 76 65 6c 20 70 75 74 73 5f 6f 72   uplevel puts_or
52f0: 69 67 69 6e 61 6c 20 24 61 72 67 73 0a 20 20 7d  iginal $args.  }
5300: 0a 7d 0a 72 65 6e 61 6d 65 20 70 75 74 73 20 70  .}.rename puts p
5310: 75 74 73 5f 6f 72 69 67 69 6e 61 6c 0a 70 72 6f  uts_original.pro
5320: 63 20 70 75 74 73 20 7b 61 72 67 73 7d 20 7b 20  c puts {args} { 
5330: 75 70 6c 65 76 65 6c 20 70 75 74 73 5f 6f 76 65  uplevel puts_ove
5340: 72 72 69 64 65 20 24 61 72 67 73 20 7d 0a 0a 0a  rride $args }...
5350: 23 20 49 6e 76 6f 6b 65 20 74 68 65 20 64 6f 5f  # Invoke the do_
5360: 74 65 73 74 20 70 72 6f 63 65 64 75 72 65 20 74  test procedure t
5370: 6f 20 72 75 6e 20 61 20 73 69 6e 67 6c 65 20 74  o run a single t
5380: 65 73 74 0a 23 0a 23 20 54 68 65 20 24 65 78 70  est.#.# The $exp
5390: 65 63 74 65 64 20 70 61 72 61 6d 65 74 65 72 20  ected parameter 
53a0: 69 73 20 74 68 65 20 65 78 70 65 63 74 65 64 20  is the expected 
53b0: 72 65 73 75 6c 74 2e 20 20 54 68 65 20 72 65 73  result.  The res
53c0: 75 6c 74 20 69 73 20 74 68 65 20 72 65 74 75 72  ult is the retur
53d0: 6e 0a 23 20 76 61 6c 75 65 20 66 72 6f 6d 20 74  n.# value from t
53e0: 68 65 20 6c 61 73 74 20 54 43 4c 20 63 6f 6d 6d  he last TCL comm
53f0: 61 6e 64 20 69 6e 20 24 63 6d 64 2e 0a 23 0a 23  and in $cmd..#.#
5400: 20 4e 6f 72 6d 61 6c 6c 79 2c 20 24 65 78 70 65   Normally, $expe
5410: 63 74 65 64 20 6d 75 73 74 20 6d 61 74 63 68 20  cted must match 
5420: 65 78 61 63 74 6c 79 2e 20 20 42 75 74 20 69 66  exactly.  But if
5430: 20 24 65 78 70 65 63 74 65 64 20 69 73 20 6f 66   $expected is of
5440: 20 74 68 65 20 66 6f 72 6d 0a 23 20 22 2f 72 65   the form.# "/re
5450: 67 65 78 70 2f 22 20 74 68 65 6e 20 72 65 67 75  gexp/" then regu
5460: 6c 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 6d  lar expression m
5470: 61 74 63 68 69 6e 67 20 69 73 20 75 73 65 64 2e  atching is used.
5480: 20 20 49 66 20 24 65 78 70 65 63 74 65 64 20 69    If $expected i
5490: 73 0a 23 20 22 7e 2f 72 65 67 65 78 70 2f 22 20  s.# "~/regexp/" 
54a0: 74 68 65 6e 20 74 68 65 20 72 65 67 75 6c 61 72  then the regular
54b0: 20 65 78 70 72 65 73 73 69 6f 6e 20 6d 75 73 74   expression must
54c0: 20 4e 4f 54 20 6d 61 74 63 68 2e 20 20 49 66 20   NOT match.  If 
54d0: 24 65 78 70 65 63 74 65 64 20 69 73 0a 23 20 6f  $expected is.# o
54e0: 66 20 74 68 65 20 66 6f 72 6d 20 22 23 2f 76 61  f the form "#/va
54f0: 6c 75 65 2d 6c 69 73 74 2f 22 20 74 68 65 6e 20  lue-list/" then 
5500: 65 61 63 68 20 74 65 72 6d 20 69 6e 20 76 61 6c  each term in val
5510: 75 65 2d 6c 69 73 74 20 6d 75 73 74 20 62 65 20  ue-list must be 
5520: 6e 75 6d 65 72 69 63 0a 23 20 61 6e 64 20 6d 75  numeric.# and mu
5530: 73 74 20 61 70 70 72 6f 78 69 6d 61 74 65 6c 79  st approximately
5540: 20 6d 61 74 63 68 20 74 68 65 20 63 6f 72 72 65   match the corre
5550: 73 70 6f 6e 64 69 6e 67 20 6e 75 6d 65 72 69 63  sponding numeric
5560: 20 74 65 72 6d 20 69 6e 20 24 72 65 73 75 6c 74   term in $result
5570: 2e 0a 23 20 56 61 6c 75 65 73 20 6d 75 73 74 20  ..# Values must 
5580: 6d 61 74 63 68 20 77 69 74 68 69 6e 20 31 30 25  match within 10%
5590: 2e 20 20 4f 72 20 69 66 20 74 68 65 20 24 65 78  .  Or if the $ex
55a0: 70 65 63 74 65 64 20 74 65 72 6d 20 69 73 20 41  pected term is A
55b0: 2e 2e 42 20 74 68 65 6e 20 74 68 65 0a 23 20 24  ..B then the.# $
55c0: 72 65 73 75 6c 74 20 74 65 72 6d 20 6d 75 73 74  result term must
55d0: 20 62 65 20 69 6e 20 62 65 74 77 65 65 6e 20 41   be in between A
55e0: 20 61 6e 64 20 42 2e 0a 23 0a 70 72 6f 63 20 64   and B..#.proc d
55f0: 6f 5f 74 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64  o_test {name cmd
5600: 20 65 78 70 65 63 74 65 64 7d 20 7b 0a 20 20 67   expected} {.  g
5610: 6c 6f 62 61 6c 20 61 72 67 76 20 63 6d 64 6c 69  lobal argv cmdli
5620: 6e 65 61 72 67 0a 0a 20 20 66 69 78 5f 74 65 73  nearg..  fix_tes
5630: 74 6e 61 6d 65 20 6e 61 6d 65 0a 0a 20 20 73 71  tname name..  sq
5640: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 73  lite3_memdebug_s
5650: 65 74 74 69 74 6c 65 20 24 6e 61 6d 65 0a 0a 23  ettitle $name..#
5660: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
5670: 61 72 67 76 5d 3d 3d 30 7d 20 7b 0a 23 20 20 20  argv]==0} {.#   
5680: 20 73 65 74 20 67 6f 20 31 0a 23 20 20 7d 20 65   set go 1.#  } e
5690: 6c 73 65 20 7b 0a 23 20 20 20 20 73 65 74 20 67  lse {.#    set g
56a0: 6f 20 30 0a 23 20 20 20 20 66 6f 72 65 61 63 68  o 0.#    foreach
56b0: 20 70 61 74 74 65 72 6e 20 24 61 72 67 76 20 7b   pattern $argv {
56c0: 0a 23 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72  .#      if {[str
56d0: 69 6e 67 20 6d 61 74 63 68 20 24 70 61 74 74 65  ing match $patte
56e0: 72 6e 20 24 6e 61 6d 65 5d 7d 20 7b 0a 23 20 20  rn $name]} {.#  
56f0: 20 20 20 20 20 20 73 65 74 20 67 6f 20 31 0a 23        set go 1.#
5700: 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a 23 20          break.# 
5710: 20 20 20 20 20 7d 0a 23 20 20 20 20 7d 0a 23 20       }.#    }.# 
5720: 20 7d 0a 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20   }..  if {[info 
5730: 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a  exists ::G(perm:
5740: 70 72 65 66 69 78 29 5d 7d 20 7b 0a 20 20 20 20  prefix)]} {.    
5750: 73 65 74 20 6e 61 6d 65 20 22 24 3a 3a 47 28 70  set name "$::G(p
5760: 65 72 6d 3a 70 72 65 66 69 78 29 24 6e 61 6d 65  erm:prefix)$name
5770: 22 0a 20 20 7d 0a 0a 20 20 69 6e 63 72 5f 6e 74  ".  }..  incr_nt
5780: 65 73 74 0a 20 20 6f 75 74 70 75 74 31 20 2d 6e  est.  output1 -n
5790: 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d 65 2e 2e  onewline $name..
57a0: 2e 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74  ..  flush stdout
57b0: 0a 0a 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65  ..  if {![info e
57c0: 78 69 73 74 73 20 3a 3a 47 28 6d 61 74 63 68 29  xists ::G(match)
57d0: 5d 20 7c 7c 20 5b 73 74 72 69 6e 67 20 6d 61 74  ] || [string mat
57e0: 63 68 20 24 3a 3a 47 28 6d 61 74 63 68 29 20 24  ch $::G(match) $
57f0: 6e 61 6d 65 5d 7d 20 7b 0a 20 20 20 20 69 66 20  name]} {.    if 
5800: 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c  {[catch {uplevel
5810: 20 23 30 20 22 24 63 6d 64 3b 5c 6e 22 7d 20 72   #0 "$cmd;\n"} r
5820: 65 73 75 6c 74 5d 7d 20 7b 0a 20 20 20 20 20 20  esult]} {.      
5830: 6f 75 74 70 75 74 32 5f 69 66 5f 6e 6f 5f 76 65  output2_if_no_ve
5840: 72 62 6f 73 65 20 2d 6e 6f 6e 65 77 6c 69 6e 65  rbose -nonewline
5850: 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 20 20 20 20   $name....      
5860: 6f 75 74 70 75 74 32 20 22 5c 6e 45 72 72 6f 72  output2 "\nError
5870: 3a 20 24 72 65 73 75 6c 74 22 0a 20 20 20 20 20  : $result".     
5880: 20 66 61 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65   fail_test $name
5890: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
58a0: 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20      if {[regexp 
58b0: 7b 5e 5b 7e 23 5d 3f 2f 2e 2a 2f 24 7d 20 24 65  {^[~#]?/.*/$} $e
58c0: 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20 20 20 20  xpected]} {.    
58d0: 20 20 20 20 23 20 22 65 78 70 65 63 74 65 64 22      # "expected"
58e0: 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20   is of the form 
58f0: 22 2f 50 41 54 54 45 52 4e 2f 22 20 74 68 65 6e  "/PATTERN/" then
5900: 20 74 68 65 20 72 65 73 75 6c 74 20 69 66 20 63   the result if c
5910: 6f 72 72 65 63 74 20 69 66 0a 20 20 20 20 20 20  orrect if.      
5920: 20 20 23 20 72 65 67 75 6c 61 72 20 65 78 70 72    # regular expr
5930: 65 73 73 69 6f 6e 20 50 41 54 54 45 52 4e 20 6d  ession PATTERN m
5940: 61 74 63 68 65 73 20 74 68 65 20 72 65 73 75 6c  atches the resul
5950: 74 2e 20 20 22 7e 2f 50 41 54 54 45 52 4e 2f 22  t.  "~/PATTERN/"
5960: 20 6d 65 61 6e 73 0a 20 20 20 20 20 20 20 20 23   means.        #
5970: 20 74 68 65 20 72 65 67 75 6c 61 72 20 65 78 70   the regular exp
5980: 72 65 73 73 69 6f 6e 20 6d 75 73 74 20 6e 6f 74  ression must not
5990: 20 6d 61 74 63 68 2e 0a 20 20 20 20 20 20 20 20   match..        
59a0: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65  if {[string inde
59b0: 78 20 24 65 78 70 65 63 74 65 64 20 30 5d 3d 3d  x $expected 0]==
59c0: 22 7e 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  "~"} {.         
59d0: 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67 20   set re [string 
59e0: 72 61 6e 67 65 20 24 65 78 70 65 63 74 65 64 20  range $expected 
59f0: 32 20 65 6e 64 2d 31 5d 0a 20 20 20 20 20 20 20  2 end-1].       
5a00: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 69     if {[string i
5a10: 6e 64 65 78 20 24 72 65 20 30 5d 3d 3d 22 2a 22  ndex $re 0]=="*"
5a20: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  } {.            
5a30: 23 20 49 66 20 74 68 65 20 72 65 67 75 6c 61 72  # If the regular
5a40: 20 65 78 70 72 65 73 73 69 6f 6e 20 62 65 67 69   expression begi
5a50: 6e 73 20 77 69 74 68 20 2a 20 74 68 65 6e 20 74  ns with * then t
5a60: 72 65 61 74 20 69 74 20 61 73 20 61 20 67 6c 6f  reat it as a glo
5a70: 62 20 69 6e 73 74 65 61 64 0a 20 20 20 20 20 20  b instead.      
5a80: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 73 74        set ok [st
5a90: 72 69 6e 67 20 6d 61 74 63 68 20 24 72 65 20 24  ring match $re $
5aa0: 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20  result].        
5ab0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
5ac0: 20 20 20 20 20 20 20 73 65 74 20 72 65 20 5b 73         set re [s
5ad0: 74 72 69 6e 67 20 6d 61 70 20 7b 23 20 7b 5b 2d  tring map {# {[-
5ae0: 30 2d 39 2e 5d 2b 7d 7d 20 24 72 65 5d 0a 20 20  0-9.]+}} $re].  
5af0: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b            set ok
5b00: 20 5b 72 65 67 65 78 70 20 24 72 65 20 24 72 65   [regexp $re $re
5b10: 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20 20 20  sult].          
5b20: 7d 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  }.          set 
5b30: 6f 6b 20 5b 65 78 70 72 20 7b 21 24 6f 6b 7d 5d  ok [expr {!$ok}]
5b40: 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 69  .        } elsei
5b50: 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65 78  f {[string index
5b60: 20 24 65 78 70 65 63 74 65 64 20 30 5d 3d 3d 22   $expected 0]=="
5b70: 23 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20  #"} {.          
5b80: 23 20 4e 75 6d 65 72 69 63 20 72 61 6e 67 65 20  # Numeric range 
5b90: 76 61 6c 75 65 20 63 6f 6d 70 61 72 69 73 6f 6e  value comparison
5ba0: 2e 20 20 45 61 63 68 20 74 65 72 6d 20 6f 66 20  .  Each term of 
5bb0: 74 68 65 20 24 72 65 73 75 6c 74 20 69 73 20 6d  the $result is m
5bc0: 61 74 63 68 65 64 0a 20 20 20 20 20 20 20 20 20  atched.         
5bd0: 20 23 20 61 67 61 69 6e 73 74 20 6f 6e 65 20 74   # against one t
5be0: 65 72 6d 20 6f 66 20 24 65 78 70 65 63 74 2e 20  erm of $expect. 
5bf0: 20 42 6f 74 68 20 24 72 65 73 75 6c 74 20 61 6e   Both $result an
5c00: 64 20 24 65 78 70 65 63 74 65 64 20 74 65 72 6d  d $expected term
5c10: 73 20 6d 75 73 74 20 62 65 0a 20 20 20 20 20 20  s must be.      
5c20: 20 20 20 20 23 20 6e 75 6d 65 72 69 63 2e 20 20      # numeric.  
5c30: 54 68 65 20 76 61 6c 75 65 73 20 6d 75 73 74 20  The values must 
5c40: 6d 61 74 63 68 20 77 69 74 68 69 6e 20 31 30 25  match within 10%
5c50: 2e 20 20 4f 72 20 69 66 20 24 65 78 70 65 63 74  .  Or if $expect
5c60: 65 64 20 69 73 20 6f 66 20 74 68 65 0a 20 20 20  ed is of the.   
5c70: 20 20 20 20 20 20 20 23 20 66 6f 72 6d 20 41 2e         # form A.
5c80: 2e 42 20 74 68 65 6e 20 74 68 65 20 24 72 65 73  .B then the $res
5c90: 75 6c 74 20 74 65 72 6d 20 6d 75 73 74 20 62 65  ult term must be
5ca0: 20 62 65 74 77 65 65 6e 20 41 20 61 6e 64 20 42   between A and B
5cb0: 2e 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  ..          set 
5cc0: 65 32 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65  e2 [string range
5cd0: 20 24 65 78 70 65 63 74 65 64 20 32 20 65 6e 64   $expected 2 end
5ce0: 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20 66 6f  -1].          fo
5cf0: 72 65 61 63 68 20 69 20 24 72 65 73 75 6c 74 20  reach i $result 
5d00: 6a 20 24 65 32 20 7b 0a 20 20 20 20 20 20 20 20  j $e2 {.        
5d10: 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20      if {[regexp 
5d20: 7b 5e 28 2d 3f 5c 64 2b 29 5c 2e 5c 2e 28 2d 3f  {^(-?\d+)\.\.(-?
5d30: 5c 64 29 24 7d 20 24 6a 20 61 6c 6c 20 41 20 42  \d)$} $j all A B
5d40: 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ]} {.           
5d50: 20 20 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20     set ok [expr 
5d60: 7b 24 69 2b 30 3e 3d 24 41 20 26 26 20 24 69 2b  {$i+0>=$A && $i+
5d70: 30 3c 3d 24 42 7d 5d 0a 20 20 20 20 20 20 20 20  0<=$B}].        
5d80: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
5d90: 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f             set o
5da0: 6b 20 5b 65 78 70 72 20 7b 24 69 2b 30 3e 3d 30  k [expr {$i+0>=0
5db0: 2e 39 2a 24 6a 20 26 26 20 24 69 2b 30 3c 3d 31  .9*$j && $i+0<=1
5dc0: 2e 31 2a 24 6a 7d 5d 0a 20 20 20 20 20 20 20 20  .1*$j}].        
5dd0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
5de0: 20 20 69 66 20 7b 21 24 6f 6b 7d 20 62 72 65 61    if {!$ok} brea
5df0: 6b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  k.          }.  
5e00: 20 20 20 20 20 20 20 20 69 66 20 7b 24 6f 6b 20          if {$ok 
5e10: 26 26 20 5b 6c 6c 65 6e 67 74 68 20 24 72 65 73  && [llength $res
5e20: 75 6c 74 5d 21 3d 5b 6c 6c 65 6e 67 74 68 20 24  ult]!=[llength $
5e30: 65 32 5d 7d 20 7b 73 65 74 20 6f 6b 20 30 7d 0a  e2]} {set ok 0}.
5e40: 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b          } else {
5e50: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 72  .          set r
5e60: 65 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  e [string range 
5e70: 24 65 78 70 65 63 74 65 64 20 31 20 65 6e 64 2d  $expected 1 end-
5e80: 31 5d 0a 20 20 20 20 20 20 20 20 20 20 69 66 20  1].          if 
5e90: 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 24  {[string index $
5ea0: 72 65 20 30 5d 3d 3d 22 2a 22 7d 20 7b 0a 20 20  re 0]=="*"} {.  
5eb0: 20 20 20 20 20 20 20 20 20 20 23 20 49 66 20 74            # If t
5ec0: 68 65 20 72 65 67 75 6c 61 72 20 65 78 70 72 65  he regular expre
5ed0: 73 73 69 6f 6e 20 62 65 67 69 6e 73 20 77 69 74  ssion begins wit
5ee0: 68 20 2a 20 74 68 65 6e 20 74 72 65 61 74 20 69  h * then treat i
5ef0: 74 20 61 73 20 61 20 67 6c 6f 62 20 69 6e 73 74  t as a glob inst
5f00: 65 61 64 0a 20 20 20 20 20 20 20 20 20 20 20 20  ead.            
5f10: 73 65 74 20 6f 6b 20 5b 73 74 72 69 6e 67 20 6d  set ok [string m
5f20: 61 74 63 68 20 24 72 65 20 24 72 65 73 75 6c 74  atch $re $result
5f30: 5d 0a 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c  ].          } el
5f40: 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  se {.           
5f50: 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67 20   set re [string 
5f60: 6d 61 70 20 7b 23 20 7b 5b 2d 30 2d 39 2e 5d 2b  map {# {[-0-9.]+
5f70: 7d 7d 20 24 72 65 5d 0a 20 20 20 20 20 20 20 20  }} $re].        
5f80: 20 20 20 20 73 65 74 20 6f 6b 20 5b 72 65 67 65      set ok [rege
5f90: 78 70 20 24 72 65 20 24 72 65 73 75 6c 74 5d 0a  xp $re $result].
5fa0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
5fb0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c      }.      } el
5fc0: 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e  seif {[regexp {^
5fd0: 7e 3f 5c 2a 2e 2a 5c 2a 24 7d 20 24 65 78 70 65  ~?\*.*\*$} $expe
5fe0: 63 74 65 64 5d 7d 20 7b 0a 20 20 20 20 20 20 20  cted]} {.       
5ff0: 20 23 20 22 65 78 70 65 63 74 65 64 22 20 69 73   # "expected" is
6000: 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 22 2a 47   of the form "*G
6010: 4c 4f 42 2a 22 20 74 68 65 6e 20 74 68 65 20 72  LOB*" then the r
6020: 65 73 75 6c 74 20 69 66 20 63 6f 72 72 65 63 74  esult if correct
6030: 20 69 66 0a 20 20 20 20 20 20 20 20 23 20 67 6c   if.        # gl
6040: 6f 62 20 70 61 74 74 65 72 6e 20 47 4c 4f 42 20  ob pattern GLOB 
6050: 6d 61 74 63 68 65 73 20 74 68 65 20 72 65 73 75  matches the resu
6060: 6c 74 2e 20 20 22 7e 2f 47 4c 4f 42 2f 22 20 6d  lt.  "~/GLOB/" m
6070: 65 61 6e 73 0a 20 20 20 20 20 20 20 20 23 20 74  eans.        # t
6080: 68 65 20 67 6c 6f 62 20 6d 75 73 74 20 6e 6f 74  he glob must not
6090: 20 6d 61 74 63 68 2e 0a 20 20 20 20 20 20 20 20   match..        
60a0: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65  if {[string inde
60b0: 78 20 24 65 78 70 65 63 74 65 64 20 30 5d 3d 3d  x $expected 0]==
60c0: 22 7e 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  "~"} {.         
60d0: 20 73 65 74 20 65 20 5b 73 74 72 69 6e 67 20 72   set e [string r
60e0: 61 6e 67 65 20 24 65 78 70 65 63 74 65 64 20 31  ange $expected 1
60f0: 20 65 6e 64 5d 0a 20 20 20 20 20 20 20 20 20 20   end].          
6100: 73 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b 21 5b  set ok [expr {![
6110: 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 65 20  string match $e 
6120: 24 72 65 73 75 6c 74 5d 7d 5d 0a 20 20 20 20 20  $result]}].     
6130: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
6140: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 73 74        set ok [st
6150: 72 69 6e 67 20 6d 61 74 63 68 20 24 65 78 70 65  ring match $expe
6160: 63 74 65 64 20 24 72 65 73 75 6c 74 5d 0a 20 20  cted $result].  
6170: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20        }.      } 
6180: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 73  else {.        s
6190: 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b 5b 73 74  et ok [expr {[st
61a0: 72 69 6e 67 20 63 6f 6d 70 61 72 65 20 24 72 65  ring compare $re
61b0: 73 75 6c 74 20 24 65 78 70 65 63 74 65 64 5d 3d  sult $expected]=
61c0: 3d 30 7d 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20  =0}].      }.   
61d0: 20 20 20 69 66 20 7b 21 24 6f 6b 7d 20 7b 0a 20     if {!$ok} {. 
61e0: 20 20 20 20 20 20 20 23 20 69 66 20 7b 21 5b 69         # if {![i
61f0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 74 65 73  nfo exists ::tes
6200: 74 70 72 65 66 69 78 5d 20 7c 7c 20 24 3a 3a 74  tprefix] || $::t
6210: 65 73 74 70 72 65 66 69 78 20 65 71 20 22 22 7d  estprefix eq ""}
6220: 20 7b 0a 20 20 20 20 20 20 20 20 23 20 20 20 65   {.        #   e
6230: 72 72 6f 72 20 22 6e 6f 20 74 65 73 74 20 70 72  rror "no test pr
6240: 65 66 69 78 22 0a 20 20 20 20 20 20 20 20 23 20  efix".        # 
6250: 7d 0a 20 20 20 20 20 20 20 20 6f 75 74 70 75 74  }.        output
6260: 31 20 22 22 0a 20 20 20 20 20 20 20 20 6f 75 74  1 "".        out
6270: 70 75 74 32 20 22 21 20 24 6e 61 6d 65 20 65 78  put2 "! $name ex
6280: 70 65 63 74 65 64 3a 20 5c 5b 24 65 78 70 65 63  pected: \[$expec
6290: 74 65 64 5c 5d 5c 6e 21 20 24 6e 61 6d 65 20 67  ted\]\n! $name g
62a0: 6f 74 3a 20 20 20 20 20 20 5c 5b 24 72 65 73 75  ot:      \[$resu
62b0: 6c 74 5c 5d 22 0a 20 20 20 20 20 20 20 20 66 61  lt\]".        fa
62c0: 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65 0a 20 20  il_test $name.  
62d0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
62e0: 20 20 20 20 20 6f 75 74 70 75 74 31 20 22 20 4f       output1 " O
62f0: 6b 22 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k".      }.    }
6300: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
6310: 6f 75 74 70 75 74 31 20 22 20 4f 6d 69 74 74 65  output1 " Omitte
6320: 64 22 0a 20 20 20 20 6f 6d 69 74 5f 74 65 73 74  d".    omit_test
6330: 20 24 6e 61 6d 65 20 22 70 61 74 74 65 72 6e 20   $name "pattern 
6340: 6d 69 73 6d 61 74 63 68 22 20 30 0a 20 20 7d 0a  mismatch" 0.  }.
6350: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 7d    flush stdout.}
6360: 0a 0a 70 72 6f 63 20 64 75 6d 70 62 79 74 65 73  ..proc dumpbytes
6370: 20 7b 73 7d 20 7b 0a 20 20 73 65 74 20 72 20 22   {s} {.  set r "
6380: 22 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30  ".  for {set i 0
6390: 7d 20 7b 24 69 20 3c 20 5b 73 74 72 69 6e 67 20  } {$i < [string 
63a0: 6c 65 6e 67 74 68 20 24 73 5d 7d 20 7b 69 6e 63  length $s]} {inc
63b0: 72 20 69 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24  r i} {.    if {$
63c0: 69 20 3e 20 30 7d 20 7b 61 70 70 65 6e 64 20 72  i > 0} {append r
63d0: 20 22 20 22 7d 0a 20 20 20 20 61 70 70 65 6e 64   " "}.    append
63e0: 20 72 20 5b 66 6f 72 6d 61 74 20 25 30 32 58 20   r [format %02X 
63f0: 5b 73 63 61 6e 20 5b 73 74 72 69 6e 67 20 69 6e  [scan [string in
6400: 64 65 78 20 24 73 20 24 69 5d 20 25 63 5d 5d 0a  dex $s $i] %c]].
6410: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a    }.  return $r.
6420: 7d 0a 0a 70 72 6f 63 20 63 61 74 63 68 63 6d 64  }..proc catchcmd
6430: 20 7b 64 62 20 7b 63 6d 64 20 22 22 7d 7d 20 7b   {db {cmd ""}} {
6440: 0a 20 20 67 6c 6f 62 61 6c 20 43 4c 49 0a 20 20  .  global CLI.  
6450: 73 65 74 20 6f 75 74 20 5b 6f 70 65 6e 20 63 6d  set out [open cm
6460: 64 73 2e 74 78 74 20 77 5d 0a 20 20 70 75 74 73  ds.txt w].  puts
6470: 20 24 6f 75 74 20 24 63 6d 64 0a 20 20 63 6c 6f   $out $cmd.  clo
6480: 73 65 20 24 6f 75 74 0a 20 20 73 65 74 20 6c 69  se $out.  set li
6490: 6e 65 20 22 65 78 65 63 20 24 43 4c 49 20 24 64  ne "exec $CLI $d
64a0: 62 20 3c 20 63 6d 64 73 2e 74 78 74 22 0a 20 20  b < cmds.txt".  
64b0: 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 20  set rc [catch { 
64c0: 65 76 61 6c 20 24 6c 69 6e 65 20 7d 20 6d 73 67  eval $line } msg
64d0: 5d 0a 20 20 6c 69 73 74 20 24 72 63 20 24 6d 73  ].  list $rc $ms
64e0: 67 0a 7d 0a 0a 70 72 6f 63 20 63 61 74 63 68 63  g.}..proc catchc
64f0: 6d 64 65 78 20 7b 64 62 20 7b 63 6d 64 20 22 22  mdex {db {cmd ""
6500: 7d 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 43 4c  }} {.  global CL
6510: 49 0a 20 20 73 65 74 20 6f 75 74 20 5b 6f 70 65  I.  set out [ope
6520: 6e 20 63 6d 64 73 2e 74 78 74 20 77 5d 0a 20 20  n cmds.txt w].  
6530: 66 63 6f 6e 66 69 67 75 72 65 20 24 6f 75 74 20  fconfigure $out 
6540: 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79  -encoding binary
6550: 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69   -translation bi
6560: 6e 61 72 79 0a 20 20 70 75 74 73 20 2d 6e 6f 6e  nary.  puts -non
6570: 65 77 6c 69 6e 65 20 24 6f 75 74 20 24 63 6d 64  ewline $out $cmd
6580: 0a 20 20 63 6c 6f 73 65 20 24 6f 75 74 0a 20 20  .  close $out.  
6590: 73 65 74 20 6c 69 6e 65 20 22 65 78 65 63 20 2d  set line "exec -
65a0: 6b 65 65 70 6e 65 77 6c 69 6e 65 20 2d 2d 20 24  keepnewline -- $
65b0: 43 4c 49 20 24 64 62 20 3c 20 63 6d 64 73 2e 74  CLI $db < cmds.t
65c0: 78 74 22 0a 20 20 73 65 74 20 63 68 61 6e 73 20  xt".  set chans 
65d0: 5b 6c 69 73 74 20 73 74 64 69 6e 20 73 74 64 6f  [list stdin stdo
65e0: 75 74 20 73 74 64 65 72 72 5d 0a 20 20 66 6f 72  ut stderr].  for
65f0: 65 61 63 68 20 63 68 61 6e 20 24 63 68 61 6e 73  each chan $chans
6600: 20 7b 0a 20 20 20 20 63 61 74 63 68 20 7b 0a 20   {.    catch {. 
6610: 20 20 20 20 20 73 65 74 20 6d 6f 64 65 73 28 24       set modes($
6620: 63 68 61 6e 29 20 5b 66 63 6f 6e 66 69 67 75 72  chan) [fconfigur
6630: 65 20 24 63 68 61 6e 5d 0a 20 20 20 20 20 20 66  e $chan].      f
6640: 63 6f 6e 66 69 67 75 72 65 20 24 63 68 61 6e 20  configure $chan 
6650: 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79  -encoding binary
6660: 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69   -translation bi
6670: 6e 61 72 79 20 2d 62 75 66 66 65 72 69 6e 67 20  nary -buffering 
6680: 6e 6f 6e 65 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  none.    }.  }. 
6690: 20 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b   set rc [catch {
66a0: 20 65 76 61 6c 20 24 6c 69 6e 65 20 7d 20 6d 73   eval $line } ms
66b0: 67 5d 0a 20 20 66 6f 72 65 61 63 68 20 63 68 61  g].  foreach cha
66c0: 6e 20 24 63 68 61 6e 73 20 7b 0a 20 20 20 20 63  n $chans {.    c
66d0: 61 74 63 68 20 7b 0a 20 20 20 20 20 20 65 76 61  atch {.      eva
66e0: 6c 20 66 63 6f 6e 66 69 67 75 72 65 20 5b 6c 69  l fconfigure [li
66f0: 73 74 20 24 63 68 61 6e 5d 20 24 6d 6f 64 65 73  st $chan] $modes
6700: 28 24 63 68 61 6e 29 0a 20 20 20 20 7d 0a 20 20  ($chan).    }.  
6710: 7d 0a 20 20 23 20 70 75 74 73 20 5b 64 75 6d 70  }.  # puts [dump
6720: 62 79 74 65 73 20 24 6d 73 67 5d 0a 20 20 6c 69  bytes $msg].  li
6730: 73 74 20 24 72 63 20 24 6d 73 67 0a 7d 0a 0a 70  st $rc $msg.}..p
6740: 72 6f 63 20 66 69 6c 65 70 61 74 68 5f 6e 6f 72  roc filepath_nor
6750: 6d 61 6c 69 7a 65 20 7b 70 7d 20 7b 0a 20 20 23  malize {p} {.  #
6760: 20 74 65 73 74 20 63 61 73 65 73 20 73 68 6f 75   test cases shou
6770: 6c 64 20 62 65 20 77 72 69 74 74 65 6e 20 74 6f  ld be written to
6780: 20 61 73 73 75 6d 65 20 22 75 6e 69 78 22 2d 6c   assume "unix"-l
6790: 69 6b 65 20 66 69 6c 65 20 70 61 74 68 73 0a 20  ike file paths. 
67a0: 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74   if {$::tcl_plat
67b0: 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 21 3d  form(platform)!=
67c0: 22 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20 23 20  "unix"} {.    # 
67d0: 6c 72 65 76 65 72 73 65 2a 32 20 61 73 20 61 20  lreverse*2 as a 
67e0: 68 61 63 6b 20 74 6f 20 72 65 6d 6f 76 65 20 61  hack to remove a
67f0: 6e 79 20 75 6e 6e 65 65 64 65 64 20 7b 7d 20 61  ny unneeded {} a
6800: 66 74 65 72 20 74 68 65 20 73 74 72 69 6e 67 20  fter the string 
6810: 6d 61 70 0a 20 20 20 20 6c 72 65 76 65 72 73 65  map.    lreverse
6820: 20 5b 6c 72 65 76 65 72 73 65 20 5b 73 74 72 69   [lreverse [stri
6830: 6e 67 20 6d 61 70 20 7b 5c 5c 20 2f 7d 20 5b 72  ng map {\\ /} [r
6840: 65 67 73 75 62 20 2d 6e 6f 63 61 73 65 20 2d 61  egsub -nocase -a
6850: 6c 6c 20 7b 5b 61 2d 7a 5d 3a 5b 2f 5c 5c 5d 2b  ll {[a-z]:[/\\]+
6860: 7d 20 24 70 20 7b 2f 7d 5d 5d 5d 0a 20 20 7d 20  } $p {/}]]].  } 
6870: 7b 0a 20 20 20 20 73 65 74 20 70 0a 20 20 7d 0a  {.    set p.  }.
6880: 7d 0a 70 72 6f 63 20 64 6f 5f 66 69 6c 65 70 61  }.proc do_filepa
6890: 74 68 5f 74 65 73 74 20 7b 6e 61 6d 65 20 63 6d  th_test {name cm
68a0: 64 20 65 78 70 65 63 74 65 64 7d 20 7b 0a 20 20  d expected} {.  
68b0: 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 64 6f  uplevel [list do
68c0: 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 0a 20 20  _test $name [.  
68d0: 20 20 73 75 62 73 74 20 2d 6e 6f 63 6f 6d 6d 61    subst -nocomma
68e0: 6e 64 73 20 7b 20 66 69 6c 65 70 61 74 68 5f 6e  nds { filepath_n
68f0: 6f 72 6d 61 6c 69 7a 65 20 5b 20 24 63 6d 64 20  ormalize [ $cmd 
6900: 5d 20 7d 0a 20 20 5d 20 5b 66 69 6c 65 70 61 74  ] }.  ] [filepat
6910: 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 24 65 78 70  h_normalize $exp
6920: 65 63 74 65 64 5d 5d 0a 7d 0a 0a 70 72 6f 63 20  ected]].}..proc 
6930: 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a  realnum_normaliz
6940: 65 20 7b 72 7d 20 7b 0a 20 20 23 20 64 69 66 66  e {r} {.  # diff
6950: 65 72 65 6e 74 20 54 43 4c 20 76 65 72 73 69 6f  erent TCL versio
6960: 6e 73 20 64 69 73 70 6c 61 79 20 66 6c 6f 61 74  ns display float
6970: 69 6e 67 20 70 6f 69 6e 74 20 76 61 6c 75 65 73  ing point values
6980: 20 64 69 66 66 65 72 65 6e 74 6c 79 2e 0a 20 20   differently..  
6990: 73 74 72 69 6e 67 20 6d 61 70 20 7b 31 2e 23 49  string map {1.#I
69a0: 4e 46 20 69 6e 66 20 49 6e 66 20 69 6e 66 20 2e  NF inf Inf inf .
69b0: 30 65 20 65 7d 20 5b 72 65 67 73 75 62 20 2d 61  0e e} [regsub -a
69c0: 6c 6c 20 7b 28 65 5b 2b 2d 5d 29 30 2b 7d 20 24  ll {(e[+-])0+} $
69d0: 72 20 7b 5c 31 7d 5d 0a 7d 0a 70 72 6f 63 20 64  r {\1}].}.proc d
69e0: 6f 5f 72 65 61 6c 6e 75 6d 5f 74 65 73 74 20 7b  o_realnum_test {
69f0: 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65  name cmd expecte
6a00: 64 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 5b  d} {.  uplevel [
6a10: 6c 69 73 74 20 64 6f 5f 74 65 73 74 20 24 6e 61  list do_test $na
6a20: 6d 65 20 5b 0a 20 20 20 20 73 75 62 73 74 20 2d  me [.    subst -
6a30: 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b 20 72 65 61  nocommands { rea
6a40: 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20 5b  lnum_normalize [
6a50: 20 24 63 6d 64 20 5d 20 7d 0a 20 20 5d 20 5b 72   $cmd ] }.  ] [r
6a60: 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65  ealnum_normalize
6a70: 20 24 65 78 70 65 63 74 65 64 5d 5d 0a 7d 0a 0a   $expected]].}..
6a80: 70 72 6f 63 20 66 69 78 5f 74 65 73 74 6e 61 6d  proc fix_testnam
6a90: 65 20 7b 76 61 72 6e 61 6d 65 7d 20 7b 0a 20 20  e {varname} {.  
6aa0: 75 70 76 61 72 20 24 76 61 72 6e 61 6d 65 20 74  upvar $varname t
6ab0: 65 73 74 6e 61 6d 65 0a 20 20 69 66 20 7b 5b 69  estname.  if {[i
6ac0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 74 65 73  nfo exists ::tes
6ad0: 74 70 72 65 66 69 78 5d 0a 20 20 20 26 26 20 5b  tprefix].   && [
6ae0: 73 74 72 69 6e 67 20 69 73 20 64 69 67 69 74 20  string is digit 
6af0: 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 74  [string range $t
6b00: 65 73 74 6e 61 6d 65 20 30 20 30 5d 5d 0a 20 20  estname 0 0]].  
6b10: 7d 20 7b 0a 20 20 20 20 73 65 74 20 74 65 73 74  } {.    set test
6b20: 6e 61 6d 65 20 22 24 7b 3a 3a 74 65 73 74 70 72  name "${::testpr
6b30: 65 66 69 78 7d 2d 24 74 65 73 74 6e 61 6d 65 22  efix}-$testname"
6b40: 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 6e 6f 72  .  }.}..proc nor
6b50: 6d 61 6c 69 7a 65 5f 6c 69 73 74 20 7b 4c 7d 20  malize_list {L} 
6b60: 7b 0a 20 20 73 65 74 20 4c 32 20 5b 6c 69 73 74  {.  set L2 [list
6b70: 5d 0a 20 20 66 6f 72 65 61 63 68 20 6c 20 24 4c  ].  foreach l $L
6b80: 20 7b 6c 61 70 70 65 6e 64 20 4c 32 20 24 6c 7d   {lappend L2 $l}
6b90: 0a 20 20 73 65 74 20 4c 32 0a 7d 0a 0a 23 20 45  .  set L2.}..# E
6ba0: 69 74 68 65 72 3a 0a 23 0a 23 20 20 20 64 6f 5f  ither:.#.#   do_
6bb0: 65 78 65 63 73 71 6c 5f 74 65 73 74 20 54 45 53  execsql_test TES
6bc0: 54 4e 41 4d 45 20 53 51 4c 20 3f 52 45 53 3f 0a  TNAME SQL ?RES?.
6bd0: 23 20 20 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74  #   do_execsql_t
6be0: 65 73 74 20 2d 64 62 20 44 42 20 54 45 53 54 4e  est -db DB TESTN
6bf0: 41 4d 45 20 53 51 4c 20 3f 52 45 53 3f 0a 23 0a  AME SQL ?RES?.#.
6c00: 70 72 6f 63 20 64 6f 5f 65 78 65 63 73 71 6c 5f  proc do_execsql_
6c10: 74 65 73 74 20 7b 61 72 67 73 7d 20 7b 0a 20 20  test {args} {.  
6c20: 73 65 74 20 64 62 20 64 62 0a 20 20 69 66 20 7b  set db db.  if {
6c30: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d  [lindex $args 0]
6c40: 3d 3d 22 2d 64 62 22 7d 20 7b 0a 20 20 20 20 73  =="-db"} {.    s
6c50: 65 74 20 64 62 20 5b 6c 69 6e 64 65 78 20 24 61  et db [lindex $a
6c60: 72 67 73 20 31 5d 0a 20 20 20 20 73 65 74 20 61  rgs 1].    set a
6c70: 72 67 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67  rgs [lrange $arg
6c80: 73 20 32 20 65 6e 64 5d 0a 20 20 7d 0a 0a 20 20  s 2 end].  }..  
6c90: 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72  if {[llength $ar
6ca0: 67 73 5d 3d 3d 32 7d 20 7b 0a 20 20 20 20 66 6f  gs]==2} {.    fo
6cb0: 72 65 61 63 68 20 7b 74 65 73 74 6e 61 6d 65 20  reach {testname 
6cc0: 73 71 6c 7d 20 24 61 72 67 73 20 7b 7d 0a 20 20  sql} $args {}.  
6cd0: 20 20 73 65 74 20 72 65 73 75 6c 74 20 22 22 0a    set result "".
6ce0: 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 6c 6c 65    } elseif {[lle
6cf0: 6e 67 74 68 20 24 61 72 67 73 5d 3d 3d 33 7d 20  ngth $args]==3} 
6d00: 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74  {.    foreach {t
6d10: 65 73 74 6e 61 6d 65 20 73 71 6c 20 72 65 73 75  estname sql resu
6d20: 6c 74 7d 20 24 61 72 67 73 20 7b 7d 0a 20 20 7d  lt} $args {}.  }
6d30: 20 65 6c 73 65 20 7b 0a 20 20 20 20 65 72 72 6f   else {.    erro
6d40: 72 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 7b  r [string trim {
6d50: 0a 20 20 20 20 20 20 77 72 6f 6e 67 20 23 20 61  .      wrong # a
6d60: 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 22  rgs: should be "
6d70: 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20  do_execsql_test 
6d80: 3f 2d 64 62 20 44 42 3f 20 74 65 73 74 6e 61 6d  ?-db DB? testnam
6d90: 65 20 73 71 6c 20 3f 72 65 73 75 6c 74 3f 22 0a  e sql ?result?".
6da0: 20 20 20 20 7d 5d 0a 20 20 7d 0a 0a 20 20 66 69      }].  }..  fi
6db0: 78 5f 74 65 73 74 6e 61 6d 65 20 74 65 73 74 6e  x_testname testn
6dc0: 61 6d 65 0a 0a 20 20 75 70 6c 65 76 65 6c 20 64  ame..  uplevel d
6dd0: 6f 5f 74 65 73 74 20 20 20 20 20 20 20 20 20 20  o_test          
6de0: 20 20 20 20 20 20 20 5c 0a 20 20 20 20 20 20 5b         \.      [
6df0: 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d 20  list $testname] 
6e00: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
6e10: 20 20 20 5b 6c 69 73 74 20 22 65 78 65 63 73 71     [list "execsq
6e20: 6c 20 7b 24 73 71 6c 7d 20 24 64 62 22 5d 20 5c  l {$sql} $db"] \
6e30: 0a 20 20 20 20 20 20 5b 6c 69 73 74 20 5b 6c 69  .      [list [li
6e40: 73 74 20 7b 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a  st {*}$result]].
6e50: 7d 0a 0a 70 72 6f 63 20 64 6f 5f 63 61 74 63 68  }..proc do_catch
6e60: 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61  sql_test {testna
6e70: 6d 65 20 73 71 6c 20 72 65 73 75 6c 74 7d 20 7b  me sql result} {
6e80: 0a 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20  .  fix_testname 
6e90: 74 65 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76  testname.  uplev
6ea0: 65 6c 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74  el do_test [list
6eb0: 20 24 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73   $testname] [lis
6ec0: 74 20 22 63 61 74 63 68 73 71 6c 20 7b 24 73 71  t "catchsql {$sq
6ed0: 6c 7d 22 5d 20 5b 6c 69 73 74 20 24 72 65 73 75  l}"] [list $resu
6ee0: 6c 74 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 74 69  lt].}.proc do_ti
6ef0: 6d 65 64 5f 65 78 65 63 73 71 6c 5f 74 65 73 74  med_execsql_test
6f00: 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 7b   {testname sql {
6f10: 72 65 73 75 6c 74 20 7b 7d 7d 7d 20 7b 0a 20 20  result {}}} {.  
6f20: 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 74 65 73  fix_testname tes
6f30: 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76 65 6c 20  tname.  uplevel 
6f40: 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74 20 24 74  do_test [list $t
6f50: 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73 74 20 22  estname] [list "
6f60: 65 78 65 63 73 71 6c 5f 74 69 6d 65 64 20 7b 24  execsql_timed {$
6f70: 73 71 6c 7d 22 5d 5c 0a 20 20 20 20 20 20 20 20  sql}"]\.        
6f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f90: 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 73 74             [list
6fa0: 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 75 6c   [list {*}$resul
6fb0: 74 5d 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 65 71  t]].}.proc do_eq
6fc0: 70 5f 74 65 73 74 20 7b 6e 61 6d 65 20 73 71 6c  p_test {name sql
6fd0: 20 72 65 73 7d 20 7b 0a 20 20 75 70 6c 65 76 65   res} {.  upleve
6fe0: 6c 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73  l do_execsql_tes
6ff0: 74 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20 22 45  t $name [list "E
7000: 58 50 4c 41 49 4e 20 51 55 45 52 59 20 50 4c 41  XPLAIN QUERY PLA
7010: 4e 20 24 73 71 6c 22 5d 20 5b 6c 69 73 74 20 24  N $sql"] [list $
7020: 72 65 73 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  res].}..#-------
7030: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7040: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7050: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7060: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7070: 2d 2d 0a 23 20 20 20 55 73 61 67 65 3a 20 64 6f  --.#   Usage: do
7080: 5f 73 65 6c 65 63 74 5f 74 65 73 74 73 20 50 52  _select_tests PR
7090: 45 46 49 58 20 3f 53 57 49 54 43 48 45 53 3f 20  EFIX ?SWITCHES? 
70a0: 54 45 53 54 4c 49 53 54 0a 23 0a 23 20 57 68 65  TESTLIST.#.# Whe
70b0: 72 65 20 73 77 69 74 63 68 65 73 20 61 72 65 3a  re switches are:
70c0: 0a 23 0a 23 20 20 20 2d 65 72 72 6f 72 66 6f 72  .#.#   -errorfor
70d0: 6d 61 74 20 46 4d 54 53 54 52 49 4e 47 0a 23 20  mat FMTSTRING.# 
70e0: 20 20 2d 63 6f 75 6e 74 0a 23 20 20 20 2d 71 75    -count.#   -qu
70f0: 65 72 79 20 53 51 4c 0a 23 20 20 20 2d 74 63 6c  ery SQL.#   -tcl
7100: 71 75 65 72 79 20 54 43 4c 0a 23 20 20 20 2d 72  query TCL.#   -r
7110: 65 70 61 69 72 20 54 43 4c 0a 23 0a 70 72 6f 63  epair TCL.#.proc
7120: 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74 73   do_select_tests
7130: 20 7b 70 72 65 66 69 78 20 61 72 67 73 7d 20 7b   {prefix args} {
7140: 0a 0a 20 20 73 65 74 20 74 65 73 74 6c 69 73 74  ..  set testlist
7150: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65   [lindex $args e
7160: 6e 64 5d 0a 20 20 73 65 74 20 73 77 69 74 63 68  nd].  set switch
7170: 65 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73  es [lrange $args
7180: 20 30 20 65 6e 64 2d 31 5d 0a 0a 20 20 73 65 74   0 end-1]..  set
7190: 20 65 72 72 66 6d 74 20 22 22 0a 20 20 73 65 74   errfmt "".  set
71a0: 20 63 6f 75 6e 74 6f 6e 6c 79 20 30 0a 20 20 73   countonly 0.  s
71b0: 65 74 20 74 63 6c 71 75 65 72 79 20 22 22 0a 20  et tclquery "". 
71c0: 20 73 65 74 20 72 65 70 61 69 72 20 22 22 0a 0a   set repair ""..
71d0: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
71e0: 7b 24 69 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24  {$i < [llength $
71f0: 73 77 69 74 63 68 65 73 5d 7d 20 7b 69 6e 63 72  switches]} {incr
7200: 20 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 20   i} {.    set s 
7210: 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68 65  [lindex $switche
7220: 73 20 24 69 5d 0a 20 20 20 20 73 65 74 20 6e 20  s $i].    set n 
7230: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
7240: 73 5d 0a 20 20 20 20 69 66 20 7b 24 6e 3e 3d 32  s].    if {$n>=2
7250: 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61   && [string equa
7260: 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20  l -length $n $s 
7270: 22 2d 71 75 65 72 79 22 5d 7d 20 7b 0a 20 20 20  "-query"]} {.   
7280: 20 20 20 73 65 74 20 74 63 6c 71 75 65 72 79 20     set tclquery 
7290: 5b 6c 69 73 74 20 65 78 65 63 73 71 6c 20 5b 6c  [list execsql [l
72a0: 69 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20  index $switches 
72b0: 5b 69 6e 63 72 20 69 5d 5d 5d 0a 20 20 20 20 7d  [incr i]]].    }
72c0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26   elseif {$n>=2 &
72d0: 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20  & [string equal 
72e0: 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d  -length $n $s "-
72f0: 74 63 6c 71 75 65 72 79 22 5d 7d 20 7b 0a 20 20  tclquery"]} {.  
7300: 20 20 20 20 73 65 74 20 74 63 6c 71 75 65 72 79      set tclquery
7310: 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68   [lindex $switch
7320: 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20  es [incr i]].   
7330: 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32   } elseif {$n>=2
7340: 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61   && [string equa
7350: 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20  l -length $n $s 
7360: 22 2d 65 72 72 6f 72 66 6f 72 6d 61 74 22 5d 7d  "-errorformat"]}
7370: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 65 72 72   {.      set err
7380: 66 6d 74 20 5b 6c 69 6e 64 65 78 20 24 73 77 69  fmt [lindex $swi
7390: 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a  tches [incr i]].
73a0: 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e      } elseif {$n
73b0: 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65  >=2 && [string e
73c0: 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20  qual -length $n 
73d0: 24 73 20 22 2d 72 65 70 61 69 72 22 5d 7d 20 7b  $s "-repair"]} {
73e0: 0a 20 20 20 20 20 20 73 65 74 20 72 65 70 61 69  .      set repai
73f0: 72 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63  r [lindex $switc
7400: 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20  hes [incr i]].  
7410: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d    } elseif {$n>=
7420: 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75  2 && [string equ
7430: 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73  al -length $n $s
7440: 20 22 2d 63 6f 75 6e 74 22 5d 7d 20 7b 0a 20 20   "-count"]} {.  
7450: 20 20 20 20 73 65 74 20 63 6f 75 6e 74 6f 6e 6c      set countonl
7460: 79 20 31 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  y 1.    } else {
7470: 0a 20 20 20 20 20 20 65 72 72 6f 72 20 22 75 6e  .      error "un
7480: 6b 6e 6f 77 6e 20 73 77 69 74 63 68 3a 20 24 73  known switch: $s
7490: 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ".    }.  }..  i
74a0: 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c 79 20 26 26  f {$countonly &&
74b0: 20 24 65 72 72 66 6d 74 21 3d 22 22 7d 20 7b 0a   $errfmt!=""} {.
74c0: 20 20 20 20 65 72 72 6f 72 20 22 43 61 6e 6e 6f      error "Canno
74d0: 74 20 75 73 65 20 2d 63 6f 75 6e 74 20 61 6e 64  t use -count and
74e0: 20 2d 65 72 72 6f 72 66 6f 72 6d 61 74 20 74 6f   -errorformat to
74f0: 67 65 74 68 65 72 22 0a 20 20 7d 0a 20 20 73 65  gether".  }.  se
7500: 74 20 6e 54 65 73 74 6c 69 73 74 20 5b 6c 6c 65  t nTestlist [lle
7510: 6e 67 74 68 20 24 74 65 73 74 6c 69 73 74 5d 0a  ngth $testlist].
7520: 20 20 69 66 20 7b 24 6e 54 65 73 74 6c 69 73 74    if {$nTestlist
7530: 25 33 20 7c 7c 20 24 6e 54 65 73 74 6c 69 73 74  %3 || $nTestlist
7540: 3d 3d 30 20 7d 20 7b 0a 20 20 20 20 65 72 72 6f  ==0 } {.    erro
7550: 72 20 22 53 45 4c 45 43 54 20 74 65 73 74 20 6c  r "SELECT test l
7560: 69 73 74 20 63 6f 6e 74 61 69 6e 73 20 5b 6c 6c  ist contains [ll
7570: 65 6e 67 74 68 20 24 74 65 73 74 6c 69 73 74 5d  ength $testlist]
7580: 20 65 6c 65 6d 65 6e 74 73 22 0a 20 20 7d 0a 0a   elements".  }..
7590: 20 20 65 76 61 6c 20 24 72 65 70 61 69 72 0a 20    eval $repair. 
75a0: 20 66 6f 72 65 61 63 68 20 7b 74 6e 20 73 71 6c   foreach {tn sql
75b0: 20 72 65 73 7d 20 24 74 65 73 74 6c 69 73 74 20   res} $testlist 
75c0: 7b 0a 20 20 20 20 69 66 20 7b 24 74 63 6c 71 75  {.    if {$tclqu
75d0: 65 72 79 20 21 3d 20 22 22 7d 20 7b 0a 20 20 20  ery != ""} {.   
75e0: 20 20 20 65 78 65 63 73 71 6c 20 24 73 71 6c 0a     execsql $sql.
75f0: 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f        uplevel do
7600: 5f 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d 2e  _test ${prefix}.
7610: 24 74 6e 20 5b 6c 69 73 74 20 24 74 63 6c 71 75  $tn [list $tclqu
7620: 65 72 79 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74  ery] [list [list
7630: 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20 20 20 20 7d   {*}$res]].    }
7640: 20 65 6c 73 65 69 66 20 7b 24 63 6f 75 6e 74 6f   elseif {$counto
7650: 6e 6c 79 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  nly} {.      set
7660: 20 6e 52 6f 77 20 30 0a 20 20 20 20 20 20 64 62   nRow 0.      db
7670: 20 65 76 61 6c 20 24 73 71 6c 20 7b 69 6e 63 72   eval $sql {incr
7680: 20 6e 52 6f 77 7d 0a 20 20 20 20 20 20 75 70 6c   nRow}.      upl
7690: 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 7b 70  evel do_test ${p
76a0: 72 65 66 69 78 7d 2e 24 74 6e 20 5b 6c 69 73 74  refix}.$tn [list
76b0: 20 5b 6c 69 73 74 20 73 65 74 20 7b 7d 20 24 6e   [list set {} $n
76c0: 52 6f 77 5d 5d 20 5b 6c 69 73 74 20 24 72 65 73  Row]] [list $res
76d0: 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b  ].    } elseif {
76e0: 24 65 72 72 66 6d 74 3d 3d 22 22 7d 20 7b 0a 20  $errfmt==""} {. 
76f0: 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f       uplevel do_
7700: 65 78 65 63 73 71 6c 5f 74 65 73 74 20 24 7b 70  execsql_test ${p
7710: 72 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69  refix}.${tn} [li
7720: 73 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74 20 5b  st $sql] [list [
7730: 6c 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20  list {*}$res]]. 
7740: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
7750: 20 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74 20    set res [list 
7760: 31 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 5b  1 [string trim [
7770: 66 6f 72 6d 61 74 20 24 65 72 72 66 6d 74 20 7b  format $errfmt {
7780: 2a 7d 24 72 65 73 5d 5d 5d 0a 20 20 20 20 20 20  *}$res]]].      
7790: 75 70 6c 65 76 65 6c 20 64 6f 5f 63 61 74 63 68  uplevel do_catch
77a0: 73 71 6c 5f 74 65 73 74 20 24 7b 70 72 65 66 69  sql_test ${prefi
77b0: 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69 73 74 20 24  x}.${tn} [list $
77c0: 73 71 6c 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d  sql] [list $res]
77d0: 0a 20 20 20 20 7d 0a 20 20 20 20 65 76 61 6c 20  .    }.    eval 
77e0: 24 72 65 70 61 69 72 0a 20 20 7d 0a 0a 7d 0a 0a  $repair.  }..}..
77f0: 70 72 6f 63 20 64 65 6c 65 74 65 5f 61 6c 6c 5f  proc delete_all_
7800: 64 61 74 61 20 7b 7d 20 7b 0a 20 20 64 62 20 65  data {} {.  db e
7810: 76 61 6c 20 7b 53 45 4c 45 43 54 20 74 62 6c 5f  val {SELECT tbl_
7820: 6e 61 6d 65 20 41 53 20 74 20 46 52 4f 4d 20 73  name AS t FROM s
7830: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45  qlite_master WHE
7840: 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65  RE type = 'table
7850: 27 7d 20 7b 0a 20 20 20 20 64 62 20 65 76 61 6c  '} {.    db eval
7860: 20 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 27 5b   "DELETE FROM '[
7870: 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27 27  string map {' ''
7880: 7d 20 24 74 5d 27 22 0a 20 20 7d 0a 7d 0a 0a 23  } $t]'".  }.}..#
7890: 20 52 75 6e 20 61 6e 20 53 51 4c 20 73 63 72 69   Run an SQL scri
78a0: 70 74 2e 0a 23 20 52 65 74 75 72 6e 20 74 68 65  pt..# Return the
78b0: 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69 63 72 6f   number of micro
78c0: 73 65 63 6f 6e 64 73 20 70 65 72 20 73 74 61 74  seconds per stat
78d0: 65 6d 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 70  ement..#.proc sp
78e0: 65 65 64 5f 74 72 69 61 6c 20 7b 6e 61 6d 65 20  eed_trial {name 
78f0: 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73 71  numstmt units sq
7900: 6c 7d 20 7b 0a 20 20 6f 75 74 70 75 74 32 20 2d  l} {.  output2 -
7910: 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f 72 6d 61  nonewline [forma
7920: 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d 20 24 6e  t {%-21.21s } $n
7930: 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68 20  ame...].  flush 
7940: 73 74 64 6f 75 74 0a 20 20 73 65 74 20 73 70 65  stdout.  set spe
7950: 65 64 20 5b 74 69 6d 65 20 7b 73 71 6c 69 74 65  ed [time {sqlite
7960: 33 5f 65 78 65 63 5f 6e 72 20 64 62 20 24 73 71  3_exec_nr db $sq
7970: 6c 7d 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69  l}].  set tm [li
7980: 6e 64 65 78 20 24 73 70 65 65 64 20 30 5d 0a 20  ndex $speed 0]. 
7990: 20 69 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b   if {$tm == 0} {
79a0: 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b 66  .    set rate [f
79b0: 6f 72 6d 61 74 20 25 32 30 73 20 22 6d 61 6e 79  ormat %20s "many
79c0: 22 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  "].  } else {.  
79d0: 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d    set rate [form
79e0: 61 74 20 25 32 30 2e 35 66 20 5b 65 78 70 72 20  at %20.5f [expr 
79f0: 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73  {1000000.0*$nums
7a00: 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20  tmt/$tm}]].  }. 
7a10: 20 73 65 74 20 75 32 20 24 75 6e 69 74 73 2f 73   set u2 $units/s
7a20: 0a 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d  .  output2 [form
7a30: 61 74 20 7b 25 31 32 64 20 75 53 20 25 73 20 25  at {%12d uS %s %
7a40: 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24 75 32  s} $tm $rate $u2
7a50: 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  ].  global total
7a60: 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61  _time.  set tota
7a70: 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b 24 74  l_time [expr {$t
7a80: 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a  otal_time+$tm}].
7a90: 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73 70 65 65    lappend ::spee
7aa0: 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 24 6e  d_trial_times $n
7ab0: 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f 63 20 73  ame $tm.}.proc s
7ac0: 70 65 65 64 5f 74 72 69 61 6c 5f 74 63 6c 20 7b  peed_trial_tcl {
7ad0: 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e 69  name numstmt uni
7ae0: 74 73 20 73 63 72 69 70 74 7d 20 7b 0a 20 20 6f  ts script} {.  o
7af0: 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e  utput2 -nonewlin
7b00: 65 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e  e [format {%-21.
7b10: 32 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a  21s } $name...].
7b20: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20    flush stdout. 
7b30: 20 73 65 74 20 73 70 65 65 64 20 5b 74 69 6d 65   set speed [time
7b40: 20 7b 65 76 61 6c 20 24 73 63 72 69 70 74 7d 5d   {eval $script}]
7b50: 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65  .  set tm [linde
7b60: 78 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69 66  x $speed 0].  if
7b70: 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20   {$tm == 0} {.  
7b80: 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d    set rate [form
7b90: 61 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a  at %20s "many"].
7ba0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73    } else {.    s
7bb0: 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20  et rate [format 
7bc0: 25 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31 30  %20.5f [expr {10
7bd0: 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74  00000.0*$numstmt
7be0: 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65  /$tm}]].  }.  se
7bf0: 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20  t u2 $units/s.  
7c00: 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20  output2 [format 
7c10: 7b 25 31 32 64 20 75 53 20 25 73 20 25 73 7d 20  {%12d uS %s %s} 
7c20: 24 74 6d 20 24 72 61 74 65 20 24 75 32 5d 0a 20  $tm $rate $u2]. 
7c30: 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69   global total_ti
7c40: 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74  me.  set total_t
7c50: 69 6d 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61  ime [expr {$tota
7c60: 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c  l_time+$tm}].  l
7c70: 61 70 70 65 6e 64 20 3a 3a 73 70 65 65 64 5f 74  append ::speed_t
7c80: 72 69 61 6c 5f 74 69 6d 65 73 20 24 6e 61 6d 65  rial_times $name
7c90: 20 24 74 6d 0a 7d 0a 70 72 6f 63 20 73 70 65 65   $tm.}.proc spee
7ca0: 64 5f 74 72 69 61 6c 5f 69 6e 69 74 20 7b 6e 61  d_trial_init {na
7cb0: 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 74  me} {.  global t
7cc0: 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20  otal_time.  set 
7cd0: 74 6f 74 61 6c 5f 74 69 6d 65 20 30 0a 20 20 73  total_time 0.  s
7ce0: 65 74 20 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  et ::speed_trial
7cf0: 5f 74 69 6d 65 73 20 5b 6c 69 73 74 5d 0a 20 20  _times [list].  
7d00: 73 71 6c 69 74 65 33 20 76 65 72 73 64 62 20 3a  sqlite3 versdb :
7d10: 6d 65 6d 6f 72 79 3a 0a 20 20 73 65 74 20 76 65  memory:.  set ve
7d20: 72 73 20 5b 76 65 72 73 64 62 20 6f 6e 65 20 7b  rs [versdb one {
7d30: 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f 73 6f  SELECT sqlite_so
7d40: 75 72 63 65 5f 69 64 28 29 7d 5d 0a 20 20 76 65  urce_id()}].  ve
7d50: 72 73 64 62 20 63 6c 6f 73 65 0a 20 20 6f 75 74  rsdb close.  out
7d60: 70 75 74 32 20 22 53 51 4c 69 74 65 20 24 76 65  put2 "SQLite $ve
7d70: 72 73 22 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64  rs".}.proc speed
7d80: 5f 74 72 69 61 6c 5f 73 75 6d 6d 61 72 79 20 7b  _trial_summary {
7d90: 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c  name} {.  global
7da0: 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 6f 75   total_time.  ou
7db0: 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25  tput2 [format {%
7dc0: 2d 32 31 2e 32 31 73 20 25 31 32 64 20 75 53 20  -21.21s %12d uS 
7dd0: 54 4f 54 41 4c 7d 20 24 6e 61 6d 65 20 24 74 6f  TOTAL} $name $to
7de0: 74 61 6c 5f 74 69 6d 65 5d 0a 0a 20 20 69 66 20  tal_time]..  if 
7df0: 7b 20 30 20 7d 20 7b 0a 20 20 20 20 73 71 6c 69  { 0 } {.    sqli
7e00: 74 65 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f  te3 versdb :memo
7e10: 72 79 3a 0a 20 20 20 20 73 65 74 20 76 65 72 73  ry:.    set vers
7e20: 20 5b 6c 69 6e 64 65 78 20 5b 76 65 72 73 64 62   [lindex [versdb
7e30: 20 6f 6e 65 20 7b 53 45 4c 45 43 54 20 73 71 6c   one {SELECT sql
7e40: 69 74 65 5f 73 6f 75 72 63 65 5f 69 64 28 29 7d  ite_source_id()}
7e50: 5d 20 30 5d 0a 20 20 20 20 76 65 72 73 64 62 20  ] 0].    versdb 
7e60: 63 6c 6f 73 65 0a 20 20 20 20 6f 75 74 70 75 74  close.    output
7e70: 32 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20  2 "CREATE TABLE 
7e80: 49 46 20 4e 4f 54 20 45 58 49 53 54 53 20 74 69  IF NOT EXISTS ti
7e90: 6d 65 28 76 65 72 73 69 6f 6e 2c 20 73 63 72 69  me(version, scri
7ea0: 70 74 2c 20 74 65 73 74 2c 20 75 73 29 3b 22 0a  pt, test, us);".
7eb0: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 65 73      foreach {tes
7ec0: 74 20 75 73 7d 20 24 3a 3a 73 70 65 65 64 5f 74  t us} $::speed_t
7ed0: 72 69 61 6c 5f 74 69 6d 65 73 20 7b 0a 20 20 20  rial_times {.   
7ee0: 20 20 20 6f 75 74 70 75 74 32 20 22 49 4e 53 45     output2 "INSE
7ef0: 52 54 20 49 4e 54 4f 20 74 69 6d 65 20 56 41 4c  RT INTO time VAL
7f00: 55 45 53 28 27 24 76 65 72 73 27 2c 20 27 24 6e  UES('$vers', '$n
7f10: 61 6d 65 27 2c 20 27 24 74 65 73 74 27 2c 20 24  ame', '$test', $
7f20: 75 73 29 3b 22 0a 20 20 20 20 7d 0a 20 20 7d 0a  us);".    }.  }.
7f30: 7d 0a 0a 23 20 52 75 6e 20 74 68 69 73 20 72 6f  }..# Run this ro
7f40: 75 74 69 6e 65 20 6c 61 73 74 0a 23 0a 70 72 6f  utine last.#.pro
7f50: 63 20 66 69 6e 69 73 68 5f 74 65 73 74 20 7b 7d  c finish_test {}
7f60: 20 7b 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63   {.  catch {db c
7f70: 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64  lose}.  catch {d
7f80: 62 31 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  b1 close}.  catc
7f90: 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20  h {db2 close}.  
7fa0: 63 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65  catch {db3 close
7fb0: 7d 0a 20 20 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f  }.  if {0==[info
7fc0: 20 65 78 69 73 74 73 20 3a 3a 53 4c 41 56 45 5d   exists ::SLAVE]
7fd0: 7d 20 7b 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73  } { finalize_tes
7fe0: 74 69 6e 67 20 7d 0a 7d 0a 70 72 6f 63 20 66 69  ting }.}.proc fi
7ff0: 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 20 7b  nalize_testing {
8000: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 73 71 6c  } {.  global sql
8010: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
8020: 75 6e 74 0a 0a 20 20 73 65 74 20 6f 6d 69 74 4c  unt..  set omitL
8030: 69 73 74 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  ist [set_test_co
8040: 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74 5d  unter omit_list]
8050: 0a 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c  ..  catch {db cl
8060: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
8070: 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  2 close}.  catch
8080: 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 0a 20 20   {db3 close}..  
8090: 76 66 73 5f 75 6e 6c 69 6e 6b 5f 74 65 73 74 0a  vfs_unlink_test.
80a0: 20 20 73 71 6c 69 74 65 33 20 64 62 20 7b 7d 0a    sqlite3 db {}.
80b0: 20 20 23 20 73 71 6c 69 74 65 33 5f 63 6c 65 61    # sqlite3_clea
80c0: 72 5f 74 73 64 5f 6d 65 6d 64 65 62 75 67 0a 20  r_tsd_memdebug. 
80d0: 20 64 62 20 63 6c 6f 73 65 0a 20 20 73 71 6c 69   db close.  sqli
80e0: 74 65 33 5f 72 65 73 65 74 5f 61 75 74 6f 5f 65  te3_reset_auto_e
80f0: 78 74 65 6e 73 69 6f 6e 0a 0a 20 20 73 71 6c 69  xtension..  sqli
8100: 74 65 33 5f 73 6f 66 74 5f 68 65 61 70 5f 6c 69  te3_soft_heap_li
8110: 6d 69 74 20 30 0a 20 20 73 65 74 20 6e 54 65 73  mit 0.  set nTes
8120: 74 20 5b 69 6e 63 72 5f 6e 74 65 73 74 5d 0a 20  t [incr_ntest]. 
8130: 20 73 65 74 20 6e 45 72 72 20 5b 73 65 74 5f 74   set nErr [set_t
8140: 65 73 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f  est_counter erro
8150: 72 73 5d 0a 0a 20 20 73 65 74 20 6e 4b 6e 6f 77  rs]..  set nKnow
8160: 6e 20 30 0a 20 20 69 66 20 7b 5b 66 69 6c 65 20  n 0.  if {[file 
8170: 72 65 61 64 61 62 6c 65 20 6b 6e 6f 77 6e 2d 70  readable known-p
8180: 72 6f 62 6c 65 6d 73 2e 74 78 74 5d 7d 20 7b 0a  roblems.txt]} {.
8190: 20 20 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e      set fd [open
81a0: 20 6b 6e 6f 77 6e 2d 70 72 6f 62 6c 65 6d 73 2e   known-problems.
81b0: 74 78 74 5d 0a 20 20 20 20 73 65 74 20 63 6f 6e  txt].    set con
81c0: 74 65 6e 74 20 5b 72 65 61 64 20 24 66 64 5d 0a  tent [read $fd].
81d0: 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a 20 20      close $fd.  
81e0: 20 20 66 6f 72 65 61 63 68 20 78 20 24 63 6f 6e    foreach x $con
81f0: 74 65 6e 74 20 7b 73 65 74 20 6b 6e 6f 77 6e 5f  tent {set known_
8200: 65 72 72 6f 72 28 24 78 29 20 31 7d 0a 20 20 20  error($x) 1}.   
8210: 20 66 6f 72 65 61 63 68 20 78 20 5b 73 65 74 5f   foreach x [set_
8220: 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66 61 69  test_counter fai
8230: 6c 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20 20 20  l_list] {.      
8240: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
8250: 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28 24 78 29   known_error($x)
8260: 5d 7d 20 7b 69 6e 63 72 20 6e 4b 6e 6f 77 6e 7d  ]} {incr nKnown}
8270: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 20  .    }.  }.  if 
8280: 7b 24 6e 4b 6e 6f 77 6e 3e 30 7d 20 7b 0a 20 20  {$nKnown>0} {.  
8290: 20 20 6f 75 74 70 75 74 32 20 22 5b 65 78 70 72    output2 "[expr
82a0: 20 7b 24 6e 45 72 72 2d 24 6e 4b 6e 6f 77 6e 7d   {$nErr-$nKnown}
82b0: 5d 20 6e 65 77 20 65 72 72 6f 72 73 20 61 6e 64  ] new errors and
82c0: 20 24 6e 4b 6e 6f 77 6e 20 6b 6e 6f 77 6e 20 65   $nKnown known e
82d0: 72 72 6f 72 73 5c 0a 20 20 20 20 20 20 20 20 20  rrors\.         
82e0: 6f 75 74 20 6f 66 20 24 6e 54 65 73 74 20 74 65  out of $nTest te
82f0: 73 74 73 22 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  sts".  } else {.
8300: 20 20 20 20 73 65 74 20 63 70 75 69 6e 66 6f 20      set cpuinfo 
8310: 7b 7d 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63  {}.    if {[catc
8320: 68 20 7b 65 78 65 63 20 68 6f 73 74 6e 61 6d 65  h {exec hostname
8330: 7d 20 68 6e 61 6d 65 5d 3d 3d 30 7d 20 7b 73 65  } hname]==0} {se
8340: 74 20 63 70 75 69 6e 66 6f 20 5b 73 74 72 69 6e  t cpuinfo [strin
8350: 67 20 74 72 69 6d 20 24 68 6e 61 6d 65 5d 7d 0a  g trim $hname]}.
8360: 20 20 20 20 61 70 70 65 6e 64 20 63 70 75 69 6e      append cpuin
8370: 66 6f 20 22 20 24 3a 3a 74 63 6c 5f 70 6c 61 74  fo " $::tcl_plat
8380: 66 6f 72 6d 28 6f 73 29 22 0a 20 20 20 20 61 70  form(os)".    ap
8390: 70 65 6e 64 20 63 70 75 69 6e 66 6f 20 22 20 5b  pend cpuinfo " [
83a0: 65 78 70 72 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61  expr {$::tcl_pla
83b0: 74 66 6f 72 6d 28 70 6f 69 6e 74 65 72 53 69 7a  tform(pointerSiz
83c0: 65 29 2a 38 7d 5d 2d 62 69 74 22 0a 20 20 20 20  e)*8}]-bit".    
83d0: 61 70 70 65 6e 64 20 63 70 75 69 6e 66 6f 20 22  append cpuinfo "
83e0: 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 45 20   [string map {E 
83f0: 2d 65 7d 20 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  -e} $::tcl_platf
8400: 6f 72 6d 28 62 79 74 65 4f 72 64 65 72 29 5d 22  orm(byteOrder)]"
8410: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 53 51  .    output2 "SQ
8420: 4c 69 74 65 20 5b 73 71 6c 69 74 65 33 20 2d 73  Lite [sqlite3 -s
8430: 6f 75 72 63 65 69 64 5d 22 0a 20 20 20 20 6f 75  ourceid]".    ou
8440: 74 70 75 74 32 20 22 24 6e 45 72 72 20 65 72 72  tput2 "$nErr err
8450: 6f 72 73 20 6f 75 74 20 6f 66 20 24 6e 54 65 73  ors out of $nTes
8460: 74 20 74 65 73 74 73 20 6f 6e 20 24 63 70 75 69  t tests on $cpui
8470: 6e 66 6f 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24  nfo".  }.  if {$
8480: 6e 45 72 72 3e 24 6e 4b 6e 6f 77 6e 7d 20 7b 0a  nErr>$nKnown} {.
8490: 20 20 20 20 6f 75 74 70 75 74 32 20 2d 6e 6f 6e      output2 -non
84a0: 65 77 6c 69 6e 65 20 22 21 46 61 69 6c 75 72 65  ewline "!Failure
84b0: 73 20 6f 6e 20 74 68 65 73 65 20 74 65 73 74 73  s on these tests
84c0: 3a 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 78  :".    foreach x
84d0: 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74   [set_test_count
84e0: 65 72 20 66 61 69 6c 5f 6c 69 73 74 5d 20 7b 0a  er fail_list] {.
84f0: 20 20 20 20 20 20 69 66 20 7b 21 5b 69 6e 66 6f        if {![info
8500: 20 65 78 69 73 74 73 20 6b 6e 6f 77 6e 5f 65 72   exists known_er
8510: 72 6f 72 28 24 78 29 5d 7d 20 7b 6f 75 74 70 75  ror($x)]} {outpu
8520: 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 20  t2 -nonewline " 
8530: 24 78 22 7d 0a 20 20 20 20 7d 0a 20 20 20 20 6f  $x"}.    }.    o
8540: 75 74 70 75 74 32 20 22 22 0a 20 20 7d 0a 20 20  utput2 "".  }.  
8550: 66 6f 72 65 61 63 68 20 77 61 72 6e 69 6e 67 20  foreach warning 
8560: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
8570: 72 20 77 61 72 6e 5f 6c 69 73 74 5d 20 7b 0a 20  r warn_list] {. 
8580: 20 20 20 6f 75 74 70 75 74 32 20 22 57 61 72 6e     output2 "Warn
8590: 69 6e 67 3a 20 24 77 61 72 6e 69 6e 67 22 0a 20  ing: $warning". 
85a0: 20 7d 0a 20 20 72 75 6e 5f 74 68 72 65 61 64 5f   }.  run_thread_
85b0: 74 65 73 74 73 20 31 0a 20 20 69 66 20 7b 5b 6c  tests 1.  if {[l
85c0: 6c 65 6e 67 74 68 20 24 6f 6d 69 74 4c 69 73 74  length $omitList
85d0: 5d 3e 30 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75  ]>0} {.    outpu
85e0: 74 32 20 22 4f 6d 69 74 74 65 64 20 74 65 73 74  t2 "Omitted test
85f0: 20 63 61 73 65 73 3a 22 0a 20 20 20 20 73 65 74   cases:".    set
8600: 20 70 72 65 63 20 7b 7d 0a 20 20 20 20 66 6f 72   prec {}.    for
8610: 65 61 63 68 20 7b 72 65 63 7d 20 5b 6c 73 6f 72  each {rec} [lsor
8620: 74 20 24 6f 6d 69 74 4c 69 73 74 5d 20 7b 0a 20  t $omitList] {. 
8630: 20 20 20 20 20 69 66 20 7b 24 72 65 63 3d 3d 24       if {$rec==$
8640: 70 72 65 63 7d 20 63 6f 6e 74 69 6e 75 65 0a 20  prec} continue. 
8650: 20 20 20 20 20 73 65 74 20 70 72 65 63 20 24 72       set prec $r
8660: 65 63 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32  ec.      output2
8670: 20 5b 66 6f 72 6d 61 74 20 7b 2e 20 20 25 2d 31   [format {.  %-1
8680: 32 73 20 25 73 7d 20 5b 6c 69 6e 64 65 78 20 24  2s %s} [lindex $
8690: 72 65 63 20 30 5d 20 5b 6c 69 6e 64 65 78 20 24  rec 0] [lindex $
86a0: 72 65 63 20 31 5d 5d 0a 20 20 20 20 7d 0a 20 20  rec 1]].    }.  
86b0: 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 30 20  }.  if {$nErr>0 
86c0: 26 26 20 21 5b 77 6f 72 6b 69 6e 67 5f 36 34 62  && ![working_64b
86d0: 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20 20 20 20 6f  it_int]} {.    o
86e0: 75 74 70 75 74 32 20 22 2a 2a 2a 2a 2a 2a 2a 2a  utput2 "********
86f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8710: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8720: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20  **********".    
8730: 6f 75 74 70 75 74 32 20 22 4e 2e 42 2e 3a 20 20  output2 "N.B.:  
8740: 54 68 65 20 76 65 72 73 69 6f 6e 20 6f 66 20 54  The version of T
8750: 43 4c 20 74 68 61 74 20 79 6f 75 20 75 73 65 64  CL that you used
8760: 20 74 6f 20 62 75 69 6c 64 20 74 68 69 73 20 74   to build this t
8770: 65 73 74 20 68 61 72 6e 65 73 73 22 0a 20 20 20  est harness".   
8780: 20 6f 75 74 70 75 74 32 20 22 69 73 20 64 65 66   output2 "is def
8790: 65 63 74 69 76 65 20 69 6e 20 74 68 61 74 20 69  ective in that i
87a0: 74 20 64 6f 65 73 20 6e 6f 74 20 73 75 70 70 6f  t does not suppo
87b0: 72 74 20 36 34 2d 62 69 74 20 69 6e 74 65 67 65  rt 64-bit intege
87c0: 72 73 2e 20 20 53 6f 6d 65 20 6f 72 22 0a 20 20  rs.  Some or".  
87d0: 20 20 6f 75 74 70 75 74 32 20 22 61 6c 6c 20 6f    output2 "all o
87e0: 66 20 74 68 65 20 74 65 73 74 20 66 61 69 6c 75  f the test failu
87f0: 72 65 73 20 61 62 6f 76 65 20 6d 69 67 68 74 20  res above might 
8800: 62 65 20 61 20 72 65 73 75 6c 74 20 66 72 6f 6d  be a result from
8810: 20 74 68 69 73 20 64 65 66 65 63 74 22 0a 20 20   this defect".  
8820: 20 20 6f 75 74 70 75 74 32 20 22 69 6e 20 79 6f    output2 "in yo
8830: 75 72 20 54 43 4c 20 62 75 69 6c 64 2e 22 0a 20  ur TCL build.". 
8840: 20 20 20 6f 75 74 70 75 74 32 20 22 2a 2a 2a 2a     output2 "****
8850: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8860: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8870: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8880: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a  **************".
8890: 20 20 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64    }.  if {$::cmd
88a0: 6c 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f  linearg(binarylo
88b0: 67 29 7d 20 7b 0a 20 20 20 20 76 66 73 6c 6f 67  g)} {.    vfslog
88c0: 20 66 69 6e 61 6c 69 7a 65 20 62 69 6e 61 72 79   finalize binary
88d0: 6c 6f 67 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73  log.  }.  if {$s
88e0: 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f  qlite_open_file_
88f0: 63 6f 75 6e 74 7d 20 7b 0a 20 20 20 20 6f 75 74  count} {.    out
8900: 70 75 74 32 20 22 24 73 71 6c 69 74 65 5f 6f 70  put2 "$sqlite_op
8910: 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 66 69  en_file_count fi
8920: 6c 65 73 20 77 65 72 65 20 6c 65 66 74 20 6f 70  les were left op
8930: 65 6e 22 0a 20 20 20 20 69 6e 63 72 20 6e 45 72  en".    incr nEr
8940: 72 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 6c 69 6e  r.  }.  if {[lin
8950: 64 65 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  dex [sqlite3_sta
8960: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
8970: 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30  S_MALLOC_COUNT 0
8980: 5d 20 31 5d 3e 30 20 7c 7c 0a 20 20 20 20 20 20  ] 1]>0 ||.      
8990: 20 20 20 20 20 20 20 20 5b 73 71 6c 69 74 65 33          [sqlite3
89a0: 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e 30 7d  _memory_used]>0}
89b0: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22   {.    output2 "
89c0: 55 6e 66 72 65 65 64 20 6d 65 6d 6f 72 79 3a 20  Unfreed memory: 
89d0: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f  [sqlite3_memory_
89e0: 75 73 65 64 5d 20 62 79 74 65 73 20 69 6e 5c 0a  used] bytes in\.
89f0: 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78           [lindex
8a00: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
8a10: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d   SQLITE_STATUS_M
8a20: 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31  ALLOC_COUNT 0] 1
8a30: 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 22 0a 20  ] allocations". 
8a40: 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 20     incr nErr.   
8a50: 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64 65   ifcapable memde
8a60: 62 75 67 7c 7c 6d 65 6d 35 7c 7c 28 6d 65 6d 33  bug||mem5||(mem3
8a70: 26 26 64 65 62 75 67 29 20 7b 0a 20 20 20 20 20  &&debug) {.     
8a80: 20 6f 75 74 70 75 74 32 20 22 57 72 69 74 69 6e   output2 "Writin
8a90: 67 20 75 6e 66 72 65 65 64 20 6d 65 6d 6f 72 79  g unfreed memory
8aa0: 20 6c 6f 67 20 74 6f 20 5c 22 2e 2f 6d 65 6d 6c   log to \"./meml
8ab0: 65 61 6b 2e 74 78 74 5c 22 22 0a 20 20 20 20 20  eak.txt\"".     
8ac0: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
8ad0: 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 6c 65 61 6b  g_dump ./memleak
8ae0: 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d 20 65  .txt.    }.  } e
8af0: 6c 73 65 20 7b 0a 20 20 20 20 6f 75 74 70 75 74  lse {.    output
8b00: 32 20 22 41 6c 6c 20 6d 65 6d 6f 72 79 20 61 6c  2 "All memory al
8b10: 6c 6f 63 61 74 69 6f 6e 73 20 66 72 65 65 64 20  locations freed 
8b20: 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a 20 20 20 20  - no leaks".    
8b30: 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64 65 62  ifcapable memdeb
8b40: 75 67 7c 7c 6d 65 6d 35 20 7b 0a 20 20 20 20 20  ug||mem5 {.     
8b50: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
8b60: 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 75 73 61 67  g_dump ./memusag
8b70: 65 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d 0a  e.txt.    }.  }.
8b80: 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73 0a    show_memstats.
8b90: 20 20 6f 75 74 70 75 74 32 20 22 4d 61 78 69 6d    output2 "Maxim
8ba0: 75 6d 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a  um memory usage:
8bb0: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79   [sqlite3_memory
8bc0: 5f 68 69 67 68 77 61 74 65 72 20 31 5d 20 62 79  _highwater 1] by
8bd0: 74 65 73 22 0a 20 20 6f 75 74 70 75 74 32 20 22  tes".  output2 "
8be0: 43 75 72 72 65 6e 74 20 6d 65 6d 6f 72 79 20 75  Current memory u
8bf0: 73 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f 6d  sage: [sqlite3_m
8c00: 65 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72 5d  emory_highwater]
8c10: 20 62 79 74 65 73 22 0a 20 20 69 66 20 7b 5b 69   bytes".  if {[i
8c20: 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20 73 71 6c  nfo commands sql
8c30: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6d 61  ite3_memdebug_ma
8c40: 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20 6e 65 20 22  lloc_count] ne "
8c50: 22 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  "} {.    output2
8c60: 20 22 4e 75 6d 62 65 72 20 6f 66 20 6d 61 6c 6c   "Number of mall
8c70: 6f 63 28 29 20 20 3a 20 5b 73 71 6c 69 74 65 33  oc()  : [sqlite3
8c80: 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63  _memdebug_malloc
8c90: 5f 63 6f 75 6e 74 5d 20 63 61 6c 6c 73 22 0a 20  _count] calls". 
8ca0: 20 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c   }.  if {$::cmdl
8cb0: 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61  inearg(malloctra
8cc0: 63 65 29 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75  ce)} {.    outpu
8cd0: 74 32 20 22 57 72 69 74 69 6e 67 20 6d 61 6c 6c  t2 "Writing mall
8ce0: 6f 63 73 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20 20  ocs.sql...".    
8cf0: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c  memdebug_log_sql
8d00: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d  .    sqlite3_mem
8d10: 64 65 62 75 67 5f 6c 6f 67 20 73 74 6f 70 0a 20  debug_log stop. 
8d20: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
8d30: 62 75 67 5f 6c 6f 67 20 63 6c 65 61 72 0a 0a 20  bug_log clear.. 
8d40: 20 20 20 69 66 20 7b 5b 73 71 6c 69 74 65 33 5f     if {[sqlite3_
8d50: 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20  memory_used]>0} 
8d60: 7b 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32 20  {.      output2 
8d70: 22 57 72 69 74 69 6e 67 20 6c 65 61 6b 73 2e 73  "Writing leaks.s
8d80: 71 6c 2e 2e 2e 22 0a 20 20 20 20 20 20 73 71 6c  ql...".      sql
8d90: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f  ite3_memdebug_lo
8da0: 67 20 73 79 6e 63 0a 20 20 20 20 20 20 6d 65 6d  g sync.      mem
8db0: 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 20 6c 65  debug_log_sql le
8dc0: 61 6b 73 2e 73 71 6c 0a 20 20 20 20 7d 0a 20 20  aks.sql.    }.  
8dd0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  }.  foreach f [g
8de0: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
8df0: 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75 72 6e 61  test.db-*-journa
8e00: 6c 5d 20 7b 0a 20 20 20 20 66 6f 72 63 65 64 65  l] {.    forcede
8e10: 6c 65 74 65 20 24 66 0a 20 20 7d 0a 20 20 66 6f  lete $f.  }.  fo
8e20: 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e  reach f [glob -n
8e30: 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64  ocomplain test.d
8e40: 62 2d 6d 6a 2a 5d 20 7b 0a 20 20 20 20 66 6f 72  b-mj*] {.    for
8e50: 63 65 64 65 6c 65 74 65 20 24 66 0a 20 20 7d 0a  cedelete $f.  }.
8e60: 20 20 65 78 69 74 20 5b 65 78 70 72 20 7b 24 6e    exit [expr {$n
8e70: 45 72 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 44 69 73  Err>0}].}..# Dis
8e80: 70 6c 61 79 20 6d 65 6d 6f 72 79 20 73 74 61 74  play memory stat
8e90: 69 73 74 69 63 73 20 66 6f 72 20 61 6e 61 6c 79  istics for analy
8ea0: 73 69 73 20 61 6e 64 20 64 65 62 75 67 67 69 6e  sis and debuggin
8eb0: 67 20 70 75 72 70 6f 73 65 73 2e 0a 23 0a 70 72  g purposes..#.pr
8ec0: 6f 63 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73  oc show_memstats
8ed0: 20 7b 7d 20 7b 0a 20 20 73 65 74 20 78 20 5b 73   {} {.  set x [s
8ee0: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
8ef0: 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 45 4d 4f  LITE_STATUS_MEMO
8f00: 52 59 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74  RY_USED 0].  set
8f10: 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   y [sqlite3_stat
8f20: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
8f30: 5f 4d 41 4c 4c 4f 43 5f 53 49 5a 45 20 30 5d 0a  _MALLOC_SIZE 0].
8f40: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
8f50: 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78  t {now %10d  max
8f60: 20 25 31 30 64 20 20 6d 61 78 2d 73 69 7a 65 20   %10d  max-size 
8f70: 25 31 30 64 7d 20 5c 0a 20 20 20 20 20 20 20 20  %10d} \.        
8f80: 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 78        [lindex $x
8f90: 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32   1] [lindex $x 2
8fa0: 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d 5d  ] [lindex $y 2]]
8fb0: 0a 20 20 6f 75 74 70 75 74 31 20 22 4d 65 6d 6f  .  output1 "Memo
8fc0: 72 79 20 75 73 65 64 3a 20 20 20 20 20 20 20 20  ry used:        
8fd0: 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20    $val".  set x 
8fe0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
8ff0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41  SQLITE_STATUS_MA
9000: 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 0a 20 20  LLOC_COUNT 0].  
9010: 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20  set val [format 
9020: 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25  {now %10d  max %
9030: 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20  10d} [lindex $x 
9040: 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d  1] [lindex $x 2]
9050: 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 41 6c 6c  ].  output1 "All
9060: 6f 63 61 74 69 6f 6e 20 63 6f 75 6e 74 3a 20 20  ocation count:  
9070: 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78     $val".  set x
9080: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
9090: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50   SQLITE_STATUS_P
90a0: 41 47 45 43 41 43 48 45 5f 55 53 45 44 20 30 5d  AGECACHE_USED 0]
90b0: 0a 20 20 73 65 74 20 79 20 5b 73 71 6c 69 74 65  .  set y [sqlite
90c0: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
90d0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
90e0: 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74 20 76  _SIZE 0].  set v
90f0: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
9100: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 20 20  %10d  max %10d  
9110: 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c  max-size %10d} \
9120: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5b  .              [
9130: 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69  lindex $x 1] [li
9140: 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64  ndex $x 2] [lind
9150: 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f 75 74 70  ex $y 2]].  outp
9160: 75 74 31 20 22 50 61 67 65 2d 63 61 63 68 65 20  ut1 "Page-cache 
9170: 75 73 65 64 3a 20 20 20 20 20 20 24 76 61 6c 22  used:      $val"
9180: 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65  .  set x [sqlite
9190: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
91a0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
91b0: 5f 4f 56 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73  _OVERFLOW 0].  s
91c0: 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b  et val [format {
91d0: 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31  now %10d  max %1
91e0: 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31  0d} [lindex $x 1
91f0: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d  ] [lindex $x 2]]
9200: 0a 20 20 6f 75 74 70 75 74 31 20 22 50 61 67 65  .  output1 "Page
9210: 2d 63 61 63 68 65 20 6f 76 65 72 66 6c 6f 77 3a  -cache overflow:
9220: 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20    $val".  set x 
9230: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
9240: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 53 43  SQLITE_STATUS_SC
9250: 52 41 54 43 48 5f 55 53 45 44 20 30 5d 0a 20 20  RATCH_USED 0].  
9260: 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20  set val [format 
9270: 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25  {now %10d  max %
9280: 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20  10d} [lindex $x 
9290: 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d  1] [lindex $x 2]
92a0: 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 53 63 72  ].  output1 "Scr
92b0: 61 74 63 68 20 6d 65 6d 6f 72 79 20 75 73 65 64  atch memory used
92c0: 3a 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78  :  $val".  set x
92d0: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
92e0: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 53   SQLITE_STATUS_S
92f0: 43 52 41 54 43 48 5f 4f 56 45 52 46 4c 4f 57 20  CRATCH_OVERFLOW 
9300: 30 5d 0a 20 20 73 65 74 20 79 20 5b 73 71 6c 69  0].  set y [sqli
9310: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
9320: 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43 48  E_STATUS_SCRATCH
9330: 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74 20 76  _SIZE 0].  set v
9340: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
9350: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 20 20  %10d  max %10d  
9360: 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c  max-size %10d} \
9370: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9380: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
9390: 69 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e  index $x 2] [lin
93a0: 64 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f 75 74  dex $y 2]].  out
93b0: 70 75 74 31 20 22 53 63 72 61 74 63 68 20 6f 76  put1 "Scratch ov
93c0: 65 72 66 6c 6f 77 3a 20 20 20 20 20 24 76 61 6c  erflow:     $val
93d0: 22 0a 20 20 69 66 63 61 70 61 62 6c 65 20 79 79  ".  ifcapable yy
93e0: 74 72 61 63 6b 6d 61 78 73 74 61 63 6b 64 65 70  trackmaxstackdep
93f0: 74 68 20 7b 0a 20 20 20 20 73 65 74 20 78 20 5b  th {.    set x [
9400: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
9410: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 52  QLITE_STATUS_PAR
9420: 53 45 52 5f 53 54 41 43 4b 20 30 5d 0a 20 20 20  SER_STACK 0].   
9430: 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74   set val [format
9440: 20 7b 20 20 20 20 20 20 20 20 20 20 20 20 20 20   {              
9450: 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e 64   max %10d} [lind
9460: 65 78 20 24 78 20 32 5d 5d 0a 20 20 20 20 6f 75  ex $x 2]].    ou
9470: 74 70 75 74 32 20 22 50 61 72 73 65 72 20 73 74  tput2 "Parser st
9480: 61 63 6b 20 64 65 70 74 68 3a 20 20 20 20 24 76  ack depth:    $v
9490: 61 6c 22 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20 70  al".  }.}..# A p
94a0: 72 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65 63  rocedure to exec
94b0: 75 74 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65  ute SQL.#.proc e
94c0: 78 65 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20  xecsql {sql {db 
94d0: 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20  db}} {.  # puts 
94e0: 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75  "SQL = $sql".  u
94f0: 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62  plevel [list $db
9500: 20 65 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 70 72   eval $sql].}.pr
9510: 6f 63 20 65 78 65 63 73 71 6c 5f 74 69 6d 65 64  oc execsql_timed
9520: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
9530: 0a 20 20 73 65 74 20 74 6d 20 5b 74 69 6d 65 20  .  set tm [time 
9540: 7b 0a 20 20 20 20 73 65 74 20 78 20 5b 75 70 6c  {.    set x [upl
9550: 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65  evel [list $db e
9560: 76 61 6c 20 24 73 71 6c 5d 5d 0a 20 20 7d 20 31  val $sql]].  } 1
9570: 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64  ].  set tm [lind
9580: 65 78 20 24 74 6d 20 30 5d 0a 20 20 6f 75 74 70  ex $tm 0].  outp
9590: 75 74 31 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22  ut1 -nonewline "
95a0: 20 28 5b 65 78 70 72 20 7b 24 74 6d 2a 30 2e 30   ([expr {$tm*0.0
95b0: 30 31 7d 5d 6d 73 29 20 22 0a 20 20 73 65 74 20  01}]ms) ".  set 
95c0: 78 0a 7d 0a 0a 23 20 45 78 65 63 75 74 65 20 53  x.}..# Execute S
95d0: 51 4c 20 61 6e 64 20 63 61 74 63 68 20 65 78 63  QL and catch exc
95e0: 65 70 74 69 6f 6e 73 2e 0a 23 0a 70 72 6f 63 20  eptions..#.proc 
95f0: 63 61 74 63 68 73 71 6c 20 7b 73 71 6c 20 7b 64  catchsql {sql {d
9600: 62 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74  b db}} {.  # put
9610: 73 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20  s "SQL = $sql". 
9620: 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 5b 6c   set r [catch [l
9630: 69 73 74 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73  ist uplevel [lis
9640: 74 20 24 64 62 20 65 76 61 6c 20 24 73 71 6c 5d  t $db eval $sql]
9650: 5d 20 6d 73 67 5d 0a 20 20 6c 61 70 70 65 6e 64  ] msg].  lappend
9660: 20 72 20 24 6d 73 67 0a 20 20 72 65 74 75 72 6e   r $msg.  return
9670: 20 24 72 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 56   $r.}..# Do an V
9680: 44 42 45 20 63 6f 64 65 20 64 75 6d 70 20 6f 6e  DBE code dump on
9690: 20 74 68 65 20 53 51 4c 20 67 69 76 65 6e 0a 23   the SQL given.#
96a0: 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 20 7b 73  .proc explain {s
96b0: 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  ql {db db}} {.  
96c0: 6f 75 74 70 75 74 32 20 22 22 0a 20 20 6f 75 74  output2 "".  out
96d0: 70 75 74 32 20 22 61 64 64 72 20 20 6f 70 63 6f  put2 "addr  opco
96e0: 64 65 20 20 20 20 20 20 20 20 70 31 20 20 20 20  de        p1    
96f0: 20 20 70 32 20 20 20 20 20 20 70 33 20 20 20 20    p2      p3    
9700: 20 20 70 34 20 20 20 20 20 20 20 20 20 20 20 20    p4            
9710: 20 20 20 70 35 20 20 23 22 0a 20 20 6f 75 74 70     p5  #".  outp
9720: 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  ut2 "----  -----
9730: 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20  -------  ------ 
9740: 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20   ------  ------ 
9750: 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   ---------------
9760: 20 20 2d 2d 20 20 2d 22 0a 20 20 24 64 62 20 65    --  -".  $db e
9770: 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73 71  val "explain $sq
9780: 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 6f 75 74 70  l" {} {.    outp
9790: 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 34  ut2 [format {%-4
97a0: 64 20 20 25 2d 31 32 2e 31 32 73 20 20 25 2d 36  d  %-12.12s  %-6
97b0: 64 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20 25  d  %-6d  %-6d  %
97c0: 20 2d 31 37 73 20 25 73 20 20 25 73 7d 20 5c 0a   -17s %s  %s} \.
97d0: 20 20 20 20 20 20 24 61 64 64 72 20 24 6f 70 63        $addr $opc
97e0: 6f 64 65 20 24 70 31 20 24 70 32 20 24 70 33 20  ode $p1 $p2 $p3 
97f0: 24 70 34 20 24 70 35 20 24 63 6f 6d 6d 65 6e 74  $p4 $p5 $comment
9800: 0a 20 20 20 20 5d 0a 20 20 7d 0a 7d 0a 0a 70 72  .    ].  }.}..pr
9810: 6f 63 20 65 78 70 6c 61 69 6e 5f 69 20 7b 73 71  oc explain_i {sq
9820: 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 6f  l {db db}} {.  o
9830: 75 74 70 75 74 32 20 22 22 0a 20 20 6f 75 74 70  utput2 "".  outp
9840: 75 74 32 20 22 61 64 64 72 20 20 6f 70 63 6f 64  ut2 "addr  opcod
9850: 65 20 20 20 20 20 20 20 20 70 31 20 20 20 20 20  e        p1     
9860: 20 70 32 20 20 20 20 20 20 70 33 20 20 20 20 20   p2      p3     
9870: 20 70 34 20 20 20 20 20 20 20 20 20 20 20 20 20   p4             
9880: 20 20 20 70 35 20 20 23 22 0a 20 20 6f 75 74 70     p5  #".  outp
9890: 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  ut2 "----  -----
98a0: 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20  -------  ------ 
98b0: 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20   ------  ------ 
98c0: 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   ---------------
98d0: 2d 20 20 2d 2d 20 20 2d 22 0a 0a 0a 20 20 23 20  -  --  -"...  # 
98e0: 53 65 74 20 75 70 20 63 6f 6c 6f 72 73 20 66 6f  Set up colors fo
98f0: 72 20 74 68 65 20 64 69 66 66 65 72 65 6e 74 20  r the different 
9900: 6f 70 63 6f 64 65 73 2e 20 53 63 68 65 6d 65 20  opcodes. Scheme 
9910: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20  is as follows:. 
9920: 20 23 0a 20 20 23 20 20 20 52 65 64 3a 20 20 20   #.  #   Red:   
9930: 4f 70 63 6f 64 65 73 20 74 68 61 74 20 77 72 69  Opcodes that wri
9940: 74 65 20 74 6f 20 61 20 62 2d 74 72 65 65 2e 0a  te to a b-tree..
9950: 20 20 23 20 20 20 42 6c 75 65 3a 20 20 4f 70 63    #   Blue:  Opc
9960: 6f 64 65 73 20 74 68 61 74 20 72 65 70 6f 73 69  odes that reposi
9970: 74 69 6f 6e 20 6f 72 20 73 65 65 6b 20 61 20 63  tion or seek a c
9980: 75 72 73 6f 72 2e 20 0a 20 20 23 20 20 20 47 72  ursor. .  #   Gr
9990: 65 65 6e 3a 20 54 68 65 20 52 65 73 75 6c 74 52  een: The ResultR
99a0: 6f 77 20 6f 70 63 6f 64 65 2e 0a 20 20 23 0a 20  ow opcode..  #. 
99b0: 20 69 66 20 7b 20 5b 63 61 74 63 68 20 7b 66 63   if { [catch {fc
99c0: 6f 6e 66 69 67 75 72 65 20 73 74 64 6f 75 74 20  onfigure stdout 
99d0: 2d 6d 6f 64 65 7d 5d 3d 3d 30 20 7d 20 7b 0a 20  -mode}]==0 } {. 
99e0: 20 20 20 73 65 74 20 52 20 22 5c 30 33 33 5c 5b     set R "\033\[
99f0: 33 31 3b 31 6d 22 20 20 20 20 20 20 20 20 3b 23  31;1m"        ;#
9a00: 20 52 65 64 20 66 67 0a 20 20 20 20 73 65 74 20   Red fg.    set 
9a10: 47 20 22 5c 30 33 33 5c 5b 33 32 3b 31 6d 22 20  G "\033\[32;1m" 
9a20: 20 20 20 20 20 20 20 3b 23 20 47 72 65 65 6e 20         ;# Green 
9a30: 66 67 0a 20 20 20 20 73 65 74 20 42 20 22 5c 30  fg.    set B "\0
9a40: 33 33 5c 5b 33 34 3b 31 6d 22 20 20 20 20 20 20  33\[34;1m"      
9a50: 20 20 3b 23 20 52 65 64 20 66 67 0a 20 20 20 20    ;# Red fg.    
9a60: 73 65 74 20 44 20 22 5c 30 33 33 5c 5b 33 39 3b  set D "\033\[39;
9a70: 30 6d 22 20 20 20 20 20 20 20 20 3b 23 20 44 65  0m"        ;# De
9a80: 66 61 75 6c 74 20 66 67 0a 20 20 7d 20 65 6c 73  fault fg.  } els
9a90: 65 20 7b 0a 20 20 20 20 73 65 74 20 52 20 22 22  e {.    set R ""
9aa0: 0a 20 20 20 20 73 65 74 20 47 20 22 22 0a 20 20  .    set G "".  
9ab0: 20 20 73 65 74 20 42 20 22 22 0a 20 20 20 20 73    set B "".    s
9ac0: 65 74 20 44 20 22 22 0a 20 20 7d 0a 20 20 66 6f  et D "".  }.  fo
9ad0: 72 65 61 63 68 20 6f 70 63 6f 64 65 20 7b 0a 20  reach opcode {. 
9ae0: 20 20 20 20 20 53 65 65 6b 20 53 65 65 6b 47 45       Seek SeekGE
9af0: 20 53 65 65 6b 47 54 20 53 65 65 6b 4c 45 20 53   SeekGT SeekLE S
9b00: 65 65 6b 4c 54 20 4e 6f 74 46 6f 75 6e 64 20 4c  eekLT NotFound L
9b10: 61 73 74 20 52 65 77 69 6e 64 0a 20 20 20 20 20  ast Rewind.     
9b20: 20 4e 6f 43 6f 6e 66 6c 69 63 74 20 4e 65 78 74   NoConflict Next
9b30: 20 50 72 65 76 20 56 4e 65 78 74 20 56 50 72 65   Prev VNext VPre
9b40: 76 20 56 46 69 6c 74 65 72 0a 20 20 20 20 20 20  v VFilter.      
9b50: 53 6f 72 74 65 72 53 6f 72 74 20 53 6f 72 74 65  SorterSort Sorte
9b60: 72 4e 65 78 74 20 4e 65 78 74 49 66 4f 70 65 6e  rNext NextIfOpen
9b70: 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 63  .  } {.    set c
9b80: 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 24 42  olor($opcode) $B
9b90: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 6f  .  }.  foreach o
9ba0: 70 63 6f 64 65 20 7b 52 65 73 75 6c 74 52 6f 77  pcode {ResultRow
9bb0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6c 6f  } {.    set colo
9bc0: 72 28 24 6f 70 63 6f 64 65 29 20 24 47 0a 20 20  r($opcode) $G.  
9bd0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 6f 70 63 6f  }.  foreach opco
9be0: 64 65 20 7b 49 64 78 49 6e 73 65 72 74 20 49 6e  de {IdxInsert In
9bf0: 73 65 72 74 20 44 65 6c 65 74 65 20 49 64 78 44  sert Delete IdxD
9c00: 65 6c 65 74 65 7d 20 7b 0a 20 20 20 20 73 65 74  elete} {.    set
9c10: 20 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20   color($opcode) 
9c20: 24 52 0a 20 20 7d 0a 0a 20 20 73 65 74 20 62 53  $R.  }..  set bS
9c30: 65 65 6e 47 6f 74 6f 20 30 0a 20 20 24 64 62 20  eenGoto 0.  $db 
9c40: 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73  eval "explain $s
9c50: 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 73 65 74  ql" {} {.    set
9c60: 20 78 28 24 61 64 64 72 29 20 30 0a 20 20 20 20   x($addr) 0.    
9c70: 73 65 74 20 6f 70 28 24 61 64 64 72 29 20 24 6f  set op($addr) $o
9c80: 70 63 6f 64 65 0a 0a 20 20 20 20 69 66 20 7b 24  pcode..    if {$
9c90: 6f 70 63 6f 64 65 20 3d 3d 20 22 47 6f 74 6f 22  opcode == "Goto"
9ca0: 20 26 26 20 28 24 62 53 65 65 6e 47 6f 74 6f 3d   && ($bSeenGoto=
9cb0: 3d 30 20 7c 7c 20 28 24 70 32 20 3e 20 24 61 64  =0 || ($p2 > $ad
9cc0: 64 72 2b 31 30 29 29 7d 20 7b 0a 20 20 20 20 20  dr+10))} {.     
9cd0: 20 73 65 74 20 6c 69 6e 65 62 72 65 61 6b 28 24   set linebreak($
9ce0: 70 32 29 20 31 0a 20 20 20 20 20 20 73 65 74 20  p2) 1.      set 
9cf0: 62 53 65 65 6e 47 6f 74 6f 20 31 0a 20 20 20 20  bSeenGoto 1.    
9d00: 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63 6f  }..    if {$opco
9d10: 64 65 3d 3d 22 4f 6e 63 65 22 7d 20 7b 0a 20 20  de=="Once"} {.  
9d20: 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 24      for {set i $
9d30: 61 64 64 72 7d 20 7b 24 69 3c 24 70 32 7d 20 7b  addr} {$i<$p2} {
9d40: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20  incr i} {.      
9d50: 20 20 73 65 74 20 73 74 61 72 28 24 69 29 20 24    set star($i) $
9d60: 61 64 64 72 0a 20 20 20 20 20 20 7d 0a 20 20 20  addr.      }.   
9d70: 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63   }..    if {$opc
9d80: 6f 64 65 3d 3d 22 4e 65 78 74 22 20 20 7c 7c 20  ode=="Next"  || 
9d90: 24 6f 70 63 6f 64 65 3d 3d 22 50 72 65 76 22 20  $opcode=="Prev" 
9da0: 0a 20 20 20 20 20 7c 7c 20 24 6f 70 63 6f 64 65  .     || $opcode
9db0: 3d 3d 22 56 4e 65 78 74 22 20 7c 7c 20 24 6f 70  =="VNext" || $op
9dc0: 63 6f 64 65 3d 3d 22 56 50 72 65 76 22 0a 20 20  code=="VPrev".  
9dd0: 20 20 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22     || $opcode=="
9de0: 53 6f 72 74 65 72 4e 65 78 74 22 20 7c 7c 20 24  SorterNext" || $
9df0: 6f 70 63 6f 64 65 3d 3d 22 4e 65 78 74 49 66 4f  opcode=="NextIfO
9e00: 70 65 6e 22 0a 20 20 20 20 7d 20 7b 0a 20 20 20  pen".    } {.   
9e10: 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 24 70     for {set i $p
9e20: 32 7d 20 7b 24 69 3c 24 61 64 64 72 7d 20 7b 69  2} {$i<$addr} {i
9e30: 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20  ncr i} {.       
9e40: 20 69 6e 63 72 20 78 28 24 69 29 20 32 0a 20 20   incr x($i) 2.  
9e50: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
9e60: 20 69 66 20 7b 24 6f 70 63 6f 64 65 20 3d 3d 20   if {$opcode == 
9e70: 22 47 6f 74 6f 22 20 26 26 20 24 70 32 3c 24 61  "Goto" && $p2<$a
9e80: 64 64 72 20 26 26 20 24 6f 70 28 24 70 32 29 3d  ddr && $op($p2)=
9e90: 3d 22 59 69 65 6c 64 22 7d 20 7b 0a 20 20 20 20  ="Yield"} {.    
9ea0: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 5b 65 78    for {set i [ex
9eb0: 70 72 20 24 70 32 2b 31 5d 7d 20 7b 24 69 3c 24  pr $p2+1]} {$i<$
9ec0: 61 64 64 72 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  addr} {incr i} {
9ed0: 0a 20 20 20 20 20 20 20 20 69 6e 63 72 20 78 28  .        incr x(
9ee0: 24 69 29 20 32 0a 20 20 20 20 20 20 7d 0a 20 20  $i) 2.      }.  
9ef0: 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70    }..    if {$op
9f00: 63 6f 64 65 20 3d 3d 20 22 48 61 6c 74 22 20 26  code == "Halt" &
9f10: 26 20 24 63 6f 6d 6d 65 6e 74 20 3d 3d 20 22 45  & $comment == "E
9f20: 6e 64 20 6f 66 20 63 6f 72 6f 75 74 69 6e 65 22  nd of coroutine"
9f30: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6c 69  } {.      set li
9f40: 6e 65 62 72 65 61 6b 28 5b 65 78 70 72 20 24 61  nebreak([expr $a
9f50: 64 64 72 2b 31 5d 29 20 31 0a 20 20 20 20 7d 0a  ddr+1]) 1.    }.
9f60: 20 20 7d 0a 0a 20 20 24 64 62 20 65 76 61 6c 20    }..  $db eval 
9f70: 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b  "explain $sql" {
9f80: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66  } {.    if {[inf
9f90: 6f 20 65 78 69 73 74 73 20 6c 69 6e 65 62 72 65  o exists linebre
9fa0: 61 6b 28 24 61 64 64 72 29 5d 7d 20 7b 0a 20 20  ak($addr)]} {.  
9fb0: 20 20 20 20 6f 75 74 70 75 74 32 20 22 22 0a 20      output2 "". 
9fc0: 20 20 20 7d 0a 20 20 20 20 73 65 74 20 49 20 5b     }.    set I [
9fd0: 73 74 72 69 6e 67 20 72 65 70 65 61 74 20 22 20  string repeat " 
9fe0: 22 20 24 78 28 24 61 64 64 72 29 5d 0a 0a 20 20  " $x($addr)]..  
9ff0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
a000: 74 73 20 73 74 61 72 28 24 61 64 64 72 29 5d 7d  ts star($addr)]}
a010: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 69 69 20   {.      set ii 
a020: 5b 65 78 70 72 20 24 78 28 24 73 74 61 72 28 24  [expr $x($star($
a030: 61 64 64 72 29 29 5d 0a 20 20 20 20 20 20 61 70  addr))].      ap
a040: 70 65 6e 64 20 49 20 22 20 20 22 0a 20 20 20 20  pend I "  ".    
a050: 20 20 73 65 74 20 49 20 5b 73 74 72 69 6e 67 20    set I [string 
a060: 72 65 70 6c 61 63 65 20 24 49 20 24 69 69 20 24  replace $I $ii $
a070: 69 69 20 2a 5d 0a 20 20 20 20 7d 0a 0a 20 20 20  ii *].    }..   
a080: 20 73 65 74 20 63 6f 6c 20 22 22 0a 20 20 20 20   set col "".    
a090: 63 61 74 63 68 20 7b 20 73 65 74 20 63 6f 6c 20  catch { set col 
a0a0: 24 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20  $color($opcode) 
a0b0: 7d 0a 0a 20 20 20 20 6f 75 74 70 75 74 32 20 5b  }..    output2 [
a0c0: 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25 73  format {%-4d  %s
a0d0: 25 73 25 2d 31 32 2e 31 32 73 25 73 20 20 25 2d  %s%-12.12s%s  %-
a0e0: 36 64 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20  6d  %-6d  %-6d  
a0f0: 25 20 2d 31 37 73 20 25 73 20 20 25 73 7d 20 5c  % -17s %s  %s} \
a100: 0a 20 20 20 20 20 20 24 61 64 64 72 20 24 49 20  .      $addr $I 
a110: 24 63 6f 6c 20 24 6f 70 63 6f 64 65 20 24 44 20  $col $opcode $D 
a120: 24 70 31 20 24 70 32 20 24 70 33 20 24 70 34 20  $p1 $p2 $p3 $p4 
a130: 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20  $p5 $comment.   
a140: 20 5d 0a 20 20 7d 0a 20 20 6f 75 74 70 75 74 32   ].  }.  output2
a150: 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d   "----  --------
a160: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
a170: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
a180: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20  --------------  
a190: 2d 2d 20 20 2d 22 0a 7d 0a 0a 23 20 53 68 6f 77  --  -".}..# Show
a1a0: 20 74 68 65 20 56 44 42 45 20 70 72 6f 67 72 61   the VDBE progra
a1b0: 6d 20 66 6f 72 20 61 6e 20 53 51 4c 20 73 74 61  m for an SQL sta
a1c0: 74 65 6d 65 6e 74 20 62 75 74 20 6f 6d 69 74 20  tement but omit 
a1d0: 74 68 65 20 54 72 61 63 65 0a 23 20 6f 70 63 6f  the Trace.# opco
a1e0: 64 65 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e  de at the beginn
a1f0: 69 6e 67 2e 20 20 54 68 69 73 20 70 72 6f 63 65  ing.  This proce
a200: 64 75 72 65 20 63 61 6e 20 62 65 20 75 73 65 64  dure can be used
a210: 20 74 6f 20 70 72 6f 76 65 0a 23 20 74 68 61 74   to prove.# that
a220: 20 64 69 66 66 65 72 65 6e 74 20 53 51 4c 20 73   different SQL s
a230: 74 61 74 65 6d 65 6e 74 73 20 67 65 6e 65 72 61  tatements genera
a240: 74 65 20 65 78 61 63 74 6c 79 20 74 68 65 20 73  te exactly the s
a250: 61 6d 65 20 56 44 42 45 20 63 6f 64 65 2e 0a 23  ame VDBE code..#
a260: 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f  .proc explain_no
a270: 5f 74 72 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20  _trace {sql} {. 
a280: 20 73 65 74 20 74 72 20 5b 64 62 20 65 76 61 6c   set tr [db eval
a290: 20 22 45 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d   "EXPLAIN $sql"]
a2a0: 0a 20 20 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67  .  return [lrang
a2b0: 65 20 24 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a  e $tr 7 end].}..
a2c0: 23 20 41 6e 6f 74 68 65 72 20 70 72 6f 63 65 64  # Another proced
a2d0: 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53  ure to execute S
a2e0: 51 4c 2e 20 20 54 68 69 73 20 6f 6e 65 20 69 6e  QL.  This one in
a2f0: 63 6c 75 64 65 73 20 74 68 65 20 66 69 65 6c 64  cludes the field
a300: 0a 23 20 6e 61 6d 65 73 20 69 6e 20 74 68 65 20  .# names in the 
a310: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23  returned list..#
a320: 0a 70 72 6f 63 20 65 78 65 63 73 71 6c 32 20 7b  .proc execsql2 {
a330: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 72 65 73  sql} {.  set res
a340: 75 6c 74 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c  ult {}.  db eval
a350: 20 24 73 71 6c 20 64 61 74 61 20 7b 0a 20 20 20   $sql data {.   
a360: 20 66 6f 72 65 61 63 68 20 66 20 24 64 61 74 61   foreach f $data
a370: 28 2a 29 20 7b 0a 20 20 20 20 20 20 6c 61 70 70  (*) {.      lapp
a380: 65 6e 64 20 72 65 73 75 6c 74 20 24 66 20 24 64  end result $f $d
a390: 61 74 61 28 24 66 29 0a 20 20 20 20 7d 0a 20 20  ata($f).    }.  
a3a0: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73 75  }.  return $resu
a3b0: 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 61 20 74 65  lt.}..# Use a te
a3c0: 6d 70 6f 72 61 72 79 20 69 6e 2d 6d 65 6d 6f 72  mporary in-memor
a3d0: 79 20 64 61 74 61 62 61 73 65 20 74 6f 20 65 78  y database to ex
a3e0: 65 63 75 74 65 20 53 51 4c 20 73 74 61 74 65 6d  ecute SQL statem
a3f0: 65 6e 74 73 0a 23 0a 70 72 6f 63 20 6d 65 6d 64  ents.#.proc memd
a400: 62 73 71 6c 20 7b 73 71 6c 7d 20 7b 0a 20 20 73  bsql {sql} {.  s
a410: 71 6c 69 74 65 33 20 6d 65 6d 64 62 20 3a 6d 65  qlite3 memdb :me
a420: 6d 6f 72 79 3a 0a 20 20 73 65 74 20 72 65 73 75  mory:.  set resu
a430: 6c 74 20 5b 6d 65 6d 64 62 20 65 76 61 6c 20 24  lt [memdb eval $
a440: 73 71 6c 5d 0a 20 20 6d 65 6d 64 62 20 63 6c 6f  sql].  memdb clo
a450: 73 65 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73  se.  return $res
a460: 75 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65  ult.}..# Use the
a470: 20 6e 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50   non-callback AP
a480: 49 20 74 6f 20 65 78 65 63 75 74 65 20 6d 75 6c  I to execute mul
a490: 74 69 70 6c 65 20 53 51 4c 20 73 74 61 74 65 6d  tiple SQL statem
a4a0: 65 6e 74 73 0a 23 0a 70 72 6f 63 20 73 74 65 70  ents.#.proc step
a4b0: 73 71 6c 20 7b 64 62 70 74 72 20 73 71 6c 7d 20  sql {dbptr sql} 
a4c0: 7b 0a 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72  {.  set sql [str
a4d0: 69 6e 67 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20  ing trim $sql]. 
a4e0: 20 73 65 74 20 72 20 30 0a 20 20 77 68 69 6c 65   set r 0.  while
a4f0: 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68   {[string length
a500: 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20   $sql]>0} {.    
a510: 69 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69  if {[catch {sqli
a520: 74 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 70  te3_prepare $dbp
a530: 74 72 20 24 73 71 6c 20 2d 31 20 73 71 6c 74 61  tr $sql -1 sqlta
a540: 69 6c 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20  il} vm]} {.     
a550: 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20   return [list 1 
a560: 24 76 6d 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73  $vm].    }.    s
a570: 65 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20 74  et sql [string t
a580: 72 69 6d 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20  rim $sqltail].# 
a590: 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74     while {[sqlit
a5a0: 65 5f 73 74 65 70 20 24 76 6d 20 4e 20 56 41 4c  e_step $vm N VAL
a5b0: 20 43 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52   COL]=="SQLITE_R
a5c0: 4f 57 22 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f  OW"} {.#      fo
a5d0: 72 65 61 63 68 20 76 20 24 56 41 4c 20 7b 6c 61  reach v $VAL {la
a5e0: 70 70 65 6e 64 20 72 20 24 76 7d 0a 23 20 20 20  ppend r $v}.#   
a5f0: 20 7d 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 73   }.    while {[s
a600: 71 6c 69 74 65 33 5f 73 74 65 70 20 24 76 6d 5d  qlite3_step $vm]
a610: 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20  =="SQLITE_ROW"} 
a620: 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74  {.      for {set
a630: 20 69 20 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74   i 0} {$i<[sqlit
a640: 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 20 24 76  e3_data_count $v
a650: 6d 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20  m]} {incr i} {. 
a660: 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72         lappend r
a670: 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e   [sqlite3_column
a680: 5f 74 65 78 74 20 24 76 6d 20 24 69 5d 0a 20 20  _text $vm $i].  
a690: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
a6a0: 69 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69  if {[catch {sqli
a6b0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d  te3_finalize $vm
a6c0: 7d 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20  } errmsg]} {.   
a6d0: 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20     return [list 
a6e0: 31 20 24 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d  1 $errmsg].    }
a6f0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72  .  }.  return $r
a700: 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65  .}..# Do an inte
a710: 67 72 69 74 79 20 63 68 65 63 6b 20 6f 66 20 74  grity check of t
a720: 68 65 20 65 6e 74 69 72 65 20 64 61 74 61 62 61  he entire databa
a730: 73 65 0a 23 0a 70 72 6f 63 20 69 6e 74 65 67 72  se.#.proc integr
a740: 69 74 79 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20  ity_check {name 
a750: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63  {db db}} {.  ifc
a760: 61 70 61 62 6c 65 20 69 6e 74 65 67 72 69 74 79  apable integrity
a770: 63 6b 20 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74  ck {.    do_test
a780: 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20 65 78 65   $name [list exe
a790: 63 73 71 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74  csql {PRAGMA int
a7a0: 65 67 72 69 74 79 5f 63 68 65 63 6b 7d 20 24 64  egrity_check} $d
a7b0: 62 5d 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 23  b] {ok}.  }.}..#
a7c0: 20 43 68 65 63 6b 20 74 68 65 20 65 78 74 65 6e   Check the exten
a7d0: 64 65 64 20 65 72 72 6f 72 20 63 6f 64 65 0a 23  ded error code.#
a7e0: 0a 70 72 6f 63 20 76 65 72 69 66 79 5f 65 78 5f  .proc verify_ex_
a7f0: 65 72 72 63 6f 64 65 20 7b 6e 61 6d 65 20 65 78  errcode {name ex
a800: 70 65 63 74 65 64 20 7b 64 62 20 64 62 7d 7d 20  pected {db db}} 
a810: 7b 0a 20 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d  {.  do_test $nam
a820: 65 20 5b 6c 69 73 74 20 73 71 6c 69 74 65 33 5f  e [list sqlite3_
a830: 65 78 74 65 6e 64 65 64 5f 65 72 72 63 6f 64 65  extended_errcode
a840: 20 24 64 62 5d 20 24 65 78 70 65 63 74 65 64 0a   $db] $expected.
a850: 7d 0a 0a 0a 23 20 52 65 74 75 72 6e 20 74 72 75  }...# Return tru
a860: 65 20 69 66 20 74 68 65 20 53 51 4c 20 73 74 61  e if the SQL sta
a870: 74 65 6d 65 6e 74 20 70 61 73 73 65 64 20 61 73  tement passed as
a880: 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75   the second argu
a890: 6d 65 6e 74 20 75 73 65 73 20 61 0a 23 20 73 74  ment uses a.# st
a8a0: 61 74 65 6d 65 6e 74 20 74 72 61 6e 73 61 63 74  atement transact
a8b0: 69 6f 6e 2e 0a 23 0a 70 72 6f 63 20 73 71 6c 5f  ion..#.proc sql_
a8c0: 75 73 65 73 5f 73 74 6d 74 20 7b 64 62 20 73 71  uses_stmt {db sq
a8d0: 6c 7d 20 7b 0a 20 20 73 65 74 20 73 74 6d 74 20  l} {.  set stmt 
a8e0: 5b 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65  [sqlite3_prepare
a8f0: 20 24 64 62 20 24 73 71 6c 20 2d 31 20 64 75 6d   $db $sql -1 dum
a900: 6d 79 5d 0a 20 20 73 65 74 20 75 73 65 73 20 5b  my].  set uses [
a910: 75 73 65 73 5f 73 74 6d 74 5f 6a 6f 75 72 6e 61  uses_stmt_journa
a920: 6c 20 24 73 74 6d 74 5d 0a 20 20 73 71 6c 69 74  l $stmt].  sqlit
a930: 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 73 74 6d  e3_finalize $stm
a940: 74 0a 20 20 72 65 74 75 72 6e 20 24 75 73 65 73  t.  return $uses
a950: 0a 7d 0a 0a 70 72 6f 63 20 66 69 78 5f 69 66 63  .}..proc fix_ifc
a960: 61 70 61 62 6c 65 5f 65 78 70 72 20 7b 65 78 70  apable_expr {exp
a970: 72 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 22  r} {.  set ret "
a980: 22 0a 20 20 73 65 74 20 73 74 61 74 65 20 30 0a  ".  set state 0.
a990: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
a9a0: 7b 24 69 20 3c 20 5b 73 74 72 69 6e 67 20 6c 65  {$i < [string le
a9b0: 6e 67 74 68 20 24 65 78 70 72 5d 7d 20 7b 69 6e  ngth $expr]} {in
a9c0: 63 72 20 69 7d 20 7b 0a 20 20 20 20 73 65 74 20  cr i} {.    set 
a9d0: 63 68 61 72 20 5b 73 74 72 69 6e 67 20 72 61 6e  char [string ran
a9e0: 67 65 20 24 65 78 70 72 20 24 69 20 24 69 5d 0a  ge $expr $i $i].
a9f0: 20 20 20 20 73 65 74 20 6e 65 77 73 74 61 74 65      set newstate
aa00: 20 5b 65 78 70 72 20 7b 5b 73 74 72 69 6e 67 20   [expr {[string 
aa10: 69 73 20 61 6c 6e 75 6d 20 24 63 68 61 72 5d 20  is alnum $char] 
aa20: 7c 7c 20 24 63 68 61 72 20 65 71 20 22 5f 22 7d  || $char eq "_"}
aa30: 5d 0a 20 20 20 20 69 66 20 7b 24 6e 65 77 73 74  ].    if {$newst
aa40: 61 74 65 20 26 26 20 21 24 73 74 61 74 65 7d 20  ate && !$state} 
aa50: 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 72  {.      append r
aa60: 65 74 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70  et {$::sqlite_op
aa70: 74 69 6f 6e 73 28 7d 0a 20 20 20 20 7d 0a 20 20  tions(}.    }.  
aa80: 20 20 69 66 20 7b 21 24 6e 65 77 73 74 61 74 65    if {!$newstate
aa90: 20 26 26 20 24 73 74 61 74 65 7d 20 7b 0a 20 20   && $state} {.  
aaa0: 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 29      append ret )
aab0: 0a 20 20 20 20 7d 0a 20 20 20 20 61 70 70 65 6e  .    }.    appen
aac0: 64 20 72 65 74 20 24 63 68 61 72 0a 20 20 20 20  d ret $char.    
aad0: 73 65 74 20 73 74 61 74 65 20 24 6e 65 77 73 74  set state $newst
aae0: 61 74 65 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73  ate.  }.  if {$s
aaf0: 74 61 74 65 7d 20 7b 61 70 70 65 6e 64 20 72 65  tate} {append re
ab00: 74 20 29 7d 0a 20 20 72 65 74 75 72 6e 20 24 72  t )}.  return $r
ab10: 65 74 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 73 20  et.}..# Returns 
ab20: 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68 65 20  non-zero if the 
ab30: 63 61 70 61 62 69 6c 69 74 69 65 73 20 61 72 65  capabilities are
ab40: 20 70 72 65 73 65 6e 74 3b 20 7a 65 72 6f 20 6f   present; zero o
ab50: 74 68 65 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63  therwise..#.proc
ab60: 20 63 61 70 61 62 6c 65 20 7b 65 78 70 72 7d 20   capable {expr} 
ab70: 7b 0a 20 20 73 65 74 20 65 20 5b 66 69 78 5f 69  {.  set e [fix_i
ab80: 66 63 61 70 61 62 6c 65 5f 65 78 70 72 20 24 65  fcapable_expr $e
ab90: 78 70 72 5d 3b 20 72 65 74 75 72 6e 20 5b 65 78  xpr]; return [ex
aba0: 70 72 20 28 24 65 29 5d 0a 7d 0a 0a 23 20 45 76  pr ($e)].}..# Ev
abb0: 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c 65 61 6e  aluate a boolean
abc0: 20 65 78 70 72 65 73 73 69 6f 6e 20 6f 66 20 63   expression of c
abd0: 61 70 61 62 69 6c 69 74 69 65 73 2e 20 20 49 66  apabilities.  If
abe0: 20 74 72 75 65 2c 20 65 78 65 63 75 74 65 20 74   true, execute t
abf0: 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f 6d 69 74  he.# code.  Omit
ac00: 20 74 68 65 20 63 6f 64 65 20 69 66 20 66 61 6c   the code if fal
ac10: 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66 63 61 70  se..#.proc ifcap
ac20: 61 62 6c 65 20 7b 65 78 70 72 20 63 6f 64 65 20  able {expr code 
ac30: 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c 73 65 63  {else ""} {elsec
ac40: 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20 23 72 65  ode ""}} {.  #re
ac50: 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5f  gsub -all {[a-z_
ac60: 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20 7b 24 3a  0-9]+} $expr {$:
ac70: 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28  :sqlite_options(
ac80: 26 29 7d 20 65 32 0a 20 20 73 65 74 20 65 32 20  &)} e2.  set e2 
ac90: 5b 66 69 78 5f 69 66 63 61 70 61 62 6c 65 5f 65  [fix_ifcapable_e
aca0: 78 70 72 20 24 65 78 70 72 5d 0a 20 20 69 66 20  xpr $expr].  if 
acb0: 28 24 65 32 29 20 7b 0a 20 20 20 20 73 65 74 20  ($e2) {.    set 
acc0: 63 20 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65  c [catch {upleve
acd0: 6c 20 31 20 24 63 6f 64 65 7d 20 72 5d 0a 20 20  l 1 $code} r].  
ace0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
acf0: 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c 65 76   c [catch {uplev
ad00: 65 6c 20 31 20 24 65 6c 73 65 63 6f 64 65 7d 20  el 1 $elsecode} 
ad10: 72 5d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  r].  }.  return 
ad20: 2d 63 6f 64 65 20 24 63 20 24 72 0a 7d 0a 0a 23  -code $c $r.}..#
ad30: 20 54 68 69 73 20 70 72 6f 63 20 65 78 65 63 73   This proc execs
ad40: 20 61 20 73 65 70 65 72 61 74 65 20 70 72 6f 63   a seperate proc
ad50: 65 73 73 20 74 68 61 74 20 63 72 61 73 68 65 73  ess that crashes
ad60: 20 6d 69 64 77 61 79 20 74 68 72 6f 75 67 68 20   midway through 
ad70: 65 78 65 63 75 74 69 6e 67 0a 23 20 74 68 65 20  executing.# the 
ad80: 53 51 4c 20 73 63 72 69 70 74 20 24 73 71 6c 20  SQL script $sql 
ad90: 6f 6e 20 64 61 74 61 62 61 73 65 20 74 65 73 74  on database test
ada0: 2e 64 62 2e 0a 23 0a 23 20 54 68 65 20 63 72 61  .db..#.# The cra
adb0: 73 68 20 6f 63 63 75 72 73 20 64 75 72 69 6e 67  sh occurs during
adc0: 20 61 20 73 79 6e 63 28 29 20 6f 66 20 66 69 6c   a sync() of fil
add0: 65 20 24 63 72 61 73 68 66 69 6c 65 2e 20 57 68  e $crashfile. Wh
ade0: 65 6e 20 74 68 65 20 63 72 61 73 68 0a 23 20 6f  en the crash.# o
adf0: 63 63 75 72 73 20 61 20 72 61 6e 64 6f 6d 20 73  ccurs a random s
ae00: 75 62 73 65 74 20 6f 66 20 61 6c 6c 20 75 6e 73  ubset of all uns
ae10: 79 6e 63 65 64 20 77 72 69 74 65 73 20 6d 61 64  ynced writes mad
ae20: 65 20 62 79 20 74 68 65 20 70 72 6f 63 65 73 73  e by the process
ae30: 20 61 72 65 0a 23 20 77 72 69 74 74 65 6e 20 69   are.# written i
ae40: 6e 74 6f 20 74 68 65 20 66 69 6c 65 73 20 6f 6e  nto the files on
ae50: 20 64 69 73 6b 2e 20 41 72 67 75 6d 65 6e 74 20   disk. Argument 
ae60: 24 63 72 61 73 68 64 65 6c 61 79 20 69 6e 64 69  $crashdelay indi
ae70: 63 61 74 65 73 20 74 68 65 0a 23 20 6e 75 6d 62  cates the.# numb
ae80: 65 72 20 6f 66 20 66 69 6c 65 20 73 79 6e 63 73  er of file syncs
ae90: 20 74 6f 20 77 61 69 74 20 62 65 66 6f 72 65 20   to wait before 
aea0: 63 72 61 73 68 69 6e 67 2e 0a 23 0a 23 20 54 68  crashing..#.# Th
aeb0: 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69  e return value i
aec0: 73 20 61 20 6c 69 73 74 20 6f 66 20 74 77 6f 20  s a list of two 
aed0: 65 6c 65 6d 65 6e 74 73 2e 20 54 68 65 20 66 69  elements. The fi
aee0: 72 73 74 20 65 6c 65 6d 65 6e 74 20 69 73 20 61  rst element is a
aef0: 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20 69 6e 64 69  .# boolean, indi
af00: 63 61 74 69 6e 67 20 77 68 65 74 68 65 72 20 6f  cating whether o
af10: 72 20 6e 6f 74 20 74 68 65 20 70 72 6f 63 65 73  r not the proces
af20: 73 20 61 63 74 75 61 6c 6c 79 20 63 72 61 73 68  s actually crash
af30: 65 64 20 6f 72 0a 23 20 72 65 70 6f 72 74 65 64  ed or.# reported
af40: 20 73 6f 6d 65 20 6f 74 68 65 72 20 65 72 72 6f   some other erro
af50: 72 2e 20 54 68 65 20 73 65 63 6f 6e 64 20 65 6c  r. The second el
af60: 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 72 65 74  ement in the ret
af70: 75 72 6e 65 64 20 6c 69 73 74 20 69 73 20 74 68  urned list is th
af80: 65 0a 23 20 65 72 72 6f 72 20 6d 65 73 73 61 67  e.# error messag
af90: 65 2e 20 54 68 69 73 20 69 73 20 22 63 68 69 6c  e. This is "chil
afa0: 64 20 70 72 6f 63 65 73 73 20 65 78 69 74 65 64  d process exited
afb0: 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 20 69 66 20   abnormally" if 
afc0: 74 68 65 20 63 72 61 73 68 0a 23 20 6f 63 63 75  the crash.# occu
afd0: 72 72 65 64 2e 0a 23 0a 23 20 20 20 63 72 61 73  rred..#.#   cras
afe0: 68 73 71 6c 20 2d 64 65 6c 61 79 20 43 52 41 53  hsql -delay CRAS
aff0: 48 44 45 4c 41 59 20 2d 66 69 6c 65 20 43 52 41  HDELAY -file CRA
b000: 53 48 46 49 4c 45 20 3f 2d 62 6c 6f 63 6b 73 69  SHFILE ?-blocksi
b010: 7a 65 20 42 4c 4f 43 4b 53 49 5a 45 3f 20 24 73  ze BLOCKSIZE? $s
b020: 71 6c 0a 23 0a 70 72 6f 63 20 63 72 61 73 68 73  ql.#.proc crashs
b030: 71 6c 20 7b 61 72 67 73 7d 20 7b 0a 0a 20 20 73  ql {args} {..  s
b040: 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22 22 0a  et blocksize "".
b050: 20 20 73 65 74 20 63 72 61 73 68 64 65 6c 61 79    set crashdelay
b060: 20 31 0a 20 20 73 65 74 20 70 72 6e 67 73 65 65   1.  set prngsee
b070: 64 20 30 0a 20 20 73 65 74 20 6f 70 65 6e 64 62  d 0.  set opendb
b080: 20 7b 20 73 71 6c 69 74 65 33 20 64 62 20 74 65   { sqlite3 db te
b090: 73 74 2e 64 62 20 2d 76 66 73 20 63 72 61 73 68  st.db -vfs crash
b0a0: 20 7d 0a 20 20 73 65 74 20 74 63 6c 62 6f 64 79   }.  set tclbody
b0b0: 20 7b 7d 0a 20 20 73 65 74 20 63 72 61 73 68 66   {}.  set crashf
b0c0: 69 6c 65 20 22 22 0a 20 20 73 65 74 20 64 63 20  ile "".  set dc 
b0d0: 22 22 0a 20 20 73 65 74 20 64 66 6c 74 76 66 73  "".  set dfltvfs
b0e0: 20 30 0a 20 20 73 65 74 20 73 71 6c 20 5b 6c 69   0.  set sql [li
b0f0: 6e 64 65 78 20 24 61 72 67 73 20 65 6e 64 5d 0a  ndex $args end].
b100: 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 69 20 30  .  for {set ii 0
b110: 7d 20 7b 24 69 69 20 3c 20 5b 6c 6c 65 6e 67 74  } {$ii < [llengt
b120: 68 20 24 61 72 67 73 5d 2d 31 7d 20 7b 69 6e 63  h $args]-1} {inc
b130: 72 20 69 69 20 32 7d 20 7b 0a 20 20 20 20 73 65  r ii 2} {.    se
b140: 74 20 7a 20 5b 6c 69 6e 64 65 78 20 24 61 72 67  t z [lindex $arg
b150: 73 20 24 69 69 5d 0a 20 20 20 20 73 65 74 20 6e  s $ii].    set n
b160: 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20   [string length 
b170: 24 7a 5d 0a 20 20 20 20 73 65 74 20 7a 32 20 5b  $z].    set z2 [
b180: 6c 69 6e 64 65 78 20 24 61 72 67 73 20 5b 65 78  lindex $args [ex
b190: 70 72 20 24 69 69 2b 31 5d 5d 0a 0a 20 20 20 20  pr $ii+1]]..    
b1a0: 69 66 20 20 20 20 20 7b 24 6e 3e 31 20 26 26 20  if     {$n>1 && 
b1b0: 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a  [string first $z
b1c0: 20 2d 64 65 6c 61 79 5d 3d 3d 30 7d 20 20 20 20   -delay]==0}    
b1d0: 20 7b 73 65 74 20 63 72 61 73 68 64 65 6c 61 79   {set crashdelay
b1e0: 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65   $z2} \.    else
b1f0: 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72  if {$n>1 && [str
b200: 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 6f 70  ing first $z -op
b210: 65 6e 64 62 5d 3d 3d 30 7d 20 20 20 20 7b 73 65  endb]==0}    {se
b220: 74 20 6f 70 65 6e 64 62 20 24 7a 32 7d 20 5c 0a  t opendb $z2} \.
b230: 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31      elseif {$n>1
b240: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
b250: 74 20 24 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20  t $z -seed]==0} 
b260: 20 20 20 20 20 7b 73 65 74 20 70 72 6e 67 73 65       {set prngse
b270: 65 64 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c  ed $z2} \.    el
b280: 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73  seif {$n>1 && [s
b290: 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d  tring first $z -
b2a0: 66 69 6c 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b  file]==0}      {
b2b0: 73 65 74 20 63 72 61 73 68 66 69 6c 65 20 24 7a  set crashfile $z
b2c0: 32 7d 20 20 5c 0a 20 20 20 20 65 6c 73 65 69 66  2}  \.    elseif
b2d0: 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e   {$n>1 && [strin
b2e0: 67 20 66 69 72 73 74 20 24 7a 20 2d 74 63 6c 62  g first $z -tclb
b2f0: 6f 64 79 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20  ody]==0}   {set 
b300: 74 63 6c 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a  tclbody $z2}  \.
b310: 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31      elseif {$n>1
b320: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
b330: 74 20 24 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d  t $z -blocksize]
b340: 3d 3d 30 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73  ==0} {set blocks
b350: 69 7a 65 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c  ize "-s $z2" } \
b360: 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e  .    elseif {$n>
b370: 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72  1 && [string fir
b380: 73 74 20 24 7a 20 2d 63 68 61 72 61 63 74 65 72  st $z -character
b390: 69 73 74 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74  istics]==0} {set
b3a0: 20 64 63 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d   dc "-c {$z2}" }
b3b0: 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e  \.    elseif {$n
b3c0: 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69  >1 && [string fi
b3d0: 72 73 74 20 24 7a 20 2d 64 66 6c 74 76 66 73 5d  rst $z -dfltvfs]
b3e0: 3d 3d 30 7d 20 7b 73 65 74 20 64 66 6c 74 76 66  ==0} {set dfltvf
b3f0: 73 20 24 7a 32 20 7d 5c 0a 20 20 20 20 65 6c 73  s $z2 }\.    els
b400: 65 20 20 20 7b 20 65 72 72 6f 72 20 22 55 6e 72  e   { error "Unr
b410: 65 63 6f 67 6e 69 7a 65 64 20 6f 70 74 69 6f 6e  ecognized option
b420: 3a 20 24 7a 22 20 7d 0a 20 20 7d 0a 0a 20 20 69  : $z" }.  }..  i
b430: 66 20 7b 24 63 72 61 73 68 66 69 6c 65 20 65 71  f {$crashfile eq
b440: 20 22 22 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72   ""} {.    error
b450: 20 22 43 6f 6d 70 75 6c 73 6f 72 79 20 6f 70 74   "Compulsory opt
b460: 69 6f 6e 20 2d 66 69 6c 65 20 6d 69 73 73 69 6e  ion -file missin
b470: 67 22 0a 20 20 7d 0a 0a 20 20 23 20 24 63 72 61  g".  }..  # $cra
b480: 73 68 66 69 6c 65 20 67 65 74 73 20 63 6f 6d 70  shfile gets comp
b490: 61 72 65 64 20 74 6f 20 74 68 65 20 6e 61 74 69  ared to the nati
b4a0: 76 65 20 66 69 6c 65 6e 61 6d 65 20 69 6e 0a 20  ve filename in. 
b4b0: 20 23 20 63 66 53 79 6e 63 28 29 2c 20 77 68 69   # cfSync(), whi
b4c0: 63 68 20 63 61 6e 20 62 65 20 64 69 66 66 65 72  ch can be differ
b4d0: 65 6e 74 20 74 68 65 6e 20 77 68 61 74 20 54 43  ent then what TC
b4e0: 4c 20 75 73 65 73 20 62 79 0a 20 20 23 20 64 65  L uses by.  # de
b4f0: 66 61 75 6c 74 2c 20 73 6f 20 68 65 72 65 20 77  fault, so here w
b500: 65 20 66 6f 72 63 65 20 69 74 20 74 6f 20 74 68  e force it to th
b510: 65 20 22 6e 61 74 69 76 65 6e 61 6d 65 22 20 66  e "nativename" f
b520: 6f 72 6d 61 74 2e 0a 20 20 73 65 74 20 63 66 69  ormat..  set cfi
b530: 6c 65 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b  le [string map {
b540: 5c 5c 20 5c 5c 5c 5c 7d 20 5b 66 69 6c 65 20 6e  \\ \\\\} [file n
b550: 61 74 69 76 65 6e 61 6d 65 20 5b 66 69 6c 65 20  ativename [file 
b560: 6a 6f 69 6e 20 5b 67 65 74 5f 70 77 64 5d 20 24  join [get_pwd] $
b570: 63 72 61 73 68 66 69 6c 65 5d 5d 5d 0a 0a 20 20  crashfile]]]..  
b580: 73 65 74 20 66 20 5b 6f 70 65 6e 20 63 72 61 73  set f [open cras
b590: 68 2e 74 63 6c 20 77 5d 0a 20 20 70 75 74 73 20  h.tcl w].  puts 
b5a0: 24 66 20 22 73 71 6c 69 74 65 33 5f 63 72 61 73  $f "sqlite3_cras
b5b0: 68 5f 65 6e 61 62 6c 65 20 31 20 24 64 66 6c 74  h_enable 1 $dflt
b5c0: 76 66 73 22 0a 20 20 70 75 74 73 20 24 66 20 22  vfs".  puts $f "
b5d0: 73 71 6c 69 74 65 33 5f 63 72 61 73 68 70 61 72  sqlite3_crashpar
b5e0: 61 6d 73 20 24 62 6c 6f 63 6b 73 69 7a 65 20 24  ams $blocksize $
b5f0: 64 63 20 24 63 72 61 73 68 64 65 6c 61 79 20 24  dc $crashdelay $
b600: 63 66 69 6c 65 22 0a 20 20 70 75 74 73 20 24 66  cfile".  puts $f
b610: 20 22 73 71 6c 69 74 65 33 5f 74 65 73 74 5f 63   "sqlite3_test_c
b620: 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f 62  ontrol_pending_b
b630: 79 74 65 20 24 3a 3a 73 71 6c 69 74 65 5f 70 65  yte $::sqlite_pe
b640: 6e 64 69 6e 67 5f 62 79 74 65 22 0a 0a 20 20 23  nding_byte"..  #
b650: 20 54 68 69 73 20 62 6c 6f 63 6b 20 73 65 74 73   This block sets
b660: 20 74 68 65 20 63 61 63 68 65 20 73 69 7a 65 20   the cache size 
b670: 6f 66 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  of the main data
b680: 62 61 73 65 20 74 6f 20 31 30 0a 20 20 23 20 70  base to 10.  # p
b690: 61 67 65 73 2e 20 54 68 69 73 20 69 73 20 64 6f  ages. This is do
b6a0: 6e 65 20 69 6e 20 63 61 73 65 20 74 68 65 20 62  ne in case the b
b6b0: 75 69 6c 64 20 69 73 20 63 6f 6e 66 69 67 75 72  uild is configur
b6c0: 65 64 20 74 6f 20 6f 6d 69 74 0a 20 20 23 20 22  ed to omit.  # "
b6d0: 50 52 41 47 4d 41 20 63 61 63 68 65 5f 73 69 7a  PRAGMA cache_siz
b6e0: 65 22 2e 0a 20 20 69 66 20 7b 24 6f 70 65 6e 64  e"..  if {$opend
b6f0: 62 21 3d 22 22 7d 20 7b 0a 20 20 20 20 70 75 74  b!=""} {.    put
b700: 73 20 24 66 20 24 6f 70 65 6e 64 62 20 0a 20 20  s $f $opendb .  
b710: 20 20 70 75 74 73 20 24 66 20 7b 64 62 20 65 76    puts $f {db ev
b720: 61 6c 20 7b 53 45 4c 45 43 54 20 2a 20 46 52 4f  al {SELECT * FRO
b730: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b  M sqlite_master;
b740: 7d 7d 0a 20 20 20 20 70 75 74 73 20 24 66 20 7b  }}.    puts $f {
b750: 73 65 74 20 62 74 20 5b 62 74 72 65 65 5f 66 72  set bt [btree_fr
b760: 6f 6d 5f 64 62 20 64 62 5d 7d 0a 20 20 20 20 70  om_db db]}.    p
b770: 75 74 73 20 24 66 20 7b 62 74 72 65 65 5f 73 65  uts $f {btree_se
b780: 74 5f 63 61 63 68 65 5f 73 69 7a 65 20 24 62 74  t_cache_size $bt
b790: 20 31 30 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b   10}.  }..  if {
b7a0: 24 70 72 6e 67 73 65 65 64 7d 20 7b 0a 20 20 20  $prngseed} {.   
b7b0: 20 73 65 74 20 73 65 65 64 20 5b 65 78 70 72 20   set seed [expr 
b7c0: 7b 24 70 72 6e 67 73 65 65 64 25 31 30 30 30 37  {$prngseed%10007
b7d0: 2b 31 7d 5d 0a 20 20 20 20 23 20 70 75 74 73 20  +1}].    # puts 
b7e0: 73 65 65 64 3d 24 73 65 65 64 0a 20 20 20 20 70  seed=$seed.    p
b7f0: 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c 20  uts $f "db eval 
b800: 7b 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c  {SELECT randombl
b810: 6f 62 28 24 73 65 65 64 29 7d 22 0a 20 20 7d 0a  ob($seed)}".  }.
b820: 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c  .  if {[string l
b830: 65 6e 67 74 68 20 24 74 63 6c 62 6f 64 79 5d 3e  ength $tclbody]>
b840: 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24 66  0} {.    puts $f
b850: 20 24 74 63 6c 62 6f 64 79 0a 20 20 7d 0a 20 20   $tclbody.  }.  
b860: 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67  if {[string leng
b870: 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20  th $sql]>0} {.  
b880: 20 20 70 75 74 73 20 24 66 20 22 64 62 20 65 76    puts $f "db ev
b890: 61 6c 20 7b 22 0a 20 20 20 20 70 75 74 73 20 24  al {".    puts $
b8a0: 66 20 20 20 22 24 73 71 6c 22 0a 20 20 20 20 70  f   "$sql".    p
b8b0: 75 74 73 20 24 66 20 22 7d 22 0a 20 20 7d 0a 20  uts $f "}".  }. 
b8c0: 20 63 6c 6f 73 65 20 24 66 0a 20 20 73 65 74 20   close $f.  set 
b8d0: 72 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 65  r [catch {.    e
b8e0: 78 65 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66  xec [info nameof
b8f0: 65 78 65 63 5d 20 63 72 61 73 68 2e 74 63 6c 20  exec] crash.tcl 
b900: 3e 40 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67  >@stdout.  } msg
b910: 5d 0a 0a 20 20 23 20 57 69 6e 64 6f 77 73 2f 41  ]..  # Windows/A
b920: 63 74 69 76 65 53 74 61 74 65 20 54 43 4c 20 72  ctiveState TCL r
b930: 65 74 75 72 6e 73 20 61 20 73 6c 69 67 68 74 6c  eturns a slightl
b940: 79 20 64 69 66 66 65 72 65 6e 74 0a 20 20 23 20  y different.  # 
b950: 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e 20 20  error message.  
b960: 57 65 20 6d 61 70 20 74 68 61 74 20 74 6f 20 74  We map that to t
b970: 68 65 20 65 78 70 65 63 74 65 64 20 6d 65 73 73  he expected mess
b980: 61 67 65 0a 20 20 23 20 73 6f 20 74 68 61 74 20  age.  # so that 
b990: 77 65 20 64 6f 6e 27 74 20 68 61 76 65 20 74 6f  we don't have to
b9a0: 20 63 68 61 6e 67 65 20 61 6c 6c 20 6f 66 20 74   change all of t
b9b0: 68 65 20 74 65 73 74 0a 20 20 23 20 63 61 73 65  he test.  # case
b9c0: 73 2e 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f  s..  if {$::tcl_
b9d0: 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72  platform(platfor
b9e0: 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d 20 7b  m)=="windows"} {
b9f0: 0a 20 20 20 20 69 66 20 7b 24 6d 73 67 3d 3d 22  .    if {$msg=="
ba00: 63 68 69 6c 64 20 6b 69 6c 6c 65 64 3a 20 75 6e  child killed: un
ba10: 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c 22 7d 20 7b  known signal"} {
ba20: 0a 20 20 20 20 20 20 73 65 74 20 6d 73 67 20 22  .      set msg "
ba30: 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78  child process ex
ba40: 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22  ited abnormally"
ba50: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 6c 61  .    }.  }..  la
ba60: 70 70 65 6e 64 20 72 20 24 6d 73 67 0a 7d 0a 0a  ppend r $msg.}..
ba70: 70 72 6f 63 20 72 75 6e 5f 69 6f 65 72 72 5f 70  proc run_ioerr_p
ba80: 72 65 70 20 7b 7d 20 7b 0a 20 20 73 65 74 20 3a  rep {} {.  set :
ba90: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
baa0: 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 63 61 74  _pending 0.  cat
bab0: 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20  ch {db close}.  
bac0: 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65  catch {db2 close
bad0: 7d 0a 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65  }.  catch {force
bae0: 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62 7d 0a  delete test.db}.
baf0: 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65    catch {forcede
bb00: 6c 65 74 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75  lete test.db-jou
bb10: 72 6e 61 6c 7d 0a 20 20 63 61 74 63 68 20 7b 66  rnal}.  catch {f
bb20: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 32  orcedelete test2
bb30: 2e 64 62 7d 0a 20 20 63 61 74 63 68 20 7b 66 6f  .db}.  catch {fo
bb40: 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 32 2e  rcedelete test2.
bb50: 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 73 65  db-journal}.  se
bb60: 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 20  t ::DB [sqlite3 
bb70: 64 62 20 74 65 73 74 2e 64 62 3b 20 73 71 6c 69  db test.db; sqli
bb80: 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70  te3_connection_p
bb90: 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 73 71 6c  ointer db].  sql
bba0: 69 74 65 33 5f 65 78 74 65 6e 64 65 64 5f 72 65  ite3_extended_re
bbb0: 73 75 6c 74 5f 63 6f 64 65 73 20 24 3a 3a 44 42  sult_codes $::DB
bbc0: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65   $::ioerropts(-e
bbd0: 72 63 29 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20  rc).  if {[info 
bbe0: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
bbf0: 74 73 28 2d 74 63 6c 70 72 65 70 29 5d 7d 20 7b  ts(-tclprep)]} {
bc00: 0a 20 20 20 20 65 76 61 6c 20 24 3a 3a 69 6f 65  .    eval $::ioe
bc10: 72 72 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29  rropts(-tclprep)
bc20: 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f  .  }.  if {[info
bc30: 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f   exists ::ioerro
bc40: 70 74 73 28 2d 73 71 6c 70 72 65 70 29 5d 7d 20  pts(-sqlprep)]} 
bc50: 7b 0a 20 20 20 20 65 78 65 63 73 71 6c 20 24 3a  {.    execsql $:
bc60: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 70  :ioerropts(-sqlp
bc70: 72 65 70 29 0a 20 20 7d 0a 20 20 65 78 70 72 20  rep).  }.  expr 
bc80: 30 0a 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64 6f  0.}..# Usage: do
bc90: 5f 69 6f 65 72 72 5f 74 65 73 74 20 3c 74 65 73  _ioerr_test <tes
bca0: 74 20 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69 6f  t number> <optio
bcb0: 6e 73 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73 20  ns...>.#.# This 
bcc0: 70 72 6f 63 20 69 73 20 75 73 65 64 20 74 6f 20  proc is used to 
bcd0: 69 6d 70 6c 65 6d 65 6e 74 20 74 65 73 74 20 63  implement test c
bce0: 61 73 65 73 20 74 68 61 74 20 63 68 65 63 6b 20  ases that check 
bcf0: 74 68 61 74 20 49 4f 20 65 72 72 6f 72 73 0a 23  that IO errors.#
bd00: 20 61 72 65 20 63 6f 72 72 65 63 74 6c 79 20 68   are correctly h
bd10: 61 6e 64 6c 65 64 2e 20 54 68 65 20 66 69 72 73  andled. The firs
bd20: 74 20 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65 73  t argument, <tes
bd30: 74 20 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61 6e  t number>, is an
bd40: 20 69 6e 74 65 67 65 72 0a 23 20 75 73 65 64 20   integer.# used 
bd50: 74 6f 20 6e 61 6d 65 20 74 68 65 20 74 65 73 74  to name the test
bd60: 73 20 65 78 65 63 75 74 65 64 20 62 79 20 74 68  s executed by th
bd70: 69 73 20 70 72 6f 63 2e 20 4f 70 74 69 6f 6e 73  is proc. Options
bd80: 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a   are as follows:
bd90: 0a 23 0a 23 20 20 20 20 20 2d 74 63 6c 70 72 65  .#.#     -tclpre
bda0: 70 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73  p          TCL s
bdb0: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74 6f 20  cript to run to 
bdc0: 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a 23 20  prepare test..# 
bdd0: 20 20 20 20 2d 73 71 6c 70 72 65 70 20 20 20 20      -sqlprep    
bde0: 20 20 20 20 20 20 53 51 4c 20 73 63 72 69 70 74        SQL script
bdf0: 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61   to run to prepa
be00: 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  re test..#     -
be10: 74 63 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20  tclbody         
be20: 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72   TCL script to r
be30: 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72  un with IO error
be40: 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20   simulation..#  
be50: 20 20 20 2d 73 71 6c 62 6f 64 79 20 20 20 20 20     -sqlbody     
be60: 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20       TCL script 
be70: 74 6f 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65  to run with IO e
be80: 72 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e  rror simulation.
be90: 0a 23 20 20 20 20 20 2d 65 78 63 6c 75 64 65 20  .#     -exclude 
bea0: 20 20 20 20 20 20 20 20 20 4c 69 73 74 20 6f 66           List of
beb0: 20 27 4e 27 20 76 61 6c 75 65 73 20 6e 6f 74 20   'N' values not 
bec0: 74 6f 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  to test..#     -
bed0: 65 72 63 20 20 20 20 20 20 20 20 20 20 20 20 20  erc             
bee0: 20 55 73 65 20 65 78 74 65 6e 64 65 64 20 72 65   Use extended re
bef0: 73 75 6c 74 20 63 6f 64 65 73 0a 23 20 20 20 20  sult codes.#    
bf00: 20 2d 70 65 72 73 69 73 74 20 20 20 20 20 20 20   -persist       
bf10: 20 20 20 4d 61 6b 65 20 73 69 6d 75 6c 61 74 65     Make simulate
bf20: 64 20 49 2f 4f 20 65 72 72 6f 72 73 20 70 65 72  d I/O errors per
bf30: 73 69 73 74 65 6e 74 0a 23 20 20 20 20 20 2d 73  sistent.#     -s
bf40: 74 61 72 74 20 20 20 20 20 20 20 20 20 20 20 20  tart            
bf50: 56 61 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f 20  Value of 'N' to 
bf60: 62 65 67 69 6e 20 77 69 74 68 20 28 64 65 66 61  begin with (defa
bf70: 75 6c 74 20 31 29 0a 23 0a 23 20 20 20 20 20 2d  ult 1).#.#     -
bf80: 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20  cksum           
bf90: 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72 75   Boolean. If tru
bfa0: 65 2c 20 74 65 73 74 20 74 68 61 74 20 74 68 65  e, test that the
bfb0: 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 0a 23   database does.#
bfc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bfd0: 20 20 20 20 20 20 20 6e 6f 74 20 63 68 61 6e 67         not chang
bfe0: 65 20 64 75 72 69 6e 67 20 74 68 65 20 65 78 65  e during the exe
bff0: 63 75 74 69 6f 6e 20 6f 66 20 74 68 65 20 74 65  cution of the te
c000: 73 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63 20  st case..#.proc 
c010: 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b 74  do_ioerr_test {t
c020: 65 73 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b 0a  estname args} {.
c030: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
c040: 74 73 28 2d 73 74 61 72 74 29 20 31 0a 20 20 73  ts(-start) 1.  s
c050: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
c060: 63 6b 73 75 6d 29 20 30 0a 20 20 73 65 74 20 3a  cksum) 0.  set :
c070: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
c080: 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   0.  set ::ioerr
c090: 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20 31 30 30  opts(-count) 100
c0a0: 30 30 30 30 30 30 0a 20 20 73 65 74 20 3a 3a 69  000000.  set ::i
c0b0: 6f 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73  oerropts(-persis
c0c0: 74 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65  t) 1.  set ::ioe
c0d0: 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75  rropts(-ckrefcou
c0e0: 6e 74 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f  nt) 0.  set ::io
c0f0: 65 72 72 6f 70 74 73 28 2d 72 65 73 74 6f 72 65  erropts(-restore
c100: 70 72 6e 67 29 20 31 0a 20 20 61 72 72 61 79 20  prng) 1.  array 
c110: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 20  set ::ioerropts 
c120: 24 61 72 67 73 0a 0a 20 20 23 20 54 45 4d 50 4f  $args..  # TEMPO
c130: 52 41 52 59 3a 20 46 6f 72 20 33 2e 35 2e 39 2c  RARY: For 3.5.9,
c140: 20 64 69 73 61 62 6c 65 20 74 65 73 74 69 6e 67   disable testing
c150: 20 6f 66 20 65 78 74 65 6e 64 65 64 20 72 65 73   of extended res
c160: 75 6c 74 20 63 6f 64 65 73 2e 20 54 68 65 72 65  ult codes. There
c170: 20 61 72 65 0a 20 20 23 20 61 20 63 6f 75 70 6c   are.  # a coupl
c180: 65 20 6f 66 20 6f 62 73 63 75 72 65 20 49 4f 20  e of obscure IO 
c190: 65 72 72 6f 72 73 20 74 68 61 74 20 64 6f 20 6e  errors that do n
c1a0: 6f 74 20 72 65 74 75 72 6e 20 74 68 65 6d 2e 0a  ot return them..
c1b0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
c1c0: 73 28 2d 65 72 63 29 20 30 0a 0a 20 20 23 20 43  s(-erc) 0..  # C
c1d0: 72 65 61 74 65 20 61 20 73 69 6e 67 6c 65 20 54  reate a single T
c1e0: 43 4c 20 73 63 72 69 70 74 20 66 72 6f 6d 20 74  CL script from t
c1f0: 68 65 20 54 43 4c 20 61 6e 64 20 53 51 4c 20 73  he TCL and SQL s
c200: 70 65 63 69 66 69 65 64 0a 20 20 23 20 61 73 20  pecified.  # as 
c210: 74 68 65 20 62 6f 64 79 20 6f 66 20 74 68 65 20  the body of the 
c220: 74 65 73 74 2e 0a 20 20 73 65 74 20 3a 3a 69 6f  test..  set ::io
c230: 65 72 72 6f 72 62 6f 64 79 20 7b 7d 0a 20 20 69  errorbody {}.  i
c240: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
c250: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c  ::ioerropts(-tcl
c260: 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20 20 61 70  body)]} {.    ap
c270: 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f  pend ::ioerrorbo
c280: 64 79 20 22 24 3a 3a 69 6f 65 72 72 6f 70 74 73  dy "$::ioerropts
c290: 28 2d 74 63 6c 62 6f 64 79 29 5c 6e 22 0a 20 20  (-tclbody)\n".  
c2a0: 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  }.  if {[info ex
c2b0: 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73  ists ::ioerropts
c2c0: 28 2d 73 71 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20  (-sqlbody)]} {. 
c2d0: 20 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72     append ::ioer
c2e0: 72 6f 72 62 6f 64 79 20 22 64 62 20 65 76 61 6c  rorbody "db eval
c2f0: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
c300: 73 71 6c 62 6f 64 79 29 7d 22 0a 20 20 7d 0a 0a  sqlbody)}".  }..
c310: 20 20 73 61 76 65 5f 70 72 6e 67 5f 73 74 61 74    save_prng_stat
c320: 65 0a 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72  e.  if {$::ioerr
c330: 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a  opts(-cksum)} {.
c340: 20 20 20 20 72 75 6e 5f 69 6f 65 72 72 5f 70 72      run_ioerr_pr
c350: 65 70 0a 20 20 20 20 65 76 61 6c 20 24 3a 3a 69  ep.    eval $::i
c360: 6f 65 72 72 6f 72 62 6f 64 79 0a 20 20 20 20 73  oerrorbody.    s
c370: 65 74 20 3a 3a 67 6f 6f 64 63 6b 73 75 6d 20 5b  et ::goodcksum [
c380: 63 6b 73 75 6d 5d 0a 20 20 7d 0a 0a 20 20 73 65  cksum].  }..  se
c390: 74 20 3a 3a 67 6f 20 31 0a 20 20 23 72 65 73 65  t ::go 1.  #rese
c3a0: 74 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 66  t_prng_state.  f
c3b0: 6f 72 20 7b 73 65 74 20 6e 20 24 3a 3a 69 6f 65  or {set n $::ioe
c3c0: 72 72 6f 70 74 73 28 2d 73 74 61 72 74 29 7d 20  rropts(-start)} 
c3d0: 7b 24 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20 6e 7d  {$::go} {incr n}
c3e0: 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 54 4e 20   {.    set ::TN 
c3f0: 24 6e 0a 20 20 20 20 69 6e 63 72 20 3a 3a 69 6f  $n.    incr ::io
c400: 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20  erropts(-count) 
c410: 2d 31 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f  -1.    if {$::io
c420: 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 3c  erropts(-count)<
c430: 30 7d 20 62 72 65 61 6b 0a 0a 20 20 20 20 23 20  0} break..    # 
c440: 53 6b 69 70 20 74 68 69 73 20 49 4f 20 65 72 72  Skip this IO err
c450: 6f 72 20 69 66 20 69 74 20 77 61 73 20 73 70 65  or if it was spe
c460: 63 69 66 69 65 64 20 77 69 74 68 20 74 68 65 20  cified with the 
c470: 22 2d 65 78 63 6c 75 64 65 22 20 6f 70 74 69 6f  "-exclude" optio
c480: 6e 2e 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f  n..    if {[info
c490: 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f   exists ::ioerro
c4a0: 70 74 73 28 2d 65 78 63 6c 75 64 65 29 5d 7d 20  pts(-exclude)]} 
c4b0: 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 6c 73 65  {.      if {[lse
c4c0: 61 72 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74  arch $::ioerropt
c4d0: 73 28 2d 65 78 63 6c 75 64 65 29 20 24 6e 5d 21  s(-exclude) $n]!
c4e0: 3d 2d 31 7d 20 63 6f 6e 74 69 6e 75 65 0a 20 20  =-1} continue.  
c4f0: 20 20 7d 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69    }.    if {$::i
c500: 6f 65 72 72 6f 70 74 73 28 2d 72 65 73 74 6f 72  oerropts(-restor
c510: 65 70 72 6e 67 29 7d 20 7b 0a 20 20 20 20 20 20  eprng)} {.      
c520: 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f 73 74 61  restore_prng_sta
c530: 74 65 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20  te.    }..    # 
c540: 44 65 6c 65 74 65 20 74 68 65 20 66 69 6c 65 73  Delete the files
c550: 20 74 65 73 74 2e 64 62 20 61 6e 64 20 74 65 73   test.db and tes
c560: 74 32 2e 64 62 2c 20 74 68 65 6e 20 65 78 65 63  t2.db, then exec
c570: 75 74 65 20 74 68 65 20 54 43 4c 20 61 6e 64 0a  ute the TCL and.
c580: 20 20 20 20 23 20 53 51 4c 20 28 69 6e 20 74 68      # SQL (in th
c590: 61 74 20 6f 72 64 65 72 29 20 74 6f 20 70 72 65  at order) to pre
c5a0: 70 61 72 65 20 66 6f 72 20 74 68 65 20 74 65 73  pare for the tes
c5b0: 74 20 63 61 73 65 2e 0a 20 20 20 20 64 6f 5f 74  t case..    do_t
c5c0: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e  est $testname.$n
c5d0: 2e 31 20 7b 0a 20 20 20 20 20 20 72 75 6e 5f 69  .1 {.      run_i
c5e0: 6f 65 72 72 5f 70 72 65 70 0a 20 20 20 20 7d 20  oerr_prep.    } 
c5f0: 7b 30 7d 0a 0a 20 20 20 20 23 20 52 65 61 64 20  {0}..    # Read 
c600: 74 68 65 20 27 63 68 65 63 6b 73 75 6d 27 20 6f  the 'checksum' o
c610: 66 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a  f the database..
c620: 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72      if {$::ioerr
c630: 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a  opts(-cksum)} {.
c640: 20 20 20 20 20 20 73 65 74 20 3a 3a 63 68 65 63        set ::chec
c650: 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 20  ksum [cksum].   
c660: 20 7d 0a 0a 20 20 20 20 23 20 53 65 74 20 74 68   }..    # Set th
c670: 65 20 4e 74 68 20 49 4f 20 65 72 72 6f 72 20 74  e Nth IO error t
c680: 6f 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74  o fail..    do_t
c690: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e  est $testname.$n
c6a0: 2e 32 20 5b 73 75 62 73 74 20 7b 0a 20 20 20 20  .2 [subst {.    
c6b0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
c6c0: 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20  o_error_persist 
c6d0: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70 65  $::ioerropts(-pe
c6e0: 72 73 69 73 74 29 0a 20 20 20 20 20 20 73 65 74  rsist).      set
c6f0: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
c700: 6f 72 5f 70 65 6e 64 69 6e 67 20 24 6e 0a 20 20  or_pending $n.  
c710: 20 20 7d 5d 20 24 6e 0a 0a 20 20 20 20 23 20 45    }] $n..    # E
c720: 78 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 73  xecute the TCL s
c730: 63 72 69 70 74 20 63 72 65 61 74 65 64 20 66 6f  cript created fo
c740: 72 20 74 68 65 20 62 6f 64 79 20 6f 66 20 74 68  r the body of th
c750: 69 73 20 74 65 73 74 2e 20 49 66 0a 20 20 20 20  is test. If.    
c760: 23 20 61 74 20 6c 65 61 73 74 20 4e 20 49 4f 20  # at least N IO 
c770: 6f 70 65 72 61 74 69 6f 6e 73 20 70 65 72 66 6f  operations perfo
c780: 72 6d 65 64 20 62 79 20 53 51 4c 69 74 65 20 61  rmed by SQLite a
c790: 73 20 61 20 72 65 73 75 6c 74 20 6f 66 0a 20 20  s a result of.  
c7a0: 20 20 23 20 74 68 65 20 73 63 72 69 70 74 2c 20    # the script, 
c7b0: 74 68 65 20 4e 74 68 20 77 69 6c 6c 20 66 61 69  the Nth will fai
c7c0: 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  l..    do_test $
c7d0: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 33 20 7b 0a  testname.$n.3 {.
c7e0: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
c7f0: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20  te_io_error_hit 
c800: 30 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  0.      set ::sq
c810: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61  lite_io_error_ha
c820: 72 64 68 69 74 20 30 0a 20 20 20 20 20 20 73 65  rdhit 0.      se
c830: 74 20 72 20 5b 63 61 74 63 68 20 24 3a 3a 69 6f  t r [catch $::io
c840: 65 72 72 6f 72 62 6f 64 79 20 6d 73 67 5d 0a 20  errorbody msg]. 
c850: 20 20 20 20 20 73 65 74 20 3a 3a 65 72 72 73 65       set ::errse
c860: 65 6e 20 24 72 0a 20 20 20 20 20 20 73 65 74 20  en $r.      set 
c870: 72 63 20 5b 73 71 6c 69 74 65 33 5f 65 72 72 63  rc [sqlite3_errc
c880: 6f 64 65 20 24 3a 3a 44 42 5d 0a 20 20 20 20 20  ode $::DB].     
c890: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
c8a0: 73 28 2d 65 72 63 29 7d 20 7b 0a 20 20 20 20 20  s(-erc)} {.     
c8b0: 20 20 20 23 20 49 66 20 77 65 20 61 72 65 20 69     # If we are i
c8c0: 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c  n extended resul
c8d0: 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20 6d 61 6b  t code mode, mak
c8e0: 65 20 73 75 72 65 20 61 6c 6c 20 6f 66 20 74 68  e sure all of th
c8f0: 65 0a 20 20 20 20 20 20 20 20 23 20 49 4f 45 52  e.        # IOER
c900: 52 73 20 77 65 20 67 65 74 20 62 61 63 6b 20 72  Rs we get back r
c910: 65 61 6c 6c 79 20 64 6f 20 68 61 76 65 20 74 68  eally do have th
c920: 65 69 72 20 65 78 74 65 6e 64 65 64 20 63 6f 64  eir extended cod
c930: 65 20 76 61 6c 75 65 73 2e 0a 20 20 20 20 20 20  e values..      
c940: 20 20 23 20 49 66 20 61 6e 20 65 78 74 65 6e 64    # If an extend
c950: 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 69  ed result code i
c960: 73 20 72 65 74 75 72 6e 65 64 2c 20 74 68 65 20  s returned, the 
c970: 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 0a  sqlite3_errcode.
c980: 20 20 20 20 20 20 20 20 23 20 54 43 4c 63 6f 6d          # TCLcom
c990: 6d 61 6e 64 20 77 69 6c 6c 20 72 65 74 75 72 6e  mand will return
c9a0: 20 61 20 73 74 72 69 6e 67 20 6f 66 20 74 68 65   a string of the
c9b0: 20 66 6f 72 6d 3a 20 20 53 51 4c 49 54 45 5f 49   form:  SQLITE_I
c9c0: 4f 45 52 52 2b 6e 6e 6e 6e 0a 20 20 20 20 20 20  OERR+nnnn.      
c9d0: 20 20 23 20 77 68 65 72 65 20 6e 6e 6e 6e 20 69    # where nnnn i
c9e0: 73 20 61 20 6e 75 6d 62 65 72 0a 20 20 20 20 20  s a number.     
c9f0: 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b     if {[regexp {
ca00: 5e 53 51 4c 49 54 45 5f 49 4f 45 52 52 7d 20 24  ^SQLITE_IOERR} $
ca10: 72 63 5d 20 26 26 20 21 5b 72 65 67 65 78 70 20  rc] && ![regexp 
ca20: 7b 49 4f 45 52 52 5c 2b 5c 64 7d 20 24 72 63 5d  {IOERR\+\d} $rc]
ca30: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65  } {.          re
ca40: 74 75 72 6e 20 24 72 63 0a 20 20 20 20 20 20 20  turn $rc.       
ca50: 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20   }.      } else 
ca60: 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 77  {.        # If w
ca70: 65 20 61 72 65 20 6e 6f 74 20 69 6e 20 65 78 74  e are not in ext
ca80: 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64  ended result cod
ca90: 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72  e mode, make sur
caa0: 65 20 6e 6f 0a 20 20 20 20 20 20 20 20 23 20 65  e no.        # e
cab0: 78 74 65 6e 64 65 64 20 65 72 72 6f 72 20 63 6f  xtended error co
cac0: 64 65 73 20 61 72 65 20 72 65 74 75 72 6e 65 64  des are returned
cad0: 2e 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72  ..        if {[r
cae0: 65 67 65 78 70 20 7b 5c 2b 5c 64 7d 20 24 72 63  egexp {\+\d} $rc
caf0: 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 72  ]} {.          r
cb00: 65 74 75 72 6e 20 24 72 63 0a 20 20 20 20 20 20  eturn $rc.      
cb10: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
cb20: 20 20 23 20 54 68 65 20 74 65 73 74 20 72 65 70    # The test rep
cb30: 65 61 74 73 20 61 73 20 6c 6f 6e 67 20 61 73 20  eats as long as 
cb40: 24 3a 3a 67 6f 20 69 73 20 6e 6f 6e 2d 7a 65 72  $::go is non-zer
cb50: 6f 2e 20 20 24 3a 3a 67 6f 20 73 74 61 72 74 73  o.  $::go starts
cb60: 20 6f 75 74 0a 20 20 20 20 20 20 23 20 61 73 20   out.      # as 
cb70: 31 2e 20 20 57 68 65 6e 20 61 20 74 65 73 74 20  1.  When a test 
cb80: 72 75 6e 73 20 74 6f 20 63 6f 6d 70 6c 65 74 69  runs to completi
cb90: 6f 6e 20 77 69 74 68 6f 75 74 20 68 69 74 74 69  on without hitti
cba0: 6e 67 20 61 6e 20 49 2f 4f 0a 20 20 20 20 20 20  ng an I/O.      
cbb0: 23 20 65 72 72 6f 72 2c 20 74 68 61 74 20 6d 65  # error, that me
cbc0: 61 6e 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20  ans there is no 
cbd0: 70 6f 69 6e 74 20 69 6e 20 63 6f 6e 74 69 6e 75  point in continu
cbe0: 69 6e 67 20 77 69 74 68 20 74 68 69 73 20 74 65  ing with this te
cbf0: 73 74 0a 20 20 20 20 20 20 23 20 63 61 73 65 20  st.      # case 
cc00: 73 6f 20 73 65 74 20 24 3a 3a 67 6f 20 74 6f 20  so set $::go to 
cc10: 7a 65 72 6f 2e 0a 20 20 20 20 20 20 23 0a 20 20  zero..      #.  
cc20: 20 20 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74      if {$::sqlit
cc30: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
cc40: 6e 67 3e 30 7d 20 7b 0a 20 20 20 20 20 20 20 20  ng>0} {.        
cc50: 73 65 74 20 3a 3a 67 6f 20 30 0a 20 20 20 20 20  set ::go 0.     
cc60: 20 20 20 73 65 74 20 71 20 30 0a 20 20 20 20 20     set q 0.     
cc70: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
cc80: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
cc90: 20 30 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20   0.      } else 
cca0: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 71 20  {.        set q 
ccb0: 31 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  1.      }..     
ccc0: 20 73 65 74 20 73 20 5b 65 78 70 72 20 24 3a 3a   set s [expr $::
ccd0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
cce0: 68 69 74 3d 3d 30 5d 0a 20 20 20 20 20 20 69 66  hit==0].      if
ccf0: 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65   {$::sqlite_io_e
cd00: 72 72 6f 72 5f 68 69 74 3e 24 3a 3a 73 71 6c 69  rror_hit>$::sqli
cd10: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64  te_io_error_hard
cd20: 68 69 74 20 26 26 20 24 72 3d 3d 30 7d 20 7b 0a  hit && $r==0} {.
cd30: 20 20 20 20 20 20 20 20 73 65 74 20 72 20 31 0a          set r 1.
cd40: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 65        }.      se
cd50: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
cd60: 72 6f 72 5f 68 69 74 20 30 0a 0a 20 20 20 20 20  ror_hit 0..     
cd70: 20 23 20 4f 6e 65 20 6f 66 20 74 77 6f 20 74 68   # One of two th
cd80: 69 6e 67 73 20 6d 75 73 74 20 68 61 76 65 20 68  ings must have h
cd90: 61 70 70 65 6e 65 64 2e 20 65 69 74 68 65 72 0a  appened. either.
cda0: 20 20 20 20 20 20 23 20 20 20 31 2e 20 20 57 65        #   1.  We
cdb0: 20 6e 65 76 65 72 20 68 69 74 20 74 68 65 20 49   never hit the I
cdc0: 4f 20 65 72 72 6f 72 20 61 6e 64 20 74 68 65 20  O error and the 
cdd0: 53 51 4c 20 72 65 74 75 72 6e 65 64 20 4f 4b 0a  SQL returned OK.
cde0: 20 20 20 20 20 20 23 20 20 20 32 2e 20 20 41 6e        #   2.  An
cdf0: 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20 68 69   IO error was hi
ce00: 74 20 61 6e 64 20 74 68 65 20 53 51 4c 20 66 61  t and the SQL fa
ce10: 69 6c 65 64 0a 20 20 20 20 20 20 23 0a 20 20 20  iled.      #.   
ce20: 20 20 20 23 70 75 74 73 20 22 73 3d 24 73 20 72     #puts "s=$s r
ce30: 3d 24 72 20 71 3d 24 71 22 0a 20 20 20 20 20 20  =$r q=$q".      
ce40: 65 78 70 72 20 7b 20 28 24 73 20 26 26 20 21 24  expr { ($s && !$
ce50: 72 20 26 26 20 21 24 71 29 20 7c 7c 20 28 21 24  r && !$q) || (!$
ce60: 73 20 26 26 20 24 72 20 26 26 20 24 71 29 20 7d  s && $r && $q) }
ce70: 0a 20 20 20 20 7d 20 7b 31 7d 0a 0a 20 20 20 20  .    } {1}..    
ce80: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
ce90: 65 72 72 6f 72 5f 68 69 74 20 30 0a 20 20 20 20  error_hit 0.    
cea0: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
ceb0: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a  error_pending 0.
cec0: 0a 20 20 20 20 23 20 43 68 65 63 6b 20 74 68 61  .    # Check tha
ced0: 74 20 6e 6f 20 70 61 67 65 20 72 65 66 65 72 65  t no page refere
cee0: 6e 63 65 73 20 77 65 72 65 20 6c 65 61 6b 65 64  nces were leaked
cef0: 2e 20 54 68 65 72 65 20 73 68 6f 75 6c 64 20 62  . There should b
cf00: 65 0a 20 20 20 20 23 20 61 20 73 69 6e 67 6c 65  e.    # a single
cf10: 20 72 65 66 65 72 65 6e 63 65 20 69 66 20 74 68   reference if th
cf20: 65 72 65 20 69 73 20 73 74 69 6c 6c 20 61 6e 20  ere is still an 
cf30: 61 63 74 69 76 65 20 74 72 61 6e 73 61 63 74 69  active transacti
cf40: 6f 6e 2c 0a 20 20 20 20 23 20 6f 72 20 7a 65 72  on,.    # or zer
cf50: 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a 20 20 20  o otherwise..   
cf60: 20 23 0a 20 20 20 20 23 20 55 50 44 41 54 45 3a   #.    # UPDATE:
cf70: 20 49 66 20 74 68 65 20 49 4f 20 65 72 72 6f 72   If the IO error
cf80: 20 6f 63 63 75 72 73 20 61 66 74 65 72 20 61 20   occurs after a 
cf90: 27 42 45 47 49 4e 27 20 62 75 74 20 62 65 66 6f  'BEGIN' but befo
cfa0: 72 65 20 61 6e 79 0a 20 20 20 20 23 20 6c 6f 63  re any.    # loc
cfb0: 6b 73 20 61 72 65 20 65 73 74 61 62 6c 69 73 68  ks are establish
cfc0: 65 64 20 6f 6e 20 64 61 74 61 62 61 73 65 20 66  ed on database f
cfd0: 69 6c 65 73 20 28 69 2e 65 2e 20 69 66 20 74 68  iles (i.e. if th
cfe0: 65 20 65 72 72 6f 72 0a 20 20 20 20 23 20 6f 63  e error.    # oc
cff0: 63 75 72 73 20 77 68 69 6c 65 20 61 74 74 65 6d  curs while attem
d000: 70 74 69 6e 67 20 74 6f 20 64 65 74 65 63 74 20  pting to detect 
d010: 61 20 68 6f 74 2d 6a 6f 75 72 6e 61 6c 20 66 69  a hot-journal fi
d020: 6c 65 29 2c 20 74 68 65 6e 0a 20 20 20 20 23 20  le), then.    # 
d030: 74 68 65 72 65 20 6d 61 79 20 30 20 70 61 67 65  there may 0 page
d040: 20 72 65 66 65 72 65 6e 63 65 73 20 61 6e 64 20   references and 
d050: 61 6e 20 61 63 74 69 76 65 20 74 72 61 6e 73 61  an active transa
d060: 63 74 69 6f 6e 20 61 63 63 6f 72 64 69 6e 67 0a  ction according.
d070: 20 20 20 20 23 20 74 6f 20 5b 73 71 6c 69 74 65      # to [sqlite
d080: 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74  3_get_autocommit
d090: 5d 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20  ]..    #.    if 
d0a0: 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71 6c  {$::go && $::sql
d0b0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72  ite_io_error_har
d0c0: 64 68 69 74 20 26 26 20 24 3a 3a 69 6f 65 72 72  dhit && $::ioerr
d0d0: 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74  opts(-ckrefcount
d0e0: 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65  )} {.      do_te
d0f0: 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e  st $testname.$n.
d100: 34 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  4 {.        set 
d110: 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64  bt [btree_from_d
d120: 62 20 64 62 5d 0a 20 20 20 20 20 20 20 20 64 62  b db].        db
d130: 5f 65 6e 74 65 72 20 64 62 0a 20 20 20 20 20 20  _enter db.      
d140: 20 20 61 72 72 61 79 20 73 65 74 20 73 74 61 74    array set stat
d150: 73 20 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73  s [btree_pager_s
d160: 74 61 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20  tats $bt].      
d170: 20 20 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20    db_leave db.  
d180: 20 20 20 20 20 20 73 65 74 20 6e 52 65 66 20 24        set nRef $
d190: 73 74 61 74 73 28 72 65 66 29 0a 20 20 20 20 20  stats(ref).     
d1a0: 20 20 20 65 78 70 72 20 7b 24 6e 52 65 66 20 3d     expr {$nRef =
d1b0: 3d 20 30 20 7c 7c 20 28 5b 73 71 6c 69 74 65 33  = 0 || ([sqlite3
d1c0: 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20  _get_autocommit 
d1d0: 64 62 5d 3d 3d 30 20 26 26 20 24 6e 52 65 66 20  db]==0 && $nRef 
d1e0: 3d 3d 20 31 29 7d 0a 20 20 20 20 20 20 7d 20 7b  == 1)}.      } {
d1f0: 31 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20  1}.    }..    # 
d200: 49 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 6f  If there is an o
d210: 70 65 6e 20 64 61 74 61 62 61 73 65 20 68 61 6e  pen database han
d220: 64 6c 65 20 61 6e 64 20 6e 6f 20 6f 70 65 6e 20  dle and no open 
d230: 74 72 61 6e 73 61 63 74 69 6f 6e 2c 0a 20 20 20  transaction,.   
d240: 20 23 20 61 6e 64 20 74 68 65 20 70 61 67 65 72   # and the pager
d250: 20 69 73 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20   is not running 
d260: 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63  in exclusive-loc
d270: 6b 69 6e 67 20 6d 6f 64 65 2c 0a 20 20 20 20 23  king mode,.    #
d280: 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65 20   check that the 
d290: 70 61 67 65 72 20 69 73 20 69 6e 20 22 75 6e 6c  pager is in "unl
d2a0: 6f 63 6b 65 64 22 20 73 74 61 74 65 2e 20 54 68  ocked" state. Th
d2b0: 65 6f 72 65 74 69 63 61 6c 6c 79 2c 0a 20 20 20  eoretically,.   
d2c0: 20 23 20 69 66 20 61 20 63 61 6c 6c 20 74 6f 20   # if a call to 
d2d0: 78 55 6e 6c 6f 63 6b 28 29 20 66 61 69 6c 65 64  xUnlock() failed
d2e0: 20 64 75 65 20 74 6f 20 61 6e 20 49 4f 20 65 72   due to an IO er
d2f0: 72 6f 72 20 74 68 65 20 75 6e 64 65 72 6c 79 69  ror the underlyi
d300: 6e 67 0a 20 20 20 20 23 20 66 69 6c 65 20 6d 61  ng.    # file ma
d310: 79 20 73 74 69 6c 6c 20 62 65 20 6c 6f 63 6b 65  y still be locke
d320: 64 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 63  d..    #.    ifc
d330: 61 70 61 62 6c 65 20 70 72 61 67 6d 61 20 7b 0a  apable pragma {.
d340: 20 20 20 20 20 20 69 66 20 7b 20 5b 69 6e 66 6f        if { [info
d350: 20 63 6f 6d 6d 61 6e 64 73 20 64 62 5d 20 6e 65   commands db] ne
d360: 20 22 22 0a 20 20 20 20 20 20 20 20 26 26 20 24   "".        && $
d370: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72  ::ioerropts(-ckr
d380: 65 66 63 6f 75 6e 74 29 0a 20 20 20 20 20 20 20  efcount).       
d390: 20 26 26 20 5b 64 62 20 6f 6e 65 20 7b 70 72 61   && [db one {pra
d3a0: 67 6d 61 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65  gma locking_mode
d3b0: 7d 5d 20 65 71 20 22 6e 6f 72 6d 61 6c 22 0a 20  }] eq "normal". 
d3c0: 20 20 20 20 20 20 20 26 26 20 5b 73 71 6c 69 74         && [sqlit
d3d0: 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69  e3_get_autocommi
d3e0: 74 20 64 62 5d 0a 20 20 20 20 20 20 7d 20 7b 0a  t db].      } {.
d3f0: 20 20 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20          do_test 
d400: 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 35 20 7b  $testname.$n.5 {
d410: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 62  .          set b
d420: 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62  t [btree_from_db
d430: 20 64 62 5d 0a 20 20 20 20 20 20 20 20 20 20 64   db].          d
d440: 62 5f 65 6e 74 65 72 20 64 62 0a 20 20 20 20 20  b_enter db.     
d450: 20 20 20 20 20 61 72 72 61 79 20 73 65 74 20 73       array set s
d460: 74 61 74 73 20 5b 62 74 72 65 65 5f 70 61 67 65  tats [btree_page
d470: 72 5f 73 74 61 74 73 20 24 62 74 5d 0a 20 20 20  r_stats $bt].   
d480: 20 20 20 20 20 20 20 64 62 5f 6c 65 61 76 65 20         db_leave 
d490: 64 62 0a 20 20 20 20 20 20 20 20 20 20 73 65 74  db.          set
d4a0: 20 73 74 61 74 73 28 73 74 61 74 65 29 0a 20 20   stats(state).  
d4b0: 20 20 20 20 20 20 7d 20 30 0a 20 20 20 20 20 20        } 0.      
d4c0: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49  }.    }..    # I
d4d0: 66 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63  f an IO error oc
d4e0: 63 75 72 72 65 64 2c 20 74 68 65 6e 20 74 68 65  curred, then the
d4f0: 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65   checksum of the
d500: 20 64 61 74 61 62 61 73 65 20 73 68 6f 75 6c 64   database should
d510: 0a 20 20 20 20 23 20 62 65 20 74 68 65 20 73 61  .    # be the sa
d520: 6d 65 20 61 73 20 62 65 66 6f 72 65 20 74 68 65  me as before the
d530: 20 73 63 72 69 70 74 20 74 68 61 74 20 63 61 75   script that cau
d540: 73 65 64 20 74 68 65 20 49 4f 20 65 72 72 6f 72  sed the IO error
d550: 20 77 61 73 20 72 75 6e 2e 0a 20 20 20 20 23 0a   was run..    #.
d560: 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26      if {$::go &&
d570: 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72   $::sqlite_io_er
d580: 72 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24  ror_hardhit && $
d590: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73  ::ioerropts(-cks
d5a0: 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f  um)} {.      do_
d5b0: 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24  test $testname.$
d5c0: 6e 2e 36 20 7b 0a 20 20 20 20 20 20 20 20 63 61  n.6 {.        ca
d5d0: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
d5e0: 20 20 20 20 20 20 20 63 61 74 63 68 20 7b 64 62         catch {db
d5f0: 32 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20  2 close}.       
d600: 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74   set ::DB [sqlit
d610: 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73  e3 db test.db; s
d620: 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f  qlite3_connectio
d630: 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20  n_pointer db].  
d640: 20 20 20 20 20 20 73 65 74 20 6e 6f 77 63 6b 73        set nowcks
d650: 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 20 20 20  um [cksum].     
d660: 20 20 20 73 65 74 20 72 65 73 20 5b 65 78 70 72     set res [expr
d670: 20 7b 24 6e 6f 77 63 6b 73 75 6d 3d 3d 24 3a 3a   {$nowcksum==$::
d680: 63 68 65 63 6b 73 75 6d 20 7c 7c 20 24 6e 6f 77  checksum || $now
d690: 63 6b 73 75 6d 3d 3d 24 3a 3a 67 6f 6f 64 63 6b  cksum==$::goodck
d6a0: 73 75 6d 7d 5d 0a 20 20 20 20 20 20 20 20 69 66  sum}].        if
d6b0: 20 7b 24 72 65 73 3d 3d 30 7d 20 7b 0a 20 20 20   {$res==0} {.   
d6c0: 20 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22         output2 "
d6d0: 6e 6f 77 3d 24 6e 6f 77 63 6b 73 75 6d 22 0a 20  now=$nowcksum". 
d6e0: 20 20 20 20 20 20 20 20 20 6f 75 74 70 75 74 32           output2
d6f0: 20 22 74 68 65 3d 24 3a 3a 63 68 65 63 6b 73 75   "the=$::checksu
d700: 6d 22 0a 20 20 20 20 20 20 20 20 20 20 6f 75 74  m".          out
d710: 70 75 74 32 20 22 66 77 64 3d 24 3a 3a 67 6f 6f  put2 "fwd=$::goo
d720: 64 63 6b 73 75 6d 22 0a 20 20 20 20 20 20 20 20  dcksum".        
d730: 7d 0a 20 20 20 20 20 20 20 20 73 65 74 20 72 65  }.        set re
d740: 73 0a 20 20 20 20 20 20 7d 20 31 0a 20 20 20 20  s.      } 1.    
d750: 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  }..    set ::sql
d760: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72  ite_io_error_har
d770: 64 68 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a  dhit 0.    set :
d780: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
d790: 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 69  _pending 0.    i
d7a0: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
d7b0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65  ::ioerropts(-cle
d7c0: 61 6e 75 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20  anup)]} {.      
d7d0: 63 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70  catch $::ioerrop
d7e0: 74 73 28 2d 63 6c 65 61 6e 75 70 29 0a 20 20 20  ts(-cleanup).   
d7f0: 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a 3a 73   }.  }.  set ::s
d800: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
d810: 65 6e 64 69 6e 67 20 30 0a 20 20 73 65 74 20 3a  ending 0.  set :
d820: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
d830: 5f 70 65 72 73 69 73 74 20 30 0a 20 20 75 6e 73  _persist 0.  uns
d840: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 0a 7d  et ::ioerropts.}
d850: 0a 0a 23 20 52 65 74 75 72 6e 20 61 20 63 68 65  ..# Return a che
d860: 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74  cksum based on t
d870: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
d880: 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65  he main database
d890: 20 61 73 73 6f 63 69 61 74 65 64 0a 23 20 77 69   associated.# wi
d8a0: 74 68 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 24 64  th connection $d
d8b0: 62 0a 23 0a 70 72 6f 63 20 63 6b 73 75 6d 20 7b  b.#.proc cksum {
d8c0: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74  {db db}} {.  set
d8d0: 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20 7b   txt [$db eval {
d8e0: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
d8f0: 6d 65 2c 20 74 79 70 65 2c 20 73 71 6c 20 46 52  me, type, sql FR
d900: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
d910: 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20   order by name. 
d920: 20 7d 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68 20   }]\n.  foreach 
d930: 74 62 6c 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a  tbl [$db eval {.
d940: 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d        SELECT nam
d950: 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  e FROM sqlite_ma
d960: 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d  ster WHERE type=
d970: 27 74 61 62 6c 65 27 20 6f 72 64 65 72 20 62 79  'table' order by
d980: 20 6e 61 6d 65 0a 20 20 7d 5d 20 7b 0a 20 20 20   name.  }] {.   
d990: 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62   append txt [$db
d9a0: 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20   eval "SELECT * 
d9b0: 46 52 4f 4d 20 24 74 62 6c 22 5d 5c 6e 0a 20 20  FROM $tbl"]\n.  
d9c0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 70 72 61 67  }.  foreach prag
d9d0: 20 7b 64 65 66 61 75 6c 74 5f 73 79 6e 63 68 72   {default_synchr
d9e0: 6f 6e 6f 75 73 20 64 65 66 61 75 6c 74 5f 63 61  onous default_ca
d9f0: 63 68 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20  che_size} {.    
da00: 61 70 70 65 6e 64 20 74 78 74 20 24 70 72 61 67  append txt $prag
da10: 2d 5b 24 64 62 20 65 76 61 6c 20 22 50 52 41 47  -[$db eval "PRAG
da20: 4d 41 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d  MA $prag"]\n.  }
da30: 0a 20 20 73 65 74 20 63 6b 73 75 6d 20 5b 73 74  .  set cksum [st
da40: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 74 78 74  ring length $txt
da50: 5d 2d 5b 6d 64 35 20 24 74 78 74 5d 0a 20 20 23  ]-[md5 $txt].  #
da60: 20 70 75 74 73 20 24 63 6b 73 75 6d 2d 5b 66 69   puts $cksum-[fi
da70: 6c 65 20 73 69 7a 65 20 74 65 73 74 2e 64 62 5d  le size test.db]
da80: 0a 20 20 72 65 74 75 72 6e 20 24 63 6b 73 75 6d  .  return $cksum
da90: 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61  .}..# Generate a
daa0: 20 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20   checksum based 
dab0: 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  on the contents 
dac0: 6f 66 20 74 68 65 20 6d 61 69 6e 20 61 6e 64 20  of the main and 
dad0: 74 65 6d 70 20 74 61 62 6c 65 73 0a 23 20 64 61  temp tables.# da
dae0: 74 61 62 61 73 65 20 24 64 62 2e 20 49 66 20 74  tabase $db. If t
daf0: 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74  he checksum of t
db00: 77 6f 20 64 61 74 61 62 61 73 65 73 20 69 73 20  wo databases is 
db10: 74 68 65 20 73 61 6d 65 2c 20 61 6e 64 20 74 68  the same, and th
db20: 65 0a 23 20 69 6e 74 65 67 72 69 74 79 2d 63 68  e.# integrity-ch
db30: 65 63 6b 20 70 61 73 73 65 73 20 66 6f 72 20 62  eck passes for b
db40: 6f 74 68 2c 20 74 68 65 20 74 77 6f 20 64 61 74  oth, the two dat
db50: 61 62 61 73 65 73 20 61 72 65 20 69 64 65 6e 74  abases are ident
db60: 69 63 61 6c 2e 0a 23 0a 70 72 6f 63 20 61 6c 6c  ical..#.proc all
db70: 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20  cksum {{db db}} 
db80: 7b 0a 20 20 73 65 74 20 72 65 74 20 5b 6c 69 73  {.  set ret [lis
db90: 74 5d 0a 20 20 69 66 63 61 70 61 62 6c 65 20 74  t].  ifcapable t
dba0: 65 6d 70 64 62 20 7b 0a 20 20 20 20 73 65 74 20  empdb {.    set 
dbb0: 73 71 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45  sql {.      SELE
dbc0: 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c  CT name FROM sql
dbd0: 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45  ite_master WHERE
dbe0: 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20   type = 'table' 
dbf0: 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45  UNION.      SELE
dc00: 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c  CT name FROM sql
dc10: 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 20  ite_temp_master 
dc20: 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74 61  WHERE type = 'ta
dc30: 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20  ble' UNION.     
dc40: 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f   SELECT 'sqlite_
dc50: 6d 61 73 74 65 72 27 20 55 4e 49 4f 4e 0a 20 20  master' UNION.  
dc60: 20 20 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69      SELECT 'sqli
dc70: 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 27 20  te_temp_master' 
dc80: 4f 52 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d  ORDER BY 1.    }
dc90: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
dca0: 73 65 74 20 73 71 6c 20 7b 0a 20 20 20 20 20 20  set sql {.      
dcb0: 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d  SELECT name FROM
dcc0: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
dcd0: 48 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62  HERE type = 'tab
dce0: 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20  le' UNION.      
dcf0: 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 6d  SELECT 'sqlite_m
dd00: 61 73 74 65 72 27 20 4f 52 44 45 52 20 42 59 20  aster' ORDER BY 
dd10: 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65  1.    }.  }.  se
dd20: 74 20 74 62 6c 6c 69 73 74 20 5b 24 64 62 20 65  t tbllist [$db e
dd30: 76 61 6c 20 24 73 71 6c 5d 0a 20 20 73 65 74 20  val $sql].  set 
dd40: 74 78 74 20 7b 7d 0a 20 20 66 6f 72 65 61 63 68  txt {}.  foreach
dd50: 20 74 62 6c 20 24 74 62 6c 6c 69 73 74 20 7b 0a   tbl $tbllist {.
dd60: 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b      append txt [
dd70: 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54  $db eval "SELECT
dd80: 20 2a 20 46 52 4f 4d 20 24 74 62 6c 22 5d 0a 20   * FROM $tbl"]. 
dd90: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 70 72 61   }.  foreach pra
dda0: 67 20 7b 64 65 66 61 75 6c 74 5f 63 61 63 68 65  g {default_cache
ddb0: 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70  _size} {.    app
ddc0: 65 6e 64 20 74 78 74 20 24 70 72 61 67 2d 5b 24  end txt $prag-[$
ddd0: 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20  db eval "PRAGMA 
dde0: 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20  $prag"]\n.  }.  
ddf0: 23 20 70 75 74 73 20 74 78 74 3d 24 74 78 74 0a  # puts txt=$txt.
de00: 20 20 72 65 74 75 72 6e 20 5b 6d 64 35 20 24 74    return [md5 $t
de10: 78 74 5d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74  xt].}..# Generat
de20: 65 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73  e a checksum bas
de30: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e  ed on the conten
de40: 74 73 20 6f 66 20 61 20 73 69 6e 67 6c 65 20 64  ts of a single d
de50: 61 74 61 62 61 73 65 20 77 69 74 68 0a 23 20 61  atabase with.# a
de60: 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63   database connec
de70: 74 69 6f 6e 2e 20 20 54 68 65 20 6e 61 6d 65 20  tion.  The name 
de80: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
de90: 69 73 20 24 64 62 6e 61 6d 65 2e 0a 23 20 45 78  is $dbname..# Ex
dea0: 61 6d 70 6c 65 73 20 6f 66 20 24 64 62 6e 61 6d  amples of $dbnam
deb0: 65 20 61 72 65 20 22 74 65 6d 70 22 20 6f 72 20  e are "temp" or 
dec0: 22 6d 61 69 6e 22 2e 0a 23 0a 70 72 6f 63 20 64  "main"..#.proc d
ded0: 62 63 6b 73 75 6d 20 7b 64 62 20 64 62 6e 61 6d  bcksum {db dbnam
dee0: 65 7d 20 7b 0a 20 20 69 66 20 7b 24 64 62 6e 61  e} {.  if {$dbna
def0: 6d 65 3d 3d 22 74 65 6d 70 22 7d 20 7b 0a 20 20  me=="temp"} {.  
df00: 20 20 73 65 74 20 6d 61 73 74 65 72 20 73 71 6c    set master sql
df10: 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 0a  ite_temp_master.
df20: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73    } else {.    s
df30: 65 74 20 6d 61 73 74 65 72 20 24 64 62 6e 61 6d  et master $dbnam
df40: 65 2e 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 0a  e.sqlite_master.
df50: 20 20 7d 0a 20 20 73 65 74 20 61 6c 6c 74 61 62    }.  set alltab
df60: 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45   [$db eval "SELE
df70: 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 24 6d 61  CT name FROM $ma
df80: 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d  ster WHERE type=
df90: 27 74 61 62 6c 65 27 22 5d 0a 20 20 73 65 74 20  'table'"].  set 
dfa0: 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53  txt [$db eval "S
dfb0: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 6d 61  ELECT * FROM $ma
dfc0: 73 74 65 72 22 5d 5c 6e 0a 20 20 66 6f 72 65 61  ster"]\n.  forea
dfd0: 63 68 20 74 61 62 20 24 61 6c 6c 74 61 62 20 7b  ch tab $alltab {
dfe0: 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20  .    append txt 
dff0: 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43  [$db eval "SELEC
e000: 54 20 2a 20 46 52 4f 4d 20 24 64 62 6e 61 6d 65  T * FROM $dbname
e010: 2e 24 74 61 62 22 5d 5c 6e 0a 20 20 7d 0a 20 20  .$tab"]\n.  }.  
e020: 72 65 74 75 72 6e 20 5b 6d 64 35 20 24 74 78 74  return [md5 $txt
e030: 5d 0a 7d 0a 0a 70 72 6f 63 20 6d 65 6d 64 65 62  ].}..proc memdeb
e040: 75 67 5f 6c 6f 67 5f 73 71 6c 20 7b 7b 66 69 6c  ug_log_sql {{fil
e050: 65 6e 61 6d 65 20 6d 61 6c 6c 6f 63 73 2e 73 71  ename mallocs.sq
e060: 6c 7d 7d 20 7b 0a 0a 20 20 73 65 74 20 64 61 74  l}} {..  set dat
e070: 61 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65  a [sqlite3_memde
e080: 62 75 67 5f 6c 6f 67 20 64 75 6d 70 5d 0a 20 20  bug_log dump].  
e090: 73 65 74 20 6e 46 72 61 6d 65 20 5b 65 78 70 72  set nFrame [expr
e0a0: 20 5b 6c 6c 65 6e 67 74 68 20 5b 6c 69 6e 64 65   [llength [linde
e0b0: 78 20 24 64 61 74 61 20 30 5d 5d 2d 32 5d 0a 20  x $data 0]]-2]. 
e0c0: 20 69 66 20 7b 24 6e 46 72 61 6d 65 20 3c 20 30   if {$nFrame < 0
e0d0: 7d 20 7b 20 72 65 74 75 72 6e 20 22 22 20 7d 0a  } { return "" }.
e0e0: 0a 20 20 73 65 74 20 64 61 74 61 62 61 73 65 20  .  set database 
e0f0: 74 65 6d 70 0a 0a 20 20 73 65 74 20 74 62 6c 20  temp..  set tbl 
e100: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b  "CREATE TABLE ${
e110: 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63  database}.malloc
e120: 28 7a 54 65 73 74 2c 20 6e 43 61 6c 6c 2c 20 6e  (zTest, nCall, n
e130: 42 79 74 65 2c 20 6c 53 74 61 63 6b 29 3b 22 0a  Byte, lStack);".
e140: 0a 20 20 73 65 74 20 73 71 6c 20 22 22 0a 20 20  .  set sql "".  
e150: 66 6f 72 65 61 63 68 20 65 20 24 64 61 74 61 20  foreach e $data 
e160: 7b 0a 20 20 20 20 73 65 74 20 6e 43 61 6c 6c 20  {.    set nCall 
e170: 5b 6c 69 6e 64 65 78 20 24 65 20 30 5d 0a 20 20  [lindex $e 0].  
e180: 20 20 73 65 74 20 6e 42 79 74 65 20 5b 6c 69 6e    set nByte [lin
e190: 64 65 78 20 24 65 20 31 5d 0a 20 20 20 20 73 65  dex $e 1].    se
e1a0: 74 20 6c 53 74 61 63 6b 20 5b 6c 72 61 6e 67 65  t lStack [lrange
e1b0: 20 24 65 20 32 20 65 6e 64 5d 0a 20 20 20 20 61   $e 2 end].    a
e1c0: 70 70 65 6e 64 20 73 71 6c 20 22 49 4e 53 45 52  ppend sql "INSER
e1d0: 54 20 49 4e 54 4f 20 24 7b 64 61 74 61 62 61 73  T INTO ${databas
e1e0: 65 7d 2e 6d 61 6c 6c 6f 63 20 56 41 4c 55 45 53  e}.malloc VALUES
e1f0: 22 0a 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c  ".    append sql
e200: 20 22 28 27 74 65 73 74 27 2c 20 24 6e 43 61 6c   "('test', $nCal
e210: 6c 2c 20 24 6e 42 79 74 65 2c 20 27 24 6c 53 74  l, $nByte, '$lSt
e220: 61 63 6b 27 29 3b 5c 6e 22 0a 20 20 20 20 66 6f  ack');\n".    fo
e230: 72 65 61 63 68 20 66 20 24 6c 53 74 61 63 6b 20  reach f $lStack 
e240: 7b 0a 20 20 20 20 20 20 73 65 74 20 66 72 61 6d  {.      set fram
e250: 65 73 28 24 66 29 20 31 0a 20 20 20 20 7d 0a 20  es($f) 1.    }. 
e260: 20 7d 0a 0a 20 20 73 65 74 20 74 62 6c 32 20 22   }..  set tbl2 "
e270: 43 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64  CREATE TABLE ${d
e280: 61 74 61 62 61 73 65 7d 2e 66 72 61 6d 65 28 66  atabase}.frame(f
e290: 72 61 6d 65 20 49 4e 54 45 47 45 52 20 50 52 49  rame INTEGER PRI
e2a0: 4d 41 52 59 20 4b 45 59 2c 20 6c 69 6e 65 29 3b  MARY KEY, line);
e2b0: 5c 6e 22 0a 20 20 73 65 74 20 74 62 6c 33 20 22  \n".  set tbl3 "
e2c0: 43 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64  CREATE TABLE ${d
e2d0: 61 74 61 62 61 73 65 7d 2e 66 69 6c 65 28 6e 61  atabase}.file(na
e2e0: 6d 65 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20  me PRIMARY KEY, 
e2f0: 63 6f 6e 74 65 6e 74 29 3b 5c 6e 22 0a 0a 20 20  content);\n"..  
e300: 66 6f 72 65 61 63 68 20 66 20 5b 61 72 72 61 79  foreach f [array
e310: 20 6e 61 6d 65 73 20 66 72 61 6d 65 73 5d 20 7b   names frames] {
e320: 0a 20 20 20 20 73 65 74 20 61 64 64 72 20 5b 66  .    set addr [f
e330: 6f 72 6d 61 74 20 25 78 20 24 66 5d 0a 20 20 20  ormat %x $f].   
e340: 20 73 65 74 20 63 6d 64 20 22 61 64 64 72 32 6c   set cmd "addr2l
e350: 69 6e 65 20 2d 65 20 5b 69 6e 66 6f 20 6e 61 6d  ine -e [info nam
e360: 65 6f 66 65 78 65 63 5d 20 24 61 64 64 72 22 0a  eofexec] $addr".
e370: 20 20 20 20 73 65 74 20 6c 69 6e 65 20 5b 65 76      set line [ev
e380: 61 6c 20 65 78 65 63 20 24 63 6d 64 5d 0a 20 20  al exec $cmd].  
e390: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e    append sql "IN
e3a0: 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61  SERT INTO ${data
e3b0: 62 61 73 65 7d 2e 66 72 61 6d 65 20 56 41 4c 55  base}.frame VALU
e3c0: 45 53 28 24 66 2c 20 27 24 6c 69 6e 65 27 29 3b  ES($f, '$line');
e3d0: 5c 6e 22 0a 0a 20 20 20 20 73 65 74 20 66 69 6c  \n"..    set fil
e3e0: 65 20 5b 6c 69 6e 64 65 78 20 5b 73 70 6c 69 74  e [lindex [split
e3f0: 20 24 6c 69 6e 65 20 3a 5d 20 30 5d 0a 20 20 20   $line :] 0].   
e400: 20 73 65 74 20 66 69 6c 65 73 28 24 66 69 6c 65   set files($file
e410: 29 20 31 0a 20 20 7d 0a 0a 20 20 66 6f 72 65 61  ) 1.  }..  forea
e420: 63 68 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65  ch f [array name
e430: 73 20 66 69 6c 65 73 5d 20 7b 0a 20 20 20 20 73  s files] {.    s
e440: 65 74 20 63 6f 6e 74 65 6e 74 73 20 22 22 0a 20  et contents "". 
e450: 20 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20     catch {.     
e460: 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66   set fd [open $f
e470: 5d 0a 20 20 20 20 20 20 73 65 74 20 63 6f 6e 74  ].      set cont
e480: 65 6e 74 73 20 5b 72 65 61 64 20 24 66 64 5d 0a  ents [read $fd].
e490: 20 20 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a        close $fd.
e4a0: 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 63 6f      }.    set co
e4b0: 6e 74 65 6e 74 73 20 5b 73 74 72 69 6e 67 20 6d  ntents [string m
e4c0: 61 70 20 7b 27 20 27 27 7d 20 24 63 6f 6e 74 65  ap {' ''} $conte
e4d0: 6e 74 73 5d 0a 20 20 20 20 61 70 70 65 6e 64 20  nts].    append 
e4e0: 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  sql "INSERT INTO
e4f0: 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 69 6c   ${database}.fil
e500: 65 20 56 41 4c 55 45 53 28 27 24 66 27 2c 20 27  e VALUES('$f', '
e510: 24 63 6f 6e 74 65 6e 74 73 27 29 3b 5c 6e 22 0a  $contents');\n".
e520: 20 20 7d 0a 0a 20 20 73 65 74 20 66 64 20 5b 6f    }..  set fd [o
e530: 70 65 6e 20 24 66 69 6c 65 6e 61 6d 65 20 77 5d  pen $filename w]
e540: 0a 20 20 70 75 74 73 20 24 66 64 20 22 42 45 47  .  puts $fd "BEG
e550: 49 4e 3b 20 24 7b 74 62 6c 7d 24 7b 74 62 6c 32  IN; ${tbl}${tbl2
e560: 7d 24 7b 74 62 6c 33 7d 24 7b 73 71 6c 7d 20 3b  }${tbl3}${sql} ;
e570: 20 43 4f 4d 4d 49 54 3b 22 0a 20 20 63 6c 6f 73   COMMIT;".  clos
e580: 65 20 24 66 64 0a 7d 0a 0a 23 20 44 72 6f 70 20  e $fd.}..# Drop 
e590: 61 6c 6c 20 74 61 62 6c 65 73 20 69 6e 20 64 61  all tables in da
e5a0: 74 61 62 61 73 65 20 5b 64 62 5d 0a 70 72 6f 63  tabase [db].proc
e5b0: 20 64 72 6f 70 5f 61 6c 6c 5f 74 61 62 6c 65 73   drop_all_tables
e5c0: 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69   {{db db}} {.  i
e5d0: 66 63 61 70 61 62 6c 65 20 74 72 69 67 67 65 72  fcapable trigger
e5e0: 26 26 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20  &&foreignkey {. 
e5f0: 20 20 20 73 65 74 20 70 6b 20 5b 24 64 62 20 6f     set pk [$db o
e600: 6e 65 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69  ne "PRAGMA forei
e610: 67 6e 5f 6b 65 79 73 22 5d 0a 20 20 20 20 24 64  gn_keys"].    $d
e620: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66  b eval "PRAGMA f
e630: 6f 72 65 69 67 6e 5f 6b 65 79 73 20 3d 20 4f 46  oreign_keys = OF
e640: 46 22 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68  F".  }.  foreach
e650: 20 7b 69 64 78 20 6e 61 6d 65 20 66 69 6c 65 7d   {idx name file}
e660: 20 5b 64 62 20 65 76 61 6c 20 7b 50 52 41 47 4d   [db eval {PRAGM
e670: 41 20 64 61 74 61 62 61 73 65 5f 6c 69 73 74 7d  A database_list}
e680: 5d 20 7b 0a 20 20 20 20 69 66 20 7b 24 69 64 78  ] {.    if {$idx
e690: 3d 3d 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  ==1} {.      set
e6a0: 20 6d 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74   master sqlite_t
e6b0: 65 6d 70 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d  emp_master.    }
e6c0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65   else {.      se
e6d0: 74 20 6d 61 73 74 65 72 20 24 6e 61 6d 65 2e 73  t master $name.s
e6e0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 0a 20 20 20  qlite_master.   
e6f0: 20 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b   }.    foreach {
e700: 74 20 74 79 70 65 7d 20 5b 24 64 62 20 65 76 61  t type} [$db eva
e710: 6c 20 22 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l ".      SELECT
e720: 20 6e 61 6d 65 2c 20 74 79 70 65 20 46 52 4f 4d   name, type FROM
e730: 20 24 6d 61 73 74 65 72 0a 20 20 20 20 20 20 57   $master.      W
e740: 48 45 52 45 20 74 79 70 65 20 49 4e 28 27 74 61  HERE type IN('ta
e750: 62 6c 65 27 2c 20 27 76 69 65 77 27 29 20 41 4e  ble', 'view') AN
e760: 44 20 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20  D name NOT LIKE 
e770: 27 73 71 6c 69 74 65 58 5f 25 27 20 45 53 43 41  'sqliteX_%' ESCA
e780: 50 45 20 27 58 27 0a 20 20 20 20 22 5d 20 7b 0a  PE 'X'.    "] {.
e790: 20 20 20 20 20 20 24 64 62 20 65 76 61 6c 20 22        $db eval "
e7a0: 44 52 4f 50 20 24 74 79 70 65 20 5c 22 24 74 5c  DROP $type \"$t\
e7b0: 22 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  "".    }.  }.  i
e7c0: 66 63 61 70 61 62 6c 65 20 74 72 69 67 67 65 72  fcapable trigger
e7d0: 26 26 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20  &&foreignkey {. 
e7e0: 20 20 20 24 64 62 20 65 76 61 6c 20 22 50 52 41     $db eval "PRA
e7f0: 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73  GMA foreign_keys
e800: 20 3d 20 24 70 6b 22 0a 20 20 7d 0a 7d 0a 0a 23   = $pk".  }.}..#
e810: 20 44 72 6f 70 20 61 6c 6c 20 61 75 78 69 6c 69   Drop all auxili
e820: 61 72 79 20 69 6e 64 65 78 65 73 20 66 72 6f 6d  ary indexes from
e830: 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61   the main databa
e840: 73 65 20 6f 70 65 6e 65 64 20 62 79 20 68 61 6e  se opened by han
e850: 64 6c 65 20 5b 64 62 5d 2e 0a 23 0a 70 72 6f 63  dle [db]..#.proc
e860: 20 64 72 6f 70 5f 61 6c 6c 5f 69 6e 64 65 78 65   drop_all_indexe
e870: 73 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  s {{db db}} {.  
e880: 73 65 74 20 4c 20 5b 24 64 62 20 65 76 61 6c 20  set L [$db eval 
e890: 7b 0a 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d  {.    SELECT nam
e8a0: 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  e FROM sqlite_ma
e8b0: 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d  ster WHERE type=
e8c0: 27 69 6e 64 65 78 27 20 41 4e 44 20 73 71 6c 20  'index' AND sql 
e8d0: 4c 49 4b 45 20 27 63 72 65 61 74 65 25 27 0a 20  LIKE 'create%'. 
e8e0: 20 7d 5d 0a 20 20 66 6f 72 65 61 63 68 20 69 64   }].  foreach id
e8f0: 78 20 24 4c 20 7b 20 24 64 62 20 65 76 61 6c 20  x $L { $db eval 
e900: 22 44 52 4f 50 20 49 4e 44 45 58 20 24 69 64 78  "DROP INDEX $idx
e910: 22 20 7d 0a 7d 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  " }.}...#-------
e920: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e930: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e940: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e950: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e960: 2d 2d 0a 23 20 49 66 20 61 20 74 65 73 74 20 73  --.# If a test s
e970: 63 72 69 70 74 20 69 73 20 65 78 65 63 75 74 65  cript is execute
e980: 64 20 77 69 74 68 20 67 6c 6f 62 61 6c 20 76 61  d with global va
e990: 72 69 61 62 6c 65 20 24 3a 3a 47 28 70 65 72 6d  riable $::G(perm
e9a0: 3a 6e 61 6d 65 29 20 73 65 74 20 74 6f 0a 23 20  :name) set to.# 
e9b0: 22 77 61 6c 22 2c 20 74 68 65 6e 20 74 68 65 20  "wal", then the 
e9c0: 74 65 73 74 73 20 61 72 65 20 72 75 6e 20 69 6e  tests are run in
e9d0: 20 57 41 4c 20 6d 6f 64 65 2e 20 4f 74 68 65 72   WAL mode. Other
e9e0: 77 69 73 65 2c 20 74 68 65 79 20 73 68 6f 75 6c  wise, they shoul
e9f0: 64 20 62 65 20 72 75 6e 0a 23 20 69 6e 20 72 6f  d be run.# in ro
ea00: 6c 6c 62 61 63 6b 20 6d 6f 64 65 2e 20 54 68 65  llback mode. The
ea10: 20 66 6f 6c 6c 6f 77 69 6e 67 20 54 63 6c 20 70   following Tcl p
ea20: 72 6f 63 73 20 61 72 65 20 75 73 65 64 20 74 6f  rocs are used to
ea30: 20 6d 61 6b 65 20 74 68 69 73 20 6c 65 73 73 0a   make this less.
ea40: 23 20 69 6e 74 72 75 73 69 76 65 3a 0a 23 0a 23  # intrusive:.#.#
ea50: 20 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e     wal_set_journ
ea60: 61 6c 5f 6d 6f 64 65 20 3f 44 42 3f 0a 23 0a 23  al_mode ?DB?.#.#
ea70: 20 20 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20       If running 
ea80: 61 20 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63  a WAL test, exec
ea90: 75 74 65 20 22 50 52 41 47 4d 41 20 6a 6f 75 72  ute "PRAGMA jour
eaa0: 6e 61 6c 5f 6d 6f 64 65 20 3d 20 77 61 6c 22 20  nal_mode = wal" 
eab0: 75 73 69 6e 67 0a 23 20 20 20 20 20 63 6f 6e 6e  using.#     conn
eac0: 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42  ection handle DB
ead0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74 68 69  . Otherwise, thi
eae0: 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61 20 6e  s command is a n
eaf0: 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f  o-op..#.#   wal_
eb00: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
eb10: 64 65 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f  de TESTNAME ?DB?
eb20: 0a 23 0a 23 20 20 20 20 20 49 66 20 72 75 6e 6e  .#.#     If runn
eb30: 69 6e 67 20 61 20 57 41 4c 20 74 65 73 74 2c 20  ing a WAL test, 
eb40: 65 78 65 63 75 74 65 20 61 20 74 65 73 74 73 20  execute a tests 
eb50: 63 61 73 65 20 74 68 61 74 20 66 61 69 6c 73 20  case that fails 
eb60: 69 66 20 74 68 65 20 6d 61 69 6e 0a 23 20 20 20  if the main.#   
eb70: 20 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 63    database for c
eb80: 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65  onnection handle
eb90: 20 44 42 20 69 73 20 6e 6f 74 20 63 75 72 72 65   DB is not curre
eba0: 6e 74 6c 79 20 61 20 57 41 4c 20 64 61 74 61 62  ntly a WAL datab
ebb0: 61 73 65 2e 0a 23 20 20 20 20 20 4f 74 68 65 72  ase..#     Other
ebc0: 77 69 73 65 20 28 69 66 20 6e 6f 74 20 72 75 6e  wise (if not run
ebd0: 6e 69 6e 67 20 61 20 57 41 4c 20 70 65 72 6d 75  ning a WAL permu
ebe0: 74 61 74 69 6f 6e 29 20 74 68 69 73 20 69 73 20  tation) this is 
ebf0: 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77  a no-op..#.#   w
ec00: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23  al_is_wal_mode.#
ec10: 0a 23 20 20 20 20 20 52 65 74 75 72 6e 73 20 74  .#     Returns t
ec20: 72 75 65 20 69 66 20 74 68 69 73 20 74 65 73 74  rue if this test
ec30: 20 73 68 6f 75 6c 64 20 62 65 20 72 75 6e 20 69   should be run i
ec40: 6e 20 57 41 4c 20 6d 6f 64 65 2e 20 46 61 6c 73  n WAL mode. Fals
ec50: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 23 0a 70  e otherwise..#.p
ec60: 72 6f 63 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d  roc wal_is_wal_m
ec70: 6f 64 65 20 7b 7d 20 7b 0a 20 20 65 78 70 72 20  ode {} {.  expr 
ec80: 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20 65  {[permutation] e
ec90: 71 20 22 77 61 6c 22 7d 0a 7d 0a 70 72 6f 63 20  q "wal"}.}.proc 
eca0: 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f  wal_set_journal_
ecb0: 6d 6f 64 65 20 7b 7b 64 62 20 64 62 7d 7d 20 7b  mode {{db db}} {
ecc0: 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f  .  if { [wal_is_
ecd0: 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20  wal_mode] } {.  
ece0: 20 20 24 64 62 20 65 76 61 6c 20 22 50 52 41 47    $db eval "PRAG
ecf0: 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  MA journal_mode 
ed00: 3d 20 57 41 4c 22 0a 20 20 7d 0a 7d 0a 70 72 6f  = WAL".  }.}.pro
ed10: 63 20 77 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72  c wal_check_jour
ed20: 6e 61 6c 5f 6d 6f 64 65 20 7b 74 65 73 74 6e 61  nal_mode {testna
ed30: 6d 65 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  me {db db}} {.  
ed40: 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c  if { [wal_is_wal
ed50: 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24  _mode] } {.    $
ed60: 64 62 20 65 76 61 6c 20 7b 20 53 45 4c 45 43 54  db eval { SELECT
ed70: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
ed80: 61 73 74 65 72 20 7d 0a 20 20 20 20 64 6f 5f 74  aster }.    do_t
ed90: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 20 5b 6c  est $testname [l
eda0: 69 73 74 20 24 64 62 20 65 76 61 6c 20 22 50 52  ist $db eval "PR
edb0: 41 47 4d 41 20 6d 61 69 6e 2e 6a 6f 75 72 6e 61  AGMA main.journa
edc0: 6c 5f 6d 6f 64 65 22 5d 20 7b 77 61 6c 7d 0a 20  l_mode"] {wal}. 
edd0: 20 7d 0a 7d 0a 0a 70 72 6f 63 20 77 61 6c 5f 69   }.}..proc wal_i
ede0: 73 5f 63 61 70 61 62 6c 65 20 7b 7d 20 7b 0a 20  s_capable {} {. 
edf0: 20 69 66 63 61 70 61 62 6c 65 20 21 77 61 6c 20   ifcapable !wal 
ee00: 7b 20 72 65 74 75 72 6e 20 30 20 7d 0a 20 20 69  { return 0 }.  i
ee10: 66 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d  f {[permutation]
ee20: 3d 3d 22 6a 6f 75 72 6e 61 6c 74 65 73 74 22 7d  =="journaltest"}
ee30: 20 7b 20 72 65 74 75 72 6e 20 30 20 7d 0a 20 20   { return 0 }.  
ee40: 72 65 74 75 72 6e 20 31 0a 7d 0a 0a 70 72 6f 63  return 1.}..proc
ee50: 20 70 65 72 6d 75 74 61 74 69 6f 6e 20 7b 7d 20   permutation {} 
ee60: 7b 0a 20 20 73 65 74 20 70 65 72 6d 20 22 22 0a  {.  set perm "".
ee70: 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 65 72    catch {set per
ee80: 6d 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65  m $::G(perm:name
ee90: 29 7d 0a 20 20 73 65 74 20 70 65 72 6d 0a 7d 0a  )}.  set perm.}.
eea0: 70 72 6f 63 20 70 72 65 73 71 6c 20 7b 7d 20 7b  proc presql {} {
eeb0: 0a 20 20 73 65 74 20 70 72 65 73 71 6c 20 22 22  .  set presql ""
eec0: 0a 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 72  .  catch {set pr
eed0: 65 73 71 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70  esql $::G(perm:p
eee0: 72 65 73 71 6c 29 7d 0a 20 20 73 65 74 20 70 72  resql)}.  set pr
eef0: 65 73 71 6c 0a 7d 0a 0a 70 72 6f 63 20 69 73 71  esql.}..proc isq
ef00: 75 69 63 6b 20 7b 7d 20 7b 0a 20 20 73 65 74 20  uick {} {.  set 
ef10: 72 65 74 20 30 0a 20 20 63 61 74 63 68 20 7b 73  ret 0.  catch {s
ef20: 65 74 20 72 65 74 20 24 3a 3a 47 28 69 73 71 75  et ret $::G(isqu
ef30: 69 63 6b 29 7d 0a 20 20 73 65 74 20 72 65 74 0a  ick)}.  set ret.
ef40: 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  }..#------------
ef50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ef60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ef70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ef80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a  -------------.#.
ef90: 70 72 6f 63 20 73 6c 61 76 65 5f 74 65 73 74 5f  proc slave_test_
efa0: 73 63 72 69 70 74 20 7b 73 63 72 69 70 74 7d 20  script {script} 
efb0: 7b 0a 0a 20 20 23 20 43 72 65 61 74 65 20 74 68  {..  # Create th
efc0: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 75 73  e interpreter us
efd0: 65 64 20 74 6f 20 72 75 6e 20 74 68 65 20 74 65  ed to run the te
efe0: 73 74 20 73 63 72 69 70 74 2e 0a 20 20 69 6e 74  st script..  int
eff0: 65 72 70 20 63 72 65 61 74 65 20 74 69 6e 74 65  erp create tinte
f000: 72 70 0a 0a 20 20 23 20 50 6f 70 75 6c 61 74 65  rp..  # Populate
f010: 20 73 6f 6d 65 20 67 6c 6f 62 61 6c 20 76 61 72   some global var
f020: 69 61 62 6c 65 73 20 74 68 61 74 20 74 65 73 74  iables that test
f030: 65 72 2e 74 63 6c 20 65 78 70 65 63 74 73 20 74  er.tcl expects t
f040: 6f 20 73 65 65 2e 0a 20 20 66 6f 72 65 61 63 68  o see..  foreach
f050: 20 7b 76 61 72 20 76 61 6c 75 65 7d 20 5b 6c 69   {var value} [li
f060: 73 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  st              
f070: 5c 0a 20 20 20 20 3a 3a 61 72 67 76 30 20 24 3a  \.    ::argv0 $:
f080: 3a 61 72 67 76 30 20 20 20 20 20 20 20 20 20 20  :argv0          
f090: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
f0a0: 20 3a 3a 61 72 67 76 20 20 7b 7d 20 20 20 20 20   ::argv  {}     
f0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f0c0: 20 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 53 4c        \.    ::SL
f0d0: 41 56 45 20 31 20 20 20 20 20 20 20 20 20 20 20  AVE 1           
f0e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f0f0: 20 5c 0a 20 20 5d 20 7b 0a 20 20 20 20 69 6e 74   \.  ] {.    int
f100: 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70  erp eval tinterp
f110: 20 5b 6c 69 73 74 20 73 65 74 20 24 76 61 72 20   [list set $var 
f120: 24 76 61 6c 75 65 5d 0a 20 20 7d 0a 0a 20 20 23  $value].  }..  #
f130: 20 49 66 20 6f 75 74 70 75 74 20 69 73 20 62 65   If output is be
f140: 69 6e 67 20 63 6f 70 69 65 64 20 69 6e 74 6f 20  ing copied into 
f150: 61 20 66 69 6c 65 2c 20 73 68 61 72 65 20 74 68  a file, share th
f160: 65 20 66 69 6c 65 2d 64 65 73 63 72 69 70 74 6f  e file-descripto
f170: 72 20 77 69 74 68 0a 20 20 23 20 74 68 65 20 69  r with.  # the i
f180: 6e 74 65 72 70 72 65 74 65 72 2e 0a 20 20 69 66  nterpreter..  if
f190: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
f1a0: 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 5d 7d 20  :G(output_fd)]} 
f1b0: 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 73 68 61  {.    interp sha
f1c0: 72 65 20 7b 7d 20 24 3a 3a 47 28 6f 75 74 70 75  re {} $::G(outpu
f1d0: 74 5f 66 64 29 20 74 69 6e 74 65 72 70 0a 20 20  t_fd) tinterp.  
f1e0: 7d 0a 0a 20 20 23 20 54 68 65 20 61 6c 69 61 73  }..  # The alias
f1f0: 20 75 73 65 64 20 74 6f 20 61 63 63 65 73 73 20   used to access 
f200: 74 68 65 20 67 6c 6f 62 61 6c 20 74 65 73 74 20  the global test 
f210: 63 6f 75 6e 74 65 72 73 2e 0a 20 20 74 69 6e 74  counters..  tint
f220: 65 72 70 20 61 6c 69 61 73 20 73 65 74 5f 74 65  erp alias set_te
f230: 73 74 5f 63 6f 75 6e 74 65 72 20 73 65 74 5f 74  st_counter set_t
f240: 65 73 74 5f 63 6f 75 6e 74 65 72 0a 0a 20 20 23  est_counter..  #
f250: 20 53 65 74 20 75 70 20 74 68 65 20 3a 3a 63 6d   Set up the ::cm
f260: 64 6c 69 6e 65 61 72 67 20 61 72 72 61 79 20 69  dlinearg array i
f270: 6e 20 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69  n the slave..  i
f280: 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65  nterp eval tinte
f290: 72 70 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73  rp [list array s
f2a0: 65 74 20 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20  et ::cmdlinearg 
f2b0: 5b 61 72 72 61 79 20 67 65 74 20 3a 3a 63 6d 64  [array get ::cmd
f2c0: 6c 69 6e 65 61 72 67 5d 5d 0a 0a 20 20 23 20 53  linearg]]..  # S
f2d0: 65 74 20 75 70 20 74 68 65 20 3a 3a 47 20 61 72  et up the ::G ar
f2e0: 72 61 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65  ray in the slave
f2f0: 2e 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20  ..  interp eval 
f300: 74 69 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72  tinterp [list ar
f310: 72 61 79 20 73 65 74 20 3a 3a 47 20 5b 61 72 72  ray set ::G [arr
f320: 61 79 20 67 65 74 20 3a 3a 47 5d 5d 0a 0a 20 20  ay get ::G]]..  
f330: 23 20 4c 6f 61 64 20 74 68 65 20 76 61 72 69 6f  # Load the vario
f340: 75 73 20 74 65 73 74 20 69 6e 74 65 72 66 61 63  us test interfac
f350: 65 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 69  es implemented i
f360: 6e 20 43 2e 0a 20 20 6c 6f 61 64 5f 74 65 73 74  n C..  load_test
f370: 66 69 78 74 75 72 65 5f 65 78 74 65 6e 73 69 6f  fixture_extensio
f380: 6e 73 20 74 69 6e 74 65 72 70 0a 0a 20 20 23 20  ns tinterp..  # 
f390: 52 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  Run the test scr
f3a0: 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 65 76  ipt..  interp ev
f3b0: 61 6c 20 74 69 6e 74 65 72 70 20 24 73 63 72 69  al tinterp $scri
f3c0: 70 74 0a 0a 20 20 23 20 43 68 65 63 6b 20 69 66  pt..  # Check if
f3d0: 20 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72   the interpreter
f3e0: 20 63 61 6c 6c 20 5b 72 75 6e 5f 74 68 72 65 61   call [run_threa
f3f0: 64 5f 74 65 73 74 73 5d 0a 20 20 69 66 20 7b 20  d_tests].  if { 
f400: 5b 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e  [interp eval tin
f410: 74 65 72 70 20 7b 69 6e 66 6f 20 65 78 69 73 74  terp {info exist
f420: 73 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74  s ::run_thread_t
f430: 65 73 74 73 5f 63 61 6c 6c 65 64 7d 5d 20 7d 20  ests_called}] } 
f440: 7b 0a 20 20 20 20 73 65 74 20 3a 3a 72 75 6e 5f  {.    set ::run_
f450: 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c  thread_tests_cal
f460: 6c 65 64 20 31 0a 20 20 7d 0a 0a 20 20 23 20 44  led 1.  }..  # D
f470: 65 6c 65 74 65 20 74 68 65 20 69 6e 74 65 72 70  elete the interp
f480: 72 65 74 65 72 20 75 73 65 64 20 74 6f 20 72 75  reter used to ru
f490: 6e 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  n the test scrip
f4a0: 74 2e 0a 20 20 69 6e 74 65 72 70 20 64 65 6c 65  t..  interp dele
f4b0: 74 65 20 74 69 6e 74 65 72 70 0a 7d 0a 0a 70 72  te tinterp.}..pr
f4c0: 6f 63 20 73 6c 61 76 65 5f 74 65 73 74 5f 66 69  oc slave_test_fi
f4d0: 6c 65 20 7b 7a 46 69 6c 65 7d 20 7b 0a 20 20 73  le {zFile} {.  s
f4e0: 65 74 20 74 61 69 6c 20 5b 66 69 6c 65 20 74 61  et tail [file ta
f4f0: 69 6c 20 24 7a 46 69 6c 65 5d 0a 0a 20 20 69 66  il $zFile]..  if
f500: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
f510: 3a 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61  :G(start:permuta
f520: 74 69 6f 6e 29 5d 7d 20 7b 0a 20 20 20 20 69 66  tion)]} {.    if
f530: 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20   {[permutation] 
f540: 21 3d 20 24 3a 3a 47 28 73 74 61 72 74 3a 70 65  != $::G(start:pe
f550: 72 6d 75 74 61 74 69 6f 6e 29 7d 20 72 65 74 75  rmutation)} retu
f560: 72 6e 0a 20 20 20 20 75 6e 73 65 74 20 3a 3a 47  rn.    unset ::G
f570: 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69  (start:permutati
f580: 6f 6e 29 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69  on).  }.  if {[i
f590: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73  nfo exists ::G(s
f5a0: 74 61 72 74 3a 66 69 6c 65 29 5d 7d 20 7b 0a 20  tart:file)]} {. 
f5b0: 20 20 20 69 66 20 7b 24 74 61 69 6c 20 21 3d 20     if {$tail != 
f5c0: 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29  $::G(start:file)
f5d0: 20 26 26 20 24 74 61 69 6c 21 3d 22 24 3a 3a 47   && $tail!="$::G
f5e0: 28 73 74 61 72 74 3a 66 69 6c 65 29 2e 74 65 73  (start:file).tes
f5f0: 74 22 7d 20 72 65 74 75 72 6e 0a 20 20 20 20 75  t"} return.    u
f600: 6e 73 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 66  nset ::G(start:f
f610: 69 6c 65 29 0a 20 20 7d 0a 0a 20 20 23 20 52 65  ile).  }..  # Re
f620: 6d 65 6d 62 65 72 20 74 68 65 20 76 61 6c 75 65  member the value
f630: 20 6f 66 20 74 68 65 20 73 68 61 72 65 64 2d 63   of the shared-c
f640: 61 63 68 65 20 73 65 74 74 69 6e 67 2e 20 53 6f  ache setting. So
f650: 20 74 68 61 74 20 69 74 20 69 73 20 70 6f 73 73   that it is poss
f660: 69 62 6c 65 0a 20 20 23 20 74 6f 20 63 68 65 63  ible.  # to chec
f670: 6b 20 61 66 74 65 72 77 61 72 64 73 20 74 68 61  k afterwards tha
f680: 74 20 69 74 20 77 61 73 20 6e 6f 74 20 6d 6f 64  t it was not mod
f690: 69 66 69 65 64 20 62 79 20 74 68 65 20 74 65 73  ified by the tes
f6a0: 74 20 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20  t script..  #.  
f6b0: 69 66 63 61 70 61 62 6c 65 20 73 68 61 72 65 64  ifcapable shared
f6c0: 5f 63 61 63 68 65 20 7b 20 73 65 74 20 73 63 73  _cache { set scs
f6d0: 20 5b 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65   [sqlite3_enable
f6e0: 5f 73 68 61 72 65 64 5f 63 61 63 68 65 5d 20 7d  _shared_cache] }
f6f0: 0a 0a 20 20 23 20 52 75 6e 20 74 68 65 20 74 65  ..  # Run the te
f700: 73 74 20 73 63 72 69 70 74 20 69 6e 20 61 20 73  st script in a s
f710: 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74 65 72  lave interpreter
f720: 2e 0a 20 20 23 0a 20 20 75 6e 73 65 74 20 2d 6e  ..  #.  unset -n
f730: 6f 63 6f 6d 70 6c 61 69 6e 20 3a 3a 72 75 6e 5f  ocomplain ::run_
f740: 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c  thread_tests_cal
f750: 6c 65 64 0a 20 20 72 65 73 65 74 5f 70 72 6e 67  led.  reset_prng
f760: 5f 73 74 61 74 65 0a 20 20 73 65 74 20 3a 3a 73  _state.  set ::s
f770: 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f  qlite_open_file_
f780: 63 6f 75 6e 74 20 30 0a 20 20 73 65 74 20 74 69  count 0.  set ti
f790: 6d 65 20 5b 74 69 6d 65 20 7b 20 73 6c 61 76 65  me [time { slave
f7a0: 5f 74 65 73 74 5f 73 63 72 69 70 74 20 5b 6c 69  _test_script [li
f7b0: 73 74 20 73 6f 75 72 63 65 20 24 7a 46 69 6c 65  st source $zFile
f7c0: 5d 20 7d 5d 0a 20 20 73 65 74 20 6d 73 20 5b 65  ] }].  set ms [e
f7d0: 78 70 72 20 5b 6c 69 6e 64 65 78 20 24 74 69 6d  xpr [lindex $tim
f7e0: 65 20 30 5d 20 2f 20 31 30 30 30 5d 0a 0a 20 20  e 0] / 1000]..  
f7f0: 23 20 54 65 73 74 20 74 68 61 74 20 61 6c 6c 20  # Test that all 
f800: 66 69 6c 65 73 20 6f 70 65 6e 65 64 20 62 79 20  files opened by 
f810: 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 20  the test script 
f820: 77 65 72 65 20 63 6c 6f 73 65 64 2e 20 4f 6d 69  were closed. Omi
f830: 74 20 74 68 69 73 0a 20 20 23 20 69 66 20 74 68  t this.  # if th
f840: 65 20 74 65 73 74 20 73 63 72 69 70 74 20 68 61  e test script ha
f850: 73 20 22 74 68 72 65 61 64 22 20 69 6e 20 69 74  s "thread" in it
f860: 73 20 6e 61 6d 65 2e 20 54 68 65 20 6f 70 65 6e  s name. The open
f870: 20 66 69 6c 65 20 63 6f 75 6e 74 65 72 0a 20 20   file counter.  
f880: 23 20 69 73 20 6e 6f 74 20 74 68 72 65 61 64 2d  # is not thread-
f890: 73 61 66 65 2e 0a 20 20 23 0a 20 20 69 66 20 7b  safe..  #.  if {
f8a0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72  [info exists ::r
f8b0: 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f  un_thread_tests_
f8c0: 63 61 6c 6c 65 64 5d 3d 3d 30 7d 20 7b 0a 20 20  called]==0} {.  
f8d0: 20 20 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c    do_test ${tail
f8e0: 7d 2d 63 6c 6f 73 65 61 6c 6c 66 69 6c 65 73 20  }-closeallfiles 
f8f0: 7b 20 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74  { expr {$::sqlit
f900: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
f910: 74 3e 30 7d 20 7d 20 7b 30 7d 0a 20 20 7d 0a 20  t>0} } {0}.  }. 
f920: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 6f 70   set ::sqlite_op
f930: 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 30 0a  en_file_count 0.
f940: 0a 20 20 23 20 54 65 73 74 20 74 68 61 74 20 74  .  # Test that t
f950: 68 65 20 67 6c 6f 62 61 6c 20 22 73 68 61 72 65  he global "share
f960: 64 2d 63 61 63 68 65 22 20 73 65 74 74 69 6e 67  d-cache" setting
f970: 20 77 61 73 20 6e 6f 74 20 61 6c 74 65 72 65 64   was not altered
f980: 20 62 79 0a 20 20 23 20 74 68 65 20 74 65 73 74   by.  # the test
f990: 20 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69   script..  #.  i
f9a0: 66 63 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f  fcapable shared_
f9b0: 63 61 63 68 65 20 7b 0a 20 20 20 20 73 65 74 20  cache {.    set 
f9c0: 72 65 73 20 5b 65 78 70 72 20 7b 5b 73 71 6c 69  res [expr {[sqli
f9d0: 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65  te3_enable_share
f9e0: 64 5f 63 61 63 68 65 5d 20 3d 3d 20 24 73 63 73  d_cache] == $scs
f9f0: 7d 5d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  }].    do_test $
fa00: 7b 74 61 69 6c 7d 2d 73 68 61 72 65 64 63 61 63  {tail}-sharedcac
fa10: 68 65 73 65 74 74 69 6e 67 20 5b 6c 69 73 74 20  hesetting [list 
fa20: 73 65 74 20 7b 7d 20 24 72 65 73 5d 20 31 0a 20  set {} $res] 1. 
fa30: 20 7d 0a 0a 20 20 23 20 41 64 64 20 73 6f 6d 65   }..  # Add some
fa40: 20 69 6e 66 6f 20 74 6f 20 74 68 65 20 6f 75 74   info to the out
fa50: 70 75 74 2e 0a 20 20 23 0a 20 20 6f 75 74 70 75  put..  #.  outpu
fa60: 74 32 20 22 54 69 6d 65 3a 20 24 74 61 69 6c 20  t2 "Time: $tail 
fa70: 24 6d 73 20 6d 73 22 0a 20 20 73 68 6f 77 5f 6d  $ms ms".  show_m
fa80: 65 6d 73 74 61 74 73 0a 7d 0a 0a 23 20 4f 70 65  emstats.}..# Ope
fa90: 6e 20 61 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69  n a new connecti
faa0: 6f 6e 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74  on on database t
fab0: 65 73 74 2e 64 62 20 61 6e 64 20 65 78 65 63 75  est.db and execu
fac0: 74 65 20 74 68 65 20 53 51 4c 20 73 63 72 69 70  te the SQL scrip
fad0: 74 0a 23 20 73 75 70 70 6c 69 65 64 20 61 73 20  t.# supplied as 
fae0: 61 6e 20 61 72 67 75 6d 65 6e 74 2e 20 42 65 66  an argument. Bef
faf0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c 20 63  ore returning, c
fb00: 6c 6f 73 65 20 74 68 65 20 6e 65 77 20 63 6f 6e  lose the new con
fb10: 65 63 74 69 6f 6e 20 61 6e 64 0a 23 20 72 65 73  ection and.# res
fb20: 74 6f 72 65 20 74 68 65 20 34 20 62 79 74 65 20  tore the 4 byte 
fb30: 66 69 65 6c 64 73 20 73 74 61 72 74 69 6e 67 20  fields starting 
fb40: 61 74 20 68 65 61 64 65 72 20 6f 66 66 73 65 74  at header offset
fb50: 73 20 32 38 2c 20 39 32 20 61 6e 64 20 39 36 0a  s 28, 92 and 96.
fb60: 23 20 74 6f 20 74 68 65 20 76 61 6c 75 65 73 20  # to the values 
fb70: 74 68 65 79 20 68 65 6c 64 20 62 65 66 6f 72 65  they held before
fb80: 20 74 68 65 20 53 51 4c 20 77 61 73 20 65 78 65   the SQL was exe
fb90: 63 75 74 65 64 2e 20 54 68 69 73 20 73 69 6d 75  cuted. This simu
fba0: 6c 61 74 65 73 0a 23 20 61 20 77 72 69 74 65 20  lates.# a write 
fbb0: 62 79 20 61 20 70 72 65 2d 33 2e 37 2e 30 20 63  by a pre-3.7.0 c
fbc0: 6c 69 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 71  lient..#.proc sq
fbd0: 6c 33 36 32 33 31 20 7b 73 71 6c 7d 20 7b 0a 20  l36231 {sql} {. 
fbe0: 20 73 65 74 20 42 20 5b 68 65 78 69 6f 5f 72 65   set B [hexio_re
fbf0: 61 64 20 74 65 73 74 2e 64 62 20 39 32 20 38 5d  ad test.db 92 8]
fc00: 0a 20 20 73 65 74 20 41 20 5b 68 65 78 69 6f 5f  .  set A [hexio_
fc10: 72 65 61 64 20 74 65 73 74 2e 64 62 20 32 38 20  read test.db 28 
fc20: 34 5d 0a 20 20 73 71 6c 69 74 65 33 20 64 62 33  4].  sqlite3 db3
fc30: 36 32 33 31 20 74 65 73 74 2e 64 62 0a 20 20 63  6231 test.db.  c
fc40: 61 74 63 68 20 7b 20 64 62 33 36 32 33 31 20 66  atch { db36231 f
fc50: 75 6e 63 20 61 5f 73 74 72 69 6e 67 20 61 5f 73  unc a_string a_s
fc60: 74 72 69 6e 67 20 7d 0a 20 20 65 78 65 63 73 71  tring }.  execsq
fc70: 6c 20 24 73 71 6c 20 64 62 33 36 32 33 31 0a 20  l $sql db36231. 
fc80: 20 64 62 33 36 32 33 31 20 63 6c 6f 73 65 0a 20   db36231 close. 
fc90: 20 68 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73   hexio_write tes
fca0: 74 2e 64 62 20 32 38 20 24 41 0a 20 20 68 65 78  t.db 28 $A.  hex
fcb0: 69 6f 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62  io_write test.db
fcc0: 20 39 32 20 24 42 0a 20 20 72 65 74 75 72 6e 20   92 $B.  return 
fcd0: 22 22 0a 7d 0a 0a 70 72 6f 63 20 64 62 5f 73 61  "".}..proc db_sa
fce0: 76 65 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63  ve {} {.  foreac
fcf0: 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
fd00: 70 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62  plain sv_test.db
fd10: 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65  *] { forcedelete
fd20: 20 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68 20   $f }.  foreach 
fd30: 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
fd40: 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b 0a  ain test.db*] {.
fd50: 20 20 20 20 73 65 74 20 66 32 20 22 73 76 5f 24      set f2 "sv_$
fd60: 66 22 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79  f".    forcecopy
fd70: 20 24 66 20 24 66 32 0a 20 20 7d 0a 7d 0a 70 72   $f $f2.  }.}.pr
fd80: 6f 63 20 64 62 5f 73 61 76 65 5f 61 6e 64 5f 63  oc db_save_and_c
fd90: 6c 6f 73 65 20 7b 7d 20 7b 0a 20 20 64 62 5f 73  lose {} {.  db_s
fda0: 61 76 65 0a 20 20 63 61 74 63 68 20 7b 20 64 62  ave.  catch { db
fdb0: 20 63 6c 6f 73 65 20 7d 0a 20 20 72 65 74 75 72   close }.  retur
fdc0: 6e 20 22 22 0a 7d 0a 70 72 6f 63 20 64 62 5f 72  n "".}.proc db_r
fdd0: 65 73 74 6f 72 65 20 7b 7d 20 7b 0a 20 20 66 6f  estore {} {.  fo
fde0: 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e  reach f [glob -n
fdf0: 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64  ocomplain test.d
fe00: 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74  b*] { forcedelet
fe10: 65 20 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68  e $f }.  foreach
fe20: 20 66 32 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d   f2 [glob -nocom
fe30: 70 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62  plain sv_test.db
fe40: 2a 5d 20 7b 0a 20 20 20 20 73 65 74 20 66 20 5b  *] {.    set f [
fe50: 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 66 32  string range $f2
fe60: 20 33 20 65 6e 64 5d 0a 20 20 20 20 66 6f 72 63   3 end].    forc
fe70: 65 63 6f 70 79 20 24 66 32 20 24 66 0a 20 20 7d  ecopy $f2 $f.  }
fe80: 0a 7d 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f  .}.proc db_resto
fe90: 72 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20 7b 7b  re_and_reopen {{
fea0: 64 62 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d  dbfile test.db}}
feb0: 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20   {.  catch { db 
fec0: 63 6c 6f 73 65 20 7d 0a 20 20 64 62 5f 72 65 73  close }.  db_res
fed0: 74 6f 72 65 0a 20 20 73 71 6c 69 74 65 33 20 64  tore.  sqlite3 d
fee0: 62 20 24 64 62 66 69 6c 65 0a 7d 0a 70 72 6f 63  b $dbfile.}.proc
fef0: 20 64 62 5f 64 65 6c 65 74 65 5f 61 6e 64 5f 72   db_delete_and_r
ff00: 65 6f 70 65 6e 20 7b 7b 66 69 6c 65 20 74 65 73  eopen {{file tes
ff10: 74 2e 64 62 7d 7d 20 7b 0a 20 20 63 61 74 63 68  t.db}} {.  catch
ff20: 20 7b 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20   { db close }.  
ff30: 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20  foreach f [glob 
ff40: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74  -nocomplain test
ff50: 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c  .db*] { forcedel
ff60: 65 74 65 20 24 66 20 7d 0a 20 20 73 71 6c 69 74  ete $f }.  sqlit
ff70: 65 33 20 64 62 20 24 66 69 6c 65 0a 7d 0a 0a 23  e3 db $file.}..#
ff80: 20 43 6c 6f 73 65 20 61 6e 79 20 63 6f 6e 6e 65   Close any conne
ff90: 63 74 69 6f 6e 73 20 6e 61 6d 65 64 20 5b 64 62  ctions named [db
ffa0: 5d 2c 20 5b 64 62 32 5d 20 6f 72 20 5b 64 62 33  ], [db2] or [db3
ffb0: 5d 2e 20 54 68 65 6e 20 75 73 65 20 73 71 6c 69  ]. Then use sqli
ffc0: 74 65 33 5f 63 6f 6e 66 69 67 0a 23 20 74 6f 20  te3_config.# to 
ffd0: 63 6f 6e 66 69 67 75 72 65 20 74 68 65 20 73 69  configure the si
ffe0: 7a 65 20 6f 66 20 74 68 65 20 50 41 47 45 43 41  ze of the PAGECA
fff0: 43 48 45 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 75  CHE allocation u
10000 73 69 6e 67 20 74 68 65 20 70 61 72 61 6d 65 74  sing the paramet
10010 65 72 73 0a 23 20 70 72 6f 76 69 64 65 64 20 74  ers.# provided t
10020 6f 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 2e 20  o this command. 
10030 53 61 76 65 20 74 68 65 20 6f 6c 64 20 50 41 47  Save the old PAG
10040 45 43 41 43 48 45 20 70 61 72 61 6d 65 74 65 72  ECACHE parameter
10050 73 20 69 6e 20 61 20 67 6c 6f 62 61 6c 20 0a 23  s in a global .#
10060 20 76 61 72 69 61 62 6c 65 20 73 6f 20 74 68 61   variable so tha
10070 74 20 5b 74 65 73 74 5f 72 65 73 74 6f 72 65 5f  t [test_restore_
10080 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65  config_pagecache
10090 5d 20 63 61 6e 20 72 65 73 74 6f 72 65 20 74 68  ] can restore th
100a0 65 20 70 72 65 76 69 6f 75 73 0a 23 20 63 6f 6e  e previous.# con
100b0 66 69 67 75 72 61 74 69 6f 6e 2e 0a 23 0a 23 20  figuration..#.# 
100c0 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  Before returning
100d0 2c 20 72 65 6f 70 65 6e 20 63 6f 6e 6e 65 63 74  , reopen connect
100e0 69 6f 6e 20 5b 64 62 5d 20 6f 6e 20 66 69 6c 65  ion [db] on file
100f0 20 74 65 73 74 2e 64 62 2e 0a 23 0a 70 72 6f 63   test.db..#.proc
10100 20 74 65 73 74 5f 73 65 74 5f 63 6f 6e 66 69 67   test_set_config
10110 5f 70 61 67 65 63 61 63 68 65 20 7b 73 7a 20 6e  _pagecache {sz n
10120 50 67 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64  Pg} {.  catch {d
10130 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
10140 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
10150 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d  atch {db3 close}
10160 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  ..  sqlite3_shut
10170 64 6f 77 6e 0a 20 20 73 65 74 20 3a 3a 6f 6c 64  down.  set ::old
10180 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69  _pagecache_confi
10190 67 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  g [sqlite3_confi
101a0 67 5f 70 61 67 65 63 61 63 68 65 20 24 73 7a 20  g_pagecache $sz 
101b0 24 6e 50 67 5d 0a 20 20 73 71 6c 69 74 65 33 5f  $nPg].  sqlite3_
101c0 69 6e 69 74 69 61 6c 69 7a 65 0a 20 20 61 75 74  initialize.  aut
101d0 6f 69 6e 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75  oinstall_test_fu
101e0 6e 63 74 69 6f 6e 73 0a 20 20 72 65 73 65 74 5f  nctions.  reset_
101f0 64 62 0a 7d 0a 0a 23 20 43 6c 6f 73 65 20 61 6e  db.}..# Close an
10200 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 6e 61  y connections na
10210 6d 65 64 20 5b 64 62 5d 2c 20 5b 64 62 32 5d 20  med [db], [db2] 
10220 6f 72 20 5b 64 62 33 5d 2e 20 54 68 65 6e 20 75  or [db3]. Then u
10230 73 65 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  se sqlite3_confi
10240 67 0a 23 20 74 6f 20 63 6f 6e 66 69 67 75 72 65  g.# to configure
10250 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
10260 20 50 41 47 45 43 41 43 48 45 20 61 6c 6c 6f 63   PAGECACHE alloc
10270 61 74 69 6f 6e 20 74 6f 20 74 68 65 20 73 69 7a  ation to the siz
10280 65 20 73 61 76 65 64 20 69 6e 0a 23 20 74 68 65  e saved in.# the
10290 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
102a0 20 62 79 20 61 6e 20 65 61 72 6c 69 65 72 20 63   by an earlier c
102b0 61 6c 6c 20 74 6f 20 5b 74 65 73 74 5f 73 65 74  all to [test_set
102c0 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68  _config_pagecach
102d0 65 5d 2e 0a 23 0a 23 20 42 65 66 6f 72 65 20 72  e]..#.# Before r
102e0 65 74 75 72 6e 69 6e 67 2c 20 72 65 6f 70 65 6e  eturning, reopen
102f0 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64 62 5d   connection [db]
10300 20 6f 6e 20 66 69 6c 65 20 74 65 73 74 2e 64 62   on file test.db
10310 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 72 65  ..#.proc test_re
10320 73 74 6f 72 65 5f 63 6f 6e 66 69 67 5f 70 61 67  store_config_pag
10330 65 63 61 63 68 65 20 7b 7d 20 7b 0a 20 20 63 61  ecache {} {.  ca
10340 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
10350 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
10360 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20  e}.  catch {db3 
10370 63 6c 6f 73 65 7d 0a 0a 20 20 73 71 6c 69 74 65  close}..  sqlite
10380 33 5f 73 68 75 74 64 6f 77 6e 0a 20 20 65 76 61  3_shutdown.  eva
10390 6c 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  l sqlite3_config
103a0 5f 70 61 67 65 63 61 63 68 65 20 24 3a 3a 6f 6c  _pagecache $::ol
103b0 64 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66  d_pagecache_conf
103c0 69 67 0a 20 20 75 6e 73 65 74 20 3a 3a 6f 6c 64  ig.  unset ::old
103d0 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69  _pagecache_confi
103e0 67 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69  g .  sqlite3_ini
103f0 74 69 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e  tialize.  autoin
10400 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74  stall_test_funct
10410 69 6f 6e 73 0a 20 20 73 71 6c 69 74 65 33 20 64  ions.  sqlite3 d
10420 62 20 74 65 73 74 2e 64 62 0a 7d 0a 0a 70 72 6f  b test.db.}..pro
10430 63 20 74 65 73 74 5f 66 69 6e 64 5f 62 69 6e 61  c test_find_bina
10440 72 79 20 7b 6e 6d 7d 20 7b 0a 20 20 69 66 20 7b  ry {nm} {.  if {
10450 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
10460 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 77 69 6e 64  platform)=="wind
10470 6f 77 73 22 7d 20 7b 0a 20 20 20 20 73 65 74 20  ows"} {.    set 
10480 72 65 74 20 22 24 6e 6d 2e 65 78 65 22 0a 20 20  ret "$nm.exe".  
10490 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
104a0 20 72 65 74 20 24 6e 6d 0a 20 20 7d 0a 20 20 73   ret $nm.  }.  s
104b0 65 74 20 72 65 74 20 5b 66 69 6c 65 20 6e 6f 72  et ret [file nor
104c0 6d 61 6c 69 7a 65 20 5b 66 69 6c 65 20 6a 6f 69  malize [file joi
104d0 6e 20 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28  n $::cmdlinearg(
104e0 54 45 53 54 46 49 58 54 55 52 45 5f 48 4f 4d 45  TESTFIXTURE_HOME
104f0 29 20 24 72 65 74 5d 5d 0a 20 20 69 66 20 7b 21  ) $ret]].  if {!
10500 5b 66 69 6c 65 20 65 78 65 63 75 74 61 62 6c 65  [file executable
10510 20 24 72 65 74 5d 7d 20 7b 0a 20 20 20 20 66 69   $ret]} {.    fi
10520 6e 69 73 68 5f 74 65 73 74 0a 20 20 20 20 72 65  nish_test.    re
10530 74 75 72 6e 20 22 22 0a 20 20 7d 0a 20 20 72 65  turn "".  }.  re
10540 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23 20 46  turn $ret.}..# F
10550 69 6e 64 20 74 68 65 20 6e 61 6d 65 20 6f 66 20  ind the name of 
10560 74 68 65 20 27 73 68 65 6c 6c 27 20 65 78 65 63  the 'shell' exec
10570 75 74 61 62 6c 65 20 28 65 2e 67 2e 20 22 73 71  utable (e.g. "sq
10580 6c 69 74 65 33 2e 65 78 65 22 29 20 74 6f 20 75  lite3.exe") to u
10590 73 65 20 66 6f 72 0a 23 20 74 68 65 20 74 65 73  se for.# the tes
105a0 74 73 20 69 6e 20 73 68 65 6c 6c 5b 31 2d 35 5d  ts in shell[1-5]
105b0 2e 74 65 73 74 2e 20 49 66 20 6e 6f 20 73 75 63  .test. If no suc
105c0 68 20 65 78 65 63 75 74 61 62 6c 65 20 63 61 6e  h executable can
105d0 20 62 65 20 66 6f 75 6e 64 2c 20 69 6e 76 6f 6b   be found, invok
105e0 65 0a 23 20 5b 66 69 6e 69 73 68 5f 74 65 73 74  e.# [finish_test
105f0 20 3b 20 72 65 74 75 72 6e 5d 20 69 6e 20 74 68   ; return] in th
10600 65 20 63 61 6c 6c 65 72 73 20 63 6f 6e 74 65 78  e callers contex
10610 74 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 66  t..#.proc test_f
10620 69 6e 64 5f 63 6c 69 20 7b 7d 20 7b 0a 20 20 73  ind_cli {} {.  s
10630 65 74 20 70 72 6f 67 20 5b 74 65 73 74 5f 66 69  et prog [test_fi
10640 6e 64 5f 62 69 6e 61 72 79 20 73 71 6c 69 74 65  nd_binary sqlite
10650 33 5d 0a 20 20 69 66 20 7b 24 70 72 6f 67 3d 3d  3].  if {$prog==
10660 22 22 7d 20 7b 20 72 65 74 75 72 6e 20 2d 63 6f  ""} { return -co
10670 64 65 20 72 65 74 75 72 6e 20 7d 0a 20 20 72 65  de return }.  re
10680 74 75 72 6e 20 24 70 72 6f 67 0a 7d 0a 0a 23 20  turn $prog.}..# 
10690 46 69 6e 64 20 74 68 65 20 6e 61 6d 65 20 6f 66  Find the name of
106a0 20 74 68 65 20 27 73 71 6c 64 69 66 66 27 20 65   the 'sqldiff' e
106b0 78 65 63 75 74 61 62 6c 65 20 28 65 2e 67 2e 20  xecutable (e.g. 
106c0 22 73 71 6c 69 74 65 33 2e 65 78 65 22 29 20 74  "sqlite3.exe") t
106d0 6f 20 75 73 65 20 66 6f 72 0a 23 20 74 68 65 20  o use for.# the 
106e0 74 65 73 74 73 20 69 6e 20 73 71 6c 64 69 66 66  tests in sqldiff
106f0 20 74 65 73 74 73 2e 20 49 66 20 6e 6f 20 73 75   tests. If no su
10700 63 68 20 65 78 65 63 75 74 61 62 6c 65 20 63 61  ch executable ca
10710 6e 20 62 65 20 66 6f 75 6e 64 2c 20 69 6e 76 6f  n be found, invo
10720 6b 65 0a 23 20 5b 66 69 6e 69 73 68 5f 74 65 73  ke.# [finish_tes
10730 74 20 3b 20 72 65 74 75 72 6e 5d 20 69 6e 20 74  t ; return] in t
10740 68 65 20 63 61 6c 6c 65 72 73 20 63 6f 6e 74 65  he callers conte
10750 78 74 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f  xt..#.proc test_
10760 66 69 6e 64 5f 73 71 6c 64 69 66 66 20 7b 7d 20  find_sqldiff {} 
10770 7b 0a 20 20 73 65 74 20 70 72 6f 67 20 5b 74 65  {.  set prog [te
10780 73 74 5f 66 69 6e 64 5f 62 69 6e 61 72 79 20 73  st_find_binary s
10790 71 6c 64 69 66 66 5d 0a 20 20 69 66 20 7b 24 70  qldiff].  if {$p
107a0 72 6f 67 3d 3d 22 22 7d 20 7b 20 72 65 74 75 72  rog==""} { retur
107b0 6e 20 2d 63 6f 64 65 20 72 65 74 75 72 6e 20 7d  n -code return }
107c0 0a 20 20 72 65 74 75 72 6e 20 24 70 72 6f 67 0a  .  return $prog.
107d0 7d 0a 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62  }...# If the lib
107e0 72 61 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64  rary is compiled
107f0 20 77 69 74 68 20 74 68 65 20 53 51 4c 49 54 45   with the SQLITE
10800 5f 44 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43  _DEFAULT_AUTOVAC
10810 55 55 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20  UUM macro set.# 
10820 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65  to non-zero, the
10830 6e 20 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c  n set the global
10840 20 76 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56   variable $AUTOV
10850 41 43 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20  ACUUM to 1..set 
10860 41 55 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69  AUTOVACUUM $sqli
10870 74 65 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75  te_options(defau
10880 6c 74 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a  lt_autovacuum)..
10890 23 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20  # Make sure the 
108a0 46 54 53 20 65 6e 68 61 6e 63 65 64 20 71 75 65  FTS enhanced que
108b0 72 79 20 73 79 6e 74 61 78 20 69 73 20 64 69 73  ry syntax is dis
108c0 61 62 6c 65 64 2e 0a 73 65 74 20 73 71 6c 69 74  abled..set sqlit
108d0 65 5f 66 74 73 33 5f 65 6e 61 62 6c 65 5f 70 61  e_fts3_enable_pa
108e0 72 65 6e 74 68 65 73 65 73 20 30 0a 0a 23 20 44  rentheses 0..# D
108f0 75 72 69 6e 67 20 74 65 73 74 69 6e 67 2c 20 61  uring testing, a
10900 73 73 75 6d 65 20 74 68 61 74 20 61 6c 6c 20 64  ssume that all d
10910 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 61 72  atabase files ar
10920 65 20 77 65 6c 6c 2d 66 6f 72 6d 65 64 2e 20 20  e well-formed.  
10930 54 68 65 0a 23 20 66 65 77 20 74 65 73 74 20 63  The.# few test c
10940 61 73 65 73 20 74 68 61 74 20 64 65 6c 69 62 65  ases that delibe
10950 72 61 74 65 6c 79 20 63 6f 72 72 75 70 74 20 64  rately corrupt d
10960 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 73 68  atabase files sh
10970 6f 75 6c 64 20 72 65 73 63 69 6e 64 20 0a 23 20  ould rescind .# 
10980 74 68 69 73 20 73 65 74 74 69 6e 67 20 62 79 20  this setting by 
10990 69 6e 76 6f 6b 69 6e 67 20 22 64 61 74 61 62 61  invoking "databa
109a0 73 65 5f 63 61 6e 5f 62 65 5f 63 6f 72 72 75 70  se_can_be_corrup
109b0 74 22 0a 23 0a 64 61 74 61 62 61 73 65 5f 6e 65  t".#.database_ne
109c0 76 65 72 5f 63 6f 72 72 75 70 74 0a 0a 73 6f 75  ver_corrupt..sou
109d0 72 63 65 20 24 74 65 73 74 64 69 72 2f 74 68 72  rce $testdir/thr
109e0 65 61 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73  ead_common.tcl.s
109f0 6f 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d  ource $testdir/m
10a00 61 6c 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c  alloc_common.tcl
10a10 0a                                               .