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

Artifact 63fca9a766cd84060e137e81419ea5ae384960e3354281ce8e4983e203d53736:


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 70 72 6f 63 20 66 6f  -limit)..proc fo
4570: 72 63 65 64 5f 70 72 6f 78 79 5f 6c 6f 63 6b 69  rced_proxy_locki
4580: 6e 67 20 7b 7d 20 7b 0a 20 20 69 66 20 24 3a 3a  ng {} {.  if $::
4590: 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 6c  sqlite_options(l
45a0: 6f 63 6b 5f 70 72 6f 78 79 5f 70 72 61 67 6d 61  ock_proxy_pragma
45b0: 73 29 26 26 24 3a 3a 73 71 6c 69 74 65 5f 6f 70  s)&&$::sqlite_op
45c0: 74 69 6f 6e 73 28 70 72 65 66 65 72 5f 70 72 6f  tions(prefer_pro
45d0: 78 79 5f 6c 6f 63 6b 69 6e 67 29 20 7b 0a 20 20  xy_locking) {.  
45e0: 20 20 73 65 74 20 66 6f 72 63 65 5f 70 72 6f 78    set force_prox
45f0: 79 5f 76 61 6c 75 65 20 30 0a 20 20 20 20 73 65  y_value 0.    se
4600: 74 20 66 6f 72 63 65 5f 6b 65 79 20 22 53 51 4c  t force_key "SQL
4610: 49 54 45 5f 46 4f 52 43 45 5f 50 52 4f 58 59 5f  ITE_FORCE_PROXY_
4620: 4c 4f 43 4b 49 4e 47 3d 22 0a 20 20 20 20 66 6f  LOCKING=".    fo
4630: 72 65 61 63 68 20 7b 65 6e 76 5f 70 61 69 72 7d  reach {env_pair}
4640: 20 5b 65 78 65 63 20 65 6e 76 5d 20 7b 20 0a 20   [exec env] { . 
4650: 20 20 20 20 20 69 66 20 7b 20 5b 73 74 72 69 6e       if { [strin
4660: 67 20 66 69 72 73 74 20 24 66 6f 72 63 65 5f 6b  g first $force_k
4670: 65 79 20 24 65 6e 76 5f 70 61 69 72 5d 20 3d 3d  ey $env_pair] ==
4680: 20 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65   0} {.        se
4690: 74 20 66 6f 72 63 65 5f 70 72 6f 78 79 5f 76 61  t force_proxy_va
46a0: 6c 75 65 20 5b 73 74 72 69 6e 67 20 72 61 6e 67  lue [string rang
46b0: 65 20 24 65 6e 76 5f 70 61 69 72 20 5b 73 74 72  e $env_pair [str
46c0: 69 6e 67 20 6c 65 6e 67 74 68 20 24 66 6f 72 63  ing length $forc
46d0: 65 5f 6b 65 79 5d 20 65 6e 64 5d 0a 20 20 20 20  e_key] end].    
46e0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
46f0: 20 7b 20 22 24 66 6f 72 63 65 5f 70 72 6f 78 79   { "$force_proxy
4700: 5f 76 61 6c 75 65 20 22 20 3d 3d 20 22 31 20 22  _value " == "1 "
4710: 20 7d 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72   } {.      retur
4720: 6e 20 31 0a 20 20 20 20 7d 20 0a 20 20 7d 0a 20  n 1.    } .  }. 
4730: 20 72 65 74 75 72 6e 20 30 0a 7d 0a 0a 0a 23 20   return 0.}...# 
4740: 43 72 65 61 74 65 20 61 20 74 65 73 74 20 64 61  Create a test da
4750: 74 61 62 61 73 65 0a 23 0a 70 72 6f 63 20 72 65  tabase.#.proc re
4760: 73 65 74 5f 64 62 20 7b 7d 20 7b 0a 20 20 63 61  set_db {} {.  ca
4770: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
4780: 20 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73   forcedelete tes
4790: 74 2e 64 62 0a 20 20 66 6f 72 63 65 64 65 6c 65  t.db.  forcedele
47a0: 74 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e  te test.db-journ
47b0: 61 6c 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65  al.  forcedelete
47c0: 20 74 65 73 74 2e 64 62 2d 77 61 6c 0a 20 20 69   test.db-wal.  i
47d0: 66 20 7b 5b 66 6f 72 63 65 64 5f 70 72 6f 78 79  f {[forced_proxy
47e0: 5f 6c 6f 63 6b 69 6e 67 5d 7d 20 7b 0a 20 20 20  _locking]} {.   
47f0: 20 73 71 6c 69 74 65 33 20 64 62 20 2e 2f 74 65   sqlite3 db ./te
4800: 73 74 2e 64 62 0a 20 20 20 20 73 65 74 20 6c 6f  st.db.    set lo
4810: 63 6b 5f 70 72 6f 78 79 5f 70 61 74 68 20 5b 64  ck_proxy_path [d
4820: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6c  b eval "PRAGMA l
4830: 6f 63 6b 5f 70 72 6f 78 79 5f 66 69 6c 65 3b 22  ock_proxy_file;"
4840: 5d 20 0a 20 20 20 20 63 61 74 63 68 20 7b 64 62  ] .    catch {db
4850: 20 63 6c 6f 73 65 7d 0a 20 20 20 20 23 20 70 75   close}.    # pu
4860: 74 73 20 22 64 65 6c 65 74 69 6e 67 20 24 6c 6f  ts "deleting $lo
4870: 63 6b 5f 70 72 6f 78 79 5f 70 61 74 68 22 0a 20  ck_proxy_path". 
4880: 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d     file delete -
4890: 66 6f 72 63 65 20 24 6c 6f 63 6b 5f 70 72 6f 78  force $lock_prox
48a0: 79 5f 70 61 74 68 20 20 20 20 0a 20 20 20 20 66  y_path    .    f
48b0: 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63  ile delete -forc
48c0: 65 20 74 65 73 74 2e 64 62 0a 20 20 7d 0a 20 20  e test.db.  }.  
48d0: 73 71 6c 69 74 65 33 20 64 62 20 2e 2f 74 65 73  sqlite3 db ./tes
48e0: 74 2e 64 62 0a 20 20 73 65 74 20 3a 3a 44 42 20  t.db.  set ::DB 
48f0: 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74  [sqlite3_connect
4900: 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a  ion_pointer db].
4910: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
4920: 74 73 20 3a 3a 53 45 54 55 50 5f 53 51 4c 5d 7d  ts ::SETUP_SQL]}
4930: 20 7b 0a 20 20 20 20 64 62 20 65 76 61 6c 20 24   {.    db eval $
4940: 3a 3a 53 45 54 55 50 5f 53 51 4c 0a 20 20 7d 0a  ::SETUP_SQL.  }.
4950: 7d 0a 72 65 73 65 74 5f 64 62 0a 0a 23 20 41 62  }.reset_db..# Ab
4960: 6f 72 74 20 65 61 72 6c 79 20 69 66 20 74 68 69  ort early if thi
4970: 73 20 73 63 72 69 70 74 20 68 61 73 20 62 65 65  s script has bee
4980: 6e 20 72 75 6e 20 62 65 66 6f 72 65 2e 0a 23 0a  n run before..#.
4990: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
49a0: 20 54 43 28 63 6f 75 6e 74 29 5d 7d 20 72 65 74   TC(count)]} ret
49b0: 75 72 6e 0a 0a 23 20 4d 61 6b 65 20 73 75 72 65  urn..# Make sure
49c0: 20 6d 65 6d 6f 72 79 20 73 74 61 74 69 73 74 69   memory statisti
49d0: 63 73 20 61 72 65 20 65 6e 61 62 6c 65 64 2e 0a  cs are enabled..
49e0: 23 0a 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  #.sqlite3_config
49f0: 5f 6d 65 6d 73 74 61 74 75 73 20 31 0a 0a 23 20  _memstatus 1..# 
4a00: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74  Initialize the t
4a10: 65 73 74 20 63 6f 75 6e 74 65 72 73 20 61 6e 64  est counters and
4a20: 20 73 65 74 20 75 70 20 63 6f 6d 6d 61 6e 64 73   set up commands
4a30: 20 74 6f 20 61 63 63 65 73 73 20 74 68 65 6d 2e   to access them.
4a40: 0a 23 20 4f 72 2c 20 69 66 20 74 68 69 73 20 69  .# Or, if this i
4a50: 73 20 61 20 73 6c 61 76 65 20 69 6e 74 65 72 70  s a slave interp
4a60: 72 65 74 65 72 2c 20 73 65 74 20 75 70 20 61 6c  reter, set up al
4a70: 69 61 73 65 73 20 74 6f 20 77 72 69 74 65 20 74  iases to write t
4a80: 68 65 0a 23 20 63 6f 75 6e 74 65 72 73 20 69 6e  he.# counters in
4a90: 20 74 68 65 20 70 61 72 65 6e 74 20 69 6e 74 65   the parent inte
4aa0: 72 70 72 65 74 65 72 2e 0a 23 0a 69 66 20 7b 30  rpreter..#.if {0
4ab0: 3d 3d 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a  ==[info exists :
4ac0: 3a 53 4c 41 56 45 5d 7d 20 7b 0a 20 20 73 65 74  :SLAVE]} {.  set
4ad0: 20 54 43 28 65 72 72 6f 72 73 29 20 20 20 20 30   TC(errors)    0
4ae0: 0a 20 20 73 65 74 20 54 43 28 63 6f 75 6e 74 29  .  set TC(count)
4af0: 20 20 20 20 20 30 0a 20 20 73 65 74 20 54 43 28       0.  set TC(
4b00: 66 61 69 6c 5f 6c 69 73 74 29 20 5b 6c 69 73 74  fail_list) [list
4b10: 5d 0a 20 20 73 65 74 20 54 43 28 6f 6d 69 74 5f  ].  set TC(omit_
4b20: 6c 69 73 74 29 20 5b 6c 69 73 74 5d 0a 20 20 73  list) [list].  s
4b30: 65 74 20 54 43 28 77 61 72 6e 5f 6c 69 73 74 29  et TC(warn_list)
4b40: 20 5b 6c 69 73 74 5d 0a 0a 20 20 70 72 6f 63 20   [list]..  proc 
4b50: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
4b60: 20 7b 63 6f 75 6e 74 65 72 20 61 72 67 73 7d 20   {counter args} 
4b70: 7b 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  {.    if {[lleng
4b80: 74 68 20 24 61 72 67 73 5d 7d 20 7b 0a 20 20 20  th $args]} {.   
4b90: 20 20 20 73 65 74 20 3a 3a 54 43 28 24 63 6f 75     set ::TC($cou
4ba0: 6e 74 65 72 29 20 5b 6c 69 6e 64 65 78 20 24 61  nter) [lindex $a
4bb0: 72 67 73 20 30 5d 0a 20 20 20 20 7d 0a 20 20 20  rgs 0].    }.   
4bc0: 20 73 65 74 20 3a 3a 54 43 28 24 63 6f 75 6e 74   set ::TC($count
4bd0: 65 72 29 0a 20 20 7d 0a 7d 0a 0a 23 20 52 65 63  er).  }.}..# Rec
4be0: 6f 72 64 20 74 68 65 20 66 61 63 74 20 74 68 61  ord the fact tha
4bf0: 74 20 61 20 73 65 71 75 65 6e 63 65 20 6f 66 20  t a sequence of 
4c00: 74 65 73 74 73 20 77 65 72 65 20 6f 6d 69 74 74  tests were omitt
4c10: 65 64 2e 0a 23 0a 70 72 6f 63 20 6f 6d 69 74 5f  ed..#.proc omit_
4c20: 74 65 73 74 20 7b 6e 61 6d 65 20 72 65 61 73 6f  test {name reaso
4c30: 6e 20 7b 61 70 70 65 6e 64 20 31 7d 7d 20 7b 0a  n {append 1}} {.
4c40: 20 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20 5b    set omitList [
4c50: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
4c60: 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 20 20 69 66   omit_list].  if
4c70: 20 7b 24 61 70 70 65 6e 64 7d 20 7b 0a 20 20 20   {$append} {.   
4c80: 20 6c 61 70 70 65 6e 64 20 6f 6d 69 74 4c 69 73   lappend omitLis
4c90: 74 20 5b 6c 69 73 74 20 24 6e 61 6d 65 20 24 72  t [list $name $r
4ca0: 65 61 73 6f 6e 5d 0a 20 20 7d 0a 20 20 73 65 74  eason].  }.  set
4cb0: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d  _test_counter om
4cc0: 69 74 5f 6c 69 73 74 20 24 6f 6d 69 74 4c 69 73  it_list $omitLis
4cd0: 74 0a 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74 68  t.}..# Record th
4ce0: 65 20 66 61 63 74 20 74 68 61 74 20 61 20 74 65  e fact that a te
4cf0: 73 74 20 66 61 69 6c 65 64 2e 0a 23 0a 70 72 6f  st failed..#.pro
4d00: 63 20 66 61 69 6c 5f 74 65 73 74 20 7b 6e 61 6d  c fail_test {nam
4d10: 65 7d 20 7b 0a 20 20 73 65 74 20 66 20 5b 73 65  e} {.  set f [se
4d20: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66  t_test_counter f
4d30: 61 69 6c 5f 6c 69 73 74 5d 0a 20 20 6c 61 70 70  ail_list].  lapp
4d40: 65 6e 64 20 66 20 24 6e 61 6d 65 0a 20 20 73 65  end f $name.  se
4d50: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66  t_test_counter f
4d60: 61 69 6c 5f 6c 69 73 74 20 24 66 0a 20 20 73 65  ail_list $f.  se
4d70: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 65  t_test_counter e
4d80: 72 72 6f 72 73 20 5b 65 78 70 72 20 5b 73 65 74  rrors [expr [set
4d90: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 65 72  _test_counter er
4da0: 72 6f 72 73 5d 20 2b 20 31 5d 0a 0a 20 20 73 65  rors] + 1]..  se
4db0: 74 20 6e 46 61 69 6c 20 5b 73 65 74 5f 74 65 73  t nFail [set_tes
4dc0: 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73  t_counter errors
4dd0: 5d 0a 20 20 69 66 20 7b 24 6e 46 61 69 6c 3e 3d  ].  if {$nFail>=
4de0: 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61  $::cmdlinearg(ma
4df0: 78 65 72 72 6f 72 29 7d 20 7b 0a 20 20 20 20 6f  xerror)} {.    o
4e00: 75 74 70 75 74 32 20 22 2a 2a 2a 20 47 69 76 69  utput2 "*** Givi
4e10: 6e 67 20 75 70 2e 2e 2e 22 0a 20 20 20 20 66 69  ng up...".    fi
4e20: 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 0a 20  nalize_testing. 
4e30: 20 7d 0a 7d 0a 0a 23 20 52 65 6d 65 6d 62 65 72   }.}..# Remember
4e40: 20 61 20 77 61 72 6e 69 6e 67 20 6d 65 73 73 61   a warning messa
4e50: 67 65 20 74 6f 20 62 65 20 64 69 73 70 6c 61 79  ge to be display
4e60: 65 64 20 61 74 20 74 68 65 20 63 6f 6e 63 6c 75  ed at the conclu
4e70: 73 69 6f 6e 20 6f 66 20 61 6c 6c 20 74 65 73 74  sion of all test
4e80: 69 6e 67 0a 23 0a 70 72 6f 63 20 77 61 72 6e 69  ing.#.proc warni
4e90: 6e 67 20 7b 6d 73 67 20 7b 61 70 70 65 6e 64 20  ng {msg {append 
4ea0: 31 7d 7d 20 7b 0a 20 20 6f 75 74 70 75 74 32 20  1}} {.  output2 
4eb0: 22 57 61 72 6e 69 6e 67 3a 20 24 6d 73 67 22 0a  "Warning: $msg".
4ec0: 20 20 73 65 74 20 77 61 72 6e 4c 69 73 74 20 5b    set warnList [
4ed0: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
4ee0: 20 77 61 72 6e 5f 6c 69 73 74 5d 0a 20 20 69 66   warn_list].  if
4ef0: 20 7b 24 61 70 70 65 6e 64 7d 20 7b 0a 20 20 20   {$append} {.   
4f00: 20 6c 61 70 70 65 6e 64 20 77 61 72 6e 4c 69 73   lappend warnLis
4f10: 74 20 24 6d 73 67 0a 20 20 7d 0a 20 20 73 65 74  t $msg.  }.  set
4f20: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 77 61  _test_counter wa
4f30: 72 6e 5f 6c 69 73 74 20 24 77 61 72 6e 4c 69 73  rn_list $warnLis
4f40: 74 0a 7d 0a 0a 0a 23 20 49 6e 63 72 65 6d 65 6e  t.}...# Incremen
4f50: 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  t the number of 
4f60: 74 65 73 74 73 20 72 75 6e 0a 23 0a 70 72 6f 63  tests run.#.proc
4f70: 20 69 6e 63 72 5f 6e 74 65 73 74 20 7b 7d 20 7b   incr_ntest {} {
4f80: 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  .  set_test_coun
4f90: 74 65 72 20 63 6f 75 6e 74 20 5b 65 78 70 72 20  ter count [expr 
4fa0: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
4fb0: 72 20 63 6f 75 6e 74 5d 20 2b 20 31 5d 0a 7d 0a  r count] + 1].}.
4fc0: 0a 23 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  .# Return true i
4fd0: 66 20 2d 2d 76 65 72 62 6f 73 65 3d 31 20 77 61  f --verbose=1 wa
4fe0: 73 20 73 70 65 63 69 66 69 65 64 20 6f 6e 20 74  s specified on t
4ff0: 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 2e  he command line.
5000: 20 4f 74 68 65 72 77 69 73 65 2c 0a 23 20 72 65   Otherwise,.# re
5010: 74 75 72 6e 20 66 61 6c 73 65 2e 0a 23 0a 70 72  turn false..#.pr
5020: 6f 63 20 76 65 72 62 6f 73 65 20 7b 7d 20 7b 0a  oc verbose {} {.
5030: 20 20 72 65 74 75 72 6e 20 24 3a 3a 63 6d 64 6c    return $::cmdl
5040: 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 0a  inearg(verbose).
5050: 7d 0a 0a 23 20 55 73 65 20 74 68 65 20 66 6f 6c  }..# Use the fol
5060: 6c 6f 77 69 6e 67 20 63 6f 6d 6d 61 6e 64 73 20  lowing commands 
5070: 69 6e 73 74 65 61 64 20 6f 66 20 5b 70 75 74 73  instead of [puts
5080: 5d 20 66 6f 72 20 74 65 73 74 20 6f 75 74 70 75  ] for test outpu
5090: 74 20 77 69 74 68 69 6e 0a 23 20 74 68 69 73 20  t within.# this 
50a0: 66 69 6c 65 2e 20 54 65 73 74 20 73 63 72 69 70  file. Test scrip
50b0: 74 73 20 63 61 6e 20 73 74 69 6c 6c 20 75 73 65  ts can still use
50c0: 20 72 65 67 75 6c 61 72 20 5b 70 75 74 73 5d 2c   regular [puts],
50d0: 20 77 68 69 63 68 20 69 73 20 64 69 72 65 63 74   which is direct
50e0: 65 64 0a 23 20 74 6f 20 73 74 64 6f 75 74 20 61  ed.# to stdout a
50f0: 6e 64 2c 20 69 66 20 6f 6e 65 20 69 73 20 6f 70  nd, if one is op
5100: 65 6e 2c 20 74 68 65 20 2d 2d 6f 75 74 70 75 74  en, the --output
5110: 20 66 69 6c 65 2e 0a 23 0a 23 20 6f 75 74 70 75   file..#.# outpu
5120: 74 31 3a 20 6f 75 74 70 75 74 20 74 68 61 74 20  t1: output that 
5130: 73 68 6f 75 6c 64 20 62 65 20 70 72 69 6e 74 65  should be printe
5140: 64 20 69 66 20 2d 2d 76 65 72 62 6f 73 65 3d 31  d if --verbose=1
5150: 20 77 61 73 20 73 70 65 63 69 66 69 65 64 2e 0a   was specified..
5160: 23 20 6f 75 74 70 75 74 32 3a 20 6f 75 74 70 75  # output2: outpu
5170: 74 20 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65  t that should be
5180: 20 70 72 69 6e 74 65 64 20 75 6e 63 6f 6e 64 69   printed uncondi
5190: 74 69 6f 6e 61 6c 6c 79 2e 0a 23 20 6f 75 74 70  tionally..# outp
51a0: 75 74 32 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f 73  ut2_if_no_verbos
51b0: 65 3a 20 6f 75 74 70 75 74 20 74 68 61 74 20 73  e: output that s
51c0: 68 6f 75 6c 64 20 62 65 20 70 72 69 6e 74 65 64  hould be printed
51d0: 20 6f 6e 6c 79 20 69 66 20 2d 2d 76 65 72 62 6f   only if --verbo
51e0: 73 65 3d 30 2e 0a 23 0a 70 72 6f 63 20 6f 75 74  se=0..#.proc out
51f0: 70 75 74 31 20 7b 61 72 67 73 7d 20 7b 0a 20 20  put1 {args} {.  
5200: 73 65 74 20 76 20 5b 76 65 72 62 6f 73 65 5d 0a  set v [verbose].
5210: 20 20 69 66 20 7b 24 76 3d 3d 31 7d 20 7b 0a 20    if {$v==1} {. 
5220: 20 20 20 75 70 6c 65 76 65 6c 20 6f 75 74 70 75     uplevel outpu
5230: 74 32 20 24 61 72 67 73 0a 20 20 7d 20 65 6c 73  t2 $args.  } els
5240: 65 69 66 20 7b 24 76 3d 3d 32 7d 20 7b 0a 20 20  eif {$v==2} {.  
5250: 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73 20 5b    uplevel puts [
5260: 6c 72 61 6e 67 65 20 24 61 72 67 73 20 30 20 65  lrange $args 0 e
5270: 6e 64 2d 31 5d 20 24 3a 3a 47 28 6f 75 74 70 75  nd-1] $::G(outpu
5280: 74 5f 66 64 29 20 5b 6c 72 61 6e 67 65 20 24 61  t_fd) [lrange $a
5290: 72 67 73 20 65 6e 64 20 65 6e 64 5d 0a 20 20 7d  rgs end end].  }
52a0: 0a 7d 0a 70 72 6f 63 20 6f 75 74 70 75 74 32 20  .}.proc output2 
52b0: 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 6e  {args} {.  set n
52c0: 41 72 67 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72  Arg [llength $ar
52d0: 67 73 5d 0a 20 20 75 70 6c 65 76 65 6c 20 70 75  gs].  uplevel pu
52e0: 74 73 20 24 61 72 67 73 0a 7d 0a 70 72 6f 63 20  ts $args.}.proc 
52f0: 6f 75 74 70 75 74 32 5f 69 66 5f 6e 6f 5f 76 65  output2_if_no_ve
5300: 72 62 6f 73 65 20 7b 61 72 67 73 7d 20 7b 0a 20  rbose {args} {. 
5310: 20 73 65 74 20 76 20 5b 76 65 72 62 6f 73 65 5d   set v [verbose]
5320: 0a 20 20 69 66 20 7b 24 76 3d 3d 30 7d 20 7b 0a  .  if {$v==0} {.
5330: 20 20 20 20 75 70 6c 65 76 65 6c 20 6f 75 74 70      uplevel outp
5340: 75 74 32 20 24 61 72 67 73 0a 20 20 7d 20 65 6c  ut2 $args.  } el
5350: 73 65 69 66 20 7b 24 76 3d 3d 32 7d 20 7b 0a 20  seif {$v==2} {. 
5360: 20 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73 20     uplevel puts 
5370: 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20 30 20  [lrange $args 0 
5380: 65 6e 64 2d 31 5d 20 73 74 64 6f 75 74 20 5b 6c  end-1] stdout [l
5390: 72 61 6e 67 65 20 24 61 72 67 73 20 65 6e 64 20  range $args end 
53a0: 65 6e 64 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 4f 76  end].  }.}..# Ov
53b0: 65 72 72 69 64 65 20 74 68 65 20 5b 70 75 74 73  erride the [puts
53c0: 5d 20 63 6f 6d 6d 61 6e 64 20 73 6f 20 74 68 61  ] command so tha
53d0: 74 20 69 66 20 6e 6f 20 63 68 61 6e 6e 65 6c 20  t if no channel 
53e0: 69 73 20 65 78 70 6c 69 63 69 74 6c 79 20 0a 23  is explicitly .#
53f0: 20 73 70 65 63 69 66 69 65 64 20 74 68 65 20 73   specified the s
5400: 74 72 69 6e 67 20 69 73 20 77 72 69 74 74 65 6e  tring is written
5410: 20 74 6f 20 62 6f 74 68 20 73 74 64 6f 75 74 20   to both stdout 
5420: 61 6e 64 20 74 6f 20 74 68 65 20 66 69 6c 65 20  and to the file 
5430: 0a 23 20 73 70 65 63 69 66 69 65 64 20 62 79 20  .# specified by 
5440: 22 2d 2d 6f 75 74 70 75 74 3d 22 2c 20 69 66 20  "--output=", if 
5450: 61 6e 79 2e 0a 23 0a 70 72 6f 63 20 70 75 74 73  any..#.proc puts
5460: 5f 6f 76 65 72 72 69 64 65 20 7b 61 72 67 73 7d  _override {args}
5470: 20 7b 0a 20 20 73 65 74 20 6e 41 72 67 20 5b 6c   {.  set nArg [l
5480: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 0a 20 20  length $args].  
5490: 69 66 20 7b 24 6e 41 72 67 3d 3d 31 20 7c 7c 20  if {$nArg==1 || 
54a0: 28 24 6e 41 72 67 3d 3d 32 20 26 26 20 5b 73 74  ($nArg==2 && [st
54b0: 72 69 6e 67 20 66 69 72 73 74 20 5b 6c 69 6e 64  ring first [lind
54c0: 65 78 20 24 61 72 67 73 20 30 5d 20 2d 6e 6f 6e  ex $args 0] -non
54d0: 65 77 6c 69 6e 65 5d 3d 3d 30 29 7d 20 7b 0a 20  ewline]==0)} {. 
54e0: 20 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73 5f     uplevel puts_
54f0: 6f 72 69 67 69 6e 61 6c 20 24 61 72 67 73 0a 20  original $args. 
5500: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
5510: 73 74 73 20 3a 3a 47 28 6f 75 74 70 75 74 5f 66  sts ::G(output_f
5520: 64 29 5d 7d 20 7b 0a 20 20 20 20 20 20 75 70 6c  d)]} {.      upl
5530: 65 76 65 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67  evel puts [lrang
5540: 65 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d  e $args 0 end-1]
5550: 20 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29   $::G(output_fd)
5560: 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20 65   [lrange $args e
5570: 6e 64 20 65 6e 64 5d 0a 20 20 20 20 7d 0a 20 20  nd end].    }.  
5580: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 23 20 41  } else {.    # A
5590: 20 63 68 61 6e 6e 65 6c 20 77 61 73 20 65 78 70   channel was exp
55a0: 6c 69 63 69 74 6c 79 20 73 70 65 63 69 66 69 65  licitly specifie
55b0: 64 2e 0a 20 20 20 20 75 70 6c 65 76 65 6c 20 70  d..    uplevel p
55c0: 75 74 73 5f 6f 72 69 67 69 6e 61 6c 20 24 61 72  uts_original $ar
55d0: 67 73 0a 20 20 7d 0a 7d 0a 72 65 6e 61 6d 65 20  gs.  }.}.rename 
55e0: 70 75 74 73 20 70 75 74 73 5f 6f 72 69 67 69 6e  puts puts_origin
55f0: 61 6c 0a 70 72 6f 63 20 70 75 74 73 20 7b 61 72  al.proc puts {ar
5600: 67 73 7d 20 7b 20 75 70 6c 65 76 65 6c 20 70 75  gs} { uplevel pu
5610: 74 73 5f 6f 76 65 72 72 69 64 65 20 24 61 72 67  ts_override $arg
5620: 73 20 7d 0a 0a 0a 23 20 49 6e 76 6f 6b 65 20 74  s }...# Invoke t
5630: 68 65 20 64 6f 5f 74 65 73 74 20 70 72 6f 63 65  he do_test proce
5640: 64 75 72 65 20 74 6f 20 72 75 6e 20 61 20 73 69  dure to run a si
5650: 6e 67 6c 65 20 74 65 73 74 0a 23 0a 23 20 54 68  ngle test.#.# Th
5660: 65 20 24 65 78 70 65 63 74 65 64 20 70 61 72 61  e $expected para
5670: 6d 65 74 65 72 20 69 73 20 74 68 65 20 65 78 70  meter is the exp
5680: 65 63 74 65 64 20 72 65 73 75 6c 74 2e 20 20 54  ected result.  T
5690: 68 65 20 72 65 73 75 6c 74 20 69 73 20 74 68 65  he result is the
56a0: 20 72 65 74 75 72 6e 0a 23 20 76 61 6c 75 65 20   return.# value 
56b0: 66 72 6f 6d 20 74 68 65 20 6c 61 73 74 20 54 43  from the last TC
56c0: 4c 20 63 6f 6d 6d 61 6e 64 20 69 6e 20 24 63 6d  L command in $cm
56d0: 64 2e 0a 23 0a 23 20 4e 6f 72 6d 61 6c 6c 79 2c  d..#.# Normally,
56e0: 20 24 65 78 70 65 63 74 65 64 20 6d 75 73 74 20   $expected must 
56f0: 6d 61 74 63 68 20 65 78 61 63 74 6c 79 2e 20 20  match exactly.  
5700: 42 75 74 20 69 66 20 24 65 78 70 65 63 74 65 64  But if $expected
5710: 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 0a   is of the form.
5720: 23 20 22 2f 72 65 67 65 78 70 2f 22 20 74 68 65  # "/regexp/" the
5730: 6e 20 72 65 67 75 6c 61 72 20 65 78 70 72 65 73  n regular expres
5740: 73 69 6f 6e 20 6d 61 74 63 68 69 6e 67 20 69 73  sion matching is
5750: 20 75 73 65 64 2e 20 20 49 66 20 24 65 78 70 65   used.  If $expe
5760: 63 74 65 64 20 69 73 0a 23 20 22 7e 2f 72 65 67  cted is.# "~/reg
5770: 65 78 70 2f 22 20 74 68 65 6e 20 74 68 65 20 72  exp/" then the r
5780: 65 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f  egular expressio
5790: 6e 20 6d 75 73 74 20 4e 4f 54 20 6d 61 74 63 68  n must NOT match
57a0: 2e 20 20 49 66 20 24 65 78 70 65 63 74 65 64 20  .  If $expected 
57b0: 69 73 0a 23 20 6f 66 20 74 68 65 20 66 6f 72 6d  is.# of the form
57c0: 20 22 23 2f 76 61 6c 75 65 2d 6c 69 73 74 2f 22   "#/value-list/"
57d0: 20 74 68 65 6e 20 65 61 63 68 20 74 65 72 6d 20   then each term 
57e0: 69 6e 20 76 61 6c 75 65 2d 6c 69 73 74 20 6d 75  in value-list mu
57f0: 73 74 20 62 65 20 6e 75 6d 65 72 69 63 0a 23 20  st be numeric.# 
5800: 61 6e 64 20 6d 75 73 74 20 61 70 70 72 6f 78 69  and must approxi
5810: 6d 61 74 65 6c 79 20 6d 61 74 63 68 20 74 68 65  mately match the
5820: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 6e   corresponding n
5830: 75 6d 65 72 69 63 20 74 65 72 6d 20 69 6e 20 24  umeric term in $
5840: 72 65 73 75 6c 74 2e 0a 23 20 56 61 6c 75 65 73  result..# Values
5850: 20 6d 75 73 74 20 6d 61 74 63 68 20 77 69 74 68   must match with
5860: 69 6e 20 31 30 25 2e 20 20 4f 72 20 69 66 20 74  in 10%.  Or if t
5870: 68 65 20 24 65 78 70 65 63 74 65 64 20 74 65 72  he $expected ter
5880: 6d 20 69 73 20 41 2e 2e 42 20 74 68 65 6e 20 74  m is A..B then t
5890: 68 65 0a 23 20 24 72 65 73 75 6c 74 20 74 65 72  he.# $result ter
58a0: 6d 20 6d 75 73 74 20 62 65 20 69 6e 20 62 65 74  m must be in bet
58b0: 77 65 65 6e 20 41 20 61 6e 64 20 42 2e 0a 23 0a  ween A and B..#.
58c0: 70 72 6f 63 20 64 6f 5f 74 65 73 74 20 7b 6e 61  proc do_test {na
58d0: 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65 64 7d  me cmd expected}
58e0: 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 61 72 67 76   {.  global argv
58f0: 20 63 6d 64 6c 69 6e 65 61 72 67 0a 0a 20 20 66   cmdlinearg..  f
5900: 69 78 5f 74 65 73 74 6e 61 6d 65 20 6e 61 6d 65  ix_testname name
5910: 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64  ..  sqlite3_memd
5920: 65 62 75 67 5f 73 65 74 74 69 74 6c 65 20 24 6e  ebug_settitle $n
5930: 61 6d 65 0a 0a 23 20 20 69 66 20 7b 5b 6c 6c 65  ame..#  if {[lle
5940: 6e 67 74 68 20 24 61 72 67 76 5d 3d 3d 30 7d 20  ngth $argv]==0} 
5950: 7b 0a 23 20 20 20 20 73 65 74 20 67 6f 20 31 0a  {.#    set go 1.
5960: 23 20 20 7d 20 65 6c 73 65 20 7b 0a 23 20 20 20  #  } else {.#   
5970: 20 73 65 74 20 67 6f 20 30 0a 23 20 20 20 20 66   set go 0.#    f
5980: 6f 72 65 61 63 68 20 70 61 74 74 65 72 6e 20 24  oreach pattern $
5990: 61 72 67 76 20 7b 0a 23 20 20 20 20 20 20 69 66  argv {.#      if
59a0: 20 7b 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20   {[string match 
59b0: 24 70 61 74 74 65 72 6e 20 24 6e 61 6d 65 5d 7d  $pattern $name]}
59c0: 20 7b 0a 23 20 20 20 20 20 20 20 20 73 65 74 20   {.#        set 
59d0: 67 6f 20 31 0a 23 20 20 20 20 20 20 20 20 62 72  go 1.#        br
59e0: 65 61 6b 0a 23 20 20 20 20 20 20 7d 0a 23 20 20  eak.#      }.#  
59f0: 20 20 7d 0a 23 20 20 7d 0a 0a 20 20 69 66 20 7b    }.#  }..  if {
5a00: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47  [info exists ::G
5a10: 28 70 65 72 6d 3a 70 72 65 66 69 78 29 5d 7d 20  (perm:prefix)]} 
5a20: 7b 0a 20 20 20 20 73 65 74 20 6e 61 6d 65 20 22  {.    set name "
5a30: 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 66 69 78  $::G(perm:prefix
5a40: 29 24 6e 61 6d 65 22 0a 20 20 7d 0a 0a 20 20 69  )$name".  }..  i
5a50: 6e 63 72 5f 6e 74 65 73 74 0a 20 20 6f 75 74 70  ncr_ntest.  outp
5a60: 75 74 31 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24  ut1 -nonewline $
5a70: 6e 61 6d 65 2e 2e 2e 0a 20 20 66 6c 75 73 68 20  name....  flush 
5a80: 73 74 64 6f 75 74 0a 0a 20 20 69 66 20 7b 21 5b  stdout..  if {![
5a90: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
5aa0: 6d 61 74 63 68 29 5d 20 7c 7c 20 5b 73 74 72 69  match)] || [stri
5ab0: 6e 67 20 6d 61 74 63 68 20 24 3a 3a 47 28 6d 61  ng match $::G(ma
5ac0: 74 63 68 29 20 24 6e 61 6d 65 5d 7d 20 7b 0a 20  tch) $name]} {. 
5ad0: 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 75     if {[catch {u
5ae0: 70 6c 65 76 65 6c 20 23 30 20 22 24 63 6d 64 3b  plevel #0 "$cmd;
5af0: 5c 6e 22 7d 20 72 65 73 75 6c 74 5d 7d 20 7b 0a  \n"} result]} {.
5b00: 20 20 20 20 20 20 6f 75 74 70 75 74 32 5f 69 66        output2_if
5b10: 5f 6e 6f 5f 76 65 72 62 6f 73 65 20 2d 6e 6f 6e  _no_verbose -non
5b20: 65 77 6c 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e 0a  ewline $name....
5b30: 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22 5c        output2 "\
5b40: 6e 45 72 72 6f 72 3a 20 24 72 65 73 75 6c 74 22  nError: $result"
5b50: 0a 20 20 20 20 20 20 66 61 69 6c 5f 74 65 73 74  .      fail_test
5b60: 20 24 6e 61 6d 65 0a 20 20 20 20 7d 20 65 6c 73   $name.    } els
5b70: 65 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 72  e {.      if {[r
5b80: 65 67 65 78 70 20 7b 5e 5b 7e 23 5d 3f 2f 2e 2a  egexp {^[~#]?/.*
5b90: 2f 24 7d 20 24 65 78 70 65 63 74 65 64 5d 7d 20  /$} $expected]} 
5ba0: 7b 0a 20 20 20 20 20 20 20 20 23 20 22 65 78 70  {.        # "exp
5bb0: 65 63 74 65 64 22 20 69 73 20 6f 66 20 74 68 65  ected" is of the
5bc0: 20 66 6f 72 6d 20 22 2f 50 41 54 54 45 52 4e 2f   form "/PATTERN/
5bd0: 22 20 74 68 65 6e 20 74 68 65 20 72 65 73 75 6c  " then the resul
5be0: 74 20 69 66 20 63 6f 72 72 65 63 74 20 69 66 0a  t if correct if.
5bf0: 20 20 20 20 20 20 20 20 23 20 72 65 67 75 6c 61          # regula
5c00: 72 20 65 78 70 72 65 73 73 69 6f 6e 20 50 41 54  r expression PAT
5c10: 54 45 52 4e 20 6d 61 74 63 68 65 73 20 74 68 65  TERN matches the
5c20: 20 72 65 73 75 6c 74 2e 20 20 22 7e 2f 50 41 54   result.  "~/PAT
5c30: 54 45 52 4e 2f 22 20 6d 65 61 6e 73 0a 20 20 20  TERN/" means.   
5c40: 20 20 20 20 20 23 20 74 68 65 20 72 65 67 75 6c       # the regul
5c50: 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 6d 75  ar expression mu
5c60: 73 74 20 6e 6f 74 20 6d 61 74 63 68 2e 0a 20 20  st not match..  
5c70: 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e        if {[strin
5c80: 67 20 69 6e 64 65 78 20 24 65 78 70 65 63 74 65  g index $expecte
5c90: 64 20 30 5d 3d 3d 22 7e 22 7d 20 7b 0a 20 20 20  d 0]=="~"} {.   
5ca0: 20 20 20 20 20 20 20 73 65 74 20 72 65 20 5b 73         set re [s
5cb0: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70  tring range $exp
5cc0: 65 63 74 65 64 20 32 20 65 6e 64 2d 31 5d 0a 20  ected 2 end-1]. 
5cd0: 20 20 20 20 20 20 20 20 20 69 66 20 7b 5b 73 74           if {[st
5ce0: 72 69 6e 67 20 69 6e 64 65 78 20 24 72 65 20 30  ring index $re 0
5cf0: 5d 3d 3d 22 2a 22 7d 20 7b 0a 20 20 20 20 20 20  ]=="*"} {.      
5d00: 20 20 20 20 20 20 23 20 49 66 20 74 68 65 20 72        # If the r
5d10: 65 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f  egular expressio
5d20: 6e 20 62 65 67 69 6e 73 20 77 69 74 68 20 2a 20  n begins with * 
5d30: 74 68 65 6e 20 74 72 65 61 74 20 69 74 20 61 73  then treat it as
5d40: 20 61 20 67 6c 6f 62 20 69 6e 73 74 65 61 64 0a   a glob instead.
5d50: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
5d60: 6f 6b 20 5b 73 74 72 69 6e 67 20 6d 61 74 63 68  ok [string match
5d70: 20 24 72 65 20 24 72 65 73 75 6c 74 5d 0a 20 20   $re $result].  
5d80: 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b          } else {
5d90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74  .            set
5da0: 20 72 65 20 5b 73 74 72 69 6e 67 20 6d 61 70 20   re [string map 
5db0: 7b 23 20 7b 5b 2d 30 2d 39 2e 5d 2b 7d 7d 20 24  {# {[-0-9.]+}} $
5dc0: 72 65 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  re].            
5dd0: 73 65 74 20 6f 6b 20 5b 72 65 67 65 78 70 20 24  set ok [regexp $
5de0: 72 65 20 24 72 65 73 75 6c 74 5d 0a 20 20 20 20  re $result].    
5df0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
5e00: 20 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b    set ok [expr {
5e10: 21 24 6f 6b 7d 5d 0a 20 20 20 20 20 20 20 20 7d  !$ok}].        }
5e20: 20 65 6c 73 65 69 66 20 7b 5b 73 74 72 69 6e 67   elseif {[string
5e30: 20 69 6e 64 65 78 20 24 65 78 70 65 63 74 65 64   index $expected
5e40: 20 30 5d 3d 3d 22 23 22 7d 20 7b 0a 20 20 20 20   0]=="#"} {.    
5e50: 20 20 20 20 20 20 23 20 4e 75 6d 65 72 69 63 20        # Numeric 
5e60: 72 61 6e 67 65 20 76 61 6c 75 65 20 63 6f 6d 70  range value comp
5e70: 61 72 69 73 6f 6e 2e 20 20 45 61 63 68 20 74 65  arison.  Each te
5e80: 72 6d 20 6f 66 20 74 68 65 20 24 72 65 73 75 6c  rm of the $resul
5e90: 74 20 69 73 20 6d 61 74 63 68 65 64 0a 20 20 20  t is matched.   
5ea0: 20 20 20 20 20 20 20 23 20 61 67 61 69 6e 73 74         # against
5eb0: 20 6f 6e 65 20 74 65 72 6d 20 6f 66 20 24 65 78   one term of $ex
5ec0: 70 65 63 74 2e 20 20 42 6f 74 68 20 24 72 65 73  pect.  Both $res
5ed0: 75 6c 74 20 61 6e 64 20 24 65 78 70 65 63 74 65  ult and $expecte
5ee0: 64 20 74 65 72 6d 73 20 6d 75 73 74 20 62 65 0a  d terms must be.
5ef0: 20 20 20 20 20 20 20 20 20 20 23 20 6e 75 6d 65            # nume
5f00: 72 69 63 2e 20 20 54 68 65 20 76 61 6c 75 65 73  ric.  The values
5f10: 20 6d 75 73 74 20 6d 61 74 63 68 20 77 69 74 68   must match with
5f20: 69 6e 20 31 30 25 2e 20 20 4f 72 20 69 66 20 24  in 10%.  Or if $
5f30: 65 78 70 65 63 74 65 64 20 69 73 20 6f 66 20 74  expected is of t
5f40: 68 65 0a 20 20 20 20 20 20 20 20 20 20 23 20 66  he.          # f
5f50: 6f 72 6d 20 41 2e 2e 42 20 74 68 65 6e 20 74 68  orm A..B then th
5f60: 65 20 24 72 65 73 75 6c 74 20 74 65 72 6d 20 6d  e $result term m
5f70: 75 73 74 20 62 65 20 62 65 74 77 65 65 6e 20 41  ust be between A
5f80: 20 61 6e 64 20 42 2e 0a 20 20 20 20 20 20 20 20   and B..        
5f90: 20 20 73 65 74 20 65 32 20 5b 73 74 72 69 6e 67    set e2 [string
5fa0: 20 72 61 6e 67 65 20 24 65 78 70 65 63 74 65 64   range $expected
5fb0: 20 32 20 65 6e 64 2d 31 5d 0a 20 20 20 20 20 20   2 end-1].      
5fc0: 20 20 20 20 66 6f 72 65 61 63 68 20 69 20 24 72      foreach i $r
5fd0: 65 73 75 6c 74 20 6a 20 24 65 32 20 7b 0a 20 20  esult j $e2 {.  
5fe0: 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72            if {[r
5ff0: 65 67 65 78 70 20 7b 5e 28 2d 3f 5c 64 2b 29 5c  egexp {^(-?\d+)\
6000: 2e 5c 2e 28 2d 3f 5c 64 29 24 7d 20 24 6a 20 61  .\.(-?\d)$} $j a
6010: 6c 6c 20 41 20 42 5d 7d 20 7b 0a 20 20 20 20 20  ll A B]} {.     
6020: 20 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20           set ok 
6030: 5b 65 78 70 72 20 7b 24 69 2b 30 3e 3d 24 41 20  [expr {$i+0>=$A 
6040: 26 26 20 24 69 2b 30 3c 3d 24 42 7d 5d 0a 20 20  && $i+0<=$B}].  
6050: 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65            } else
6060: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
6070: 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b 24   set ok [expr {$
6080: 69 2b 30 3e 3d 30 2e 39 2a 24 6a 20 26 26 20 24  i+0>=0.9*$j && $
6090: 69 2b 30 3c 3d 31 2e 31 2a 24 6a 7d 5d 0a 20 20  i+0<=1.1*$j}].  
60a0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
60b0: 20 20 20 20 20 20 20 20 69 66 20 7b 21 24 6f 6b          if {!$ok
60c0: 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  } break.        
60d0: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69 66    }.          if
60e0: 20 7b 24 6f 6b 20 26 26 20 5b 6c 6c 65 6e 67 74   {$ok && [llengt
60f0: 68 20 24 72 65 73 75 6c 74 5d 21 3d 5b 6c 6c 65  h $result]!=[lle
6100: 6e 67 74 68 20 24 65 32 5d 7d 20 7b 73 65 74 20  ngth $e2]} {set 
6110: 6f 6b 20 30 7d 0a 20 20 20 20 20 20 20 20 7d 20  ok 0}.        } 
6120: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20  else {.         
6130: 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67 20   set re [string 
6140: 72 61 6e 67 65 20 24 65 78 70 65 63 74 65 64 20  range $expected 
6150: 31 20 65 6e 64 2d 31 5d 0a 20 20 20 20 20 20 20  1 end-1].       
6160: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 69     if {[string i
6170: 6e 64 65 78 20 24 72 65 20 30 5d 3d 3d 22 2a 22  ndex $re 0]=="*"
6180: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  } {.            
6190: 23 20 49 66 20 74 68 65 20 72 65 67 75 6c 61 72  # If the regular
61a0: 20 65 78 70 72 65 73 73 69 6f 6e 20 62 65 67 69   expression begi
61b0: 6e 73 20 77 69 74 68 20 2a 20 74 68 65 6e 20 74  ns with * then t
61c0: 72 65 61 74 20 69 74 20 61 73 20 61 20 67 6c 6f  reat it as a glo
61d0: 62 20 69 6e 73 74 65 61 64 0a 20 20 20 20 20 20  b instead.      
61e0: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 73 74        set ok [st
61f0: 72 69 6e 67 20 6d 61 74 63 68 20 24 72 65 20 24  ring match $re $
6200: 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20  result].        
6210: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
6220: 20 20 20 20 20 20 20 73 65 74 20 72 65 20 5b 73         set re [s
6230: 74 72 69 6e 67 20 6d 61 70 20 7b 23 20 7b 5b 2d  tring map {# {[-
6240: 30 2d 39 2e 5d 2b 7d 7d 20 24 72 65 5d 0a 20 20  0-9.]+}} $re].  
6250: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b            set ok
6260: 20 5b 72 65 67 65 78 70 20 24 72 65 20 24 72 65   [regexp $re $re
6270: 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20 20 20  sult].          
6280: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
6290: 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65 67    } elseif {[reg
62a0: 65 78 70 20 7b 5e 7e 3f 5c 2a 2e 2a 5c 2a 24 7d  exp {^~?\*.*\*$}
62b0: 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20   $expected]} {. 
62c0: 20 20 20 20 20 20 20 23 20 22 65 78 70 65 63 74         # "expect
62d0: 65 64 22 20 69 73 20 6f 66 20 74 68 65 20 66 6f  ed" is of the fo
62e0: 72 6d 20 22 2a 47 4c 4f 42 2a 22 20 74 68 65 6e  rm "*GLOB*" then
62f0: 20 74 68 65 20 72 65 73 75 6c 74 20 69 66 20 63   the result if c
6300: 6f 72 72 65 63 74 20 69 66 0a 20 20 20 20 20 20  orrect if.      
6310: 20 20 23 20 67 6c 6f 62 20 70 61 74 74 65 72 6e    # glob pattern
6320: 20 47 4c 4f 42 20 6d 61 74 63 68 65 73 20 74 68   GLOB matches th
6330: 65 20 72 65 73 75 6c 74 2e 20 20 22 7e 2f 47 4c  e result.  "~/GL
6340: 4f 42 2f 22 20 6d 65 61 6e 73 0a 20 20 20 20 20  OB/" means.     
6350: 20 20 20 23 20 74 68 65 20 67 6c 6f 62 20 6d 75     # the glob mu
6360: 73 74 20 6e 6f 74 20 6d 61 74 63 68 2e 0a 20 20  st not match..  
6370: 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e        if {[strin
6380: 67 20 69 6e 64 65 78 20 24 65 78 70 65 63 74 65  g index $expecte
6390: 64 20 30 5d 3d 3d 22 7e 22 7d 20 7b 0a 20 20 20  d 0]=="~"} {.   
63a0: 20 20 20 20 20 20 20 73 65 74 20 65 20 5b 73 74         set e [st
63b0: 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70 65  ring range $expe
63c0: 63 74 65 64 20 31 20 65 6e 64 5d 0a 20 20 20 20  cted 1 end].    
63d0: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 65 78        set ok [ex
63e0: 70 72 20 7b 21 5b 73 74 72 69 6e 67 20 6d 61 74  pr {![string mat
63f0: 63 68 20 24 65 20 24 72 65 73 75 6c 74 5d 7d 5d  ch $e $result]}]
6400: 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20  .        } else 
6410: 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  {.          set 
6420: 6f 6b 20 5b 73 74 72 69 6e 67 20 6d 61 74 63 68  ok [string match
6430: 20 24 65 78 70 65 63 74 65 64 20 24 72 65 73 75   $expected $resu
6440: 6c 74 5d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  lt].        }.  
6450: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
6460: 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 65 78 70       set ok [exp
6470: 72 20 7b 5b 73 74 72 69 6e 67 20 63 6f 6d 70 61  r {[string compa
6480: 72 65 20 24 72 65 73 75 6c 74 20 24 65 78 70 65  re $result $expe
6490: 63 74 65 64 5d 3d 3d 30 7d 5d 0a 20 20 20 20 20  cted]==0}].     
64a0: 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 21 24 6f   }.      if {!$o
64b0: 6b 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20 69  k} {.        # i
64c0: 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73  f {![info exists
64d0: 20 3a 3a 74 65 73 74 70 72 65 66 69 78 5d 20 7c   ::testprefix] |
64e0: 7c 20 24 3a 3a 74 65 73 74 70 72 65 66 69 78 20  | $::testprefix 
64f0: 65 71 20 22 22 7d 20 7b 0a 20 20 20 20 20 20 20  eq ""} {.       
6500: 20 23 20 20 20 65 72 72 6f 72 20 22 6e 6f 20 74   #   error "no t
6510: 65 73 74 20 70 72 65 66 69 78 22 0a 20 20 20 20  est prefix".    
6520: 20 20 20 20 23 20 7d 0a 20 20 20 20 20 20 20 20      # }.        
6530: 6f 75 74 70 75 74 31 20 22 22 0a 20 20 20 20 20  output1 "".     
6540: 20 20 20 6f 75 74 70 75 74 32 20 22 21 20 24 6e     output2 "! $n
6550: 61 6d 65 20 65 78 70 65 63 74 65 64 3a 20 5c 5b  ame expected: \[
6560: 24 65 78 70 65 63 74 65 64 5c 5d 5c 6e 21 20 24  $expected\]\n! $
6570: 6e 61 6d 65 20 67 6f 74 3a 20 20 20 20 20 20 5c  name got:      \
6580: 5b 24 72 65 73 75 6c 74 5c 5d 22 0a 20 20 20 20  [$result\]".    
6590: 20 20 20 20 66 61 69 6c 5f 74 65 73 74 20 24 6e      fail_test $n
65a0: 61 6d 65 0a 20 20 20 20 20 20 7d 20 65 6c 73 65  ame.      } else
65b0: 20 7b 0a 20 20 20 20 20 20 20 20 6f 75 74 70 75   {.        outpu
65c0: 74 31 20 22 20 4f 6b 22 0a 20 20 20 20 20 20 7d  t1 " Ok".      }
65d0: 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20  .    }.  } else 
65e0: 7b 0a 20 20 20 20 6f 75 74 70 75 74 31 20 22 20  {.    output1 " 
65f0: 4f 6d 69 74 74 65 64 22 0a 20 20 20 20 6f 6d 69  Omitted".    omi
6600: 74 5f 74 65 73 74 20 24 6e 61 6d 65 20 22 70 61  t_test $name "pa
6610: 74 74 65 72 6e 20 6d 69 73 6d 61 74 63 68 22 20  ttern mismatch" 
6620: 30 0a 20 20 7d 0a 20 20 66 6c 75 73 68 20 73 74  0.  }.  flush st
6630: 64 6f 75 74 0a 7d 0a 0a 70 72 6f 63 20 64 75 6d  dout.}..proc dum
6640: 70 62 79 74 65 73 20 7b 73 7d 20 7b 0a 20 20 73  pbytes {s} {.  s
6650: 65 74 20 72 20 22 22 0a 20 20 66 6f 72 20 7b 73  et r "".  for {s
6660: 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b 73  et i 0} {$i < [s
6670: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 5d  tring length $s]
6680: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
6690: 20 69 66 20 7b 24 69 20 3e 20 30 7d 20 7b 61 70   if {$i > 0} {ap
66a0: 70 65 6e 64 20 72 20 22 20 22 7d 0a 20 20 20 20  pend r " "}.    
66b0: 61 70 70 65 6e 64 20 72 20 5b 66 6f 72 6d 61 74  append r [format
66c0: 20 25 30 32 58 20 5b 73 63 61 6e 20 5b 73 74 72   %02X [scan [str
66d0: 69 6e 67 20 69 6e 64 65 78 20 24 73 20 24 69 5d  ing index $s $i]
66e0: 20 25 63 5d 5d 0a 20 20 7d 0a 20 20 72 65 74 75   %c]].  }.  retu
66f0: 72 6e 20 24 72 0a 7d 0a 0a 70 72 6f 63 20 63 61  rn $r.}..proc ca
6700: 74 63 68 63 6d 64 20 7b 64 62 20 7b 63 6d 64 20  tchcmd {db {cmd 
6710: 22 22 7d 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20  ""}} {.  global 
6720: 43 4c 49 0a 20 20 73 65 74 20 6f 75 74 20 5b 6f  CLI.  set out [o
6730: 70 65 6e 20 63 6d 64 73 2e 74 78 74 20 77 5d 0a  pen cmds.txt w].
6740: 20 20 70 75 74 73 20 24 6f 75 74 20 24 63 6d 64    puts $out $cmd
6750: 0a 20 20 63 6c 6f 73 65 20 24 6f 75 74 0a 20 20  .  close $out.  
6760: 73 65 74 20 6c 69 6e 65 20 22 65 78 65 63 20 24  set line "exec $
6770: 43 4c 49 20 24 64 62 20 3c 20 63 6d 64 73 2e 74  CLI $db < cmds.t
6780: 78 74 22 0a 20 20 73 65 74 20 72 63 20 5b 63 61  xt".  set rc [ca
6790: 74 63 68 20 7b 20 65 76 61 6c 20 24 6c 69 6e 65  tch { eval $line
67a0: 20 7d 20 6d 73 67 5d 0a 20 20 6c 69 73 74 20 24   } msg].  list $
67b0: 72 63 20 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20  rc $msg.}..proc 
67c0: 63 61 74 63 68 63 6d 64 65 78 20 7b 64 62 20 7b  catchcmdex {db {
67d0: 63 6d 64 20 22 22 7d 7d 20 7b 0a 20 20 67 6c 6f  cmd ""}} {.  glo
67e0: 62 61 6c 20 43 4c 49 0a 20 20 73 65 74 20 6f 75  bal CLI.  set ou
67f0: 74 20 5b 6f 70 65 6e 20 63 6d 64 73 2e 74 78 74  t [open cmds.txt
6800: 20 77 5d 0a 20 20 66 63 6f 6e 66 69 67 75 72 65   w].  fconfigure
6810: 20 24 6f 75 74 20 2d 65 6e 63 6f 64 69 6e 67 20   $out -encoding 
6820: 62 69 6e 61 72 79 20 2d 74 72 61 6e 73 6c 61 74  binary -translat
6830: 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 70 75 74  ion binary.  put
6840: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6f 75  s -nonewline $ou
6850: 74 20 24 63 6d 64 0a 20 20 63 6c 6f 73 65 20 24  t $cmd.  close $
6860: 6f 75 74 0a 20 20 73 65 74 20 6c 69 6e 65 20 22  out.  set line "
6870: 65 78 65 63 20 2d 6b 65 65 70 6e 65 77 6c 69 6e  exec -keepnewlin
6880: 65 20 2d 2d 20 24 43 4c 49 20 24 64 62 20 3c 20  e -- $CLI $db < 
6890: 63 6d 64 73 2e 74 78 74 22 0a 20 20 73 65 74 20  cmds.txt".  set 
68a0: 63 68 61 6e 73 20 5b 6c 69 73 74 20 73 74 64 69  chans [list stdi
68b0: 6e 20 73 74 64 6f 75 74 20 73 74 64 65 72 72 5d  n stdout stderr]
68c0: 0a 20 20 66 6f 72 65 61 63 68 20 63 68 61 6e 20  .  foreach chan 
68d0: 24 63 68 61 6e 73 20 7b 0a 20 20 20 20 63 61 74  $chans {.    cat
68e0: 63 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d  ch {.      set m
68f0: 6f 64 65 73 28 24 63 68 61 6e 29 20 5b 66 63 6f  odes($chan) [fco
6900: 6e 66 69 67 75 72 65 20 24 63 68 61 6e 5d 0a 20  nfigure $chan]. 
6910: 20 20 20 20 20 66 63 6f 6e 66 69 67 75 72 65 20       fconfigure 
6920: 24 63 68 61 6e 20 2d 65 6e 63 6f 64 69 6e 67 20  $chan -encoding 
6930: 62 69 6e 61 72 79 20 2d 74 72 61 6e 73 6c 61 74  binary -translat
6940: 69 6f 6e 20 62 69 6e 61 72 79 20 2d 62 75 66 66  ion binary -buff
6950: 65 72 69 6e 67 20 6e 6f 6e 65 0a 20 20 20 20 7d  ering none.    }
6960: 0a 20 20 7d 0a 20 20 73 65 74 20 72 63 20 5b 63  .  }.  set rc [c
6970: 61 74 63 68 20 7b 20 65 76 61 6c 20 24 6c 69 6e  atch { eval $lin
6980: 65 20 7d 20 6d 73 67 5d 0a 20 20 66 6f 72 65 61  e } msg].  forea
6990: 63 68 20 63 68 61 6e 20 24 63 68 61 6e 73 20 7b  ch chan $chans {
69a0: 0a 20 20 20 20 63 61 74 63 68 20 7b 0a 20 20 20  .    catch {.   
69b0: 20 20 20 65 76 61 6c 20 66 63 6f 6e 66 69 67 75     eval fconfigu
69c0: 72 65 20 5b 6c 69 73 74 20 24 63 68 61 6e 5d 20  re [list $chan] 
69d0: 24 6d 6f 64 65 73 28 24 63 68 61 6e 29 0a 20 20  $modes($chan).  
69e0: 20 20 7d 0a 20 20 7d 0a 20 20 23 20 70 75 74 73    }.  }.  # puts
69f0: 20 5b 64 75 6d 70 62 79 74 65 73 20 24 6d 73 67   [dumpbytes $msg
6a00: 5d 0a 20 20 6c 69 73 74 20 24 72 63 20 24 6d 73  ].  list $rc $ms
6a10: 67 0a 7d 0a 0a 70 72 6f 63 20 66 69 6c 65 70 61  g.}..proc filepa
6a20: 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 7b 70 7d  th_normalize {p}
6a30: 20 7b 0a 20 20 23 20 74 65 73 74 20 63 61 73 65   {.  # test case
6a40: 73 20 73 68 6f 75 6c 64 20 62 65 20 77 72 69 74  s should be writ
6a50: 74 65 6e 20 74 6f 20 61 73 73 75 6d 65 20 22 75  ten to assume "u
6a60: 6e 69 78 22 2d 6c 69 6b 65 20 66 69 6c 65 20 70  nix"-like file p
6a70: 61 74 68 73 0a 20 20 69 66 20 7b 24 3a 3a 74 63  aths.  if {$::tc
6a80: 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66  l_platform(platf
6a90: 6f 72 6d 29 21 3d 22 75 6e 69 78 22 7d 20 7b 0a  orm)!="unix"} {.
6aa0: 20 20 20 20 23 20 6c 72 65 76 65 72 73 65 2a 32      # lreverse*2
6ab0: 20 61 73 20 61 20 68 61 63 6b 20 74 6f 20 72 65   as a hack to re
6ac0: 6d 6f 76 65 20 61 6e 79 20 75 6e 6e 65 65 64 65  move any unneede
6ad0: 64 20 7b 7d 20 61 66 74 65 72 20 74 68 65 20 73  d {} after the s
6ae0: 74 72 69 6e 67 20 6d 61 70 0a 20 20 20 20 6c 72  tring map.    lr
6af0: 65 76 65 72 73 65 20 5b 6c 72 65 76 65 72 73 65  everse [lreverse
6b00: 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 5c 5c   [string map {\\
6b10: 20 2f 7d 20 5b 72 65 67 73 75 62 20 2d 6e 6f 63   /} [regsub -noc
6b20: 61 73 65 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5d 3a  ase -all {[a-z]:
6b30: 5b 2f 5c 5c 5d 2b 7d 20 24 70 20 7b 2f 7d 5d 5d  [/\\]+} $p {/}]]
6b40: 5d 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74 20  ].  } {.    set 
6b50: 70 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 6f 5f  p.  }.}.proc do_
6b60: 66 69 6c 65 70 61 74 68 5f 74 65 73 74 20 7b 6e  filepath_test {n
6b70: 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65 64  ame cmd expected
6b80: 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 5b 6c  } {.  uplevel [l
6b90: 69 73 74 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d  ist do_test $nam
6ba0: 65 20 5b 0a 20 20 20 20 73 75 62 73 74 20 2d 6e  e [.    subst -n
6bb0: 6f 63 6f 6d 6d 61 6e 64 73 20 7b 20 66 69 6c 65  ocommands { file
6bc0: 70 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 5b  path_normalize [
6bd0: 20 24 63 6d 64 20 5d 20 7d 0a 20 20 5d 20 5b 66   $cmd ] }.  ] [f
6be0: 69 6c 65 70 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a  ilepath_normaliz
6bf0: 65 20 24 65 78 70 65 63 74 65 64 5d 5d 0a 7d 0a  e $expected]].}.
6c00: 0a 70 72 6f 63 20 72 65 61 6c 6e 75 6d 5f 6e 6f  .proc realnum_no
6c10: 72 6d 61 6c 69 7a 65 20 7b 72 7d 20 7b 0a 20 20  rmalize {r} {.  
6c20: 23 20 64 69 66 66 65 72 65 6e 74 20 54 43 4c 20  # different TCL 
6c30: 76 65 72 73 69 6f 6e 73 20 64 69 73 70 6c 61 79  versions display
6c40: 20 66 6c 6f 61 74 69 6e 67 20 70 6f 69 6e 74 20   floating point 
6c50: 76 61 6c 75 65 73 20 64 69 66 66 65 72 65 6e 74  values different
6c60: 6c 79 2e 0a 20 20 73 74 72 69 6e 67 20 6d 61 70  ly..  string map
6c70: 20 7b 31 2e 23 49 4e 46 20 69 6e 66 20 49 6e 66   {1.#INF inf Inf
6c80: 20 69 6e 66 20 2e 30 65 20 65 7d 20 5b 72 65 67   inf .0e e} [reg
6c90: 73 75 62 20 2d 61 6c 6c 20 7b 28 65 5b 2b 2d 5d  sub -all {(e[+-]
6ca0: 29 30 2b 7d 20 24 72 20 7b 5c 31 7d 5d 0a 7d 0a  )0+} $r {\1}].}.
6cb0: 70 72 6f 63 20 64 6f 5f 72 65 61 6c 6e 75 6d 5f  proc do_realnum_
6cc0: 74 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65  test {name cmd e
6cd0: 78 70 65 63 74 65 64 7d 20 7b 0a 20 20 75 70 6c  xpected} {.  upl
6ce0: 65 76 65 6c 20 5b 6c 69 73 74 20 64 6f 5f 74 65  evel [list do_te
6cf0: 73 74 20 24 6e 61 6d 65 20 5b 0a 20 20 20 20 73  st $name [.    s
6d00: 75 62 73 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64 73  ubst -nocommands
6d10: 20 7b 20 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61   { realnum_norma
6d20: 6c 69 7a 65 20 5b 20 24 63 6d 64 20 5d 20 7d 0a  lize [ $cmd ] }.
6d30: 20 20 5d 20 5b 72 65 61 6c 6e 75 6d 5f 6e 6f 72    ] [realnum_nor
6d40: 6d 61 6c 69 7a 65 20 24 65 78 70 65 63 74 65 64  malize $expected
6d50: 5d 5d 0a 7d 0a 0a 70 72 6f 63 20 66 69 78 5f 74  ]].}..proc fix_t
6d60: 65 73 74 6e 61 6d 65 20 7b 76 61 72 6e 61 6d 65  estname {varname
6d70: 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 76 61 72  } {.  upvar $var
6d80: 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20  name testname.  
6d90: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
6da0: 20 3a 3a 74 65 73 74 70 72 65 66 69 78 5d 0a 20   ::testprefix]. 
6db0: 20 20 26 26 20 5b 73 74 72 69 6e 67 20 69 73 20    && [string is 
6dc0: 64 69 67 69 74 20 5b 73 74 72 69 6e 67 20 72 61  digit [string ra
6dd0: 6e 67 65 20 24 74 65 73 74 6e 61 6d 65 20 30 20  nge $testname 0 
6de0: 30 5d 5d 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65  0]].  } {.    se
6df0: 74 20 74 65 73 74 6e 61 6d 65 20 22 24 7b 3a 3a  t testname "${::
6e00: 74 65 73 74 70 72 65 66 69 78 7d 2d 24 74 65 73  testprefix}-$tes
6e10: 74 6e 61 6d 65 22 0a 20 20 7d 0a 7d 0a 0a 70 72  tname".  }.}..pr
6e20: 6f 63 20 6e 6f 72 6d 61 6c 69 7a 65 5f 6c 69 73  oc normalize_lis
6e30: 74 20 7b 4c 7d 20 7b 0a 20 20 73 65 74 20 4c 32  t {L} {.  set L2
6e40: 20 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61 63   [list].  foreac
6e50: 68 20 6c 20 24 4c 20 7b 6c 61 70 70 65 6e 64 20  h l $L {lappend 
6e60: 4c 32 20 24 6c 7d 0a 20 20 73 65 74 20 4c 32 0a  L2 $l}.  set L2.
6e70: 7d 0a 0a 23 20 45 69 74 68 65 72 3a 0a 23 0a 23  }..# Either:.#.#
6e80: 20 20 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65     do_execsql_te
6e90: 73 74 20 54 45 53 54 4e 41 4d 45 20 53 51 4c 20  st TESTNAME SQL 
6ea0: 3f 52 45 53 3f 0a 23 20 20 20 64 6f 5f 65 78 65  ?RES?.#   do_exe
6eb0: 63 73 71 6c 5f 74 65 73 74 20 2d 64 62 20 44 42  csql_test -db DB
6ec0: 20 54 45 53 54 4e 41 4d 45 20 53 51 4c 20 3f 52   TESTNAME SQL ?R
6ed0: 45 53 3f 0a 23 0a 70 72 6f 63 20 64 6f 5f 65 78  ES?.#.proc do_ex
6ee0: 65 63 73 71 6c 5f 74 65 73 74 20 7b 61 72 67 73  ecsql_test {args
6ef0: 7d 20 7b 0a 20 20 73 65 74 20 64 62 20 64 62 0a  } {.  set db db.
6f00: 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20 24 61    if {[lindex $a
6f10: 72 67 73 20 30 5d 3d 3d 22 2d 64 62 22 7d 20 7b  rgs 0]=="-db"} {
6f20: 0a 20 20 20 20 73 65 74 20 64 62 20 5b 6c 69 6e  .    set db [lin
6f30: 64 65 78 20 24 61 72 67 73 20 31 5d 0a 20 20 20  dex $args 1].   
6f40: 20 73 65 74 20 61 72 67 73 20 5b 6c 72 61 6e 67   set args [lrang
6f50: 65 20 24 61 72 67 73 20 32 20 65 6e 64 5d 0a 20  e $args 2 end]. 
6f60: 20 7d 0a 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67   }..  if {[lleng
6f70: 74 68 20 24 61 72 67 73 5d 3d 3d 32 7d 20 7b 0a  th $args]==2} {.
6f80: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 65 73      foreach {tes
6f90: 74 6e 61 6d 65 20 73 71 6c 7d 20 24 61 72 67 73  tname sql} $args
6fa0: 20 7b 7d 0a 20 20 20 20 73 65 74 20 72 65 73 75   {}.    set resu
6fb0: 6c 74 20 22 22 0a 20 20 7d 20 65 6c 73 65 69 66  lt "".  } elseif
6fc0: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73   {[llength $args
6fd0: 5d 3d 3d 33 7d 20 7b 0a 20 20 20 20 66 6f 72 65  ]==3} {.    fore
6fe0: 61 63 68 20 7b 74 65 73 74 6e 61 6d 65 20 73 71  ach {testname sq
6ff0: 6c 20 72 65 73 75 6c 74 7d 20 24 61 72 67 73 20  l result} $args 
7000: 7b 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  {}.  } else {.  
7010: 20 20 65 72 72 6f 72 20 5b 73 74 72 69 6e 67 20    error [string 
7020: 74 72 69 6d 20 7b 0a 20 20 20 20 20 20 77 72 6f  trim {.      wro
7030: 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c  ng # args: shoul
7040: 64 20 62 65 20 22 64 6f 5f 65 78 65 63 73 71 6c  d be "do_execsql
7050: 5f 74 65 73 74 20 3f 2d 64 62 20 44 42 3f 20 74  _test ?-db DB? t
7060: 65 73 74 6e 61 6d 65 20 73 71 6c 20 3f 72 65 73  estname sql ?res
7070: 75 6c 74 3f 22 0a 20 20 20 20 7d 5d 0a 20 20 7d  ult?".    }].  }
7080: 0a 0a 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65  ..  fix_testname
7090: 20 74 65 73 74 6e 61 6d 65 0a 0a 20 20 75 70 6c   testname..  upl
70a0: 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 20 20 20  evel do_test    
70b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
70c0: 20 20 20 20 20 5b 6c 69 73 74 20 24 74 65 73 74       [list $test
70d0: 6e 61 6d 65 5d 20 20 20 20 20 20 20 20 20 20 20  name]           
70e0: 20 5c 0a 20 20 20 20 20 20 5b 6c 69 73 74 20 22   \.      [list "
70f0: 65 78 65 63 73 71 6c 20 7b 24 73 71 6c 7d 20 24  execsql {$sql} $
7100: 64 62 22 5d 20 5c 0a 20 20 20 20 20 20 5b 6c 69  db"] \.      [li
7110: 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73  st [list {*}$res
7120: 75 6c 74 5d 5d 0a 7d 0a 0a 70 72 6f 63 20 64 6f  ult]].}..proc do
7130: 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74 20 7b  _catchsql_test {
7140: 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 72 65 73  testname sql res
7150: 75 6c 74 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73  ult} {.  fix_tes
7160: 74 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20  tname testname. 
7170: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74   uplevel do_test
7180: 20 5b 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65   [list $testname
7190: 5d 20 5b 6c 69 73 74 20 22 63 61 74 63 68 73 71  ] [list "catchsq
71a0: 6c 20 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69 73 74  l {$sql}"] [list
71b0: 20 24 72 65 73 75 6c 74 5d 0a 7d 0a 70 72 6f 63   $result].}.proc
71c0: 20 64 6f 5f 74 69 6d 65 64 5f 65 78 65 63 73 71   do_timed_execsq
71d0: 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61 6d 65  l_test {testname
71e0: 20 73 71 6c 20 7b 72 65 73 75 6c 74 20 7b 7d 7d   sql {result {}}
71f0: 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73 74 6e 61  } {.  fix_testna
7200: 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20 75 70  me testname.  up
7210: 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 5b 6c  level do_test [l
7220: 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d 20 5b  ist $testname] [
7230: 6c 69 73 74 20 22 65 78 65 63 73 71 6c 5f 74 69  list "execsql_ti
7240: 6d 65 64 20 7b 24 73 71 6c 7d 22 5d 5c 0a 20 20  med {$sql}"]\.  
7250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7270: 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d   [list [list {*}
7280: 24 72 65 73 75 6c 74 5d 5d 0a 7d 0a 70 72 6f 63  $result]].}.proc
7290: 20 64 6f 5f 65 71 70 5f 74 65 73 74 20 7b 6e 61   do_eqp_test {na
72a0: 6d 65 20 73 71 6c 20 72 65 73 7d 20 7b 0a 20 20  me sql res} {.  
72b0: 75 70 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63 73  uplevel do_execs
72c0: 71 6c 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 6c  ql_test $name [l
72d0: 69 73 74 20 22 45 58 50 4c 41 49 4e 20 51 55 45  ist "EXPLAIN QUE
72e0: 52 59 20 50 4c 41 4e 20 24 73 71 6c 22 5d 20 5b  RY PLAN $sql"] [
72f0: 6c 69 73 74 20 24 72 65 73 5d 0a 7d 0a 0a 23 2d  list $res].}..#-
7300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7330: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7340: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 20 20 55 73 61  --------.#   Usa
7350: 67 65 3a 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65  ge: do_select_te
7360: 73 74 73 20 50 52 45 46 49 58 20 3f 53 57 49 54  sts PREFIX ?SWIT
7370: 43 48 45 53 3f 20 54 45 53 54 4c 49 53 54 0a 23  CHES? TESTLIST.#
7380: 0a 23 20 57 68 65 72 65 20 73 77 69 74 63 68 65  .# Where switche
7390: 73 20 61 72 65 3a 0a 23 0a 23 20 20 20 2d 65 72  s are:.#.#   -er
73a0: 72 6f 72 66 6f 72 6d 61 74 20 46 4d 54 53 54 52  rorformat FMTSTR
73b0: 49 4e 47 0a 23 20 20 20 2d 63 6f 75 6e 74 0a 23  ING.#   -count.#
73c0: 20 20 20 2d 71 75 65 72 79 20 53 51 4c 0a 23 20     -query SQL.# 
73d0: 20 20 2d 74 63 6c 71 75 65 72 79 20 54 43 4c 0a    -tclquery TCL.
73e0: 23 20 20 20 2d 72 65 70 61 69 72 20 54 43 4c 0a  #   -repair TCL.
73f0: 23 0a 70 72 6f 63 20 64 6f 5f 73 65 6c 65 63 74  #.proc do_select
7400: 5f 74 65 73 74 73 20 7b 70 72 65 66 69 78 20 61  _tests {prefix a
7410: 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 74 65  rgs} {..  set te
7420: 73 74 6c 69 73 74 20 5b 6c 69 6e 64 65 78 20 24  stlist [lindex $
7430: 61 72 67 73 20 65 6e 64 5d 0a 20 20 73 65 74 20  args end].  set 
7440: 73 77 69 74 63 68 65 73 20 5b 6c 72 61 6e 67 65  switches [lrange
7450: 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 0a   $args 0 end-1].
7460: 0a 20 20 73 65 74 20 65 72 72 66 6d 74 20 22 22  .  set errfmt ""
7470: 0a 20 20 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79  .  set countonly
7480: 20 30 0a 20 20 73 65 74 20 74 63 6c 71 75 65 72   0.  set tclquer
7490: 79 20 22 22 0a 20 20 73 65 74 20 72 65 70 61 69  y "".  set repai
74a0: 72 20 22 22 0a 0a 20 20 66 6f 72 20 7b 73 65 74  r ""..  for {set
74b0: 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b 6c 6c 65   i 0} {$i < [lle
74c0: 6e 67 74 68 20 24 73 77 69 74 63 68 65 73 5d 7d  ngth $switches]}
74d0: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
74e0: 73 65 74 20 73 20 5b 6c 69 6e 64 65 78 20 24 73  set s [lindex $s
74f0: 77 69 74 63 68 65 73 20 24 69 5d 0a 20 20 20 20  witches $i].    
7500: 73 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65  set n [string le
7510: 6e 67 74 68 20 24 73 5d 0a 20 20 20 20 69 66 20  ngth $s].    if 
7520: 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e  {$n>=2 && [strin
7530: 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20  g equal -length 
7540: 24 6e 20 24 73 20 22 2d 71 75 65 72 79 22 5d 7d  $n $s "-query"]}
7550: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 74 63 6c   {.      set tcl
7560: 71 75 65 72 79 20 5b 6c 69 73 74 20 65 78 65 63  query [list exec
7570: 73 71 6c 20 5b 6c 69 6e 64 65 78 20 24 73 77 69  sql [lindex $swi
7580: 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 5d  tches [incr i]]]
7590: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
75a0: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
75b0: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
75c0: 20 24 73 20 22 2d 74 63 6c 71 75 65 72 79 22 5d   $s "-tclquery"]
75d0: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 74 63  } {.      set tc
75e0: 6c 71 75 65 72 79 20 5b 6c 69 6e 64 65 78 20 24  lquery [lindex $
75f0: 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69  switches [incr i
7600: 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20  ]].    } elseif 
7610: 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e  {$n>=2 && [strin
7620: 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20  g equal -length 
7630: 24 6e 20 24 73 20 22 2d 65 72 72 6f 72 66 6f 72  $n $s "-errorfor
7640: 6d 61 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73  mat"]} {.      s
7650: 65 74 20 65 72 72 66 6d 74 20 5b 6c 69 6e 64 65  et errfmt [linde
7660: 78 20 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63  x $switches [inc
7670: 72 20 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65  r i]].    } else
7680: 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74  if {$n>=2 && [st
7690: 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67  ring equal -leng
76a0: 74 68 20 24 6e 20 24 73 20 22 2d 72 65 70 61 69  th $n $s "-repai
76b0: 72 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  r"]} {.      set
76c0: 20 72 65 70 61 69 72 20 5b 6c 69 6e 64 65 78 20   repair [lindex 
76d0: 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20  $switches [incr 
76e0: 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66  i]].    } elseif
76f0: 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69   {$n>=2 && [stri
7700: 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68  ng equal -length
7710: 20 24 6e 20 24 73 20 22 2d 63 6f 75 6e 74 22 5d   $n $s "-count"]
7720: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 63 6f  } {.      set co
7730: 75 6e 74 6f 6e 6c 79 20 31 0a 20 20 20 20 7d 20  untonly 1.    } 
7740: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 65 72 72  else {.      err
7750: 6f 72 20 22 75 6e 6b 6e 6f 77 6e 20 73 77 69 74  or "unknown swit
7760: 63 68 3a 20 24 73 22 0a 20 20 20 20 7d 0a 20 20  ch: $s".    }.  
7770: 7d 0a 0a 20 20 69 66 20 7b 24 63 6f 75 6e 74 6f  }..  if {$counto
7780: 6e 6c 79 20 26 26 20 24 65 72 72 66 6d 74 21 3d  nly && $errfmt!=
7790: 22 22 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20  ""} {.    error 
77a0: 22 43 61 6e 6e 6f 74 20 75 73 65 20 2d 63 6f 75  "Cannot use -cou
77b0: 6e 74 20 61 6e 64 20 2d 65 72 72 6f 72 66 6f 72  nt and -errorfor
77c0: 6d 61 74 20 74 6f 67 65 74 68 65 72 22 0a 20 20  mat together".  
77d0: 7d 0a 20 20 73 65 74 20 6e 54 65 73 74 6c 69 73  }.  set nTestlis
77e0: 74 20 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73 74  t [llength $test
77f0: 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24 6e 54 65  list].  if {$nTe
7800: 73 74 6c 69 73 74 25 33 20 7c 7c 20 24 6e 54 65  stlist%3 || $nTe
7810: 73 74 6c 69 73 74 3d 3d 30 20 7d 20 7b 0a 20 20  stlist==0 } {.  
7820: 20 20 65 72 72 6f 72 20 22 53 45 4c 45 43 54 20    error "SELECT 
7830: 74 65 73 74 20 6c 69 73 74 20 63 6f 6e 74 61 69  test list contai
7840: 6e 73 20 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73  ns [llength $tes
7850: 74 6c 69 73 74 5d 20 65 6c 65 6d 65 6e 74 73 22  tlist] elements"
7860: 0a 20 20 7d 0a 0a 20 20 65 76 61 6c 20 24 72 65  .  }..  eval $re
7870: 70 61 69 72 0a 20 20 66 6f 72 65 61 63 68 20 7b  pair.  foreach {
7880: 74 6e 20 73 71 6c 20 72 65 73 7d 20 24 74 65 73  tn sql res} $tes
7890: 74 6c 69 73 74 20 7b 0a 20 20 20 20 69 66 20 7b  tlist {.    if {
78a0: 24 74 63 6c 71 75 65 72 79 20 21 3d 20 22 22 7d  $tclquery != ""}
78b0: 20 7b 0a 20 20 20 20 20 20 65 78 65 63 73 71 6c   {.      execsql
78c0: 20 24 73 71 6c 0a 20 20 20 20 20 20 75 70 6c 65   $sql.      uple
78d0: 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 7b 70 72  vel do_test ${pr
78e0: 65 66 69 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20  efix}.$tn [list 
78f0: 24 74 63 6c 71 75 65 72 79 5d 20 5b 6c 69 73 74  $tclquery] [list
7900: 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d   [list {*}$res]]
7910: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
7920: 63 6f 75 6e 74 6f 6e 6c 79 7d 20 7b 0a 20 20 20  countonly} {.   
7930: 20 20 20 73 65 74 20 6e 52 6f 77 20 30 0a 20 20     set nRow 0.  
7940: 20 20 20 20 64 62 20 65 76 61 6c 20 24 73 71 6c      db eval $sql
7950: 20 7b 69 6e 63 72 20 6e 52 6f 77 7d 0a 20 20 20   {incr nRow}.   
7960: 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65     uplevel do_te
7970: 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e  st ${prefix}.$tn
7980: 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 73 65 74   [list [list set
7990: 20 7b 7d 20 24 6e 52 6f 77 5d 5d 20 5b 6c 69 73   {} $nRow]] [lis
79a0: 74 20 24 72 65 73 5d 0a 20 20 20 20 7d 20 65 6c  t $res].    } el
79b0: 73 65 69 66 20 7b 24 65 72 72 66 6d 74 3d 3d 22  seif {$errfmt=="
79c0: 22 7d 20 7b 0a 20 20 20 20 20 20 75 70 6c 65 76  "} {.      uplev
79d0: 65 6c 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65  el do_execsql_te
79e0: 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 7b 74  st ${prefix}.${t
79f0: 6e 7d 20 5b 6c 69 73 74 20 24 73 71 6c 5d 20 5b  n} [list $sql] [
7a00: 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72  list [list {*}$r
7a10: 65 73 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20  es]].    } else 
7a20: 7b 0a 20 20 20 20 20 20 73 65 74 20 72 65 73 20  {.      set res 
7a30: 5b 6c 69 73 74 20 31 20 5b 73 74 72 69 6e 67 20  [list 1 [string 
7a40: 74 72 69 6d 20 5b 66 6f 72 6d 61 74 20 24 65 72  trim [format $er
7a50: 72 66 6d 74 20 7b 2a 7d 24 72 65 73 5d 5d 5d 0a  rfmt {*}$res]]].
7a60: 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f        uplevel do
7a70: 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74 20 24  _catchsql_test $
7a80: 7b 70 72 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b  {prefix}.${tn} [
7a90: 6c 69 73 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74  list $sql] [list
7aa0: 20 24 72 65 73 5d 0a 20 20 20 20 7d 0a 20 20 20   $res].    }.   
7ab0: 20 65 76 61 6c 20 24 72 65 70 61 69 72 0a 20 20   eval $repair.  
7ac0: 7d 0a 0a 7d 0a 0a 70 72 6f 63 20 64 65 6c 65 74  }..}..proc delet
7ad0: 65 5f 61 6c 6c 5f 64 61 74 61 20 7b 7d 20 7b 0a  e_all_data {} {.
7ae0: 20 20 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43    db eval {SELEC
7af0: 54 20 74 62 6c 5f 6e 61 6d 65 20 41 53 20 74 20  T tbl_name AS t 
7b00: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
7b10: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
7b20: 27 74 61 62 6c 65 27 7d 20 7b 0a 20 20 20 20 64  'table'} {.    d
7b30: 62 20 65 76 61 6c 20 22 44 45 4c 45 54 45 20 46  b eval "DELETE F
7b40: 52 4f 4d 20 27 5b 73 74 72 69 6e 67 20 6d 61 70  ROM '[string map
7b50: 20 7b 27 20 27 27 7d 20 24 74 5d 27 22 0a 20 20   {' ''} $t]'".  
7b60: 7d 0a 7d 0a 0a 23 20 52 75 6e 20 61 6e 20 53 51  }.}..# Run an SQ
7b70: 4c 20 73 63 72 69 70 74 2e 0a 23 20 52 65 74 75  L script..# Retu
7b80: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
7b90: 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20 70 65   microseconds pe
7ba0: 72 20 73 74 61 74 65 6d 65 6e 74 2e 0a 23 0a 70  r statement..#.p
7bb0: 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 20  roc speed_trial 
7bc0: 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e  {name numstmt un
7bd0: 69 74 73 20 73 71 6c 7d 20 7b 0a 20 20 6f 75 74  its sql} {.  out
7be0: 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  put2 -nonewline 
7bf0: 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31  [format {%-21.21
7c00: 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20  s } $name...].  
7c10: 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73  flush stdout.  s
7c20: 65 74 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b  et speed [time {
7c30: 73 71 6c 69 74 65 33 5f 65 78 65 63 5f 6e 72 20  sqlite3_exec_nr 
7c40: 64 62 20 24 73 71 6c 7d 5d 0a 20 20 73 65 74 20  db $sql}].  set 
7c50: 74 6d 20 5b 6c 69 6e 64 65 78 20 24 73 70 65 65  tm [lindex $spee
7c60: 64 20 30 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d  d 0].  if {$tm =
7c70: 3d 20 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 72  = 0} {.    set r
7c80: 61 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 73  ate [format %20s
7c90: 20 22 6d 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73   "many"].  } els
7ca0: 65 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65  e {.    set rate
7cb0: 20 5b 66 6f 72 6d 61 74 20 25 32 30 2e 35 66 20   [format %20.5f 
7cc0: 5b 65 78 70 72 20 7b 31 30 30 30 30 30 30 2e 30  [expr {1000000.0
7cd0: 2a 24 6e 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d  *$numstmt/$tm}]]
7ce0: 0a 20 20 7d 0a 20 20 73 65 74 20 75 32 20 24 75  .  }.  set u2 $u
7cf0: 6e 69 74 73 2f 73 0a 20 20 6f 75 74 70 75 74 32  nits/s.  output2
7d00: 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32 64 20 75   [format {%12d u
7d10: 53 20 25 73 20 25 73 7d 20 24 74 6d 20 24 72 61  S %s %s} $tm $ra
7d20: 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f 62 61 6c  te $u2].  global
7d30: 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65   total_time.  se
7d40: 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20 5b 65 78  t total_time [ex
7d50: 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69 6d 65 2b  pr {$total_time+
7d60: 24 74 6d 7d 5d 0a 20 20 6c 61 70 70 65 6e 64 20  $tm}].  lappend 
7d70: 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 69  ::speed_trial_ti
7d80: 6d 65 73 20 24 6e 61 6d 65 20 24 74 6d 0a 7d 0a  mes $name $tm.}.
7d90: 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c  proc speed_trial
7da0: 5f 74 63 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73 74  _tcl {name numst
7db0: 6d 74 20 75 6e 69 74 73 20 73 63 72 69 70 74 7d  mt units script}
7dc0: 20 7b 0a 20 20 6f 75 74 70 75 74 32 20 2d 6e 6f   {.  output2 -no
7dd0: 6e 65 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74 20  newline [format 
7de0: 7b 25 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61 6d  {%-21.21s } $nam
7df0: 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73 74  e...].  flush st
7e00: 64 6f 75 74 0a 20 20 73 65 74 20 73 70 65 65 64  dout.  set speed
7e10: 20 5b 74 69 6d 65 20 7b 65 76 61 6c 20 24 73 63   [time {eval $sc
7e20: 72 69 70 74 7d 5d 0a 20 20 73 65 74 20 74 6d 20  ript}].  set tm 
7e30: 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64 20 30  [lindex $speed 0
7e40: 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d 3d 20 30  ].  if {$tm == 0
7e50: 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65  } {.    set rate
7e60: 20 5b 66 6f 72 6d 61 74 20 25 32 30 73 20 22 6d   [format %20s "m
7e70: 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73 65 20 7b  any"].  } else {
7e80: 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b 66  .    set rate [f
7e90: 6f 72 6d 61 74 20 25 32 30 2e 35 66 20 5b 65 78  ormat %20.5f [ex
7ea0: 70 72 20 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e  pr {1000000.0*$n
7eb0: 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20  umstmt/$tm}]].  
7ec0: 7d 0a 20 20 73 65 74 20 75 32 20 24 75 6e 69 74  }.  set u2 $unit
7ed0: 73 2f 73 0a 20 20 6f 75 74 70 75 74 32 20 5b 66  s/s.  output2 [f
7ee0: 6f 72 6d 61 74 20 7b 25 31 32 64 20 75 53 20 25  ormat {%12d uS %
7ef0: 73 20 25 73 7d 20 24 74 6d 20 24 72 61 74 65 20  s %s} $tm $rate 
7f00: 24 75 32 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f  $u2].  global to
7f10: 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20 74  tal_time.  set t
7f20: 6f 74 61 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20  otal_time [expr 
7f30: 7b 24 74 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d  {$total_time+$tm
7f40: 7d 5d 0a 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73  }].  lappend ::s
7f50: 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73  peed_trial_times
7f60: 20 24 6e 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f   $name $tm.}.pro
7f70: 63 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 69 6e  c speed_trial_in
7f80: 69 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c  it {name} {.  gl
7f90: 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a  obal total_time.
7fa0: 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65    set total_time
7fb0: 20 30 0a 20 20 73 65 74 20 3a 3a 73 70 65 65 64   0.  set ::speed
7fc0: 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 5b 6c 69  _trial_times [li
7fd0: 73 74 5d 0a 20 20 73 71 6c 69 74 65 33 20 76 65  st].  sqlite3 ve
7fe0: 72 73 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20  rsdb :memory:.  
7ff0: 73 65 74 20 76 65 72 73 20 5b 76 65 72 73 64 62  set vers [versdb
8000: 20 6f 6e 65 20 7b 53 45 4c 45 43 54 20 73 71 6c   one {SELECT sql
8010: 69 74 65 5f 73 6f 75 72 63 65 5f 69 64 28 29 7d  ite_source_id()}
8020: 5d 0a 20 20 76 65 72 73 64 62 20 63 6c 6f 73 65  ].  versdb close
8030: 0a 20 20 6f 75 74 70 75 74 32 20 22 53 51 4c 69  .  output2 "SQLi
8040: 74 65 20 24 76 65 72 73 22 0a 7d 0a 70 72 6f 63  te $vers".}.proc
8050: 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 73 75 6d   speed_trial_sum
8060: 6d 61 72 79 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20  mary {name} {.  
8070: 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d  global total_tim
8080: 65 0a 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72  e.  output2 [for
8090: 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 25 31  mat {%-21.21s %1
80a0: 32 64 20 75 53 20 54 4f 54 41 4c 7d 20 24 6e 61  2d uS TOTAL} $na
80b0: 6d 65 20 24 74 6f 74 61 6c 5f 74 69 6d 65 5d 0a  me $total_time].
80c0: 0a 20 20 69 66 20 7b 20 30 20 7d 20 7b 0a 20 20  .  if { 0 } {.  
80d0: 20 20 73 71 6c 69 74 65 33 20 76 65 72 73 64 62    sqlite3 versdb
80e0: 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 20 20 73 65   :memory:.    se
80f0: 74 20 76 65 72 73 20 5b 6c 69 6e 64 65 78 20 5b  t vers [lindex [
8100: 76 65 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45  versdb one {SELE
8110: 43 54 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65  CT sqlite_source
8120: 5f 69 64 28 29 7d 5d 20 30 5d 0a 20 20 20 20 76  _id()}] 0].    v
8130: 65 72 73 64 62 20 63 6c 6f 73 65 0a 20 20 20 20  ersdb close.    
8140: 6f 75 74 70 75 74 32 20 22 43 52 45 41 54 45 20  output2 "CREATE 
8150: 54 41 42 4c 45 20 49 46 20 4e 4f 54 20 45 58 49  TABLE IF NOT EXI
8160: 53 54 53 20 74 69 6d 65 28 76 65 72 73 69 6f 6e  STS time(version
8170: 2c 20 73 63 72 69 70 74 2c 20 74 65 73 74 2c 20  , script, test, 
8180: 75 73 29 3b 22 0a 20 20 20 20 66 6f 72 65 61 63  us);".    foreac
8190: 68 20 7b 74 65 73 74 20 75 73 7d 20 24 3a 3a 73  h {test us} $::s
81a0: 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73  peed_trial_times
81b0: 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32   {.      output2
81c0: 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 69   "INSERT INTO ti
81d0: 6d 65 20 56 41 4c 55 45 53 28 27 24 76 65 72 73  me VALUES('$vers
81e0: 27 2c 20 27 24 6e 61 6d 65 27 2c 20 27 24 74 65  ', '$name', '$te
81f0: 73 74 27 2c 20 24 75 73 29 3b 22 0a 20 20 20 20  st', $us);".    
8200: 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75 6e 20 74  }.  }.}..# Run t
8210: 68 69 73 20 72 6f 75 74 69 6e 65 20 6c 61 73 74  his routine last
8220: 0a 23 0a 70 72 6f 63 20 66 69 6e 69 73 68 5f 74  .#.proc finish_t
8230: 65 73 74 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68  est {} {.  catch
8240: 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61   {db close}.  ca
8250: 74 63 68 20 7b 64 62 31 20 63 6c 6f 73 65 7d 0a  tch {db1 close}.
8260: 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f    catch {db2 clo
8270: 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33  se}.  catch {db3
8280: 20 63 6c 6f 73 65 7d 0a 20 20 69 66 20 7b 30 3d   close}.  if {0=
8290: 3d 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  =[info exists ::
82a0: 53 4c 41 56 45 5d 7d 20 7b 20 66 69 6e 61 6c 69  SLAVE]} { finali
82b0: 7a 65 5f 74 65 73 74 69 6e 67 20 7d 0a 7d 0a 70  ze_testing }.}.p
82c0: 72 6f 63 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73  roc finalize_tes
82d0: 74 69 6e 67 20 7b 7d 20 7b 0a 20 20 67 6c 6f 62  ting {} {.  glob
82e0: 61 6c 20 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66  al sqlite_open_f
82f0: 69 6c 65 5f 63 6f 75 6e 74 0a 0a 20 20 73 65 74  ile_count..  set
8300: 20 6f 6d 69 74 4c 69 73 74 20 5b 73 65 74 5f 74   omitList [set_t
8310: 65 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74  est_counter omit
8320: 5f 6c 69 73 74 5d 0a 0a 20 20 63 61 74 63 68 20  _list]..  catch 
8330: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74  {db close}.  cat
8340: 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20  ch {db2 close}. 
8350: 20 63 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73   catch {db3 clos
8360: 65 7d 0a 0a 20 20 76 66 73 5f 75 6e 6c 69 6e 6b  e}..  vfs_unlink
8370: 5f 74 65 73 74 0a 20 20 73 71 6c 69 74 65 33 20  _test.  sqlite3 
8380: 64 62 20 7b 7d 0a 20 20 23 20 73 71 6c 69 74 65  db {}.  # sqlite
8390: 33 5f 63 6c 65 61 72 5f 74 73 64 5f 6d 65 6d 64  3_clear_tsd_memd
83a0: 65 62 75 67 0a 20 20 64 62 20 63 6c 6f 73 65 0a  ebug.  db close.
83b0: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 5f    sqlite3_reset_
83c0: 61 75 74 6f 5f 65 78 74 65 6e 73 69 6f 6e 0a 0a  auto_extension..
83d0: 20 20 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68    sqlite3_soft_h
83e0: 65 61 70 5f 6c 69 6d 69 74 20 30 0a 20 20 73 65  eap_limit 0.  se
83f0: 74 20 6e 54 65 73 74 20 5b 69 6e 63 72 5f 6e 74  t nTest [incr_nt
8400: 65 73 74 5d 0a 20 20 73 65 74 20 6e 45 72 72 20  est].  set nErr 
8410: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
8420: 72 20 65 72 72 6f 72 73 5d 0a 0a 20 20 73 65 74  r errors]..  set
8430: 20 6e 4b 6e 6f 77 6e 20 30 0a 20 20 69 66 20 7b   nKnown 0.  if {
8440: 5b 66 69 6c 65 20 72 65 61 64 61 62 6c 65 20 6b  [file readable k
8450: 6e 6f 77 6e 2d 70 72 6f 62 6c 65 6d 73 2e 74 78  nown-problems.tx
8460: 74 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 64  t]} {.    set fd
8470: 20 5b 6f 70 65 6e 20 6b 6e 6f 77 6e 2d 70 72 6f   [open known-pro
8480: 62 6c 65 6d 73 2e 74 78 74 5d 0a 20 20 20 20 73  blems.txt].    s
8490: 65 74 20 63 6f 6e 74 65 6e 74 20 5b 72 65 61 64  et content [read
84a0: 20 24 66 64 5d 0a 20 20 20 20 63 6c 6f 73 65 20   $fd].    close 
84b0: 24 66 64 0a 20 20 20 20 66 6f 72 65 61 63 68 20  $fd.    foreach 
84c0: 78 20 24 63 6f 6e 74 65 6e 74 20 7b 73 65 74 20  x $content {set 
84d0: 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28 24 78 29 20  known_error($x) 
84e0: 31 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 78  1}.    foreach x
84f0: 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74   [set_test_count
8500: 65 72 20 66 61 69 6c 5f 6c 69 73 74 5d 20 7b 0a  er fail_list] {.
8510: 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20        if {[info 
8520: 65 78 69 73 74 73 20 6b 6e 6f 77 6e 5f 65 72 72  exists known_err
8530: 6f 72 28 24 78 29 5d 7d 20 7b 69 6e 63 72 20 6e  or($x)]} {incr n
8540: 4b 6e 6f 77 6e 7d 0a 20 20 20 20 7d 0a 20 20 7d  Known}.    }.  }
8550: 0a 20 20 69 66 20 7b 24 6e 4b 6e 6f 77 6e 3e 30  .  if {$nKnown>0
8560: 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20  } {.    output2 
8570: 22 5b 65 78 70 72 20 7b 24 6e 45 72 72 2d 24 6e  "[expr {$nErr-$n
8580: 4b 6e 6f 77 6e 7d 5d 20 6e 65 77 20 65 72 72 6f  Known}] new erro
8590: 72 73 20 61 6e 64 20 24 6e 4b 6e 6f 77 6e 20 6b  rs and $nKnown k
85a0: 6e 6f 77 6e 20 65 72 72 6f 72 73 5c 0a 20 20 20  nown errors\.   
85b0: 20 20 20 20 20 20 6f 75 74 20 6f 66 20 24 6e 54        out of $nT
85c0: 65 73 74 20 74 65 73 74 73 22 0a 20 20 7d 20 65  est tests".  } e
85d0: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 63 70  lse {.    set cp
85e0: 75 69 6e 66 6f 20 7b 7d 0a 20 20 20 20 69 66 20  uinfo {}.    if 
85f0: 7b 5b 63 61 74 63 68 20 7b 65 78 65 63 20 68 6f  {[catch {exec ho
8600: 73 74 6e 61 6d 65 7d 20 68 6e 61 6d 65 5d 3d 3d  stname} hname]==
8610: 30 7d 20 7b 73 65 74 20 63 70 75 69 6e 66 6f 20  0} {set cpuinfo 
8620: 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 68 6e  [string trim $hn
8630: 61 6d 65 5d 7d 0a 20 20 20 20 61 70 70 65 6e 64  ame]}.    append
8640: 20 63 70 75 69 6e 66 6f 20 22 20 24 3a 3a 74 63   cpuinfo " $::tc
8650: 6c 5f 70 6c 61 74 66 6f 72 6d 28 6f 73 29 22 0a  l_platform(os)".
8660: 20 20 20 20 61 70 70 65 6e 64 20 63 70 75 69 6e      append cpuin
8670: 66 6f 20 22 20 5b 65 78 70 72 20 7b 24 3a 3a 74  fo " [expr {$::t
8680: 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6f 69 6e  cl_platform(poin
8690: 74 65 72 53 69 7a 65 29 2a 38 7d 5d 2d 62 69 74  terSize)*8}]-bit
86a0: 22 0a 20 20 20 20 61 70 70 65 6e 64 20 63 70 75  ".    append cpu
86b0: 69 6e 66 6f 20 22 20 5b 73 74 72 69 6e 67 20 6d  info " [string m
86c0: 61 70 20 7b 45 20 2d 65 7d 20 24 3a 3a 74 63 6c  ap {E -e} $::tcl
86d0: 5f 70 6c 61 74 66 6f 72 6d 28 62 79 74 65 4f 72  _platform(byteOr
86e0: 64 65 72 29 5d 22 0a 20 20 20 20 6f 75 74 70 75  der)]".    outpu
86f0: 74 32 20 22 53 51 4c 69 74 65 20 5b 73 71 6c 69  t2 "SQLite [sqli
8700: 74 65 33 20 2d 73 6f 75 72 63 65 69 64 5d 22 0a  te3 -sourceid]".
8710: 20 20 20 20 6f 75 74 70 75 74 32 20 22 24 6e 45      output2 "$nE
8720: 72 72 20 65 72 72 6f 72 73 20 6f 75 74 20 6f 66  rr errors out of
8730: 20 24 6e 54 65 73 74 20 74 65 73 74 73 20 6f 6e   $nTest tests on
8740: 20 24 63 70 75 69 6e 66 6f 22 0a 20 20 7d 0a 20   $cpuinfo".  }. 
8750: 20 69 66 20 7b 24 6e 45 72 72 3e 24 6e 4b 6e 6f   if {$nErr>$nKno
8760: 77 6e 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74  wn} {.    output
8770: 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 21 46  2 -nonewline "!F
8780: 61 69 6c 75 72 65 73 20 6f 6e 20 74 68 65 73 65  ailures on these
8790: 20 74 65 73 74 73 3a 22 0a 20 20 20 20 66 6f 72   tests:".    for
87a0: 65 61 63 68 20 78 20 5b 73 65 74 5f 74 65 73 74  each x [set_test
87b0: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
87c0: 73 74 5d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b  st] {.      if {
87d0: 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 6b 6e  ![info exists kn
87e0: 6f 77 6e 5f 65 72 72 6f 72 28 24 78 29 5d 7d 20  own_error($x)]} 
87f0: 7b 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c  {output2 -nonewl
8800: 69 6e 65 20 22 20 24 78 22 7d 0a 20 20 20 20 7d  ine " $x"}.    }
8810: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 22 0a  .    output2 "".
8820: 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 77 61    }.  foreach wa
8830: 72 6e 69 6e 67 20 5b 73 65 74 5f 74 65 73 74 5f  rning [set_test_
8840: 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73  counter warn_lis
8850: 74 5d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  t] {.    output2
8860: 20 22 57 61 72 6e 69 6e 67 3a 20 24 77 61 72 6e   "Warning: $warn
8870: 69 6e 67 22 0a 20 20 7d 0a 20 20 72 75 6e 5f 74  ing".  }.  run_t
8880: 68 72 65 61 64 5f 74 65 73 74 73 20 31 0a 20 20  hread_tests 1.  
8890: 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 6f 6d  if {[llength $om
88a0: 69 74 4c 69 73 74 5d 3e 30 7d 20 7b 0a 20 20 20  itList]>0} {.   
88b0: 20 6f 75 74 70 75 74 32 20 22 4f 6d 69 74 74 65   output2 "Omitte
88c0: 64 20 74 65 73 74 20 63 61 73 65 73 3a 22 0a 20  d test cases:". 
88d0: 20 20 20 73 65 74 20 70 72 65 63 20 7b 7d 0a 20     set prec {}. 
88e0: 20 20 20 66 6f 72 65 61 63 68 20 7b 72 65 63 7d     foreach {rec}
88f0: 20 5b 6c 73 6f 72 74 20 24 6f 6d 69 74 4c 69 73   [lsort $omitLis
8900: 74 5d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 24  t] {.      if {$
8910: 72 65 63 3d 3d 24 70 72 65 63 7d 20 63 6f 6e 74  rec==$prec} cont
8920: 69 6e 75 65 0a 20 20 20 20 20 20 73 65 74 20 70  inue.      set p
8930: 72 65 63 20 24 72 65 63 0a 20 20 20 20 20 20 6f  rec $rec.      o
8940: 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b  utput2 [format {
8950: 2e 20 20 25 2d 31 32 73 20 25 73 7d 20 5b 6c 69  .  %-12s %s} [li
8960: 6e 64 65 78 20 24 72 65 63 20 30 5d 20 5b 6c 69  ndex $rec 0] [li
8970: 6e 64 65 78 20 24 72 65 63 20 31 5d 5d 0a 20 20  ndex $rec 1]].  
8980: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e    }.  }.  if {$n
8990: 45 72 72 3e 30 20 26 26 20 21 5b 77 6f 72 6b 69  Err>0 && ![worki
89a0: 6e 67 5f 36 34 62 69 74 5f 69 6e 74 5d 7d 20 7b  ng_64bit_int]} {
89b0: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 2a 2a  .    output2 "**
89c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
89d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
89e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
89f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8a00: 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 4e  ".    output2 "N
8a10: 2e 42 2e 3a 20 20 54 68 65 20 76 65 72 73 69 6f  .B.:  The versio
8a20: 6e 20 6f 66 20 54 43 4c 20 74 68 61 74 20 79 6f  n of TCL that yo
8a30: 75 20 75 73 65 64 20 74 6f 20 62 75 69 6c 64 20  u used to build 
8a40: 74 68 69 73 20 74 65 73 74 20 68 61 72 6e 65 73  this test harnes
8a50: 73 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22  s".    output2 "
8a60: 69 73 20 64 65 66 65 63 74 69 76 65 20 69 6e 20  is defective in 
8a70: 74 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f 74  that it does not
8a80: 20 73 75 70 70 6f 72 74 20 36 34 2d 62 69 74 20   support 64-bit 
8a90: 69 6e 74 65 67 65 72 73 2e 20 20 53 6f 6d 65 20  integers.  Some 
8aa0: 6f 72 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20  or".    output2 
8ab0: 22 61 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74  "all of the test
8ac0: 20 66 61 69 6c 75 72 65 73 20 61 62 6f 76 65 20   failures above 
8ad0: 6d 69 67 68 74 20 62 65 20 61 20 72 65 73 75 6c  might be a resul
8ae0: 74 20 66 72 6f 6d 20 74 68 69 73 20 64 65 66 65  t from this defe
8af0: 63 74 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20  ct".    output2 
8b00: 22 69 6e 20 79 6f 75 72 20 54 43 4c 20 62 75 69  "in your TCL bui
8b10: 6c 64 2e 22 0a 20 20 20 20 6f 75 74 70 75 74 32  ld.".    output2
8b20: 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   "**************
8b30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8b40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8b50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8b60: 2a 2a 2a 2a 22 0a 20 20 7d 0a 20 20 69 66 20 7b  ****".  }.  if {
8b70: 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 62 69  $::cmdlinearg(bi
8b80: 6e 61 72 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20  narylog)} {.    
8b90: 76 66 73 6c 6f 67 20 66 69 6e 61 6c 69 7a 65 20  vfslog finalize 
8ba0: 62 69 6e 61 72 79 6c 6f 67 0a 20 20 7d 0a 20 20  binarylog.  }.  
8bb0: 69 66 20 7b 24 73 71 6c 69 74 65 5f 6f 70 65 6e  if {$sqlite_open
8bc0: 5f 66 69 6c 65 5f 63 6f 75 6e 74 7d 20 7b 0a 20  _file_count} {. 
8bd0: 20 20 20 6f 75 74 70 75 74 32 20 22 24 73 71 6c     output2 "$sql
8be0: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
8bf0: 75 6e 74 20 66 69 6c 65 73 20 77 65 72 65 20 6c  unt files were l
8c00: 65 66 74 20 6f 70 65 6e 22 0a 20 20 20 20 69 6e  eft open".    in
8c10: 63 72 20 6e 45 72 72 0a 20 20 7d 0a 20 20 69 66  cr nErr.  }.  if
8c20: 20 7b 5b 6c 69 6e 64 65 78 20 5b 73 71 6c 69 74   {[lindex [sqlit
8c30: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
8c40: 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43  _STATUS_MALLOC_C
8c50: 4f 55 4e 54 20 30 5d 20 31 5d 3e 30 20 7c 7c 0a  OUNT 0] 1]>0 ||.
8c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5b 73                [s
8c70: 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73  qlite3_memory_us
8c80: 65 64 5d 3e 30 7d 20 7b 0a 20 20 20 20 6f 75 74  ed]>0} {.    out
8c90: 70 75 74 32 20 22 55 6e 66 72 65 65 64 20 6d 65  put2 "Unfreed me
8ca0: 6d 6f 72 79 3a 20 5b 73 71 6c 69 74 65 33 5f 6d  mory: [sqlite3_m
8cb0: 65 6d 6f 72 79 5f 75 73 65 64 5d 20 62 79 74 65  emory_used] byte
8cc0: 73 20 69 6e 5c 0a 20 20 20 20 20 20 20 20 20 5b  s in\.         [
8cd0: 6c 69 6e 64 65 78 20 5b 73 71 6c 69 74 65 33 5f  lindex [sqlite3_
8ce0: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
8cf0: 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e  ATUS_MALLOC_COUN
8d00: 54 20 30 5d 20 31 5d 20 61 6c 6c 6f 63 61 74 69  T 0] 1] allocati
8d10: 6f 6e 73 22 0a 20 20 20 20 69 6e 63 72 20 6e 45  ons".    incr nE
8d20: 72 72 0a 20 20 20 20 69 66 63 61 70 61 62 6c 65  rr.    ifcapable
8d30: 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d 35 7c   memdebug||mem5|
8d40: 7c 28 6d 65 6d 33 26 26 64 65 62 75 67 29 20 7b  |(mem3&&debug) {
8d50: 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22  .      output2 "
8d60: 57 72 69 74 69 6e 67 20 75 6e 66 72 65 65 64 20  Writing unfreed 
8d70: 6d 65 6d 6f 72 79 20 6c 6f 67 20 74 6f 20 5c 22  memory log to \"
8d80: 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 5c 22 22  ./memleak.txt\""
8d90: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
8da0: 65 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f 6d  emdebug_dump ./m
8db0: 65 6d 6c 65 61 6b 2e 74 78 74 0a 20 20 20 20 7d  emleak.txt.    }
8dc0: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
8dd0: 6f 75 74 70 75 74 32 20 22 41 6c 6c 20 6d 65 6d  output2 "All mem
8de0: 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20  ory allocations 
8df0: 66 72 65 65 64 20 2d 20 6e 6f 20 6c 65 61 6b 73  freed - no leaks
8e00: 22 0a 20 20 20 20 69 66 63 61 70 61 62 6c 65 20  ".    ifcapable 
8e10: 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d 35 20 7b  memdebug||mem5 {
8e20: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
8e30: 65 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f 6d  emdebug_dump ./m
8e40: 65 6d 75 73 61 67 65 2e 74 78 74 0a 20 20 20 20  emusage.txt.    
8e50: 7d 0a 20 20 7d 0a 20 20 73 68 6f 77 5f 6d 65 6d  }.  }.  show_mem
8e60: 73 74 61 74 73 0a 20 20 6f 75 74 70 75 74 32 20  stats.  output2 
8e70: 22 4d 61 78 69 6d 75 6d 20 6d 65 6d 6f 72 79 20  "Maximum memory 
8e80: 75 73 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f  usage: [sqlite3_
8e90: 6d 65 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72  memory_highwater
8ea0: 20 31 5d 20 62 79 74 65 73 22 0a 20 20 6f 75 74   1] bytes".  out
8eb0: 70 75 74 32 20 22 43 75 72 72 65 6e 74 20 6d 65  put2 "Current me
8ec0: 6d 6f 72 79 20 75 73 61 67 65 3a 20 5b 73 71 6c  mory usage: [sql
8ed0: 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 68 69 67 68  ite3_memory_high
8ee0: 77 61 74 65 72 5d 20 62 79 74 65 73 22 0a 20 20  water] bytes".  
8ef0: 69 66 20 7b 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e  if {[info comman
8f00: 64 73 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65  ds sqlite3_memde
8f10: 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74  bug_malloc_count
8f20: 5d 20 6e 65 20 22 22 7d 20 7b 0a 20 20 20 20 6f  ] ne ""} {.    o
8f30: 75 74 70 75 74 32 20 22 4e 75 6d 62 65 72 20 6f  utput2 "Number o
8f40: 66 20 6d 61 6c 6c 6f 63 28 29 20 20 3a 20 5b 73  f malloc()  : [s
8f50: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
8f60: 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20 63 61  malloc_count] ca
8f70: 6c 6c 73 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24  lls".  }.  if {$
8f80: 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c  ::cmdlinearg(mal
8f90: 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20 20 20  loctrace)} {.   
8fa0: 20 6f 75 74 70 75 74 32 20 22 57 72 69 74 69 6e   output2 "Writin
8fb0: 67 20 6d 61 6c 6c 6f 63 73 2e 73 71 6c 2e 2e 2e  g mallocs.sql...
8fc0: 22 0a 20 20 20 20 6d 65 6d 64 65 62 75 67 5f 6c  ".    memdebug_l
8fd0: 6f 67 5f 73 71 6c 0a 20 20 20 20 73 71 6c 69 74  og_sql.    sqlit
8fe0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20  e3_memdebug_log 
8ff0: 73 74 6f 70 0a 20 20 20 20 73 71 6c 69 74 65 33  stop.    sqlite3
9000: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 63 6c  _memdebug_log cl
9010: 65 61 72 0a 0a 20 20 20 20 69 66 20 7b 5b 73 71  ear..    if {[sq
9020: 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65  lite3_memory_use
9030: 64 5d 3e 30 7d 20 7b 0a 20 20 20 20 20 20 6f 75  d]>0} {.      ou
9040: 74 70 75 74 32 20 22 57 72 69 74 69 6e 67 20 6c  tput2 "Writing l
9050: 65 61 6b 73 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20  eaks.sql...".   
9060: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
9070: 62 75 67 5f 6c 6f 67 20 73 79 6e 63 0a 20 20 20  bug_log sync.   
9080: 20 20 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f     memdebug_log_
9090: 73 71 6c 20 6c 65 61 6b 73 2e 73 71 6c 0a 20 20  sql leaks.sql.  
90a0: 20 20 7d 0a 20 20 7d 0a 20 20 63 61 74 63 68 20    }.  }.  catch 
90b0: 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66 20  {.    foreach f 
90c0: 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69  [glob -nocomplai
90d0: 6e 20 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75 72  n test.db-*-jour
90e0: 6e 61 6c 5d 20 7b 0a 20 20 20 20 20 20 66 6f 72  nal] {.      for
90f0: 63 65 64 65 6c 65 74 65 20 24 66 0a 20 20 20 20  cedelete $f.    
9100: 7d 0a 20 20 7d 0a 20 20 63 61 74 63 68 20 7b 0a  }.  }.  catch {.
9110: 20 20 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67      foreach f [g
9120: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
9130: 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d 20 7b 0a 20  test.db-mj*] {. 
9140: 20 20 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65       forcedelete
9150: 20 24 66 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   $f.    }.  }.  
9160: 65 78 69 74 20 5b 65 78 70 72 20 7b 24 6e 45 72  exit [expr {$nEr
9170: 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 44 69 73 70 6c  r>0}].}..# Displ
9180: 61 79 20 6d 65 6d 6f 72 79 20 73 74 61 74 69 73  ay memory statis
9190: 74 69 63 73 20 66 6f 72 20 61 6e 61 6c 79 73 69  tics for analysi
91a0: 73 20 61 6e 64 20 64 65 62 75 67 67 69 6e 67 20  s and debugging 
91b0: 70 75 72 70 6f 73 65 73 2e 0a 23 0a 70 72 6f 63  purposes..#.proc
91c0: 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73 20 7b   show_memstats {
91d0: 7d 20 7b 0a 20 20 73 65 74 20 78 20 5b 73 71 6c  } {.  set x [sql
91e0: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
91f0: 54 45 5f 53 54 41 54 55 53 5f 4d 45 4d 4f 52 59  TE_STATUS_MEMORY
9200: 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20 79  _USED 0].  set y
9210: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
9220: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d   SQLITE_STATUS_M
9230: 41 4c 4c 4f 43 5f 53 49 5a 45 20 30 5d 0a 20 20  ALLOC_SIZE 0].  
9240: 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20  set val [format 
9250: 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25  {now %10d  max %
9260: 31 30 64 20 20 6d 61 78 2d 73 69 7a 65 20 25 31  10d  max-size %1
9270: 30 64 7d 20 5c 0a 20 20 20 20 20 20 20 20 20 20  0d} \.          
9280: 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 78 20 31      [lindex $x 1
9290: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 20  ] [lindex $x 2] 
92a0: 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20  [lindex $y 2]]. 
92b0: 20 6f 75 74 70 75 74 31 20 22 4d 65 6d 6f 72 79   output1 "Memory
92c0: 20 75 73 65 64 3a 20 20 20 20 20 20 20 20 20 20   used:          
92d0: 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73  $val".  set x [s
92e0: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
92f0: 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c  LITE_STATUS_MALL
9300: 4f 43 5f 43 4f 55 4e 54 20 30 5d 0a 20 20 73 65  OC_COUNT 0].  se
9310: 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e  t val [format {n
9320: 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31 30  ow %10d  max %10
9330: 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d  d} [lindex $x 1]
9340: 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a   [lindex $x 2]].
9350: 20 20 6f 75 74 70 75 74 31 20 22 41 6c 6c 6f 63    output1 "Alloc
9360: 61 74 69 6f 6e 20 63 6f 75 6e 74 3a 20 20 20 20  ation count:    
9370: 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b   $val".  set x [
9380: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
9390: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
93a0: 45 43 41 43 48 45 5f 55 53 45 44 20 30 5d 0a 20  ECACHE_USED 0]. 
93b0: 20 73 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f   set y [sqlite3_
93c0: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
93d0: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53  ATUS_PAGECACHE_S
93e0: 49 5a 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c  IZE 0].  set val
93f0: 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31   [format {now %1
9400: 30 64 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61  0d  max %10d  ma
9410: 78 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20  x-size %10d} \. 
9420: 20 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69               [li
9430: 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64  ndex $x 1] [lind
9440: 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78  ex $x 2] [lindex
9450: 20 24 79 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74   $y 2]].  output
9460: 31 20 22 50 61 67 65 2d 63 61 63 68 65 20 75 73  1 "Page-cache us
9470: 65 64 3a 20 20 20 20 20 20 24 76 61 6c 22 0a 20  ed:      $val". 
9480: 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f   set x [sqlite3_
9490: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
94a0: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f  ATUS_PAGECACHE_O
94b0: 56 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73 65 74  VERFLOW 0].  set
94c0: 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f   val [format {no
94d0: 77 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64  w %10d  max %10d
94e0: 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20  } [lindex $x 1] 
94f0: 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20  [lindex $x 2]]. 
9500: 20 6f 75 74 70 75 74 31 20 22 50 61 67 65 2d 63   output1 "Page-c
9510: 61 63 68 65 20 6f 76 65 72 66 6c 6f 77 3a 20 20  ache overflow:  
9520: 24 76 61 6c 22 0a 20 20 69 66 63 61 70 61 62 6c  $val".  ifcapabl
9530: 65 20 79 79 74 72 61 63 6b 6d 61 78 73 74 61 63  e yytrackmaxstac
9540: 6b 64 65 70 74 68 20 7b 0a 20 20 20 20 73 65 74  kdepth {.    set
9550: 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   x [sqlite3_stat
9560: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
9570: 5f 50 41 52 53 45 52 5f 53 54 41 43 4b 20 30 5d  _PARSER_STACK 0]
9580: 0a 20 20 20 20 73 65 74 20 76 61 6c 20 5b 66 6f  .    set val [fo
9590: 72 6d 61 74 20 7b 20 20 20 20 20 20 20 20 20 20  rmat {          
95a0: 20 20 20 20 20 6d 61 78 20 25 31 30 64 7d 20 5b       max %10d} [
95b0: 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20  lindex $x 2]].  
95c0: 20 20 6f 75 74 70 75 74 32 20 22 50 61 72 73 65    output2 "Parse
95d0: 72 20 73 74 61 63 6b 20 64 65 70 74 68 3a 20 20  r stack depth:  
95e0: 20 20 24 76 61 6c 22 0a 20 20 7d 0a 7d 0a 0a 23    $val".  }.}..#
95f0: 20 41 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20   A procedure to 
9600: 65 78 65 63 75 74 65 20 53 51 4c 0a 23 0a 70 72  execute SQL.#.pr
9610: 6f 63 20 65 78 65 63 73 71 6c 20 7b 73 71 6c 20  oc execsql {sql 
9620: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70  {db db}} {.  # p
9630: 75 74 73 20 22 53 51 4c 20 3d 20 24 73 71 6c 22  uts "SQL = $sql"
9640: 0a 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74  .  uplevel [list
9650: 20 24 64 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a   $db eval $sql].
9660: 7d 0a 70 72 6f 63 20 65 78 65 63 73 71 6c 5f 74  }.proc execsql_t
9670: 69 6d 65 64 20 7b 73 71 6c 20 7b 64 62 20 64 62  imed {sql {db db
9680: 7d 7d 20 7b 0a 20 20 73 65 74 20 74 6d 20 5b 74  }} {.  set tm [t
9690: 69 6d 65 20 7b 0a 20 20 20 20 73 65 74 20 78 20  ime {.    set x 
96a0: 5b 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24  [uplevel [list $
96b0: 64 62 20 65 76 61 6c 20 24 73 71 6c 5d 5d 0a 20  db eval $sql]]. 
96c0: 20 7d 20 31 5d 0a 20 20 73 65 74 20 74 6d 20 5b   } 1].  set tm [
96d0: 6c 69 6e 64 65 78 20 24 74 6d 20 30 5d 0a 20 20  lindex $tm 0].  
96e0: 6f 75 74 70 75 74 31 20 2d 6e 6f 6e 65 77 6c 69  output1 -nonewli
96f0: 6e 65 20 22 20 28 5b 65 78 70 72 20 7b 24 74 6d  ne " ([expr {$tm
9700: 2a 30 2e 30 30 31 7d 5d 6d 73 29 20 22 0a 20 20  *0.001}]ms) ".  
9710: 73 65 74 20 78 0a 7d 0a 0a 23 20 45 78 65 63 75  set x.}..# Execu
9720: 74 65 20 53 51 4c 20 61 6e 64 20 63 61 74 63 68  te SQL and catch
9730: 20 65 78 63 65 70 74 69 6f 6e 73 2e 0a 23 0a 70   exceptions..#.p
9740: 72 6f 63 20 63 61 74 63 68 73 71 6c 20 7b 73 71  roc catchsql {sq
9750: 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 23  l {db db}} {.  #
9760: 20 70 75 74 73 20 22 53 51 4c 20 3d 20 24 73 71   puts "SQL = $sq
9770: 6c 22 0a 20 20 73 65 74 20 72 20 5b 63 61 74 63  l".  set r [catc
9780: 68 20 5b 6c 69 73 74 20 75 70 6c 65 76 65 6c 20  h [list uplevel 
9790: 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c 20 24  [list $db eval $
97a0: 73 71 6c 5d 5d 20 6d 73 67 5d 0a 20 20 6c 61 70  sql]] msg].  lap
97b0: 70 65 6e 64 20 72 20 24 6d 73 67 0a 20 20 72 65  pend r $msg.  re
97c0: 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20  turn $r.}..# Do 
97d0: 61 6e 20 56 44 42 45 20 63 6f 64 65 20 64 75 6d  an VDBE code dum
97e0: 70 20 6f 6e 20 74 68 65 20 53 51 4c 20 67 69 76  p on the SQL giv
97f0: 65 6e 0a 23 0a 70 72 6f 63 20 65 78 70 6c 61 69  en.#.proc explai
9800: 6e 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20  n {sql {db db}} 
9810: 7b 0a 20 20 6f 75 74 70 75 74 32 20 22 22 0a 20  {.  output2 "". 
9820: 20 6f 75 74 70 75 74 32 20 22 61 64 64 72 20 20   output2 "addr  
9830: 6f 70 63 6f 64 65 20 20 20 20 20 20 20 20 70 31  opcode        p1
9840: 20 20 20 20 20 20 70 32 20 20 20 20 20 20 70 33        p2      p3
9850: 20 20 20 20 20 20 70 34 20 20 20 20 20 20 20 20        p4        
9860: 20 20 20 20 20 20 20 70 35 20 20 23 22 0a 20 20         p5  #".  
9870: 6f 75 74 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d  output2 "----  -
9880: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  -----------  ---
9890: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
98a0: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ---  -----------
98b0: 2d 2d 2d 2d 20 20 2d 2d 20 20 2d 22 0a 20 20 24  ----  --  -".  $
98c0: 64 62 20 65 76 61 6c 20 22 65 78 70 6c 61 69 6e  db eval "explain
98d0: 20 24 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20   $sql" {} {.    
98e0: 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20  output2 [format 
98f0: 7b 25 2d 34 64 20 20 25 2d 31 32 2e 31 32 73 20  {%-4d  %-12.12s 
9900: 20 25 2d 36 64 20 20 25 2d 36 64 20 20 25 2d 36   %-6d  %-6d  %-6
9910: 64 20 20 25 20 2d 31 37 73 20 25 73 20 20 25 73  d  % -17s %s  %s
9920: 7d 20 5c 0a 20 20 20 20 20 20 24 61 64 64 72 20  } \.      $addr 
9930: 24 6f 70 63 6f 64 65 20 24 70 31 20 24 70 32 20  $opcode $p1 $p2 
9940: 24 70 33 20 24 70 34 20 24 70 35 20 24 63 6f 6d  $p3 $p4 $p5 $com
9950: 6d 65 6e 74 0a 20 20 20 20 5d 0a 20 20 7d 0a 7d  ment.    ].  }.}
9960: 0a 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 5f 69  ..proc explain_i
9970: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
9980: 0a 20 20 6f 75 74 70 75 74 32 20 22 22 0a 20 20  .  output2 "".  
9990: 6f 75 74 70 75 74 32 20 22 61 64 64 72 20 20 6f  output2 "addr  o
99a0: 70 63 6f 64 65 20 20 20 20 20 20 20 20 70 31 20  pcode        p1 
99b0: 20 20 20 20 20 70 32 20 20 20 20 20 20 70 33 20       p2      p3 
99c0: 20 20 20 20 20 70 34 20 20 20 20 20 20 20 20 20       p4         
99d0: 20 20 20 20 20 20 20 70 35 20 20 23 22 0a 20 20         p5  #".  
99e0: 6f 75 74 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d  output2 "----  -
99f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  -----------  ---
9a00: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
9a10: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ---  -----------
9a20: 2d 2d 2d 2d 2d 20 20 2d 2d 20 20 2d 22 0a 0a 0a  -----  --  -"...
9a30: 20 20 23 20 53 65 74 20 75 70 20 63 6f 6c 6f 72    # Set up color
9a40: 73 20 66 6f 72 20 74 68 65 20 64 69 66 66 65 72  s for the differ
9a50: 65 6e 74 20 6f 70 63 6f 64 65 73 2e 20 53 63 68  ent opcodes. Sch
9a60: 65 6d 65 20 69 73 20 61 73 20 66 6f 6c 6c 6f 77  eme is as follow
9a70: 73 3a 0a 20 20 23 0a 20 20 23 20 20 20 52 65 64  s:.  #.  #   Red
9a80: 3a 20 20 20 4f 70 63 6f 64 65 73 20 74 68 61 74  :   Opcodes that
9a90: 20 77 72 69 74 65 20 74 6f 20 61 20 62 2d 74 72   write to a b-tr
9aa0: 65 65 2e 0a 20 20 23 20 20 20 42 6c 75 65 3a 20  ee..  #   Blue: 
9ab0: 20 4f 70 63 6f 64 65 73 20 74 68 61 74 20 72 65   Opcodes that re
9ac0: 70 6f 73 69 74 69 6f 6e 20 6f 72 20 73 65 65 6b  position or seek
9ad0: 20 61 20 63 75 72 73 6f 72 2e 20 0a 20 20 23 20   a cursor. .  # 
9ae0: 20 20 47 72 65 65 6e 3a 20 54 68 65 20 52 65 73    Green: The Res
9af0: 75 6c 74 52 6f 77 20 6f 70 63 6f 64 65 2e 0a 20  ultRow opcode.. 
9b00: 20 23 0a 20 20 69 66 20 7b 20 5b 63 61 74 63 68   #.  if { [catch
9b10: 20 7b 66 63 6f 6e 66 69 67 75 72 65 20 73 74 64   {fconfigure std
9b20: 6f 75 74 20 2d 6d 6f 64 65 7d 5d 3d 3d 30 20 7d  out -mode}]==0 }
9b30: 20 7b 0a 20 20 20 20 73 65 74 20 52 20 22 5c 30   {.    set R "\0
9b40: 33 33 5c 5b 33 31 3b 31 6d 22 20 20 20 20 20 20  33\[31;1m"      
9b50: 20 20 3b 23 20 52 65 64 20 66 67 0a 20 20 20 20    ;# Red fg.    
9b60: 73 65 74 20 47 20 22 5c 30 33 33 5c 5b 33 32 3b  set G "\033\[32;
9b70: 31 6d 22 20 20 20 20 20 20 20 20 3b 23 20 47 72  1m"        ;# Gr
9b80: 65 65 6e 20 66 67 0a 20 20 20 20 73 65 74 20 42  een fg.    set B
9b90: 20 22 5c 30 33 33 5c 5b 33 34 3b 31 6d 22 20 20   "\033\[34;1m"  
9ba0: 20 20 20 20 20 20 3b 23 20 52 65 64 20 66 67 0a        ;# Red fg.
9bb0: 20 20 20 20 73 65 74 20 44 20 22 5c 30 33 33 5c      set D "\033\
9bc0: 5b 33 39 3b 30 6d 22 20 20 20 20 20 20 20 20 3b  [39;0m"        ;
9bd0: 23 20 44 65 66 61 75 6c 74 20 66 67 0a 20 20 7d  # Default fg.  }
9be0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
9bf0: 52 20 22 22 0a 20 20 20 20 73 65 74 20 47 20 22  R "".    set G "
9c00: 22 0a 20 20 20 20 73 65 74 20 42 20 22 22 0a 20  ".    set B "". 
9c10: 20 20 20 73 65 74 20 44 20 22 22 0a 20 20 7d 0a     set D "".  }.
9c20: 20 20 66 6f 72 65 61 63 68 20 6f 70 63 6f 64 65    foreach opcode
9c30: 20 7b 0a 20 20 20 20 20 20 53 65 65 6b 20 53 65   {.      Seek Se
9c40: 65 6b 47 45 20 53 65 65 6b 47 54 20 53 65 65 6b  ekGE SeekGT Seek
9c50: 4c 45 20 53 65 65 6b 4c 54 20 4e 6f 74 46 6f 75  LE SeekLT NotFou
9c60: 6e 64 20 4c 61 73 74 20 52 65 77 69 6e 64 0a 20  nd Last Rewind. 
9c70: 20 20 20 20 20 4e 6f 43 6f 6e 66 6c 69 63 74 20       NoConflict 
9c80: 4e 65 78 74 20 50 72 65 76 20 56 4e 65 78 74 20  Next Prev VNext 
9c90: 56 50 72 65 76 20 56 46 69 6c 74 65 72 0a 20 20  VPrev VFilter.  
9ca0: 20 20 20 20 53 6f 72 74 65 72 53 6f 72 74 20 53      SorterSort S
9cb0: 6f 72 74 65 72 4e 65 78 74 20 4e 65 78 74 49 66  orterNext NextIf
9cc0: 4f 70 65 6e 0a 20 20 7d 20 7b 0a 20 20 20 20 73  Open.  } {.    s
9cd0: 65 74 20 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65  et color($opcode
9ce0: 29 20 24 42 0a 20 20 7d 0a 20 20 66 6f 72 65 61  ) $B.  }.  forea
9cf0: 63 68 20 6f 70 63 6f 64 65 20 7b 52 65 73 75 6c  ch opcode {Resul
9d00: 74 52 6f 77 7d 20 7b 0a 20 20 20 20 73 65 74 20  tRow} {.    set 
9d10: 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 24  color($opcode) $
9d20: 47 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  G.  }.  foreach 
9d30: 6f 70 63 6f 64 65 20 7b 49 64 78 49 6e 73 65 72  opcode {IdxInser
9d40: 74 20 49 6e 73 65 72 74 20 44 65 6c 65 74 65 20  t Insert Delete 
9d50: 49 64 78 44 65 6c 65 74 65 7d 20 7b 0a 20 20 20  IdxDelete} {.   
9d60: 20 73 65 74 20 63 6f 6c 6f 72 28 24 6f 70 63 6f   set color($opco
9d70: 64 65 29 20 24 52 0a 20 20 7d 0a 0a 20 20 73 65  de) $R.  }..  se
9d80: 74 20 62 53 65 65 6e 47 6f 74 6f 20 30 0a 20 20  t bSeenGoto 0.  
9d90: 24 64 62 20 65 76 61 6c 20 22 65 78 70 6c 61 69  $db eval "explai
9da0: 6e 20 24 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20  n $sql" {} {.   
9db0: 20 73 65 74 20 78 28 24 61 64 64 72 29 20 30 0a   set x($addr) 0.
9dc0: 20 20 20 20 73 65 74 20 6f 70 28 24 61 64 64 72      set op($addr
9dd0: 29 20 24 6f 70 63 6f 64 65 0a 0a 20 20 20 20 69  ) $opcode..    i
9de0: 66 20 7b 24 6f 70 63 6f 64 65 20 3d 3d 20 22 47  f {$opcode == "G
9df0: 6f 74 6f 22 20 26 26 20 28 24 62 53 65 65 6e 47  oto" && ($bSeenG
9e00: 6f 74 6f 3d 3d 30 20 7c 7c 20 28 24 70 32 20 3e  oto==0 || ($p2 >
9e10: 20 24 61 64 64 72 2b 31 30 29 29 7d 20 7b 0a 20   $addr+10))} {. 
9e20: 20 20 20 20 20 73 65 74 20 6c 69 6e 65 62 72 65       set linebre
9e30: 61 6b 28 24 70 32 29 20 31 0a 20 20 20 20 20 20  ak($p2) 1.      
9e40: 73 65 74 20 62 53 65 65 6e 47 6f 74 6f 20 31 0a  set bSeenGoto 1.
9e50: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24      }..    if {$
9e60: 6f 70 63 6f 64 65 3d 3d 22 4f 6e 63 65 22 7d 20  opcode=="Once"} 
9e70: 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74  {.      for {set
9e80: 20 69 20 24 61 64 64 72 7d 20 7b 24 69 3c 24 70   i $addr} {$i<$p
9e90: 32 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  2} {incr i} {.  
9ea0: 20 20 20 20 20 20 73 65 74 20 73 74 61 72 28 24        set star($
9eb0: 69 29 20 24 61 64 64 72 0a 20 20 20 20 20 20 7d  i) $addr.      }
9ec0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b  .    }..    if {
9ed0: 24 6f 70 63 6f 64 65 3d 3d 22 4e 65 78 74 22 20  $opcode=="Next" 
9ee0: 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22 50 72   || $opcode=="Pr
9ef0: 65 76 22 20 0a 20 20 20 20 20 7c 7c 20 24 6f 70  ev" .     || $op
9f00: 63 6f 64 65 3d 3d 22 56 4e 65 78 74 22 20 7c 7c  code=="VNext" ||
9f10: 20 24 6f 70 63 6f 64 65 3d 3d 22 56 50 72 65 76   $opcode=="VPrev
9f20: 22 0a 20 20 20 20 20 7c 7c 20 24 6f 70 63 6f 64  ".     || $opcod
9f30: 65 3d 3d 22 53 6f 72 74 65 72 4e 65 78 74 22 20  e=="SorterNext" 
9f40: 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22 4e 65 78  || $opcode=="Nex
9f50: 74 49 66 4f 70 65 6e 22 0a 20 20 20 20 7d 20 7b  tIfOpen".    } {
9f60: 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20  .      for {set 
9f70: 69 20 24 70 32 7d 20 7b 24 69 3c 24 61 64 64 72  i $p2} {$i<$addr
9f80: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
9f90: 20 20 20 20 20 69 6e 63 72 20 78 28 24 69 29 20       incr x($i) 
9fa0: 32 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  2.      }.    }.
9fb0: 0a 20 20 20 20 69 66 20 7b 24 6f 70 63 6f 64 65  .    if {$opcode
9fc0: 20 3d 3d 20 22 47 6f 74 6f 22 20 26 26 20 24 70   == "Goto" && $p
9fd0: 32 3c 24 61 64 64 72 20 26 26 20 24 6f 70 28 24  2<$addr && $op($
9fe0: 70 32 29 3d 3d 22 59 69 65 6c 64 22 7d 20 7b 0a  p2)=="Yield"} {.
9ff0: 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69        for {set i
a000: 20 5b 65 78 70 72 20 24 70 32 2b 31 5d 7d 20 7b   [expr $p2+1]} {
a010: 24 69 3c 24 61 64 64 72 7d 20 7b 69 6e 63 72 20  $i<$addr} {incr 
a020: 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 69 6e 63  i} {.        inc
a030: 72 20 78 28 24 69 29 20 32 0a 20 20 20 20 20 20  r x($i) 2.      
a040: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20  }.    }..    if 
a050: 7b 24 6f 70 63 6f 64 65 20 3d 3d 20 22 48 61 6c  {$opcode == "Hal
a060: 74 22 20 26 26 20 24 63 6f 6d 6d 65 6e 74 20 3d  t" && $comment =
a070: 3d 20 22 45 6e 64 20 6f 66 20 63 6f 72 6f 75 74  = "End of corout
a080: 69 6e 65 22 7d 20 7b 0a 20 20 20 20 20 20 73 65  ine"} {.      se
a090: 74 20 6c 69 6e 65 62 72 65 61 6b 28 5b 65 78 70  t linebreak([exp
a0a0: 72 20 24 61 64 64 72 2b 31 5d 29 20 31 0a 20 20  r $addr+1]) 1.  
a0b0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 24 64 62 20 65    }.  }..  $db e
a0c0: 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73 71  val "explain $sq
a0d0: 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 69 66 20 7b  l" {} {.    if {
a0e0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 6c 69 6e  [info exists lin
a0f0: 65 62 72 65 61 6b 28 24 61 64 64 72 29 5d 7d 20  ebreak($addr)]} 
a100: 7b 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32 20  {.      output2 
a110: 22 22 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74  "".    }.    set
a120: 20 49 20 5b 73 74 72 69 6e 67 20 72 65 70 65 61   I [string repea
a130: 74 20 22 20 22 20 24 78 28 24 61 64 64 72 29 5d  t " " $x($addr)]
a140: 0a 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  ..    if {[info 
a150: 65 78 69 73 74 73 20 73 74 61 72 28 24 61 64 64  exists star($add
a160: 72 29 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  r)]} {.      set
a170: 20 69 69 20 5b 65 78 70 72 20 24 78 28 24 73 74   ii [expr $x($st
a180: 61 72 28 24 61 64 64 72 29 29 5d 0a 20 20 20 20  ar($addr))].    
a190: 20 20 61 70 70 65 6e 64 20 49 20 22 20 20 22 0a    append I "  ".
a1a0: 20 20 20 20 20 20 73 65 74 20 49 20 5b 73 74 72        set I [str
a1b0: 69 6e 67 20 72 65 70 6c 61 63 65 20 24 49 20 24  ing replace $I $
a1c0: 69 69 20 24 69 69 20 2a 5d 0a 20 20 20 20 7d 0a  ii $ii *].    }.
a1d0: 0a 20 20 20 20 73 65 74 20 63 6f 6c 20 22 22 0a  .    set col "".
a1e0: 20 20 20 20 63 61 74 63 68 20 7b 20 73 65 74 20      catch { set 
a1f0: 63 6f 6c 20 24 63 6f 6c 6f 72 28 24 6f 70 63 6f  col $color($opco
a200: 64 65 29 20 7d 0a 0a 20 20 20 20 6f 75 74 70 75  de) }..    outpu
a210: 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64  t2 [format {%-4d
a220: 20 20 25 73 25 73 25 2d 31 32 2e 31 32 73 25 73    %s%s%-12.12s%s
a230: 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20 25 2d    %-6d  %-6d  %-
a240: 36 64 20 20 25 20 2d 31 37 73 20 25 73 20 20 25  6d  % -17s %s  %
a250: 73 7d 20 5c 0a 20 20 20 20 20 20 24 61 64 64 72  s} \.      $addr
a260: 20 24 49 20 24 63 6f 6c 20 24 6f 70 63 6f 64 65   $I $col $opcode
a270: 20 24 44 20 24 70 31 20 24 70 32 20 24 70 33 20   $D $p1 $p2 $p3 
a280: 24 70 34 20 24 70 35 20 24 63 6f 6d 6d 65 6e 74  $p4 $p5 $comment
a290: 0a 20 20 20 20 5d 0a 20 20 7d 0a 20 20 6f 75 74  .    ].  }.  out
a2a0: 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d  put2 "----  ----
a2b0: 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  --------  ------
a2c0: 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d    ------  ------
a2d0: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
a2e0: 2d 2d 20 20 2d 2d 20 20 2d 22 0a 7d 0a 0a 23 20  --  --  -".}..# 
a2f0: 53 68 6f 77 20 74 68 65 20 56 44 42 45 20 70 72  Show the VDBE pr
a300: 6f 67 72 61 6d 20 66 6f 72 20 61 6e 20 53 51 4c  ogram for an SQL
a310: 20 73 74 61 74 65 6d 65 6e 74 20 62 75 74 20 6f   statement but o
a320: 6d 69 74 20 74 68 65 20 54 72 61 63 65 0a 23 20  mit the Trace.# 
a330: 6f 70 63 6f 64 65 20 61 74 20 74 68 65 20 62 65  opcode at the be
a340: 67 69 6e 6e 69 6e 67 2e 20 20 54 68 69 73 20 70  ginning.  This p
a350: 72 6f 63 65 64 75 72 65 20 63 61 6e 20 62 65 20  rocedure can be 
a360: 75 73 65 64 20 74 6f 20 70 72 6f 76 65 0a 23 20  used to prove.# 
a370: 74 68 61 74 20 64 69 66 66 65 72 65 6e 74 20 53  that different S
a380: 51 4c 20 73 74 61 74 65 6d 65 6e 74 73 20 67 65  QL statements ge
a390: 6e 65 72 61 74 65 20 65 78 61 63 74 6c 79 20 74  nerate exactly t
a3a0: 68 65 20 73 61 6d 65 20 56 44 42 45 20 63 6f 64  he same VDBE cod
a3b0: 65 2e 0a 23 0a 70 72 6f 63 20 65 78 70 6c 61 69  e..#.proc explai
a3c0: 6e 5f 6e 6f 5f 74 72 61 63 65 20 7b 73 71 6c 7d  n_no_trace {sql}
a3d0: 20 7b 0a 20 20 73 65 74 20 74 72 20 5b 64 62 20   {.  set tr [db 
a3e0: 65 76 61 6c 20 22 45 58 50 4c 41 49 4e 20 24 73  eval "EXPLAIN $s
a3f0: 71 6c 22 5d 0a 20 20 72 65 74 75 72 6e 20 5b 6c  ql"].  return [l
a400: 72 61 6e 67 65 20 24 74 72 20 37 20 65 6e 64 5d  range $tr 7 end]
a410: 0a 7d 0a 0a 23 20 41 6e 6f 74 68 65 72 20 70 72  .}..# Another pr
a420: 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65 63 75  ocedure to execu
a430: 74 65 20 53 51 4c 2e 20 20 54 68 69 73 20 6f 6e  te SQL.  This on
a440: 65 20 69 6e 63 6c 75 64 65 73 20 74 68 65 20 66  e includes the f
a450: 69 65 6c 64 0a 23 20 6e 61 6d 65 73 20 69 6e 20  ield.# names in 
a460: 74 68 65 20 72 65 74 75 72 6e 65 64 20 6c 69 73  the returned lis
a470: 74 2e 0a 23 0a 70 72 6f 63 20 65 78 65 63 73 71  t..#.proc execsq
a480: 6c 32 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74  l2 {sql} {.  set
a490: 20 72 65 73 75 6c 74 20 7b 7d 0a 20 20 64 62 20   result {}.  db 
a4a0: 65 76 61 6c 20 24 73 71 6c 20 64 61 74 61 20 7b  eval $sql data {
a4b0: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66 20 24  .    foreach f $
a4c0: 64 61 74 61 28 2a 29 20 7b 0a 20 20 20 20 20 20  data(*) {.      
a4d0: 6c 61 70 70 65 6e 64 20 72 65 73 75 6c 74 20 24  lappend result $
a4e0: 66 20 24 64 61 74 61 28 24 66 29 0a 20 20 20 20  f $data($f).    
a4f0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  }.  }.  return $
a500: 72 65 73 75 6c 74 0a 7d 0a 0a 23 20 55 73 65 20  result.}..# Use 
a510: 61 20 74 65 6d 70 6f 72 61 72 79 20 69 6e 2d 6d  a temporary in-m
a520: 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 20 74  emory database t
a530: 6f 20 65 78 65 63 75 74 65 20 53 51 4c 20 73 74  o execute SQL st
a540: 61 74 65 6d 65 6e 74 73 0a 23 0a 70 72 6f 63 20  atements.#.proc 
a550: 6d 65 6d 64 62 73 71 6c 20 7b 73 71 6c 7d 20 7b  memdbsql {sql} {
a560: 0a 20 20 73 71 6c 69 74 65 33 20 6d 65 6d 64 62  .  sqlite3 memdb
a570: 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 73 65 74 20   :memory:.  set 
a580: 72 65 73 75 6c 74 20 5b 6d 65 6d 64 62 20 65 76  result [memdb ev
a590: 61 6c 20 24 73 71 6c 5d 0a 20 20 6d 65 6d 64 62  al $sql].  memdb
a5a0: 20 63 6c 6f 73 65 0a 20 20 72 65 74 75 72 6e 20   close.  return 
a5b0: 24 72 65 73 75 6c 74 0a 7d 0a 0a 23 20 55 73 65  $result.}..# Use
a5c0: 20 74 68 65 20 6e 6f 6e 2d 63 61 6c 6c 62 61 63   the non-callbac
a5d0: 6b 20 41 50 49 20 74 6f 20 65 78 65 63 75 74 65  k API to execute
a5e0: 20 6d 75 6c 74 69 70 6c 65 20 53 51 4c 20 73 74   multiple SQL st
a5f0: 61 74 65 6d 65 6e 74 73 0a 23 0a 70 72 6f 63 20  atements.#.proc 
a600: 73 74 65 70 73 71 6c 20 7b 64 62 70 74 72 20 73  stepsql {dbptr s
a610: 71 6c 7d 20 7b 0a 20 20 73 65 74 20 73 71 6c 20  ql} {.  set sql 
a620: 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 73 71  [string trim $sq
a630: 6c 5d 0a 20 20 73 65 74 20 72 20 30 0a 20 20 77  l].  set r 0.  w
a640: 68 69 6c 65 20 7b 5b 73 74 72 69 6e 67 20 6c 65  hile {[string le
a650: 6e 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a  ngth $sql]>0} {.
a660: 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b      if {[catch {
a670: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 20  sqlite3_prepare 
a680: 24 64 62 70 74 72 20 24 73 71 6c 20 2d 31 20 73  $dbptr $sql -1 s
a690: 71 6c 74 61 69 6c 7d 20 76 6d 5d 7d 20 7b 0a 20  qltail} vm]} {. 
a6a0: 20 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73       return [lis
a6b0: 74 20 31 20 24 76 6d 5d 0a 20 20 20 20 7d 0a 20  t 1 $vm].    }. 
a6c0: 20 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69     set sql [stri
a6d0: 6e 67 20 74 72 69 6d 20 24 73 71 6c 74 61 69 6c  ng trim $sqltail
a6e0: 5d 0a 23 20 20 20 20 77 68 69 6c 65 20 7b 5b 73  ].#    while {[s
a6f0: 71 6c 69 74 65 5f 73 74 65 70 20 24 76 6d 20 4e  qlite_step $vm N
a700: 20 56 41 4c 20 43 4f 4c 5d 3d 3d 22 53 51 4c 49   VAL COL]=="SQLI
a710: 54 45 5f 52 4f 57 22 7d 20 7b 0a 23 20 20 20 20  TE_ROW"} {.#    
a720: 20 20 66 6f 72 65 61 63 68 20 76 20 24 56 41 4c    foreach v $VAL
a730: 20 7b 6c 61 70 70 65 6e 64 20 72 20 24 76 7d 0a   {lappend r $v}.
a740: 23 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65  #    }.    while
a750: 20 7b 5b 73 71 6c 69 74 65 33 5f 73 74 65 70 20   {[sqlite3_step 
a760: 24 76 6d 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f  $vm]=="SQLITE_RO
a770: 57 22 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72 20  W"} {.      for 
a780: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b 73  {set i 0} {$i<[s
a790: 71 6c 69 74 65 33 5f 64 61 74 61 5f 63 6f 75 6e  qlite3_data_coun
a7a0: 74 20 24 76 6d 5d 7d 20 7b 69 6e 63 72 20 69 7d  t $vm]} {incr i}
a7b0: 20 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65   {.        lappe
a7c0: 6e 64 20 72 20 5b 73 71 6c 69 74 65 33 5f 63 6f  nd r [sqlite3_co
a7d0: 6c 75 6d 6e 5f 74 65 78 74 20 24 76 6d 20 24 69  lumn_text $vm $i
a7e0: 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ].      }.    }.
a7f0: 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b      if {[catch {
a800: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
a810: 20 24 76 6d 7d 20 65 72 72 6d 73 67 5d 7d 20 7b   $vm} errmsg]} {
a820: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 6c  .      return [l
a830: 69 73 74 20 31 20 24 65 72 72 6d 73 67 5d 0a 20  ist 1 $errmsg]. 
a840: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
a850: 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20  n $r.}..# Do an 
a860: 69 6e 74 65 67 72 69 74 79 20 63 68 65 63 6b 20  integrity check 
a870: 6f 66 20 74 68 65 20 65 6e 74 69 72 65 20 64 61  of the entire da
a880: 74 61 62 61 73 65 0a 23 0a 70 72 6f 63 20 69 6e  tabase.#.proc in
a890: 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20 7b 6e  tegrity_check {n
a8a0: 61 6d 65 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20  ame {db db}} {. 
a8b0: 20 69 66 63 61 70 61 62 6c 65 20 69 6e 74 65 67   ifcapable integ
a8c0: 72 69 74 79 63 6b 20 7b 0a 20 20 20 20 64 6f 5f  rityck {.    do_
a8d0: 74 65 73 74 20 24 6e 61 6d 65 20 5b 6c 69 73 74  test $name [list
a8e0: 20 65 78 65 63 73 71 6c 20 7b 50 52 41 47 4d 41   execsql {PRAGMA
a8f0: 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b   integrity_check
a900: 7d 20 24 64 62 5d 20 7b 6f 6b 7d 0a 20 20 7d 0a  } $db] {ok}.  }.
a910: 7d 0a 0a 23 20 43 68 65 63 6b 20 74 68 65 20 65  }..# Check the e
a920: 78 74 65 6e 64 65 64 20 65 72 72 6f 72 20 63 6f  xtended error co
a930: 64 65 0a 23 0a 70 72 6f 63 20 76 65 72 69 66 79  de.#.proc verify
a940: 5f 65 78 5f 65 72 72 63 6f 64 65 20 7b 6e 61 6d  _ex_errcode {nam
a950: 65 20 65 78 70 65 63 74 65 64 20 7b 64 62 20 64  e expected {db d
a960: 62 7d 7d 20 7b 0a 20 20 64 6f 5f 74 65 73 74 20  b}} {.  do_test 
a970: 24 6e 61 6d 65 20 5b 6c 69 73 74 20 73 71 6c 69  $name [list sqli
a980: 74 65 33 5f 65 78 74 65 6e 64 65 64 5f 65 72 72  te3_extended_err
a990: 63 6f 64 65 20 24 64 62 5d 20 24 65 78 70 65 63  code $db] $expec
a9a0: 74 65 64 0a 7d 0a 0a 0a 23 20 52 65 74 75 72 6e  ted.}...# Return
a9b0: 20 74 72 75 65 20 69 66 20 74 68 65 20 53 51 4c   true if the SQL
a9c0: 20 73 74 61 74 65 6d 65 6e 74 20 70 61 73 73 65   statement passe
a9d0: 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20  d as the second 
a9e0: 61 72 67 75 6d 65 6e 74 20 75 73 65 73 20 61 0a  argument uses a.
a9f0: 23 20 73 74 61 74 65 6d 65 6e 74 20 74 72 61 6e  # statement tran
aa00: 73 61 63 74 69 6f 6e 2e 0a 23 0a 70 72 6f 63 20  saction..#.proc 
aa10: 73 71 6c 5f 75 73 65 73 5f 73 74 6d 74 20 7b 64  sql_uses_stmt {d
aa20: 62 20 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 73  b sql} {.  set s
aa30: 74 6d 74 20 5b 73 71 6c 69 74 65 33 5f 70 72 65  tmt [sqlite3_pre
aa40: 70 61 72 65 20 24 64 62 20 24 73 71 6c 20 2d 31  pare $db $sql -1
aa50: 20 64 75 6d 6d 79 5d 0a 20 20 73 65 74 20 75 73   dummy].  set us
aa60: 65 73 20 5b 75 73 65 73 5f 73 74 6d 74 5f 6a 6f  es [uses_stmt_jo
aa70: 75 72 6e 61 6c 20 24 73 74 6d 74 5d 0a 20 20 73  urnal $stmt].  s
aa80: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 20  qlite3_finalize 
aa90: 24 73 74 6d 74 0a 20 20 72 65 74 75 72 6e 20 24  $stmt.  return $
aaa0: 75 73 65 73 0a 7d 0a 0a 70 72 6f 63 20 66 69 78  uses.}..proc fix
aab0: 5f 69 66 63 61 70 61 62 6c 65 5f 65 78 70 72 20  _ifcapable_expr 
aac0: 7b 65 78 70 72 7d 20 7b 0a 20 20 73 65 74 20 72  {expr} {.  set r
aad0: 65 74 20 22 22 0a 20 20 73 65 74 20 73 74 61 74  et "".  set stat
aae0: 65 20 30 0a 20 20 66 6f 72 20 7b 73 65 74 20 69  e 0.  for {set i
aaf0: 20 30 7d 20 7b 24 69 20 3c 20 5b 73 74 72 69 6e   0} {$i < [strin
ab00: 67 20 6c 65 6e 67 74 68 20 24 65 78 70 72 5d 7d  g length $expr]}
ab10: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
ab20: 73 65 74 20 63 68 61 72 20 5b 73 74 72 69 6e 67  set char [string
ab30: 20 72 61 6e 67 65 20 24 65 78 70 72 20 24 69 20   range $expr $i 
ab40: 24 69 5d 0a 20 20 20 20 73 65 74 20 6e 65 77 73  $i].    set news
ab50: 74 61 74 65 20 5b 65 78 70 72 20 7b 5b 73 74 72  tate [expr {[str
ab60: 69 6e 67 20 69 73 20 61 6c 6e 75 6d 20 24 63 68  ing is alnum $ch
ab70: 61 72 5d 20 7c 7c 20 24 63 68 61 72 20 65 71 20  ar] || $char eq 
ab80: 22 5f 22 7d 5d 0a 20 20 20 20 69 66 20 7b 24 6e  "_"}].    if {$n
ab90: 65 77 73 74 61 74 65 20 26 26 20 21 24 73 74 61  ewstate && !$sta
aba0: 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70 70 65  te} {.      appe
abb0: 6e 64 20 72 65 74 20 7b 24 3a 3a 73 71 6c 69 74  nd ret {$::sqlit
abc0: 65 5f 6f 70 74 69 6f 6e 73 28 7d 0a 20 20 20 20  e_options(}.    
abd0: 7d 0a 20 20 20 20 69 66 20 7b 21 24 6e 65 77 73  }.    if {!$news
abe0: 74 61 74 65 20 26 26 20 24 73 74 61 74 65 7d 20  tate && $state} 
abf0: 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 72  {.      append r
ac00: 65 74 20 29 0a 20 20 20 20 7d 0a 20 20 20 20 61  et ).    }.    a
ac10: 70 70 65 6e 64 20 72 65 74 20 24 63 68 61 72 0a  ppend ret $char.
ac20: 20 20 20 20 73 65 74 20 73 74 61 74 65 20 24 6e      set state $n
ac30: 65 77 73 74 61 74 65 0a 20 20 7d 0a 20 20 69 66  ewstate.  }.  if
ac40: 20 7b 24 73 74 61 74 65 7d 20 7b 61 70 70 65 6e   {$state} {appen
ac50: 64 20 72 65 74 20 29 7d 0a 20 20 72 65 74 75 72  d ret )}.  retur
ac60: 6e 20 24 72 65 74 0a 7d 0a 0a 23 20 52 65 74 75  n $ret.}..# Retu
ac70: 72 6e 73 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20  rns non-zero if 
ac80: 74 68 65 20 63 61 70 61 62 69 6c 69 74 69 65 73  the capabilities
ac90: 20 61 72 65 20 70 72 65 73 65 6e 74 3b 20 7a 65   are present; ze
aca0: 72 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a 23 0a  ro otherwise..#.
acb0: 70 72 6f 63 20 63 61 70 61 62 6c 65 20 7b 65 78  proc capable {ex
acc0: 70 72 7d 20 7b 0a 20 20 73 65 74 20 65 20 5b 66  pr} {.  set e [f
acd0: 69 78 5f 69 66 63 61 70 61 62 6c 65 5f 65 78 70  ix_ifcapable_exp
ace0: 72 20 24 65 78 70 72 5d 3b 20 72 65 74 75 72 6e  r $expr]; return
acf0: 20 5b 65 78 70 72 20 28 24 65 29 5d 0a 7d 0a 0a   [expr ($e)].}..
ad00: 23 20 45 76 61 6c 75 61 74 65 20 61 20 62 6f 6f  # Evaluate a boo
ad10: 6c 65 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20  lean expression 
ad20: 6f 66 20 63 61 70 61 62 69 6c 69 74 69 65 73 2e  of capabilities.
ad30: 20 20 49 66 20 74 72 75 65 2c 20 65 78 65 63 75    If true, execu
ad40: 74 65 20 74 68 65 0a 23 20 63 6f 64 65 2e 20 20  te the.# code.  
ad50: 4f 6d 69 74 20 74 68 65 20 63 6f 64 65 20 69 66  Omit the code if
ad60: 20 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69   false..#.proc i
ad70: 66 63 61 70 61 62 6c 65 20 7b 65 78 70 72 20 63  fcapable {expr c
ad80: 6f 64 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65  ode {else ""} {e
ad90: 6c 73 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20  lsecode ""}} {. 
ada0: 20 23 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b   #regsub -all {[
adb0: 61 2d 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72  a-z_0-9]+} $expr
adc0: 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69   {$::sqlite_opti
add0: 6f 6e 73 28 26 29 7d 20 65 32 0a 20 20 73 65 74  ons(&)} e2.  set
ade0: 20 65 32 20 5b 66 69 78 5f 69 66 63 61 70 61 62   e2 [fix_ifcapab
adf0: 6c 65 5f 65 78 70 72 20 24 65 78 70 72 5d 0a 20  le_expr $expr]. 
ae00: 20 69 66 20 28 24 65 32 29 20 7b 0a 20 20 20 20   if ($e2) {.    
ae10: 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70  set c [catch {up
ae20: 6c 65 76 65 6c 20 31 20 24 63 6f 64 65 7d 20 72  level 1 $code} r
ae30: 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  ].  } else {.   
ae40: 20 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75   set c [catch {u
ae50: 70 6c 65 76 65 6c 20 31 20 24 65 6c 73 65 63 6f  plevel 1 $elseco
ae60: 64 65 7d 20 72 5d 0a 20 20 7d 0a 20 20 72 65 74  de} r].  }.  ret
ae70: 75 72 6e 20 2d 63 6f 64 65 20 24 63 20 24 72 0a  urn -code $c $r.
ae80: 7d 0a 0a 23 20 54 68 69 73 20 70 72 6f 63 20 65  }..# This proc e
ae90: 78 65 63 73 20 61 20 73 65 70 65 72 61 74 65 20  xecs a seperate 
aea0: 70 72 6f 63 65 73 73 20 74 68 61 74 20 63 72 61  process that cra
aeb0: 73 68 65 73 20 6d 69 64 77 61 79 20 74 68 72 6f  shes midway thro
aec0: 75 67 68 20 65 78 65 63 75 74 69 6e 67 0a 23 20  ugh executing.# 
aed0: 74 68 65 20 53 51 4c 20 73 63 72 69 70 74 20 24  the SQL script $
aee0: 73 71 6c 20 6f 6e 20 64 61 74 61 62 61 73 65 20  sql on database 
aef0: 74 65 73 74 2e 64 62 2e 0a 23 0a 23 20 54 68 65  test.db..#.# The
af00: 20 63 72 61 73 68 20 6f 63 63 75 72 73 20 64 75   crash occurs du
af10: 72 69 6e 67 20 61 20 73 79 6e 63 28 29 20 6f 66  ring a sync() of
af20: 20 66 69 6c 65 20 24 63 72 61 73 68 66 69 6c 65   file $crashfile
af30: 2e 20 57 68 65 6e 20 74 68 65 20 63 72 61 73 68  . When the crash
af40: 0a 23 20 6f 63 63 75 72 73 20 61 20 72 61 6e 64  .# occurs a rand
af50: 6f 6d 20 73 75 62 73 65 74 20 6f 66 20 61 6c 6c  om subset of all
af60: 20 75 6e 73 79 6e 63 65 64 20 77 72 69 74 65 73   unsynced writes
af70: 20 6d 61 64 65 20 62 79 20 74 68 65 20 70 72 6f   made by the pro
af80: 63 65 73 73 20 61 72 65 0a 23 20 77 72 69 74 74  cess are.# writt
af90: 65 6e 20 69 6e 74 6f 20 74 68 65 20 66 69 6c 65  en into the file
afa0: 73 20 6f 6e 20 64 69 73 6b 2e 20 41 72 67 75 6d  s on disk. Argum
afb0: 65 6e 74 20 24 63 72 61 73 68 64 65 6c 61 79 20  ent $crashdelay 
afc0: 69 6e 64 69 63 61 74 65 73 20 74 68 65 0a 23 20  indicates the.# 
afd0: 6e 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 20 73  number of file s
afe0: 79 6e 63 73 20 74 6f 20 77 61 69 74 20 62 65 66  yncs to wait bef
aff0: 6f 72 65 20 63 72 61 73 68 69 6e 67 2e 0a 23 0a  ore crashing..#.
b000: 23 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c  # The return val
b010: 75 65 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20  ue is a list of 
b020: 74 77 6f 20 65 6c 65 6d 65 6e 74 73 2e 20 54 68  two elements. Th
b030: 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20  e first element 
b040: 69 73 20 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20  is a.# boolean, 
b050: 69 6e 64 69 63 61 74 69 6e 67 20 77 68 65 74 68  indicating wheth
b060: 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 70 72  er or not the pr
b070: 6f 63 65 73 73 20 61 63 74 75 61 6c 6c 79 20 63  ocess actually c
b080: 72 61 73 68 65 64 20 6f 72 0a 23 20 72 65 70 6f  rashed or.# repo
b090: 72 74 65 64 20 73 6f 6d 65 20 6f 74 68 65 72 20  rted some other 
b0a0: 65 72 72 6f 72 2e 20 54 68 65 20 73 65 63 6f 6e  error. The secon
b0b0: 64 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65  d element in the
b0c0: 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74 20 69   returned list i
b0d0: 73 20 74 68 65 0a 23 20 65 72 72 6f 72 20 6d 65  s the.# error me
b0e0: 73 73 61 67 65 2e 20 54 68 69 73 20 69 73 20 22  ssage. This is "
b0f0: 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78  child process ex
b100: 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22  ited abnormally"
b110: 20 69 66 20 74 68 65 20 63 72 61 73 68 0a 23 20   if the crash.# 
b120: 6f 63 63 75 72 72 65 64 2e 0a 23 0a 23 20 20 20  occurred..#.#   
b130: 63 72 61 73 68 73 71 6c 20 2d 64 65 6c 61 79 20  crashsql -delay 
b140: 43 52 41 53 48 44 45 4c 41 59 20 2d 66 69 6c 65  CRASHDELAY -file
b150: 20 43 52 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f   CRASHFILE ?-blo
b160: 63 6b 73 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45  cksize BLOCKSIZE
b170: 3f 20 24 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72  ? $sql.#.proc cr
b180: 61 73 68 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a  ashsql {args} {.
b190: 0a 20 20 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  .  set blocksize
b1a0: 20 22 22 0a 20 20 73 65 74 20 63 72 61 73 68 64   "".  set crashd
b1b0: 65 6c 61 79 20 31 0a 20 20 73 65 74 20 70 72 6e  elay 1.  set prn
b1c0: 67 73 65 65 64 20 30 0a 20 20 73 65 74 20 6f 70  gseed 0.  set op
b1d0: 65 6e 64 62 20 7b 20 73 71 6c 69 74 65 33 20 64  endb { sqlite3 d
b1e0: 62 20 74 65 73 74 2e 64 62 20 2d 76 66 73 20 63  b test.db -vfs c
b1f0: 72 61 73 68 20 7d 0a 20 20 73 65 74 20 74 63 6c  rash }.  set tcl
b200: 62 6f 64 79 20 7b 7d 0a 20 20 73 65 74 20 63 72  body {}.  set cr
b210: 61 73 68 66 69 6c 65 20 22 22 0a 20 20 73 65 74  ashfile "".  set
b220: 20 64 63 20 22 22 0a 20 20 73 65 74 20 64 66 6c   dc "".  set dfl
b230: 74 76 66 73 20 30 0a 20 20 73 65 74 20 73 71 6c  tvfs 0.  set sql
b240: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65   [lindex $args e
b250: 6e 64 5d 0a 0a 20 20 66 6f 72 20 7b 73 65 74 20  nd]..  for {set 
b260: 69 69 20 30 7d 20 7b 24 69 69 20 3c 20 5b 6c 6c  ii 0} {$ii < [ll
b270: 65 6e 67 74 68 20 24 61 72 67 73 5d 2d 31 7d 20  ength $args]-1} 
b280: 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b 0a 20 20  {incr ii 2} {.  
b290: 20 20 73 65 74 20 7a 20 5b 6c 69 6e 64 65 78 20    set z [lindex 
b2a0: 24 61 72 67 73 20 24 69 69 5d 0a 20 20 20 20 73  $args $ii].    s
b2b0: 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e  et n [string len
b2c0: 67 74 68 20 24 7a 5d 0a 20 20 20 20 73 65 74 20  gth $z].    set 
b2d0: 7a 32 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73  z2 [lindex $args
b2e0: 20 5b 65 78 70 72 20 24 69 69 2b 31 5d 5d 0a 0a   [expr $ii+1]]..
b2f0: 20 20 20 20 69 66 20 20 20 20 20 7b 24 6e 3e 31      if     {$n>1
b300: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
b310: 74 20 24 7a 20 2d 64 65 6c 61 79 5d 3d 3d 30 7d  t $z -delay]==0}
b320: 20 20 20 20 20 7b 73 65 74 20 63 72 61 73 68 64       {set crashd
b330: 65 6c 61 79 20 24 7a 32 7d 20 5c 0a 20 20 20 20  elay $z2} \.    
b340: 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20  elseif {$n>1 && 
b350: 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a  [string first $z
b360: 20 2d 6f 70 65 6e 64 62 5d 3d 3d 30 7d 20 20 20   -opendb]==0}   
b370: 20 7b 73 65 74 20 6f 70 65 6e 64 62 20 24 7a 32   {set opendb $z2
b380: 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b  } \.    elseif {
b390: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
b3a0: 66 69 72 73 74 20 24 7a 20 2d 73 65 65 64 5d 3d  first $z -seed]=
b3b0: 3d 30 7d 20 20 20 20 20 20 7b 73 65 74 20 70 72  =0}      {set pr
b3c0: 6e 67 73 65 65 64 20 24 7a 32 7d 20 5c 0a 20 20  ngseed $z2} \.  
b3d0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
b3e0: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
b3f0: 24 7a 20 2d 66 69 6c 65 5d 3d 3d 30 7d 20 20 20  $z -file]==0}   
b400: 20 20 20 7b 73 65 74 20 63 72 61 73 68 66 69 6c     {set crashfil
b410: 65 20 24 7a 32 7d 20 20 5c 0a 20 20 20 20 65 6c  e $z2}  \.    el
b420: 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73  seif {$n>1 && [s
b430: 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d  tring first $z -
b440: 74 63 6c 62 6f 64 79 5d 3d 3d 30 7d 20 20 20 7b  tclbody]==0}   {
b450: 73 65 74 20 74 63 6c 62 6f 64 79 20 24 7a 32 7d  set tclbody $z2}
b460: 20 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b    \.    elseif {
b470: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
b480: 66 69 72 73 74 20 24 7a 20 2d 62 6c 6f 63 6b 73  first $z -blocks
b490: 69 7a 65 5d 3d 3d 30 7d 20 7b 73 65 74 20 62 6c  ize]==0} {set bl
b4a0: 6f 63 6b 73 69 7a 65 20 22 2d 73 20 24 7a 32 22  ocksize "-s $z2"
b4b0: 20 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20   } \.    elseif 
b4c0: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
b4d0: 20 66 69 72 73 74 20 24 7a 20 2d 63 68 61 72 61   first $z -chara
b4e0: 63 74 65 72 69 73 74 69 63 73 5d 3d 3d 30 7d 20  cteristics]==0} 
b4f0: 7b 73 65 74 20 64 63 20 22 2d 63 20 7b 24 7a 32  {set dc "-c {$z2
b500: 7d 22 20 7d 5c 0a 20 20 20 20 65 6c 73 65 69 66  }" }\.    elseif
b510: 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e   {$n>1 && [strin
b520: 67 20 66 69 72 73 74 20 24 7a 20 2d 64 66 6c 74  g first $z -dflt
b530: 76 66 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 66  vfs]==0} {set df
b540: 6c 74 76 66 73 20 24 7a 32 20 7d 5c 0a 20 20 20  ltvfs $z2 }\.   
b550: 20 65 6c 73 65 20 20 20 7b 20 65 72 72 6f 72 20   else   { error 
b560: 22 55 6e 72 65 63 6f 67 6e 69 7a 65 64 20 6f 70  "Unrecognized op
b570: 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a 20 20 7d 0a  tion: $z" }.  }.
b580: 0a 20 20 69 66 20 7b 24 63 72 61 73 68 66 69 6c  .  if {$crashfil
b590: 65 20 65 71 20 22 22 7d 20 7b 0a 20 20 20 20 65  e eq ""} {.    e
b5a0: 72 72 6f 72 20 22 43 6f 6d 70 75 6c 73 6f 72 79  rror "Compulsory
b5b0: 20 6f 70 74 69 6f 6e 20 2d 66 69 6c 65 20 6d 69   option -file mi
b5c0: 73 73 69 6e 67 22 0a 20 20 7d 0a 0a 20 20 23 20  ssing".  }..  # 
b5d0: 24 63 72 61 73 68 66 69 6c 65 20 67 65 74 73 20  $crashfile gets 
b5e0: 63 6f 6d 70 61 72 65 64 20 74 6f 20 74 68 65 20  compared to the 
b5f0: 6e 61 74 69 76 65 20 66 69 6c 65 6e 61 6d 65 20  native filename 
b600: 69 6e 0a 20 20 23 20 63 66 53 79 6e 63 28 29 2c  in.  # cfSync(),
b610: 20 77 68 69 63 68 20 63 61 6e 20 62 65 20 64 69   which can be di
b620: 66 66 65 72 65 6e 74 20 74 68 65 6e 20 77 68 61  fferent then wha
b630: 74 20 54 43 4c 20 75 73 65 73 20 62 79 0a 20 20  t TCL uses by.  
b640: 23 20 64 65 66 61 75 6c 74 2c 20 73 6f 20 68 65  # default, so he
b650: 72 65 20 77 65 20 66 6f 72 63 65 20 69 74 20 74  re we force it t
b660: 6f 20 74 68 65 20 22 6e 61 74 69 76 65 6e 61 6d  o the "nativenam
b670: 65 22 20 66 6f 72 6d 61 74 2e 0a 20 20 73 65 74  e" format..  set
b680: 20 63 66 69 6c 65 20 5b 73 74 72 69 6e 67 20 6d   cfile [string m
b690: 61 70 20 7b 5c 5c 20 5c 5c 5c 5c 7d 20 5b 66 69  ap {\\ \\\\} [fi
b6a0: 6c 65 20 6e 61 74 69 76 65 6e 61 6d 65 20 5b 66  le nativename [f
b6b0: 69 6c 65 20 6a 6f 69 6e 20 5b 67 65 74 5f 70 77  ile join [get_pw
b6c0: 64 5d 20 24 63 72 61 73 68 66 69 6c 65 5d 5d 5d  d] $crashfile]]]
b6d0: 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20  ..  set f [open 
b6e0: 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70  crash.tcl w].  p
b6f0: 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f  uts $f "sqlite3_
b700: 63 72 61 73 68 5f 65 6e 61 62 6c 65 20 31 20 24  crash_enable 1 $
b710: 64 66 6c 74 76 66 73 22 0a 20 20 70 75 74 73 20  dfltvfs".  puts 
b720: 24 66 20 22 73 71 6c 69 74 65 33 5f 63 72 61 73  $f "sqlite3_cras
b730: 68 70 61 72 61 6d 73 20 24 62 6c 6f 63 6b 73 69  hparams $blocksi
b740: 7a 65 20 24 64 63 20 24 63 72 61 73 68 64 65 6c  ze $dc $crashdel
b750: 61 79 20 24 63 66 69 6c 65 22 0a 20 20 70 75 74  ay $cfile".  put
b760: 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f 74 65  s $f "sqlite3_te
b770: 73 74 5f 63 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69  st_control_pendi
b780: 6e 67 5f 62 79 74 65 20 24 3a 3a 73 71 6c 69 74  ng_byte $::sqlit
b790: 65 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 22 0a  e_pending_byte".
b7a0: 0a 20 20 23 20 54 68 69 73 20 62 6c 6f 63 6b 20  .  # This block 
b7b0: 73 65 74 73 20 74 68 65 20 63 61 63 68 65 20 73  sets the cache s
b7c0: 69 7a 65 20 6f 66 20 74 68 65 20 6d 61 69 6e 20  ize of the main 
b7d0: 64 61 74 61 62 61 73 65 20 74 6f 20 31 30 0a 20  database to 10. 
b7e0: 20 23 20 70 61 67 65 73 2e 20 54 68 69 73 20 69   # pages. This i
b7f0: 73 20 64 6f 6e 65 20 69 6e 20 63 61 73 65 20 74  s done in case t
b800: 68 65 20 62 75 69 6c 64 20 69 73 20 63 6f 6e 66  he build is conf
b810: 69 67 75 72 65 64 20 74 6f 20 6f 6d 69 74 0a 20  igured to omit. 
b820: 20 23 20 22 50 52 41 47 4d 41 20 63 61 63 68 65   # "PRAGMA cache
b830: 5f 73 69 7a 65 22 2e 0a 20 20 69 66 20 7b 24 6f  _size"..  if {$o
b840: 70 65 6e 64 62 21 3d 22 22 7d 20 7b 0a 20 20 20  pendb!=""} {.   
b850: 20 70 75 74 73 20 24 66 20 24 6f 70 65 6e 64 62   puts $f $opendb
b860: 20 0a 20 20 20 20 70 75 74 73 20 24 66 20 7b 64   .    puts $f {d
b870: 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 2a  b eval {SELECT *
b880: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
b890: 74 65 72 3b 7d 7d 0a 20 20 20 20 70 75 74 73 20  ter;}}.    puts 
b8a0: 24 66 20 7b 73 65 74 20 62 74 20 5b 62 74 72 65  $f {set bt [btre
b8b0: 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 7d 0a 20  e_from_db db]}. 
b8c0: 20 20 20 70 75 74 73 20 24 66 20 7b 62 74 72 65     puts $f {btre
b8d0: 65 5f 73 65 74 5f 63 61 63 68 65 5f 73 69 7a 65  e_set_cache_size
b8e0: 20 24 62 74 20 31 30 7d 0a 20 20 7d 0a 0a 20 20   $bt 10}.  }..  
b8f0: 69 66 20 7b 24 70 72 6e 67 73 65 65 64 7d 20 7b  if {$prngseed} {
b900: 0a 20 20 20 20 73 65 74 20 73 65 65 64 20 5b 65  .    set seed [e
b910: 78 70 72 20 7b 24 70 72 6e 67 73 65 65 64 25 31  xpr {$prngseed%1
b920: 30 30 30 37 2b 31 7d 5d 0a 20 20 20 20 23 20 70  0007+1}].    # p
b930: 75 74 73 20 73 65 65 64 3d 24 73 65 65 64 0a 20  uts seed=$seed. 
b940: 20 20 20 70 75 74 73 20 24 66 20 22 64 62 20 65     puts $f "db e
b950: 76 61 6c 20 7b 53 45 4c 45 43 54 20 72 61 6e 64  val {SELECT rand
b960: 6f 6d 62 6c 6f 62 28 24 73 65 65 64 29 7d 22 0a  omblob($seed)}".
b970: 20 20 7d 0a 0a 20 20 69 66 20 7b 5b 73 74 72 69    }..  if {[stri
b980: 6e 67 20 6c 65 6e 67 74 68 20 24 74 63 6c 62 6f  ng length $tclbo
b990: 64 79 5d 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74  dy]>0} {.    put
b9a0: 73 20 24 66 20 24 74 63 6c 62 6f 64 79 0a 20 20  s $f $tclbody.  
b9b0: 7d 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20  }.  if {[string 
b9c0: 6c 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20  length $sql]>0} 
b9d0: 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20 22 64  {.    puts $f "d
b9e0: 62 20 65 76 61 6c 20 7b 22 0a 20 20 20 20 70 75  b eval {".    pu
b9f0: 74 73 20 24 66 20 20 20 22 24 73 71 6c 22 0a 20  ts $f   "$sql". 
ba00: 20 20 20 70 75 74 73 20 24 66 20 22 7d 22 0a 20     puts $f "}". 
ba10: 20 7d 0a 20 20 63 6c 6f 73 65 20 24 66 0a 20 20   }.  close $f.  
ba20: 73 65 74 20 72 20 5b 63 61 74 63 68 20 7b 0a 20  set r [catch {. 
ba30: 20 20 20 65 78 65 63 20 5b 69 6e 66 6f 20 6e 61     exec [info na
ba40: 6d 65 6f 66 65 78 65 63 5d 20 63 72 61 73 68 2e  meofexec] crash.
ba50: 74 63 6c 20 3e 40 73 74 64 6f 75 74 0a 20 20 7d  tcl >@stdout.  }
ba60: 20 6d 73 67 5d 0a 0a 20 20 23 20 57 69 6e 64 6f   msg]..  # Windo
ba70: 77 73 2f 41 63 74 69 76 65 53 74 61 74 65 20 54  ws/ActiveState T
ba80: 43 4c 20 72 65 74 75 72 6e 73 20 61 20 73 6c 69  CL returns a sli
ba90: 67 68 74 6c 79 20 64 69 66 66 65 72 65 6e 74 0a  ghtly different.
baa0: 20 20 23 20 65 72 72 6f 72 20 6d 65 73 73 61 67    # error messag
bab0: 65 2e 20 20 57 65 20 6d 61 70 20 74 68 61 74 20  e.  We map that 
bac0: 74 6f 20 74 68 65 20 65 78 70 65 63 74 65 64 20  to the expected 
bad0: 6d 65 73 73 61 67 65 0a 20 20 23 20 73 6f 20 74  message.  # so t
bae0: 68 61 74 20 77 65 20 64 6f 6e 27 74 20 68 61 76  hat we don't hav
baf0: 65 20 74 6f 20 63 68 61 6e 67 65 20 61 6c 6c 20  e to change all 
bb00: 6f 66 20 74 68 65 20 74 65 73 74 0a 20 20 23 20  of the test.  # 
bb10: 63 61 73 65 73 2e 0a 20 20 69 66 20 7b 24 3a 3a  cases..  if {$::
bb20: 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61  tcl_platform(pla
bb30: 74 66 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73  tform)=="windows
bb40: 22 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24 6d 73  "} {.    if {$ms
bb50: 67 3d 3d 22 63 68 69 6c 64 20 6b 69 6c 6c 65 64  g=="child killed
bb60: 3a 20 75 6e 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c  : unknown signal
bb70: 22 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d  "} {.      set m
bb80: 73 67 20 22 63 68 69 6c 64 20 70 72 6f 63 65 73  sg "child proces
bb90: 73 20 65 78 69 74 65 64 20 61 62 6e 6f 72 6d 61  s exited abnorma
bba0: 6c 6c 79 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  lly".    }.  }..
bbb0: 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67    lappend r $msg
bbc0: 0a 7d 0a 0a 23 20 20 20 63 72 61 73 68 5f 6f 6e  .}..#   crash_on
bbd0: 5f 77 72 69 74 65 20 3f 2d 64 65 76 63 68 61 72  _write ?-devchar
bbe0: 20 44 45 56 43 48 41 52 3f 20 43 52 41 53 48 44   DEVCHAR? CRASHD
bbf0: 45 4c 41 59 20 53 51 4c 0a 23 0a 70 72 6f 63 20  ELAY SQL.#.proc 
bc00: 63 72 61 73 68 5f 6f 6e 5f 77 72 69 74 65 20 7b  crash_on_write {
bc10: 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 6e  args} {..  set n
bc20: 41 72 67 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72  Arg [llength $ar
bc30: 67 73 5d 0a 20 20 69 66 20 7b 24 6e 41 72 67 3c  gs].  if {$nArg<
bc40: 32 20 7c 7c 20 24 6e 41 72 67 25 32 7d 20 7b 0a  2 || $nArg%2} {.
bc50: 20 20 20 20 65 72 72 6f 72 20 22 62 61 64 20 61      error "bad a
bc60: 72 67 73 3a 20 24 61 72 67 73 22 0a 20 20 7d 0a  rgs: $args".  }.
bc70: 20 20 73 65 74 20 7a 53 71 6c 20 5b 6c 69 6e 64    set zSql [lind
bc80: 65 78 20 24 61 72 67 73 20 65 6e 64 5d 0a 20 20  ex $args end].  
bc90: 73 65 74 20 6e 44 65 6c 61 79 20 5b 6c 69 6e 64  set nDelay [lind
bca0: 65 78 20 24 61 72 67 73 20 65 6e 64 2d 31 5d 0a  ex $args end-1].
bcb0: 0a 20 20 73 65 74 20 64 65 76 63 68 61 72 20 7b  .  set devchar {
bcc0: 7d 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 69 20  }.  for {set ii 
bcd0: 30 7d 20 7b 24 69 69 20 3c 20 24 6e 41 72 67 2d  0} {$ii < $nArg-
bce0: 32 7d 20 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b  2} {incr ii 2} {
bcf0: 0a 20 20 20 20 73 65 74 20 6f 70 74 20 5b 6c 69  .    set opt [li
bd00: 6e 64 65 78 20 24 61 72 67 73 20 24 69 69 5d 0a  ndex $args $ii].
bd10: 20 20 20 20 73 77 69 74 63 68 20 2d 2d 20 5b 6c      switch -- [l
bd20: 69 6e 64 65 78 20 24 61 72 67 73 20 24 69 69 5d  index $args $ii]
bd30: 20 7b 0a 20 20 20 20 20 20 2d 64 65 76 63 68 61   {.      -devcha
bd40: 72 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  r {.        set 
bd50: 64 65 76 63 68 61 72 20 5b 6c 69 6e 64 65 78 20  devchar [lindex 
bd60: 24 61 72 67 73 20 5b 65 78 70 72 20 24 69 69 2b  $args [expr $ii+
bd70: 31 5d 5d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  1]].      }..   
bd80: 20 20 20 64 65 66 61 75 6c 74 20 7b 20 65 72 72     default { err
bd90: 6f 72 20 22 75 6e 72 65 63 6f 67 6e 69 7a 65 64  or "unrecognized
bda0: 20 6f 70 74 69 6f 6e 3a 20 24 6f 70 74 22 20 7d   option: $opt" }
bdb0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65  .    }.  }..  se
bdc0: 74 20 66 20 5b 6f 70 65 6e 20 63 72 61 73 68 2e  t f [open crash.
bdd0: 74 63 6c 20 77 5d 0a 20 20 70 75 74 73 20 24 66  tcl w].  puts $f
bde0: 20 22 73 71 6c 69 74 65 33 5f 63 72 61 73 68 5f   "sqlite3_crash_
bdf0: 6f 6e 5f 77 72 69 74 65 20 24 6e 44 65 6c 61 79  on_write $nDelay
be00: 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 71 6c  ".  puts $f "sql
be10: 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f  ite3_test_contro
be20: 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 24  l_pending_byte $
be30: 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67  ::sqlite_pending
be40: 5f 62 79 74 65 22 0a 20 20 70 75 74 73 20 24 66  _byte".  puts $f
be50: 20 22 73 71 6c 69 74 65 33 20 64 62 20 74 65 73   "sqlite3 db tes
be60: 74 2e 64 62 20 2d 76 66 73 20 77 72 69 74 65 63  t.db -vfs writec
be70: 72 61 73 68 22 0a 20 20 70 75 74 73 20 24 66 20  rash".  puts $f 
be80: 22 64 62 20 65 76 61 6c 20 7b 24 7a 53 71 6c 7d  "db eval {$zSql}
be90: 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 65 74  ".  puts $f "set
bea0: 20 7b 7d 20 7b 7d 22 0a 0a 20 20 63 6c 6f 73 65   {} {}"..  close
beb0: 20 24 66 0a 20 20 73 65 74 20 72 20 5b 63 61 74   $f.  set r [cat
bec0: 63 68 20 7b 0a 20 20 20 20 65 78 65 63 20 5b 69  ch {.    exec [i
bed0: 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 5d 20  nfo nameofexec] 
bee0: 63 72 61 73 68 2e 74 63 6c 20 3e 40 73 74 64 6f  crash.tcl >@stdo
bef0: 75 74 0a 20 20 7d 20 6d 73 67 5d 0a 0a 20 20 23  ut.  } msg]..  #
bf00: 20 57 69 6e 64 6f 77 73 2f 41 63 74 69 76 65 53   Windows/ActiveS
bf10: 74 61 74 65 20 54 43 4c 20 72 65 74 75 72 6e 73  tate TCL returns
bf20: 20 61 20 73 6c 69 67 68 74 6c 79 20 64 69 66 66   a slightly diff
bf30: 65 72 65 6e 74 0a 20 20 23 20 65 72 72 6f 72 20  erent.  # error 
bf40: 6d 65 73 73 61 67 65 2e 20 20 57 65 20 6d 61 70  message.  We map
bf50: 20 74 68 61 74 20 74 6f 20 74 68 65 20 65 78 70   that to the exp
bf60: 65 63 74 65 64 20 6d 65 73 73 61 67 65 0a 20 20  ected message.  
bf70: 23 20 73 6f 20 74 68 61 74 20 77 65 20 64 6f 6e  # so that we don
bf80: 27 74 20 68 61 76 65 20 74 6f 20 63 68 61 6e 67  't have to chang
bf90: 65 20 61 6c 6c 20 6f 66 20 74 68 65 20 74 65 73  e all of the tes
bfa0: 74 0a 20 20 23 20 63 61 73 65 73 2e 0a 20 20 69  t.  # cases..  i
bfb0: 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f  f {$::tcl_platfo
bfc0: 72 6d 28 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 77  rm(platform)=="w
bfd0: 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20 20 20 69  indows"} {.    i
bfe0: 66 20 7b 24 6d 73 67 3d 3d 22 63 68 69 6c 64 20  f {$msg=="child 
bff0: 6b 69 6c 6c 65 64 3a 20 75 6e 6b 6e 6f 77 6e 20  killed: unknown 
c000: 73 69 67 6e 61 6c 22 7d 20 7b 0a 20 20 20 20 20  signal"} {.     
c010: 20 73 65 74 20 6d 73 67 20 22 63 68 69 6c 64 20   set msg "child 
c020: 70 72 6f 63 65 73 73 20 65 78 69 74 65 64 20 61  process exited a
c030: 62 6e 6f 72 6d 61 6c 6c 79 22 0a 20 20 20 20 7d  bnormally".    }
c040: 0a 20 20 7d 0a 0a 20 20 6c 61 70 70 65 6e 64 20  .  }..  lappend 
c050: 72 20 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20 72  r $msg.}..proc r
c060: 75 6e 5f 69 6f 65 72 72 5f 70 72 65 70 20 7b 7d  un_ioerr_prep {}
c070: 20 7b 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74   {.  set ::sqlit
c080: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
c090: 6e 67 20 30 0a 20 20 63 61 74 63 68 20 7b 64 62  ng 0.  catch {db
c0a0: 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20   close}.  catch 
c0b0: 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61  {db2 close}.  ca
c0c0: 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65 74 65  tch {forcedelete
c0d0: 20 74 65 73 74 2e 64 62 7d 0a 20 20 63 61 74 63   test.db}.  catc
c0e0: 68 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20 74  h {forcedelete t
c0f0: 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a  est.db-journal}.
c100: 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65    catch {forcede
c110: 6c 65 74 65 20 74 65 73 74 32 2e 64 62 7d 0a 20  lete test2.db}. 
c120: 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c   catch {forcedel
c130: 65 74 65 20 74 65 73 74 32 2e 64 62 2d 6a 6f 75  ete test2.db-jou
c140: 72 6e 61 6c 7d 0a 20 20 73 65 74 20 3a 3a 44 42  rnal}.  set ::DB
c150: 20 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65 73   [sqlite3 db tes
c160: 74 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f  t.db; sqlite3_co
c170: 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72  nnection_pointer
c180: 20 64 62 5d 0a 20 20 73 71 6c 69 74 65 33 5f 65   db].  sqlite3_e
c190: 78 74 65 6e 64 65 64 5f 72 65 73 75 6c 74 5f 63  xtended_result_c
c1a0: 6f 64 65 73 20 24 3a 3a 44 42 20 24 3a 3a 69 6f  odes $::DB $::io
c1b0: 65 72 72 6f 70 74 73 28 2d 65 72 63 29 0a 20 20  erropts(-erc).  
c1c0: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
c1d0: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63   ::ioerropts(-tc
c1e0: 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 65  lprep)]} {.    e
c1f0: 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  val $::ioerropts
c200: 28 2d 74 63 6c 70 72 65 70 29 0a 20 20 7d 0a 20  (-tclprep).  }. 
c210: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
c220: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73  s ::ioerropts(-s
c230: 71 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20  qlprep)]} {.    
c240: 65 78 65 63 73 71 6c 20 24 3a 3a 69 6f 65 72 72  execsql $::ioerr
c250: 6f 70 74 73 28 2d 73 71 6c 70 72 65 70 29 0a 20  opts(-sqlprep). 
c260: 20 7d 0a 20 20 65 78 70 72 20 30 0a 7d 0a 0a 23   }.  expr 0.}..#
c270: 20 55 73 61 67 65 3a 20 64 6f 5f 69 6f 65 72 72   Usage: do_ioerr
c280: 5f 74 65 73 74 20 3c 74 65 73 74 20 6e 75 6d 62  _test <test numb
c290: 65 72 3e 20 3c 6f 70 74 69 6f 6e 73 2e 2e 2e 3e  er> <options...>
c2a0: 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63 20 69  .#.# This proc i
c2b0: 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d  s used to implem
c2c0: 65 6e 74 20 74 65 73 74 20 63 61 73 65 73 20 74  ent test cases t
c2d0: 68 61 74 20 63 68 65 63 6b 20 74 68 61 74 20 49  hat check that I
c2e0: 4f 20 65 72 72 6f 72 73 0a 23 20 61 72 65 20 63  O errors.# are c
c2f0: 6f 72 72 65 63 74 6c 79 20 68 61 6e 64 6c 65 64  orrectly handled
c300: 2e 20 54 68 65 20 66 69 72 73 74 20 61 72 67 75  . The first argu
c310: 6d 65 6e 74 2c 20 3c 74 65 73 74 20 6e 75 6d 62  ment, <test numb
c320: 65 72 3e 2c 20 69 73 20 61 6e 20 69 6e 74 65 67  er>, is an integ
c330: 65 72 0a 23 20 75 73 65 64 20 74 6f 20 6e 61 6d  er.# used to nam
c340: 65 20 74 68 65 20 74 65 73 74 73 20 65 78 65 63  e the tests exec
c350: 75 74 65 64 20 62 79 20 74 68 69 73 20 70 72 6f  uted by this pro
c360: 63 2e 20 4f 70 74 69 6f 6e 73 20 61 72 65 20 61  c. Options are a
c370: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20  s follows:.#.#  
c380: 20 20 20 2d 74 63 6c 70 72 65 70 20 20 20 20 20     -tclprep     
c390: 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20       TCL script 
c3a0: 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61 72  to run to prepar
c3b0: 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 73  e test..#     -s
c3c0: 71 6c 70 72 65 70 20 20 20 20 20 20 20 20 20 20  qlprep          
c3d0: 53 51 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75  SQL script to ru
c3e0: 6e 20 74 6f 20 70 72 65 70 61 72 65 20 74 65 73  n to prepare tes
c3f0: 74 2e 0a 23 20 20 20 20 20 2d 74 63 6c 62 6f 64  t..#     -tclbod
c400: 79 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73  y          TCL s
c410: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69 74  cript to run wit
c420: 68 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c  h IO error simul
c430: 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 73 71  ation..#     -sq
c440: 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20 20 54  lbody          T
c450: 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e  CL script to run
c460: 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20 73   with IO error s
c470: 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20  imulation..#    
c480: 20 2d 65 78 63 6c 75 64 65 20 20 20 20 20 20 20   -exclude       
c490: 20 20 20 4c 69 73 74 20 6f 66 20 27 4e 27 20 76     List of 'N' v
c4a0: 61 6c 75 65 73 20 6e 6f 74 20 74 6f 20 74 65 73  alues not to tes
c4b0: 74 2e 0a 23 20 20 20 20 20 2d 65 72 63 20 20 20  t..#     -erc   
c4c0: 20 20 20 20 20 20 20 20 20 20 20 55 73 65 20 65             Use e
c4d0: 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63  xtended result c
c4e0: 6f 64 65 73 0a 23 20 20 20 20 20 2d 70 65 72 73  odes.#     -pers
c4f0: 69 73 74 20 20 20 20 20 20 20 20 20 20 4d 61 6b  ist          Mak
c500: 65 20 73 69 6d 75 6c 61 74 65 64 20 49 2f 4f 20  e simulated I/O 
c510: 65 72 72 6f 72 73 20 70 65 72 73 69 73 74 65 6e  errors persisten
c520: 74 0a 23 20 20 20 20 20 2d 73 74 61 72 74 20 20  t.#     -start  
c530: 20 20 20 20 20 20 20 20 20 20 56 61 6c 75 65 20            Value 
c540: 6f 66 20 27 4e 27 20 74 6f 20 62 65 67 69 6e 20  of 'N' to begin 
c550: 77 69 74 68 20 28 64 65 66 61 75 6c 74 20 31 29  with (default 1)
c560: 0a 23 0a 23 20 20 20 20 20 2d 63 6b 73 75 6d 20  .#.#     -cksum 
c570: 20 20 20 20 20 20 20 20 20 20 20 42 6f 6f 6c 65             Boole
c580: 61 6e 2e 20 49 66 20 74 72 75 65 2c 20 74 65 73  an. If true, tes
c590: 74 20 74 68 61 74 20 74 68 65 20 64 61 74 61 62  t that the datab
c5a0: 61 73 65 20 64 6f 65 73 0a 23 20 20 20 20 20 20  ase does.#      
c5b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c5c0: 20 6e 6f 74 20 63 68 61 6e 67 65 20 64 75 72 69   not change duri
c5d0: 6e 67 20 74 68 65 20 65 78 65 63 75 74 69 6f 6e  ng the execution
c5e0: 20 6f 66 20 74 68 65 20 74 65 73 74 20 63 61 73   of the test cas
c5f0: 65 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 69 6f 65  e..#.proc do_ioe
c600: 72 72 5f 74 65 73 74 20 7b 74 65 73 74 6e 61 6d  rr_test {testnam
c610: 65 20 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74  e args} {..  set
c620: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 74   ::ioerropts(-st
c630: 61 72 74 29 20 31 0a 20 20 73 65 74 20 3a 3a 69  art) 1.  set ::i
c640: 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29  oerropts(-cksum)
c650: 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   0.  set ::ioerr
c660: 6f 70 74 73 28 2d 65 72 63 29 20 30 0a 20 20 73  opts(-erc) 0.  s
c670: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
c680: 63 6f 75 6e 74 29 20 31 30 30 30 30 30 30 30 30  count) 100000000
c690: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
c6a0: 74 73 28 2d 70 65 72 73 69 73 74 29 20 31 0a 20  ts(-persist) 1. 
c6b0: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
c6c0: 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29 20 30 0a  (-ckrefcount) 0.
c6d0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
c6e0: 73 28 2d 72 65 73 74 6f 72 65 70 72 6e 67 29 20  s(-restoreprng) 
c6f0: 31 0a 20 20 61 72 72 61 79 20 73 65 74 20 3a 3a  1.  array set ::
c700: 69 6f 65 72 72 6f 70 74 73 20 24 61 72 67 73 0a  ioerropts $args.
c710: 0a 20 20 23 20 54 45 4d 50 4f 52 41 52 59 3a 20  .  # TEMPORARY: 
c720: 46 6f 72 20 33 2e 35 2e 39 2c 20 64 69 73 61 62  For 3.5.9, disab
c730: 6c 65 20 74 65 73 74 69 6e 67 20 6f 66 20 65 78  le testing of ex
c740: 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f  tended result co
c750: 64 65 73 2e 20 54 68 65 72 65 20 61 72 65 0a 20  des. There are. 
c760: 20 23 20 61 20 63 6f 75 70 6c 65 20 6f 66 20 6f   # a couple of o
c770: 62 73 63 75 72 65 20 49 4f 20 65 72 72 6f 72 73  bscure IO errors
c780: 20 74 68 61 74 20 64 6f 20 6e 6f 74 20 72 65 74   that do not ret
c790: 75 72 6e 20 74 68 65 6d 2e 0a 20 20 73 65 74 20  urn them..  set 
c7a0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63  ::ioerropts(-erc
c7b0: 29 20 30 0a 0a 20 20 23 20 43 72 65 61 74 65 20  ) 0..  # Create 
c7c0: 61 20 73 69 6e 67 6c 65 20 54 43 4c 20 73 63 72  a single TCL scr
c7d0: 69 70 74 20 66 72 6f 6d 20 74 68 65 20 54 43 4c  ipt from the TCL
c7e0: 20 61 6e 64 20 53 51 4c 20 73 70 65 63 69 66 69   and SQL specifi
c7f0: 65 64 0a 20 20 23 20 61 73 20 74 68 65 20 62 6f  ed.  # as the bo
c800: 64 79 20 6f 66 20 74 68 65 20 74 65 73 74 2e 0a  dy of the test..
c810: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 72 62    set ::ioerrorb
c820: 6f 64 79 20 7b 7d 0a 20 20 69 66 20 7b 5b 69 6e  ody {}.  if {[in
c830: 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72  fo exists ::ioer
c840: 72 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5d  ropts(-tclbody)]
c850: 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 3a  } {.    append :
c860: 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 24 3a  :ioerrorbody "$:
c870: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62  :ioerropts(-tclb
c880: 6f 64 79 29 5c 6e 22 0a 20 20 7d 0a 20 20 69 66  ody)\n".  }.  if
c890: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
c8a0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62  :ioerropts(-sqlb
c8b0: 6f 64 79 29 5d 7d 20 7b 0a 20 20 20 20 61 70 70  ody)]} {.    app
c8c0: 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64  end ::ioerrorbod
c8d0: 79 20 22 64 62 20 65 76 61 6c 20 7b 24 3a 3a 69  y "db eval {$::i
c8e0: 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f 64  oerropts(-sqlbod
c8f0: 79 29 7d 22 0a 20 20 7d 0a 0a 20 20 73 61 76 65  y)}".  }..  save
c900: 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 69 66  _prng_state.  if
c910: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
c920: 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 72 75  cksum)} {.    ru
c930: 6e 5f 69 6f 65 72 72 5f 70 72 65 70 0a 20 20 20  n_ioerr_prep.   
c940: 20 65 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 72   eval $::ioerror
c950: 62 6f 64 79 0a 20 20 20 20 73 65 74 20 3a 3a 67  body.    set ::g
c960: 6f 6f 64 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d  oodcksum [cksum]
c970: 0a 20 20 7d 0a 0a 20 20 73 65 74 20 3a 3a 67 6f  .  }..  set ::go
c980: 20 31 0a 20 20 23 72 65 73 65 74 5f 70 72 6e 67   1.  #reset_prng
c990: 5f 73 74 61 74 65 0a 20 20 66 6f 72 20 7b 73 65  _state.  for {se
c9a0: 74 20 6e 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  t n $::ioerropts
c9b0: 28 2d 73 74 61 72 74 29 7d 20 7b 24 3a 3a 67 6f  (-start)} {$::go
c9c0: 7d 20 7b 69 6e 63 72 20 6e 7d 20 7b 0a 20 20 20  } {incr n} {.   
c9d0: 20 73 65 74 20 3a 3a 54 4e 20 24 6e 0a 20 20 20   set ::TN $n.   
c9e0: 20 69 6e 63 72 20 3a 3a 69 6f 65 72 72 6f 70 74   incr ::ioerropt
c9f0: 73 28 2d 63 6f 75 6e 74 29 20 2d 31 0a 20 20 20  s(-count) -1.   
ca00: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
ca10: 73 28 2d 63 6f 75 6e 74 29 3c 30 7d 20 62 72 65  s(-count)<0} bre
ca20: 61 6b 0a 0a 20 20 20 20 23 20 53 6b 69 70 20 74  ak..    # Skip t
ca30: 68 69 73 20 49 4f 20 65 72 72 6f 72 20 69 66 20  his IO error if 
ca40: 69 74 20 77 61 73 20 73 70 65 63 69 66 69 65 64  it was specified
ca50: 20 77 69 74 68 20 74 68 65 20 22 2d 65 78 63 6c   with the "-excl
ca60: 75 64 65 22 20 6f 70 74 69 6f 6e 2e 0a 20 20 20  ude" option..   
ca70: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
ca80: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65  s ::ioerropts(-e
ca90: 78 63 6c 75 64 65 29 5d 7d 20 7b 0a 20 20 20 20  xclude)]} {.    
caa0: 20 20 69 66 20 7b 5b 6c 73 65 61 72 63 68 20 24    if {[lsearch $
cab0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78 63  ::ioerropts(-exc
cac0: 6c 75 64 65 29 20 24 6e 5d 21 3d 2d 31 7d 20 63  lude) $n]!=-1} c
cad0: 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a 20 20  ontinue.    }.  
cae0: 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70    if {$::ioerrop
caf0: 74 73 28 2d 72 65 73 74 6f 72 65 70 72 6e 67 29  ts(-restoreprng)
cb00: 7d 20 7b 0a 20 20 20 20 20 20 72 65 73 74 6f 72  } {.      restor
cb10: 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 20  e_prng_state.   
cb20: 20 7d 0a 0a 20 20 20 20 23 20 44 65 6c 65 74 65   }..    # Delete
cb30: 20 74 68 65 20 66 69 6c 65 73 20 74 65 73 74 2e   the files test.
cb40: 64 62 20 61 6e 64 20 74 65 73 74 32 2e 64 62 2c  db and test2.db,
cb50: 20 74 68 65 6e 20 65 78 65 63 75 74 65 20 74 68   then execute th
cb60: 65 20 54 43 4c 20 61 6e 64 0a 20 20 20 20 23 20  e TCL and.    # 
cb70: 53 51 4c 20 28 69 6e 20 74 68 61 74 20 6f 72 64  SQL (in that ord
cb80: 65 72 29 20 74 6f 20 70 72 65 70 61 72 65 20 66  er) to prepare f
cb90: 6f 72 20 74 68 65 20 74 65 73 74 20 63 61 73 65  or the test case
cba0: 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74  ..    do_test $t
cbb0: 65 73 74 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a 20  estname.$n.1 {. 
cbc0: 20 20 20 20 20 72 75 6e 5f 69 6f 65 72 72 5f 70       run_ioerr_p
cbd0: 72 65 70 0a 20 20 20 20 7d 20 7b 30 7d 0a 0a 20  rep.    } {0}.. 
cbe0: 20 20 20 23 20 52 65 61 64 20 74 68 65 20 27 63     # Read the 'c
cbf0: 68 65 63 6b 73 75 6d 27 20 6f 66 20 74 68 65 20  hecksum' of the 
cc00: 64 61 74 61 62 61 73 65 2e 0a 20 20 20 20 69 66  database..    if
cc10: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
cc20: 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20  cksum)} {.      
cc30: 73 65 74 20 3a 3a 63 68 65 63 6b 73 75 6d 20 5b  set ::checksum [
cc40: 63 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a 0a 20 20  cksum].    }..  
cc50: 20 20 23 20 53 65 74 20 74 68 65 20 4e 74 68 20    # Set the Nth 
cc60: 49 4f 20 65 72 72 6f 72 20 74 6f 20 66 61 69 6c  IO error to fail
cc70: 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74  ..    do_test $t
cc80: 65 73 74 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73 75  estname.$n.2 [su
cc90: 62 73 74 20 7b 0a 20 20 20 20 20 20 73 65 74 20  bst {.      set 
cca0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
ccb0: 72 5f 70 65 72 73 69 73 74 20 24 3a 3a 69 6f 65  r_persist $::ioe
ccc0: 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74 29  rropts(-persist)
ccd0: 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  .      set ::sql
cce0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
ccf0: 64 69 6e 67 20 24 6e 0a 20 20 20 20 7d 5d 20 24  ding $n.    }] $
cd00: 6e 0a 0a 20 20 20 20 23 20 45 78 65 63 75 74 65  n..    # Execute
cd10: 20 74 68 65 20 54 43 4c 20 73 63 72 69 70 74 20   the TCL script 
cd20: 63 72 65 61 74 65 64 20 66 6f 72 20 74 68 65 20  created for the 
cd30: 62 6f 64 79 20 6f 66 20 74 68 69 73 20 74 65 73  body of this tes
cd40: 74 2e 20 49 66 0a 20 20 20 20 23 20 61 74 20 6c  t. If.    # at l
cd50: 65 61 73 74 20 4e 20 49 4f 20 6f 70 65 72 61 74  east N IO operat
cd60: 69 6f 6e 73 20 70 65 72 66 6f 72 6d 65 64 20 62  ions performed b
cd70: 79 20 53 51 4c 69 74 65 20 61 73 20 61 20 72 65  y SQLite as a re
cd80: 73 75 6c 74 20 6f 66 0a 20 20 20 20 23 20 74 68  sult of.    # th
cd90: 65 20 73 63 72 69 70 74 2c 20 74 68 65 20 4e 74  e script, the Nt
cda0: 68 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 20 20 20  h will fail..   
cdb0: 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61   do_test $testna
cdc0: 6d 65 2e 24 6e 2e 33 20 7b 0a 20 20 20 20 20 20  me.$n.3 {.      
cdd0: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
cde0: 65 72 72 6f 72 5f 68 69 74 20 30 0a 20 20 20 20  error_hit 0.    
cdf0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
ce00: 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20  o_error_hardhit 
ce10: 30 0a 20 20 20 20 20 20 73 65 74 20 72 20 5b 63  0.      set r [c
ce20: 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 72 62  atch $::ioerrorb
ce30: 6f 64 79 20 6d 73 67 5d 0a 20 20 20 20 20 20 73  ody msg].      s
ce40: 65 74 20 3a 3a 65 72 72 73 65 65 6e 20 24 72 0a  et ::errseen $r.
ce50: 20 20 20 20 20 20 73 65 74 20 72 63 20 5b 73 71        set rc [sq
ce60: 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 20 24 3a  lite3_errcode $:
ce70: 3a 44 42 5d 0a 20 20 20 20 20 20 69 66 20 7b 24  :DB].      if {$
ce80: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63  ::ioerropts(-erc
ce90: 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20 49  )} {.        # I
cea0: 66 20 77 65 20 61 72 65 20 69 6e 20 65 78 74 65  f we are in exte
ceb0: 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65  nded result code
cec0: 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72 65   mode, make sure
ced0: 20 61 6c 6c 20 6f 66 20 74 68 65 0a 20 20 20 20   all of the.    
cee0: 20 20 20 20 23 20 49 4f 45 52 52 73 20 77 65 20      # IOERRs we 
cef0: 67 65 74 20 62 61 63 6b 20 72 65 61 6c 6c 79 20  get back really 
cf00: 64 6f 20 68 61 76 65 20 74 68 65 69 72 20 65 78  do have their ex
cf10: 74 65 6e 64 65 64 20 63 6f 64 65 20 76 61 6c 75  tended code valu
cf20: 65 73 2e 0a 20 20 20 20 20 20 20 20 23 20 49 66  es..        # If
cf30: 20 61 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73   an extended res
cf40: 75 6c 74 20 63 6f 64 65 20 69 73 20 72 65 74 75  ult code is retu
cf50: 72 6e 65 64 2c 20 74 68 65 20 73 71 6c 69 74 65  rned, the sqlite
cf60: 33 5f 65 72 72 63 6f 64 65 0a 20 20 20 20 20 20  3_errcode.      
cf70: 20 20 23 20 54 43 4c 63 6f 6d 6d 61 6e 64 20 77    # TCLcommand w
cf80: 69 6c 6c 20 72 65 74 75 72 6e 20 61 20 73 74 72  ill return a str
cf90: 69 6e 67 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a  ing of the form:
cfa0: 20 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 2b 6e    SQLITE_IOERR+n
cfb0: 6e 6e 6e 0a 20 20 20 20 20 20 20 20 23 20 77 68  nnn.        # wh
cfc0: 65 72 65 20 6e 6e 6e 6e 20 69 73 20 61 20 6e 75  ere nnnn is a nu
cfd0: 6d 62 65 72 0a 20 20 20 20 20 20 20 20 69 66 20  mber.        if 
cfe0: 7b 5b 72 65 67 65 78 70 20 7b 5e 53 51 4c 49 54  {[regexp {^SQLIT
cff0: 45 5f 49 4f 45 52 52 7d 20 24 72 63 5d 20 26 26  E_IOERR} $rc] &&
d000: 20 21 5b 72 65 67 65 78 70 20 7b 49 4f 45 52 52   ![regexp {IOERR
d010: 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20  \+\d} $rc]} {.  
d020: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 24          return $
d030: 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  rc.        }.   
d040: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
d050: 20 20 20 20 23 20 49 66 20 77 65 20 61 72 65 20      # If we are 
d060: 6e 6f 74 20 69 6e 20 65 78 74 65 6e 64 65 64 20  not in extended 
d070: 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65  result code mode
d080: 2c 20 6d 61 6b 65 20 73 75 72 65 20 6e 6f 0a 20  , make sure no. 
d090: 20 20 20 20 20 20 20 23 20 65 78 74 65 6e 64 65         # extende
d0a0: 64 20 65 72 72 6f 72 20 63 6f 64 65 73 20 61 72  d error codes ar
d0b0: 65 20 72 65 74 75 72 6e 65 64 2e 0a 20 20 20 20  e returned..    
d0c0: 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20      if {[regexp 
d0d0: 7b 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20  {\+\d} $rc]} {. 
d0e0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
d0f0: 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  $rc.        }.  
d100: 20 20 20 20 7d 0a 20 20 20 20 20 20 23 20 54 68      }.      # Th
d110: 65 20 74 65 73 74 20 72 65 70 65 61 74 73 20 61  e test repeats a
d120: 73 20 6c 6f 6e 67 20 61 73 20 24 3a 3a 67 6f 20  s long as $::go 
d130: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 20 24 3a  is non-zero.  $:
d140: 3a 67 6f 20 73 74 61 72 74 73 20 6f 75 74 0a 20  :go starts out. 
d150: 20 20 20 20 20 23 20 61 73 20 31 2e 20 20 57 68       # as 1.  Wh
d160: 65 6e 20 61 20 74 65 73 74 20 72 75 6e 73 20 74  en a test runs t
d170: 6f 20 63 6f 6d 70 6c 65 74 69 6f 6e 20 77 69 74  o completion wit
d180: 68 6f 75 74 20 68 69 74 74 69 6e 67 20 61 6e 20  hout hitting an 
d190: 49 2f 4f 0a 20 20 20 20 20 20 23 20 65 72 72 6f  I/O.      # erro
d1a0: 72 2c 20 74 68 61 74 20 6d 65 61 6e 73 20 74 68  r, that means th
d1b0: 65 72 65 20 69 73 20 6e 6f 20 70 6f 69 6e 74 20  ere is no point 
d1c0: 69 6e 20 63 6f 6e 74 69 6e 75 69 6e 67 20 77 69  in continuing wi
d1d0: 74 68 20 74 68 69 73 20 74 65 73 74 0a 20 20 20  th this test.   
d1e0: 20 20 20 23 20 63 61 73 65 20 73 6f 20 73 65 74     # case so set
d1f0: 20 24 3a 3a 67 6f 20 74 6f 20 7a 65 72 6f 2e 0a   $::go to zero..
d200: 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 69 66        #.      if
d210: 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65   {$::sqlite_io_e
d220: 72 72 6f 72 5f 70 65 6e 64 69 6e 67 3e 30 7d 20  rror_pending>0} 
d230: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a  {.        set ::
d240: 67 6f 20 30 0a 20 20 20 20 20 20 20 20 73 65 74  go 0.        set
d250: 20 71 20 30 0a 20 20 20 20 20 20 20 20 73 65 74   q 0.        set
d260: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
d270: 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 20  or_pending 0.   
d280: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
d290: 20 20 20 20 73 65 74 20 71 20 31 0a 20 20 20 20      set q 1.    
d2a0: 20 20 7d 0a 0a 20 20 20 20 20 20 73 65 74 20 73    }..      set s
d2b0: 20 5b 65 78 70 72 20 24 3a 3a 73 71 6c 69 74 65   [expr $::sqlite
d2c0: 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3d 3d 30  _io_error_hit==0
d2d0: 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 73  ].      if {$::s
d2e0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
d2f0: 69 74 3e 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  it>$::sqlite_io_
d300: 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26 26  error_hardhit &&
d310: 20 24 72 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20   $r==0} {.      
d320: 20 20 73 65 74 20 72 20 31 0a 20 20 20 20 20 20    set r 1.      
d330: 7d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  }.      set ::sq
d340: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69  lite_io_error_hi
d350: 74 20 30 0a 0a 20 20 20 20 20 20 23 20 4f 6e 65  t 0..      # One
d360: 20 6f 66 20 74 77 6f 20 74 68 69 6e 67 73 20 6d   of two things m
d370: 75 73 74 20 68 61 76 65 20 68 61 70 70 65 6e 65  ust have happene
d380: 64 2e 20 65 69 74 68 65 72 0a 20 20 20 20 20 20  d. either.      
d390: 23 20 20 20 31 2e 20 20 57 65 20 6e 65 76 65 72  #   1.  We never
d3a0: 20 68 69 74 20 74 68 65 20 49 4f 20 65 72 72 6f   hit the IO erro
d3b0: 72 20 61 6e 64 20 74 68 65 20 53 51 4c 20 72 65  r and the SQL re
d3c0: 74 75 72 6e 65 64 20 4f 4b 0a 20 20 20 20 20 20  turned OK.      
d3d0: 23 20 20 20 32 2e 20 20 41 6e 20 49 4f 20 65 72  #   2.  An IO er
d3e0: 72 6f 72 20 77 61 73 20 68 69 74 20 61 6e 64 20  ror was hit and 
d3f0: 74 68 65 20 53 51 4c 20 66 61 69 6c 65 64 0a 20  the SQL failed. 
d400: 20 20 20 20 20 23 0a 20 20 20 20 20 20 23 70 75       #.      #pu
d410: 74 73 20 22 73 3d 24 73 20 72 3d 24 72 20 71 3d  ts "s=$s r=$r q=
d420: 24 71 22 0a 20 20 20 20 20 20 65 78 70 72 20 7b  $q".      expr {
d430: 20 28 24 73 20 26 26 20 21 24 72 20 26 26 20 21   ($s && !$r && !
d440: 24 71 29 20 7c 7c 20 28 21 24 73 20 26 26 20 24  $q) || (!$s && $
d450: 72 20 26 26 20 24 71 29 20 7d 0a 20 20 20 20 7d  r && $q) }.    }
d460: 20 7b 31 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a   {1}..    set ::
d470: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
d480: 68 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a 3a  hit 0.    set ::
d490: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
d4a0: 70 65 6e 64 69 6e 67 20 30 0a 0a 20 20 20 20 23  pending 0..    #
d4b0: 20 43 68 65 63 6b 20 74 68 61 74 20 6e 6f 20 70   Check that no p
d4c0: 61 67 65 20 72 65 66 65 72 65 6e 63 65 73 20 77  age references w
d4d0: 65 72 65 20 6c 65 61 6b 65 64 2e 20 54 68 65 72  ere leaked. Ther
d4e0: 65 20 73 68 6f 75 6c 64 20 62 65 0a 20 20 20 20  e should be.    
d4f0: 23 20 61 20 73 69 6e 67 6c 65 20 72 65 66 65 72  # a single refer
d500: 65 6e 63 65 20 69 66 20 74 68 65 72 65 20 69 73  ence if there is
d510: 20 73 74 69 6c 6c 20 61 6e 20 61 63 74 69 76 65   still an active
d520: 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 0a 20 20   transaction,.  
d530: 20 20 23 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65    # or zero othe
d540: 72 77 69 73 65 2e 0a 20 20 20 20 23 0a 20 20 20  rwise..    #.   
d550: 20 23 20 55 50 44 41 54 45 3a 20 49 66 20 74 68   # UPDATE: If th
d560: 65 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72  e IO error occur
d570: 73 20 61 66 74 65 72 20 61 20 27 42 45 47 49 4e  s after a 'BEGIN
d580: 27 20 62 75 74 20 62 65 66 6f 72 65 20 61 6e 79  ' but before any
d590: 0a 20 20 20 20 23 20 6c 6f 63 6b 73 20 61 72 65  .    # locks are
d5a0: 20 65 73 74 61 62 6c 69 73 68 65 64 20 6f 6e 20   established on 
d5b0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 28  database files (
d5c0: 69 2e 65 2e 20 69 66 20 74 68 65 20 65 72 72 6f  i.e. if the erro
d5d0: 72 0a 20 20 20 20 23 20 6f 63 63 75 72 73 20 77  r.    # occurs w
d5e0: 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20  hile attempting 
d5f0: 74 6f 20 64 65 74 65 63 74 20 61 20 68 6f 74 2d  to detect a hot-
d600: 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 29 2c 20 74  journal file), t
d610: 68 65 6e 0a 20 20 20 20 23 20 74 68 65 72 65 20  hen.    # there 
d620: 6d 61 79 20 30 20 70 61 67 65 20 72 65 66 65 72  may 0 page refer
d630: 65 6e 63 65 73 20 61 6e 64 20 61 6e 20 61 63 74  ences and an act
d640: 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ive transaction 
d650: 61 63 63 6f 72 64 69 6e 67 0a 20 20 20 20 23 20  according.    # 
d660: 74 6f 20 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f  to [sqlite3_get_
d670: 61 75 74 6f 63 6f 6d 6d 69 74 5d 2e 0a 20 20 20  autocommit]..   
d680: 20 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f   #.    if {$::go
d690: 20 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f   && $::sqlite_io
d6a0: 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26  _error_hardhit &
d6b0: 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  & $::ioerropts(-
d6c0: 63 6b 72 65 66 63 6f 75 6e 74 29 7d 20 7b 0a 20  ckrefcount)} {. 
d6d0: 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65       do_test $te
d6e0: 73 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b 0a 20 20  stname.$n.4 {.  
d6f0: 20 20 20 20 20 20 73 65 74 20 62 74 20 5b 62 74        set bt [bt
d700: 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a  ree_from_db db].
d710: 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74 65 72          db_enter
d720: 20 64 62 0a 20 20 20 20 20 20 20 20 61 72 72 61   db.        arra
d730: 79 20 73 65 74 20 73 74 61 74 73 20 5b 62 74 72  y set stats [btr
d740: 65 65 5f 70 61 67 65 72 5f 73 74 61 74 73 20 24  ee_pager_stats $
d750: 62 74 5d 0a 20 20 20 20 20 20 20 20 64 62 5f 6c  bt].        db_l
d760: 65 61 76 65 20 64 62 0a 20 20 20 20 20 20 20 20  eave db.        
d770: 73 65 74 20 6e 52 65 66 20 24 73 74 61 74 73 28  set nRef $stats(
d780: 72 65 66 29 0a 20 20 20 20 20 20 20 20 65 78 70  ref).        exp
d790: 72 20 7b 24 6e 52 65 66 20 3d 3d 20 30 20 7c 7c  r {$nRef == 0 ||
d7a0: 20 28 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61   ([sqlite3_get_a
d7b0: 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 3d 3d 30  utocommit db]==0
d7c0: 20 26 26 20 24 6e 52 65 66 20 3d 3d 20 31 29 7d   && $nRef == 1)}
d7d0: 0a 20 20 20 20 20 20 7d 20 7b 31 7d 0a 20 20 20  .      } {1}.   
d7e0: 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 74 68 65   }..    # If the
d7f0: 72 65 20 69 73 20 61 6e 20 6f 70 65 6e 20 64 61  re is an open da
d800: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 61 6e  tabase handle an
d810: 64 20 6e 6f 20 6f 70 65 6e 20 74 72 61 6e 73 61  d no open transa
d820: 63 74 69 6f 6e 2c 0a 20 20 20 20 23 20 61 6e 64  ction,.    # and
d830: 20 74 68 65 20 70 61 67 65 72 20 69 73 20 6e 6f   the pager is no
d840: 74 20 72 75 6e 6e 69 6e 67 20 69 6e 20 65 78 63  t running in exc
d850: 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67 20 6d  lusive-locking m
d860: 6f 64 65 2c 0a 20 20 20 20 23 20 63 68 65 63 6b  ode,.    # check
d870: 20 74 68 61 74 20 74 68 65 20 70 61 67 65 72 20   that the pager 
d880: 69 73 20 69 6e 20 22 75 6e 6c 6f 63 6b 65 64 22  is in "unlocked"
d890: 20 73 74 61 74 65 2e 20 54 68 65 6f 72 65 74 69   state. Theoreti
d8a0: 63 61 6c 6c 79 2c 0a 20 20 20 20 23 20 69 66 20  cally,.    # if 
d8b0: 61 20 63 61 6c 6c 20 74 6f 20 78 55 6e 6c 6f 63  a call to xUnloc
d8c0: 6b 28 29 20 66 61 69 6c 65 64 20 64 75 65 20 74  k() failed due t
d8d0: 6f 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 74 68  o an IO error th
d8e0: 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 20 20 20  e underlying.   
d8f0: 20 23 20 66 69 6c 65 20 6d 61 79 20 73 74 69 6c   # file may stil
d900: 6c 20 62 65 20 6c 6f 63 6b 65 64 2e 0a 20 20 20  l be locked..   
d910: 20 23 0a 20 20 20 20 69 66 63 61 70 61 62 6c 65   #.    ifcapable
d920: 20 70 72 61 67 6d 61 20 7b 0a 20 20 20 20 20 20   pragma {.      
d930: 69 66 20 7b 20 5b 69 6e 66 6f 20 63 6f 6d 6d 61  if { [info comma
d940: 6e 64 73 20 64 62 5d 20 6e 65 20 22 22 0a 20 20  nds db] ne "".  
d950: 20 20 20 20 20 20 26 26 20 24 3a 3a 69 6f 65 72        && $::ioer
d960: 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e  ropts(-ckrefcoun
d970: 74 29 0a 20 20 20 20 20 20 20 20 26 26 20 5b 64  t).        && [d
d980: 62 20 6f 6e 65 20 7b 70 72 61 67 6d 61 20 6c 6f  b one {pragma lo
d990: 63 6b 69 6e 67 5f 6d 6f 64 65 7d 5d 20 65 71 20  cking_mode}] eq 
d9a0: 22 6e 6f 72 6d 61 6c 22 0a 20 20 20 20 20 20 20  "normal".       
d9b0: 20 26 26 20 5b 73 71 6c 69 74 65 33 5f 67 65 74   && [sqlite3_get
d9c0: 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 0a  _autocommit db].
d9d0: 20 20 20 20 20 20 7d 20 7b 0a 20 20 20 20 20 20        } {.      
d9e0: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
d9f0: 61 6d 65 2e 24 6e 2e 35 20 7b 0a 20 20 20 20 20  ame.$n.5 {.     
da00: 20 20 20 20 20 73 65 74 20 62 74 20 5b 62 74 72       set bt [btr
da10: 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a 20  ee_from_db db]. 
da20: 20 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74 65           db_ente
da30: 72 20 64 62 0a 20 20 20 20 20 20 20 20 20 20 61  r db.          a
da40: 72 72 61 79 20 73 65 74 20 73 74 61 74 73 20 5b  rray set stats [
da50: 62 74 72 65 65 5f 70 61 67 65 72 5f 73 74 61 74  btree_pager_stat
da60: 73 20 24 62 74 5d 0a 20 20 20 20 20 20 20 20 20  s $bt].         
da70: 20 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20 20   db_leave db.   
da80: 20 20 20 20 20 20 20 73 65 74 20 73 74 61 74 73         set stats
da90: 28 73 74 61 74 65 29 0a 20 20 20 20 20 20 20 20  (state).        
daa0: 7d 20 30 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  } 0.      }.    
dab0: 7d 0a 0a 20 20 20 20 23 20 49 66 20 61 6e 20 49  }..    # If an I
dac0: 4f 20 65 72 72 6f 72 20 6f 63 63 75 72 72 65 64  O error occurred
dad0: 2c 20 74 68 65 6e 20 74 68 65 20 63 68 65 63 6b  , then the check
dae0: 73 75 6d 20 6f 66 20 74 68 65 20 64 61 74 61 62  sum of the datab
daf0: 61 73 65 20 73 68 6f 75 6c 64 0a 20 20 20 20 23  ase should.    #
db00: 20 62 65 20 74 68 65 20 73 61 6d 65 20 61 73 20   be the same as 
db10: 62 65 66 6f 72 65 20 74 68 65 20 73 63 72 69 70  before the scrip
db20: 74 20 74 68 61 74 20 63 61 75 73 65 64 20 74 68  t that caused th
db30: 65 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20 72  e IO error was r
db40: 75 6e 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66  un..    #.    if
db50: 20 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71   {$::go && $::sq
db60: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61  lite_io_error_ha
db70: 72 64 68 69 74 20 26 26 20 24 3a 3a 69 6f 65 72  rdhit && $::ioer
db80: 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b  ropts(-cksum)} {
db90: 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24  .      do_test $
dba0: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 36 20 7b 0a  testname.$n.6 {.
dbb0: 20 20 20 20 20 20 20 20 63 61 74 63 68 20 7b 64          catch {d
dbc0: 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20  b close}.       
dbd0: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
dbe0: 65 7d 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a  e}.        set :
dbf0: 3a 44 42 20 5b 73 71 6c 69 74 65 33 20 64 62 20  :DB [sqlite3 db 
dc00: 74 65 73 74 2e 64 62 3b 20 73 71 6c 69 74 65 33  test.db; sqlite3
dc10: 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e  _connection_poin
dc20: 74 65 72 20 64 62 5d 0a 20 20 20 20 20 20 20 20  ter db].        
dc30: 73 65 74 20 6e 6f 77 63 6b 73 75 6d 20 5b 63 6b  set nowcksum [ck
dc40: 73 75 6d 5d 0a 20 20 20 20 20 20 20 20 73 65 74  sum].        set
dc50: 20 72 65 73 20 5b 65 78 70 72 20 7b 24 6e 6f 77   res [expr {$now
dc60: 63 6b 73 75 6d 3d 3d 24 3a 3a 63 68 65 63 6b 73  cksum==$::checks
dc70: 75 6d 20 7c 7c 20 24 6e 6f 77 63 6b 73 75 6d 3d  um || $nowcksum=
dc80: 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75 6d 7d 5d 0a  =$::goodcksum}].
dc90: 20 20 20 20 20 20 20 20 69 66 20 7b 24 72 65 73          if {$res
dca0: 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  ==0} {.         
dcb0: 20 6f 75 74 70 75 74 32 20 22 6e 6f 77 3d 24 6e   output2 "now=$n
dcc0: 6f 77 63 6b 73 75 6d 22 0a 20 20 20 20 20 20 20  owcksum".       
dcd0: 20 20 20 6f 75 74 70 75 74 32 20 22 74 68 65 3d     output2 "the=
dce0: 24 3a 3a 63 68 65 63 6b 73 75 6d 22 0a 20 20 20  $::checksum".   
dcf0: 20 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22         output2 "
dd00: 66 77 64 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75 6d  fwd=$::goodcksum
dd10: 22 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ".        }.    
dd20: 20 20 20 20 73 65 74 20 72 65 73 0a 20 20 20 20      set res.    
dd30: 20 20 7d 20 31 0a 20 20 20 20 7d 0a 0a 20 20 20    } 1.    }..   
dd40: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
dd50: 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 30  _error_hardhit 0
dd60: 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74  .    set ::sqlit
dd70: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
dd80: 6e 67 20 30 0a 20 20 20 20 69 66 20 7b 5b 69 6e  ng 0.    if {[in
dd90: 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72  fo exists ::ioer
dda0: 72 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70 29 5d  ropts(-cleanup)]
ddb0: 7d 20 7b 0a 20 20 20 20 20 20 63 61 74 63 68 20  } {.      catch 
ddc0: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c  $::ioerropts(-cl
ddd0: 65 61 6e 75 70 29 0a 20 20 20 20 7d 0a 20 20 7d  eanup).    }.  }
dde0: 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f  .  set ::sqlite_
ddf0: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
de00: 20 30 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74   0.  set ::sqlit
de10: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69  e_io_error_persi
de20: 73 74 20 30 0a 20 20 75 6e 73 65 74 20 3a 3a 69  st 0.  unset ::i
de30: 6f 65 72 72 6f 70 74 73 0a 7d 0a 0a 23 20 52 65  oerropts.}..# Re
de40: 74 75 72 6e 20 61 20 63 68 65 63 6b 73 75 6d 20  turn a checksum 
de50: 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e  based on the con
de60: 74 65 6e 74 73 20 6f 66 20 74 68 65 20 6d 61 69  tents of the mai
de70: 6e 20 64 61 74 61 62 61 73 65 20 61 73 73 6f 63  n database assoc
de80: 69 61 74 65 64 0a 23 20 77 69 74 68 20 63 6f 6e  iated.# with con
de90: 6e 65 63 74 69 6f 6e 20 24 64 62 0a 23 0a 70 72  nection $db.#.pr
dea0: 6f 63 20 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62  oc cksum {{db db
deb0: 7d 7d 20 7b 0a 20 20 73 65 74 20 74 78 74 20 5b  }} {.  set txt [
dec0: 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20  $db eval {.     
ded0: 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79   SELECT name, ty
dee0: 70 65 2c 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c  pe, sql FROM sql
def0: 69 74 65 5f 6d 61 73 74 65 72 20 6f 72 64 65 72  ite_master order
df00: 20 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e 0a   by name.  }]\n.
df10: 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20 5b 24    foreach tbl [$
df20: 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20  db eval {.      
df30: 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d  SELECT name FROM
df40: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
df50: 48 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c 65  HERE type='table
df60: 27 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65 0a  ' order by name.
df70: 20 20 7d 5d 20 7b 0a 20 20 20 20 61 70 70 65 6e    }] {.    appen
df80: 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20  d txt [$db eval 
df90: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24  "SELECT * FROM $
dfa0: 74 62 6c 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66 6f  tbl"]\n.  }.  fo
dfb0: 72 65 61 63 68 20 70 72 61 67 20 7b 64 65 66 61  reach prag {defa
dfc0: 75 6c 74 5f 73 79 6e 63 68 72 6f 6e 6f 75 73 20  ult_synchronous 
dfd0: 64 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73 69  default_cache_si
dfe0: 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64  ze} {.    append
dff0: 20 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62 20   txt $prag-[$db 
e000: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70 72  eval "PRAGMA $pr
e010: 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65 74  ag"]\n.  }.  set
e020: 20 63 6b 73 75 6d 20 5b 73 74 72 69 6e 67 20 6c   cksum [string l
e030: 65 6e 67 74 68 20 24 74 78 74 5d 2d 5b 6d 64 35  ength $txt]-[md5
e040: 20 24 74 78 74 5d 0a 20 20 23 20 70 75 74 73 20   $txt].  # puts 
e050: 24 63 6b 73 75 6d 2d 5b 66 69 6c 65 20 73 69 7a  $cksum-[file siz
e060: 65 20 74 65 73 74 2e 64 62 5d 0a 20 20 72 65 74  e test.db].  ret
e070: 75 72 6e 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23 20  urn $cksum.}..# 
e080: 47 65 6e 65 72 61 74 65 20 61 20 63 68 65 63 6b  Generate a check
e090: 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65  sum based on the
e0a0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
e0b0: 20 6d 61 69 6e 20 61 6e 64 20 74 65 6d 70 20 74   main and temp t
e0c0: 61 62 6c 65 73 0a 23 20 64 61 74 61 62 61 73 65  ables.# database
e0d0: 20 24 64 62 2e 20 49 66 20 74 68 65 20 63 68 65   $db. If the che
e0e0: 63 6b 73 75 6d 20 6f 66 20 74 77 6f 20 64 61 74  cksum of two dat
e0f0: 61 62 61 73 65 73 20 69 73 20 74 68 65 20 73 61  abases is the sa
e100: 6d 65 2c 20 61 6e 64 20 74 68 65 0a 23 20 69 6e  me, and the.# in
e110: 74 65 67 72 69 74 79 2d 63 68 65 63 6b 20 70 61  tegrity-check pa
e120: 73 73 65 73 20 66 6f 72 20 62 6f 74 68 2c 20 74  sses for both, t
e130: 68 65 20 74 77 6f 20 64 61 74 61 62 61 73 65 73  he two databases
e140: 20 61 72 65 20 69 64 65 6e 74 69 63 61 6c 2e 0a   are identical..
e150: 23 0a 70 72 6f 63 20 61 6c 6c 63 6b 73 75 6d 20  #.proc allcksum 
e160: 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65  {{db db}} {.  se
e170: 74 20 72 65 74 20 5b 6c 69 73 74 5d 0a 20 20 69  t ret [list].  i
e180: 66 63 61 70 61 62 6c 65 20 74 65 6d 70 64 62 20  fcapable tempdb 
e190: 7b 0a 20 20 20 20 73 65 74 20 73 71 6c 20 7b 0a  {.    set sql {.
e1a0: 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d        SELECT nam
e1b0: 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  e FROM sqlite_ma
e1c0: 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65 20  ster WHERE type 
e1d0: 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a  = 'table' UNION.
e1e0: 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d        SELECT nam
e1f0: 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 74 65  e FROM sqlite_te
e200: 6d 70 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20  mp_master WHERE 
e210: 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55  type = 'table' U
e220: 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43  NION.      SELEC
e230: 54 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  T 'sqlite_master
e240: 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45  ' UNION.      SE
e250: 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 74 65 6d  LECT 'sqlite_tem
e260: 70 5f 6d 61 73 74 65 72 27 20 4f 52 44 45 52 20  p_master' ORDER 
e270: 42 59 20 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65  BY 1.    }.  } e
e280: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 73 71  lse {.    set sq
e290: 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l {.      SELECT
e2a0: 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74   name FROM sqlit
e2b0: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  e_master WHERE t
e2c0: 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e  ype = 'table' UN
e2d0: 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54  ION.      SELECT
e2e0: 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27   'sqlite_master'
e2f0: 20 4f 52 44 45 52 20 42 59 20 31 0a 20 20 20 20   ORDER BY 1.    
e300: 7d 0a 20 20 7d 0a 20 20 73 65 74 20 74 62 6c 6c  }.  }.  set tbll
e310: 69 73 74 20 5b 24 64 62 20 65 76 61 6c 20 24 73  ist [$db eval $s
e320: 71 6c 5d 0a 20 20 73 65 74 20 74 78 74 20 7b 7d  ql].  set txt {}
e330: 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20 24  .  foreach tbl $
e340: 74 62 6c 6c 69 73 74 20 7b 0a 20 20 20 20 61 70  tbllist {.    ap
e350: 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76  pend txt [$db ev
e360: 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  al "SELECT * FRO
e370: 4d 20 24 74 62 6c 22 5d 0a 20 20 7d 0a 20 20 66  M $tbl"].  }.  f
e380: 6f 72 65 61 63 68 20 70 72 61 67 20 7b 64 65 66  oreach prag {def
e390: 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d  ault_cache_size}
e3a0: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78   {.    append tx
e3b0: 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76 61  t $prag-[$db eva
e3c0: 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61 67 22  l "PRAGMA $prag"
e3d0: 5d 5c 6e 0a 20 20 7d 0a 20 20 23 20 70 75 74 73  ]\n.  }.  # puts
e3e0: 20 74 78 74 3d 24 74 78 74 0a 20 20 72 65 74 75   txt=$txt.  retu
e3f0: 72 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a  rn [md5 $txt].}.
e400: 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 63 68  .# Generate a ch
e410: 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20  ecksum based on 
e420: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
e430: 61 20 73 69 6e 67 6c 65 20 64 61 74 61 62 61 73  a single databas
e440: 65 20 77 69 74 68 0a 23 20 61 20 64 61 74 61 62  e with.# a datab
e450: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20  ase connection. 
e460: 20 54 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65   The name of the
e470: 20 64 61 74 61 62 61 73 65 20 69 73 20 24 64 62   database is $db
e480: 6e 61 6d 65 2e 0a 23 20 45 78 61 6d 70 6c 65 73  name..# Examples
e490: 20 6f 66 20 24 64 62 6e 61 6d 65 20 61 72 65 20   of $dbname are 
e4a0: 22 74 65 6d 70 22 20 6f 72 20 22 6d 61 69 6e 22  "temp" or "main"
e4b0: 2e 0a 23 0a 70 72 6f 63 20 64 62 63 6b 73 75 6d  ..#.proc dbcksum
e4c0: 20 7b 64 62 20 64 62 6e 61 6d 65 7d 20 7b 0a 20   {db dbname} {. 
e4d0: 20 69 66 20 7b 24 64 62 6e 61 6d 65 3d 3d 22 74   if {$dbname=="t
e4e0: 65 6d 70 22 7d 20 7b 0a 20 20 20 20 73 65 74 20  emp"} {.    set 
e4f0: 6d 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74 65  master sqlite_te
e500: 6d 70 5f 6d 61 73 74 65 72 0a 20 20 7d 20 65 6c  mp_master.  } el
e510: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 6d 61 73  se {.    set mas
e520: 74 65 72 20 24 64 62 6e 61 6d 65 2e 73 71 6c 69  ter $dbname.sqli
e530: 74 65 5f 6d 61 73 74 65 72 0a 20 20 7d 0a 20 20  te_master.  }.  
e540: 73 65 74 20 61 6c 6c 74 61 62 20 5b 24 64 62 20  set alltab [$db 
e550: 65 76 61 6c 20 22 53 45 4c 45 43 54 20 6e 61 6d  eval "SELECT nam
e560: 65 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 20 57  e FROM $master W
e570: 48 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c 65  HERE type='table
e580: 27 22 5d 0a 20 20 73 65 74 20 74 78 74 20 5b 24  '"].  set txt [$
e590: 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20  db eval "SELECT 
e5a0: 2a 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 22 5d  * FROM $master"]
e5b0: 5c 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 61 62  \n.  foreach tab
e5c0: 20 24 61 6c 6c 74 61 62 20 7b 0a 20 20 20 20 61   $alltab {.    a
e5d0: 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65  ppend txt [$db e
e5e0: 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  val "SELECT * FR
e5f0: 4f 4d 20 24 64 62 6e 61 6d 65 2e 24 74 61 62 22  OM $dbname.$tab"
e600: 5d 5c 6e 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ]\n.  }.  return
e610: 20 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 70   [md5 $txt].}..p
e620: 72 6f 63 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67  roc memdebug_log
e630: 5f 73 71 6c 20 7b 7b 66 69 6c 65 6e 61 6d 65 20  _sql {{filename 
e640: 6d 61 6c 6c 6f 63 73 2e 73 71 6c 7d 7d 20 7b 0a  mallocs.sql}} {.
e650: 0a 20 20 73 65 74 20 64 61 74 61 20 5b 73 71 6c  .  set data [sql
e660: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f  ite3_memdebug_lo
e670: 67 20 64 75 6d 70 5d 0a 20 20 73 65 74 20 6e 46  g dump].  set nF
e680: 72 61 6d 65 20 5b 65 78 70 72 20 5b 6c 6c 65 6e  rame [expr [llen
e690: 67 74 68 20 5b 6c 69 6e 64 65 78 20 24 64 61 74  gth [lindex $dat
e6a0: 61 20 30 5d 5d 2d 32 5d 0a 20 20 69 66 20 7b 24  a 0]]-2].  if {$
e6b0: 6e 46 72 61 6d 65 20 3c 20 30 7d 20 7b 20 72 65  nFrame < 0} { re
e6c0: 74 75 72 6e 20 22 22 20 7d 0a 0a 20 20 73 65 74  turn "" }..  set
e6d0: 20 64 61 74 61 62 61 73 65 20 74 65 6d 70 0a 0a   database temp..
e6e0: 20 20 73 65 74 20 74 62 6c 20 22 43 52 45 41 54    set tbl "CREAT
e6f0: 45 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61  E TABLE ${databa
e700: 73 65 7d 2e 6d 61 6c 6c 6f 63 28 7a 54 65 73 74  se}.malloc(zTest
e710: 2c 20 6e 43 61 6c 6c 2c 20 6e 42 79 74 65 2c 20  , nCall, nByte, 
e720: 6c 53 74 61 63 6b 29 3b 22 0a 0a 20 20 73 65 74  lStack);"..  set
e730: 20 73 71 6c 20 22 22 0a 20 20 66 6f 72 65 61 63   sql "".  foreac
e740: 68 20 65 20 24 64 61 74 61 20 7b 0a 20 20 20 20  h e $data {.    
e750: 73 65 74 20 6e 43 61 6c 6c 20 5b 6c 69 6e 64 65  set nCall [linde
e760: 78 20 24 65 20 30 5d 0a 20 20 20 20 73 65 74 20  x $e 0].    set 
e770: 6e 42 79 74 65 20 5b 6c 69 6e 64 65 78 20 24 65  nByte [lindex $e
e780: 20 31 5d 0a 20 20 20 20 73 65 74 20 6c 53 74 61   1].    set lSta
e790: 63 6b 20 5b 6c 72 61 6e 67 65 20 24 65 20 32 20  ck [lrange $e 2 
e7a0: 65 6e 64 5d 0a 20 20 20 20 61 70 70 65 6e 64 20  end].    append 
e7b0: 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  sql "INSERT INTO
e7c0: 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c   ${database}.mal
e7d0: 6c 6f 63 20 56 41 4c 55 45 53 22 0a 20 20 20 20  loc VALUES".    
e7e0: 61 70 70 65 6e 64 20 73 71 6c 20 22 28 27 74 65  append sql "('te
e7f0: 73 74 27 2c 20 24 6e 43 61 6c 6c 2c 20 24 6e 42  st', $nCall, $nB
e800: 79 74 65 2c 20 27 24 6c 53 74 61 63 6b 27 29 3b  yte, '$lStack');
e810: 5c 6e 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20  \n".    foreach 
e820: 66 20 24 6c 53 74 61 63 6b 20 7b 0a 20 20 20 20  f $lStack {.    
e830: 20 20 73 65 74 20 66 72 61 6d 65 73 28 24 66 29    set frames($f)
e840: 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   1.    }.  }..  
e850: 73 65 74 20 74 62 6c 32 20 22 43 52 45 41 54 45  set tbl2 "CREATE
e860: 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73   TABLE ${databas
e870: 65 7d 2e 66 72 61 6d 65 28 66 72 61 6d 65 20 49  e}.frame(frame I
e880: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b  NTEGER PRIMARY K
e890: 45 59 2c 20 6c 69 6e 65 29 3b 5c 6e 22 0a 20 20  EY, line);\n".  
e8a0: 73 65 74 20 74 62 6c 33 20 22 43 52 45 41 54 45  set tbl3 "CREATE
e8b0: 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73   TABLE ${databas
e8c0: 65 7d 2e 66 69 6c 65 28 6e 61 6d 65 20 50 52 49  e}.file(name PRI
e8d0: 4d 41 52 59 20 4b 45 59 2c 20 63 6f 6e 74 65 6e  MARY KEY, conten
e8e0: 74 29 3b 5c 6e 22 0a 0a 20 20 66 6f 72 65 61 63  t);\n"..  foreac
e8f0: 68 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73  h f [array names
e900: 20 66 72 61 6d 65 73 5d 20 7b 0a 20 20 20 20 73   frames] {.    s
e910: 65 74 20 61 64 64 72 20 5b 66 6f 72 6d 61 74 20  et addr [format 
e920: 25 78 20 24 66 5d 0a 20 20 20 20 73 65 74 20 63  %x $f].    set c
e930: 6d 64 20 22 61 64 64 72 32 6c 69 6e 65 20 2d 65  md "addr2line -e
e940: 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65   [info nameofexe
e950: 63 5d 20 24 61 64 64 72 22 0a 20 20 20 20 73 65  c] $addr".    se
e960: 74 20 6c 69 6e 65 20 5b 65 76 61 6c 20 65 78 65  t line [eval exe
e970: 63 20 24 63 6d 64 5d 0a 20 20 20 20 61 70 70 65  c $cmd].    appe
e980: 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49  nd sql "INSERT I
e990: 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e  NTO ${database}.
e9a0: 66 72 61 6d 65 20 56 41 4c 55 45 53 28 24 66 2c  frame VALUES($f,
e9b0: 20 27 24 6c 69 6e 65 27 29 3b 5c 6e 22 0a 0a 20   '$line');\n".. 
e9c0: 20 20 20 73 65 74 20 66 69 6c 65 20 5b 6c 69 6e     set file [lin
e9d0: 64 65 78 20 5b 73 70 6c 69 74 20 24 6c 69 6e 65  dex [split $line
e9e0: 20 3a 5d 20 30 5d 0a 20 20 20 20 73 65 74 20 66   :] 0].    set f
e9f0: 69 6c 65 73 28 24 66 69 6c 65 29 20 31 0a 20 20  iles($file) 1.  
ea00: 7d 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b  }..  foreach f [
ea10: 61 72 72 61 79 20 6e 61 6d 65 73 20 66 69 6c 65  array names file
ea20: 73 5d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6e  s] {.    set con
ea30: 74 65 6e 74 73 20 22 22 0a 20 20 20 20 63 61 74  tents "".    cat
ea40: 63 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66  ch {.      set f
ea50: 64 20 5b 6f 70 65 6e 20 24 66 5d 0a 20 20 20 20  d [open $f].    
ea60: 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 5b    set contents [
ea70: 72 65 61 64 20 24 66 64 5d 0a 20 20 20 20 20 20  read $fd].      
ea80: 63 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 7d 0a  close $fd.    }.
ea90: 20 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73      set contents
eaa0: 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20   [string map {' 
eab0: 27 27 7d 20 24 63 6f 6e 74 65 6e 74 73 5d 0a 20  ''} $contents]. 
eac0: 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49     append sql "I
ead0: 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74  NSERT INTO ${dat
eae0: 61 62 61 73 65 7d 2e 66 69 6c 65 20 56 41 4c 55  abase}.file VALU
eaf0: 45 53 28 27 24 66 27 2c 20 27 24 63 6f 6e 74 65  ES('$f', '$conte
eb00: 6e 74 73 27 29 3b 5c 6e 22 0a 20 20 7d 0a 0a 20  nts');\n".  }.. 
eb10: 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66   set fd [open $f
eb20: 69 6c 65 6e 61 6d 65 20 77 5d 0a 20 20 70 75 74  ilename w].  put
eb30: 73 20 24 66 64 20 22 42 45 47 49 4e 3b 20 24 7b  s $fd "BEGIN; ${
eb40: 74 62 6c 7d 24 7b 74 62 6c 32 7d 24 7b 74 62 6c  tbl}${tbl2}${tbl
eb50: 33 7d 24 7b 73 71 6c 7d 20 3b 20 43 4f 4d 4d 49  3}${sql} ; COMMI
eb60: 54 3b 22 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a  T;".  close $fd.
eb70: 7d 0a 0a 23 20 44 72 6f 70 20 61 6c 6c 20 74 61  }..# Drop all ta
eb80: 62 6c 65 73 20 69 6e 20 64 61 74 61 62 61 73 65  bles in database
eb90: 20 5b 64 62 5d 0a 70 72 6f 63 20 64 72 6f 70 5f   [db].proc drop_
eba0: 61 6c 6c 5f 74 61 62 6c 65 73 20 7b 7b 64 62 20  all_tables {{db 
ebb0: 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61 62  db}} {.  ifcapab
ebc0: 6c 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65  le trigger&&fore
ebd0: 69 67 6e 6b 65 79 20 7b 0a 20 20 20 20 73 65 74  ignkey {.    set
ebe0: 20 70 6b 20 5b 24 64 62 20 6f 6e 65 20 22 50 52   pk [$db one "PR
ebf0: 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79  AGMA foreign_key
ec00: 73 22 5d 0a 20 20 20 20 24 64 62 20 65 76 61 6c  s"].    $db eval
ec10: 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67 6e   "PRAGMA foreign
ec20: 5f 6b 65 79 73 20 3d 20 4f 46 46 22 0a 20 20 7d  _keys = OFF".  }
ec30: 0a 20 20 66 6f 72 65 61 63 68 20 7b 69 64 78 20  .  foreach {idx 
ec40: 6e 61 6d 65 20 66 69 6c 65 7d 20 5b 64 62 20 65  name file} [db e
ec50: 76 61 6c 20 7b 50 52 41 47 4d 41 20 64 61 74 61  val {PRAGMA data
ec60: 62 61 73 65 5f 6c 69 73 74 7d 5d 20 7b 0a 20 20  base_list}] {.  
ec70: 20 20 69 66 20 7b 24 69 64 78 3d 3d 31 7d 20 7b    if {$idx==1} {
ec80: 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74 65  .      set maste
ec90: 72 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61  r sqlite_temp_ma
eca0: 73 74 65 72 0a 20 20 20 20 7d 20 65 6c 73 65 20  ster.    } else 
ecb0: 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74  {.      set mast
ecc0: 65 72 20 24 6e 61 6d 65 2e 73 71 6c 69 74 65 5f  er $name.sqlite_
ecd0: 6d 61 73 74 65 72 0a 20 20 20 20 7d 0a 20 20 20  master.    }.   
ece0: 20 66 6f 72 65 61 63 68 20 7b 74 20 74 79 70 65   foreach {t type
ecf0: 7d 20 5b 24 64 62 20 65 76 61 6c 20 22 0a 20 20  } [$db eval ".  
ed00: 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c      SELECT name,
ed10: 20 74 79 70 65 20 46 52 4f 4d 20 24 6d 61 73 74   type FROM $mast
ed20: 65 72 0a 20 20 20 20 20 20 57 48 45 52 45 20 74  er.      WHERE t
ed30: 79 70 65 20 49 4e 28 27 74 61 62 6c 65 27 2c 20  ype IN('table', 
ed40: 27 76 69 65 77 27 29 20 41 4e 44 20 6e 61 6d 65  'view') AND name
ed50: 20 4e 4f 54 20 4c 49 4b 45 20 27 73 71 6c 69 74   NOT LIKE 'sqlit
ed60: 65 58 5f 25 27 20 45 53 43 41 50 45 20 27 58 27  eX_%' ESCAPE 'X'
ed70: 0a 20 20 20 20 22 5d 20 7b 0a 20 20 20 20 20 20  .    "] {.      
ed80: 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20 24  $db eval "DROP $
ed90: 74 79 70 65 20 5c 22 24 74 5c 22 22 0a 20 20 20  type \"$t\"".   
eda0: 20 7d 0a 20 20 7d 0a 20 20 69 66 63 61 70 61 62   }.  }.  ifcapab
edb0: 6c 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65  le trigger&&fore
edc0: 69 67 6e 6b 65 79 20 7b 0a 20 20 20 20 24 64 62  ignkey {.    $db
edd0: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66 6f   eval "PRAGMA fo
ede0: 72 65 69 67 6e 5f 6b 65 79 73 20 3d 20 24 70 6b  reign_keys = $pk
edf0: 22 0a 20 20 7d 0a 7d 0a 0a 23 20 44 72 6f 70 20  ".  }.}..# Drop 
ee00: 61 6c 6c 20 61 75 78 69 6c 69 61 72 79 20 69 6e  all auxiliary in
ee10: 64 65 78 65 73 20 66 72 6f 6d 20 74 68 65 20 6d  dexes from the m
ee20: 61 69 6e 20 64 61 74 61 62 61 73 65 20 6f 70 65  ain database ope
ee30: 6e 65 64 20 62 79 20 68 61 6e 64 6c 65 20 5b 64  ned by handle [d
ee40: 62 5d 2e 0a 23 0a 70 72 6f 63 20 64 72 6f 70 5f  b]..#.proc drop_
ee50: 61 6c 6c 5f 69 6e 64 65 78 65 73 20 7b 7b 64 62  all_indexes {{db
ee60: 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 4c 20   db}} {.  set L 
ee70: 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20  [$db eval {.    
ee80: 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d  SELECT name FROM
ee90: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
eea0: 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65 78  HERE type='index
eeb0: 27 20 41 4e 44 20 73 71 6c 20 4c 49 4b 45 20 27  ' AND sql LIKE '
eec0: 63 72 65 61 74 65 25 27 0a 20 20 7d 5d 0a 20 20  create%'.  }].  
eed0: 66 6f 72 65 61 63 68 20 69 64 78 20 24 4c 20 7b  foreach idx $L {
eee0: 20 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20   $db eval "DROP 
eef0: 49 4e 44 45 58 20 24 69 64 78 22 20 7d 0a 7d 0a  INDEX $idx" }.}.
ef00: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
ef10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ef20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ef30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ef40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 49  ------------.# I
ef50: 66 20 61 20 74 65 73 74 20 73 63 72 69 70 74 20  f a test script 
ef60: 69 73 20 65 78 65 63 75 74 65 64 20 77 69 74 68  is executed with
ef70: 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
ef80: 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65 29   $::G(perm:name)
ef90: 20 73 65 74 20 74 6f 0a 23 20 22 77 61 6c 22 2c   set to.# "wal",
efa0: 20 74 68 65 6e 20 74 68 65 20 74 65 73 74 73 20   then the tests 
efb0: 61 72 65 20 72 75 6e 20 69 6e 20 57 41 4c 20 6d  are run in WAL m
efc0: 6f 64 65 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ode. Otherwise, 
efd0: 74 68 65 79 20 73 68 6f 75 6c 64 20 62 65 20 72  they should be r
efe0: 75 6e 0a 23 20 69 6e 20 72 6f 6c 6c 62 61 63 6b  un.# in rollback
eff0: 20 6d 6f 64 65 2e 20 54 68 65 20 66 6f 6c 6c 6f   mode. The follo
f000: 77 69 6e 67 20 54 63 6c 20 70 72 6f 63 73 20 61  wing Tcl procs a
f010: 72 65 20 75 73 65 64 20 74 6f 20 6d 61 6b 65 20  re used to make 
f020: 74 68 69 73 20 6c 65 73 73 0a 23 20 69 6e 74 72  this less.# intr
f030: 75 73 69 76 65 3a 0a 23 0a 23 20 20 20 77 61 6c  usive:.#.#   wal
f040: 5f 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64  _set_journal_mod
f050: 65 20 3f 44 42 3f 0a 23 0a 23 20 20 20 20 20 49  e ?DB?.#.#     I
f060: 66 20 72 75 6e 6e 69 6e 67 20 61 20 57 41 4c 20  f running a WAL 
f070: 74 65 73 74 2c 20 65 78 65 63 75 74 65 20 22 50  test, execute "P
f080: 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f  RAGMA journal_mo
f090: 64 65 20 3d 20 77 61 6c 22 20 75 73 69 6e 67 0a  de = wal" using.
f0a0: 23 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f 6e  #     connection
f0b0: 20 68 61 6e 64 6c 65 20 44 42 2e 20 4f 74 68 65   handle DB. Othe
f0c0: 72 77 69 73 65 2c 20 74 68 69 73 20 63 6f 6d 6d  rwise, this comm
f0d0: 61 6e 64 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  and is a no-op..
f0e0: 23 0a 23 20 20 20 77 61 6c 5f 63 68 65 63 6b 5f  #.#   wal_check_
f0f0: 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 54 45 53  journal_mode TES
f100: 54 4e 41 4d 45 20 3f 44 42 3f 0a 23 0a 23 20 20  TNAME ?DB?.#.#  
f110: 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20 61 20     If running a 
f120: 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63 75 74  WAL test, execut
f130: 65 20 61 20 74 65 73 74 73 20 63 61 73 65 20 74  e a tests case t
f140: 68 61 74 20 66 61 69 6c 73 20 69 66 20 74 68 65  hat fails if the
f150: 20 6d 61 69 6e 0a 23 20 20 20 20 20 64 61 74 61   main.#     data
f160: 62 61 73 65 20 66 6f 72 20 63 6f 6e 6e 65 63 74  base for connect
f170: 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42 20 69 73  ion handle DB is
f180: 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 61   not currently a
f190: 20 57 41 4c 20 64 61 74 61 62 61 73 65 2e 0a 23   WAL database..#
f1a0: 20 20 20 20 20 4f 74 68 65 72 77 69 73 65 20 28       Otherwise (
f1b0: 69 66 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20 61  if not running a
f1c0: 20 57 41 4c 20 70 65 72 6d 75 74 61 74 69 6f 6e   WAL permutation
f1d0: 29 20 74 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f  ) this is a no-o
f1e0: 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f 69 73 5f  p..#.#   wal_is_
f1f0: 77 61 6c 5f 6d 6f 64 65 0a 23 0a 23 20 20 20 20  wal_mode.#.#    
f200: 20 52 65 74 75 72 6e 73 20 74 72 75 65 20 69 66   Returns true if
f210: 20 74 68 69 73 20 74 65 73 74 20 73 68 6f 75 6c   this test shoul
f220: 64 20 62 65 20 72 75 6e 20 69 6e 20 57 41 4c 20  d be run in WAL 
f230: 6d 6f 64 65 2e 20 46 61 6c 73 65 20 6f 74 68 65  mode. False othe
f240: 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63 20 77 61  rwise..#.proc wa
f250: 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 20 7b 7d  l_is_wal_mode {}
f260: 20 7b 0a 20 20 65 78 70 72 20 7b 5b 70 65 72 6d   {.  expr {[perm
f270: 75 74 61 74 69 6f 6e 5d 20 65 71 20 22 77 61 6c  utation] eq "wal
f280: 22 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f 73 65  "}.}.proc wal_se
f290: 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b  t_journal_mode {
f2a0: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 20  {db db}} {.  if 
f2b0: 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f  { [wal_is_wal_mo
f2c0: 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24 64 62 20  de] } {.    $db 
f2d0: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6a 6f 75  eval "PRAGMA jou
f2e0: 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c 22  rnal_mode = WAL"
f2f0: 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f  .  }.}.proc wal_
f300: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
f310: 64 65 20 7b 74 65 73 74 6e 61 6d 65 20 7b 64 62  de {testname {db
f320: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 20 7b 20 5b   db}} {.  if { [
f330: 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d  wal_is_wal_mode]
f340: 20 7d 20 7b 0a 20 20 20 20 24 64 62 20 65 76 61   } {.    $db eva
f350: 6c 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f  l { SELECT * FRO
f360: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
f370: 7d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74  }.    do_test $t
f380: 65 73 74 6e 61 6d 65 20 5b 6c 69 73 74 20 24 64  estname [list $d
f390: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6d  b eval "PRAGMA m
f3a0: 61 69 6e 2e 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65  ain.journal_mode
f3b0: 22 5d 20 7b 77 61 6c 7d 0a 20 20 7d 0a 7d 0a 0a  "] {wal}.  }.}..
f3c0: 70 72 6f 63 20 77 61 6c 5f 69 73 5f 63 61 70 61  proc wal_is_capa
f3d0: 62 6c 65 20 7b 7d 20 7b 0a 20 20 69 66 63 61 70  ble {} {.  ifcap
f3e0: 61 62 6c 65 20 21 77 61 6c 20 7b 20 72 65 74 75  able !wal { retu
f3f0: 72 6e 20 30 20 7d 0a 20 20 69 66 20 7b 5b 70 65  rn 0 }.  if {[pe
f400: 72 6d 75 74 61 74 69 6f 6e 5d 3d 3d 22 6a 6f 75  rmutation]=="jou
f410: 72 6e 61 6c 74 65 73 74 22 7d 20 7b 20 72 65 74  rnaltest"} { ret
f420: 75 72 6e 20 30 20 7d 0a 20 20 72 65 74 75 72 6e  urn 0 }.  return
f430: 20 31 0a 7d 0a 0a 70 72 6f 63 20 70 65 72 6d 75   1.}..proc permu
f440: 74 61 74 69 6f 6e 20 7b 7d 20 7b 0a 20 20 73 65  tation {} {.  se
f450: 74 20 70 65 72 6d 20 22 22 0a 20 20 63 61 74 63  t perm "".  catc
f460: 68 20 7b 73 65 74 20 70 65 72 6d 20 24 3a 3a 47  h {set perm $::G
f470: 28 70 65 72 6d 3a 6e 61 6d 65 29 7d 0a 20 20 73  (perm:name)}.  s
f480: 65 74 20 70 65 72 6d 0a 7d 0a 70 72 6f 63 20 70  et perm.}.proc p
f490: 72 65 73 71 6c 20 7b 7d 20 7b 0a 20 20 73 65 74  resql {} {.  set
f4a0: 20 70 72 65 73 71 6c 20 22 22 0a 20 20 63 61 74   presql "".  cat
f4b0: 63 68 20 7b 73 65 74 20 70 72 65 73 71 6c 20 24  ch {set presql $
f4c0: 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c 29  ::G(perm:presql)
f4d0: 7d 0a 20 20 73 65 74 20 70 72 65 73 71 6c 0a 7d  }.  set presql.}
f4e0: 0a 0a 70 72 6f 63 20 77 61 6c 5f 69 73 5f 6f 6b  ..proc wal_is_ok
f4f0: 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 20 5b 66 6f   {} {.  if { [fo
f500: 72 63 65 64 5f 70 72 6f 78 79 5f 6c 6f 63 6b 69  rced_proxy_locki
f510: 6e 67 5d 20 7d 20 7b 0a 20 20 20 20 72 65 74 75  ng] } {.    retu
f520: 72 6e 20 31 0a 20 20 7d 0a 20 20 69 66 20 7b 20  rn 1.  }.  if { 
f530: 21 5b 70 61 74 68 5f 69 73 5f 6c 6f 63 61 6c 20  ![path_is_local 
f540: 22 2e 22 5d 20 7d 20 7b 0a 20 20 20 20 72 65 74  "."] } {.    ret
f550: 75 72 6e 20 30 0a 20 20 7d 0a 20 20 69 66 20 7b  urn 0.  }.  if {
f560: 20 5b 70 61 74 68 5f 69 73 5f 64 6f 73 20 22 2e   [path_is_dos ".
f570: 22 5d 20 7d 20 7b 0a 20 20 20 20 72 65 74 75 72  "] } {.    retur
f580: 6e 20 30 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  n 0.  }.  return
f590: 20 31 0a 7d 0a 0a 70 72 6f 63 20 69 73 71 75 69   1.}..proc isqui
f5a0: 63 6b 20 7b 7d 20 7b 0a 20 20 73 65 74 20 72 65  ck {} {.  set re
f5b0: 74 20 30 0a 20 20 63 61 74 63 68 20 7b 73 65 74  t 0.  catch {set
f5c0: 20 72 65 74 20 24 3a 3a 47 28 69 73 71 75 69 63   ret $::G(isquic
f5d0: 6b 29 7d 0a 20 20 73 65 74 20 72 65 74 0a 7d 0a  k)}.  set ret.}.
f5e0: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
f5f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
f600: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
f610: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
f620: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72  -----------.#.pr
f630: 6f 63 20 73 6c 61 76 65 5f 74 65 73 74 5f 73 63  oc slave_test_sc
f640: 72 69 70 74 20 7b 73 63 72 69 70 74 7d 20 7b 0a  ript {script} {.
f650: 0a 20 20 23 20 43 72 65 61 74 65 20 74 68 65 20  .  # Create the 
f660: 69 6e 74 65 72 70 72 65 74 65 72 20 75 73 65 64  interpreter used
f670: 20 74 6f 20 72 75 6e 20 74 68 65 20 74 65 73 74   to run the test
f680: 20 73 63 72 69 70 74 2e 0a 20 20 69 6e 74 65 72   script..  inter
f690: 70 20 63 72 65 61 74 65 20 74 69 6e 74 65 72 70  p create tinterp
f6a0: 0a 0a 20 20 23 20 50 6f 70 75 6c 61 74 65 20 73  ..  # Populate s
f6b0: 6f 6d 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  ome global varia
f6c0: 62 6c 65 73 20 74 68 61 74 20 74 65 73 74 65 72  bles that tester
f6d0: 2e 74 63 6c 20 65 78 70 65 63 74 73 20 74 6f 20  .tcl expects to 
f6e0: 73 65 65 2e 0a 20 20 66 6f 72 65 61 63 68 20 7b  see..  foreach {
f6f0: 76 61 72 20 76 61 6c 75 65 7d 20 5b 6c 69 73 74  var value} [list
f700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
f710: 20 20 20 20 3a 3a 61 72 67 76 30 20 24 3a 3a 61      ::argv0 $::a
f720: 72 67 76 30 20 20 20 20 20 20 20 20 20 20 20 20  rgv0            
f730: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 3a           \.    :
f740: 3a 61 72 67 76 20 20 7b 7d 20 20 20 20 20 20 20  :argv  {}       
f750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f760: 20 20 20 20 5c 0a 20 20 20 20 3a 3a 53 4c 41 56      \.    ::SLAV
f770: 45 20 31 20 20 20 20 20 20 20 20 20 20 20 20 20  E 1             
f780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
f790: 0a 20 20 5d 20 7b 0a 20 20 20 20 69 6e 74 65 72  .  ] {.    inter
f7a0: 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20 5b  p eval tinterp [
f7b0: 6c 69 73 74 20 73 65 74 20 24 76 61 72 20 24 76  list set $var $v
f7c0: 61 6c 75 65 5d 0a 20 20 7d 0a 0a 20 20 23 20 49  alue].  }..  # I
f7d0: 66 20 6f 75 74 70 75 74 20 69 73 20 62 65 69 6e  f output is bein
f7e0: 67 20 63 6f 70 69 65 64 20 69 6e 74 6f 20 61 20  g copied into a 
f7f0: 66 69 6c 65 2c 20 73 68 61 72 65 20 74 68 65 20  file, share the 
f800: 66 69 6c 65 2d 64 65 73 63 72 69 70 74 6f 72 20  file-descriptor 
f810: 77 69 74 68 0a 20 20 23 20 74 68 65 20 69 6e 74  with.  # the int
f820: 65 72 70 72 65 74 65 72 2e 0a 20 20 69 66 20 7b  erpreter..  if {
f830: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47  [info exists ::G
f840: 28 6f 75 74 70 75 74 5f 66 64 29 5d 7d 20 7b 0a  (output_fd)]} {.
f850: 20 20 20 20 69 6e 74 65 72 70 20 73 68 61 72 65      interp share
f860: 20 7b 7d 20 24 3a 3a 47 28 6f 75 74 70 75 74 5f   {} $::G(output_
f870: 66 64 29 20 74 69 6e 74 65 72 70 0a 20 20 7d 0a  fd) tinterp.  }.
f880: 0a 20 20 23 20 54 68 65 20 61 6c 69 61 73 20 75  .  # The alias u
f890: 73 65 64 20 74 6f 20 61 63 63 65 73 73 20 74 68  sed to access th
f8a0: 65 20 67 6c 6f 62 61 6c 20 74 65 73 74 20 63 6f  e global test co
f8b0: 75 6e 74 65 72 73 2e 0a 20 20 74 69 6e 74 65 72  unters..  tinter
f8c0: 70 20 61 6c 69 61 73 20 73 65 74 5f 74 65 73 74  p alias set_test
f8d0: 5f 63 6f 75 6e 74 65 72 20 73 65 74 5f 74 65 73  _counter set_tes
f8e0: 74 5f 63 6f 75 6e 74 65 72 0a 0a 20 20 23 20 53  t_counter..  # S
f8f0: 65 74 20 75 70 20 74 68 65 20 3a 3a 63 6d 64 6c  et up the ::cmdl
f900: 69 6e 65 61 72 67 20 61 72 72 61 79 20 69 6e 20  inearg array in 
f910: 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69 6e 74  the slave..  int
f920: 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70  erp eval tinterp
f930: 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73 65 74   [list array set
f940: 20 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 5b 61   ::cmdlinearg [a
f950: 72 72 61 79 20 67 65 74 20 3a 3a 63 6d 64 6c 69  rray get ::cmdli
f960: 6e 65 61 72 67 5d 5d 0a 0a 20 20 23 20 53 65 74  nearg]]..  # Set
f970: 20 75 70 20 74 68 65 20 3a 3a 47 20 61 72 72 61   up the ::G arra
f980: 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65 2e 0a  y in the slave..
f990: 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69    interp eval ti
f9a0: 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72 72 61  nterp [list arra
f9b0: 79 20 73 65 74 20 3a 3a 47 20 5b 61 72 72 61 79  y set ::G [array
f9c0: 20 67 65 74 20 3a 3a 47 5d 5d 0a 0a 20 20 23 20   get ::G]]..  # 
f9d0: 4c 6f 61 64 20 74 68 65 20 76 61 72 69 6f 75 73  Load the various
f9e0: 20 74 65 73 74 20 69 6e 74 65 72 66 61 63 65 73   test interfaces
f9f0: 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 69 6e 20   implemented in 
fa00: 43 2e 0a 20 20 6c 6f 61 64 5f 74 65 73 74 66 69  C..  load_testfi
fa10: 78 74 75 72 65 5f 65 78 74 65 6e 73 69 6f 6e 73  xture_extensions
fa20: 20 74 69 6e 74 65 72 70 0a 0a 20 20 23 20 52 75   tinterp..  # Ru
fa30: 6e 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  n the test scrip
fa40: 74 2e 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c  t..  interp eval
fa50: 20 74 69 6e 74 65 72 70 20 24 73 63 72 69 70 74   tinterp $script
fa60: 0a 0a 20 20 23 20 43 68 65 63 6b 20 69 66 20 74  ..  # Check if t
fa70: 68 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 63  he interpreter c
fa80: 61 6c 6c 20 5b 72 75 6e 5f 74 68 72 65 61 64 5f  all [run_thread_
fa90: 74 65 73 74 73 5d 0a 20 20 69 66 20 7b 20 5b 69  tests].  if { [i
faa0: 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65  nterp eval tinte
fab0: 72 70 20 7b 69 6e 66 6f 20 65 78 69 73 74 73 20  rp {info exists 
fac0: 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73  ::run_thread_tes
fad0: 74 73 5f 63 61 6c 6c 65 64 7d 5d 20 7d 20 7b 0a  ts_called}] } {.
fae0: 20 20 20 20 73 65 74 20 3a 3a 72 75 6e 5f 74 68      set ::run_th
faf0: 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65  read_tests_calle
fb00: 64 20 31 0a 20 20 7d 0a 0a 20 20 23 20 44 65 6c  d 1.  }..  # Del
fb10: 65 74 65 20 74 68 65 20 69 6e 74 65 72 70 72 65  ete the interpre
fb20: 74 65 72 20 75 73 65 64 20 74 6f 20 72 75 6e 20  ter used to run 
fb30: 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 2e  the test script.
fb40: 0a 20 20 69 6e 74 65 72 70 20 64 65 6c 65 74 65  .  interp delete
fb50: 20 74 69 6e 74 65 72 70 0a 7d 0a 0a 70 72 6f 63   tinterp.}..proc
fb60: 20 73 6c 61 76 65 5f 74 65 73 74 5f 66 69 6c 65   slave_test_file
fb70: 20 7b 7a 46 69 6c 65 7d 20 7b 0a 20 20 73 65 74   {zFile} {.  set
fb80: 20 74 61 69 6c 20 5b 66 69 6c 65 20 74 61 69 6c   tail [file tail
fb90: 20 24 7a 46 69 6c 65 5d 0a 0a 20 20 69 66 20 7b   $zFile]..  if {
fba0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47  [info exists ::G
fbb0: 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69  (start:permutati
fbc0: 6f 6e 29 5d 7d 20 7b 0a 20 20 20 20 69 66 20 7b  on)]} {.    if {
fbd0: 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20 21 3d  [permutation] !=
fbe0: 20 24 3a 3a 47 28 73 74 61 72 74 3a 70 65 72 6d   $::G(start:perm
fbf0: 75 74 61 74 69 6f 6e 29 7d 20 72 65 74 75 72 6e  utation)} return
fc00: 0a 20 20 20 20 75 6e 73 65 74 20 3a 3a 47 28 73  .    unset ::G(s
fc10: 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e  tart:permutation
fc20: 29 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66  ).  }.  if {[inf
fc30: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73 74 61  o exists ::G(sta
fc40: 72 74 3a 66 69 6c 65 29 5d 7d 20 7b 0a 20 20 20  rt:file)]} {.   
fc50: 20 69 66 20 7b 24 74 61 69 6c 20 21 3d 20 24 3a   if {$tail != $:
fc60: 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 20 26  :G(start:file) &
fc70: 26 20 24 74 61 69 6c 21 3d 22 24 3a 3a 47 28 73  & $tail!="$::G(s
fc80: 74 61 72 74 3a 66 69 6c 65 29 2e 74 65 73 74 22  tart:file).test"
fc90: 7d 20 72 65 74 75 72 6e 0a 20 20 20 20 75 6e 73  } return.    uns
fca0: 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c  et ::G(start:fil
fcb0: 65 29 0a 20 20 7d 0a 0a 20 20 23 20 52 65 6d 65  e).  }..  # Reme
fcc0: 6d 62 65 72 20 74 68 65 20 76 61 6c 75 65 20 6f  mber the value o
fcd0: 66 20 74 68 65 20 73 68 61 72 65 64 2d 63 61 63  f the shared-cac
fce0: 68 65 20 73 65 74 74 69 6e 67 2e 20 53 6f 20 74  he setting. So t
fcf0: 68 61 74 20 69 74 20 69 73 20 70 6f 73 73 69 62  hat it is possib
fd00: 6c 65 0a 20 20 23 20 74 6f 20 63 68 65 63 6b 20  le.  # to check 
fd10: 61 66 74 65 72 77 61 72 64 73 20 74 68 61 74 20  afterwards that 
fd20: 69 74 20 77 61 73 20 6e 6f 74 20 6d 6f 64 69 66  it was not modif
fd30: 69 65 64 20 62 79 20 74 68 65 20 74 65 73 74 20  ied by the test 
fd40: 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69 66  script..  #.  if
fd50: 63 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f 63  capable shared_c
fd60: 61 63 68 65 20 7b 20 73 65 74 20 73 63 73 20 5b  ache { set scs [
fd70: 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 73  sqlite3_enable_s
fd80: 68 61 72 65 64 5f 63 61 63 68 65 5d 20 7d 0a 0a  hared_cache] }..
fd90: 20 20 23 20 52 75 6e 20 74 68 65 20 74 65 73 74    # Run the test
fda0: 20 73 63 72 69 70 74 20 69 6e 20 61 20 73 6c 61   script in a sla
fdb0: 76 65 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a  ve interpreter..
fdc0: 20 20 23 0a 20 20 75 6e 73 65 74 20 2d 6e 6f 63    #.  unset -noc
fdd0: 6f 6d 70 6c 61 69 6e 20 3a 3a 72 75 6e 5f 74 68  omplain ::run_th
fde0: 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65  read_tests_calle
fdf0: 64 0a 20 20 72 65 73 65 74 5f 70 72 6e 67 5f 73  d.  reset_prng_s
fe00: 74 61 74 65 0a 20 20 73 65 74 20 3a 3a 73 71 6c  tate.  set ::sql
fe10: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
fe20: 75 6e 74 20 30 0a 20 20 73 65 74 20 74 69 6d 65  unt 0.  set time
fe30: 20 5b 74 69 6d 65 20 7b 20 73 6c 61 76 65 5f 74   [time { slave_t
fe40: 65 73 74 5f 73 63 72 69 70 74 20 5b 6c 69 73 74  est_script [list
fe50: 20 73 6f 75 72 63 65 20 24 7a 46 69 6c 65 5d 20   source $zFile] 
fe60: 7d 5d 0a 20 20 73 65 74 20 6d 73 20 5b 65 78 70  }].  set ms [exp
fe70: 72 20 5b 6c 69 6e 64 65 78 20 24 74 69 6d 65 20  r [lindex $time 
fe80: 30 5d 20 2f 20 31 30 30 30 5d 0a 0a 20 20 23 20  0] / 1000]..  # 
fe90: 54 65 73 74 20 74 68 61 74 20 61 6c 6c 20 66 69  Test that all fi
fea0: 6c 65 73 20 6f 70 65 6e 65 64 20 62 79 20 74 68  les opened by th
feb0: 65 20 74 65 73 74 20 73 63 72 69 70 74 20 77 65  e test script we
fec0: 72 65 20 63 6c 6f 73 65 64 2e 20 4f 6d 69 74 20  re closed. Omit 
fed0: 74 68 69 73 0a 20 20 23 20 69 66 20 74 68 65 20  this.  # if the 
fee0: 74 65 73 74 20 73 63 72 69 70 74 20 68 61 73 20  test script has 
fef0: 22 74 68 72 65 61 64 22 20 69 6e 20 69 74 73 20  "thread" in its 
ff00: 6e 61 6d 65 2e 20 54 68 65 20 6f 70 65 6e 20 66  name. The open f
ff10: 69 6c 65 20 63 6f 75 6e 74 65 72 0a 20 20 23 20  ile counter.  # 
ff20: 69 73 20 6e 6f 74 20 74 68 72 65 61 64 2d 73 61  is not thread-sa
ff30: 66 65 2e 0a 20 20 23 0a 20 20 69 66 20 7b 5b 69  fe..  #.  if {[i
ff40: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72 75 6e  nfo exists ::run
ff50: 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61  _thread_tests_ca
ff60: 6c 6c 65 64 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20  lled]==0} {.    
ff70: 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c 7d 2d  do_test ${tail}-
ff80: 63 6c 6f 73 65 61 6c 6c 66 69 6c 65 73 20 7b 20  closeallfiles { 
ff90: 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f  expr {$::sqlite_
ffa0: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 3e  open_file_count>
ffb0: 30 7d 20 7d 20 7b 30 7d 0a 20 20 7d 0a 20 20 73  0} } {0}.  }.  s
ffc0: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e  et ::sqlite_open
ffd0: 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 30 0a 0a 20  _file_count 0.. 
ffe0: 20 23 20 54 65 73 74 20 74 68 61 74 20 74 68 65   # Test that the
fff0: 20 67 6c 6f 62 61 6c 20 22 73 68 61 72 65 64 2d   global "shared-
10000 63 61 63 68 65 22 20 73 65 74 74 69 6e 67 20 77  cache" setting w
10010 61 73 20 6e 6f 74 20 61 6c 74 65 72 65 64 20 62  as not altered b
10020 79 0a 20 20 23 20 74 68 65 20 74 65 73 74 20 73  y.  # the test s
10030 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69 66 63  cript..  #.  ifc
10040 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f 63 61  apable shared_ca
10050 63 68 65 20 7b 0a 20 20 20 20 73 65 74 20 72 65  che {.    set re
10060 73 20 5b 65 78 70 72 20 7b 5b 73 71 6c 69 74 65  s [expr {[sqlite
10070 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65 64 5f  3_enable_shared_
10080 63 61 63 68 65 5d 20 3d 3d 20 24 73 63 73 7d 5d  cache] == $scs}]
10090 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 7b 74  .    do_test ${t
100a0 61 69 6c 7d 2d 73 68 61 72 65 64 63 61 63 68 65  ail}-sharedcache
100b0 73 65 74 74 69 6e 67 20 5b 6c 69 73 74 20 73 65  setting [list se
100c0 74 20 7b 7d 20 24 72 65 73 5d 20 31 0a 20 20 7d  t {} $res] 1.  }
100d0 0a 0a 20 20 23 20 41 64 64 20 73 6f 6d 65 20 69  ..  # Add some i
100e0 6e 66 6f 20 74 6f 20 74 68 65 20 6f 75 74 70 75  nfo to the outpu
100f0 74 2e 0a 20 20 23 0a 20 20 6f 75 74 70 75 74 32  t..  #.  output2
10100 20 22 54 69 6d 65 3a 20 24 74 61 69 6c 20 24 6d   "Time: $tail $m
10110 73 20 6d 73 22 0a 20 20 73 68 6f 77 5f 6d 65 6d  s ms".  show_mem
10120 73 74 61 74 73 0a 7d 0a 0a 23 20 4f 70 65 6e 20  stats.}..# Open 
10130 61 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e  a new connection
10140 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74 65 73   on database tes
10150 74 2e 64 62 20 61 6e 64 20 65 78 65 63 75 74 65  t.db and execute
10160 20 74 68 65 20 53 51 4c 20 73 63 72 69 70 74 0a   the SQL script.
10170 23 20 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e  # supplied as an
10180 20 61 72 67 75 6d 65 6e 74 2e 20 42 65 66 6f 72   argument. Befor
10190 65 20 72 65 74 75 72 6e 69 6e 67 2c 20 63 6c 6f  e returning, clo
101a0 73 65 20 74 68 65 20 6e 65 77 20 63 6f 6e 65 63  se the new conec
101b0 74 69 6f 6e 20 61 6e 64 0a 23 20 72 65 73 74 6f  tion and.# resto
101c0 72 65 20 74 68 65 20 34 20 62 79 74 65 20 66 69  re the 4 byte fi
101d0 65 6c 64 73 20 73 74 61 72 74 69 6e 67 20 61 74  elds starting at
101e0 20 68 65 61 64 65 72 20 6f 66 66 73 65 74 73 20   header offsets 
101f0 32 38 2c 20 39 32 20 61 6e 64 20 39 36 0a 23 20  28, 92 and 96.# 
10200 74 6f 20 74 68 65 20 76 61 6c 75 65 73 20 74 68  to the values th
10210 65 79 20 68 65 6c 64 20 62 65 66 6f 72 65 20 74  ey held before t
10220 68 65 20 53 51 4c 20 77 61 73 20 65 78 65 63 75  he SQL was execu
10230 74 65 64 2e 20 54 68 69 73 20 73 69 6d 75 6c 61  ted. This simula
10240 74 65 73 0a 23 20 61 20 77 72 69 74 65 20 62 79  tes.# a write by
10250 20 61 20 70 72 65 2d 33 2e 37 2e 30 20 63 6c 69   a pre-3.7.0 cli
10260 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 71 6c 33  ent..#.proc sql3
10270 36 32 33 31 20 7b 73 71 6c 7d 20 7b 0a 20 20 73  6231 {sql} {.  s
10280 65 74 20 42 20 5b 68 65 78 69 6f 5f 72 65 61 64  et B [hexio_read
10290 20 74 65 73 74 2e 64 62 20 39 32 20 38 5d 0a 20   test.db 92 8]. 
102a0 20 73 65 74 20 41 20 5b 68 65 78 69 6f 5f 72 65   set A [hexio_re
102b0 61 64 20 74 65 73 74 2e 64 62 20 32 38 20 34 5d  ad test.db 28 4]
102c0 0a 20 20 73 71 6c 69 74 65 33 20 64 62 33 36 32  .  sqlite3 db362
102d0 33 31 20 74 65 73 74 2e 64 62 0a 20 20 63 61 74  31 test.db.  cat
102e0 63 68 20 7b 20 64 62 33 36 32 33 31 20 66 75 6e  ch { db36231 fun
102f0 63 20 61 5f 73 74 72 69 6e 67 20 61 5f 73 74 72  c a_string a_str
10300 69 6e 67 20 7d 0a 20 20 65 78 65 63 73 71 6c 20  ing }.  execsql 
10310 24 73 71 6c 20 64 62 33 36 32 33 31 0a 20 20 64  $sql db36231.  d
10320 62 33 36 32 33 31 20 63 6c 6f 73 65 0a 20 20 68  b36231 close.  h
10330 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73 74 2e  exio_write test.
10340 64 62 20 32 38 20 24 41 0a 20 20 68 65 78 69 6f  db 28 $A.  hexio
10350 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62 20 39  _write test.db 9
10360 32 20 24 42 0a 20 20 72 65 74 75 72 6e 20 22 22  2 $B.  return ""
10370 0a 7d 0a 0a 70 72 6f 63 20 64 62 5f 73 61 76 65  .}..proc db_save
10380 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20   {} {.  foreach 
10390 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
103a0 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62 2a 5d  ain sv_test.db*]
103b0 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24   { forcedelete $
103c0 66 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20  f }.  foreach f 
103d0 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69  [glob -nocomplai
103e0 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b 0a 20 20  n test.db*] {.  
103f0 20 20 73 65 74 20 66 32 20 22 73 76 5f 24 66 22    set f2 "sv_$f"
10400 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79 20 24  .    forcecopy $
10410 66 20 24 66 32 0a 20 20 7d 0a 7d 0a 70 72 6f 63  f $f2.  }.}.proc
10420 20 64 62 5f 73 61 76 65 5f 61 6e 64 5f 63 6c 6f   db_save_and_clo
10430 73 65 20 7b 7d 20 7b 0a 20 20 64 62 5f 73 61 76  se {} {.  db_sav
10440 65 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20 63  e.  catch { db c
10450 6c 6f 73 65 20 7d 0a 20 20 72 65 74 75 72 6e 20  lose }.  return 
10460 22 22 0a 7d 0a 70 72 6f 63 20 64 62 5f 72 65 73  "".}.proc db_res
10470 74 6f 72 65 20 7b 7d 20 7b 0a 20 20 66 6f 72 65  tore {} {.  fore
10480 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ach f [glob -noc
10490 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a  omplain test.db*
104a0 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65 20  ] { forcedelete 
104b0 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66  $f }.  foreach f
104c0 32 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  2 [glob -nocompl
104d0 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62 2a 5d  ain sv_test.db*]
104e0 20 7b 0a 20 20 20 20 73 65 74 20 66 20 5b 73 74   {.    set f [st
104f0 72 69 6e 67 20 72 61 6e 67 65 20 24 66 32 20 33  ring range $f2 3
10500 20 65 6e 64 5d 0a 20 20 20 20 66 6f 72 63 65 63   end].    forcec
10510 6f 70 79 20 24 66 32 20 24 66 0a 20 20 7d 0a 7d  opy $f2 $f.  }.}
10520 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f 72 65  .proc db_restore
10530 5f 61 6e 64 5f 72 65 6f 70 65 6e 20 7b 7b 64 62  _and_reopen {{db
10540 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d 20 7b  file test.db}} {
10550 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20 63 6c  .  catch { db cl
10560 6f 73 65 20 7d 0a 20 20 64 62 5f 72 65 73 74 6f  ose }.  db_resto
10570 72 65 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20  re.  sqlite3 db 
10580 24 64 62 66 69 6c 65 0a 7d 0a 70 72 6f 63 20 64  $dbfile.}.proc d
10590 62 5f 64 65 6c 65 74 65 5f 61 6e 64 5f 72 65 6f  b_delete_and_reo
105a0 70 65 6e 20 7b 7b 66 69 6c 65 20 74 65 73 74 2e  pen {{file test.
105b0 64 62 7d 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b  db}} {.  catch {
105c0 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20 66 6f   db close }.  fo
105d0 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e  reach f [glob -n
105e0 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64  ocomplain test.d
105f0 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74  b*] { forcedelet
10600 65 20 24 66 20 7d 0a 20 20 73 71 6c 69 74 65 33  e $f }.  sqlite3
10610 20 64 62 20 24 66 69 6c 65 0a 7d 0a 0a 23 20 43   db $file.}..# C
10620 6c 6f 73 65 20 61 6e 79 20 63 6f 6e 6e 65 63 74  lose any connect
10630 69 6f 6e 73 20 6e 61 6d 65 64 20 5b 64 62 5d 2c  ions named [db],
10640 20 5b 64 62 32 5d 20 6f 72 20 5b 64 62 33 5d 2e   [db2] or [db3].
10650 20 54 68 65 6e 20 75 73 65 20 73 71 6c 69 74 65   Then use sqlite
10660 33 5f 63 6f 6e 66 69 67 0a 23 20 74 6f 20 63 6f  3_config.# to co
10670 6e 66 69 67 75 72 65 20 74 68 65 20 73 69 7a 65  nfigure the size
10680 20 6f 66 20 74 68 65 20 50 41 47 45 43 41 43 48   of the PAGECACH
10690 45 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 75 73 69  E allocation usi
106a0 6e 67 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  ng the parameter
106b0 73 0a 23 20 70 72 6f 76 69 64 65 64 20 74 6f 20  s.# provided to 
106c0 74 68 69 73 20 63 6f 6d 6d 61 6e 64 2e 20 53 61  this command. Sa
106d0 76 65 20 74 68 65 20 6f 6c 64 20 50 41 47 45 43  ve the old PAGEC
106e0 41 43 48 45 20 70 61 72 61 6d 65 74 65 72 73 20  ACHE parameters 
106f0 69 6e 20 61 20 67 6c 6f 62 61 6c 20 0a 23 20 76  in a global .# v
10700 61 72 69 61 62 6c 65 20 73 6f 20 74 68 61 74 20  ariable so that 
10710 5b 74 65 73 74 5f 72 65 73 74 6f 72 65 5f 63 6f  [test_restore_co
10720 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65 5d 20  nfig_pagecache] 
10730 63 61 6e 20 72 65 73 74 6f 72 65 20 74 68 65 20  can restore the 
10740 70 72 65 76 69 6f 75 73 0a 23 20 63 6f 6e 66 69  previous.# confi
10750 67 75 72 61 74 69 6f 6e 2e 0a 23 0a 23 20 42 65  guration..#.# Be
10760 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c 20  fore returning, 
10770 72 65 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f  reopen connectio
10780 6e 20 5b 64 62 5d 20 6f 6e 20 66 69 6c 65 20 74  n [db] on file t
10790 65 73 74 2e 64 62 2e 0a 23 0a 70 72 6f 63 20 74  est.db..#.proc t
107a0 65 73 74 5f 73 65 74 5f 63 6f 6e 66 69 67 5f 70  est_set_config_p
107b0 61 67 65 63 61 63 68 65 20 7b 73 7a 20 6e 50 67  agecache {sz nPg
107c0 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64 62 20  } {.  catch {db 
107d0 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b  close}.  catch {
107e0 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74  db2 close}.  cat
107f0 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 0a  ch {db3 close}..
10800 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74 64 6f    sqlite3_shutdo
10810 77 6e 0a 20 20 73 65 74 20 3a 3a 6f 6c 64 5f 70  wn.  set ::old_p
10820 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69 67 20  agecache_config 
10830 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 5f  [sqlite3_config_
10840 70 61 67 65 63 61 63 68 65 20 24 73 7a 20 24 6e  pagecache $sz $n
10850 50 67 5d 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e  Pg].  sqlite3_in
10860 69 74 69 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69  itialize.  autoi
10870 6e 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63  nstall_test_func
10880 74 69 6f 6e 73 0a 20 20 72 65 73 65 74 5f 64 62  tions.  reset_db
10890 0a 7d 0a 0a 23 20 43 6c 6f 73 65 20 61 6e 79 20  .}..# Close any 
108a0 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 6e 61 6d 65  connections name
108b0 64 20 5b 64 62 5d 2c 20 5b 64 62 32 5d 20 6f 72  d [db], [db2] or
108c0 20 5b 64 62 33 5d 2e 20 54 68 65 6e 20 75 73 65   [db3]. Then use
108d0 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 0a   sqlite3_config.
108e0 23 20 74 6f 20 63 6f 6e 66 69 67 75 72 65 20 74  # to configure t
108f0 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 50  he size of the P
10900 41 47 45 43 41 43 48 45 20 61 6c 6c 6f 63 61 74  AGECACHE allocat
10910 69 6f 6e 20 74 6f 20 74 68 65 20 73 69 7a 65 20  ion to the size 
10920 73 61 76 65 64 20 69 6e 0a 23 20 74 68 65 20 67  saved in.# the g
10930 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20 62  lobal variable b
10940 79 20 61 6e 20 65 61 72 6c 69 65 72 20 63 61 6c  y an earlier cal
10950 6c 20 74 6f 20 5b 74 65 73 74 5f 73 65 74 5f 63  l to [test_set_c
10960 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65 5d  onfig_pagecache]
10970 2e 0a 23 0a 23 20 42 65 66 6f 72 65 20 72 65 74  ..#.# Before ret
10980 75 72 6e 69 6e 67 2c 20 72 65 6f 70 65 6e 20 63  urning, reopen c
10990 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64 62 5d 20 6f  onnection [db] o
109a0 6e 20 66 69 6c 65 20 74 65 73 74 2e 64 62 2e 0a  n file test.db..
109b0 23 0a 70 72 6f 63 20 74 65 73 74 5f 72 65 73 74  #.proc test_rest
109c0 6f 72 65 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63  ore_config_pagec
109d0 61 63 68 65 20 7b 7d 20 7b 0a 20 20 63 61 74 63  ache {} {.  catc
109e0 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63  h {db close}.  c
109f0 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d  atch {db2 close}
10a00 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20 63 6c  .  catch {db3 cl
10a10 6f 73 65 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f  ose}..  sqlite3_
10a20 73 68 75 74 64 6f 77 6e 0a 20 20 65 76 61 6c 20  shutdown.  eval 
10a30 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 5f 70  sqlite3_config_p
10a40 61 67 65 63 61 63 68 65 20 24 3a 3a 6f 6c 64 5f  agecache $::old_
10a50 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69 67  pagecache_config
10a60 0a 20 20 75 6e 73 65 74 20 3a 3a 6f 6c 64 5f 70  .  unset ::old_p
10a70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69 67 20  agecache_config 
10a80 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69  .  sqlite3_initi
10a90 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74  alize.  autoinst
10aa0 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f  all_test_functio
10ab0 6e 73 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20  ns.  sqlite3 db 
10ac0 74 65 73 74 2e 64 62 0a 7d 0a 0a 70 72 6f 63 20  test.db.}..proc 
10ad0 74 65 73 74 5f 62 69 6e 61 72 79 5f 6e 61 6d 65  test_binary_name
10ae0 20 7b 6e 6d 7d 20 7b 0a 20 20 69 66 20 7b 24 3a   {nm} {.  if {$:
10af0 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c  :tcl_platform(pl
10b00 61 74 66 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f 77  atform)=="window
10b10 73 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 65  s"} {.    set re
10b20 74 20 22 24 6e 6d 2e 65 78 65 22 0a 20 20 7d 20  t "$nm.exe".  } 
10b30 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 72  else {.    set r
10b40 65 74 20 24 6e 6d 0a 20 20 7d 0a 20 20 66 69 6c  et $nm.  }.  fil
10b50 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 5b 66 69 6c  e normalize [fil
10b60 65 20 6a 6f 69 6e 20 24 3a 3a 63 6d 64 6c 69 6e  e join $::cmdlin
10b70 65 61 72 67 28 54 45 53 54 46 49 58 54 55 52 45  earg(TESTFIXTURE
10b80 5f 48 4f 4d 45 29 20 24 72 65 74 5d 0a 7d 0a 0a  _HOME) $ret].}..
10b90 70 72 6f 63 20 74 65 73 74 5f 66 69 6e 64 5f 62  proc test_find_b
10ba0 69 6e 61 72 79 20 7b 6e 6d 7d 20 7b 0a 20 20 73  inary {nm} {.  s
10bb0 65 74 20 72 65 74 20 5b 74 65 73 74 5f 62 69 6e  et ret [test_bin
10bc0 61 72 79 5f 6e 61 6d 65 20 24 6e 6d 5d 0a 20 20  ary_name $nm].  
10bd0 69 66 20 7b 21 5b 66 69 6c 65 20 65 78 65 63 75  if {![file execu
10be0 74 61 62 6c 65 20 24 72 65 74 5d 7d 20 7b 0a 20  table $ret]} {. 
10bf0 20 20 20 66 69 6e 69 73 68 5f 74 65 73 74 0a 20     finish_test. 
10c00 20 20 20 72 65 74 75 72 6e 20 22 22 0a 20 20 7d     return "".  }
10c10 0a 20 20 72 65 74 75 72 6e 20 24 72 65 74 0a 7d  .  return $ret.}
10c20 0a 0a 23 20 46 69 6e 64 20 74 68 65 20 6e 61 6d  ..# Find the nam
10c30 65 20 6f 66 20 74 68 65 20 27 73 68 65 6c 6c 27  e of the 'shell'
10c40 20 65 78 65 63 75 74 61 62 6c 65 20 28 65 2e 67   executable (e.g
10c50 2e 20 22 73 71 6c 69 74 65 33 2e 65 78 65 22 29  . "sqlite3.exe")
10c60 20 74 6f 20 75 73 65 20 66 6f 72 0a 23 20 74 68   to use for.# th
10c70 65 20 74 65 73 74 73 20 69 6e 20 73 68 65 6c 6c  e tests in shell
10c80 5b 31 2d 35 5d 2e 74 65 73 74 2e 20 49 66 20 6e  [1-5].test. If n
10c90 6f 20 73 75 63 68 20 65 78 65 63 75 74 61 62 6c  o such executabl
10ca0 65 20 63 61 6e 20 62 65 20 66 6f 75 6e 64 2c 20  e can be found, 
10cb0 69 6e 76 6f 6b 65 0a 23 20 5b 66 69 6e 69 73 68  invoke.# [finish
10cc0 5f 74 65 73 74 20 3b 20 72 65 74 75 72 6e 5d 20  _test ; return] 
10cd0 69 6e 20 74 68 65 20 63 61 6c 6c 65 72 73 20 63  in the callers c
10ce0 6f 6e 74 65 78 74 2e 0a 23 0a 70 72 6f 63 20 74  ontext..#.proc t
10cf0 65 73 74 5f 66 69 6e 64 5f 63 6c 69 20 7b 7d 20  est_find_cli {} 
10d00 7b 0a 20 20 73 65 74 20 70 72 6f 67 20 5b 74 65  {.  set prog [te
10d10 73 74 5f 66 69 6e 64 5f 62 69 6e 61 72 79 20 73  st_find_binary s
10d20 71 6c 69 74 65 33 5d 0a 20 20 69 66 20 7b 24 70  qlite3].  if {$p
10d30 72 6f 67 3d 3d 22 22 7d 20 7b 20 72 65 74 75 72  rog==""} { retur
10d40 6e 20 2d 63 6f 64 65 20 72 65 74 75 72 6e 20 7d  n -code return }
10d50 0a 20 20 72 65 74 75 72 6e 20 24 70 72 6f 67 0a  .  return $prog.
10d60 7d 0a 0a 23 20 46 69 6e 64 20 74 68 65 20 6e 61  }..# Find the na
10d70 6d 65 20 6f 66 20 74 68 65 20 27 73 71 6c 64 69  me of the 'sqldi
10d80 66 66 27 20 65 78 65 63 75 74 61 62 6c 65 20 28  ff' executable (
10d90 65 2e 67 2e 20 22 73 71 6c 69 74 65 33 2e 65 78  e.g. "sqlite3.ex
10da0 65 22 29 20 74 6f 20 75 73 65 20 66 6f 72 0a 23  e") to use for.#
10db0 20 74 68 65 20 74 65 73 74 73 20 69 6e 20 73 71   the tests in sq
10dc0 6c 64 69 66 66 20 74 65 73 74 73 2e 20 49 66 20  ldiff tests. If 
10dd0 6e 6f 20 73 75 63 68 20 65 78 65 63 75 74 61 62  no such executab
10de0 6c 65 20 63 61 6e 20 62 65 20 66 6f 75 6e 64 2c  le can be found,
10df0 20 69 6e 76 6f 6b 65 0a 23 20 5b 66 69 6e 69 73   invoke.# [finis
10e00 68 5f 74 65 73 74 20 3b 20 72 65 74 75 72 6e 5d  h_test ; return]
10e10 20 69 6e 20 74 68 65 20 63 61 6c 6c 65 72 73 20   in the callers 
10e20 63 6f 6e 74 65 78 74 2e 0a 23 0a 70 72 6f 63 20  context..#.proc 
10e30 74 65 73 74 5f 66 69 6e 64 5f 73 71 6c 64 69 66  test_find_sqldif
10e40 66 20 7b 7d 20 7b 0a 20 20 73 65 74 20 70 72 6f  f {} {.  set pro
10e50 67 20 5b 74 65 73 74 5f 66 69 6e 64 5f 62 69 6e  g [test_find_bin
10e60 61 72 79 20 73 71 6c 64 69 66 66 5d 0a 20 20 69  ary sqldiff].  i
10e70 66 20 7b 24 70 72 6f 67 3d 3d 22 22 7d 20 7b 20  f {$prog==""} { 
10e80 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 72 65 74  return -code ret
10e90 75 72 6e 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  urn }.  return $
10ea0 70 72 6f 67 0a 7d 0a 0a 23 20 43 61 6c 6c 20 73  prog.}..# Call s
10eb0 71 6c 69 74 65 33 5f 65 78 70 61 6e 64 65 64 5f  qlite3_expanded_
10ec0 73 71 6c 28 29 20 6f 6e 20 61 6c 6c 20 73 74 61  sql() on all sta
10ed0 74 65 6d 65 6e 74 73 20 61 73 73 6f 63 69 61 74  tements associat
10ee0 65 64 20 77 69 74 68 20 64 61 74 61 62 61 73 65  ed with database
10ef0 0a 23 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 24 64  .# connection $d
10f00 62 2e 20 54 68 69 73 20 73 6f 6d 65 74 69 6d 65  b. This sometime
10f10 73 20 66 69 6e 64 73 20 75 73 65 2d 61 66 74 65  s finds use-afte
10f20 72 2d 66 72 65 65 20 62 75 67 73 20 69 66 20 72  r-free bugs if r
10f30 75 6e 20 77 69 74 68 0a 23 20 76 61 6c 67 72 69  un with.# valgri
10f40 6e 64 20 6f 72 20 61 64 64 72 65 73 73 2d 73 61  nd or address-sa
10f50 6e 69 74 69 7a 65 72 2e 0a 70 72 6f 63 20 65 78  nitizer..proc ex
10f60 70 61 6e 64 5f 61 6c 6c 5f 73 71 6c 20 7b 64 62  pand_all_sql {db
10f70 7d 20 7b 0a 20 20 73 65 74 20 73 74 6d 74 20 22  } {.  set stmt "
10f80 22 0a 20 20 77 68 69 6c 65 20 7b 5b 73 65 74 20  ".  while {[set 
10f90 73 74 6d 74 20 5b 73 71 6c 69 74 65 33 5f 6e 65  stmt [sqlite3_ne
10fa0 78 74 5f 73 74 6d 74 20 24 64 62 20 24 73 74 6d  xt_stmt $db $stm
10fb0 74 5d 5d 21 3d 22 22 7d 20 7b 0a 20 20 20 20 73  t]]!=""} {.    s
10fc0 71 6c 69 74 65 33 5f 65 78 70 61 6e 64 65 64 5f  qlite3_expanded_
10fd0 73 71 6c 20 24 73 74 6d 74 0a 20 20 7d 0a 7d 0a  sql $stmt.  }.}.
10fe0 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62 72 61  ..# If the libra
10ff0 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77  ry is compiled w
11000 69 74 68 20 74 68 65 20 53 51 4c 49 54 45 5f 44  ith the SQLITE_D
11010 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43 55 55  EFAULT_AUTOVACUU
11020 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20 74 6f  M macro set.# to
11030 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20   non-zero, then 
11040 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 76  set the global v
11050 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56 41 43  ariable $AUTOVAC
11060 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41 55  UUM to 1..set AU
11070 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69 74 65  TOVACUUM $sqlite
11080 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75 6c 74  _options(default
11090 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a 23 20  _autovacuum)..# 
110a0 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 46 54  Make sure the FT
110b0 53 20 65 6e 68 61 6e 63 65 64 20 71 75 65 72 79  S enhanced query
110c0 20 73 79 6e 74 61 78 20 69 73 20 64 69 73 61 62   syntax is disab
110d0 6c 65 64 2e 0a 73 65 74 20 73 71 6c 69 74 65 5f  led..set sqlite_
110e0 66 74 73 33 5f 65 6e 61 62 6c 65 5f 70 61 72 65  fts3_enable_pare
110f0 6e 74 68 65 73 65 73 20 30 0a 0a 23 20 44 75 72  ntheses 0..# Dur
11100 69 6e 67 20 74 65 73 74 69 6e 67 2c 20 61 73 73  ing testing, ass
11110 75 6d 65 20 74 68 61 74 20 61 6c 6c 20 64 61 74  ume that all dat
11120 61 62 61 73 65 20 66 69 6c 65 73 20 61 72 65 20  abase files are 
11130 77 65 6c 6c 2d 66 6f 72 6d 65 64 2e 20 20 54 68  well-formed.  Th
11140 65 0a 23 20 66 65 77 20 74 65 73 74 20 63 61 73  e.# few test cas
11150 65 73 20 74 68 61 74 20 64 65 6c 69 62 65 72 61  es that delibera
11160 74 65 6c 79 20 63 6f 72 72 75 70 74 20 64 61 74  tely corrupt dat
11170 61 62 61 73 65 20 66 69 6c 65 73 20 73 68 6f 75  abase files shou
11180 6c 64 20 72 65 73 63 69 6e 64 20 0a 23 20 74 68  ld rescind .# th
11190 69 73 20 73 65 74 74 69 6e 67 20 62 79 20 69 6e  is setting by in
111a0 76 6f 6b 69 6e 67 20 22 64 61 74 61 62 61 73 65  voking "database
111b0 5f 63 61 6e 5f 62 65 5f 63 6f 72 72 75 70 74 22  _can_be_corrupt"
111c0 0a 23 0a 64 61 74 61 62 61 73 65 5f 6e 65 76 65  .#.database_neve
111d0 72 5f 63 6f 72 72 75 70 74 0a 0a 73 6f 75 72 63  r_corrupt..sourc
111e0 65 20 24 74 65 73 74 64 69 72 2f 74 68 72 65 61  e $testdir/threa
111f0 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f 75  d_common.tcl.sou
11200 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d 61 6c  rce $testdir/mal
11210 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a     loc_common.tcl.