/ Hex Artifact Content
Login

Artifact 2665f64c9ce71944b4d41269114e658fb81bda05:


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 20 0a 23 20 74 65 73 74 20  reating .# test 
02a0: 63 61 73 65 73 20 61 72 65 20 61 73 20 66 6f 6c  cases are as fol
02b0: 6c 6f 77 73 3a 0a 23 0a 23 20 43 6f 6d 6d 61 6e  lows:.#.# Comman
02c0: 64 73 20 74 6f 20 6d 61 6e 69 70 75 6c 61 74 65  ds to manipulate
02d0: 20 74 68 65 20 64 62 20 61 6e 64 20 74 68 65 20   the db and the 
02e0: 66 69 6c 65 2d 73 79 73 74 65 6d 20 61 74 20 61  file-system at a
02f0: 20 68 69 67 68 20 6c 65 76 65 6c 3a 0a 23 0a 23   high level:.#.#
0300: 20 20 20 20 20 20 69 73 5f 72 65 6c 61 74 69 76        is_relativ
0310: 65 5f 66 69 6c 65 0a 23 20 20 20 20 20 20 74 65  e_file.#      te
0320: 73 74 5f 70 77 64 0a 23 20 20 20 20 20 20 67 65  st_pwd.#      ge
0330: 74 5f 70 77 64 0a 23 20 20 20 20 20 20 63 6f 70  t_pwd.#      cop
0340: 79 5f 66 69 6c 65 20 20 20 20 20 20 20 20 20 20  y_file          
0350: 20 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20 20 20      FROM TO.#   
0360: 20 20 20 64 65 6c 65 74 65 5f 66 69 6c 65 20 20     delete_file  
0370: 20 20 20 20 20 20 20 20 20 20 46 49 4c 45 4e 41            FILENA
0380: 4d 45 0a 23 20 20 20 20 20 20 64 72 6f 70 5f 61  ME.#      drop_a
0390: 6c 6c 5f 74 61 62 6c 65 73 20 20 20 20 20 20 20  ll_tables       
03a0: 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 66 6f 72   ?DB?.#      for
03b0: 63 65 63 6f 70 79 20 20 20 20 20 20 20 20 20 20  cecopy          
03c0: 20 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20 20 20      FROM TO.#   
03d0: 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 20     forcedelete  
03e0: 20 20 20 20 20 20 20 20 20 20 46 49 4c 45 4e 41            FILENA
03f0: 4d 45 0a 23 0a 23 20 54 65 73 74 20 74 68 65 20  ME.#.# Test the 
0400: 63 61 70 61 62 69 6c 69 74 79 20 6f 66 20 74 68  capability of th
0410: 65 20 53 51 4c 69 74 65 20 76 65 72 73 69 6f 6e  e SQLite version
0420: 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68 65 20   built into the 
0430: 69 6e 74 65 72 70 72 65 74 65 72 20 74 6f 0a 23  interpreter to.#
0440: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20 61 20   determine if a 
0450: 73 70 65 63 69 66 69 63 20 74 65 73 74 20 63 61  specific test ca
0460: 6e 20 62 65 20 72 75 6e 3a 0a 23 0a 23 20 20 20  n be run:.#.#   
0470: 20 20 20 69 66 63 61 70 61 62 6c 65 20 20 20 20     ifcapable    
0480: 20 20 20 20 20 20 20 20 20 20 45 58 50 52 0a 23            EXPR.#
0490: 0a 23 20 43 61 6c 75 6c 61 74 65 20 63 68 65 63  .# Calulate chec
04a0: 6b 73 75 6d 73 20 62 61 73 65 64 20 6f 6e 20 64  ksums based on d
04b0: 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 73  atabase contents
04c0: 3a 0a 23 0a 23 20 20 20 20 20 20 64 62 63 6b 73  :.#.#      dbcks
04d0: 75 6d 20 20 20 20 20 20 20 20 20 20 20 20 20 20  um              
04e0: 20 20 44 42 20 44 42 4e 41 4d 45 0a 23 20 20 20    DB DBNAME.#   
04f0: 20 20 20 61 6c 6c 63 6b 73 75 6d 20 20 20 20 20     allcksum     
0500: 20 20 20 20 20 20 20 20 20 20 3f 44 42 3f 0a 23            ?DB?.#
0510: 20 20 20 20 20 20 63 6b 73 75 6d 20 20 20 20 20        cksum     
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 3f 44 42               ?DB
0530: 3f 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20 74  ?.#.# Commands t
0540: 6f 20 65 78 65 63 75 74 65 2f 65 78 70 6c 61 69  o execute/explai
0550: 6e 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 73  n SQL statements
0560: 3a 0a 23 0a 23 20 20 20 20 20 20 73 74 65 70 73  :.#.#      steps
0570: 71 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ql              
0580: 20 20 44 42 20 53 51 4c 0a 23 20 20 20 20 20 20    DB SQL.#      
0590: 65 78 65 63 73 71 6c 32 20 20 20 20 20 20 20 20  execsql2        
05a0: 20 20 20 20 20 20 20 53 51 4c 0a 23 20 20 20 20         SQL.#    
05b0: 20 20 65 78 70 6c 61 69 6e 5f 6e 6f 5f 74 72 61    explain_no_tra
05c0: 63 65 20 20 20 20 20 20 20 53 51 4c 0a 23 20 20  ce       SQL.#  
05d0: 20 20 20 20 65 78 70 6c 61 69 6e 20 20 20 20 20      explain     
05e0: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 20 3f             SQL ?
05f0: 44 42 3f 0a 23 20 20 20 20 20 20 63 61 74 63 68  DB?.#      catch
0600: 73 71 6c 20 20 20 20 20 20 20 20 20 20 20 20 20  sql             
0610: 20 20 53 51 4c 20 3f 44 42 3f 0a 23 20 20 20 20    SQL ?DB?.#    
0620: 20 20 65 78 65 63 73 71 6c 20 20 20 20 20 20 20    execsql       
0630: 20 20 20 20 20 20 20 20 20 53 51 4c 20 3f 44 42           SQL ?DB
0640: 3f 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20 74  ?.#.# Commands t
0650: 6f 20 72 75 6e 20 74 65 73 74 20 63 61 73 65 73  o run test cases
0660: 3a 0a 23 0a 23 20 20 20 20 20 20 64 6f 5f 69 6f  :.#.#      do_io
0670: 65 72 72 5f 74 65 73 74 20 20 20 20 20 20 20 20  err_test        
0680: 20 20 54 45 53 54 4e 41 4d 45 20 41 52 47 53 2e    TESTNAME ARGS.
0690: 2e 2e 0a 23 20 20 20 20 20 20 63 72 61 73 68 73  ...#      crashs
06a0: 71 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ql              
06b0: 20 41 52 47 53 2e 2e 2e 0a 23 20 20 20 20 20 20   ARGS....#      
06c0: 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20  integrity_check 
06d0: 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20         TESTNAME 
06e0: 3f 44 42 3f 0a 23 20 20 20 20 20 20 64 6f 5f 74  ?DB?.#      do_t
06f0: 65 73 74 20 20 20 20 20 20 20 20 20 20 20 20 20  est             
0700: 20 20 20 54 45 53 54 4e 41 4d 45 20 53 43 52 49     TESTNAME SCRI
0710: 50 54 20 45 58 50 45 43 54 45 44 0a 23 20 20 20  PT EXPECTED.#   
0720: 20 20 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65     do_execsql_te
0730: 73 74 20 20 20 20 20 20 20 20 54 45 53 54 4e 41  st        TESTNA
0740: 4d 45 20 53 51 4c 20 45 58 50 45 43 54 45 44 0a  ME SQL EXPECTED.
0750: 23 20 20 20 20 20 20 64 6f 5f 63 61 74 63 68 73  #      do_catchs
0760: 71 6c 5f 74 65 73 74 20 20 20 20 20 20 20 54 45  ql_test       TE
0770: 53 54 4e 41 4d 45 20 53 51 4c 20 45 58 50 45 43  STNAME SQL EXPEC
0780: 54 45 44 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73  TED.#.# Commands
0790: 20 70 72 6f 76 69 64 69 6e 67 20 61 20 6c 6f 77   providing a low
07a0: 65 72 20 6c 65 76 65 6c 20 69 6e 74 65 72 66 61  er level interfa
07b0: 63 65 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c  ce to the global
07c0: 20 74 65 73 74 20 63 6f 75 6e 74 65 72 73 3a 0a   test counters:.
07d0: 23 0a 23 20 20 20 20 20 20 73 65 74 5f 74 65 73  #.#      set_tes
07e0: 74 5f 63 6f 75 6e 74 65 72 20 20 20 20 20 20 20  t_counter       
07f0: 43 4f 55 4e 54 45 52 20 3f 56 41 4c 55 45 3f 0a  COUNTER ?VALUE?.
0800: 23 20 20 20 20 20 20 6f 6d 69 74 5f 74 65 73 74  #      omit_test
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 45                TE
0820: 53 54 4e 41 4d 45 20 52 45 41 53 4f 4e 20 3f 41  STNAME REASON ?A
0830: 50 50 45 4e 44 3f 0a 23 20 20 20 20 20 20 66 61  PPEND?.#      fa
0840: 69 6c 5f 74 65 73 74 20 20 20 20 20 20 20 20 20  il_test         
0850: 20 20 20 20 20 54 45 53 54 4e 41 4d 45 0a 23 20       TESTNAME.# 
0860: 20 20 20 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a       incr_ntest.
0870: 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 72 75 6e 20  #.# Command run 
0880: 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61  at the end of ea
0890: 63 68 20 74 65 73 74 20 66 69 6c 65 3a 0a 23 0a  ch test file:.#.
08a0: 23 20 20 20 20 20 20 66 69 6e 69 73 68 5f 74 65  #      finish_te
08b0: 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20  st.#.# Commands 
08c0: 74 6f 20 68 65 6c 70 20 63 72 65 61 74 65 20 74  to help create t
08d0: 65 73 74 20 66 69 6c 65 73 20 74 68 61 74 20 72  est files that r
08e0: 75 6e 20 77 69 74 68 20 74 68 65 20 22 57 41 4c  un with the "WAL
08f0: 22 20 61 6e 64 20 6f 74 68 65 72 0a 23 20 70 65  " and other.# pe
0900: 72 6d 75 74 61 74 69 6f 6e 73 20 28 73 65 65 20  rmutations (see 
0910: 66 69 6c 65 20 70 65 72 6d 75 74 61 74 69 6f 6e  file permutation
0920: 73 2e 74 65 73 74 29 3a 0a 23 0a 23 20 20 20 20  s.test):.#.#    
0930: 20 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64    wal_is_wal_mod
0940: 65 0a 23 20 20 20 20 20 20 77 61 6c 5f 73 65 74  e.#      wal_set
0950: 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 20 20  _journal_mode   
0960: 3f 44 42 3f 0a 23 20 20 20 20 20 20 77 61 6c 5f  ?DB?.#      wal_
0970: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
0980: 64 65 20 54 45 53 54 4e 41 4d 45 3f 44 42 3f 0a  de TESTNAME?DB?.
0990: 23 20 20 20 20 20 20 70 65 72 6d 75 74 61 74 69  #      permutati
09a0: 6f 6e 0a 23 20 20 20 20 20 20 70 72 65 73 71 6c  on.#      presql
09b0: 0a 23 0a 0a 23 20 53 65 74 20 74 68 65 20 70 72  .#..# Set the pr
09c0: 65 63 69 73 69 6f 6e 20 6f 66 20 46 50 20 61 72  ecision of FP ar
09d0: 69 74 68 6d 61 74 69 63 20 75 73 65 64 20 62 79  ithmatic used by
09e0: 20 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72   the interpreter
09f0: 2e 20 41 6e 64 20 0a 23 20 63 6f 6e 66 69 67 75  . And .# configu
0a00: 72 65 20 53 51 4c 69 74 65 20 74 6f 20 74 61 6b  re SQLite to tak
0a10: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
0a20: 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20 70 61 67  locks on the pag
0a30: 65 20 74 68 61 74 20 62 65 67 69 6e 73 0a 23 20  e that begins.# 
0a40: 36 34 4b 42 20 69 6e 74 6f 20 74 68 65 20 64 61  64KB into the da
0a50: 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 73 74  tabase file inst
0a60: 65 61 64 20 6f 66 20 74 68 65 20 6f 6e 65 20 31  ead of the one 1
0a70: 47 42 20 69 6e 2e 20 54 68 69 73 20 6d 65 61 6e  GB in. This mean
0a80: 73 0a 23 20 74 68 65 20 63 6f 64 65 20 74 68 61  s.# the code tha
0a90: 74 20 68 61 6e 64 6c 65 73 20 74 68 61 74 20 73  t handles that s
0aa0: 70 65 63 69 61 6c 20 63 61 73 65 20 63 61 6e 20  pecial case can 
0ab0: 62 65 20 74 65 73 74 65 64 20 77 69 74 68 6f 75  be tested withou
0ac0: 74 20 63 72 65 61 74 69 6e 67 0a 23 20 76 65 72  t creating.# ver
0ad0: 79 20 6c 61 72 67 65 20 64 61 74 61 62 61 73 65  y large database
0ae0: 20 66 69 6c 65 73 2e 0a 23 0a 73 65 74 20 74 63   files..#.set tc
0af0: 6c 5f 70 72 65 63 69 73 69 6f 6e 20 31 35 0a 73  l_precision 15.s
0b00: 71 6c 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74  qlite3_test_cont
0b10: 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65  rol_pending_byte
0b20: 20 30 78 30 30 31 30 30 30 30 0a 0a 0a 23 20 49   0x0010000...# I
0b30: 66 20 74 68 65 20 70 61 67 65 72 20 63 6f 64 65  f the pager code
0b40: 63 20 69 73 20 61 76 61 69 6c 61 62 6c 65 2c 20  c is available, 
0b50: 63 72 65 61 74 65 20 61 20 77 72 61 70 70 65 72  create a wrapper
0b60: 20 66 6f 72 20 74 68 65 20 5b 73 71 6c 69 74 65   for the [sqlite
0b70: 33 5d 20 0a 23 20 63 6f 6d 6d 61 6e 64 20 74 68  3] .# command th
0b80: 61 74 20 61 70 70 65 6e 64 73 20 22 2d 6b 65 79  at appends "-key
0b90: 20 7b 78 79 7a 7a 79 7d 22 20 74 6f 20 74 68 65   {xyzzy}" to the
0ba0: 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 2e 20 69   command line. i
0bb0: 2e 65 2e 20 74 68 69 73 3a 0a 23 0a 23 20 20 20  .e. this:.#.#   
0bc0: 20 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73    sqlite3 db tes
0bd0: 74 2e 64 62 0a 23 0a 23 20 62 65 63 6f 6d 65 73  t.db.#.# becomes
0be0: 0a 23 0a 23 20 20 20 20 20 73 71 6c 69 74 65 33  .#.#     sqlite3
0bf0: 20 64 62 20 74 65 73 74 2e 64 62 20 2d 6b 65 79   db test.db -key
0c00: 20 7b 78 79 7a 7a 79 7d 0a 23 0a 69 66 20 7b 5b   {xyzzy}.#.if {[
0c10: 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 20 73 71 6c  info command sql
0c20: 69 74 65 5f 6f 72 69 67 5d 3d 3d 22 22 7d 20 7b  ite_orig]==""} {
0c30: 0a 20 20 72 65 6e 61 6d 65 20 73 71 6c 69 74 65  .  rename sqlite
0c40: 33 20 73 71 6c 69 74 65 5f 6f 72 69 67 0a 20 20  3 sqlite_orig.  
0c50: 70 72 6f 63 20 73 71 6c 69 74 65 33 20 7b 61 72  proc sqlite3 {ar
0c60: 67 73 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 6c  gs} {.    if {[l
0c70: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 3e 3d 32  length $args]>=2
0c80: 20 26 26 20 5b 73 74 72 69 6e 67 20 69 6e 64 65   && [string inde
0c90: 78 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20  x [lindex $args 
0ca0: 30 5d 20 30 5d 21 3d 22 2d 22 7d 20 7b 0a 20 20  0] 0]!="-"} {.  
0cb0: 20 20 20 20 23 20 54 68 69 73 20 63 6f 6d 6d 61      # This comma
0cc0: 6e 64 20 69 73 20 6f 70 65 6e 69 6e 67 20 61 20  nd is opening a 
0cd0: 6e 65 77 20 64 61 74 61 62 61 73 65 20 63 6f 6e  new database con
0ce0: 6e 65 63 74 69 6f 6e 2e 0a 20 20 20 20 20 20 23  nection..      #
0cf0: 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f  .      if {[info
0d00: 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72 6d   exists ::G(perm
0d10: 3a 73 71 6c 69 74 65 33 5f 61 72 67 73 29 5d 7d  :sqlite3_args)]}
0d20: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 61   {.        set a
0d30: 72 67 73 20 5b 63 6f 6e 63 61 74 20 24 61 72 67  rgs [concat $arg
0d40: 73 20 24 3a 3a 47 28 70 65 72 6d 3a 73 71 6c 69  s $::G(perm:sqli
0d50: 74 65 33 5f 61 72 67 73 29 5d 0a 20 20 20 20 20  te3_args)].     
0d60: 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b 73 71   }.      if {[sq
0d70: 6c 69 74 65 5f 6f 72 69 67 20 2d 68 61 73 2d 63  lite_orig -has-c
0d80: 6f 64 65 63 5d 20 26 26 20 21 5b 69 6e 66 6f 20  odec] && ![info 
0d90: 65 78 69 73 74 73 20 3a 3a 64 6f 5f 6e 6f 74 5f  exists ::do_not_
0da0: 75 73 65 5f 63 6f 64 65 63 5d 7d 20 7b 0a 20 20  use_codec]} {.  
0db0: 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 61 72        lappend ar
0dc0: 67 73 20 2d 6b 65 79 20 7b 78 79 7a 7a 79 7d 0a  gs -key {xyzzy}.
0dd0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 73        }..      s
0de0: 65 74 20 72 65 73 20 5b 75 70 6c 65 76 65 6c 20  et res [uplevel 
0df0: 31 20 73 71 6c 69 74 65 5f 6f 72 69 67 20 24 61  1 sqlite_orig $a
0e00: 72 67 73 5d 0a 20 20 20 20 20 20 69 66 20 7b 5b  rgs].      if {[
0e10: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
0e20: 70 65 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20 7b  perm:presql)]} {
0e30: 0a 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78  .        [lindex
0e40: 20 24 61 72 67 73 20 30 5d 20 65 76 61 6c 20 24   $args 0] eval $
0e50: 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c 29  ::G(perm:presql)
0e60: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
0e70: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
0e80: 3a 3a 47 28 70 65 72 6d 3a 64 62 63 6f 6e 66 69  ::G(perm:dbconfi
0e90: 67 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  g)]} {.        s
0ea0: 65 74 20 3a 3a 64 62 68 61 6e 64 6c 65 20 5b 6c  et ::dbhandle [l
0eb0: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 0a 20  index $args 0]. 
0ec0: 20 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 23         uplevel #
0ed0: 30 20 24 3a 3a 47 28 70 65 72 6d 3a 64 62 63 6f  0 $::G(perm:dbco
0ee0: 6e 66 69 67 29 0a 20 20 20 20 20 20 7d 0a 20 20  nfig).      }.  
0ef0: 20 20 20 20 73 65 74 20 72 65 73 0a 20 20 20 20      set res.    
0f00: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 23  } else {.      #
0f10: 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73   This command is
0f20: 20 6e 6f 74 20 6f 70 65 6e 69 6e 67 20 61 20 6e   not opening a n
0f30: 65 77 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  ew database conn
0f40: 65 63 74 69 6f 6e 2e 20 50 61 73 73 20 74 68 65  ection. Pass the
0f50: 20 0a 20 20 20 20 20 20 23 20 61 72 67 75 6d 65   .      # argume
0f60: 6e 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  nts through to t
0f70: 68 65 20 43 20 69 6d 70 6c 65 6d 65 6e 61 74 69  he C implemenati
0f80: 6f 6e 20 61 73 20 74 68 65 20 61 72 65 2e 0a 20  on as the are.. 
0f90: 20 20 20 20 20 23 0a 20 20 20 20 20 20 75 70 6c       #.      upl
0fa0: 65 76 65 6c 20 31 20 73 71 6c 69 74 65 5f 6f 72  evel 1 sqlite_or
0fb0: 69 67 20 24 61 72 67 73 0a 20 20 20 20 7d 0a 20  ig $args.    }. 
0fc0: 20 7d 0a 7d 0a 0a 70 72 6f 63 20 67 65 74 46 69   }.}..proc getFi
0fd0: 6c 65 52 65 74 72 69 65 73 20 7b 7d 20 7b 0a 20  leRetries {} {. 
0fe0: 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73   if {![info exis
0ff0: 74 73 20 3a 3a 47 28 66 69 6c 65 2d 72 65 74 72  ts ::G(file-retr
1000: 69 65 73 29 5d 7d 20 7b 0a 20 20 20 20 23 0a 20  ies)]} {.    #. 
1010: 20 20 20 23 20 4e 4f 54 45 3a 20 52 65 74 75 72     # NOTE: Retur
1020: 6e 20 74 68 65 20 64 65 66 61 75 6c 74 20 6e 75  n the default nu
1030: 6d 62 65 72 20 6f 66 20 72 65 74 72 69 65 73 20  mber of retries 
1040: 66 6f 72 20 5b 66 69 6c 65 5d 20 6f 70 65 72 61  for [file] opera
1050: 74 69 6f 6e 73 2e 20 20 41 0a 20 20 20 20 23 20  tions.  A.    # 
1060: 20 20 20 20 20 20 76 61 6c 75 65 20 6f 66 20 7a        value of z
1070: 65 72 6f 20 6f 72 20 6c 65 73 73 20 68 65 72 65  ero or less here
1080: 20 6d 65 61 6e 73 20 22 64 69 73 61 62 6c 65 64   means "disabled
1090: 22 2e 0a 20 20 20 20 23 0a 20 20 20 20 72 65 74  "..    #.    ret
10a0: 75 72 6e 20 5b 65 78 70 72 20 7b 24 3a 3a 74 63  urn [expr {$::tc
10b0: 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66  l_platform(platf
10c0: 6f 72 6d 29 20 65 71 20 22 77 69 6e 64 6f 77 73  orm) eq "windows
10d0: 22 20 3f 20 31 30 20 3a 20 30 7d 5d 0a 20 20 7d  " ? 10 : 0}].  }
10e0: 0a 20 20 72 65 74 75 72 6e 20 24 3a 3a 47 28 66  .  return $::G(f
10f0: 69 6c 65 2d 72 65 74 72 69 65 73 29 0a 7d 0a 0a  ile-retries).}..
1100: 70 72 6f 63 20 67 65 74 46 69 6c 65 52 65 74 72  proc getFileRetr
1110: 79 44 65 6c 61 79 20 7b 7d 20 7b 0a 20 20 69 66  yDelay {} {.  if
1120: 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20   {![info exists 
1130: 3a 3a 47 28 66 69 6c 65 2d 72 65 74 72 79 2d 64  ::G(file-retry-d
1140: 65 6c 61 79 29 5d 7d 20 7b 0a 20 20 20 20 23 0a  elay)]} {.    #.
1150: 20 20 20 20 23 20 4e 4f 54 45 3a 20 52 65 74 75      # NOTE: Retu
1160: 72 6e 20 74 68 65 20 64 65 66 61 75 6c 74 20 6e  rn the default n
1170: 75 6d 62 65 72 20 6f 66 20 6d 69 6c 6c 69 73 65  umber of millise
1180: 63 6f 6e 64 73 20 74 6f 20 77 61 69 74 20 77 68  conds to wait wh
1190: 65 6e 20 72 65 74 72 79 69 6e 67 0a 20 20 20 20  en retrying.    
11a0: 23 20 20 20 20 20 20 20 66 61 69 6c 65 64 20 5b  #       failed [
11b0: 66 69 6c 65 5d 20 6f 70 65 72 61 74 69 6f 6e 73  file] operations
11c0: 2e 20 20 41 20 76 61 6c 75 65 20 6f 66 20 7a 65  .  A value of ze
11d0: 72 6f 20 6f 72 20 6c 65 73 73 20 6d 65 61 6e 73  ro or less means
11e0: 20 22 64 6f 20 6e 6f 74 0a 20 20 20 20 23 20 20   "do not.    #  
11f0: 20 20 20 20 20 77 61 69 74 22 2e 0a 20 20 20 20       wait"..    
1200: 23 0a 20 20 20 20 72 65 74 75 72 6e 20 31 30 30  #.    return 100
1210: 3b 20 23 20 54 4f 44 4f 3a 20 47 6f 6f 64 20 64  ; # TODO: Good d
1220: 65 66 61 75 6c 74 3f 0a 20 20 7d 0a 20 20 72 65  efault?.  }.  re
1230: 74 75 72 6e 20 24 3a 3a 47 28 66 69 6c 65 2d 72  turn $::G(file-r
1240: 65 74 72 79 2d 64 65 6c 61 79 29 0a 7d 0a 0a 23  etry-delay).}..#
1250: 20 52 65 74 75 72 6e 20 74 68 65 20 73 74 72 69   Return the stri
1260: 6e 67 20 72 65 70 72 65 73 65 6e 74 69 6e 67 20  ng representing 
1270: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  the name of the 
1280: 63 75 72 72 65 6e 74 20 64 69 72 65 63 74 6f 72  current director
1290: 79 2e 20 20 4f 6e 0a 23 20 57 69 6e 64 6f 77 73  y.  On.# Windows
12a0: 2c 20 74 68 65 20 72 65 73 75 6c 74 20 69 73 20  , the result is 
12b0: 22 6e 6f 72 6d 61 6c 69 7a 65 64 22 20 74 6f 20  "normalized" to 
12c0: 77 68 61 74 65 76 65 72 20 6f 75 72 20 70 61 72  whatever our par
12d0: 65 6e 74 20 63 6f 6d 6d 61 6e 64 20 73 68 65 6c  ent command shel
12e0: 6c 0a 23 20 69 73 20 75 73 69 6e 67 20 74 6f 20  l.# is using to 
12f0: 70 72 65 76 65 6e 74 20 63 61 73 65 2d 6d 69 73  prevent case-mis
1300: 6d 61 74 63 68 20 69 73 73 75 65 73 2e 0a 23 0a  match issues..#.
1310: 70 72 6f 63 20 67 65 74 5f 70 77 64 20 7b 7d 20  proc get_pwd {} 
1320: 7b 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70  {.  if {$::tcl_p
1330: 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d  latform(platform
1340: 29 20 65 71 20 22 77 69 6e 64 6f 77 73 22 7d 20  ) eq "windows"} 
1350: 7b 0a 20 20 20 20 23 0a 20 20 20 20 23 20 4e 4f  {.    #.    # NO
1360: 54 45 3a 20 43 61 6e 6e 6f 74 20 75 73 65 20 5b  TE: Cannot use [
1370: 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 5d 20  file normalize] 
1380: 68 65 72 65 20 62 65 63 61 75 73 65 20 69 74 20  here because it 
1390: 77 6f 75 6c 64 20 61 6c 74 65 72 20 74 68 65 0a  would alter the.
13a0: 20 20 20 20 23 20 20 20 20 20 20 20 63 61 73 65      #       case
13b0: 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20 74   of the result t
13c0: 6f 20 77 68 61 74 20 54 63 6c 20 63 6f 6e 73 69  o what Tcl consi
13d0: 64 65 72 73 20 63 61 6e 6f 6e 69 63 61 6c 2c 20  ders canonical, 
13e0: 77 68 69 63 68 20 77 6f 75 6c 64 0a 20 20 20 20  which would.    
13f0: 23 20 20 20 20 20 20 20 64 65 66 65 61 74 20 74  #       defeat t
1400: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1410: 69 73 20 70 72 6f 63 65 64 75 72 65 2e 0a 20 20  is procedure..  
1420: 20 20 23 0a 20 20 20 20 72 65 74 75 72 6e 20 5b    #.    return [
1430: 73 74 72 69 6e 67 20 6d 61 70 20 5b 6c 69 73 74  string map [list
1440: 20 5c 5c 20 2f 5d 20 5c 0a 20 20 20 20 20 20 20   \\ /] \.       
1450: 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 5b 65   [string trim [e
1460: 78 65 63 20 2d 2d 20 24 3a 3a 65 6e 76 28 43 6f  xec -- $::env(Co
1470: 6d 53 70 65 63 29 20 2f 63 20 65 63 68 6f 20 25  mSpec) /c echo %
1480: 43 44 25 5d 5d 5d 0a 20 20 7d 20 65 6c 73 65 20  CD%]]].  } else 
1490: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 70 77  {.    return [pw
14a0: 64 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 43 6f 70 79  d].  }.}..# Copy
14b0: 20 66 69 6c 65 20 24 66 72 6f 6d 20 69 6e 74 6f   file $from into
14c0: 20 24 74 6f 2e 20 54 68 69 73 20 69 73 20 75 73   $to. This is us
14d0: 65 64 20 62 65 63 61 75 73 65 20 73 6f 6d 65 20  ed because some 
14e0: 76 65 72 73 69 6f 6e 73 20 6f 66 0a 23 20 54 43  versions of.# TC
14f0: 4c 20 66 6f 72 20 77 69 6e 64 6f 77 73 20 28 6e  L for windows (n
1500: 6f 74 61 62 6c 79 20 74 68 65 20 38 2e 34 2e 31  otably the 8.4.1
1510: 20 62 69 6e 61 72 79 20 70 61 63 6b 61 67 65 20   binary package 
1520: 73 68 69 70 70 65 64 20 77 69 74 68 20 74 68 65  shipped with the
1530: 0a 23 20 63 75 72 72 65 6e 74 20 6d 69 6e 67 77  .# current mingw
1540: 20 72 65 6c 65 61 73 65 29 20 68 61 76 65 20 61   release) have a
1550: 20 62 72 6f 6b 65 6e 20 22 66 69 6c 65 20 63 6f   broken "file co
1560: 70 79 22 20 63 6f 6d 6d 61 6e 64 2e 0a 23 0a 70  py" command..#.p
1570: 72 6f 63 20 63 6f 70 79 5f 66 69 6c 65 20 7b 66  roc copy_file {f
1580: 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 64 6f 5f 63  rom to} {.  do_c
1590: 6f 70 79 5f 66 69 6c 65 20 66 61 6c 73 65 20 24  opy_file false $
15a0: 66 72 6f 6d 20 24 74 6f 0a 7d 0a 0a 70 72 6f 63  from $to.}..proc
15b0: 20 66 6f 72 63 65 63 6f 70 79 20 7b 66 72 6f 6d   forcecopy {from
15c0: 20 74 6f 7d 20 7b 0a 20 20 64 6f 5f 63 6f 70 79   to} {.  do_copy
15d0: 5f 66 69 6c 65 20 74 72 75 65 20 24 66 72 6f 6d  _file true $from
15e0: 20 24 74 6f 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f   $to.}..proc do_
15f0: 63 6f 70 79 5f 66 69 6c 65 20 7b 66 6f 72 63 65  copy_file {force
1600: 20 66 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 73 65   from to} {.  se
1610: 74 20 6e 52 65 74 72 79 20 5b 67 65 74 46 69 6c  t nRetry [getFil
1620: 65 52 65 74 72 69 65 73 5d 20 20 20 20 20 3b 23  eRetries]     ;#
1630: 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20   Maximum number 
1640: 6f 66 20 72 65 74 72 69 65 73 2e 0a 20 20 73 65  of retries..  se
1650: 74 20 6e 44 65 6c 61 79 20 5b 67 65 74 46 69 6c  t nDelay [getFil
1660: 65 52 65 74 72 79 44 65 6c 61 79 5d 20 20 3b 23  eRetryDelay]  ;#
1670: 20 44 65 6c 61 79 20 69 6e 20 6d 73 20 62 65 66   Delay in ms bef
1680: 6f 72 65 20 72 65 74 72 79 69 6e 67 2e 0a 0a 20  ore retrying... 
1690: 20 23 20 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73   # On windows, s
16a0: 6f 6d 65 74 69 6d 65 73 20 65 76 65 6e 20 61 20  ometimes even a 
16b0: 5b 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63  [file copy -forc
16c0: 65 5d 20 63 61 6e 20 66 61 69 6c 2e 20 54 68 65  e] can fail. The
16d0: 20 63 61 75 73 65 20 69 73 0a 20 20 23 20 75 73   cause is.  # us
16e0: 75 61 6c 6c 79 20 22 74 61 67 2d 61 6c 6f 6e 67  ually "tag-along
16f0: 73 22 20 2d 20 70 72 6f 67 72 61 6d 73 20 6c 69  s" - programs li
1700: 6b 65 20 61 6e 74 69 2d 76 69 72 75 73 20 73 6f  ke anti-virus so
1710: 66 74 77 61 72 65 2c 20 61 75 74 6f 6d 61 74 69  ftware, automati
1720: 63 20 62 61 63 6b 75 70 0a 20 20 23 20 74 6f 6f  c backup.  # too
1730: 6c 73 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65  ls and various e
1740: 78 70 6c 6f 72 65 72 20 65 78 74 65 6e 73 69 6f  xplorer extensio
1750: 6e 73 20 74 68 61 74 20 6b 65 65 70 20 61 20 66  ns that keep a f
1760: 69 6c 65 20 6f 70 65 6e 20 61 20 6c 69 74 74 6c  ile open a littl
1770: 65 20 6c 6f 6e 67 65 72 0a 20 20 23 20 74 68 61  e longer.  # tha
1780: 6e 20 77 65 20 65 78 70 65 63 74 2c 20 63 61 75  n we expect, cau
1790: 73 69 6e 67 20 74 68 65 20 64 65 6c 65 74 65 20  sing the delete 
17a0: 74 6f 20 66 61 69 6c 2e 0a 20 20 23 0a 20 20 23  to fail..  #.  #
17b0: 20 54 68 65 20 73 6f 6c 75 74 69 6f 6e 20 69 73   The solution is
17c0: 20 74 6f 20 77 61 69 74 20 61 20 73 68 6f 72 74   to wait a short
17d0: 20 61 6d 6f 75 6e 74 20 6f 66 20 74 69 6d 65 20   amount of time 
17e0: 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e 67 20  before retrying 
17f0: 74 68 65 20 63 6f 70 79 2e 0a 20 20 23 0a 20 20  the copy..  #.  
1800: 69 66 20 7b 24 6e 52 65 74 72 79 20 3e 20 30 7d  if {$nRetry > 0}
1810: 20 7b 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20   {.    for {set 
1820: 69 20 30 7d 20 7b 24 69 3c 24 6e 52 65 74 72 79  i 0} {$i<$nRetry
1830: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
1840: 20 20 20 73 65 74 20 72 63 20 5b 63 61 74 63 68     set rc [catch
1850: 20 7b 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24   {.        if {$
1860: 66 6f 72 63 65 7d 20 7b 0a 20 20 20 20 20 20 20  force} {.       
1870: 20 20 20 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f     file copy -fo
1880: 72 63 65 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20  rce $from $to.  
1890: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
18a0: 20 20 20 20 20 20 20 20 20 66 69 6c 65 20 63 6f           file co
18b0: 70 79 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20  py $from $to.   
18c0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 6d       }.      } m
18d0: 73 67 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 72  sg].      if {$r
18e0: 63 3d 3d 30 7d 20 62 72 65 61 6b 0a 20 20 20 20  c==0} break.    
18f0: 20 20 69 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20    if {$nDelay > 
1900: 30 7d 20 7b 20 61 66 74 65 72 20 24 6e 44 65 6c  0} { after $nDel
1910: 61 79 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69  ay }.    }.    i
1920: 66 20 7b 24 72 63 7d 20 7b 20 65 72 72 6f 72 20  f {$rc} { error 
1930: 24 6d 73 67 20 7d 0a 20 20 7d 20 65 6c 73 65 20  $msg }.  } else 
1940: 7b 0a 20 20 20 20 69 66 20 7b 24 66 6f 72 63 65  {.    if {$force
1950: 7d 20 7b 0a 20 20 20 20 20 20 66 69 6c 65 20 63  } {.      file c
1960: 6f 70 79 20 2d 66 6f 72 63 65 20 24 66 72 6f 6d  opy -force $from
1970: 20 24 74 6f 0a 20 20 20 20 7d 20 65 6c 73 65 20   $to.    } else 
1980: 7b 0a 20 20 20 20 20 20 66 69 6c 65 20 63 6f 70  {.      file cop
1990: 79 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20  y $from $to.    
19a0: 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 43 68 65 63 6b  }.  }.}..# Check
19b0: 20 69 66 20 61 20 66 69 6c 65 20 6e 61 6d 65 20   if a file name 
19c0: 69 73 20 72 65 6c 61 74 69 76 65 0a 23 0a 70 72  is relative.#.pr
19d0: 6f 63 20 69 73 5f 72 65 6c 61 74 69 76 65 5f 66  oc is_relative_f
19e0: 69 6c 65 20 7b 20 66 69 6c 65 20 7d 20 7b 0a 20  ile { file } {. 
19f0: 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20 7b 5b   return [expr {[
1a00: 66 69 6c 65 20 70 61 74 68 74 79 70 65 20 24 66  file pathtype $f
1a10: 69 6c 65 5d 20 21 3d 20 22 61 62 73 6f 6c 75 74  ile] != "absolut
1a20: 65 22 7d 5d 0a 7d 0a 0a 23 20 49 66 20 74 68 65  e"}].}..# If the
1a30: 20 56 46 53 20 73 75 70 70 6f 72 74 73 20 75 73   VFS supports us
1a40: 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74 20  ing the current 
1a50: 64 69 72 65 63 74 6f 72 79 2c 20 72 65 74 75 72  directory, retur
1a60: 6e 73 20 5b 70 77 64 5d 3b 0a 23 20 6f 74 68 65  ns [pwd];.# othe
1a70: 72 77 69 73 65 2c 20 69 74 20 72 65 74 75 72 6e  rwise, it return
1a80: 73 20 6f 6e 6c 79 20 74 68 65 20 70 72 6f 76 69  s only the provi
1a90: 64 65 64 20 73 75 66 66 69 78 20 73 74 72 69 6e  ded suffix strin
1aa0: 67 20 28 77 68 69 63 68 20 69 73 0a 23 20 65 6d  g (which is.# em
1ab0: 70 74 79 20 62 79 20 64 65 66 61 75 6c 74 29 2e  pty by default).
1ac0: 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 70 77 64  .#.proc test_pwd
1ad0: 20 7b 20 61 72 67 73 20 7d 20 7b 0a 20 20 69 66   { args } {.  if
1ae0: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73   {[llength $args
1af0: 5d 20 3e 20 30 7d 20 7b 0a 20 20 20 20 73 65 74  ] > 0} {.    set
1b00: 20 73 75 66 66 69 78 31 20 5b 6c 69 6e 64 65 78   suffix1 [lindex
1b10: 20 24 61 72 67 73 20 30 5d 0a 20 20 20 20 69 66   $args 0].    if
1b20: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73   {[llength $args
1b30: 5d 20 3e 20 31 7d 20 7b 0a 20 20 20 20 20 20 73  ] > 1} {.      s
1b40: 65 74 20 73 75 66 66 69 78 32 20 5b 6c 69 6e 64  et suffix2 [lind
1b50: 65 78 20 24 61 72 67 73 20 31 5d 0a 20 20 20 20  ex $args 1].    
1b60: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 73  } else {.      s
1b70: 65 74 20 73 75 66 66 69 78 32 20 24 73 75 66 66  et suffix2 $suff
1b80: 69 78 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c  ix1.    }.  } el
1b90: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 73 75 66  se {.    set suf
1ba0: 66 69 78 31 20 22 22 3b 20 73 65 74 20 73 75 66  fix1 ""; set suf
1bb0: 66 69 78 32 20 22 22 0a 20 20 7d 0a 20 20 69 66  fix2 "".  }.  if
1bc0: 63 61 70 61 62 6c 65 20 63 75 72 64 69 72 20 7b  capable curdir {
1bd0: 0a 20 20 20 20 72 65 74 75 72 6e 20 22 5b 67 65  .    return "[ge
1be0: 74 5f 70 77 64 5d 24 73 75 66 66 69 78 31 22 0a  t_pwd]$suffix1".
1bf0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 72    } else {.    r
1c00: 65 74 75 72 6e 20 24 73 75 66 66 69 78 32 0a 20  eturn $suffix2. 
1c10: 20 7d 0a 7d 0a 0a 23 20 44 65 6c 65 74 65 20 61   }.}..# Delete a
1c20: 20 66 69 6c 65 20 6f 72 20 64 69 72 65 63 74 6f   file or directo
1c30: 72 79 0a 23 0a 70 72 6f 63 20 64 65 6c 65 74 65  ry.#.proc delete
1c40: 5f 66 69 6c 65 20 7b 61 72 67 73 7d 20 7b 0a 20  _file {args} {. 
1c50: 20 64 6f 5f 64 65 6c 65 74 65 5f 66 69 6c 65 20   do_delete_file 
1c60: 66 61 6c 73 65 20 7b 2a 7d 24 61 72 67 73 0a 7d  false {*}$args.}
1c70: 0a 0a 70 72 6f 63 20 66 6f 72 63 65 64 65 6c 65  ..proc forcedele
1c80: 74 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 64 6f  te {args} {.  do
1c90: 5f 64 65 6c 65 74 65 5f 66 69 6c 65 20 74 72 75  _delete_file tru
1ca0: 65 20 7b 2a 7d 24 61 72 67 73 0a 7d 0a 0a 70 72  e {*}$args.}..pr
1cb0: 6f 63 20 64 6f 5f 64 65 6c 65 74 65 5f 66 69 6c  oc do_delete_fil
1cc0: 65 20 7b 66 6f 72 63 65 20 61 72 67 73 7d 20 7b  e {force args} {
1cd0: 0a 20 20 73 65 74 20 6e 52 65 74 72 79 20 5b 67  .  set nRetry [g
1ce0: 65 74 46 69 6c 65 52 65 74 72 69 65 73 5d 20 20  etFileRetries]  
1cf0: 20 20 20 3b 23 20 4d 61 78 69 6d 75 6d 20 6e 75     ;# Maximum nu
1d00: 6d 62 65 72 20 6f 66 20 72 65 74 72 69 65 73 2e  mber of retries.
1d10: 0a 20 20 73 65 74 20 6e 44 65 6c 61 79 20 5b 67  .  set nDelay [g
1d20: 65 74 46 69 6c 65 52 65 74 72 79 44 65 6c 61 79  etFileRetryDelay
1d30: 5d 20 20 3b 23 20 44 65 6c 61 79 20 69 6e 20 6d  ]  ;# Delay in m
1d40: 73 20 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e  s before retryin
1d50: 67 2e 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 69  g...  foreach fi
1d60: 6c 65 6e 61 6d 65 20 24 61 72 67 73 20 7b 0a 20  lename $args {. 
1d70: 20 20 20 23 20 4f 6e 20 77 69 6e 64 6f 77 73 2c     # On windows,
1d80: 20 73 6f 6d 65 74 69 6d 65 73 20 65 76 65 6e 20   sometimes even 
1d90: 61 20 5b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d  a [file delete -
1da0: 66 6f 72 63 65 5d 20 63 61 6e 20 66 61 69 6c 20  force] can fail 
1db0: 6a 75 73 74 20 61 66 74 65 72 0a 20 20 20 20 23  just after.    #
1dc0: 20 61 20 66 69 6c 65 20 69 73 20 63 6c 6f 73 65   a file is close
1dd0: 64 2e 20 54 68 65 20 63 61 75 73 65 20 69 73 20  d. The cause is 
1de0: 75 73 75 61 6c 6c 79 20 22 74 61 67 2d 61 6c 6f  usually "tag-alo
1df0: 6e 67 73 22 20 2d 20 70 72 6f 67 72 61 6d 73 20  ngs" - programs 
1e00: 6c 69 6b 65 0a 20 20 20 20 23 20 61 6e 74 69 2d  like.    # anti-
1e10: 76 69 72 75 73 20 73 6f 66 74 77 61 72 65 2c 20  virus software, 
1e20: 61 75 74 6f 6d 61 74 69 63 20 62 61 63 6b 75 70  automatic backup
1e30: 20 74 6f 6f 6c 73 20 61 6e 64 20 76 61 72 69 6f   tools and vario
1e40: 75 73 20 65 78 70 6c 6f 72 65 72 0a 20 20 20 20  us explorer.    
1e50: 23 20 65 78 74 65 6e 73 69 6f 6e 73 20 74 68 61  # extensions tha
1e60: 74 20 6b 65 65 70 20 61 20 66 69 6c 65 20 6f 70  t keep a file op
1e70: 65 6e 20 61 20 6c 69 74 74 6c 65 20 6c 6f 6e 67  en a little long
1e80: 65 72 20 74 68 61 6e 20 77 65 20 65 78 70 65 63  er than we expec
1e90: 74 2c 20 63 61 75 73 69 6e 67 0a 20 20 20 20 23  t, causing.    #
1ea0: 20 74 68 65 20 64 65 6c 65 74 65 20 74 6f 20 66   the delete to f
1eb0: 61 69 6c 2e 0a 20 20 20 20 23 0a 20 20 20 20 23  ail..    #.    #
1ec0: 20 54 68 65 20 73 6f 6c 75 74 69 6f 6e 20 69 73   The solution is
1ed0: 20 74 6f 20 77 61 69 74 20 61 20 73 68 6f 72 74   to wait a short
1ee0: 20 61 6d 6f 75 6e 74 20 6f 66 20 74 69 6d 65 20   amount of time 
1ef0: 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e 67 20  before retrying 
1f00: 74 68 65 0a 20 20 20 20 23 20 64 65 6c 65 74 65  the.    # delete
1f10: 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b  ..    #.    if {
1f20: 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b 0a 20  $nRetry > 0} {. 
1f30: 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20       for {set i 
1f40: 30 7d 20 7b 24 69 3c 24 6e 52 65 74 72 79 7d 20  0} {$i<$nRetry} 
1f50: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
1f60: 20 20 20 73 65 74 20 72 63 20 5b 63 61 74 63 68     set rc [catch
1f70: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 20   {.          if 
1f80: 7b 24 66 6f 72 63 65 7d 20 7b 0a 20 20 20 20 20  {$force} {.     
1f90: 20 20 20 20 20 20 20 66 69 6c 65 20 64 65 6c 65         file dele
1fa0: 74 65 20 2d 66 6f 72 63 65 20 24 66 69 6c 65 6e  te -force $filen
1fb0: 61 6d 65 0a 20 20 20 20 20 20 20 20 20 20 7d 20  ame.          } 
1fc0: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20  else {.         
1fd0: 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 24     file delete $
1fe0: 66 69 6c 65 6e 61 6d 65 0a 20 20 20 20 20 20 20  filename.       
1ff0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 20 6d     }.        } m
2000: 73 67 5d 0a 20 20 20 20 20 20 20 20 69 66 20 7b  sg].        if {
2010: 24 72 63 3d 3d 30 7d 20 62 72 65 61 6b 0a 20 20  $rc==0} break.  
2020: 20 20 20 20 20 20 69 66 20 7b 24 6e 44 65 6c 61        if {$nDela
2030: 79 20 3e 20 30 7d 20 7b 20 61 66 74 65 72 20 24  y > 0} { after $
2040: 6e 44 65 6c 61 79 20 7d 0a 20 20 20 20 20 20 7d  nDelay }.      }
2050: 0a 20 20 20 20 20 20 69 66 20 7b 24 72 63 7d 20  .      if {$rc} 
2060: 7b 20 65 72 72 6f 72 20 24 6d 73 67 20 7d 0a 20  { error $msg }. 
2070: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
2080: 20 20 69 66 20 7b 24 66 6f 72 63 65 7d 20 7b 0a    if {$force} {.
2090: 20 20 20 20 20 20 20 20 66 69 6c 65 20 64 65 6c          file del
20a0: 65 74 65 20 2d 66 6f 72 63 65 20 24 66 69 6c 65  ete -force $file
20b0: 6e 61 6d 65 0a 20 20 20 20 20 20 7d 20 65 6c 73  name.      } els
20c0: 65 20 7b 0a 20 20 20 20 20 20 20 20 66 69 6c 65  e {.        file
20d0: 20 64 65 6c 65 74 65 20 24 66 69 6c 65 6e 61 6d   delete $filenam
20e0: 65 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  e.      }.    }.
20f0: 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78 65 63    }.}..proc exec
2100: 70 72 65 73 71 6c 20 7b 68 61 6e 64 6c 65 20 61  presql {handle a
2110: 72 67 73 7d 20 7b 0a 20 20 74 72 61 63 65 20 72  rgs} {.  trace r
2120: 65 6d 6f 76 65 20 65 78 65 63 75 74 69 6f 6e 20  emove execution 
2130: 24 68 61 6e 64 6c 65 20 65 6e 74 65 72 20 5b 6c  $handle enter [l
2140: 69 73 74 20 65 78 65 63 70 72 65 73 71 6c 20 24  ist execpresql $
2150: 68 61 6e 64 6c 65 5d 0a 20 20 69 66 20 7b 5b 69  handle].  if {[i
2160: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70  nfo exists ::G(p
2170: 65 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a  erm:presql)]} {.
2180: 20 20 20 20 24 68 61 6e 64 6c 65 20 65 76 61 6c      $handle eval
2190: 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71   $::G(perm:presq
21a0: 6c 29 0a 20 20 7d 0a 7d 0a 0a 23 20 54 68 69 73  l).  }.}..# This
21b0: 20 63 6f 6d 6d 61 6e 64 20 73 68 6f 75 6c 64 20   command should 
21c0: 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20  be called after 
21d0: 6c 6f 61 64 69 6e 67 20 74 65 73 74 65 72 2e 74  loading tester.t
21e0: 63 6c 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a 23  cl from within.#
21f0: 20 61 6c 6c 20 74 65 73 74 20 73 63 72 69 70 74   all test script
2200: 73 20 74 68 61 74 20 61 72 65 20 69 6e 63 6f 6d  s that are incom
2210: 70 61 74 69 62 6c 65 20 77 69 74 68 20 65 6e 63  patible with enc
2220: 72 79 70 74 69 6f 6e 20 63 6f 64 65 63 73 2e 0a  ryption codecs..
2230: 23 0a 70 72 6f 63 20 64 6f 5f 6e 6f 74 5f 75 73  #.proc do_not_us
2240: 65 5f 63 6f 64 65 63 20 7b 7d 20 7b 0a 20 20 73  e_codec {} {.  s
2250: 65 74 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f  et ::do_not_use_
2260: 63 6f 64 65 63 20 31 0a 20 20 72 65 73 65 74 5f  codec 1.  reset_
2270: 64 62 0a 7d 0a 0a 23 20 54 68 65 20 66 6f 6c 6c  db.}..# The foll
2280: 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 6f 6e 6c 79  owing block only
2290: 20 72 75 6e 73 20 74 68 65 20 66 69 72 73 74 20   runs the first 
22a0: 74 69 6d 65 20 74 68 69 73 20 66 69 6c 65 20 69  time this file i
22b0: 73 20 73 6f 75 72 63 65 64 2e 20 49 74 0a 23 20  s sourced. It.# 
22c0: 64 6f 65 73 20 6e 6f 74 20 72 75 6e 20 69 6e 20  does not run in 
22d0: 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74 65  slave interprete
22e0: 72 73 20 28 73 69 6e 63 65 20 74 68 65 20 3a 3a  rs (since the ::
22f0: 63 6d 64 6c 69 6e 65 61 72 67 20 61 72 72 61 79  cmdlinearg array
2300: 20 69 73 0a 23 20 70 6f 70 75 6c 61 74 65 64 20   is.# populated 
2310: 62 65 66 6f 72 65 20 74 68 65 20 74 65 73 74 20  before the test 
2320: 73 63 72 69 70 74 20 69 73 20 72 75 6e 20 69 6e  script is run in
2330: 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74   slave interpret
2340: 65 72 73 29 2e 0a 23 0a 69 66 20 7b 5b 69 6e 66  ers)..#.if {[inf
2350: 6f 20 65 78 69 73 74 73 20 63 6d 64 6c 69 6e 65  o exists cmdline
2360: 61 72 67 5d 3d 3d 30 7d 20 7b 0a 0a 20 20 23 20  arg]==0} {..  # 
2370: 50 61 72 73 65 20 61 6e 79 20 6f 70 74 69 6f 6e  Parse any option
2380: 73 20 73 70 65 63 69 66 69 65 64 20 69 6e 20 74  s specified in t
2390: 68 65 20 24 61 72 67 76 20 61 72 72 61 79 2e 20  he $argv array. 
23a0: 54 68 69 73 20 73 63 72 69 70 74 20 61 63 63 65  This script acce
23b0: 70 74 73 20 74 68 65 20 0a 20 20 23 20 66 6f 6c  pts the .  # fol
23c0: 6c 6f 77 69 6e 67 20 6f 70 74 69 6f 6e 73 3a 20  lowing options: 
23d0: 0a 20 20 23 0a 20 20 23 20 20 20 2d 2d 70 61 75  .  #.  #   --pau
23e0: 73 65 0a 20 20 23 20 20 20 2d 2d 73 6f 66 74 2d  se.  #   --soft-
23f0: 68 65 61 70 2d 6c 69 6d 69 74 3d 4e 4e 0a 20 20  heap-limit=NN.  
2400: 23 20 20 20 2d 2d 6d 61 78 65 72 72 6f 72 3d 4e  #   --maxerror=N
2410: 4e 0a 20 20 23 20 20 20 2d 2d 6d 61 6c 6c 6f 63  N.  #   --malloc
2420: 74 72 61 63 65 3d 4e 0a 20 20 23 20 20 20 2d 2d  trace=N.  #   --
2430: 62 61 63 6b 74 72 61 63 65 3d 4e 0a 20 20 23 20  backtrace=N.  # 
2440: 20 20 2d 2d 62 69 6e 61 72 79 6c 6f 67 3d 4e 0a    --binarylog=N.
2450: 20 20 23 20 20 20 2d 2d 73 6f 61 6b 3d 4e 0a 20    #   --soak=N. 
2460: 20 23 20 20 20 2d 2d 66 69 6c 65 2d 72 65 74 72   #   --file-retr
2470: 69 65 73 3d 4e 0a 20 20 23 20 20 20 2d 2d 66 69  ies=N.  #   --fi
2480: 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79 3d 4e  le-retry-delay=N
2490: 0a 20 20 23 20 20 20 2d 2d 73 74 61 72 74 3d 5b  .  #   --start=[
24a0: 24 70 65 72 6d 75 74 61 74 69 6f 6e 3a 5d 24 74  $permutation:]$t
24b0: 65 73 74 66 69 6c 65 0a 20 20 23 20 20 20 2d 2d  estfile.  #   --
24c0: 6d 61 74 63 68 3d 24 70 61 74 74 65 72 6e 0a 20  match=$pattern. 
24d0: 20 23 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65   #.  set cmdline
24e0: 61 72 67 28 73 6f 66 74 2d 68 65 61 70 2d 6c 69  arg(soft-heap-li
24f0: 6d 69 74 29 20 20 20 20 30 0a 20 20 73 65 74 20  mit)    0.  set 
2500: 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 78 65 72  cmdlinearg(maxer
2510: 72 6f 72 29 20 20 20 20 20 20 20 20 31 30 30 30  ror)        1000
2520: 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72  .  set cmdlinear
2530: 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 20 20  g(malloctrace)  
2540: 20 20 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d        0.  set cm
2550: 64 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61  dlinearg(backtra
2560: 63 65 29 20 20 20 20 20 20 20 20 20 31 30 0a 20  ce)         10. 
2570: 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28   set cmdlinearg(
2580: 62 69 6e 61 72 79 6c 6f 67 29 20 20 20 20 20 20  binarylog)      
2590: 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c      0.  set cmdl
25a0: 69 6e 65 61 72 67 28 73 6f 61 6b 29 20 20 20 20  inearg(soak)    
25b0: 20 20 20 20 20 20 20 20 20 20 20 30 0a 20 20 73             0.  s
25c0: 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69  et cmdlinearg(fi
25d0: 6c 65 2d 72 65 74 72 69 65 73 29 20 20 20 20 20  le-retries)     
25e0: 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e    0.  set cmdlin
25f0: 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72 79 2d  earg(file-retry-
2600: 64 65 6c 61 79 29 20 20 20 30 0a 20 20 73 65 74  delay)   0.  set
2610: 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 74 61 72   cmdlinearg(star
2620: 74 29 20 20 20 20 20 20 20 20 20 20 20 20 20 22  t)             "
2630: 22 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61  ".  set cmdlinea
2640: 72 67 28 6d 61 74 63 68 29 20 20 20 20 20 20 20  rg(match)       
2650: 20 20 20 20 20 20 22 22 0a 0a 20 20 73 65 74 20        ""..  set 
2660: 6c 65 66 74 6f 76 65 72 20 5b 6c 69 73 74 5d 0a  leftover [list].
2670: 20 20 66 6f 72 65 61 63 68 20 61 20 24 61 72 67    foreach a $arg
2680: 76 20 7b 0a 20 20 20 20 73 77 69 74 63 68 20 2d  v {.    switch -
2690: 72 65 67 65 78 70 20 2d 2d 20 24 61 20 7b 0a 20  regexp -- $a {. 
26a0: 20 20 20 20 20 7b 5e 2d 2b 70 61 75 73 65 24 7d       {^-+pause$}
26b0: 20 7b 0a 20 20 20 20 20 20 20 20 23 20 57 61 69   {.        # Wai
26c0: 74 20 66 6f 72 20 75 73 65 72 20 69 6e 70 75 74  t for user input
26d0: 20 62 65 66 6f 72 65 20 63 6f 6e 74 69 6e 75 69   before continui
26e0: 6e 67 2e 20 54 68 69 73 20 69 73 20 74 6f 20 67  ng. This is to g
26f0: 69 76 65 20 74 68 65 20 75 73 65 72 20 61 6e 20  ive the user an 
2700: 0a 20 20 20 20 20 20 20 20 23 20 6f 70 70 6f 72  .        # oppor
2710: 74 75 6e 69 74 79 20 74 6f 20 63 6f 6e 6e 65 63  tunity to connec
2720: 74 20 70 72 6f 66 69 6c 69 6e 67 20 74 6f 6f 6c  t profiling tool
2730: 73 20 74 6f 20 74 68 65 20 70 72 6f 63 65 73 73  s to the process
2740: 2e 0a 20 20 20 20 20 20 20 20 70 75 74 73 20 2d  ..        puts -
2750: 6e 6f 6e 65 77 6c 69 6e 65 20 22 50 72 65 73 73  nonewline "Press
2760: 20 52 45 54 55 52 4e 20 74 6f 20 62 65 67 69 6e   RETURN to begin
2770: 2e 2e 2e 22 0a 20 20 20 20 20 20 20 20 66 6c 75  ...".        flu
2780: 73 68 20 73 74 64 6f 75 74 0a 20 20 20 20 20 20  sh stdout.      
2790: 20 20 67 65 74 73 20 73 74 64 69 6e 0a 20 20 20    gets stdin.   
27a0: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 73     }.      {^-+s
27b0: 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d 2e  oft-heap-limit=.
27c0: 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f  +$} {.        fo
27d0: 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64  reach {dummy cmd
27e0: 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65 61  linearg(soft-hea
27f0: 70 2d 6c 69 6d 69 74 29 7d 20 5b 73 70 6c 69 74  p-limit)} [split
2800: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20   $a =] break.   
2810: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 6d     }.      {^-+m
2820: 61 78 65 72 72 6f 72 3d 2e 2b 24 7d 20 7b 0a 20  axerror=.+$} {. 
2830: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
2840: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
2850: 28 6d 61 78 65 72 72 6f 72 29 7d 20 5b 73 70 6c  (maxerror)} [spl
2860: 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20  it $a =] break. 
2870: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d       }.      {^-
2880: 2b 6d 61 6c 6c 6f 63 74 72 61 63 65 3d 2e 2b 24  +malloctrace=.+$
2890: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
28a0: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
28b0: 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63  nearg(malloctrac
28c0: 65 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d  e)} [split $a =]
28d0: 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 69   break.        i
28e0: 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 6d  f {$cmdlinearg(m
28f0: 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20  alloctrace)} {. 
2900: 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
2910: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74  _memdebug_log st
2920: 61 72 74 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  art.        }.  
2930: 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b      }.      {^-+
2940: 62 61 63 6b 74 72 61 63 65 3d 2e 2b 24 7d 20 7b  backtrace=.+$} {
2950: 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68  .        foreach
2960: 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61   {dummy cmdlinea
2970: 72 67 28 62 61 63 6b 74 72 61 63 65 29 7d 20 5b  rg(backtrace)} [
2980: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
2990: 6b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  k.        sqlite
29a0: 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63 6b 74  3_memdebug_backt
29b0: 72 61 63 65 20 24 76 61 6c 75 65 0a 20 20 20 20  race $value.    
29c0: 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 62 69    }.      {^-+bi
29d0: 6e 61 72 79 6c 6f 67 3d 2e 2b 24 7d 20 7b 0a 20  narylog=.+$} {. 
29e0: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
29f0: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
2a00: 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 5b 73 70  (binarylog)} [sp
2a10: 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a  lit $a =] break.
2a20: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
2a30: 2d 2b 73 6f 61 6b 3d 2e 2b 24 7d 20 7b 0a 20 20  -+soak=.+$} {.  
2a40: 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64        foreach {d
2a50: 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28  ummy cmdlinearg(
2a60: 73 6f 61 6b 29 7d 20 5b 73 70 6c 69 74 20 24 61  soak)} [split $a
2a70: 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20   =] break.      
2a80: 20 20 73 65 74 20 3a 3a 47 28 69 73 73 6f 61 6b    set ::G(issoak
2a90: 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f  ) $cmdlinearg(so
2aa0: 61 6b 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak).      }.    
2ab0: 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74 72 69    {^-+file-retri
2ac0: 65 73 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  es=.+$} {.      
2ad0: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
2ae0: 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c 65   cmdlinearg(file
2af0: 2d 72 65 74 72 69 65 73 29 7d 20 5b 73 70 6c 69  -retries)} [spli
2b00: 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20  t $a =] break.  
2b10: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 66 69        set ::G(fi
2b20: 6c 65 2d 72 65 74 72 69 65 73 29 20 24 63 6d 64  le-retries) $cmd
2b30: 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74  linearg(file-ret
2b40: 72 69 65 73 29 0a 20 20 20 20 20 20 7d 0a 20 20  ries).      }.  
2b50: 20 20 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74      {^-+file-ret
2b60: 72 79 2d 64 65 6c 61 79 3d 2e 2b 24 7d 20 7b 0a  ry-delay=.+$} {.
2b70: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
2b80: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
2b90: 67 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c  g(file-retry-del
2ba0: 61 79 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ay)} [split $a =
2bb0: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
2bc0: 73 65 74 20 3a 3a 47 28 66 69 6c 65 2d 72 65 74  set ::G(file-ret
2bd0: 72 79 2d 64 65 6c 61 79 29 20 24 63 6d 64 6c 69  ry-delay) $cmdli
2be0: 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72 79  nearg(file-retry
2bf0: 2d 64 65 6c 61 79 29 0a 20 20 20 20 20 20 7d 0a  -delay).      }.
2c00: 20 20 20 20 20 20 7b 5e 2d 2b 73 74 61 72 74 3d        {^-+start=
2c10: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
2c20: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
2c30: 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29 7d  dlinearg(start)}
2c40: 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72   [split $a =] br
2c50: 65 61 6b 0a 0a 20 20 20 20 20 20 20 20 73 65 74  eak..        set
2c60: 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29   ::G(start:file)
2c70: 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 74 61   $cmdlinearg(sta
2c80: 72 74 29 0a 20 20 20 20 20 20 20 20 69 66 20 7b  rt).        if {
2c90: 5b 72 65 67 65 78 70 20 7b 28 2e 2a 29 3a 28 2e  [regexp {(.*):(.
2ca0: 2a 29 7d 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  *)} $cmdlinearg(
2cb0: 73 74 61 72 74 29 20 2d 3e 20 73 2e 70 65 72 6d  start) -> s.perm
2cc0: 20 73 2e 66 69 6c 65 5d 7d 20 7b 0a 20 20 20 20   s.file]} {.    
2cd0: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74        set ::G(st
2ce0: 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29  art:permutation)
2cf0: 20 24 7b 73 2e 70 65 72 6d 7d 0a 20 20 20 20 20   ${s.perm}.     
2d00: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74 61       set ::G(sta
2d10: 72 74 3a 66 69 6c 65 29 20 20 20 20 20 20 20 20  rt:file)        
2d20: 24 7b 73 2e 66 69 6c 65 7d 0a 20 20 20 20 20 20  ${s.file}.      
2d30: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 20 7b    }.        if {
2d40: 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29  $::G(start:file)
2d50: 20 3d 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a   == ""} {unset :
2d60: 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 7d 0a  :G(start:file)}.
2d70: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
2d80: 2d 2b 6d 61 74 63 68 3d 2e 2b 24 7d 20 7b 0a 20  -+match=.+$} {. 
2d90: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
2da0: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
2db0: 28 6d 61 74 63 68 29 7d 20 5b 73 70 6c 69 74 20  (match)} [split 
2dc0: 24 61 20 3d 5d 20 62 72 65 61 6b 0a 0a 20 20 20  $a =] break..   
2dd0: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 6d 61 74       set ::G(mat
2de0: 63 68 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  ch) $cmdlinearg(
2df0: 6d 61 74 63 68 29 0a 20 20 20 20 20 20 20 20 69  match).        i
2e00: 66 20 7b 24 3a 3a 47 28 6d 61 74 63 68 29 20 3d  f {$::G(match) =
2e10: 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a 3a 47  = ""} {unset ::G
2e20: 28 6d 61 74 63 68 29 7d 0a 20 20 20 20 20 20 7d  (match)}.      }
2e30: 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 20 7b  .      default {
2e40: 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64  .        lappend
2e50: 20 6c 65 66 74 6f 76 65 72 20 24 61 0a 20 20 20   leftover $a.   
2e60: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20     }.    }.  }. 
2e70: 20 73 65 74 20 61 72 67 76 20 24 6c 65 66 74 6f   set argv $lefto
2e80: 76 65 72 0a 0a 20 20 23 20 49 6e 73 74 61 6c 6c  ver..  # Install
2e90: 20 74 68 65 20 6d 61 6c 6c 6f 63 20 6c 61 79 65   the malloc laye
2ea0: 72 20 75 73 65 64 20 74 6f 20 69 6e 6a 65 63 74  r used to inject
2eb0: 20 4f 4f 4d 20 65 72 72 6f 72 73 2e 20 41 6e 64   OOM errors. And
2ec0: 20 74 68 65 20 27 61 75 74 6f 6d 61 74 69 63 27   the 'automatic'
2ed0: 0a 20 20 23 20 65 78 74 65 6e 73 69 6f 6e 73 2e  .  # extensions.
2ee0: 20 54 68 69 73 20 6f 6e 6c 79 20 6e 65 65 64 73   This only needs
2ef0: 20 74 6f 20 62 65 20 64 6f 6e 65 20 6f 6e 63 65   to be done once
2f00: 20 66 6f 72 20 74 68 65 20 70 72 6f 63 65 73 73   for the process
2f10: 2e 0a 20 20 23 0a 20 20 73 71 6c 69 74 65 33 5f  ..  #.  sqlite3_
2f20: 73 68 75 74 64 6f 77 6e 20 0a 20 20 69 6e 73 74  shutdown .  inst
2f30: 61 6c 6c 5f 6d 61 6c 6c 6f 63 5f 66 61 75 6c 74  all_malloc_fault
2f40: 73 69 6d 20 31 20 0a 20 20 73 71 6c 69 74 65 33  sim 1 .  sqlite3
2f50: 5f 69 6e 69 74 69 61 6c 69 7a 65 0a 20 20 61 75  _initialize.  au
2f60: 74 6f 69 6e 73 74 61 6c 6c 5f 74 65 73 74 5f 66  toinstall_test_f
2f70: 75 6e 63 74 69 6f 6e 73 0a 0a 20 20 23 20 49 66  unctions..  # If
2f80: 20 74 68 65 20 2d 2d 62 69 6e 61 72 79 6c 6f 67   the --binarylog
2f90: 20 6f 70 74 69 6f 6e 20 77 61 73 20 73 70 65 63   option was spec
2fa0: 69 66 69 65 64 2c 20 63 72 65 61 74 65 20 74 68  ified, create th
2fb0: 65 20 6c 6f 67 67 69 6e 67 20 56 46 53 2e 20 54  e logging VFS. T
2fc0: 68 69 73 0a 20 20 23 20 63 61 6c 6c 20 69 6e 73  his.  # call ins
2fd0: 74 61 6c 6c 73 20 74 68 65 20 6e 65 77 20 56 46  talls the new VF
2fe0: 53 20 61 73 20 74 68 65 20 64 65 66 61 75 6c 74  S as the default
2ff0: 20 66 6f 72 20 61 6c 6c 20 53 51 4c 69 74 65 20   for all SQLite 
3000: 63 6f 6e 6e 65 63 74 69 6f 6e 73 2e 0a 20 20 23  connections..  #
3010: 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61  .  if {$cmdlinea
3020: 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 7b  rg(binarylog)} {
3030: 0a 20 20 20 20 76 66 73 6c 6f 67 20 6e 65 77 20  .    vfslog new 
3040: 62 69 6e 61 72 79 6c 6f 67 20 7b 7d 20 76 66 73  binarylog {} vfs
3050: 6c 6f 67 2e 62 69 6e 0a 20 20 7d 0a 0a 20 20 23  log.bin.  }..  #
3060: 20 53 65 74 20 74 68 65 20 62 61 63 6b 74 72 61   Set the backtra
3070: 63 65 20 64 65 70 74 68 2c 20 69 66 20 6d 61 6c  ce depth, if mal
3080: 6c 6f 63 20 74 72 61 63 69 6e 67 20 69 73 20 65  loc tracing is e
3090: 6e 61 62 6c 65 64 2e 0a 20 20 23 0a 20 20 69 66  nabled..  #.  if
30a0: 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61   {$cmdlinearg(ma
30b0: 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20 20  lloctrace)} {.  
30c0: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
30d0: 75 67 5f 62 61 63 6b 74 72 61 63 65 20 24 63 6d  ug_backtrace $cm
30e0: 64 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61  dlinearg(backtra
30f0: 63 65 29 0a 20 20 7d 0a 7d 0a 0a 23 20 55 70 64  ce).  }.}..# Upd
3100: 61 74 65 20 74 68 65 20 73 6f 66 74 2d 68 65 61  ate the soft-hea
3110: 70 2d 6c 69 6d 69 74 20 65 61 63 68 20 74 69 6d  p-limit each tim
3120: 65 20 74 68 69 73 20 73 63 72 69 70 74 20 69 73  e this script is
3130: 20 72 75 6e 2e 20 49 6e 20 74 68 61 74 0a 23 20   run. In that.# 
3140: 77 61 79 20 69 66 20 61 6e 20 69 6e 64 69 76 69  way if an indivi
3150: 64 75 61 6c 20 74 65 73 74 20 66 69 6c 65 20 63  dual test file c
3160: 68 61 6e 67 65 73 20 74 68 65 20 73 6f 66 74 2d  hanges the soft-
3170: 68 65 61 70 2d 6c 69 6d 69 74 2c 20 69 74 0a 23  heap-limit, it.#
3180: 20 77 69 6c 6c 20 62 65 20 72 65 73 65 74 20 61   will be reset a
3190: 74 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  t the start of t
31a0: 68 65 20 6e 65 78 74 20 74 65 73 74 20 66 69 6c  he next test fil
31b0: 65 2e 0a 23 0a 73 71 6c 69 74 65 33 5f 73 6f 66  e..#.sqlite3_sof
31c0: 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20 24 63 6d  t_heap_limit $cm
31d0: 64 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65  dlinearg(soft-he
31e0: 61 70 2d 6c 69 6d 69 74 29 0a 0a 23 20 43 72 65  ap-limit)..# Cre
31f0: 61 74 65 20 61 20 74 65 73 74 20 64 61 74 61 62  ate a test datab
3200: 61 73 65 0a 23 0a 70 72 6f 63 20 72 65 73 65 74  ase.#.proc reset
3210: 5f 64 62 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68  _db {} {.  catch
3220: 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66 6f   {db close}.  fo
3230: 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64  rcedelete test.d
3240: 62 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20  b.  forcedelete 
3250: 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a  test.db-journal.
3260: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65    forcedelete te
3270: 73 74 2e 64 62 2d 77 61 6c 0a 20 20 73 71 6c 69  st.db-wal.  sqli
3280: 74 65 33 20 64 62 20 2e 2f 74 65 73 74 2e 64 62  te3 db ./test.db
3290: 0a 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c  .  set ::DB [sql
32a0: 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f  ite3_connection_
32b0: 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 69 66  pointer db].  if
32c0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
32d0: 3a 53 45 54 55 50 5f 53 51 4c 5d 7d 20 7b 0a 20  :SETUP_SQL]} {. 
32e0: 20 20 20 64 62 20 65 76 61 6c 20 24 3a 3a 53 45     db eval $::SE
32f0: 54 55 50 5f 53 51 4c 0a 20 20 7d 0a 7d 0a 72 65  TUP_SQL.  }.}.re
3300: 73 65 74 5f 64 62 0a 0a 23 20 41 62 6f 72 74 20  set_db..# Abort 
3310: 65 61 72 6c 79 20 69 66 20 74 68 69 73 20 73 63  early if this sc
3320: 72 69 70 74 20 68 61 73 20 62 65 65 6e 20 72 75  ript has been ru
3330: 6e 20 62 65 66 6f 72 65 2e 0a 23 0a 69 66 20 7b  n before..#.if {
3340: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 54 43 28  [info exists TC(
3350: 63 6f 75 6e 74 29 5d 7d 20 72 65 74 75 72 6e 0a  count)]} return.
3360: 0a 23 20 4d 61 6b 65 20 73 75 72 65 20 6d 65 6d  .# Make sure mem
3370: 6f 72 79 20 73 74 61 74 69 73 74 69 63 73 20 61  ory statistics a
3380: 72 65 20 65 6e 61 62 6c 65 64 2e 0a 23 0a 73 71  re enabled..#.sq
3390: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 5f 6d 65 6d  lite3_config_mem
33a0: 73 74 61 74 75 73 20 31 0a 0a 23 20 49 6e 69 74  status 1..# Init
33b0: 69 61 6c 69 7a 65 20 74 68 65 20 74 65 73 74 20  ialize the test 
33c0: 63 6f 75 6e 74 65 72 73 20 61 6e 64 20 73 65 74  counters and set
33d0: 20 75 70 20 63 6f 6d 6d 61 6e 64 73 20 74 6f 20   up commands to 
33e0: 61 63 63 65 73 73 20 74 68 65 6d 2e 0a 23 20 4f  access them..# O
33f0: 72 2c 20 69 66 20 74 68 69 73 20 69 73 20 61 20  r, if this is a 
3400: 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74 65  slave interprete
3410: 72 2c 20 73 65 74 20 75 70 20 61 6c 69 61 73 65  r, set up aliase
3420: 73 20 74 6f 20 77 72 69 74 65 20 74 68 65 0a 23  s to write the.#
3430: 20 63 6f 75 6e 74 65 72 73 20 69 6e 20 74 68 65   counters in the
3440: 20 70 61 72 65 6e 74 20 69 6e 74 65 72 70 72 65   parent interpre
3450: 74 65 72 2e 0a 23 0a 69 66 20 7b 30 3d 3d 5b 69  ter..#.if {0==[i
3460: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c 41  nfo exists ::SLA
3470: 56 45 5d 7d 20 7b 0a 20 20 73 65 74 20 54 43 28  VE]} {.  set TC(
3480: 65 72 72 6f 72 73 29 20 20 20 20 30 0a 20 20 73  errors)    0.  s
3490: 65 74 20 54 43 28 63 6f 75 6e 74 29 20 20 20 20  et TC(count)    
34a0: 20 30 0a 20 20 73 65 74 20 54 43 28 66 61 69 6c   0.  set TC(fail
34b0: 5f 6c 69 73 74 29 20 5b 6c 69 73 74 5d 0a 20 20  _list) [list].  
34c0: 73 65 74 20 54 43 28 6f 6d 69 74 5f 6c 69 73 74  set TC(omit_list
34d0: 29 20 5b 6c 69 73 74 5d 0a 0a 20 20 70 72 6f 63  ) [list]..  proc
34e0: 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65   set_test_counte
34f0: 72 20 7b 63 6f 75 6e 74 65 72 20 61 72 67 73 7d  r {counter args}
3500: 20 7b 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e   {.    if {[llen
3510: 67 74 68 20 24 61 72 67 73 5d 7d 20 7b 0a 20 20  gth $args]} {.  
3520: 20 20 20 20 73 65 74 20 3a 3a 54 43 28 24 63 6f      set ::TC($co
3530: 75 6e 74 65 72 29 20 5b 6c 69 6e 64 65 78 20 24  unter) [lindex $
3540: 61 72 67 73 20 30 5d 0a 20 20 20 20 7d 0a 20 20  args 0].    }.  
3550: 20 20 73 65 74 20 3a 3a 54 43 28 24 63 6f 75 6e    set ::TC($coun
3560: 74 65 72 29 0a 20 20 7d 0a 7d 0a 0a 23 20 52 65  ter).  }.}..# Re
3570: 63 6f 72 64 20 74 68 65 20 66 61 63 74 20 74 68  cord the fact th
3580: 61 74 20 61 20 73 65 71 75 65 6e 63 65 20 6f 66  at a sequence of
3590: 20 74 65 73 74 73 20 77 65 72 65 20 6f 6d 69 74   tests were omit
35a0: 74 65 64 2e 0a 23 0a 70 72 6f 63 20 6f 6d 69 74  ted..#.proc omit
35b0: 5f 74 65 73 74 20 7b 6e 61 6d 65 20 72 65 61 73  _test {name reas
35c0: 6f 6e 20 7b 61 70 70 65 6e 64 20 31 7d 7d 20 7b  on {append 1}} {
35d0: 0a 20 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20  .  set omitList 
35e0: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
35f0: 72 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 20 20 69  r omit_list].  i
3600: 66 20 7b 24 61 70 70 65 6e 64 7d 20 7b 0a 20 20  f {$append} {.  
3610: 20 20 6c 61 70 70 65 6e 64 20 6f 6d 69 74 4c 69    lappend omitLi
3620: 73 74 20 5b 6c 69 73 74 20 24 6e 61 6d 65 20 24  st [list $name $
3630: 72 65 61 73 6f 6e 5d 0a 20 20 7d 0a 20 20 73 65  reason].  }.  se
3640: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 6f  t_test_counter o
3650: 6d 69 74 5f 6c 69 73 74 20 24 6f 6d 69 74 4c 69  mit_list $omitLi
3660: 73 74 0a 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74  st.}..# Record t
3670: 68 65 20 66 61 63 74 20 74 68 61 74 20 61 20 74  he fact that a t
3680: 65 73 74 20 66 61 69 6c 65 64 2e 0a 23 0a 70 72  est failed..#.pr
3690: 6f 63 20 66 61 69 6c 5f 74 65 73 74 20 7b 6e 61  oc fail_test {na
36a0: 6d 65 7d 20 7b 0a 20 20 73 65 74 20 66 20 5b 73  me} {.  set f [s
36b0: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
36c0: 66 61 69 6c 5f 6c 69 73 74 5d 0a 20 20 6c 61 70  fail_list].  lap
36d0: 70 65 6e 64 20 66 20 24 6e 61 6d 65 0a 20 20 73  pend f $name.  s
36e0: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
36f0: 66 61 69 6c 5f 6c 69 73 74 20 24 66 0a 20 20 73  fail_list $f.  s
3700: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
3710: 65 72 72 6f 72 73 20 5b 65 78 70 72 20 5b 73 65  errors [expr [se
3720: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 65  t_test_counter e
3730: 72 72 6f 72 73 5d 20 2b 20 31 5d 0a 0a 20 20 73  rrors] + 1]..  s
3740: 65 74 20 6e 46 61 69 6c 20 5b 73 65 74 5f 74 65  et nFail [set_te
3750: 73 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72  st_counter error
3760: 73 5d 0a 20 20 69 66 20 7b 24 6e 46 61 69 6c 3e  s].  if {$nFail>
3770: 3d 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 6d  =$::cmdlinearg(m
3780: 61 78 65 72 72 6f 72 29 7d 20 7b 0a 20 20 20 20  axerror)} {.    
3790: 70 75 74 73 20 22 2a 2a 2a 20 47 69 76 69 6e 67  puts "*** Giving
37a0: 20 75 70 2e 2e 2e 22 0a 20 20 20 20 66 69 6e 61   up...".    fina
37b0: 6c 69 7a 65 5f 74 65 73 74 69 6e 67 0a 20 20 7d  lize_testing.  }
37c0: 0a 7d 0a 0a 23 20 49 6e 63 72 65 6d 65 6e 74 20  .}..# Increment 
37d0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 65  the number of te
37e0: 73 74 73 20 72 75 6e 0a 23 0a 70 72 6f 63 20 69  sts run.#.proc i
37f0: 6e 63 72 5f 6e 74 65 73 74 20 7b 7d 20 7b 0a 20  ncr_ntest {} {. 
3800: 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65   set_test_counte
3810: 72 20 63 6f 75 6e 74 20 5b 65 78 70 72 20 5b 73  r count [expr [s
3820: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
3830: 63 6f 75 6e 74 5d 20 2b 20 31 5d 0a 7d 0a 0a 0a  count] + 1].}...
3840: 23 20 49 6e 76 6f 6b 65 20 74 68 65 20 64 6f 5f  # Invoke the do_
3850: 74 65 73 74 20 70 72 6f 63 65 64 75 72 65 20 74  test procedure t
3860: 6f 20 72 75 6e 20 61 20 73 69 6e 67 6c 65 20 74  o run a single t
3870: 65 73 74 20 0a 23 0a 70 72 6f 63 20 64 6f 5f 74  est .#.proc do_t
3880: 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78  est {name cmd ex
3890: 70 65 63 74 65 64 7d 20 7b 0a 20 20 67 6c 6f 62  pected} {.  glob
38a0: 61 6c 20 61 72 67 76 20 63 6d 64 6c 69 6e 65 61  al argv cmdlinea
38b0: 72 67 0a 0a 20 20 66 69 78 5f 74 65 73 74 6e 61  rg..  fix_testna
38c0: 6d 65 20 6e 61 6d 65 0a 0a 20 20 73 71 6c 69 74  me name..  sqlit
38d0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 73 65 74 74  e3_memdebug_sett
38e0: 69 74 6c 65 20 24 6e 61 6d 65 0a 0a 23 20 20 69  itle $name..#  i
38f0: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67  f {[llength $arg
3900: 76 5d 3d 3d 30 7d 20 7b 20 0a 23 20 20 20 20 73  v]==0} { .#    s
3910: 65 74 20 67 6f 20 31 0a 23 20 20 7d 20 65 6c 73  et go 1.#  } els
3920: 65 20 7b 0a 23 20 20 20 20 73 65 74 20 67 6f 20  e {.#    set go 
3930: 30 0a 23 20 20 20 20 66 6f 72 65 61 63 68 20 70  0.#    foreach p
3940: 61 74 74 65 72 6e 20 24 61 72 67 76 20 7b 0a 23  attern $argv {.#
3950: 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e        if {[strin
3960: 67 20 6d 61 74 63 68 20 24 70 61 74 74 65 72 6e  g match $pattern
3970: 20 24 6e 61 6d 65 5d 7d 20 7b 0a 23 20 20 20 20   $name]} {.#    
3980: 20 20 20 20 73 65 74 20 67 6f 20 31 0a 23 20 20      set go 1.#  
3990: 20 20 20 20 20 20 62 72 65 61 6b 0a 23 20 20 20        break.#   
39a0: 20 20 20 7d 0a 23 20 20 20 20 7d 0a 23 20 20 7d     }.#    }.#  }
39b0: 0a 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  ..  if {[info ex
39c0: 69 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a 70 72  ists ::G(perm:pr
39d0: 65 66 69 78 29 5d 7d 20 7b 0a 20 20 20 20 73 65  efix)]} {.    se
39e0: 74 20 6e 61 6d 65 20 22 24 3a 3a 47 28 70 65 72  t name "$::G(per
39f0: 6d 3a 70 72 65 66 69 78 29 24 6e 61 6d 65 22 0a  m:prefix)$name".
3a00: 20 20 7d 0a 0a 20 20 69 6e 63 72 5f 6e 74 65 73    }..  incr_ntes
3a10: 74 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c  t.  puts -nonewl
3a20: 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 66  ine $name....  f
3a30: 6c 75 73 68 20 73 74 64 6f 75 74 0a 0a 20 20 69  lush stdout..  i
3a40: 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73  f {![info exists
3a50: 20 3a 3a 47 28 6d 61 74 63 68 29 5d 20 7c 7c 20   ::G(match)] || 
3a60: 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 3a  [string match $:
3a70: 3a 47 28 6d 61 74 63 68 29 20 24 6e 61 6d 65 5d  :G(match) $name]
3a80: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 63 61 74  } {.    if {[cat
3a90: 63 68 20 7b 75 70 6c 65 76 65 6c 20 23 30 20 22  ch {uplevel #0 "
3aa0: 24 63 6d 64 3b 5c 6e 22 7d 20 72 65 73 75 6c 74  $cmd;\n"} result
3ab0: 5d 7d 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20  ]} {.      puts 
3ac0: 22 5c 6e 45 72 72 6f 72 3a 20 24 72 65 73 75 6c  "\nError: $resul
3ad0: 74 22 0a 20 20 20 20 20 20 66 61 69 6c 5f 74 65  t".      fail_te
3ae0: 73 74 20 24 6e 61 6d 65 0a 20 20 20 20 7d 20 65  st $name.    } e
3af0: 6c 73 65 20 7b 0a 20 20 20 20 20 20 69 66 20 7b  lse {.      if {
3b00: 5b 72 65 67 65 78 70 20 7b 5e 7e 3f 2f 2e 2a 2f  [regexp {^~?/.*/
3b10: 24 7d 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b  $} $expected]} {
3b20: 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 73 74  .        if {[st
3b30: 72 69 6e 67 20 69 6e 64 65 78 20 24 65 78 70 65  ring index $expe
3b40: 63 74 65 64 20 30 5d 3d 3d 22 7e 22 7d 20 7b 0a  cted 0]=="~"} {.
3b50: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 72 65            set re
3b60: 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24   [string range $
3b70: 65 78 70 65 63 74 65 64 20 32 20 65 6e 64 2d 31  expected 2 end-1
3b80: 5d 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  ].          set 
3b90: 6f 6b 20 5b 65 78 70 72 20 7b 21 5b 72 65 67 65  ok [expr {![rege
3ba0: 78 70 20 24 72 65 20 24 72 65 73 75 6c 74 5d 7d  xp $re $result]}
3bb0: 5d 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65  ].        } else
3bc0: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 74   {.          set
3bd0: 20 72 65 20 5b 73 74 72 69 6e 67 20 72 61 6e 67   re [string rang
3be0: 65 20 24 65 78 70 65 63 74 65 64 20 31 20 65 6e  e $expected 1 en
3bf0: 64 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20 73  d-1].          s
3c00: 65 74 20 6f 6b 20 5b 72 65 67 65 78 70 20 24 72  et ok [regexp $r
3c10: 65 20 24 72 65 73 75 6c 74 5d 0a 20 20 20 20 20  e $result].     
3c20: 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73     }.      } els
3c30: 65 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  e {.        set 
3c40: 6f 6b 20 5b 65 78 70 72 20 7b 5b 73 74 72 69 6e  ok [expr {[strin
3c50: 67 20 63 6f 6d 70 61 72 65 20 24 72 65 73 75 6c  g compare $resul
3c60: 74 20 24 65 78 70 65 63 74 65 64 5d 3d 3d 30 7d  t $expected]==0}
3c70: 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ].      }.      
3c80: 69 66 20 7b 21 24 6f 6b 7d 20 7b 0a 20 20 20 20  if {!$ok} {.    
3c90: 20 20 20 20 70 75 74 73 20 22 5c 6e 45 78 70 65      puts "\nExpe
3ca0: 63 74 65 64 3a 20 5c 5b 24 65 78 70 65 63 74 65  cted: \[$expecte
3cb0: 64 5c 5d 5c 6e 20 20 20 20 20 47 6f 74 3a 20 5c  d\]\n     Got: \
3cc0: 5b 24 72 65 73 75 6c 74 5c 5d 22 0a 20 20 20 20  [$result\]".    
3cd0: 20 20 20 20 66 61 69 6c 5f 74 65 73 74 20 24 6e      fail_test $n
3ce0: 61 6d 65 0a 20 20 20 20 20 20 7d 20 65 6c 73 65  ame.      } else
3cf0: 20 7b 0a 20 20 20 20 20 20 20 20 70 75 74 73 20   {.        puts 
3d00: 22 20 4f 6b 22 0a 20 20 20 20 20 20 7d 0a 20 20  " Ok".      }.  
3d10: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
3d20: 20 20 20 70 75 74 73 20 22 20 4f 6d 69 74 74 65     puts " Omitte
3d30: 64 22 0a 20 20 20 20 6f 6d 69 74 5f 74 65 73 74  d".    omit_test
3d40: 20 24 6e 61 6d 65 20 22 70 61 74 74 65 72 6e 20   $name "pattern 
3d50: 6d 69 73 6d 61 74 63 68 22 20 30 0a 20 20 7d 0a  mismatch" 0.  }.
3d60: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 7d    flush stdout.}
3d70: 0a 0a 70 72 6f 63 20 63 61 74 63 68 63 6d 64 20  ..proc catchcmd 
3d80: 7b 64 62 20 7b 63 6d 64 20 22 22 7d 7d 20 7b 0a  {db {cmd ""}} {.
3d90: 20 20 67 6c 6f 62 61 6c 20 43 4c 49 0a 20 20 73    global CLI.  s
3da0: 65 74 20 6f 75 74 20 5b 6f 70 65 6e 20 63 6d 64  et out [open cmd
3db0: 73 2e 74 78 74 20 77 5d 0a 20 20 70 75 74 73 20  s.txt w].  puts 
3dc0: 24 6f 75 74 20 24 63 6d 64 0a 20 20 63 6c 6f 73  $out $cmd.  clos
3dd0: 65 20 24 6f 75 74 0a 20 20 73 65 74 20 6c 69 6e  e $out.  set lin
3de0: 65 20 22 65 78 65 63 20 24 43 4c 49 20 24 64 62  e "exec $CLI $db
3df0: 20 3c 20 63 6d 64 73 2e 74 78 74 22 0a 20 20 73   < cmds.txt".  s
3e00: 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 20 65  et rc [catch { e
3e10: 76 61 6c 20 24 6c 69 6e 65 20 7d 20 6d 73 67 5d  val $line } msg]
3e20: 0a 20 20 6c 69 73 74 20 24 72 63 20 24 6d 73 67  .  list $rc $msg
3e30: 0a 7d 0a 0a 70 72 6f 63 20 66 69 6c 65 70 61 74  .}..proc filepat
3e40: 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 7b 70 7d 20  h_normalize {p} 
3e50: 7b 0a 20 20 23 20 74 65 73 74 20 63 61 73 65 73  {.  # test cases
3e60: 20 73 68 6f 75 6c 64 20 62 65 20 77 72 69 74 74   should be writt
3e70: 65 6e 20 74 6f 20 61 73 73 75 6d 65 20 22 75 6e  en to assume "un
3e80: 69 78 22 2d 6c 69 6b 65 20 66 69 6c 65 20 70 61  ix"-like file pa
3e90: 74 68 73 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c  ths.  if {$::tcl
3ea0: 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f  _platform(platfo
3eb0: 72 6d 29 21 3d 22 75 6e 69 78 22 7d 20 7b 0a 20  rm)!="unix"} {. 
3ec0: 20 20 20 23 20 6c 72 65 76 65 72 73 65 2a 32 20     # lreverse*2 
3ed0: 61 73 20 61 20 68 61 63 6b 20 74 6f 20 72 65 6d  as a hack to rem
3ee0: 6f 76 65 20 61 6e 79 20 75 6e 6e 65 65 64 65 64  ove any unneeded
3ef0: 20 7b 7d 20 61 66 74 65 72 20 74 68 65 20 73 74   {} after the st
3f00: 72 69 6e 67 20 6d 61 70 0a 20 20 20 20 6c 72 65  ring map.    lre
3f10: 76 65 72 73 65 20 5b 6c 72 65 76 65 72 73 65 20  verse [lreverse 
3f20: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 5c 5c 20  [string map {\\ 
3f30: 2f 7d 20 5b 72 65 67 73 75 62 20 2d 6e 6f 63 61  /} [regsub -noca
3f40: 73 65 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5d 3a 5b  se -all {[a-z]:[
3f50: 2f 5c 5c 5d 2b 7d 20 24 70 20 7b 2f 7d 5d 5d 5d  /\\]+} $p {/}]]]
3f60: 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 70  .  } {.    set p
3f70: 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 66  .  }.}.proc do_f
3f80: 69 6c 65 70 61 74 68 5f 74 65 73 74 20 7b 6e 61  ilepath_test {na
3f90: 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65 64 7d  me cmd expected}
3fa0: 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69   {.  uplevel [li
3fb0: 73 74 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65  st do_test $name
3fc0: 20 5b 0a 20 20 20 20 73 75 62 73 74 20 2d 6e 6f   [.    subst -no
3fd0: 63 6f 6d 6d 61 6e 64 73 20 7b 20 66 69 6c 65 70  commands { filep
3fe0: 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 5b 20  ath_normalize [ 
3ff0: 24 63 6d 64 20 5d 20 7d 0a 20 20 5d 20 5b 66 69  $cmd ] }.  ] [fi
4000: 6c 65 70 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65  lepath_normalize
4010: 20 24 65 78 70 65 63 74 65 64 5d 5d 0a 7d 0a 0a   $expected]].}..
4020: 70 72 6f 63 20 72 65 61 6c 6e 75 6d 5f 6e 6f 72  proc realnum_nor
4030: 6d 61 6c 69 7a 65 20 7b 72 7d 20 7b 0a 20 20 23  malize {r} {.  #
4040: 20 64 69 66 66 65 72 65 6e 74 20 54 43 4c 20 76   different TCL v
4050: 65 72 73 69 6f 6e 73 20 64 69 73 70 6c 61 79 20  ersions display 
4060: 66 6c 6f 61 74 69 6e 67 20 70 6f 69 6e 74 20 76  floating point v
4070: 61 6c 75 65 73 20 64 69 66 66 65 72 65 6e 74 6c  alues differentl
4080: 79 2e 0a 20 20 73 74 72 69 6e 67 20 6d 61 70 20  y..  string map 
4090: 7b 31 2e 23 49 4e 46 20 69 6e 66 20 49 6e 66 20  {1.#INF inf Inf 
40a0: 69 6e 66 20 2e 30 65 20 65 7d 20 5b 72 65 67 73  inf .0e e} [regs
40b0: 75 62 20 2d 61 6c 6c 20 7b 28 65 5b 2b 2d 5d 29  ub -all {(e[+-])
40c0: 30 2b 7d 20 24 72 20 7b 5c 31 7d 5d 0a 7d 0a 70  0+} $r {\1}].}.p
40d0: 72 6f 63 20 64 6f 5f 72 65 61 6c 6e 75 6d 5f 74  roc do_realnum_t
40e0: 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78  est {name cmd ex
40f0: 70 65 63 74 65 64 7d 20 7b 0a 20 20 75 70 6c 65  pected} {.  uple
4100: 76 65 6c 20 5b 6c 69 73 74 20 64 6f 5f 74 65 73  vel [list do_tes
4110: 74 20 24 6e 61 6d 65 20 5b 0a 20 20 20 20 73 75  t $name [.    su
4120: 62 73 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64 73 20  bst -nocommands 
4130: 7b 20 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c  { realnum_normal
4140: 69 7a 65 20 5b 20 24 63 6d 64 20 5d 20 7d 0a 20  ize [ $cmd ] }. 
4150: 20 5d 20 5b 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d   ] [realnum_norm
4160: 61 6c 69 7a 65 20 24 65 78 70 65 63 74 65 64 5d  alize $expected]
4170: 5d 0a 7d 0a 0a 70 72 6f 63 20 66 69 78 5f 74 65  ].}..proc fix_te
4180: 73 74 6e 61 6d 65 20 7b 76 61 72 6e 61 6d 65 7d  stname {varname}
4190: 20 7b 0a 20 20 75 70 76 61 72 20 24 76 61 72 6e   {.  upvar $varn
41a0: 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20 69  ame testname.  i
41b0: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
41c0: 3a 3a 74 65 73 74 70 72 65 66 69 78 5d 20 0a 20  ::testprefix] . 
41d0: 20 20 26 26 20 5b 73 74 72 69 6e 67 20 69 73 20    && [string is 
41e0: 64 69 67 69 74 20 5b 73 74 72 69 6e 67 20 72 61  digit [string ra
41f0: 6e 67 65 20 24 74 65 73 74 6e 61 6d 65 20 30 20  nge $testname 0 
4200: 30 5d 5d 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65  0]].  } {.    se
4210: 74 20 74 65 73 74 6e 61 6d 65 20 22 24 7b 3a 3a  t testname "${::
4220: 74 65 73 74 70 72 65 66 69 78 7d 2d 24 74 65 73  testprefix}-$tes
4230: 74 6e 61 6d 65 22 0a 20 20 7d 0a 7d 0a 20 20 20  tname".  }.}.   
4240: 20 0a 70 72 6f 63 20 64 6f 5f 65 78 65 63 73 71   .proc do_execsq
4250: 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61 6d 65  l_test {testname
4260: 20 73 71 6c 20 7b 72 65 73 75 6c 74 20 7b 7d 7d   sql {result {}}
4270: 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73 74 6e 61  } {.  fix_testna
4280: 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20 75 70  me testname.  up
4290: 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 5b 6c  level do_test [l
42a0: 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d 20 5b  ist $testname] [
42b0: 6c 69 73 74 20 22 65 78 65 63 73 71 6c 20 7b 24  list "execsql {$
42c0: 73 71 6c 7d 22 5d 20 5b 6c 69 73 74 20 5b 6c 69  sql}"] [list [li
42d0: 73 74 20 7b 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a  st {*}$result]].
42e0: 7d 0a 70 72 6f 63 20 64 6f 5f 63 61 74 63 68 73  }.proc do_catchs
42f0: 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61 6d  ql_test {testnam
4300: 65 20 73 71 6c 20 72 65 73 75 6c 74 7d 20 7b 0a  e sql result} {.
4310: 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 74    fix_testname t
4320: 65 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76 65  estname.  upleve
4330: 6c 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74 20  l do_test [list 
4340: 24 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73 74  $testname] [list
4350: 20 22 63 61 74 63 68 73 71 6c 20 7b 24 73 71 6c   "catchsql {$sql
4360: 7d 22 5d 20 5b 6c 69 73 74 20 24 72 65 73 75 6c  }"] [list $resul
4370: 74 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 65 71 70  t].}.proc do_eqp
4380: 5f 74 65 73 74 20 7b 6e 61 6d 65 20 73 71 6c 20  _test {name sql 
4390: 72 65 73 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c  res} {.  uplevel
43a0: 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74   do_execsql_test
43b0: 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20 22 45 58   $name [list "EX
43c0: 50 4c 41 49 4e 20 51 55 45 52 59 20 50 4c 41 4e  PLAIN QUERY PLAN
43d0: 20 24 73 71 6c 22 5d 20 5b 6c 69 73 74 20 24 72   $sql"] [list $r
43e0: 65 73 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  es].}..#--------
43f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4400: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4410: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4420: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4430: 2d 0a 23 20 20 20 55 73 61 67 65 3a 20 64 6f 5f  -.#   Usage: do_
4440: 73 65 6c 65 63 74 5f 74 65 73 74 73 20 50 52 45  select_tests PRE
4450: 46 49 58 20 3f 53 57 49 54 43 48 45 53 3f 20 54  FIX ?SWITCHES? T
4460: 45 53 54 4c 49 53 54 0a 23 0a 23 20 57 68 65 72  ESTLIST.#.# Wher
4470: 65 20 73 77 69 74 63 68 65 73 20 61 72 65 3a 0a  e switches are:.
4480: 23 0a 23 20 20 20 2d 65 72 72 6f 72 66 6f 72 6d  #.#   -errorform
4490: 61 74 20 46 4d 54 53 54 52 49 4e 47 0a 23 20 20  at FMTSTRING.#  
44a0: 20 2d 63 6f 75 6e 74 0a 23 20 20 20 2d 71 75 65   -count.#   -que
44b0: 72 79 20 53 51 4c 0a 23 20 20 20 2d 74 63 6c 71  ry SQL.#   -tclq
44c0: 75 65 72 79 20 54 43 4c 0a 23 20 20 20 2d 72 65  uery TCL.#   -re
44d0: 70 61 69 72 20 54 43 4c 0a 23 0a 70 72 6f 63 20  pair TCL.#.proc 
44e0: 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74 73 20  do_select_tests 
44f0: 7b 70 72 65 66 69 78 20 61 72 67 73 7d 20 7b 0a  {prefix args} {.
4500: 0a 20 20 73 65 74 20 74 65 73 74 6c 69 73 74 20  .  set testlist 
4510: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65 6e  [lindex $args en
4520: 64 5d 0a 20 20 73 65 74 20 73 77 69 74 63 68 65  d].  set switche
4530: 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20  s [lrange $args 
4540: 30 20 65 6e 64 2d 31 5d 0a 0a 20 20 73 65 74 20  0 end-1]..  set 
4550: 65 72 72 66 6d 74 20 22 22 0a 20 20 73 65 74 20  errfmt "".  set 
4560: 63 6f 75 6e 74 6f 6e 6c 79 20 30 0a 20 20 73 65  countonly 0.  se
4570: 74 20 74 63 6c 71 75 65 72 79 20 22 22 0a 20 20  t tclquery "".  
4580: 73 65 74 20 72 65 70 61 69 72 20 22 22 0a 0a 20  set repair "".. 
4590: 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b   for {set i 0} {
45a0: 24 69 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 73  $i < [llength $s
45b0: 77 69 74 63 68 65 73 5d 7d 20 7b 69 6e 63 72 20  witches]} {incr 
45c0: 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 20 5b  i} {.    set s [
45d0: 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68 65 73  lindex $switches
45e0: 20 24 69 5d 0a 20 20 20 20 73 65 74 20 6e 20 5b   $i].    set n [
45f0: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73  string length $s
4600: 5d 0a 20 20 20 20 69 66 20 7b 24 6e 3e 3d 32 20  ].    if {$n>=2 
4610: 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c  && [string equal
4620: 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22   -length $n $s "
4630: 2d 71 75 65 72 79 22 5d 7d 20 7b 0a 20 20 20 20  -query"]} {.    
4640: 20 20 73 65 74 20 74 63 6c 71 75 65 72 79 20 5b    set tclquery [
4650: 6c 69 73 74 20 65 78 65 63 73 71 6c 20 5b 6c 69  list execsql [li
4660: 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20 5b  ndex $switches [
4670: 69 6e 63 72 20 69 5d 5d 5d 0a 20 20 20 20 7d 20  incr i]]].    } 
4680: 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26  elseif {$n>=2 &&
4690: 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d   [string equal -
46a0: 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 74  length $n $s "-t
46b0: 63 6c 71 75 65 72 79 22 5d 7d 20 7b 0a 20 20 20  clquery"]} {.   
46c0: 20 20 20 73 65 74 20 74 63 6c 71 75 65 72 79 20     set tclquery 
46d0: 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68 65  [lindex $switche
46e0: 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20  s [incr i]].    
46f0: 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20  } elseif {$n>=2 
4700: 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c  && [string equal
4710: 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22   -length $n $s "
4720: 2d 65 72 72 6f 72 66 6f 72 6d 61 74 22 5d 7d 20  -errorformat"]} 
4730: 7b 0a 20 20 20 20 20 20 73 65 74 20 65 72 72 66  {.      set errf
4740: 6d 74 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74  mt [lindex $swit
4750: 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20  ches [incr i]]. 
4760: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e     } elseif {$n>
4770: 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71  =2 && [string eq
4780: 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24  ual -length $n $
4790: 73 20 22 2d 72 65 70 61 69 72 22 5d 7d 20 7b 0a  s "-repair"]} {.
47a0: 20 20 20 20 20 20 73 65 74 20 72 65 70 61 69 72        set repair
47b0: 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68   [lindex $switch
47c0: 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20  es [incr i]].   
47d0: 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32   } elseif {$n>=2
47e0: 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61   && [string equa
47f0: 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20  l -length $n $s 
4800: 22 2d 63 6f 75 6e 74 22 5d 7d 20 7b 0a 20 20 20  "-count"]} {.   
4810: 20 20 20 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79     set countonly
4820: 20 31 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a   1.    } else {.
4830: 20 20 20 20 20 20 65 72 72 6f 72 20 22 75 6e 6b        error "unk
4840: 6e 6f 77 6e 20 73 77 69 74 63 68 3a 20 24 73 22  nown switch: $s"
4850: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
4860: 20 7b 24 63 6f 75 6e 74 6f 6e 6c 79 20 26 26 20   {$countonly && 
4870: 24 65 72 72 66 6d 74 21 3d 22 22 7d 20 7b 0a 20  $errfmt!=""} {. 
4880: 20 20 20 65 72 72 6f 72 20 22 43 61 6e 6e 6f 74     error "Cannot
4890: 20 75 73 65 20 2d 63 6f 75 6e 74 20 61 6e 64 20   use -count and 
48a0: 2d 65 72 72 6f 72 66 6f 72 6d 61 74 20 74 6f 67  -errorformat tog
48b0: 65 74 68 65 72 22 0a 20 20 7d 0a 20 20 73 65 74  ether".  }.  set
48c0: 20 6e 54 65 73 74 6c 69 73 74 20 5b 6c 6c 65 6e   nTestlist [llen
48d0: 67 74 68 20 24 74 65 73 74 6c 69 73 74 5d 0a 20  gth $testlist]. 
48e0: 20 69 66 20 7b 24 6e 54 65 73 74 6c 69 73 74 25   if {$nTestlist%
48f0: 33 20 7c 7c 20 24 6e 54 65 73 74 6c 69 73 74 3d  3 || $nTestlist=
4900: 3d 30 20 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72  =0 } {.    error
4910: 20 22 53 45 4c 45 43 54 20 74 65 73 74 20 6c 69   "SELECT test li
4920: 73 74 20 63 6f 6e 74 61 69 6e 73 20 5b 6c 6c 65  st contains [lle
4930: 6e 67 74 68 20 24 74 65 73 74 6c 69 73 74 5d 20  ngth $testlist] 
4940: 65 6c 65 6d 65 6e 74 73 22 0a 20 20 7d 0a 0a 20  elements".  }.. 
4950: 20 65 76 61 6c 20 24 72 65 70 61 69 72 0a 20 20   eval $repair.  
4960: 66 6f 72 65 61 63 68 20 7b 74 6e 20 73 71 6c 20  foreach {tn sql 
4970: 72 65 73 7d 20 24 74 65 73 74 6c 69 73 74 20 7b  res} $testlist {
4980: 0a 20 20 20 20 69 66 20 7b 24 74 63 6c 71 75 65  .    if {$tclque
4990: 72 79 20 21 3d 20 22 22 7d 20 7b 0a 20 20 20 20  ry != ""} {.    
49a0: 20 20 65 78 65 63 73 71 6c 20 24 73 71 6c 0a 20    execsql $sql. 
49b0: 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f       uplevel do_
49c0: 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24  test ${prefix}.$
49d0: 74 6e 20 5b 6c 69 73 74 20 24 74 63 6c 71 75 65  tn [list $tclque
49e0: 72 79 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20  ry] [list [list 
49f0: 7b 2a 7d 24 72 65 73 5d 5d 0a 20 20 20 20 7d 20  {*}$res]].    } 
4a00: 65 6c 73 65 69 66 20 7b 24 63 6f 75 6e 74 6f 6e  elseif {$counton
4a10: 6c 79 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  ly} {.      set 
4a20: 6e 52 6f 77 20 30 0a 20 20 20 20 20 20 64 62 20  nRow 0.      db 
4a30: 65 76 61 6c 20 24 73 71 6c 20 7b 69 6e 63 72 20  eval $sql {incr 
4a40: 6e 52 6f 77 7d 0a 20 20 20 20 20 20 75 70 6c 65  nRow}.      uple
4a50: 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 7b 70 72  vel do_test ${pr
4a60: 65 66 69 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20  efix}.$tn [list 
4a70: 5b 6c 69 73 74 20 73 65 74 20 7b 7d 20 24 6e 52  [list set {} $nR
4a80: 6f 77 5d 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d  ow]] [list $res]
4a90: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
4aa0: 65 72 72 66 6d 74 3d 3d 22 22 7d 20 7b 0a 20 20  errfmt==""} {.  
4ab0: 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 65      uplevel do_e
4ac0: 78 65 63 73 71 6c 5f 74 65 73 74 20 24 7b 70 72  xecsql_test ${pr
4ad0: 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69 73  efix}.${tn} [lis
4ae0: 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74 20 5b 6c  t $sql] [list [l
4af0: 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20 20  ist {*}$res]].  
4b00: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
4b10: 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74 20 31   set res [list 1
4b20: 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 5b 66   [string trim [f
4b30: 6f 72 6d 61 74 20 24 65 72 72 66 6d 74 20 7b 2a  ormat $errfmt {*
4b40: 7d 24 72 65 73 5d 5d 5d 0a 20 20 20 20 20 20 75  }$res]]].      u
4b50: 70 6c 65 76 65 6c 20 64 6f 5f 63 61 74 63 68 73  plevel do_catchs
4b60: 71 6c 5f 74 65 73 74 20 24 7b 70 72 65 66 69 78  ql_test ${prefix
4b70: 7d 2e 24 7b 74 6e 7d 20 5b 6c 69 73 74 20 24 73  }.${tn} [list $s
4b80: 71 6c 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a  ql] [list $res].
4b90: 20 20 20 20 7d 0a 20 20 20 20 65 76 61 6c 20 24      }.    eval $
4ba0: 72 65 70 61 69 72 0a 20 20 7d 0a 0a 7d 0a 0a 70  repair.  }..}..p
4bb0: 72 6f 63 20 64 65 6c 65 74 65 5f 61 6c 6c 5f 64  roc delete_all_d
4bc0: 61 74 61 20 7b 7d 20 7b 0a 20 20 64 62 20 65 76  ata {} {.  db ev
4bd0: 61 6c 20 7b 53 45 4c 45 43 54 20 74 62 6c 5f 6e  al {SELECT tbl_n
4be0: 61 6d 65 20 41 53 20 74 20 46 52 4f 4d 20 73 71  ame AS t FROM sq
4bf0: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
4c00: 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27  E type = 'table'
4c10: 7d 20 7b 0a 20 20 20 20 64 62 20 65 76 61 6c 20  } {.    db eval 
4c20: 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 27 5b 73  "DELETE FROM '[s
4c30: 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27 27 7d  tring map {' ''}
4c40: 20 24 74 5d 27 22 0a 20 20 7d 0a 7d 0a 0a 23 20   $t]'".  }.}..# 
4c50: 52 75 6e 20 61 6e 20 53 51 4c 20 73 63 72 69 70  Run an SQL scrip
4c60: 74 2e 20 20 0a 23 20 52 65 74 75 72 6e 20 74 68  t.  .# Return th
4c70: 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69 63 72  e number of micr
4c80: 6f 73 65 63 6f 6e 64 73 20 70 65 72 20 73 74 61  oseconds per sta
4c90: 74 65 6d 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73  tement..#.proc s
4ca0: 70 65 65 64 5f 74 72 69 61 6c 20 7b 6e 61 6d 65  peed_trial {name
4cb0: 20 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73   numstmt units s
4cc0: 71 6c 7d 20 7b 0a 20 20 70 75 74 73 20 2d 6e 6f  ql} {.  puts -no
4cd0: 6e 65 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74 20  newline [format 
4ce0: 7b 25 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61 6d  {%-21.21s } $nam
4cf0: 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73 74  e...].  flush st
4d00: 64 6f 75 74 0a 20 20 73 65 74 20 73 70 65 65 64  dout.  set speed
4d10: 20 5b 74 69 6d 65 20 7b 73 71 6c 69 74 65 33 5f   [time {sqlite3_
4d20: 65 78 65 63 5f 6e 72 20 64 62 20 24 73 71 6c 7d  exec_nr db $sql}
4d30: 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64  ].  set tm [lind
4d40: 65 78 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69  ex $speed 0].  i
4d50: 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20  f {$tm == 0} {. 
4d60: 20 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72     set rate [for
4d70: 6d 61 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d  mat %20s "many"]
4d80: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
4d90: 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74  set rate [format
4da0: 20 25 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31   %20.5f [expr {1
4db0: 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d  000000.0*$numstm
4dc0: 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73  t/$tm}]].  }.  s
4dd0: 65 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20  et u2 $units/s. 
4de0: 20 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25   puts [format {%
4df0: 31 32 64 20 75 53 20 25 73 20 25 73 7d 20 24 74  12d uS %s %s} $t
4e00: 6d 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67  m $rate $u2].  g
4e10: 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65  lobal total_time
4e20: 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d  .  set total_tim
4e30: 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f  e [expr {$total_
4e40: 74 69 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70  time+$tm}].  lap
4e50: 70 65 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72 69  pend ::speed_tri
4e60: 61 6c 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20 24  al_times $name $
4e70: 74 6d 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f  tm.}.proc speed_
4e80: 74 72 69 61 6c 5f 74 63 6c 20 7b 6e 61 6d 65 20  trial_tcl {name 
4e90: 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73 63  numstmt units sc
4ea0: 72 69 70 74 7d 20 7b 0a 20 20 70 75 74 73 20 2d  ript} {.  puts -
4eb0: 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f 72 6d 61  nonewline [forma
4ec0: 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d 20 24 6e  t {%-21.21s } $n
4ed0: 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68 20  ame...].  flush 
4ee0: 73 74 64 6f 75 74 0a 20 20 73 65 74 20 73 70 65  stdout.  set spe
4ef0: 65 64 20 5b 74 69 6d 65 20 7b 65 76 61 6c 20 24  ed [time {eval $
4f00: 73 63 72 69 70 74 7d 5d 0a 20 20 73 65 74 20 74  script}].  set t
4f10: 6d 20 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64  m [lindex $speed
4f20: 20 30 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d 3d   0].  if {$tm ==
4f30: 20 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 61   0} {.    set ra
4f40: 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 73 20  te [format %20s 
4f50: 22 6d 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73 65  "many"].  } else
4f60: 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65 20   {.    set rate 
4f70: 5b 66 6f 72 6d 61 74 20 25 32 30 2e 35 66 20 5b  [format %20.5f [
4f80: 65 78 70 72 20 7b 31 30 30 30 30 30 30 2e 30 2a  expr {1000000.0*
4f90: 24 6e 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a  $numstmt/$tm}]].
4fa0: 20 20 7d 0a 20 20 73 65 74 20 75 32 20 24 75 6e    }.  set u2 $un
4fb0: 69 74 73 2f 73 0a 20 20 70 75 74 73 20 5b 66 6f  its/s.  puts [fo
4fc0: 72 6d 61 74 20 7b 25 31 32 64 20 75 53 20 25 73  rmat {%12d uS %s
4fd0: 20 25 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24   %s} $tm $rate $
4fe0: 75 32 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74  u2].  global tot
4ff0: 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f  al_time.  set to
5000: 74 61 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b  tal_time [expr {
5010: 24 74 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d  $total_time+$tm}
5020: 5d 0a 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73 70  ].  lappend ::sp
5030: 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20  eed_trial_times 
5040: 24 6e 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f 63  $name $tm.}.proc
5050: 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 69 6e 69   speed_trial_ini
5060: 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f  t {name} {.  glo
5070: 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20  bal total_time. 
5080: 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20   set total_time 
5090: 30 0a 20 20 73 65 74 20 3a 3a 73 70 65 65 64 5f  0.  set ::speed_
50a0: 74 72 69 61 6c 5f 74 69 6d 65 73 20 5b 6c 69 73  trial_times [lis
50b0: 74 5d 0a 20 20 73 71 6c 69 74 65 33 20 76 65 72  t].  sqlite3 ver
50c0: 73 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 73  sdb :memory:.  s
50d0: 65 74 20 76 65 72 73 20 5b 76 65 72 73 64 62 20  et vers [versdb 
50e0: 6f 6e 65 20 7b 53 45 4c 45 43 54 20 73 71 6c 69  one {SELECT sqli
50f0: 74 65 5f 73 6f 75 72 63 65 5f 69 64 28 29 7d 5d  te_source_id()}]
5100: 0a 20 20 76 65 72 73 64 62 20 63 6c 6f 73 65 0a  .  versdb close.
5110: 20 20 70 75 74 73 20 22 53 51 4c 69 74 65 20 24    puts "SQLite $
5120: 76 65 72 73 22 0a 7d 0a 70 72 6f 63 20 73 70 65  vers".}.proc spe
5130: 65 64 5f 74 72 69 61 6c 5f 73 75 6d 6d 61 72 79  ed_trial_summary
5140: 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62   {name} {.  glob
5150: 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20  al total_time.  
5160: 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 2d  puts [format {%-
5170: 32 31 2e 32 31 73 20 25 31 32 64 20 75 53 20 54  21.21s %12d uS T
5180: 4f 54 41 4c 7d 20 24 6e 61 6d 65 20 24 74 6f 74  OTAL} $name $tot
5190: 61 6c 5f 74 69 6d 65 5d 0a 0a 20 20 69 66 20 7b  al_time]..  if {
51a0: 20 30 20 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74   0 } {.    sqlit
51b0: 65 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f 72  e3 versdb :memor
51c0: 79 3a 0a 20 20 20 20 73 65 74 20 76 65 72 73 20  y:.    set vers 
51d0: 5b 6c 69 6e 64 65 78 20 5b 76 65 72 73 64 62 20  [lindex [versdb 
51e0: 6f 6e 65 20 7b 53 45 4c 45 43 54 20 73 71 6c 69  one {SELECT sqli
51f0: 74 65 5f 73 6f 75 72 63 65 5f 69 64 28 29 7d 5d  te_source_id()}]
5200: 20 30 5d 0a 20 20 20 20 76 65 72 73 64 62 20 63   0].    versdb c
5210: 6c 6f 73 65 0a 20 20 20 20 70 75 74 73 20 22 43  lose.    puts "C
5220: 52 45 41 54 45 20 54 41 42 4c 45 20 49 46 20 4e  REATE TABLE IF N
5230: 4f 54 20 45 58 49 53 54 53 20 74 69 6d 65 28 76  OT EXISTS time(v
5240: 65 72 73 69 6f 6e 2c 20 73 63 72 69 70 74 2c 20  ersion, script, 
5250: 74 65 73 74 2c 20 75 73 29 3b 22 0a 20 20 20 20  test, us);".    
5260: 66 6f 72 65 61 63 68 20 7b 74 65 73 74 20 75 73  foreach {test us
5270: 7d 20 24 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  } $::speed_trial
5280: 5f 74 69 6d 65 73 20 7b 0a 20 20 20 20 20 20 70  _times {.      p
5290: 75 74 73 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  uts "INSERT INTO
52a0: 20 74 69 6d 65 20 56 41 4c 55 45 53 28 27 24 76   time VALUES('$v
52b0: 65 72 73 27 2c 20 27 24 6e 61 6d 65 27 2c 20 27  ers', '$name', '
52c0: 24 74 65 73 74 27 2c 20 24 75 73 29 3b 22 0a 20  $test', $us);". 
52d0: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75     }.  }.}..# Ru
52e0: 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6c  n this routine l
52f0: 61 73 74 0a 23 0a 70 72 6f 63 20 66 69 6e 69 73  ast.#.proc finis
5300: 68 5f 74 65 73 74 20 7b 7d 20 7b 0a 20 20 63 61  h_test {} {.  ca
5310: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
5320: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
5330: 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20  e}.  catch {db3 
5340: 63 6c 6f 73 65 7d 0a 20 20 69 66 20 7b 30 3d 3d  close}.  if {0==
5350: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53  [info exists ::S
5360: 4c 41 56 45 5d 7d 20 7b 20 66 69 6e 61 6c 69 7a  LAVE]} { finaliz
5370: 65 5f 74 65 73 74 69 6e 67 20 7d 0a 7d 0a 70 72  e_testing }.}.pr
5380: 6f 63 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74  oc finalize_test
5390: 69 6e 67 20 7b 7d 20 7b 0a 20 20 67 6c 6f 62 61  ing {} {.  globa
53a0: 6c 20 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  l sqlite_open_fi
53b0: 6c 65 5f 63 6f 75 6e 74 0a 0a 20 20 73 65 74 20  le_count..  set 
53c0: 6f 6d 69 74 4c 69 73 74 20 5b 73 65 74 5f 74 65  omitList [set_te
53d0: 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f  st_counter omit_
53e0: 6c 69 73 74 5d 0a 0a 20 20 63 61 74 63 68 20 7b  list]..  catch {
53f0: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  db close}.  catc
5400: 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20  h {db2 close}.  
5410: 63 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65  catch {db3 close
5420: 7d 0a 0a 20 20 76 66 73 5f 75 6e 6c 69 6e 6b 5f  }..  vfs_unlink_
5430: 74 65 73 74 0a 20 20 73 71 6c 69 74 65 33 20 64  test.  sqlite3 d
5440: 62 20 7b 7d 0a 20 20 23 20 73 71 6c 69 74 65 33  b {}.  # sqlite3
5450: 5f 63 6c 65 61 72 5f 74 73 64 5f 6d 65 6d 64 65  _clear_tsd_memde
5460: 62 75 67 0a 20 20 64 62 20 63 6c 6f 73 65 0a 20  bug.  db close. 
5470: 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 5f 61   sqlite3_reset_a
5480: 75 74 6f 5f 65 78 74 65 6e 73 69 6f 6e 0a 0a 20  uto_extension.. 
5490: 20 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68 65   sqlite3_soft_he
54a0: 61 70 5f 6c 69 6d 69 74 20 30 0a 20 20 73 65 74  ap_limit 0.  set
54b0: 20 6e 54 65 73 74 20 5b 69 6e 63 72 5f 6e 74 65   nTest [incr_nte
54c0: 73 74 5d 0a 20 20 73 65 74 20 6e 45 72 72 20 5b  st].  set nErr [
54d0: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
54e0: 20 65 72 72 6f 72 73 5d 0a 0a 20 20 70 75 74 73   errors]..  puts
54f0: 20 22 24 6e 45 72 72 20 65 72 72 6f 72 73 20 6f   "$nErr errors o
5500: 75 74 20 6f 66 20 24 6e 54 65 73 74 20 74 65 73  ut of $nTest tes
5510: 74 73 22 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e  ts".  if {$nErr>
5520: 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 46  0} {.    puts "F
5530: 61 69 6c 75 72 65 73 20 6f 6e 20 74 68 65 73 65  ailures on these
5540: 20 74 65 73 74 73 3a 20 5b 73 65 74 5f 74 65 73   tests: [set_tes
5550: 74 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c  t_counter fail_l
5560: 69 73 74 5d 22 0a 20 20 7d 0a 20 20 72 75 6e 5f  ist]".  }.  run_
5570: 74 68 72 65 61 64 5f 74 65 73 74 73 20 31 0a 20  thread_tests 1. 
5580: 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 6f   if {[llength $o
5590: 6d 69 74 4c 69 73 74 5d 3e 30 7d 20 7b 0a 20 20  mitList]>0} {.  
55a0: 20 20 70 75 74 73 20 22 4f 6d 69 74 74 65 64 20    puts "Omitted 
55b0: 74 65 73 74 20 63 61 73 65 73 3a 22 0a 20 20 20  test cases:".   
55c0: 20 73 65 74 20 70 72 65 63 20 7b 7d 0a 20 20 20   set prec {}.   
55d0: 20 66 6f 72 65 61 63 68 20 7b 72 65 63 7d 20 5b   foreach {rec} [
55e0: 6c 73 6f 72 74 20 24 6f 6d 69 74 4c 69 73 74 5d  lsort $omitList]
55f0: 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 24 72 65   {.      if {$re
5600: 63 3d 3d 24 70 72 65 63 7d 20 63 6f 6e 74 69 6e  c==$prec} contin
5610: 75 65 0a 20 20 20 20 20 20 73 65 74 20 70 72 65  ue.      set pre
5620: 63 20 24 72 65 63 0a 20 20 20 20 20 20 70 75 74  c $rec.      put
5630: 73 20 5b 66 6f 72 6d 61 74 20 7b 20 20 25 2d 31  s [format {  %-1
5640: 32 73 20 25 73 7d 20 5b 6c 69 6e 64 65 78 20 24  2s %s} [lindex $
5650: 72 65 63 20 30 5d 20 5b 6c 69 6e 64 65 78 20 24  rec 0] [lindex $
5660: 72 65 63 20 31 5d 5d 0a 20 20 20 20 7d 0a 20 20  rec 1]].    }.  
5670: 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 30 20  }.  if {$nErr>0 
5680: 26 26 20 21 5b 77 6f 72 6b 69 6e 67 5f 36 34 62  && ![working_64b
5690: 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20 20 20 20 70  it_int]} {.    p
56a0: 75 74 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  uts "***********
56b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
56c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
56d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
56e0: 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20 70 75 74  *******".    put
56f0: 73 20 22 4e 2e 42 2e 3a 20 20 54 68 65 20 76 65  s "N.B.:  The ve
5700: 72 73 69 6f 6e 20 6f 66 20 54 43 4c 20 74 68 61  rsion of TCL tha
5710: 74 20 79 6f 75 20 75 73 65 64 20 74 6f 20 62 75  t you used to bu
5720: 69 6c 64 20 74 68 69 73 20 74 65 73 74 20 68 61  ild this test ha
5730: 72 6e 65 73 73 22 0a 20 20 20 20 70 75 74 73 20  rness".    puts 
5740: 22 69 73 20 64 65 66 65 63 74 69 76 65 20 69 6e  "is defective in
5750: 20 74 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f   that it does no
5760: 74 20 73 75 70 70 6f 72 74 20 36 34 2d 62 69 74  t support 64-bit
5770: 20 69 6e 74 65 67 65 72 73 2e 20 20 53 6f 6d 65   integers.  Some
5780: 20 6f 72 22 0a 20 20 20 20 70 75 74 73 20 22 61   or".    puts "a
5790: 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74 20 66  ll of the test f
57a0: 61 69 6c 75 72 65 73 20 61 62 6f 76 65 20 6d 69  ailures above mi
57b0: 67 68 74 20 62 65 20 61 20 72 65 73 75 6c 74 20  ght be a result 
57c0: 66 72 6f 6d 20 74 68 69 73 20 64 65 66 65 63 74  from this defect
57d0: 22 0a 20 20 20 20 70 75 74 73 20 22 69 6e 20 79  ".    puts "in y
57e0: 6f 75 72 20 54 43 4c 20 62 75 69 6c 64 2e 22 0a  our TCL build.".
57f0: 20 20 20 20 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a      puts "******
5800: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5810: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5820: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5830: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20  ************".  
5840: 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c 69  }.  if {$::cmdli
5850: 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29  nearg(binarylog)
5860: 7d 20 7b 0a 20 20 20 20 76 66 73 6c 6f 67 20 66  } {.    vfslog f
5870: 69 6e 61 6c 69 7a 65 20 62 69 6e 61 72 79 6c 6f  inalize binarylo
5880: 67 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c  g.  }.  if {$sql
5890: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
58a0: 75 6e 74 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  unt} {.    puts 
58b0: 22 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  "$sqlite_open_fi
58c0: 6c 65 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20 77  le_count files w
58d0: 65 72 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a 20  ere left open". 
58e0: 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d     incr nErr.  }
58f0: 0a 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20 5b  .  if {[lindex [
5900: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
5910: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c  QLITE_STATUS_MAL
5920: 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d 3e  LOC_COUNT 0] 1]>
5930: 30 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20  0 ||.           
5940: 20 20 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f     [sqlite3_memo
5950: 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20 20  ry_used]>0} {.  
5960: 20 20 70 75 74 73 20 22 55 6e 66 72 65 65 64 20    puts "Unfreed 
5970: 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c 69 74 65 33  memory: [sqlite3
5980: 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 20 62 79  _memory_used] by
5990: 74 65 73 20 69 6e 5c 0a 20 20 20 20 20 20 20 20  tes in\.        
59a0: 20 5b 6c 69 6e 64 65 78 20 5b 73 71 6c 69 74 65   [lindex [sqlite
59b0: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
59c0: 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f  STATUS_MALLOC_CO
59d0: 55 4e 54 20 30 5d 20 31 5d 20 61 6c 6c 6f 63 61  UNT 0] 1] alloca
59e0: 74 69 6f 6e 73 22 0a 20 20 20 20 69 6e 63 72 20  tions".    incr 
59f0: 6e 45 72 72 0a 20 20 20 20 69 66 63 61 70 61 62  nErr.    ifcapab
5a00: 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d  le memdebug||mem
5a10: 35 7c 7c 28 6d 65 6d 33 26 26 64 65 62 75 67 29  5||(mem3&&debug)
5a20: 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20 22 57   {.      puts "W
5a30: 72 69 74 69 6e 67 20 75 6e 66 72 65 65 64 20 6d  riting unfreed m
5a40: 65 6d 6f 72 79 20 6c 6f 67 20 74 6f 20 5c 22 2e  emory log to \".
5a50: 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 5c 22 22 0a  /memleak.txt\"".
5a60: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65        sqlite3_me
5a70: 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65  mdebug_dump ./me
5a80: 6d 6c 65 61 6b 2e 74 78 74 0a 20 20 20 20 7d 0a  mleak.txt.    }.
5a90: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 70    } else {.    p
5aa0: 75 74 73 20 22 41 6c 6c 20 6d 65 6d 6f 72 79 20  uts "All memory 
5ab0: 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 72 65 65  allocations free
5ac0: 64 20 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a 20 20  d - no leaks".  
5ad0: 20 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64    ifcapable memd
5ae0: 65 62 75 67 7c 7c 6d 65 6d 35 20 7b 0a 20 20 20  ebug||mem5 {.   
5af0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
5b00: 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 75 73  bug_dump ./memus
5b10: 61 67 65 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20  age.txt.    }.  
5b20: 7d 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74  }.  show_memstat
5b30: 73 0a 20 20 70 75 74 73 20 22 4d 61 78 69 6d 75  s.  puts "Maximu
5b40: 6d 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a 20  m memory usage: 
5b50: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f  [sqlite3_memory_
5b60: 68 69 67 68 77 61 74 65 72 20 31 5d 20 62 79 74  highwater 1] byt
5b70: 65 73 22 0a 20 20 70 75 74 73 20 22 43 75 72 72  es".  puts "Curr
5b80: 65 6e 74 20 6d 65 6d 6f 72 79 20 75 73 61 67 65  ent memory usage
5b90: 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72  : [sqlite3_memor
5ba0: 79 5f 68 69 67 68 77 61 74 65 72 5d 20 62 79 74  y_highwater] byt
5bb0: 65 73 22 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20  es".  if {[info 
5bc0: 63 6f 6d 6d 61 6e 64 73 20 73 71 6c 69 74 65 33  commands sqlite3
5bd0: 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63  _memdebug_malloc
5be0: 5f 63 6f 75 6e 74 5d 20 6e 65 20 22 22 7d 20 7b  _count] ne ""} {
5bf0: 0a 20 20 20 20 70 75 74 73 20 22 4e 75 6d 62 65  .    puts "Numbe
5c00: 72 20 6f 66 20 6d 61 6c 6c 6f 63 28 29 20 20 3a  r of malloc()  :
5c10: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62   [sqlite3_memdeb
5c20: 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d  ug_malloc_count]
5c30: 20 63 61 6c 6c 73 22 0a 20 20 7d 0a 20 20 69 66   calls".  }.  if
5c40: 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28   {$::cmdlinearg(
5c50: 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a  malloctrace)} {.
5c60: 20 20 20 20 70 75 74 73 20 22 57 72 69 74 69 6e      puts "Writin
5c70: 67 20 6d 61 6c 6c 6f 63 73 2e 73 71 6c 2e 2e 2e  g mallocs.sql...
5c80: 22 0a 20 20 20 20 6d 65 6d 64 65 62 75 67 5f 6c  ".    memdebug_l
5c90: 6f 67 5f 73 71 6c 0a 20 20 20 20 73 71 6c 69 74  og_sql.    sqlit
5ca0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20  e3_memdebug_log 
5cb0: 73 74 6f 70 0a 20 20 20 20 73 71 6c 69 74 65 33  stop.    sqlite3
5cc0: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 63 6c  _memdebug_log cl
5cd0: 65 61 72 0a 0a 20 20 20 20 69 66 20 7b 5b 73 71  ear..    if {[sq
5ce0: 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65  lite3_memory_use
5cf0: 64 5d 3e 30 7d 20 7b 0a 20 20 20 20 20 20 70 75  d]>0} {.      pu
5d00: 74 73 20 22 57 72 69 74 69 6e 67 20 6c 65 61 6b  ts "Writing leak
5d10: 73 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20 20 20 20  s.sql...".      
5d20: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
5d30: 5f 6c 6f 67 20 73 79 6e 63 0a 20 20 20 20 20 20  _log sync.      
5d40: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c  memdebug_log_sql
5d50: 20 6c 65 61 6b 73 2e 73 71 6c 0a 20 20 20 20 7d   leaks.sql.    }
5d60: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66  .  }.  foreach f
5d70: 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61   [glob -nocompla
5d80: 69 6e 20 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75  in test.db-*-jou
5d90: 72 6e 61 6c 5d 20 7b 0a 20 20 20 20 66 6f 72 63  rnal] {.    forc
5da0: 65 64 65 6c 65 74 65 20 24 66 0a 20 20 7d 0a 20  edelete $f.  }. 
5db0: 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62   foreach f [glob
5dc0: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73   -nocomplain tes
5dd0: 74 2e 64 62 2d 6d 6a 2a 5d 20 7b 0a 20 20 20 20  t.db-mj*] {.    
5de0: 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 0a 20  forcedelete $f. 
5df0: 20 7d 0a 20 20 65 78 69 74 20 5b 65 78 70 72 20   }.  exit [expr 
5e00: 7b 24 6e 45 72 72 3e 30 7d 5d 0a 7d 0a 0a 23 20  {$nErr>0}].}..# 
5e10: 44 69 73 70 6c 61 79 20 6d 65 6d 6f 72 79 20 73  Display memory s
5e20: 74 61 74 69 73 74 69 63 73 20 66 6f 72 20 61 6e  tatistics for an
5e30: 61 6c 79 73 69 73 20 61 6e 64 20 64 65 62 75 67  alysis and debug
5e40: 67 69 6e 67 20 70 75 72 70 6f 73 65 73 2e 0a 23  ging purposes..#
5e50: 0a 70 72 6f 63 20 73 68 6f 77 5f 6d 65 6d 73 74  .proc show_memst
5e60: 61 74 73 20 7b 7d 20 7b 0a 20 20 73 65 74 20 78  ats {} {.  set x
5e70: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
5e80: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d   SQLITE_STATUS_M
5e90: 45 4d 4f 52 59 5f 55 53 45 44 20 30 5d 0a 20 20  EMORY_USED 0].  
5ea0: 73 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73  set y [sqlite3_s
5eb0: 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41  tatus SQLITE_STA
5ec0: 54 55 53 5f 4d 41 4c 4c 4f 43 5f 53 49 5a 45 20  TUS_MALLOC_SIZE 
5ed0: 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f  0].  set val [fo
5ee0: 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20  rmat {now %10d  
5ef0: 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d 73 69  max %10d  max-si
5f00: 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20 20 20  ze %10d} \.     
5f10: 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78           [lindex
5f20: 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24   $x 1] [lindex $
5f30: 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20  x 2] [lindex $y 
5f40: 32 5d 5d 0a 20 20 70 75 74 73 20 22 4d 65 6d 6f  2]].  puts "Memo
5f50: 72 79 20 75 73 65 64 3a 20 20 20 20 20 20 20 20  ry used:        
5f60: 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20    $val".  set x 
5f70: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
5f80: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41  SQLITE_STATUS_MA
5f90: 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 0a 20 20  LLOC_COUNT 0].  
5fa0: 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20  set val [format 
5fb0: 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25  {now %10d  max %
5fc0: 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20  10d} [lindex $x 
5fd0: 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d  1] [lindex $x 2]
5fe0: 5d 0a 20 20 70 75 74 73 20 22 41 6c 6c 6f 63 61  ].  puts "Alloca
5ff0: 74 69 6f 6e 20 63 6f 75 6e 74 3a 20 20 20 20 20  tion count:     
6000: 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73  $val".  set x [s
6010: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
6020: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
6030: 43 41 43 48 45 5f 55 53 45 44 20 30 5d 0a 20 20  CACHE_USED 0].  
6040: 73 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73  set y [sqlite3_s
6050: 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41  tatus SQLITE_STA
6060: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49  TUS_PAGECACHE_SI
6070: 5a 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20  ZE 0].  set val 
6080: 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30  [format {now %10
6090: 64 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78  d  max %10d  max
60a0: 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20  -size %10d} \.  
60b0: 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e              [lin
60c0: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
60d0: 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20  x $x 2] [lindex 
60e0: 24 79 20 32 5d 5d 0a 20 20 70 75 74 73 20 22 50  $y 2]].  puts "P
60f0: 61 67 65 2d 63 61 63 68 65 20 75 73 65 64 3a 20  age-cache used: 
6100: 20 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74       $val".  set
6110: 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   x [sqlite3_stat
6120: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
6130: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
6140: 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 76 61 6c  LOW 0].  set val
6150: 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31   [format {now %1
6160: 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c  0d  max %10d} [l
6170: 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e  index $x 1] [lin
6180: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 70 75 74  dex $x 2]].  put
6190: 73 20 22 50 61 67 65 2d 63 61 63 68 65 20 6f 76  s "Page-cache ov
61a0: 65 72 66 6c 6f 77 3a 20 20 24 76 61 6c 22 0a 20  erflow:  $val". 
61b0: 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f   set x [sqlite3_
61c0: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
61d0: 41 54 55 53 5f 53 43 52 41 54 43 48 5f 55 53 45  ATUS_SCRATCH_USE
61e0: 44 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b  D 0].  set val [
61f0: 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64  format {now %10d
6200: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
6210: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
6220: 78 20 24 78 20 32 5d 5d 0a 20 20 70 75 74 73 20  x $x 2]].  puts 
6230: 22 53 63 72 61 74 63 68 20 6d 65 6d 6f 72 79 20  "Scratch memory 
6240: 75 73 65 64 3a 20 20 24 76 61 6c 22 0a 20 20 73  used:  $val".  s
6250: 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74  et x [sqlite3_st
6260: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
6270: 55 53 5f 53 43 52 41 54 43 48 5f 4f 56 45 52 46  US_SCRATCH_OVERF
6280: 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 79 20 5b  LOW 0].  set y [
6290: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
62a0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 53 43 52  QLITE_STATUS_SCR
62b0: 41 54 43 48 5f 53 49 5a 45 20 30 5d 0a 20 20 73  ATCH_SIZE 0].  s
62c0: 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b  et val [format {
62d0: 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31  now %10d  max %1
62e0: 30 64 20 20 6d 61 78 2d 73 69 7a 65 20 25 31 30  0d  max-size %10
62f0: 64 7d 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20  d} \.           
6300: 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 78 20 31      [lindex $x 1
6310: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 20  ] [lindex $x 2] 
6320: 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20  [lindex $y 2]]. 
6330: 20 70 75 74 73 20 22 53 63 72 61 74 63 68 20 6f   puts "Scratch o
6340: 76 65 72 66 6c 6f 77 3a 20 20 20 20 20 24 76 61  verflow:     $va
6350: 6c 22 0a 20 20 69 66 63 61 70 61 62 6c 65 20 79  l".  ifcapable y
6360: 79 74 72 61 63 6b 6d 61 78 73 74 61 63 6b 64 65  ytrackmaxstackde
6370: 70 74 68 20 7b 0a 20 20 20 20 73 65 74 20 78 20  pth {.    set x 
6380: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
6390: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
63a0: 52 53 45 52 5f 53 54 41 43 4b 20 30 5d 0a 20 20  RSER_STACK 0].  
63b0: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
63c0: 74 20 7b 20 20 20 20 20 20 20 20 20 20 20 20 20  t {             
63d0: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
63e0: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 20 20 70  dex $x 2]].    p
63f0: 75 74 73 20 22 50 61 72 73 65 72 20 73 74 61 63  uts "Parser stac
6400: 6b 20 64 65 70 74 68 3a 20 20 20 20 24 76 61 6c  k depth:    $val
6410: 22 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20 70 72 6f  ".  }.}..# A pro
6420: 63 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74  cedure to execut
6430: 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65  e SQL.#.proc exe
6440: 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62  csql {sql {db db
6450: 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53  }} {.  # puts "S
6460: 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c  QL = $sql".  upl
6470: 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65  evel [list $db e
6480: 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20 45  val $sql].}..# E
6490: 78 65 63 75 74 65 20 53 51 4c 20 61 6e 64 20 63  xecute SQL and c
64a0: 61 74 63 68 20 65 78 63 65 70 74 69 6f 6e 73 2e  atch exceptions.
64b0: 0a 23 0a 70 72 6f 63 20 63 61 74 63 68 73 71 6c  .#.proc catchsql
64c0: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
64d0: 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c 20 3d  .  # puts "SQL =
64e0: 20 24 73 71 6c 22 0a 20 20 73 65 74 20 72 20 5b   $sql".  set r [
64f0: 63 61 74 63 68 20 5b 6c 69 73 74 20 75 70 6c 65  catch [list uple
6500: 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76  vel [list $db ev
6510: 61 6c 20 24 73 71 6c 5d 5d 20 6d 73 67 5d 0a 20  al $sql]] msg]. 
6520: 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a   lappend r $msg.
6530: 20 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23    return $r.}..#
6540: 20 44 6f 20 61 6e 20 56 44 42 45 20 63 6f 64 65   Do an VDBE code
6550: 20 64 75 6d 70 20 6f 6e 20 74 68 65 20 53 51 4c   dump on the SQL
6560: 20 67 69 76 65 6e 0a 23 0a 70 72 6f 63 20 65 78   given.#.proc ex
6570: 70 6c 61 69 6e 20 7b 73 71 6c 20 7b 64 62 20 64  plain {sql {db d
6580: 62 7d 7d 20 7b 0a 20 20 70 75 74 73 20 22 22 0a  b}} {.  puts "".
6590: 20 20 70 75 74 73 20 22 61 64 64 72 20 20 6f 70    puts "addr  op
65a0: 63 6f 64 65 20 20 20 20 20 20 20 20 70 31 20 20  code        p1  
65b0: 20 20 20 20 70 32 20 20 20 20 20 20 70 33 20 20      p2      p3  
65c0: 20 20 20 20 70 34 20 20 20 20 20 20 20 20 20 20      p4          
65d0: 20 20 20 20 20 70 35 20 20 23 22 0a 20 20 70 75       p5  #".  pu
65e0: 74 73 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  ts "----  ------
65f0: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20  ------  ------  
6600: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20  ------  ------  
6610: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20  --------------- 
6620: 20 2d 2d 20 20 2d 22 0a 20 20 24 64 62 20 65 76   --  -".  $db ev
6630: 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73 71 6c  al "explain $sql
6640: 22 20 7b 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  " {} {.    puts 
6650: 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25  [format {%-4d  %
6660: 2d 31 32 2e 31 32 73 20 20 25 2d 36 64 20 20 25  -12.12s  %-6d  %
6670: 2d 36 64 20 20 25 2d 36 64 20 20 25 20 2d 31 37  -6d  %-6d  % -17
6680: 73 20 25 73 20 20 25 73 7d 20 5c 0a 20 20 20 20  s %s  %s} \.    
6690: 20 20 24 61 64 64 72 20 24 6f 70 63 6f 64 65 20    $addr $opcode 
66a0: 24 70 31 20 24 70 32 20 24 70 33 20 24 70 34 20  $p1 $p2 $p3 $p4 
66b0: 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20  $p5 $comment.   
66c0: 20 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 53 68 6f 77   ].  }.}..# Show
66d0: 20 74 68 65 20 56 44 42 45 20 70 72 6f 67 72 61   the VDBE progra
66e0: 6d 20 66 6f 72 20 61 6e 20 53 51 4c 20 73 74 61  m for an SQL sta
66f0: 74 65 6d 65 6e 74 20 62 75 74 20 6f 6d 69 74 20  tement but omit 
6700: 74 68 65 20 54 72 61 63 65 0a 23 20 6f 70 63 6f  the Trace.# opco
6710: 64 65 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e  de at the beginn
6720: 69 6e 67 2e 20 20 54 68 69 73 20 70 72 6f 63 65  ing.  This proce
6730: 64 75 72 65 20 63 61 6e 20 62 65 20 75 73 65 64  dure can be used
6740: 20 74 6f 20 70 72 6f 76 65 0a 23 20 74 68 61 74   to prove.# that
6750: 20 64 69 66 66 65 72 65 6e 74 20 53 51 4c 20 73   different SQL s
6760: 74 61 74 65 6d 65 6e 74 73 20 67 65 6e 65 72 61  tatements genera
6770: 74 65 20 65 78 61 63 74 6c 79 20 74 68 65 20 73  te exactly the s
6780: 61 6d 65 20 56 44 42 45 20 63 6f 64 65 2e 0a 23  ame VDBE code..#
6790: 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f  .proc explain_no
67a0: 5f 74 72 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20  _trace {sql} {. 
67b0: 20 73 65 74 20 74 72 20 5b 64 62 20 65 76 61 6c   set tr [db eval
67c0: 20 22 45 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d   "EXPLAIN $sql"]
67d0: 0a 20 20 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67  .  return [lrang
67e0: 65 20 24 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a  e $tr 7 end].}..
67f0: 23 20 41 6e 6f 74 68 65 72 20 70 72 6f 63 65 64  # Another proced
6800: 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53  ure to execute S
6810: 51 4c 2e 20 20 54 68 69 73 20 6f 6e 65 20 69 6e  QL.  This one in
6820: 63 6c 75 64 65 73 20 74 68 65 20 66 69 65 6c 64  cludes the field
6830: 0a 23 20 6e 61 6d 65 73 20 69 6e 20 74 68 65 20  .# names in the 
6840: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23  returned list..#
6850: 0a 70 72 6f 63 20 65 78 65 63 73 71 6c 32 20 7b  .proc execsql2 {
6860: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 72 65 73  sql} {.  set res
6870: 75 6c 74 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c  ult {}.  db eval
6880: 20 24 73 71 6c 20 64 61 74 61 20 7b 0a 20 20 20   $sql data {.   
6890: 20 66 6f 72 65 61 63 68 20 66 20 24 64 61 74 61   foreach f $data
68a0: 28 2a 29 20 7b 0a 20 20 20 20 20 20 6c 61 70 70  (*) {.      lapp
68b0: 65 6e 64 20 72 65 73 75 6c 74 20 24 66 20 24 64  end result $f $d
68c0: 61 74 61 28 24 66 29 0a 20 20 20 20 7d 0a 20 20  ata($f).    }.  
68d0: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73 75  }.  return $resu
68e0: 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65 20  lt.}..# Use the 
68f0: 6e 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49  non-callback API
6900: 20 74 6f 20 65 78 65 63 75 74 65 20 6d 75 6c 74   to execute mult
6910: 69 70 6c 65 20 53 51 4c 20 73 74 61 74 65 6d 65  iple SQL stateme
6920: 6e 74 73 0a 23 0a 70 72 6f 63 20 73 74 65 70 73  nts.#.proc steps
6930: 71 6c 20 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b  ql {dbptr sql} {
6940: 0a 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69  .  set sql [stri
6950: 6e 67 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20  ng trim $sql].  
6960: 73 65 74 20 72 20 30 0a 20 20 77 68 69 6c 65 20  set r 0.  while 
6970: 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  {[string length 
6980: 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69  $sql]>0} {.    i
6990: 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74  f {[catch {sqlit
69a0: 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 70 74  e3_prepare $dbpt
69b0: 72 20 24 73 71 6c 20 2d 31 20 73 71 6c 74 61 69  r $sql -1 sqltai
69c0: 6c 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20  l} vm]} {.      
69d0: 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24  return [list 1 $
69e0: 76 6d 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65  vm].    }.    se
69f0: 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72  t sql [string tr
6a00: 69 6d 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20  im $sqltail].#  
6a10: 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65    while {[sqlite
6a20: 5f 73 74 65 70 20 24 76 6d 20 4e 20 56 41 4c 20  _step $vm N VAL 
6a30: 43 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f  COL]=="SQLITE_RO
6a40: 57 22 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f 72  W"} {.#      for
6a50: 65 61 63 68 20 76 20 24 56 41 4c 20 7b 6c 61 70  each v $VAL {lap
6a60: 70 65 6e 64 20 72 20 24 76 7d 0a 23 20 20 20 20  pend r $v}.#    
6a70: 7d 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71  }.    while {[sq
6a80: 6c 69 74 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d  lite3_step $vm]=
6a90: 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b  ="SQLITE_ROW"} {
6aa0: 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20  .      for {set 
6ab0: 69 20 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65  i 0} {$i<[sqlite
6ac0: 33 5f 64 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d  3_data_count $vm
6ad0: 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  ]} {incr i} {.  
6ae0: 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72 20        lappend r 
6af0: 5b 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  [sqlite3_column_
6b00: 74 65 78 74 20 24 76 6d 20 24 69 5d 0a 20 20 20  text $vm $i].   
6b10: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
6b20: 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74  f {[catch {sqlit
6b30: 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d  e3_finalize $vm}
6b40: 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20   errmsg]} {.    
6b50: 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31    return [list 1
6b60: 20 24 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a   $errmsg].    }.
6b70: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a    }.  return $r.
6b80: 7d 0a 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67  }..# Do an integ
6b90: 72 69 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68  rity check of th
6ba0: 65 20 65 6e 74 69 72 65 20 64 61 74 61 62 61 73  e entire databas
6bb0: 65 0a 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69  e.#.proc integri
6bc0: 74 79 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20 7b  ty_check {name {
6bd0: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61  db db}} {.  ifca
6be0: 70 61 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63  pable integrityc
6bf0: 6b 20 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20  k {.    do_test 
6c00: 24 6e 61 6d 65 20 5b 6c 69 73 74 20 65 78 65 63  $name [list exec
6c10: 73 71 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65  sql {PRAGMA inte
6c20: 67 72 69 74 79 5f 63 68 65 63 6b 7d 20 24 64 62  grity_check} $db
6c30: 5d 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 0a 23  ] {ok}.  }.}...#
6c40: 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20   Return true if 
6c50: 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e  the SQL statemen
6c60: 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  t passed as the 
6c70: 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20  second argument 
6c80: 75 73 65 73 20 61 0a 23 20 73 74 61 74 65 6d 65  uses a.# stateme
6c90: 6e 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a  nt transaction..
6ca0: 23 0a 70 72 6f 63 20 73 71 6c 5f 75 73 65 73 5f  #.proc sql_uses_
6cb0: 73 74 6d 74 20 7b 64 62 20 73 71 6c 7d 20 7b 0a  stmt {db sql} {.
6cc0: 20 20 73 65 74 20 73 74 6d 74 20 5b 73 71 6c 69    set stmt [sqli
6cd0: 74 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 20  te3_prepare $db 
6ce0: 24 73 71 6c 20 2d 31 20 64 75 6d 6d 79 5d 0a 20  $sql -1 dummy]. 
6cf0: 20 73 65 74 20 75 73 65 73 20 5b 75 73 65 73 5f   set uses [uses_
6d00: 73 74 6d 74 5f 6a 6f 75 72 6e 61 6c 20 24 73 74  stmt_journal $st
6d10: 6d 74 5d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  mt].  sqlite3_fi
6d20: 6e 61 6c 69 7a 65 20 24 73 74 6d 74 0a 20 20 72  nalize $stmt.  r
6d30: 65 74 75 72 6e 20 24 75 73 65 73 0a 7d 0a 0a 70  eturn $uses.}..p
6d40: 72 6f 63 20 66 69 78 5f 69 66 63 61 70 61 62 6c  roc fix_ifcapabl
6d50: 65 5f 65 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a  e_expr {expr} {.
6d60: 20 20 73 65 74 20 72 65 74 20 22 22 0a 20 20 73    set ret "".  s
6d70: 65 74 20 73 74 61 74 65 20 30 0a 20 20 66 6f 72  et state 0.  for
6d80: 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c   {set i 0} {$i <
6d90: 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20   [string length 
6da0: 24 65 78 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d  $expr]} {incr i}
6db0: 20 7b 0a 20 20 20 20 73 65 74 20 63 68 61 72 20   {.    set char 
6dc0: 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65  [string range $e
6dd0: 78 70 72 20 24 69 20 24 69 5d 0a 20 20 20 20 73  xpr $i $i].    s
6de0: 65 74 20 6e 65 77 73 74 61 74 65 20 5b 65 78 70  et newstate [exp
6df0: 72 20 7b 5b 73 74 72 69 6e 67 20 69 73 20 61 6c  r {[string is al
6e00: 6e 75 6d 20 24 63 68 61 72 5d 20 7c 7c 20 24 63  num $char] || $c
6e10: 68 61 72 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20  har eq "_"}].   
6e20: 20 69 66 20 7b 24 6e 65 77 73 74 61 74 65 20 26   if {$newstate &
6e30: 26 20 21 24 73 74 61 74 65 7d 20 7b 0a 20 20 20  & !$state} {.   
6e40: 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 7b 24     append ret {$
6e50: 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73  ::sqlite_options
6e60: 28 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20  (}.    }.    if 
6e70: 7b 21 24 6e 65 77 73 74 61 74 65 20 26 26 20 24  {!$newstate && $
6e80: 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20 20 61  state} {.      a
6e90: 70 70 65 6e 64 20 72 65 74 20 29 0a 20 20 20 20  ppend ret ).    
6ea0: 7d 0a 20 20 20 20 61 70 70 65 6e 64 20 72 65 74  }.    append ret
6eb0: 20 24 63 68 61 72 0a 20 20 20 20 73 65 74 20 73   $char.    set s
6ec0: 74 61 74 65 20 24 6e 65 77 73 74 61 74 65 0a 20  tate $newstate. 
6ed0: 20 7d 0a 20 20 69 66 20 7b 24 73 74 61 74 65 7d   }.  if {$state}
6ee0: 20 7b 61 70 70 65 6e 64 20 72 65 74 20 29 7d 0a   {append ret )}.
6ef0: 20 20 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a    return $ret.}.
6f00: 0a 23 20 45 76 61 6c 75 61 74 65 20 61 20 62 6f  .# Evaluate a bo
6f10: 6f 6c 65 61 6e 20 65 78 70 72 65 73 73 69 6f 6e  olean expression
6f20: 20 6f 66 20 63 61 70 61 62 69 6c 69 74 69 65 73   of capabilities
6f30: 2e 20 20 49 66 20 74 72 75 65 2c 20 65 78 65 63  .  If true, exec
6f40: 75 74 65 20 74 68 65 0a 23 20 63 6f 64 65 2e 20  ute the.# code. 
6f50: 20 4f 6d 69 74 20 74 68 65 20 63 6f 64 65 20 69   Omit the code i
6f60: 66 20 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20  f false..#.proc 
6f70: 69 66 63 61 70 61 62 6c 65 20 7b 65 78 70 72 20  ifcapable {expr 
6f80: 63 6f 64 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b  code {else ""} {
6f90: 65 6c 73 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a  elsecode ""}} {.
6fa0: 20 20 23 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b    #regsub -all {
6fb0: 5b 61 2d 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70  [a-z_0-9]+} $exp
6fc0: 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74  r {$::sqlite_opt
6fd0: 69 6f 6e 73 28 26 29 7d 20 65 32 0a 20 20 73 65  ions(&)} e2.  se
6fe0: 74 20 65 32 20 5b 66 69 78 5f 69 66 63 61 70 61  t e2 [fix_ifcapa
6ff0: 62 6c 65 5f 65 78 70 72 20 24 65 78 70 72 5d 0a  ble_expr $expr].
7000: 20 20 69 66 20 28 24 65 32 29 20 7b 0a 20 20 20    if ($e2) {.   
7010: 20 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75   set c [catch {u
7020: 70 6c 65 76 65 6c 20 31 20 24 63 6f 64 65 7d 20  plevel 1 $code} 
7030: 72 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  r].  } else {.  
7040: 20 20 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b    set c [catch {
7050: 75 70 6c 65 76 65 6c 20 31 20 24 65 6c 73 65 63  uplevel 1 $elsec
7060: 6f 64 65 7d 20 72 5d 0a 20 20 7d 0a 20 20 72 65  ode} r].  }.  re
7070: 74 75 72 6e 20 2d 63 6f 64 65 20 24 63 20 24 72  turn -code $c $r
7080: 0a 7d 0a 0a 23 20 54 68 69 73 20 70 72 6f 63 20  .}..# This proc 
7090: 65 78 65 63 73 20 61 20 73 65 70 65 72 61 74 65  execs a seperate
70a0: 20 70 72 6f 63 65 73 73 20 74 68 61 74 20 63 72   process that cr
70b0: 61 73 68 65 73 20 6d 69 64 77 61 79 20 74 68 72  ashes midway thr
70c0: 6f 75 67 68 20 65 78 65 63 75 74 69 6e 67 0a 23  ough executing.#
70d0: 20 74 68 65 20 53 51 4c 20 73 63 72 69 70 74 20   the SQL script 
70e0: 24 73 71 6c 20 6f 6e 20 64 61 74 61 62 61 73 65  $sql on database
70f0: 20 74 65 73 74 2e 64 62 2e 0a 23 0a 23 20 54 68   test.db..#.# Th
7100: 65 20 63 72 61 73 68 20 6f 63 63 75 72 73 20 64  e crash occurs d
7110: 75 72 69 6e 67 20 61 20 73 79 6e 63 28 29 20 6f  uring a sync() o
7120: 66 20 66 69 6c 65 20 24 63 72 61 73 68 66 69 6c  f file $crashfil
7130: 65 2e 20 57 68 65 6e 20 74 68 65 20 63 72 61 73  e. When the cras
7140: 68 0a 23 20 6f 63 63 75 72 73 20 61 20 72 61 6e  h.# occurs a ran
7150: 64 6f 6d 20 73 75 62 73 65 74 20 6f 66 20 61 6c  dom subset of al
7160: 6c 20 75 6e 73 79 6e 63 65 64 20 77 72 69 74 65  l unsynced write
7170: 73 20 6d 61 64 65 20 62 79 20 74 68 65 20 70 72  s made by the pr
7180: 6f 63 65 73 73 20 61 72 65 0a 23 20 77 72 69 74  ocess are.# writ
7190: 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 66 69 6c  ten into the fil
71a0: 65 73 20 6f 6e 20 64 69 73 6b 2e 20 41 72 67 75  es on disk. Argu
71b0: 6d 65 6e 74 20 24 63 72 61 73 68 64 65 6c 61 79  ment $crashdelay
71c0: 20 69 6e 64 69 63 61 74 65 73 20 74 68 65 0a 23   indicates the.#
71d0: 20 6e 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 20   number of file 
71e0: 73 79 6e 63 73 20 74 6f 20 77 61 69 74 20 62 65  syncs to wait be
71f0: 66 6f 72 65 20 63 72 61 73 68 69 6e 67 2e 0a 23  fore crashing..#
7200: 0a 23 20 54 68 65 20 72 65 74 75 72 6e 20 76 61  .# The return va
7210: 6c 75 65 20 69 73 20 61 20 6c 69 73 74 20 6f 66  lue is a list of
7220: 20 74 77 6f 20 65 6c 65 6d 65 6e 74 73 2e 20 54   two elements. T
7230: 68 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74  he first element
7240: 20 69 73 20 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c   is a.# boolean,
7250: 20 69 6e 64 69 63 61 74 69 6e 67 20 77 68 65 74   indicating whet
7260: 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 70  her or not the p
7270: 72 6f 63 65 73 73 20 61 63 74 75 61 6c 6c 79 20  rocess actually 
7280: 63 72 61 73 68 65 64 20 6f 72 0a 23 20 72 65 70  crashed or.# rep
7290: 6f 72 74 65 64 20 73 6f 6d 65 20 6f 74 68 65 72  orted some other
72a0: 20 65 72 72 6f 72 2e 20 54 68 65 20 73 65 63 6f   error. The seco
72b0: 6e 64 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68  nd element in th
72c0: 65 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74 20  e returned list 
72d0: 69 73 20 74 68 65 0a 23 20 65 72 72 6f 72 20 6d  is the.# error m
72e0: 65 73 73 61 67 65 2e 20 54 68 69 73 20 69 73 20  essage. This is 
72f0: 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65  "child process e
7300: 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79  xited abnormally
7310: 22 20 69 66 20 74 68 65 20 63 72 61 73 68 0a 23  " if the crash.#
7320: 20 6f 63 63 75 72 65 64 2e 0a 23 0a 23 20 20 20   occured..#.#   
7330: 63 72 61 73 68 73 71 6c 20 2d 64 65 6c 61 79 20  crashsql -delay 
7340: 43 52 41 53 48 44 45 4c 41 59 20 2d 66 69 6c 65  CRASHDELAY -file
7350: 20 43 52 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f   CRASHFILE ?-blo
7360: 63 6b 73 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45  cksize BLOCKSIZE
7370: 3f 20 24 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72  ? $sql.#.proc cr
7380: 61 73 68 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a  ashsql {args} {.
7390: 0a 20 20 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  .  set blocksize
73a0: 20 22 22 0a 20 20 73 65 74 20 63 72 61 73 68 64   "".  set crashd
73b0: 65 6c 61 79 20 31 0a 20 20 73 65 74 20 70 72 6e  elay 1.  set prn
73c0: 67 73 65 65 64 20 30 0a 20 20 73 65 74 20 74 63  gseed 0.  set tc
73d0: 6c 62 6f 64 79 20 7b 7d 0a 20 20 73 65 74 20 63  lbody {}.  set c
73e0: 72 61 73 68 66 69 6c 65 20 22 22 0a 20 20 73 65  rashfile "".  se
73f0: 74 20 64 63 20 22 22 0a 20 20 73 65 74 20 73 71  t dc "".  set sq
7400: 6c 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20  l [lindex $args 
7410: 65 6e 64 5d 0a 20 20 0a 20 20 66 6f 72 20 7b 73  end].  .  for {s
7420: 65 74 20 69 69 20 30 7d 20 7b 24 69 69 20 3c 20  et ii 0} {$ii < 
7430: 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 2d  [llength $args]-
7440: 31 7d 20 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b  1} {incr ii 2} {
7450: 0a 20 20 20 20 73 65 74 20 7a 20 5b 6c 69 6e 64  .    set z [lind
7460: 65 78 20 24 61 72 67 73 20 24 69 69 5d 0a 20 20  ex $args $ii].  
7470: 20 20 73 65 74 20 6e 20 5b 73 74 72 69 6e 67 20    set n [string 
7480: 6c 65 6e 67 74 68 20 24 7a 5d 0a 20 20 20 20 73  length $z].    s
7490: 65 74 20 7a 32 20 5b 6c 69 6e 64 65 78 20 24 61  et z2 [lindex $a
74a0: 72 67 73 20 5b 65 78 70 72 20 24 69 69 2b 31 5d  rgs [expr $ii+1]
74b0: 5d 0a 0a 20 20 20 20 69 66 20 20 20 20 20 7b 24  ]..    if     {$
74c0: 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66  n>1 && [string f
74d0: 69 72 73 74 20 24 7a 20 2d 64 65 6c 61 79 5d 3d  irst $z -delay]=
74e0: 3d 30 7d 20 20 20 20 20 7b 73 65 74 20 63 72 61  =0}     {set cra
74f0: 73 68 64 65 6c 61 79 20 24 7a 32 7d 20 5c 0a 20  shdelay $z2} \. 
7500: 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20     elseif {$n>1 
7510: 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74  && [string first
7520: 20 24 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20   $z -seed]==0}  
7530: 20 20 20 20 7b 73 65 74 20 70 72 6e 67 73 65 65      {set prngsee
7540: 64 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73  d $z2} \.    els
7550: 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74  eif {$n>1 && [st
7560: 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66  ring first $z -f
7570: 69 6c 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73  ile]==0}      {s
7580: 65 74 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32  et crashfile $z2
7590: 7d 20 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20  }  \.    elseif 
75a0: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
75b0: 20 66 69 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f   first $z -tclbo
75c0: 64 79 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74  dy]==0}   {set t
75d0: 63 6c 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20  clbody $z2}  \. 
75e0: 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20     elseif {$n>1 
75f0: 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74  && [string first
7600: 20 24 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d   $z -blocksize]=
7610: 3d 30 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69  =0} {set blocksi
7620: 7a 65 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a  ze "-s $z2" } \.
7630: 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31      elseif {$n>1
7640: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
7650: 74 20 24 7a 20 2d 63 68 61 72 61 63 74 65 72 69  t $z -characteri
7660: 73 74 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20  stics]==0} {set 
7670: 64 63 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 20  dc "-c {$z2}" } 
7680: 5c 0a 20 20 20 20 65 6c 73 65 20 20 20 7b 20 65  \.    else   { e
7690: 72 72 6f 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a  rror "Unrecogniz
76a0: 65 64 20 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d  ed option: $z" }
76b0: 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61  .  }..  if {$cra
76c0: 73 68 66 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a  shfile eq ""} {.
76d0: 20 20 20 20 65 72 72 6f 72 20 22 43 6f 6d 70 75      error "Compu
76e0: 6c 73 6f 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69  lsory option -fi
76f0: 6c 65 20 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a  le missing".  }.
7700: 0a 20 20 23 20 24 63 72 61 73 68 66 69 6c 65 20  .  # $crashfile 
7710: 67 65 74 73 20 63 6f 6d 70 61 72 65 64 20 74 6f  gets compared to
7720: 20 74 68 65 20 6e 61 74 69 76 65 20 66 69 6c 65   the native file
7730: 6e 61 6d 65 20 69 6e 20 0a 20 20 23 20 63 66 53  name in .  # cfS
7740: 79 6e 63 28 29 2c 20 77 68 69 63 68 20 63 61 6e  ync(), which can
7750: 20 62 65 20 64 69 66 66 65 72 65 6e 74 20 74 68   be different th
7760: 65 6e 20 77 68 61 74 20 54 43 4c 20 75 73 65 73  en what TCL uses
7770: 20 62 79 0a 20 20 23 20 64 65 66 61 75 6c 74 2c   by.  # default,
7780: 20 73 6f 20 68 65 72 65 20 77 65 20 66 6f 72 63   so here we forc
7790: 65 20 69 74 20 74 6f 20 74 68 65 20 22 6e 61 74  e it to the "nat
77a0: 69 76 65 6e 61 6d 65 22 20 66 6f 72 6d 61 74 2e  ivename" format.
77b0: 0a 20 20 73 65 74 20 63 66 69 6c 65 20 5b 73 74  .  set cfile [st
77c0: 72 69 6e 67 20 6d 61 70 20 7b 5c 5c 20 5c 5c 5c  ring map {\\ \\\
77d0: 5c 7d 20 5b 66 69 6c 65 20 6e 61 74 69 76 65 6e  \} [file nativen
77e0: 61 6d 65 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b  ame [file join [
77f0: 67 65 74 5f 70 77 64 5d 20 24 63 72 61 73 68 66  get_pwd] $crashf
7800: 69 6c 65 5d 5d 5d 0a 0a 20 20 73 65 74 20 66 20  ile]]]..  set f 
7810: 5b 6f 70 65 6e 20 63 72 61 73 68 2e 74 63 6c 20  [open crash.tcl 
7820: 77 5d 0a 20 20 70 75 74 73 20 24 66 20 22 73 71  w].  puts $f "sq
7830: 6c 69 74 65 33 5f 63 72 61 73 68 5f 65 6e 61 62  lite3_crash_enab
7840: 6c 65 20 31 22 0a 20 20 70 75 74 73 20 24 66 20  le 1".  puts $f 
7850: 22 73 71 6c 69 74 65 33 5f 63 72 61 73 68 70 61  "sqlite3_crashpa
7860: 72 61 6d 73 20 24 62 6c 6f 63 6b 73 69 7a 65 20  rams $blocksize 
7870: 24 64 63 20 24 63 72 61 73 68 64 65 6c 61 79 20  $dc $crashdelay 
7880: 24 63 66 69 6c 65 22 0a 20 20 70 75 74 73 20 24  $cfile".  puts $
7890: 66 20 22 73 71 6c 69 74 65 33 5f 74 65 73 74 5f  f "sqlite3_test_
78a0: 63 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f  control_pending_
78b0: 62 79 74 65 20 24 3a 3a 73 71 6c 69 74 65 5f 70  byte $::sqlite_p
78c0: 65 6e 64 69 6e 67 5f 62 79 74 65 22 0a 20 20 70  ending_byte".  p
78d0: 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33 20  uts $f "sqlite3 
78e0: 64 62 20 74 65 73 74 2e 64 62 20 2d 76 66 73 20  db test.db -vfs 
78f0: 63 72 61 73 68 22 0a 0a 20 20 23 20 54 68 69 73  crash"..  # This
7900: 20 62 6c 6f 63 6b 20 73 65 74 73 20 74 68 65 20   block sets the 
7910: 63 61 63 68 65 20 73 69 7a 65 20 6f 66 20 74 68  cache size of th
7920: 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
7930: 74 6f 20 31 30 0a 20 20 23 20 70 61 67 65 73 2e  to 10.  # pages.
7940: 20 54 68 69 73 20 69 73 20 64 6f 6e 65 20 69 6e   This is done in
7950: 20 63 61 73 65 20 74 68 65 20 62 75 69 6c 64 20   case the build 
7960: 69 73 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f  is configured to
7970: 20 6f 6d 69 74 0a 20 20 23 20 22 50 52 41 47 4d   omit.  # "PRAGM
7980: 41 20 63 61 63 68 65 5f 73 69 7a 65 22 2e 0a 20  A cache_size".. 
7990: 20 70 75 74 73 20 24 66 20 7b 64 62 20 65 76 61   puts $f {db eva
79a0: 6c 20 7b 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  l {SELECT * FROM
79b0: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 7d   sqlite_master;}
79c0: 7d 0a 20 20 70 75 74 73 20 24 66 20 7b 73 65 74  }.  puts $f {set
79d0: 20 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f   bt [btree_from_
79e0: 64 62 20 64 62 5d 7d 0a 20 20 70 75 74 73 20 24  db db]}.  puts $
79f0: 66 20 7b 62 74 72 65 65 5f 73 65 74 5f 63 61 63  f {btree_set_cac
7a00: 68 65 5f 73 69 7a 65 20 24 62 74 20 31 30 7d 0a  he_size $bt 10}.
7a10: 20 20 69 66 20 7b 24 70 72 6e 67 73 65 65 64 7d    if {$prngseed}
7a20: 20 7b 0a 20 20 20 20 73 65 74 20 73 65 65 64 20   {.    set seed 
7a30: 5b 65 78 70 72 20 7b 24 70 72 6e 67 73 65 65 64  [expr {$prngseed
7a40: 25 31 30 30 30 37 2b 31 7d 5d 0a 20 20 20 20 23  %10007+1}].    #
7a50: 20 70 75 74 73 20 73 65 65 64 3d 24 73 65 65 64   puts seed=$seed
7a60: 0a 20 20 20 20 70 75 74 73 20 24 66 20 22 64 62  .    puts $f "db
7a70: 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 72 61   eval {SELECT ra
7a80: 6e 64 6f 6d 62 6c 6f 62 28 24 73 65 65 64 29 7d  ndomblob($seed)}
7a90: 22 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 5b 73 74  ".  }..  if {[st
7aa0: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 74 63 6c  ring length $tcl
7ab0: 62 6f 64 79 5d 3e 30 7d 20 7b 0a 20 20 20 20 70  body]>0} {.    p
7ac0: 75 74 73 20 24 66 20 24 74 63 6c 62 6f 64 79 0a  uts $f $tclbody.
7ad0: 20 20 7d 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e    }.  if {[strin
7ae0: 67 20 6c 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30  g length $sql]>0
7af0: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20  } {.    puts $f 
7b00: 22 64 62 20 65 76 61 6c 20 7b 22 0a 20 20 20 20  "db eval {".    
7b10: 70 75 74 73 20 24 66 20 20 20 22 24 73 71 6c 22  puts $f   "$sql"
7b20: 0a 20 20 20 20 70 75 74 73 20 24 66 20 22 7d 22  .    puts $f "}"
7b30: 0a 20 20 7d 0a 20 20 63 6c 6f 73 65 20 24 66 0a  .  }.  close $f.
7b40: 20 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 7b    set r [catch {
7b50: 0a 20 20 20 20 65 78 65 63 20 5b 69 6e 66 6f 20  .    exec [info 
7b60: 6e 61 6d 65 6f 66 65 78 65 63 5d 20 63 72 61 73  nameofexec] cras
7b70: 68 2e 74 63 6c 20 3e 40 73 74 64 6f 75 74 0a 20  h.tcl >@stdout. 
7b80: 20 7d 20 6d 73 67 5d 0a 20 20 0a 20 20 23 20 57   } msg].  .  # W
7b90: 69 6e 64 6f 77 73 2f 41 63 74 69 76 65 53 74 61  indows/ActiveSta
7ba0: 74 65 20 54 43 4c 20 72 65 74 75 72 6e 73 20 61  te TCL returns a
7bb0: 20 73 6c 69 67 68 74 6c 79 20 64 69 66 66 65 72   slightly differ
7bc0: 65 6e 74 0a 20 20 23 20 65 72 72 6f 72 20 6d 65  ent.  # error me
7bd0: 73 73 61 67 65 2e 20 20 57 65 20 6d 61 70 20 74  ssage.  We map t
7be0: 68 61 74 20 74 6f 20 74 68 65 20 65 78 70 65 63  hat to the expec
7bf0: 74 65 64 20 6d 65 73 73 61 67 65 0a 20 20 23 20  ted message.  # 
7c00: 73 6f 20 74 68 61 74 20 77 65 20 64 6f 6e 27 74  so that we don't
7c10: 20 68 61 76 65 20 74 6f 20 63 68 61 6e 67 65 20   have to change 
7c20: 61 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74 0a  all of the test.
7c30: 20 20 23 20 63 61 73 65 73 2e 0a 20 20 69 66 20    # cases..  if 
7c40: 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d  {$::tcl_platform
7c50: 28 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 77 69 6e  (platform)=="win
7c60: 64 6f 77 73 22 7d 20 7b 0a 20 20 20 20 69 66 20  dows"} {.    if 
7c70: 7b 24 6d 73 67 3d 3d 22 63 68 69 6c 64 20 6b 69  {$msg=="child ki
7c80: 6c 6c 65 64 3a 20 75 6e 6b 6e 6f 77 6e 20 73 69  lled: unknown si
7c90: 67 6e 61 6c 22 7d 20 7b 0a 20 20 20 20 20 20 73  gnal"} {.      s
7ca0: 65 74 20 6d 73 67 20 22 63 68 69 6c 64 20 70 72  et msg "child pr
7cb0: 6f 63 65 73 73 20 65 78 69 74 65 64 20 61 62 6e  ocess exited abn
7cc0: 6f 72 6d 61 6c 6c 79 22 0a 20 20 20 20 7d 0a 20  ormally".    }. 
7cd0: 20 7d 0a 20 20 0a 20 20 6c 61 70 70 65 6e 64 20   }.  .  lappend 
7ce0: 72 20 24 6d 73 67 0a 7d 0a 0a 23 20 55 73 61 67  r $msg.}..# Usag
7cf0: 65 3a 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74  e: do_ioerr_test
7d00: 20 3c 74 65 73 74 20 6e 75 6d 62 65 72 3e 20 3c   <test number> <
7d10: 6f 70 74 69 6f 6e 73 2e 2e 2e 3e 0a 23 0a 23 20  options...>.#.# 
7d20: 54 68 69 73 20 70 72 6f 63 20 69 73 20 75 73 65  This proc is use
7d30: 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 74  d to implement t
7d40: 65 73 74 20 63 61 73 65 73 20 74 68 61 74 20 63  est cases that c
7d50: 68 65 63 6b 20 74 68 61 74 20 49 4f 20 65 72 72  heck that IO err
7d60: 6f 72 73 0a 23 20 61 72 65 20 63 6f 72 72 65 63  ors.# are correc
7d70: 74 6c 79 20 68 61 6e 64 6c 65 64 2e 20 54 68 65  tly handled. The
7d80: 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2c   first argument,
7d90: 20 3c 74 65 73 74 20 6e 75 6d 62 65 72 3e 2c 20   <test number>, 
7da0: 69 73 20 61 6e 20 69 6e 74 65 67 65 72 20 0a 23  is an integer .#
7db0: 20 75 73 65 64 20 74 6f 20 6e 61 6d 65 20 74 68   used to name th
7dc0: 65 20 74 65 73 74 73 20 65 78 65 63 75 74 65 64  e tests executed
7dd0: 20 62 79 20 74 68 69 73 20 70 72 6f 63 2e 20 4f   by this proc. O
7de0: 70 74 69 6f 6e 73 20 61 72 65 20 61 73 20 66 6f  ptions are as fo
7df0: 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20 20 20 20 2d  llows:.#.#     -
7e00: 74 63 6c 70 72 65 70 20 20 20 20 20 20 20 20 20  tclprep         
7e10: 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72   TCL script to r
7e20: 75 6e 20 74 6f 20 70 72 65 70 61 72 65 20 74 65  un to prepare te
7e30: 73 74 2e 0a 23 20 20 20 20 20 2d 73 71 6c 70 72  st..#     -sqlpr
7e40: 65 70 20 20 20 20 20 20 20 20 20 20 53 51 4c 20  ep          SQL 
7e50: 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74 6f  script to run to
7e60: 20 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a 23   prepare test..#
7e70: 20 20 20 20 20 2d 74 63 6c 62 6f 64 79 20 20 20       -tclbody   
7e80: 20 20 20 20 20 20 20 54 43 4c 20 73 63 72 69 70         TCL scrip
7e90: 74 20 74 6f 20 72 75 6e 20 77 69 74 68 20 49 4f  t to run with IO
7ea0: 20 65 72 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f   error simulatio
7eb0: 6e 2e 0a 23 20 20 20 20 20 2d 73 71 6c 62 6f 64  n..#     -sqlbod
7ec0: 79 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73  y          TCL s
7ed0: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69 74  cript to run wit
7ee0: 68 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c  h IO error simul
7ef0: 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 65 78  ation..#     -ex
7f00: 63 6c 75 64 65 20 20 20 20 20 20 20 20 20 20 4c  clude          L
7f10: 69 73 74 20 6f 66 20 27 4e 27 20 76 61 6c 75 65  ist of 'N' value
7f20: 73 20 6e 6f 74 20 74 6f 20 74 65 73 74 2e 0a 23  s not to test..#
7f30: 20 20 20 20 20 2d 65 72 63 20 20 20 20 20 20 20       -erc       
7f40: 20 20 20 20 20 20 20 55 73 65 20 65 78 74 65 6e         Use exten
7f50: 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 73  ded result codes
7f60: 0a 23 20 20 20 20 20 2d 70 65 72 73 69 73 74 20  .#     -persist 
7f70: 20 20 20 20 20 20 20 20 20 4d 61 6b 65 20 73 69           Make si
7f80: 6d 75 6c 61 74 65 64 20 49 2f 4f 20 65 72 72 6f  mulated I/O erro
7f90: 72 73 20 70 65 72 73 69 73 74 65 6e 74 0a 23 20  rs persistent.# 
7fa0: 20 20 20 20 2d 73 74 61 72 74 20 20 20 20 20 20      -start      
7fb0: 20 20 20 20 20 20 56 61 6c 75 65 20 6f 66 20 27        Value of '
7fc0: 4e 27 20 74 6f 20 62 65 67 69 6e 20 77 69 74 68  N' to begin with
7fd0: 20 28 64 65 66 61 75 6c 74 20 31 29 0a 23 0a 23   (default 1).#.#
7fe0: 20 20 20 20 20 2d 63 6b 73 75 6d 20 20 20 20 20       -cksum     
7ff0: 20 20 20 20 20 20 20 42 6f 6f 6c 65 61 6e 2e 20         Boolean. 
8000: 49 66 20 74 72 75 65 2c 20 74 65 73 74 20 74 68  If true, test th
8010: 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20  at the database 
8020: 64 6f 65 73 0a 23 20 20 20 20 20 20 20 20 20 20  does.#          
8030: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 6f 74               not
8040: 20 63 68 61 6e 67 65 20 64 75 72 69 6e 67 20 74   change during t
8050: 68 65 20 65 78 65 63 75 74 69 6f 6e 20 6f 66 20  he execution of 
8060: 74 68 65 20 74 65 73 74 20 63 61 73 65 2e 0a 23  the test case..#
8070: 0a 70 72 6f 63 20 64 6f 5f 69 6f 65 72 72 5f 74  .proc do_ioerr_t
8080: 65 73 74 20 7b 74 65 73 74 6e 61 6d 65 20 61 72  est {testname ar
8090: 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 3a 3a 69  gs} {..  set ::i
80a0: 6f 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74 29  oerropts(-start)
80b0: 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   1.  set ::ioerr
80c0: 6f 70 74 73 28 2d 63 6b 73 75 6d 29 20 30 0a 20  opts(-cksum) 0. 
80d0: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
80e0: 28 2d 65 72 63 29 20 30 0a 20 20 73 65 74 20 3a  (-erc) 0.  set :
80f0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e  :ioerropts(-coun
8100: 74 29 20 31 30 30 30 30 30 30 30 30 0a 20 20 73  t) 100000000.  s
8110: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
8120: 70 65 72 73 69 73 74 29 20 31 0a 20 20 73 65 74  persist) 1.  set
8130: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b   ::ioerropts(-ck
8140: 72 65 66 63 6f 75 6e 74 29 20 30 0a 20 20 73 65  refcount) 0.  se
8150: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 72  t ::ioerropts(-r
8160: 65 73 74 6f 72 65 70 72 6e 67 29 20 31 0a 20 20  estoreprng) 1.  
8170: 61 72 72 61 79 20 73 65 74 20 3a 3a 69 6f 65 72  array set ::ioer
8180: 72 6f 70 74 73 20 24 61 72 67 73 0a 0a 20 20 23  ropts $args..  #
8190: 20 54 45 4d 50 4f 52 41 52 59 3a 20 46 6f 72 20   TEMPORARY: For 
81a0: 33 2e 35 2e 39 2c 20 64 69 73 61 62 6c 65 20 74  3.5.9, disable t
81b0: 65 73 74 69 6e 67 20 6f 66 20 65 78 74 65 6e 64  esting of extend
81c0: 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 73 2e  ed result codes.
81d0: 20 54 68 65 72 65 20 61 72 65 0a 20 20 23 20 61   There are.  # a
81e0: 20 63 6f 75 70 6c 65 20 6f 66 20 6f 62 73 63 75   couple of obscu
81f0: 72 65 20 49 4f 20 65 72 72 6f 72 73 20 74 68 61  re IO errors tha
8200: 74 20 64 6f 20 6e 6f 74 20 72 65 74 75 72 6e 20  t do not return 
8210: 74 68 65 6d 2e 0a 20 20 73 65 74 20 3a 3a 69 6f  them..  set ::io
8220: 65 72 72 6f 70 74 73 28 2d 65 72 63 29 20 30 0a  erropts(-erc) 0.
8230: 0a 20 20 73 65 74 20 3a 3a 67 6f 20 31 0a 20 20  .  set ::go 1.  
8240: 23 72 65 73 65 74 5f 70 72 6e 67 5f 73 74 61 74  #reset_prng_stat
8250: 65 0a 20 20 73 61 76 65 5f 70 72 6e 67 5f 73 74  e.  save_prng_st
8260: 61 74 65 0a 20 20 66 6f 72 20 7b 73 65 74 20 6e  ate.  for {set n
8270: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73   $::ioerropts(-s
8280: 74 61 72 74 29 7d 20 7b 24 3a 3a 67 6f 7d 20 7b  tart)} {$::go} {
8290: 69 6e 63 72 20 6e 7d 20 7b 0a 20 20 20 20 73 65  incr n} {.    se
82a0: 74 20 3a 3a 54 4e 20 24 6e 0a 20 20 20 20 69 6e  t ::TN $n.    in
82b0: 63 72 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  cr ::ioerropts(-
82c0: 63 6f 75 6e 74 29 20 2d 31 0a 20 20 20 20 69 66  count) -1.    if
82d0: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
82e0: 63 6f 75 6e 74 29 3c 30 7d 20 62 72 65 61 6b 0a  count)<0} break.
82f0: 20 0a 20 20 20 20 23 20 53 6b 69 70 20 74 68 69   .    # Skip thi
8300: 73 20 49 4f 20 65 72 72 6f 72 20 69 66 20 69 74  s IO error if it
8310: 20 77 61 73 20 73 70 65 63 69 66 69 65 64 20 77   was specified w
8320: 69 74 68 20 74 68 65 20 22 2d 65 78 63 6c 75 64  ith the "-exclud
8330: 65 22 20 6f 70 74 69 6f 6e 2e 0a 20 20 20 20 69  e" option..    i
8340: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
8350: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78 63  ::ioerropts(-exc
8360: 6c 75 64 65 29 5d 7d 20 7b 0a 20 20 20 20 20 20  lude)]} {.      
8370: 69 66 20 7b 5b 6c 73 65 61 72 63 68 20 24 3a 3a  if {[lsearch $::
8380: 69 6f 65 72 72 6f 70 74 73 28 2d 65 78 63 6c 75  ioerropts(-exclu
8390: 64 65 29 20 24 6e 5d 21 3d 2d 31 7d 20 63 6f 6e  de) $n]!=-1} con
83a0: 74 69 6e 75 65 0a 20 20 20 20 7d 0a 20 20 20 20  tinue.    }.    
83b0: 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73  if {$::ioerropts
83c0: 28 2d 72 65 73 74 6f 72 65 70 72 6e 67 29 7d 20  (-restoreprng)} 
83d0: 7b 0a 20 20 20 20 20 20 72 65 73 74 6f 72 65 5f  {.      restore_
83e0: 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 20 20 7d  prng_state.    }
83f0: 0a 0a 20 20 20 20 23 20 44 65 6c 65 74 65 20 74  ..    # Delete t
8400: 68 65 20 66 69 6c 65 73 20 74 65 73 74 2e 64 62  he files test.db
8410: 20 61 6e 64 20 74 65 73 74 32 2e 64 62 2c 20 74   and test2.db, t
8420: 68 65 6e 20 65 78 65 63 75 74 65 20 74 68 65 20  hen execute the 
8430: 54 43 4c 20 61 6e 64 20 0a 20 20 20 20 23 20 53  TCL and .    # S
8440: 51 4c 20 28 69 6e 20 74 68 61 74 20 6f 72 64 65  QL (in that orde
8450: 72 29 20 74 6f 20 70 72 65 70 61 72 65 20 66 6f  r) to prepare fo
8460: 72 20 74 68 65 20 74 65 73 74 20 63 61 73 65 2e  r the test case.
8470: 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65  .    do_test $te
8480: 73 74 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a 20 20  stname.$n.1 {.  
8490: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
84a0: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e  _io_error_pendin
84b0: 67 20 30 0a 20 20 20 20 20 20 63 61 74 63 68 20  g 0.      catch 
84c0: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20  {db close}.     
84d0: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
84e0: 65 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20 7b  e}.      catch {
84f0: 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74  forcedelete test
8500: 2e 64 62 7d 0a 20 20 20 20 20 20 63 61 74 63 68  .db}.      catch
8510: 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65   {forcedelete te
8520: 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20  st.db-journal}. 
8530: 20 20 20 20 20 63 61 74 63 68 20 7b 66 6f 72 63       catch {forc
8540: 65 64 65 6c 65 74 65 20 74 65 73 74 32 2e 64 62  edelete test2.db
8550: 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20 7b 66  }.      catch {f
8560: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 32  orcedelete test2
8570: 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 20  .db-journal}.   
8580: 20 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c     set ::DB [sql
8590: 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b  ite3 db test.db;
85a0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74   sqlite3_connect
85b0: 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a  ion_pointer db].
85c0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 65 78        sqlite3_ex
85d0: 74 65 6e 64 65 64 5f 72 65 73 75 6c 74 5f 63 6f  tended_result_co
85e0: 64 65 73 20 24 3a 3a 44 42 20 24 3a 3a 69 6f 65  des $::DB $::ioe
85f0: 72 72 6f 70 74 73 28 2d 65 72 63 29 0a 20 20 20  rropts(-erc).   
8600: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
8610: 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  sts ::ioerropts(
8620: 2d 74 63 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20  -tclprep)]} {.  
8630: 20 20 20 20 20 20 65 76 61 6c 20 24 3a 3a 69 6f        eval $::io
8640: 65 72 72 6f 70 74 73 28 2d 74 63 6c 70 72 65 70  erropts(-tclprep
8650: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ).      }.      
8660: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
8670: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71   ::ioerropts(-sq
8680: 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 20  lprep)]} {.     
8690: 20 20 20 65 78 65 63 73 71 6c 20 24 3a 3a 69 6f     execsql $::io
86a0: 65 72 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70  erropts(-sqlprep
86b0: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ).      }.      
86c0: 65 78 70 72 20 30 0a 20 20 20 20 7d 20 7b 30 7d  expr 0.    } {0}
86d0: 0a 0a 20 20 20 20 23 20 52 65 61 64 20 74 68 65  ..    # Read the
86e0: 20 27 63 68 65 63 6b 73 75 6d 27 20 6f 66 20 74   'checksum' of t
86f0: 68 65 20 64 61 74 61 62 61 73 65 2e 0a 20 20 20  he database..   
8700: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
8710: 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20  s(-cksum)} {.   
8720: 20 20 20 73 65 74 20 63 68 65 63 6b 73 75 6d 20     set checksum 
8730: 5b 63 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a 0a 20  [cksum].    }.. 
8740: 20 20 20 23 20 53 65 74 20 74 68 65 20 4e 74 68     # Set the Nth
8750: 20 49 4f 20 65 72 72 6f 72 20 74 6f 20 66 61 69   IO error to fai
8760: 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  l..    do_test $
8770: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73  testname.$n.2 [s
8780: 75 62 73 74 20 7b 0a 20 20 20 20 20 20 73 65 74  ubst {.      set
8790: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
87a0: 6f 72 5f 70 65 72 73 69 73 74 20 24 3a 3a 69 6f  or_persist $::io
87b0: 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74  erropts(-persist
87c0: 29 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  ).      set ::sq
87d0: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65  lite_io_error_pe
87e0: 6e 64 69 6e 67 20 24 6e 0a 20 20 20 20 7d 5d 20  nding $n.    }] 
87f0: 24 6e 0a 20 20 0a 20 20 20 20 23 20 43 72 65 61  $n.  .    # Crea
8800: 74 65 20 61 20 73 69 6e 67 6c 65 20 54 43 4c 20  te a single TCL 
8810: 73 63 72 69 70 74 20 66 72 6f 6d 20 74 68 65 20  script from the 
8820: 54 43 4c 20 61 6e 64 20 53 51 4c 20 73 70 65 63  TCL and SQL spec
8830: 69 66 69 65 64 0a 20 20 20 20 23 20 61 73 20 74  ified.    # as t
8840: 68 65 20 62 6f 64 79 20 6f 66 20 74 68 65 20 74  he body of the t
8850: 65 73 74 2e 0a 20 20 20 20 73 65 74 20 3a 3a 69  est..    set ::i
8860: 6f 65 72 72 6f 72 62 6f 64 79 20 7b 7d 0a 20 20  oerrorbody {}.  
8870: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
8880: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
8890: 74 63 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20  tclbody)]} {.   
88a0: 20 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72     append ::ioer
88b0: 72 6f 72 62 6f 64 79 20 22 24 3a 3a 69 6f 65 72  rorbody "$::ioer
88c0: 72 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5c  ropts(-tclbody)\
88d0: 6e 22 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20  n".    }.    if 
88e0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
88f0: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f  ioerropts(-sqlbo
8900: 64 79 29 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70  dy)]} {.      ap
8910: 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f  pend ::ioerrorbo
8920: 64 79 20 22 64 62 20 65 76 61 6c 20 7b 24 3a 3a  dy "db eval {$::
8930: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f  ioerropts(-sqlbo
8940: 64 79 29 7d 22 0a 20 20 20 20 7d 0a 0a 20 20 20  dy)}".    }..   
8950: 20 23 20 45 78 65 63 75 74 65 20 74 68 65 20 54   # Execute the T
8960: 43 4c 20 53 63 72 69 70 74 20 63 72 65 61 74 65  CL Script create
8970: 64 20 69 6e 20 74 68 65 20 61 62 6f 76 65 20 62  d in the above b
8980: 6c 6f 63 6b 2e 20 49 66 0a 20 20 20 20 23 20 74  lock. If.    # t
8990: 68 65 72 65 20 61 72 65 20 61 74 20 6c 65 61 73  here are at leas
89a0: 74 20 4e 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e  t N IO operation
89b0: 73 20 70 65 72 66 6f 72 6d 65 64 20 62 79 20 53  s performed by S
89c0: 51 4c 69 74 65 20 61 73 0a 20 20 20 20 23 20 61  QLite as.    # a
89d0: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 73   result of the s
89e0: 63 72 69 70 74 2c 20 74 68 65 20 4e 74 68 20 77  cript, the Nth w
89f0: 69 6c 6c 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f  ill fail..    do
8a00: 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e  _test $testname.
8a10: 24 6e 2e 33 20 7b 0a 20 20 20 20 20 20 73 65 74  $n.3 {.      set
8a20: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
8a30: 6f 72 5f 68 69 74 20 30 0a 20 20 20 20 20 20 73  or_hit 0.      s
8a40: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  et ::sqlite_io_e
8a50: 72 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a 20  rror_hardhit 0. 
8a60: 20 20 20 20 20 73 65 74 20 72 20 5b 63 61 74 63       set r [catc
8a70: 68 20 24 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  h $::ioerrorbody
8a80: 20 6d 73 67 5d 0a 20 20 20 20 20 20 73 65 74 20   msg].      set 
8a90: 3a 3a 65 72 72 73 65 65 6e 20 24 72 0a 20 20 20  ::errseen $r.   
8aa0: 20 20 20 73 65 74 20 72 63 20 5b 73 71 6c 69 74     set rc [sqlit
8ab0: 65 33 5f 65 72 72 63 6f 64 65 20 24 3a 3a 44 42  e3_errcode $::DB
8ac0: 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 69  ].      if {$::i
8ad0: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 7d 20  oerropts(-erc)} 
8ae0: 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 77  {.        # If w
8af0: 65 20 61 72 65 20 69 6e 20 65 78 74 65 6e 64 65  e are in extende
8b00: 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f  d result code mo
8b10: 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 61 6c  de, make sure al
8b20: 6c 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20 20  l of the.       
8b30: 20 23 20 49 4f 45 52 52 73 20 77 65 20 67 65 74   # IOERRs we get
8b40: 20 62 61 63 6b 20 72 65 61 6c 6c 79 20 64 6f 20   back really do 
8b50: 68 61 76 65 20 74 68 65 69 72 20 65 78 74 65 6e  have their exten
8b60: 64 65 64 20 63 6f 64 65 20 76 61 6c 75 65 73 2e  ded code values.
8b70: 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 61 6e  .        # If an
8b80: 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74   extended result
8b90: 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65   code is returne
8ba0: 64 2c 20 74 68 65 20 73 71 6c 69 74 65 33 5f 65  d, the sqlite3_e
8bb0: 72 72 63 6f 64 65 0a 20 20 20 20 20 20 20 20 23  rrcode.        #
8bc0: 20 54 43 4c 63 6f 6d 6d 61 6e 64 20 77 69 6c 6c   TCLcommand will
8bd0: 20 72 65 74 75 72 6e 20 61 20 73 74 72 69 6e 67   return a string
8be0: 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 20 20 53   of the form:  S
8bf0: 51 4c 49 54 45 5f 49 4f 45 52 52 2b 6e 6e 6e 6e  QLITE_IOERR+nnnn
8c00: 0a 20 20 20 20 20 20 20 20 23 20 77 68 65 72 65  .        # where
8c10: 20 6e 6e 6e 6e 20 69 73 20 61 20 6e 75 6d 62 65   nnnn is a numbe
8c20: 72 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72  r.        if {[r
8c30: 65 67 65 78 70 20 7b 5e 53 51 4c 49 54 45 5f 49  egexp {^SQLITE_I
8c40: 4f 45 52 52 7d 20 24 72 63 5d 20 26 26 20 21 5b  OERR} $rc] && ![
8c50: 72 65 67 65 78 70 20 7b 49 4f 45 52 52 5c 2b 5c  regexp {IOERR\+\
8c60: 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20 20  d} $rc]} {.     
8c70: 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63 0a       return $rc.
8c80: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
8c90: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
8ca0: 20 23 20 49 66 20 77 65 20 61 72 65 20 6e 6f 74   # If we are not
8cb0: 20 69 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73   in extended res
8cc0: 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20 6d  ult code mode, m
8cd0: 61 6b 65 20 73 75 72 65 20 6e 6f 0a 20 20 20 20  ake sure no.    
8ce0: 20 20 20 20 23 20 65 78 74 65 6e 64 65 64 20 65      # extended e
8cf0: 72 72 6f 72 20 63 6f 64 65 73 20 61 72 65 20 72  rror codes are r
8d00: 65 74 75 72 6e 65 64 2e 0a 20 20 20 20 20 20 20  eturned..       
8d10: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5c 2b   if {[regexp {\+
8d20: 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20  \d} $rc]} {.    
8d30: 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63        return $rc
8d40: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
8d50: 20 7d 0a 20 20 20 20 20 20 23 20 54 68 65 20 74   }.      # The t
8d60: 65 73 74 20 72 65 70 65 61 74 73 20 61 73 20 6c  est repeats as l
8d70: 6f 6e 67 20 61 73 20 24 3a 3a 67 6f 20 69 73 20  ong as $::go is 
8d80: 6e 6f 6e 2d 7a 65 72 6f 2e 20 20 24 3a 3a 67 6f  non-zero.  $::go
8d90: 20 73 74 61 72 74 73 20 6f 75 74 0a 20 20 20 20   starts out.    
8da0: 20 20 23 20 61 73 20 31 2e 20 20 57 68 65 6e 20    # as 1.  When 
8db0: 61 20 74 65 73 74 20 72 75 6e 73 20 74 6f 20 63  a test runs to c
8dc0: 6f 6d 70 6c 65 74 69 6f 6e 20 77 69 74 68 6f 75  ompletion withou
8dd0: 74 20 68 69 74 74 69 6e 67 20 61 6e 20 49 2f 4f  t hitting an I/O
8de0: 0a 20 20 20 20 20 20 23 20 65 72 72 6f 72 2c 20  .      # error, 
8df0: 74 68 61 74 20 6d 65 61 6e 73 20 74 68 65 72 65  that means there
8e00: 20 69 73 20 6e 6f 20 70 6f 69 6e 74 20 69 6e 20   is no point in 
8e10: 63 6f 6e 74 69 6e 75 69 6e 67 20 77 69 74 68 20  continuing with 
8e20: 74 68 69 73 20 74 65 73 74 0a 20 20 20 20 20 20  this test.      
8e30: 23 20 63 61 73 65 20 73 6f 20 73 65 74 20 24 3a  # case so set $:
8e40: 3a 67 6f 20 74 6f 20 7a 65 72 6f 2e 0a 20 20 20  :go to zero..   
8e50: 20 20 20 23 0a 20 20 20 20 20 20 69 66 20 7b 24     #.      if {$
8e60: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
8e70: 72 5f 70 65 6e 64 69 6e 67 3e 30 7d 20 7b 0a 20  r_pending>0} {. 
8e80: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 67 6f 20         set ::go 
8e90: 30 0a 20 20 20 20 20 20 20 20 73 65 74 20 71 20  0.        set q 
8ea0: 30 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a  0.        set ::
8eb0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
8ec0: 70 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 20 20  pending 0.      
8ed0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
8ee0: 20 73 65 74 20 71 20 31 0a 20 20 20 20 20 20 7d   set q 1.      }
8ef0: 0a 0a 20 20 20 20 20 20 73 65 74 20 73 20 5b 65  ..      set s [e
8f00: 78 70 72 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f  xpr $::sqlite_io
8f10: 5f 65 72 72 6f 72 5f 68 69 74 3d 3d 30 5d 0a 20  _error_hit==0]. 
8f20: 20 20 20 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69       if {$::sqli
8f30: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3e  te_io_error_hit>
8f40: 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72  $::sqlite_io_err
8f50: 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 72  or_hardhit && $r
8f60: 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  ==0} {.        s
8f70: 65 74 20 72 20 31 0a 20 20 20 20 20 20 7d 0a 20  et r 1.      }. 
8f80: 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74       set ::sqlit
8f90: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30  e_io_error_hit 0
8fa0: 0a 0a 20 20 20 20 20 20 23 20 4f 6e 65 20 6f 66  ..      # One of
8fb0: 20 74 77 6f 20 74 68 69 6e 67 73 20 6d 75 73 74   two things must
8fc0: 20 68 61 76 65 20 68 61 70 70 65 6e 65 64 2e 20   have happened. 
8fd0: 65 69 74 68 65 72 0a 20 20 20 20 20 20 23 20 20  either.      #  
8fe0: 20 31 2e 20 20 57 65 20 6e 65 76 65 72 20 68 69   1.  We never hi
8ff0: 74 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 61  t the IO error a
9000: 6e 64 20 74 68 65 20 53 51 4c 20 72 65 74 75 72  nd the SQL retur
9010: 6e 65 64 20 4f 4b 0a 20 20 20 20 20 20 23 20 20  ned OK.      #  
9020: 20 32 2e 20 20 41 6e 20 49 4f 20 65 72 72 6f 72   2.  An IO error
9030: 20 77 61 73 20 68 69 74 20 61 6e 64 20 74 68 65   was hit and the
9040: 20 53 51 4c 20 66 61 69 6c 65 64 0a 20 20 20 20   SQL failed.    
9050: 20 20 23 0a 20 20 20 20 20 20 23 70 75 74 73 20    #.      #puts 
9060: 22 73 3d 24 73 20 72 3d 24 72 20 71 3d 24 71 22  "s=$s r=$r q=$q"
9070: 0a 20 20 20 20 20 20 65 78 70 72 20 7b 20 28 24  .      expr { ($
9080: 73 20 26 26 20 21 24 72 20 26 26 20 21 24 71 29  s && !$r && !$q)
9090: 20 7c 7c 20 28 21 24 73 20 26 26 20 24 72 20 26   || (!$s && $r &
90a0: 26 20 24 71 29 20 7d 0a 20 20 20 20 7d 20 7b 31  & $q) }.    } {1
90b0: 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  }..    set ::sql
90c0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74  ite_io_error_hit
90d0: 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c   0.    set ::sql
90e0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
90f0: 64 69 6e 67 20 30 0a 0a 20 20 20 20 23 20 43 68  ding 0..    # Ch
9100: 65 63 6b 20 74 68 61 74 20 6e 6f 20 70 61 67 65  eck that no page
9110: 20 72 65 66 65 72 65 6e 63 65 73 20 77 65 72 65   references were
9120: 20 6c 65 61 6b 65 64 2e 20 54 68 65 72 65 20 73   leaked. There s
9130: 68 6f 75 6c 64 20 62 65 20 0a 20 20 20 20 23 20  hould be .    # 
9140: 61 20 73 69 6e 67 6c 65 20 72 65 66 65 72 65 6e  a single referen
9150: 63 65 20 69 66 20 74 68 65 72 65 20 69 73 20 73  ce if there is s
9160: 74 69 6c 6c 20 61 6e 20 61 63 74 69 76 65 20 74  till an active t
9170: 72 61 6e 73 61 63 74 69 6f 6e 2c 20 0a 20 20 20  ransaction, .   
9180: 20 23 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65 72   # or zero other
9190: 77 69 73 65 2e 0a 20 20 20 20 23 0a 20 20 20 20  wise..    #.    
91a0: 23 20 55 50 44 41 54 45 3a 20 49 66 20 74 68 65  # UPDATE: If the
91b0: 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   IO error occurs
91c0: 20 61 66 74 65 72 20 61 20 27 42 45 47 49 4e 27   after a 'BEGIN'
91d0: 20 62 75 74 20 62 65 66 6f 72 65 20 61 6e 79 0a   but before any.
91e0: 20 20 20 20 23 20 6c 6f 63 6b 73 20 61 72 65 20      # locks are 
91f0: 65 73 74 61 62 6c 69 73 68 65 64 20 6f 6e 20 64  established on d
9200: 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 28 69  atabase files (i
9210: 2e 65 2e 20 69 66 20 74 68 65 20 65 72 72 6f 72  .e. if the error
9220: 20 0a 20 20 20 20 23 20 6f 63 63 75 72 73 20 77   .    # occurs w
9230: 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20  hile attempting 
9240: 74 6f 20 64 65 74 65 63 74 20 61 20 68 6f 74 2d  to detect a hot-
9250: 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 29 2c 20 74  journal file), t
9260: 68 65 6e 0a 20 20 20 20 23 20 74 68 65 72 65 20  hen.    # there 
9270: 6d 61 79 20 30 20 70 61 67 65 20 72 65 66 65 72  may 0 page refer
9280: 65 6e 63 65 73 20 61 6e 64 20 61 6e 20 61 63 74  ences and an act
9290: 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ive transaction 
92a0: 61 63 63 6f 72 64 69 6e 67 0a 20 20 20 20 23 20  according.    # 
92b0: 74 6f 20 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f  to [sqlite3_get_
92c0: 61 75 74 6f 63 6f 6d 6d 69 74 5d 2e 0a 20 20 20  autocommit]..   
92d0: 20 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f   #.    if {$::go
92e0: 20 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f   && $::sqlite_io
92f0: 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26  _error_hardhit &
9300: 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  & $::ioerropts(-
9310: 63 6b 72 65 66 63 6f 75 6e 74 29 7d 20 7b 0a 20  ckrefcount)} {. 
9320: 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65       do_test $te
9330: 73 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b 0a 20 20  stname.$n.4 {.  
9340: 20 20 20 20 20 20 73 65 74 20 62 74 20 5b 62 74        set bt [bt
9350: 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a  ree_from_db db].
9360: 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74 65 72          db_enter
9370: 20 64 62 0a 20 20 20 20 20 20 20 20 61 72 72 61   db.        arra
9380: 79 20 73 65 74 20 73 74 61 74 73 20 5b 62 74 72  y set stats [btr
9390: 65 65 5f 70 61 67 65 72 5f 73 74 61 74 73 20 24  ee_pager_stats $
93a0: 62 74 5d 0a 20 20 20 20 20 20 20 20 64 62 5f 6c  bt].        db_l
93b0: 65 61 76 65 20 64 62 0a 20 20 20 20 20 20 20 20  eave db.        
93c0: 73 65 74 20 6e 52 65 66 20 24 73 74 61 74 73 28  set nRef $stats(
93d0: 72 65 66 29 0a 20 20 20 20 20 20 20 20 65 78 70  ref).        exp
93e0: 72 20 7b 24 6e 52 65 66 20 3d 3d 20 30 20 7c 7c  r {$nRef == 0 ||
93f0: 20 28 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61   ([sqlite3_get_a
9400: 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 3d 3d 30  utocommit db]==0
9410: 20 26 26 20 24 6e 52 65 66 20 3d 3d 20 31 29 7d   && $nRef == 1)}
9420: 0a 20 20 20 20 20 20 7d 20 7b 31 7d 0a 20 20 20  .      } {1}.   
9430: 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 74 68 65   }..    # If the
9440: 72 65 20 69 73 20 61 6e 20 6f 70 65 6e 20 64 61  re is an open da
9450: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 61 6e  tabase handle an
9460: 64 20 6e 6f 20 6f 70 65 6e 20 74 72 61 6e 73 61  d no open transa
9470: 63 74 69 6f 6e 2c 20 0a 20 20 20 20 23 20 61 6e  ction, .    # an
9480: 64 20 74 68 65 20 70 61 67 65 72 20 69 73 20 6e  d the pager is n
9490: 6f 74 20 72 75 6e 6e 69 6e 67 20 69 6e 20 65 78  ot running in ex
94a0: 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67 20  clusive-locking 
94b0: 6d 6f 64 65 2c 0a 20 20 20 20 23 20 63 68 65 63  mode,.    # chec
94c0: 6b 20 74 68 61 74 20 74 68 65 20 70 61 67 65 72  k that the pager
94d0: 20 69 73 20 69 6e 20 22 75 6e 6c 6f 63 6b 65 64   is in "unlocked
94e0: 22 20 73 74 61 74 65 2e 20 54 68 65 6f 72 65 74  " state. Theoret
94f0: 69 63 61 6c 6c 79 2c 0a 20 20 20 20 23 20 69 66  ically,.    # if
9500: 20 61 20 63 61 6c 6c 20 74 6f 20 78 55 6e 6c 6f   a call to xUnlo
9510: 63 6b 28 29 20 66 61 69 6c 65 64 20 64 75 65 20  ck() failed due 
9520: 74 6f 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 74  to an IO error t
9530: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 20 20  he underlying.  
9540: 20 20 23 20 66 69 6c 65 20 6d 61 79 20 73 74 69    # file may sti
9550: 6c 6c 20 62 65 20 6c 6f 63 6b 65 64 2e 0a 20 20  ll be locked..  
9560: 20 20 23 0a 20 20 20 20 69 66 63 61 70 61 62 6c    #.    ifcapabl
9570: 65 20 70 72 61 67 6d 61 20 7b 0a 20 20 20 20 20  e pragma {.     
9580: 20 69 66 20 7b 20 5b 69 6e 66 6f 20 63 6f 6d 6d   if { [info comm
9590: 61 6e 64 73 20 64 62 5d 20 6e 65 20 22 22 0a 20  ands db] ne "". 
95a0: 20 20 20 20 20 20 20 26 26 20 24 3a 3a 69 6f 65         && $::ioe
95b0: 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75  rropts(-ckrefcou
95c0: 6e 74 29 0a 20 20 20 20 20 20 20 20 26 26 20 5b  nt).        && [
95d0: 64 62 20 6f 6e 65 20 7b 70 72 61 67 6d 61 20 6c  db one {pragma l
95e0: 6f 63 6b 69 6e 67 5f 6d 6f 64 65 7d 5d 20 65 71  ocking_mode}] eq
95f0: 20 22 6e 6f 72 6d 61 6c 22 0a 20 20 20 20 20 20   "normal".      
9600: 20 20 26 26 20 5b 73 71 6c 69 74 65 33 5f 67 65    && [sqlite3_ge
9610: 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d  t_autocommit db]
9620: 0a 20 20 20 20 20 20 7d 20 7b 0a 20 20 20 20 20  .      } {.     
9630: 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74     do_test $test
9640: 6e 61 6d 65 2e 24 6e 2e 35 20 7b 0a 20 20 20 20  name.$n.5 {.    
9650: 20 20 20 20 20 20 73 65 74 20 62 74 20 5b 62 74        set bt [bt
9660: 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a  ree_from_db db].
9670: 20 20 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74            db_ent
9680: 65 72 20 64 62 0a 20 20 20 20 20 20 20 20 20 20  er db.          
9690: 61 72 72 61 79 20 73 65 74 20 73 74 61 74 73 20  array set stats 
96a0: 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73 74 61  [btree_pager_sta
96b0: 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20 20 20  ts $bt].        
96c0: 20 20 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20    db_leave db.  
96d0: 20 20 20 20 20 20 20 20 73 65 74 20 73 74 61 74          set stat
96e0: 73 28 73 74 61 74 65 29 0a 20 20 20 20 20 20 20  s(state).       
96f0: 20 7d 20 30 0a 20 20 20 20 20 20 7d 0a 20 20 20   } 0.      }.   
9700: 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 61 6e 20   }..    # If an 
9710: 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72 65 64  IO error occured
9720: 2c 20 74 68 65 6e 20 74 68 65 20 63 68 65 63 6b  , then the check
9730: 73 75 6d 20 6f 66 20 74 68 65 20 64 61 74 61 62  sum of the datab
9740: 61 73 65 20 73 68 6f 75 6c 64 0a 20 20 20 20 23  ase should.    #
9750: 20 62 65 20 74 68 65 20 73 61 6d 65 20 61 73 20   be the same as 
9760: 62 65 66 6f 72 65 20 74 68 65 20 73 63 72 69 70  before the scrip
9770: 74 20 74 68 61 74 20 63 61 75 73 65 64 20 74 68  t that caused th
9780: 65 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20 72  e IO error was r
9790: 75 6e 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66  un..    #.    if
97a0: 20 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71   {$::go && $::sq
97b0: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61  lite_io_error_ha
97c0: 72 64 68 69 74 20 26 26 20 24 3a 3a 69 6f 65 72  rdhit && $::ioer
97d0: 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b  ropts(-cksum)} {
97e0: 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24  .      do_test $
97f0: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 36 20 7b 0a  testname.$n.6 {.
9800: 20 20 20 20 20 20 20 20 63 61 74 63 68 20 7b 64          catch {d
9810: 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20  b close}.       
9820: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
9830: 65 7d 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a  e}.        set :
9840: 3a 44 42 20 5b 73 71 6c 69 74 65 33 20 64 62 20  :DB [sqlite3 db 
9850: 74 65 73 74 2e 64 62 3b 20 73 71 6c 69 74 65 33  test.db; sqlite3
9860: 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e  _connection_poin
9870: 74 65 72 20 64 62 5d 0a 20 20 20 20 20 20 20 20  ter db].        
9880: 63 6b 73 75 6d 0a 20 20 20 20 20 20 7d 20 24 63  cksum.      } $c
9890: 68 65 63 6b 73 75 6d 0a 20 20 20 20 7d 0a 0a 20  hecksum.    }.. 
98a0: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
98b0: 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74  io_error_hardhit
98c0: 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c   0.    set ::sql
98d0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
98e0: 64 69 6e 67 20 30 0a 20 20 20 20 69 66 20 7b 5b  ding 0.    if {[
98f0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f  info exists ::io
9900: 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70  erropts(-cleanup
9910: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 63 61 74 63  )]} {.      catc
9920: 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  h $::ioerropts(-
9930: 63 6c 65 61 6e 75 70 29 0a 20 20 20 20 7d 0a 20  cleanup).    }. 
9940: 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74   }.  set ::sqlit
9950: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
9960: 6e 67 20 30 0a 20 20 73 65 74 20 3a 3a 73 71 6c  ng 0.  set ::sql
9970: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 72  ite_io_error_per
9980: 73 69 73 74 20 30 0a 20 20 75 6e 73 65 74 20 3a  sist 0.  unset :
9990: 3a 69 6f 65 72 72 6f 70 74 73 0a 7d 0a 0a 23 20  :ioerropts.}..# 
99a0: 52 65 74 75 72 6e 20 61 20 63 68 65 63 6b 73 75  Return a checksu
99b0: 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63  m based on the c
99c0: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 6d  ontents of the m
99d0: 61 69 6e 20 64 61 74 61 62 61 73 65 20 61 73 73  ain database ass
99e0: 6f 63 69 61 74 65 64 0a 23 20 77 69 74 68 20 63  ociated.# with c
99f0: 6f 6e 6e 65 63 74 69 6f 6e 20 24 64 62 0a 23 0a  onnection $db.#.
9a00: 70 72 6f 63 20 63 6b 73 75 6d 20 7b 7b 64 62 20  proc cksum {{db 
9a10: 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 74 78 74  db}} {.  set txt
9a20: 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20   [$db eval {.   
9a30: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20     SELECT name, 
9a40: 74 79 70 65 2c 20 73 71 6c 20 46 52 4f 4d 20 73  type, sql FROM s
9a50: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 6f 72 64  qlite_master ord
9a60: 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 5c  er by name.  }]\
9a70: 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20  n.  foreach tbl 
9a80: 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20  [$db eval {.    
9a90: 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52    SELECT name FR
9aa0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
9ab0: 20 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62   WHERE type='tab
9ac0: 6c 65 27 20 6f 72 64 65 72 20 62 79 20 6e 61 6d  le' order by nam
9ad0: 65 0a 20 20 7d 5d 20 7b 0a 20 20 20 20 61 70 70  e.  }] {.    app
9ae0: 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76 61  end txt [$db eva
9af0: 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  l "SELECT * FROM
9b00: 20 24 74 62 6c 22 5d 5c 6e 0a 20 20 7d 0a 20 20   $tbl"]\n.  }.  
9b10: 66 6f 72 65 61 63 68 20 70 72 61 67 20 7b 64 65  foreach prag {de
9b20: 66 61 75 6c 74 5f 73 79 6e 63 68 72 6f 6e 6f 75  fault_synchronou
9b30: 73 20 64 65 66 61 75 6c 74 5f 63 61 63 68 65 5f  s default_cache_
9b40: 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70 65  size} {.    appe
9b50: 6e 64 20 74 78 74 20 24 70 72 61 67 2d 5b 24 64  nd txt $prag-[$d
9b60: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 24  b eval "PRAGMA $
9b70: 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 73  prag"]\n.  }.  s
9b80: 65 74 20 63 6b 73 75 6d 20 5b 73 74 72 69 6e 67  et cksum [string
9b90: 20 6c 65 6e 67 74 68 20 24 74 78 74 5d 2d 5b 6d   length $txt]-[m
9ba0: 64 35 20 24 74 78 74 5d 0a 20 20 23 20 70 75 74  d5 $txt].  # put
9bb0: 73 20 24 63 6b 73 75 6d 2d 5b 66 69 6c 65 20 73  s $cksum-[file s
9bc0: 69 7a 65 20 74 65 73 74 2e 64 62 5d 0a 20 20 72  ize test.db].  r
9bd0: 65 74 75 72 6e 20 24 63 6b 73 75 6d 0a 7d 0a 0a  eturn $cksum.}..
9be0: 23 20 47 65 6e 65 72 61 74 65 20 61 20 63 68 65  # Generate a che
9bf0: 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74  cksum based on t
9c00: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
9c10: 68 65 20 6d 61 69 6e 20 61 6e 64 20 74 65 6d 70  he main and temp
9c20: 20 74 61 62 6c 65 73 0a 23 20 64 61 74 61 62 61   tables.# databa
9c30: 73 65 20 24 64 62 2e 20 49 66 20 74 68 65 20 63  se $db. If the c
9c40: 68 65 63 6b 73 75 6d 20 6f 66 20 74 77 6f 20 64  hecksum of two d
9c50: 61 74 61 62 61 73 65 73 20 69 73 20 74 68 65 20  atabases is the 
9c60: 73 61 6d 65 2c 20 61 6e 64 20 74 68 65 0a 23 20  same, and the.# 
9c70: 69 6e 74 65 67 72 69 74 79 2d 63 68 65 63 6b 20  integrity-check 
9c80: 70 61 73 73 65 73 20 66 6f 72 20 62 6f 74 68 2c  passes for both,
9c90: 20 74 68 65 20 74 77 6f 20 64 61 74 61 62 61 73   the two databas
9ca0: 65 73 20 61 72 65 20 69 64 65 6e 74 69 63 61 6c  es are identical
9cb0: 2e 0a 23 0a 70 72 6f 63 20 61 6c 6c 63 6b 73 75  ..#.proc allcksu
9cc0: 6d 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  m {{db db}} {.  
9cd0: 73 65 74 20 72 65 74 20 5b 6c 69 73 74 5d 0a 20  set ret [list]. 
9ce0: 20 69 66 63 61 70 61 62 6c 65 20 74 65 6d 70 64   ifcapable tempd
9cf0: 62 20 7b 0a 20 20 20 20 73 65 74 20 73 71 6c 20  b {.    set sql 
9d00: 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e  {.      SELECT n
9d10: 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  ame FROM sqlite_
9d20: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
9d30: 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f  e = 'table' UNIO
9d40: 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e  N.      SELECT n
9d50: 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  ame FROM sqlite_
9d60: 74 65 6d 70 5f 6d 61 73 74 65 72 20 57 48 45 52  temp_master WHER
9d70: 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27  E type = 'table'
9d80: 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c   UNION.      SEL
9d90: 45 43 54 20 27 73 71 6c 69 74 65 5f 6d 61 73 74  ECT 'sqlite_mast
9da0: 65 72 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20  er' UNION.      
9db0: 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 74  SELECT 'sqlite_t
9dc0: 65 6d 70 5f 6d 61 73 74 65 72 27 20 4f 52 44 45  emp_master' ORDE
9dd0: 52 20 42 59 20 31 0a 20 20 20 20 7d 0a 20 20 7d  R BY 1.    }.  }
9de0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
9df0: 73 71 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45  sql {.      SELE
9e00: 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c  CT name FROM sql
9e10: 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45  ite_master WHERE
9e20: 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20   type = 'table' 
9e30: 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45  UNION.      SELE
9e40: 43 54 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65  CT 'sqlite_maste
9e50: 72 27 20 4f 52 44 45 52 20 42 59 20 31 0a 20 20  r' ORDER BY 1.  
9e60: 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20 74 62    }.  }.  set tb
9e70: 6c 6c 69 73 74 20 5b 24 64 62 20 65 76 61 6c 20  llist [$db eval 
9e80: 24 73 71 6c 5d 0a 20 20 73 65 74 20 74 78 74 20  $sql].  set txt 
9e90: 7b 7d 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c  {}.  foreach tbl
9ea0: 20 24 74 62 6c 6c 69 73 74 20 7b 0a 20 20 20 20   $tbllist {.    
9eb0: 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20  append txt [$db 
9ec0: 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46  eval "SELECT * F
9ed0: 52 4f 4d 20 24 74 62 6c 22 5d 0a 20 20 7d 0a 20  ROM $tbl"].  }. 
9ee0: 20 66 6f 72 65 61 63 68 20 70 72 61 67 20 7b 64   foreach prag {d
9ef0: 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a  efault_cache_siz
9f00: 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20  e} {.    append 
9f10: 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65  txt $prag-[$db e
9f20: 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61  val "PRAGMA $pra
9f30: 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 23 20 70 75  g"]\n.  }.  # pu
9f40: 74 73 20 74 78 74 3d 24 74 78 74 0a 20 20 72 65  ts txt=$txt.  re
9f50: 74 75 72 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a  turn [md5 $txt].
9f60: 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20  }..# Generate a 
9f70: 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f  checksum based o
9f80: 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  n the contents o
9f90: 66 20 61 20 73 69 6e 67 6c 65 20 64 61 74 61 62  f a single datab
9fa0: 61 73 65 20 77 69 74 68 0a 23 20 61 20 64 61 74  ase with.# a dat
9fb0: 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  abase connection
9fc0: 2e 20 20 54 68 65 20 6e 61 6d 65 20 6f 66 20 74  .  The name of t
9fd0: 68 65 20 64 61 74 61 62 61 73 65 20 69 73 20 24  he database is $
9fe0: 64 62 6e 61 6d 65 2e 20 20 0a 23 20 45 78 61 6d  dbname.  .# Exam
9ff0: 70 6c 65 73 20 6f 66 20 24 64 62 6e 61 6d 65 20  ples of $dbname 
a000: 61 72 65 20 22 74 65 6d 70 22 20 6f 72 20 22 6d  are "temp" or "m
a010: 61 69 6e 22 2e 0a 23 0a 70 72 6f 63 20 64 62 63  ain"..#.proc dbc
a020: 6b 73 75 6d 20 7b 64 62 20 64 62 6e 61 6d 65 7d  ksum {db dbname}
a030: 20 7b 0a 20 20 69 66 20 7b 24 64 62 6e 61 6d 65   {.  if {$dbname
a040: 3d 3d 22 74 65 6d 70 22 7d 20 7b 0a 20 20 20 20  =="temp"} {.    
a050: 73 65 74 20 6d 61 73 74 65 72 20 73 71 6c 69 74  set master sqlit
a060: 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 0a 20 20  e_temp_master.  
a070: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
a080: 20 6d 61 73 74 65 72 20 24 64 62 6e 61 6d 65 2e   master $dbname.
a090: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 0a 20 20  sqlite_master.  
a0a0: 7d 0a 20 20 73 65 74 20 61 6c 6c 74 61 62 20 5b  }.  set alltab [
a0b0: 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54  $db eval "SELECT
a0c0: 20 6e 61 6d 65 20 46 52 4f 4d 20 24 6d 61 73 74   name FROM $mast
a0d0: 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27 74  er WHERE type='t
a0e0: 61 62 6c 65 27 22 5d 0a 20 20 73 65 74 20 74 78  able'"].  set tx
a0f0: 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c  t [$db eval "SEL
a100: 45 43 54 20 2a 20 46 52 4f 4d 20 24 6d 61 73 74  ECT * FROM $mast
a110: 65 72 22 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68  er"]\n.  foreach
a120: 20 74 61 62 20 24 61 6c 6c 74 61 62 20 7b 0a 20   tab $alltab {. 
a130: 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24     append txt [$
a140: 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20  db eval "SELECT 
a150: 2a 20 46 52 4f 4d 20 24 64 62 6e 61 6d 65 2e 24  * FROM $dbname.$
a160: 74 61 62 22 5d 5c 6e 0a 20 20 7d 0a 20 20 72 65  tab"]\n.  }.  re
a170: 74 75 72 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a  turn [md5 $txt].
a180: 7d 0a 0a 70 72 6f 63 20 6d 65 6d 64 65 62 75 67  }..proc memdebug
a190: 5f 6c 6f 67 5f 73 71 6c 20 7b 7b 66 69 6c 65 6e  _log_sql {{filen
a1a0: 61 6d 65 20 6d 61 6c 6c 6f 63 73 2e 73 71 6c 7d  ame mallocs.sql}
a1b0: 7d 20 7b 0a 0a 20 20 73 65 74 20 64 61 74 61 20  } {..  set data 
a1c0: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75  [sqlite3_memdebu
a1d0: 67 5f 6c 6f 67 20 64 75 6d 70 5d 0a 20 20 73 65  g_log dump].  se
a1e0: 74 20 6e 46 72 61 6d 65 20 5b 65 78 70 72 20 5b  t nFrame [expr [
a1f0: 6c 6c 65 6e 67 74 68 20 5b 6c 69 6e 64 65 78 20  llength [lindex 
a200: 24 64 61 74 61 20 30 5d 5d 2d 32 5d 0a 20 20 69  $data 0]]-2].  i
a210: 66 20 7b 24 6e 46 72 61 6d 65 20 3c 20 30 7d 20  f {$nFrame < 0} 
a220: 7b 20 72 65 74 75 72 6e 20 22 22 20 7d 0a 0a 20  { return "" }.. 
a230: 20 73 65 74 20 64 61 74 61 62 61 73 65 20 74 65   set database te
a240: 6d 70 0a 0a 20 20 73 65 74 20 74 62 6c 20 22 43  mp..  set tbl "C
a250: 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64 61  REATE TABLE ${da
a260: 74 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63 28 7a  tabase}.malloc(z
a270: 54 65 73 74 2c 20 6e 43 61 6c 6c 2c 20 6e 42 79  Test, nCall, nBy
a280: 74 65 2c 20 6c 53 74 61 63 6b 29 3b 22 0a 0a 20  te, lStack);".. 
a290: 20 73 65 74 20 73 71 6c 20 22 22 0a 20 20 66 6f   set sql "".  fo
a2a0: 72 65 61 63 68 20 65 20 24 64 61 74 61 20 7b 0a  reach e $data {.
a2b0: 20 20 20 20 73 65 74 20 6e 43 61 6c 6c 20 5b 6c      set nCall [l
a2c0: 69 6e 64 65 78 20 24 65 20 30 5d 0a 20 20 20 20  index $e 0].    
a2d0: 73 65 74 20 6e 42 79 74 65 20 5b 6c 69 6e 64 65  set nByte [linde
a2e0: 78 20 24 65 20 31 5d 0a 20 20 20 20 73 65 74 20  x $e 1].    set 
a2f0: 6c 53 74 61 63 6b 20 5b 6c 72 61 6e 67 65 20 24  lStack [lrange $
a300: 65 20 32 20 65 6e 64 5d 0a 20 20 20 20 61 70 70  e 2 end].    app
a310: 65 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20  end sql "INSERT 
a320: 49 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d  INTO ${database}
a330: 2e 6d 61 6c 6c 6f 63 20 56 41 4c 55 45 53 22 0a  .malloc VALUES".
a340: 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22      append sql "
a350: 28 27 74 65 73 74 27 2c 20 24 6e 43 61 6c 6c 2c  ('test', $nCall,
a360: 20 24 6e 42 79 74 65 2c 20 27 24 6c 53 74 61 63   $nByte, '$lStac
a370: 6b 27 29 3b 5c 6e 22 0a 20 20 20 20 66 6f 72 65  k');\n".    fore
a380: 61 63 68 20 66 20 24 6c 53 74 61 63 6b 20 7b 0a  ach f $lStack {.
a390: 20 20 20 20 20 20 73 65 74 20 66 72 61 6d 65 73        set frames
a3a0: 28 24 66 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d  ($f) 1.    }.  }
a3b0: 0a 0a 20 20 73 65 74 20 74 62 6c 32 20 22 43 52  ..  set tbl2 "CR
a3c0: 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64 61 74  EATE TABLE ${dat
a3d0: 61 62 61 73 65 7d 2e 66 72 61 6d 65 28 66 72 61  abase}.frame(fra
a3e0: 6d 65 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41  me INTEGER PRIMA
a3f0: 52 59 20 4b 45 59 2c 20 6c 69 6e 65 29 3b 5c 6e  RY KEY, line);\n
a400: 22 0a 20 20 73 65 74 20 74 62 6c 33 20 22 43 52  ".  set tbl3 "CR
a410: 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64 61 74  EATE TABLE ${dat
a420: 61 62 61 73 65 7d 2e 66 69 6c 65 28 6e 61 6d 65  abase}.file(name
a430: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 6f   PRIMARY KEY, co
a440: 6e 74 65 6e 74 29 3b 5c 6e 22 0a 0a 20 20 66 6f  ntent);\n"..  fo
a450: 72 65 61 63 68 20 66 20 5b 61 72 72 61 79 20 6e  reach f [array n
a460: 61 6d 65 73 20 66 72 61 6d 65 73 5d 20 7b 0a 20  ames frames] {. 
a470: 20 20 20 73 65 74 20 61 64 64 72 20 5b 66 6f 72     set addr [for
a480: 6d 61 74 20 25 78 20 24 66 5d 0a 20 20 20 20 73  mat %x $f].    s
a490: 65 74 20 63 6d 64 20 22 61 64 64 72 32 6c 69 6e  et cmd "addr2lin
a4a0: 65 20 2d 65 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f  e -e [info nameo
a4b0: 66 65 78 65 63 5d 20 24 61 64 64 72 22 0a 20 20  fexec] $addr".  
a4c0: 20 20 73 65 74 20 6c 69 6e 65 20 5b 65 76 61 6c    set line [eval
a4d0: 20 65 78 65 63 20 24 63 6d 64 5d 0a 20 20 20 20   exec $cmd].    
a4e0: 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e 53 45  append sql "INSE
a4f0: 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61 62 61  RT INTO ${databa
a500: 73 65 7d 2e 66 72 61 6d 65 20 56 41 4c 55 45 53  se}.frame VALUES
a510: 28 24 66 2c 20 27 24 6c 69 6e 65 27 29 3b 5c 6e  ($f, '$line');\n
a520: 22 0a 0a 20 20 20 20 73 65 74 20 66 69 6c 65 20  "..    set file 
a530: 5b 6c 69 6e 64 65 78 20 5b 73 70 6c 69 74 20 24  [lindex [split $
a540: 6c 69 6e 65 20 3a 5d 20 30 5d 0a 20 20 20 20 73  line :] 0].    s
a550: 65 74 20 66 69 6c 65 73 28 24 66 69 6c 65 29 20  et files($file) 
a560: 31 0a 20 20 7d 0a 0a 20 20 66 6f 72 65 61 63 68  1.  }..  foreach
a570: 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20   f [array names 
a580: 66 69 6c 65 73 5d 20 7b 0a 20 20 20 20 73 65 74  files] {.    set
a590: 20 63 6f 6e 74 65 6e 74 73 20 22 22 0a 20 20 20   contents "".   
a5a0: 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20 73   catch {.      s
a5b0: 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66 5d 0a  et fd [open $f].
a5c0: 20 20 20 20 20 20 73 65 74 20 63 6f 6e 74 65 6e        set conten
a5d0: 74 73 20 5b 72 65 61 64 20 24 66 64 5d 0a 20 20  ts [read $fd].  
a5e0: 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a 20 20      close $fd.  
a5f0: 20 20 7d 0a 20 20 20 20 73 65 74 20 63 6f 6e 74    }.    set cont
a600: 65 6e 74 73 20 5b 73 74 72 69 6e 67 20 6d 61 70  ents [string map
a610: 20 7b 27 20 27 27 7d 20 24 63 6f 6e 74 65 6e 74   {' ''} $content
a620: 73 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73 71  s].    append sq
a630: 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 24  l "INSERT INTO $
a640: 7b 64 61 74 61 62 61 73 65 7d 2e 66 69 6c 65 20  {database}.file 
a650: 56 41 4c 55 45 53 28 27 24 66 27 2c 20 27 24 63  VALUES('$f', '$c
a660: 6f 6e 74 65 6e 74 73 27 29 3b 5c 6e 22 0a 20 20  ontents');\n".  
a670: 7d 0a 0a 20 20 73 65 74 20 66 64 20 5b 6f 70 65  }..  set fd [ope
a680: 6e 20 24 66 69 6c 65 6e 61 6d 65 20 77 5d 0a 20  n $filename w]. 
a690: 20 70 75 74 73 20 24 66 64 20 22 42 45 47 49 4e   puts $fd "BEGIN
a6a0: 3b 20 24 7b 74 62 6c 7d 24 7b 74 62 6c 32 7d 24  ; ${tbl}${tbl2}$
a6b0: 7b 74 62 6c 33 7d 24 7b 73 71 6c 7d 20 3b 20 43  {tbl3}${sql} ; C
a6c0: 4f 4d 4d 49 54 3b 22 0a 20 20 63 6c 6f 73 65 20  OMMIT;".  close 
a6d0: 24 66 64 0a 7d 0a 0a 23 20 44 72 6f 70 20 61 6c  $fd.}..# Drop al
a6e0: 6c 20 74 61 62 6c 65 73 20 69 6e 20 64 61 74 61  l tables in data
a6f0: 62 61 73 65 20 5b 64 62 5d 0a 70 72 6f 63 20 64  base [db].proc d
a700: 72 6f 70 5f 61 6c 6c 5f 74 61 62 6c 65 73 20 7b  rop_all_tables {
a710: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63  {db db}} {.  ifc
a720: 61 70 61 62 6c 65 20 74 72 69 67 67 65 72 26 26  apable trigger&&
a730: 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20 20 20  foreignkey {.   
a740: 20 73 65 74 20 70 6b 20 5b 24 64 62 20 6f 6e 65   set pk [$db one
a750: 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67 6e   "PRAGMA foreign
a760: 5f 6b 65 79 73 22 5d 0a 20 20 20 20 24 64 62 20  _keys"].    $db 
a770: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66 6f 72  eval "PRAGMA for
a780: 65 69 67 6e 5f 6b 65 79 73 20 3d 20 4f 46 46 22  eign_keys = OFF"
a790: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 7b  .  }.  foreach {
a7a0: 69 64 78 20 6e 61 6d 65 20 66 69 6c 65 7d 20 5b  idx name file} [
a7b0: 64 62 20 65 76 61 6c 20 7b 50 52 41 47 4d 41 20  db eval {PRAGMA 
a7c0: 64 61 74 61 62 61 73 65 5f 6c 69 73 74 7d 5d 20  database_list}] 
a7d0: 7b 0a 20 20 20 20 69 66 20 7b 24 69 64 78 3d 3d  {.    if {$idx==
a7e0: 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d  1} {.      set m
a7f0: 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74 65 6d  aster sqlite_tem
a800: 70 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d 20 65  p_master.    } e
a810: 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20  lse {.      set 
a820: 6d 61 73 74 65 72 20 24 6e 61 6d 65 2e 73 71 6c  master $name.sql
a830: 69 74 65 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d  ite_master.    }
a840: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 20  .    foreach {t 
a850: 74 79 70 65 7d 20 5b 24 64 62 20 65 76 61 6c 20  type} [$db eval 
a860: 22 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e  ".      SELECT n
a870: 61 6d 65 2c 20 74 79 70 65 20 46 52 4f 4d 20 24  ame, type FROM $
a880: 6d 61 73 74 65 72 0a 20 20 20 20 20 20 57 48 45  master.      WHE
a890: 52 45 20 74 79 70 65 20 49 4e 28 27 74 61 62 6c  RE type IN('tabl
a8a0: 65 27 2c 20 27 76 69 65 77 27 29 20 41 4e 44 20  e', 'view') AND 
a8b0: 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20 27 73  name NOT LIKE 's
a8c0: 71 6c 69 74 65 58 5f 25 27 20 45 53 43 41 50 45  qliteX_%' ESCAPE
a8d0: 20 27 58 27 0a 20 20 20 20 22 5d 20 7b 0a 20 20   'X'.    "] {.  
a8e0: 20 20 20 20 24 64 62 20 65 76 61 6c 20 22 44 52      $db eval "DR
a8f0: 4f 50 20 24 74 79 70 65 20 5c 22 24 74 5c 22 22  OP $type \"$t\""
a900: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 63  .    }.  }.  ifc
a910: 61 70 61 62 6c 65 20 74 72 69 67 67 65 72 26 26  apable trigger&&
a920: 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20 20 20  foreignkey {.   
a930: 20 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d   $db eval "PRAGM
a940: 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73 20 3d  A foreign_keys =
a950: 20 24 70 6b 22 0a 20 20 7d 0a 7d 0a 0a 23 2d 2d   $pk".  }.}..#--
a960: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a970: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a980: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a990: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a9a0: 2d 2d 2d 2d 2d 2d 2d 0a 23 20 49 66 20 61 20 74  -------.# If a t
a9b0: 65 73 74 20 73 63 72 69 70 74 20 69 73 20 65 78  est script is ex
a9c0: 65 63 75 74 65 64 20 77 69 74 68 20 67 6c 6f 62  ecuted with glob
a9d0: 61 6c 20 76 61 72 69 61 62 6c 65 20 24 3a 3a 47  al variable $::G
a9e0: 28 70 65 72 6d 3a 6e 61 6d 65 29 20 73 65 74 20  (perm:name) set 
a9f0: 74 6f 0a 23 20 22 77 61 6c 22 2c 20 74 68 65 6e  to.# "wal", then
aa00: 20 74 68 65 20 74 65 73 74 73 20 61 72 65 20 72   the tests are r
aa10: 75 6e 20 69 6e 20 57 41 4c 20 6d 6f 64 65 2e 20  un in WAL mode. 
aa20: 4f 74 68 65 72 77 69 73 65 2c 20 74 68 65 79 20  Otherwise, they 
aa30: 73 68 6f 75 6c 64 20 62 65 20 72 75 6e 20 0a 23  should be run .#
aa40: 20 69 6e 20 72 6f 6c 6c 62 61 63 6b 20 6d 6f 64   in rollback mod
aa50: 65 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  e. The following
aa60: 20 54 63 6c 20 70 72 6f 63 73 20 61 72 65 20 75   Tcl procs are u
aa70: 73 65 64 20 74 6f 20 6d 61 6b 65 20 74 68 69 73  sed to make this
aa80: 20 6c 65 73 73 20 0a 23 20 69 6e 74 72 75 73 69   less .# intrusi
aa90: 76 65 3a 0a 23 0a 23 20 20 20 77 61 6c 5f 73 65  ve:.#.#   wal_se
aaa0: 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3f  t_journal_mode ?
aab0: 44 42 3f 0a 23 0a 23 20 20 20 20 20 49 66 20 72  DB?.#.#     If r
aac0: 75 6e 6e 69 6e 67 20 61 20 57 41 4c 20 74 65 73  unning a WAL tes
aad0: 74 2c 20 65 78 65 63 75 74 65 20 22 50 52 41 47  t, execute "PRAG
aae0: 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  MA journal_mode 
aaf0: 3d 20 77 61 6c 22 20 75 73 69 6e 67 0a 23 20 20  = wal" using.#  
ab00: 20 20 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61     connection ha
ab10: 6e 64 6c 65 20 44 42 2e 20 4f 74 68 65 72 77 69  ndle DB. Otherwi
ab20: 73 65 2c 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64  se, this command
ab30: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23   is a no-op..#.#
ab40: 20 20 20 77 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75     wal_check_jou
ab50: 72 6e 61 6c 5f 6d 6f 64 65 20 54 45 53 54 4e 41  rnal_mode TESTNA
ab60: 4d 45 20 3f 44 42 3f 0a 23 0a 23 20 20 20 20 20  ME ?DB?.#.#     
ab70: 49 66 20 72 75 6e 6e 69 6e 67 20 61 20 57 41 4c  If running a WAL
ab80: 20 74 65 73 74 2c 20 65 78 65 63 75 74 65 20 61   test, execute a
ab90: 20 74 65 73 74 73 20 63 61 73 65 20 74 68 61 74   tests case that
aba0: 20 66 61 69 6c 73 20 69 66 20 74 68 65 20 6d 61   fails if the ma
abb0: 69 6e 0a 23 20 20 20 20 20 64 61 74 61 62 61 73  in.#     databas
abc0: 65 20 66 6f 72 20 63 6f 6e 6e 65 63 74 69 6f 6e  e for connection
abd0: 20 68 61 6e 64 6c 65 20 44 42 20 69 73 20 6e 6f   handle DB is no
abe0: 74 20 63 75 72 72 65 6e 74 6c 79 20 61 20 57 41  t currently a WA
abf0: 4c 20 64 61 74 61 62 61 73 65 2e 0a 23 20 20 20  L database..#   
ac00: 20 20 4f 74 68 65 72 77 69 73 65 20 28 69 66 20    Otherwise (if 
ac10: 6e 6f 74 20 72 75 6e 6e 69 6e 67 20 61 20 57 41  not running a WA
ac20: 4c 20 70 65 72 6d 75 74 61 74 69 6f 6e 29 20 74  L permutation) t
ac30: 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  his is a no-op..
ac40: 23 0a 23 20 20 20 77 61 6c 5f 69 73 5f 77 61 6c  #.#   wal_is_wal
ac50: 5f 6d 6f 64 65 0a 23 20 20 20 0a 23 20 20 20 20  _mode.#   .#    
ac60: 20 52 65 74 75 72 6e 73 20 74 72 75 65 20 69 66   Returns true if
ac70: 20 74 68 69 73 20 74 65 73 74 20 73 68 6f 75 6c   this test shoul
ac80: 64 20 62 65 20 72 75 6e 20 69 6e 20 57 41 4c 20  d be run in WAL 
ac90: 6d 6f 64 65 2e 20 46 61 6c 73 65 20 6f 74 68 65  mode. False othe
aca0: 72 77 69 73 65 2e 0a 23 20 0a 70 72 6f 63 20 77  rwise..# .proc w
acb0: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 20 7b  al_is_wal_mode {
acc0: 7d 20 7b 0a 20 20 65 78 70 72 20 7b 5b 70 65 72  } {.  expr {[per
acd0: 6d 75 74 61 74 69 6f 6e 5d 20 65 71 20 22 77 61  mutation] eq "wa
ace0: 6c 22 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f 73  l"}.}.proc wal_s
acf0: 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  et_journal_mode 
ad00: 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66  {{db db}} {.  if
ad10: 20 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d   { [wal_is_wal_m
ad20: 6f 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24 64 62  ode] } {.    $db
ad30: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6a 6f   eval "PRAGMA jo
ad40: 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c  urnal_mode = WAL
ad50: 22 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c  ".  }.}.proc wal
ad60: 5f 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d  _check_journal_m
ad70: 6f 64 65 20 7b 74 65 73 74 6e 61 6d 65 20 7b 64  ode {testname {d
ad80: 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 20 7b 20  b db}} {.  if { 
ad90: 5b 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65  [wal_is_wal_mode
ada0: 5d 20 7d 20 7b 0a 20 20 20 20 24 64 62 20 65 76  ] } {.    $db ev
adb0: 61 6c 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52  al { SELECT * FR
adc0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
add0: 20 7d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24   }.    do_test $
ade0: 74 65 73 74 6e 61 6d 65 20 5b 6c 69 73 74 20 24  testname [list $
adf0: 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20  db eval "PRAGMA 
ae00: 6d 61 69 6e 2e 6a 6f 75 72 6e 61 6c 5f 6d 6f 64  main.journal_mod
ae10: 65 22 5d 20 7b 77 61 6c 7d 0a 20 20 7d 0a 7d 0a  e"] {wal}.  }.}.
ae20: 0a 70 72 6f 63 20 70 65 72 6d 75 74 61 74 69 6f  .proc permutatio
ae30: 6e 20 7b 7d 20 7b 0a 20 20 73 65 74 20 70 65 72  n {} {.  set per
ae40: 6d 20 22 22 0a 20 20 63 61 74 63 68 20 7b 73 65  m "".  catch {se
ae50: 74 20 70 65 72 6d 20 24 3a 3a 47 28 70 65 72 6d  t perm $::G(perm
ae60: 3a 6e 61 6d 65 29 7d 0a 20 20 73 65 74 20 70 65  :name)}.  set pe
ae70: 72 6d 0a 7d 0a 70 72 6f 63 20 70 72 65 73 71 6c  rm.}.proc presql
ae80: 20 7b 7d 20 7b 0a 20 20 73 65 74 20 70 72 65 73   {} {.  set pres
ae90: 71 6c 20 22 22 0a 20 20 63 61 74 63 68 20 7b 73  ql "".  catch {s
aea0: 65 74 20 70 72 65 73 71 6c 20 24 3a 3a 47 28 70  et presql $::G(p
aeb0: 65 72 6d 3a 70 72 65 73 71 6c 29 7d 0a 20 20 73  erm:presql)}.  s
aec0: 65 74 20 70 72 65 73 71 6c 0a 7d 0a 0a 23 2d 2d  et presql.}..#--
aed0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
aee0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
aef0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
af00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
af10: 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72 6f 63 20 73  -------.#.proc s
af20: 6c 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70 74  lave_test_script
af30: 20 7b 73 63 72 69 70 74 7d 20 7b 0a 0a 20 20 23   {script} {..  #
af40: 20 43 72 65 61 74 65 20 74 68 65 20 69 6e 74 65   Create the inte
af50: 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f 20  rpreter used to 
af60: 72 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  run the test scr
af70: 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 63 72  ipt..  interp cr
af80: 65 61 74 65 20 74 69 6e 74 65 72 70 0a 0a 20 20  eate tinterp..  
af90: 23 20 50 6f 70 75 6c 61 74 65 20 73 6f 6d 65 20  # Populate some 
afa0: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  global variables
afb0: 20 74 68 61 74 20 74 65 73 74 65 72 2e 74 63 6c   that tester.tcl
afc0: 20 65 78 70 65 63 74 73 20 74 6f 20 73 65 65 2e   expects to see.
afd0: 0a 20 20 66 6f 72 65 61 63 68 20 7b 76 61 72 20  .  foreach {var 
afe0: 76 61 6c 75 65 7d 20 5b 6c 69 73 74 20 20 20 20  value} [list    
aff0: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
b000: 3a 3a 61 72 67 76 30 20 24 3a 3a 61 72 67 76 30  ::argv0 $::argv0
b010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b020: 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72 67       \.    ::arg
b030: 76 20 20 7b 7d 20 20 20 20 20 20 20 20 20 20 20  v  {}           
b040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b050: 5c 0a 20 20 20 20 3a 3a 53 4c 41 56 45 20 31 20  \.    ::SLAVE 1 
b060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b070: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 5d             \.  ]
b080: 20 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 65 76   {.    interp ev
b090: 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73 74  al tinterp [list
b0a0: 20 73 65 74 20 24 76 61 72 20 24 76 61 6c 75 65   set $var $value
b0b0: 5d 0a 20 20 7d 0a 0a 20 20 23 20 54 68 65 20 61  ].  }..  # The a
b0c0: 6c 69 61 73 20 75 73 65 64 20 74 6f 20 61 63 63  lias used to acc
b0d0: 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20 74  ess the global t
b0e0: 65 73 74 20 63 6f 75 6e 74 65 72 73 2e 0a 20 20  est counters..  
b0f0: 74 69 6e 74 65 72 70 20 61 6c 69 61 73 20 73 65  tinterp alias se
b100: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 73  t_test_counter s
b110: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 0a  et_test_counter.
b120: 0a 20 20 23 20 53 65 74 20 75 70 20 74 68 65 20  .  # Set up the 
b130: 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 61 72 72  ::cmdlinearg arr
b140: 61 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65 2e  ay in the slave.
b150: 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74  .  interp eval t
b160: 69 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72 72  interp [list arr
b170: 61 79 20 73 65 74 20 3a 3a 63 6d 64 6c 69 6e 65  ay set ::cmdline
b180: 61 72 67 20 5b 61 72 72 61 79 20 67 65 74 20 3a  arg [array get :
b190: 3a 63 6d 64 6c 69 6e 65 61 72 67 5d 5d 0a 0a 20  :cmdlinearg]].. 
b1a0: 20 23 20 53 65 74 20 75 70 20 74 68 65 20 3a 3a   # Set up the ::
b1b0: 47 20 61 72 72 61 79 20 69 6e 20 74 68 65 20 73  G array in the s
b1c0: 6c 61 76 65 2e 0a 20 20 69 6e 74 65 72 70 20 65  lave..  interp e
b1d0: 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73  val tinterp [lis
b1e0: 74 20 61 72 72 61 79 20 73 65 74 20 3a 3a 47 20  t array set ::G 
b1f0: 5b 61 72 72 61 79 20 67 65 74 20 3a 3a 47 5d 5d  [array get ::G]]
b200: 0a 0a 20 20 23 20 4c 6f 61 64 20 74 68 65 20 76  ..  # Load the v
b210: 61 72 69 6f 75 73 20 74 65 73 74 20 69 6e 74 65  arious test inte
b220: 72 66 61 63 65 73 20 69 6d 70 6c 65 6d 65 6e 74  rfaces implement
b230: 65 64 20 69 6e 20 43 2e 0a 20 20 6c 6f 61 64 5f  ed in C..  load_
b240: 74 65 73 74 66 69 78 74 75 72 65 5f 65 78 74 65  testfixture_exte
b250: 6e 73 69 6f 6e 73 20 74 69 6e 74 65 72 70 0a 0a  nsions tinterp..
b260: 20 20 23 20 52 75 6e 20 74 68 65 20 74 65 73 74    # Run the test
b270: 20 73 63 72 69 70 74 2e 0a 20 20 69 6e 74 65 72   script..  inter
b280: 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20 24  p eval tinterp $
b290: 73 63 72 69 70 74 0a 0a 20 20 23 20 43 68 65 63  script..  # Chec
b2a0: 6b 20 69 66 20 74 68 65 20 69 6e 74 65 72 70 72  k if the interpr
b2b0: 65 74 65 72 20 63 61 6c 6c 20 5b 72 75 6e 5f 74  eter call [run_t
b2c0: 68 72 65 61 64 5f 74 65 73 74 73 5d 0a 20 20 69  hread_tests].  i
b2d0: 66 20 7b 20 5b 69 6e 74 65 72 70 20 65 76 61 6c  f { [interp eval
b2e0: 20 74 69 6e 74 65 72 70 20 7b 69 6e 66 6f 20 65   tinterp {info e
b2f0: 78 69 73 74 73 20 3a 3a 72 75 6e 5f 74 68 72 65  xists ::run_thre
b300: 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 7d  ad_tests_called}
b310: 5d 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a  ] } {.    set ::
b320: 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73  run_thread_tests
b330: 5f 63 61 6c 6c 65 64 20 31 0a 20 20 7d 0a 0a 20  _called 1.  }.. 
b340: 20 23 20 44 65 6c 65 74 65 20 74 68 65 20 69 6e   # Delete the in
b350: 74 65 72 70 72 65 74 65 72 20 75 73 65 64 20 74  terpreter used t
b360: 6f 20 72 75 6e 20 74 68 65 20 74 65 73 74 20 73  o run the test s
b370: 63 72 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20  cript..  interp 
b380: 64 65 6c 65 74 65 20 74 69 6e 74 65 72 70 0a 7d  delete tinterp.}
b390: 0a 0a 70 72 6f 63 20 73 6c 61 76 65 5f 74 65 73  ..proc slave_tes
b3a0: 74 5f 66 69 6c 65 20 7b 7a 46 69 6c 65 7d 20 7b  t_file {zFile} {
b3b0: 0a 20 20 73 65 74 20 74 61 69 6c 20 5b 66 69 6c  .  set tail [fil
b3c0: 65 20 74 61 69 6c 20 24 7a 46 69 6c 65 5d 0a 0a  e tail $zFile]..
b3d0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
b3e0: 74 73 20 3a 3a 47 28 73 74 61 72 74 3a 70 65 72  ts ::G(start:per
b3f0: 6d 75 74 61 74 69 6f 6e 29 5d 7d 20 7b 0a 20 20  mutation)]} {.  
b400: 20 20 69 66 20 7b 5b 70 65 72 6d 75 74 61 74 69    if {[permutati
b410: 6f 6e 5d 20 21 3d 20 24 3a 3a 47 28 73 74 61 72  on] != $::G(star
b420: 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 7d 20  t:permutation)} 
b430: 72 65 74 75 72 6e 0a 20 20 20 20 75 6e 73 65 74  return.    unset
b440: 20 3a 3a 47 28 73 74 61 72 74 3a 70 65 72 6d 75   ::G(start:permu
b450: 74 61 74 69 6f 6e 29 0a 20 20 7d 0a 20 20 69 66  tation).  }.  if
b460: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
b470: 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 5d 7d  :G(start:file)]}
b480: 20 7b 0a 20 20 20 20 69 66 20 7b 24 74 61 69 6c   {.    if {$tail
b490: 20 21 3d 20 24 3a 3a 47 28 73 74 61 72 74 3a 66   != $::G(start:f
b4a0: 69 6c 65 29 20 26 26 20 24 74 61 69 6c 21 3d 22  ile) && $tail!="
b4b0: 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29  $::G(start:file)
b4c0: 2e 74 65 73 74 22 7d 20 72 65 74 75 72 6e 0a 20  .test"} return. 
b4d0: 20 20 20 75 6e 73 65 74 20 3a 3a 47 28 73 74 61     unset ::G(sta
b4e0: 72 74 3a 66 69 6c 65 29 0a 20 20 7d 0a 0a 20 20  rt:file).  }..  
b4f0: 23 20 52 65 6d 65 6d 62 65 72 20 74 68 65 20 76  # Remember the v
b500: 61 6c 75 65 20 6f 66 20 74 68 65 20 73 68 61 72  alue of the shar
b510: 65 64 2d 63 61 63 68 65 20 73 65 74 74 69 6e 67  ed-cache setting
b520: 2e 20 53 6f 20 74 68 61 74 20 69 74 20 69 73 20  . So that it is 
b530: 70 6f 73 73 69 62 6c 65 0a 20 20 23 20 74 6f 20  possible.  # to 
b540: 63 68 65 63 6b 20 61 66 74 65 72 77 61 72 64 73  check afterwards
b550: 20 74 68 61 74 20 69 74 20 77 61 73 20 6e 6f 74   that it was not
b560: 20 6d 6f 64 69 66 69 65 64 20 62 79 20 74 68 65   modified by the
b570: 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20   test script..  
b580: 23 0a 20 20 69 66 63 61 70 61 62 6c 65 20 73 68  #.  ifcapable sh
b590: 61 72 65 64 5f 63 61 63 68 65 20 7b 20 73 65 74  ared_cache { set
b5a0: 20 73 63 73 20 5b 73 71 6c 69 74 65 33 5f 65 6e   scs [sqlite3_en
b5b0: 61 62 6c 65 5f 73 68 61 72 65 64 5f 63 61 63 68  able_shared_cach
b5c0: 65 5d 20 7d 0a 0a 20 20 23 20 52 75 6e 20 74 68  e] }..  # Run th
b5d0: 65 20 74 65 73 74 20 73 63 72 69 70 74 20 69 6e  e test script in
b5e0: 20 61 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72   a slave interpr
b5f0: 65 74 65 72 2e 0a 20 20 23 0a 20 20 75 6e 73 65  eter..  #.  unse
b600: 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 3a 3a  t -nocomplain ::
b610: 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73  run_thread_tests
b620: 5f 63 61 6c 6c 65 64 0a 20 20 72 65 73 65 74 5f  _called.  reset_
b630: 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 73 65 74  prng_state.  set
b640: 20 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66   ::sqlite_open_f
b650: 69 6c 65 5f 63 6f 75 6e 74 20 30 0a 20 20 73 65  ile_count 0.  se
b660: 74 20 74 69 6d 65 20 5b 74 69 6d 65 20 7b 20 73  t time [time { s
b670: 6c 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70 74  lave_test_script
b680: 20 5b 6c 69 73 74 20 73 6f 75 72 63 65 20 24 7a   [list source $z
b690: 46 69 6c 65 5d 20 7d 5d 0a 20 20 73 65 74 20 6d  File] }].  set m
b6a0: 73 20 5b 65 78 70 72 20 5b 6c 69 6e 64 65 78 20  s [expr [lindex 
b6b0: 24 74 69 6d 65 20 30 5d 20 2f 20 31 30 30 30 5d  $time 0] / 1000]
b6c0: 0a 0a 20 20 23 20 54 65 73 74 20 74 68 61 74 20  ..  # Test that 
b6d0: 61 6c 6c 20 66 69 6c 65 73 20 6f 70 65 6e 65 64  all files opened
b6e0: 20 62 79 20 74 68 65 20 74 65 73 74 20 73 63 72   by the test scr
b6f0: 69 70 74 20 77 65 72 65 20 63 6c 6f 73 65 64 2e  ipt were closed.
b700: 20 4f 6d 69 74 20 74 68 69 73 0a 20 20 23 20 69   Omit this.  # i
b710: 66 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  f the test scrip
b720: 74 20 68 61 73 20 22 74 68 72 65 61 64 22 20 69  t has "thread" i
b730: 6e 20 69 74 73 20 6e 61 6d 65 2e 20 54 68 65 20  n its name. The 
b740: 6f 70 65 6e 20 66 69 6c 65 20 63 6f 75 6e 74 65  open file counte
b750: 72 0a 20 20 23 20 69 73 20 6e 6f 74 20 74 68 72  r.  # is not thr
b760: 65 61 64 2d 73 61 66 65 2e 0a 20 20 23 0a 20 20  ead-safe..  #.  
b770: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
b780: 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65   ::run_thread_te
b790: 73 74 73 5f 63 61 6c 6c 65 64 5d 3d 3d 30 7d 20  sts_called]==0} 
b7a0: 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 7b  {.    do_test ${
b7b0: 74 61 69 6c 7d 2d 63 6c 6f 73 65 61 6c 6c 66 69  tail}-closeallfi
b7c0: 6c 65 73 20 7b 20 65 78 70 72 20 7b 24 3a 3a 73  les { expr {$::s
b7d0: 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f  qlite_open_file_
b7e0: 63 6f 75 6e 74 3e 30 7d 20 7d 20 7b 30 7d 0a 20  count>0} } {0}. 
b7f0: 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74   }.  set ::sqlit
b800: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
b810: 74 20 30 0a 0a 20 20 23 20 54 65 73 74 20 74 68  t 0..  # Test th
b820: 61 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 22 73  at the global "s
b830: 68 61 72 65 64 2d 63 61 63 68 65 22 20 73 65 74  hared-cache" set
b840: 74 69 6e 67 20 77 61 73 20 6e 6f 74 20 61 6c 74  ting was not alt
b850: 65 72 65 64 20 62 79 20 0a 20 20 23 20 74 68 65  ered by .  # the
b860: 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20   test script..  
b870: 23 0a 20 20 69 66 63 61 70 61 62 6c 65 20 73 68  #.  ifcapable sh
b880: 61 72 65 64 5f 63 61 63 68 65 20 7b 20 0a 20 20  ared_cache { .  
b890: 20 20 73 65 74 20 72 65 73 20 5b 65 78 70 72 20    set res [expr 
b8a0: 7b 5b 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65  {[sqlite3_enable
b8b0: 5f 73 68 61 72 65 64 5f 63 61 63 68 65 5d 20 3d  _shared_cache] =
b8c0: 3d 20 24 73 63 73 7d 5d 0a 20 20 20 20 64 6f 5f  = $scs}].    do_
b8d0: 74 65 73 74 20 24 7b 74 61 69 6c 7d 2d 73 68 61  test ${tail}-sha
b8e0: 72 65 64 63 61 63 68 65 73 65 74 74 69 6e 67 20  redcachesetting 
b8f0: 5b 6c 69 73 74 20 73 65 74 20 7b 7d 20 24 72 65  [list set {} $re
b900: 73 5d 20 31 0a 20 20 7d 0a 0a 20 20 23 20 41 64  s] 1.  }..  # Ad
b910: 64 20 73 6f 6d 65 20 69 6e 66 6f 20 74 6f 20 74  d some info to t
b920: 68 65 20 6f 75 74 70 75 74 2e 0a 20 20 23 0a 20  he output..  #. 
b930: 20 70 75 74 73 20 22 54 69 6d 65 3a 20 24 74 61   puts "Time: $ta
b940: 69 6c 20 24 6d 73 20 6d 73 22 0a 20 20 73 68 6f  il $ms ms".  sho
b950: 77 5f 6d 65 6d 73 74 61 74 73 0a 7d 0a 0a 23 20  w_memstats.}..# 
b960: 4f 70 65 6e 20 61 20 6e 65 77 20 63 6f 6e 6e 65  Open a new conne
b970: 63 74 69 6f 6e 20 6f 6e 20 64 61 74 61 62 61 73  ction on databas
b980: 65 20 74 65 73 74 2e 64 62 20 61 6e 64 20 65 78  e test.db and ex
b990: 65 63 75 74 65 20 74 68 65 20 53 51 4c 20 73 63  ecute the SQL sc
b9a0: 72 69 70 74 0a 23 20 73 75 70 70 6c 69 65 64 20  ript.# supplied 
b9b0: 61 73 20 61 6e 20 61 72 67 75 6d 65 6e 74 2e 20  as an argument. 
b9c0: 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  Before returning
b9d0: 2c 20 63 6c 6f 73 65 20 74 68 65 20 6e 65 77 20  , close the new 
b9e0: 63 6f 6e 65 63 74 69 6f 6e 20 61 6e 64 0a 23 20  conection and.# 
b9f0: 72 65 73 74 6f 72 65 20 74 68 65 20 34 20 62 79  restore the 4 by
ba00: 74 65 20 66 69 65 6c 64 73 20 73 74 61 72 74 69  te fields starti
ba10: 6e 67 20 61 74 20 68 65 61 64 65 72 20 6f 66 66  ng at header off
ba20: 73 65 74 73 20 32 38 2c 20 39 32 20 61 6e 64 20  sets 28, 92 and 
ba30: 39 36 0a 23 20 74 6f 20 74 68 65 20 76 61 6c 75  96.# to the valu
ba40: 65 73 20 74 68 65 79 20 68 65 6c 64 20 62 65 66  es they held bef
ba50: 6f 72 65 20 74 68 65 20 53 51 4c 20 77 61 73 20  ore the SQL was 
ba60: 65 78 65 63 75 74 65 64 2e 20 54 68 69 73 20 73  executed. This s
ba70: 69 6d 75 6c 61 74 65 73 0a 23 20 61 20 77 72 69  imulates.# a wri
ba80: 74 65 20 62 79 20 61 20 70 72 65 2d 33 2e 37 2e  te by a pre-3.7.
ba90: 30 20 63 6c 69 65 6e 74 2e 0a 23 0a 70 72 6f 63  0 client..#.proc
baa0: 20 73 71 6c 33 36 32 33 31 20 7b 73 71 6c 7d 20   sql36231 {sql} 
bab0: 7b 0a 20 20 73 65 74 20 42 20 5b 68 65 78 69 6f  {.  set B [hexio
bac0: 5f 72 65 61 64 20 74 65 73 74 2e 64 62 20 39 32  _read test.db 92
bad0: 20 38 5d 0a 20 20 73 65 74 20 41 20 5b 68 65 78   8].  set A [hex
bae0: 69 6f 5f 72 65 61 64 20 74 65 73 74 2e 64 62 20  io_read test.db 
baf0: 32 38 20 34 5d 0a 20 20 73 71 6c 69 74 65 33 20  28 4].  sqlite3 
bb00: 64 62 33 36 32 33 31 20 74 65 73 74 2e 64 62 0a  db36231 test.db.
bb10: 20 20 63 61 74 63 68 20 7b 20 64 62 33 36 32 33    catch { db3623
bb20: 31 20 66 75 6e 63 20 61 5f 73 74 72 69 6e 67 20  1 func a_string 
bb30: 61 5f 73 74 72 69 6e 67 20 7d 0a 20 20 65 78 65  a_string }.  exe
bb40: 63 73 71 6c 20 24 73 71 6c 20 64 62 33 36 32 33  csql $sql db3623
bb50: 31 0a 20 20 64 62 33 36 32 33 31 20 63 6c 6f 73  1.  db36231 clos
bb60: 65 0a 20 20 68 65 78 69 6f 5f 77 72 69 74 65 20  e.  hexio_write 
bb70: 74 65 73 74 2e 64 62 20 32 38 20 24 41 0a 20 20  test.db 28 $A.  
bb80: 68 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73 74  hexio_write test
bb90: 2e 64 62 20 39 32 20 24 42 0a 20 20 72 65 74 75  .db 92 $B.  retu
bba0: 72 6e 20 22 22 0a 7d 0a 0a 70 72 6f 63 20 64 62  rn "".}..proc db
bbb0: 5f 73 61 76 65 20 7b 7d 20 7b 0a 20 20 66 6f 72  _save {} {.  for
bbc0: 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f  each f [glob -no
bbd0: 63 6f 6d 70 6c 61 69 6e 20 73 76 5f 74 65 73 74  complain sv_test
bbe0: 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c  .db*] { forcedel
bbf0: 65 74 65 20 24 66 20 7d 0a 20 20 66 6f 72 65 61  ete $f }.  forea
bc00: 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f  ch f [glob -noco
bc10: 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d  mplain test.db*]
bc20: 20 7b 0a 20 20 20 20 73 65 74 20 66 32 20 22 73   {.    set f2 "s
bc30: 76 5f 24 66 22 0a 20 20 20 20 66 6f 72 63 65 63  v_$f".    forcec
bc40: 6f 70 79 20 24 66 20 24 66 32 0a 20 20 7d 0a 7d  opy $f $f2.  }.}
bc50: 0a 70 72 6f 63 20 64 62 5f 73 61 76 65 5f 61 6e  .proc db_save_an
bc60: 64 5f 63 6c 6f 73 65 20 7b 7d 20 7b 0a 20 20 64  d_close {} {.  d
bc70: 62 5f 73 61 76 65 0a 20 20 63 61 74 63 68 20 7b  b_save.  catch {
bc80: 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20 72 65   db close }.  re
bc90: 74 75 72 6e 20 22 22 0a 7d 0a 70 72 6f 63 20 64  turn "".}.proc d
bca0: 62 5f 72 65 73 74 6f 72 65 20 7b 7d 20 7b 0a 20  b_restore {} {. 
bcb0: 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62   foreach f [glob
bcc0: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73   -nocomplain tes
bcd0: 74 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65  t.db*] { forcede
bce0: 6c 65 74 65 20 24 66 20 7d 0a 20 20 66 6f 72 65  lete $f }.  fore
bcf0: 61 63 68 20 66 32 20 5b 67 6c 6f 62 20 2d 6e 6f  ach f2 [glob -no
bd00: 63 6f 6d 70 6c 61 69 6e 20 73 76 5f 74 65 73 74  complain sv_test
bd10: 2e 64 62 2a 5d 20 7b 0a 20 20 20 20 73 65 74 20  .db*] {.    set 
bd20: 66 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  f [string range 
bd30: 24 66 32 20 33 20 65 6e 64 5d 0a 20 20 20 20 66  $f2 3 end].    f
bd40: 6f 72 63 65 63 6f 70 79 20 24 66 32 20 24 66 0a  orcecopy $f2 $f.
bd50: 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 62 5f 72 65    }.}.proc db_re
bd60: 73 74 6f 72 65 5f 61 6e 64 5f 72 65 6f 70 65 6e  store_and_reopen
bd70: 20 7b 7b 64 62 66 69 6c 65 20 74 65 73 74 2e 64   {{dbfile test.d
bd80: 62 7d 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 20  b}} {.  catch { 
bd90: 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20 64 62 5f  db close }.  db_
bda0: 72 65 73 74 6f 72 65 0a 20 20 73 71 6c 69 74 65  restore.  sqlite
bdb0: 33 20 64 62 20 24 64 62 66 69 6c 65 0a 7d 0a 70  3 db $dbfile.}.p
bdc0: 72 6f 63 20 64 62 5f 64 65 6c 65 74 65 5f 61 6e  roc db_delete_an
bdd0: 64 5f 72 65 6f 70 65 6e 20 7b 7b 66 69 6c 65 20  d_reopen {{file 
bde0: 74 65 73 74 2e 64 62 7d 7d 20 7b 0a 20 20 63 61  test.db}} {.  ca
bdf0: 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65 20 7d  tch { db close }
be00: 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c  .  foreach f [gl
be10: 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74  ob -nocomplain t
be20: 65 73 74 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65  est.db*] { force
be30: 64 65 6c 65 74 65 20 24 66 20 7d 0a 20 20 73 71  delete $f }.  sq
be40: 6c 69 74 65 33 20 64 62 20 24 66 69 6c 65 0a 7d  lite3 db $file.}
be50: 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62 72 61  ..# If the libra
be60: 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77  ry is compiled w
be70: 69 74 68 20 74 68 65 20 53 51 4c 49 54 45 5f 44  ith the SQLITE_D
be80: 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43 55 55  EFAULT_AUTOVACUU
be90: 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20 74 6f  M macro set.# to
bea0: 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20   non-zero, then 
beb0: 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 76  set the global v
bec0: 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56 41 43  ariable $AUTOVAC
bed0: 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41 55  UUM to 1..set AU
bee0: 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69 74 65  TOVACUUM $sqlite
bef0: 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75 6c 74  _options(default
bf00: 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a 23 20  _autovacuum)..# 
bf10: 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 46 54  Make sure the FT
bf20: 53 20 65 6e 68 61 6e 63 65 64 20 71 75 65 72 79  S enhanced query
bf30: 20 73 79 6e 74 61 78 20 69 73 20 64 69 73 61 62   syntax is disab
bf40: 6c 65 64 2e 0a 73 65 74 20 73 71 6c 69 74 65 5f  led..set sqlite_
bf50: 66 74 73 33 5f 65 6e 61 62 6c 65 5f 70 61 72 65  fts3_enable_pare
bf60: 6e 74 68 65 73 65 73 20 30 0a 0a 73 6f 75 72 63  ntheses 0..sourc
bf70: 65 20 24 74 65 73 74 64 69 72 2f 74 68 72 65 61  e $testdir/threa
bf80: 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f 75  d_common.tcl.sou
bf90: 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d 61 6c  rce $testdir/mal
bfa0: 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a     loc_common.tcl.