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

Artifact f2b99e912d4da1e5755969b8614febd883885c8b:


0000: 23 20 32 30 30 31 20 53 65 70 74 65 6d 62 65 72  # 2001 September
0010: 20 31 35 0a 23 0a 23 20 54 68 65 20 61 75 74 68   15.#.# The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 23 20 61 20 6c 65 67  place of.# a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23  is a blessing:.#
0080: 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 64 6f  .#    May you do
0090: 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76   good and not ev
00a0: 69 6c 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75  il..#    May you
00b0: 20 66 69 6e 64 20 66 6f 72 67 69 76 65 6e 65 73   find forgivenes
00c0: 73 20 66 6f 72 20 79 6f 75 72 73 65 6c 66 20 61  s for yourself a
00d0: 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 68 65 72  nd forgive other
00e0: 73 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20  s..#    May you 
00f0: 73 68 61 72 65 20 66 72 65 65 6c 79 2c 20 6e 65  share freely, ne
0100: 76 65 72 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20  ver taking more 
0110: 74 68 61 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23  than you give..#
0120: 0a 23 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .#**************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73  *********.# This
0170: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0180: 20 73 6f 6d 65 20 63 6f 6d 6d 6f 6e 20 54 43 4c   some common TCL
0190: 20 72 6f 75 74 69 6e 65 73 20 75 73 65 64 20 66   routines used f
01a0: 6f 72 20 72 65 67 72 65 73 73 69 6f 6e 0a 23 20  or regression.# 
01b0: 74 65 73 74 69 6e 67 20 74 68 65 20 53 51 4c 69  testing the SQLi
01c0: 74 65 20 6c 69 62 72 61 72 79 0a 23 0a 23 20 24  te library.#.# $
01d0: 49 64 3a 20 74 65 73 74 65 72 2e 74 63 6c 2c 76  Id: tester.tcl,v
01e0: 20 31 2e 31 34 33 20 32 30 30 39 2f 30 34 2f 30   1.143 2009/04/0
01f0: 39 20 30 31 3a 32 33 3a 34 39 20 64 72 68 20 45  9 01:23:49 drh E
0200: 78 70 20 24 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  xp $..#---------
0210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0240: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0250: 0a 23 20 54 68 65 20 63 6f 6d 6d 61 6e 64 73 20  .# The commands 
0260: 70 72 6f 76 69 64 65 64 20 62 79 20 74 68 65 20  provided by the 
0270: 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c  code in this fil
0280: 65 20 74 6f 20 68 65 6c 70 20 77 69 74 68 20 63  e to help with c
0290: 72 65 61 74 69 6e 67 0a 23 20 74 65 73 74 20 63  reating.# test c
02a0: 61 73 65 73 20 61 72 65 20 61 73 20 66 6f 6c 6c  ases are as foll
02b0: 6f 77 73 3a 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64  ows:.#.# Command
02c0: 73 20 74 6f 20 6d 61 6e 69 70 75 6c 61 74 65 20  s to manipulate 
02d0: 74 68 65 20 64 62 20 61 6e 64 20 74 68 65 20 66  the db and the f
02e0: 69 6c 65 2d 73 79 73 74 65 6d 20 61 74 20 61 20  ile-system at a 
02f0: 68 69 67 68 20 6c 65 76 65 6c 3a 0a 23 0a 23 20  high level:.#.# 
0300: 20 20 20 20 20 69 73 5f 72 65 6c 61 74 69 76 65       is_relative
0310: 5f 66 69 6c 65 0a 23 20 20 20 20 20 20 74 65 73  _file.#      tes
0320: 74 5f 70 77 64 0a 23 20 20 20 20 20 20 67 65 74  t_pwd.#      get
0330: 5f 70 77 64 0a 23 20 20 20 20 20 20 63 6f 70 79  _pwd.#      copy
0340: 5f 66 69 6c 65 20 20 20 20 20 20 20 20 20 20 20  _file           
0350: 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20 20 20 20     FROM TO.#    
0360: 20 20 64 65 6c 65 74 65 5f 66 69 6c 65 20 20 20    delete_file   
0370: 20 20 20 20 20 20 20 20 20 46 49 4c 45 4e 41 4d           FILENAM
0380: 45 0a 23 20 20 20 20 20 20 64 72 6f 70 5f 61 6c  E.#      drop_al
0390: 6c 5f 74 61 62 6c 65 73 20 20 20 20 20 20 20 20  l_tables        
03a0: 3f 44 42 3f 0a 23 20 20 20 20 20 20 66 6f 72 63  ?DB?.#      forc
03b0: 65 63 6f 70 79 20 20 20 20 20 20 20 20 20 20 20  ecopy           
03c0: 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20 20 20 20     FROM TO.#    
03d0: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 20 20    forcedelete   
03e0: 20 20 20 20 20 20 20 20 20 46 49 4c 45 4e 41 4d           FILENAM
03f0: 45 0a 23 0a 23 20 54 65 73 74 20 74 68 65 20 63  E.#.# Test the c
0400: 61 70 61 62 69 6c 69 74 79 20 6f 66 20 74 68 65  apability of the
0410: 20 53 51 4c 69 74 65 20 76 65 72 73 69 6f 6e 20   SQLite version 
0420: 62 75 69 6c 74 20 69 6e 74 6f 20 74 68 65 20 69  built into the i
0430: 6e 74 65 72 70 72 65 74 65 72 20 74 6f 0a 23 20  nterpreter to.# 
0440: 64 65 74 65 72 6d 69 6e 65 20 69 66 20 61 20 73  determine if a s
0450: 70 65 63 69 66 69 63 20 74 65 73 74 20 63 61 6e  pecific test can
0460: 20 62 65 20 72 75 6e 3a 0a 23 0a 23 20 20 20 20   be run:.#.#    
0470: 20 20 63 61 70 61 62 6c 65 20 20 20 20 20 20 20    capable       
0480: 20 20 20 20 20 20 20 20 20 45 58 50 52 0a 23 20           EXPR.# 
0490: 20 20 20 20 20 69 66 63 61 70 61 62 6c 65 20 20       ifcapable  
04a0: 20 20 20 20 20 20 20 20 20 20 20 20 45 58 50 52              EXPR
04b0: 0a 23 0a 23 20 43 61 6c 75 6c 61 74 65 20 63 68  .#.# Calulate ch
04c0: 65 63 6b 73 75 6d 73 20 62 61 73 65 64 20 6f 6e  ecksums based on
04d0: 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e   database conten
04e0: 74 73 3a 0a 23 0a 23 20 20 20 20 20 20 64 62 63  ts:.#.#      dbc
04f0: 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20 20  ksum            
0500: 20 20 20 20 44 42 20 44 42 4e 41 4d 45 0a 23 20      DB DBNAME.# 
0510: 20 20 20 20 20 61 6c 6c 63 6b 73 75 6d 20 20 20       allcksum   
0520: 20 20 20 20 20 20 20 20 20 20 20 20 3f 44 42 3f              ?DB?
0530: 0a 23 20 20 20 20 20 20 63 6b 73 75 6d 20 20 20  .#      cksum   
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3f                 ?
0550: 44 42 3f 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73  DB?.#.# Commands
0560: 20 74 6f 20 65 78 65 63 75 74 65 2f 65 78 70 6c   to execute/expl
0570: 61 69 6e 20 53 51 4c 20 73 74 61 74 65 6d 65 6e  ain SQL statemen
0580: 74 73 3a 0a 23 0a 23 20 20 20 20 20 20 6d 65 6d  ts:.#.#      mem
0590: 64 62 73 71 6c 20 20 20 20 20 20 20 20 20 20 20  dbsql           
05a0: 20 20 20 20 53 51 4c 0a 23 20 20 20 20 20 20 73      SQL.#      s
05b0: 74 65 70 73 71 6c 20 20 20 20 20 20 20 20 20 20  tepsql          
05c0: 20 20 20 20 20 20 44 42 20 53 51 4c 0a 23 20 20        DB SQL.#  
05d0: 20 20 20 20 65 78 65 63 73 71 6c 32 20 20 20 20      execsql2    
05e0: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 0a 23             SQL.#
05f0: 20 20 20 20 20 20 65 78 70 6c 61 69 6e 5f 6e 6f        explain_no
0600: 5f 74 72 61 63 65 20 20 20 20 20 20 20 53 51 4c  _trace       SQL
0610: 0a 23 20 20 20 20 20 20 65 78 70 6c 61 69 6e 20  .#      explain 
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
0630: 51 4c 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 63  QL ?DB?.#      c
0640: 61 74 63 68 73 71 6c 20 20 20 20 20 20 20 20 20  atchsql         
0650: 20 20 20 20 20 20 53 51 4c 20 3f 44 42 3f 0a 23        SQL ?DB?.#
0660: 20 20 20 20 20 20 65 78 65 63 73 71 6c 20 20 20        execsql   
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
0680: 20 3f 44 42 3f 0a 23 0a 23 20 43 6f 6d 6d 61 6e   ?DB?.#.# Comman
0690: 64 73 20 74 6f 20 72 75 6e 20 74 65 73 74 20 63  ds to run test c
06a0: 61 73 65 73 3a 0a 23 0a 23 20 20 20 20 20 20 64  ases:.#.#      d
06b0: 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 20 20 20  o_ioerr_test    
06c0: 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20 41        TESTNAME A
06d0: 52 47 53 2e 2e 2e 0a 23 20 20 20 20 20 20 63 72  RGS....#      cr
06e0: 61 73 68 73 71 6c 20 20 20 20 20 20 20 20 20 20  ashsql          
06f0: 20 20 20 20 20 41 52 47 53 2e 2e 2e 0a 23 20 20       ARGS....#  
0700: 20 20 20 20 69 6e 74 65 67 72 69 74 79 5f 63 68      integrity_ch
0710: 65 63 6b 20 20 20 20 20 20 20 20 54 45 53 54 4e  eck        TESTN
0720: 41 4d 45 20 3f 44 42 3f 0a 23 20 20 20 20 20 20  AME ?DB?.#      
0730: 76 65 72 69 66 79 5f 65 78 5f 65 72 72 63 6f 64  verify_ex_errcod
0740: 65 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20  e      TESTNAME 
0750: 45 58 50 45 43 54 45 44 20 3f 44 42 3f 0a 23 20  EXPECTED ?DB?.# 
0760: 20 20 20 20 20 64 6f 5f 74 65 73 74 20 20 20 20       do_test    
0770: 20 20 20 20 20 20 20 20 20 20 20 20 54 45 53 54              TEST
0780: 4e 41 4d 45 20 53 43 52 49 50 54 20 45 58 50 45  NAME SCRIPT EXPE
0790: 43 54 45 44 0a 23 20 20 20 20 20 20 64 6f 5f 65  CTED.#      do_e
07a0: 78 65 63 73 71 6c 5f 74 65 73 74 20 20 20 20 20  xecsql_test     
07b0: 20 20 20 54 45 53 54 4e 41 4d 45 20 53 51 4c 20     TESTNAME SQL 
07c0: 45 58 50 45 43 54 45 44 0a 23 20 20 20 20 20 20  EXPECTED.#      
07d0: 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74  do_catchsql_test
07e0: 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20         TESTNAME 
07f0: 53 51 4c 20 45 58 50 45 43 54 45 44 0a 23 20 20  SQL EXPECTED.#  
0800: 20 20 20 20 64 6f 5f 74 69 6d 65 64 5f 65 78 65      do_timed_exe
0810: 63 73 71 6c 5f 74 65 73 74 20 20 54 45 53 54 4e  csql_test  TESTN
0820: 41 4d 45 20 53 51 4c 20 45 58 50 45 43 54 45 44  AME SQL EXPECTED
0830: 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20 70 72  .#.# Commands pr
0840: 6f 76 69 64 69 6e 67 20 61 20 6c 6f 77 65 72 20  oviding a lower 
0850: 6c 65 76 65 6c 20 69 6e 74 65 72 66 61 63 65 20  level interface 
0860: 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c 20 74 65  to the global te
0870: 73 74 20 63 6f 75 6e 74 65 72 73 3a 0a 23 0a 23  st counters:.#.#
0880: 20 20 20 20 20 20 73 65 74 5f 74 65 73 74 5f 63        set_test_c
0890: 6f 75 6e 74 65 72 20 20 20 20 20 20 20 43 4f 55  ounter       COU
08a0: 4e 54 45 52 20 3f 56 41 4c 55 45 3f 0a 23 20 20  NTER ?VALUE?.#  
08b0: 20 20 20 20 6f 6d 69 74 5f 74 65 73 74 20 20 20      omit_test   
08c0: 20 20 20 20 20 20 20 20 20 20 20 54 45 53 54 4e             TESTN
08d0: 41 4d 45 20 52 45 41 53 4f 4e 20 3f 41 50 50 45  AME REASON ?APPE
08e0: 4e 44 3f 0a 23 20 20 20 20 20 20 66 61 69 6c 5f  ND?.#      fail_
08f0: 74 65 73 74 20 20 20 20 20 20 20 20 20 20 20 20  test            
0900: 20 20 54 45 53 54 4e 41 4d 45 0a 23 20 20 20 20    TESTNAME.#    
0910: 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a 23 0a 23    incr_ntest.#.#
0920: 20 43 6f 6d 6d 61 6e 64 20 72 75 6e 20 61 74 20   Command run at 
0930: 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68 20  the end of each 
0940: 74 65 73 74 20 66 69 6c 65 3a 0a 23 0a 23 20 20  test file:.#.#  
0950: 20 20 20 20 66 69 6e 69 73 68 5f 74 65 73 74 0a      finish_test.
0960: 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20 74 6f 20  #.# Commands to 
0970: 68 65 6c 70 20 63 72 65 61 74 65 20 74 65 73 74  help create test
0980: 20 66 69 6c 65 73 20 74 68 61 74 20 72 75 6e 20   files that run 
0990: 77 69 74 68 20 74 68 65 20 22 57 41 4c 22 20 61  with the "WAL" a
09a0: 6e 64 20 6f 74 68 65 72 0a 23 20 70 65 72 6d 75  nd other.# permu
09b0: 74 61 74 69 6f 6e 73 20 28 73 65 65 20 66 69 6c  tations (see fil
09c0: 65 20 70 65 72 6d 75 74 61 74 69 6f 6e 73 2e 74  e permutations.t
09d0: 65 73 74 29 3a 0a 23 0a 23 20 20 20 20 20 20 77  est):.#.#      w
09e0: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23  al_is_wal_mode.#
09f0: 20 20 20 20 20 20 77 61 6c 5f 73 65 74 5f 6a 6f        wal_set_jo
0a00: 75 72 6e 61 6c 5f 6d 6f 64 65 20 20 20 3f 44 42  urnal_mode   ?DB
0a10: 3f 0a 23 20 20 20 20 20 20 77 61 6c 5f 63 68 65  ?.#      wal_che
0a20: 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  ck_journal_mode 
0a30: 54 45 53 54 4e 41 4d 45 3f 44 42 3f 0a 23 20 20  TESTNAME?DB?.#  
0a40: 20 20 20 20 70 65 72 6d 75 74 61 74 69 6f 6e 0a      permutation.
0a50: 23 20 20 20 20 20 20 70 72 65 73 71 6c 0a 23 0a  #      presql.#.
0a60: 23 20 43 6f 6d 6d 61 6e 64 20 74 6f 20 74 65 73  # Command to tes
0a70: 74 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  t whether or not
0a80: 20 2d 2d 76 65 72 62 6f 73 65 3d 31 20 77 61 73   --verbose=1 was
0a90: 20 73 70 65 63 69 66 69 65 64 20 6f 6e 20 74 68   specified on th
0aa0: 65 20 63 6f 6d 6d 61 6e 64 0a 23 20 6c 69 6e 65  e command.# line
0ab0: 20 28 72 65 74 75 72 6e 73 20 30 20 66 6f 72 20   (returns 0 for 
0ac0: 6e 6f 74 2d 76 65 72 62 6f 73 65 2c 20 31 20 66  not-verbose, 1 f
0ad0: 6f 72 20 76 65 72 62 6f 73 65 20 61 6e 64 20 32  or verbose and 2
0ae0: 20 66 6f 72 20 22 76 65 72 62 6f 73 65 20 69 6e   for "verbose in
0af0: 20 74 68 65 0a 23 20 6f 75 74 70 75 74 20 66 69   the.# output fi
0b00: 6c 65 20 6f 6e 6c 79 22 29 2e 0a 23 0a 23 20 20  le only")..#.#  
0b10: 20 20 20 20 76 65 72 62 6f 73 65 0a 23 0a 0a 23      verbose.#..#
0b20: 20 53 65 74 20 74 68 65 20 70 72 65 63 69 73 69   Set the precisi
0b30: 6f 6e 20 6f 66 20 46 50 20 61 72 69 74 68 6d 61  on of FP arithma
0b40: 74 69 63 20 75 73 65 64 20 62 79 20 74 68 65 20  tic used by the 
0b50: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 41 6e 64  interpreter. And
0b60: 0a 23 20 63 6f 6e 66 69 67 75 72 65 20 53 51 4c  .# configure SQL
0b70: 69 74 65 20 74 6f 20 74 61 6b 65 20 64 61 74 61  ite to take data
0b80: 62 61 73 65 20 66 69 6c 65 20 6c 6f 63 6b 73 20  base file locks 
0b90: 6f 6e 20 74 68 65 20 70 61 67 65 20 74 68 61 74  on the page that
0ba0: 20 62 65 67 69 6e 73 0a 23 20 36 34 4b 42 20 69   begins.# 64KB i
0bb0: 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
0bc0: 20 66 69 6c 65 20 69 6e 73 74 65 61 64 20 6f 66   file instead of
0bd0: 20 74 68 65 20 6f 6e 65 20 31 47 42 20 69 6e 2e   the one 1GB in.
0be0: 20 54 68 69 73 20 6d 65 61 6e 73 0a 23 20 74 68   This means.# th
0bf0: 65 20 63 6f 64 65 20 74 68 61 74 20 68 61 6e 64  e code that hand
0c00: 6c 65 73 20 74 68 61 74 20 73 70 65 63 69 61 6c  les that special
0c10: 20 63 61 73 65 20 63 61 6e 20 62 65 20 74 65 73   case can be tes
0c20: 74 65 64 20 77 69 74 68 6f 75 74 20 63 72 65 61  ted without crea
0c30: 74 69 6e 67 0a 23 20 76 65 72 79 20 6c 61 72 67  ting.# very larg
0c40: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 73  e database files
0c50: 2e 0a 23 0a 73 65 74 20 74 63 6c 5f 70 72 65 63  ..#.set tcl_prec
0c60: 69 73 69 6f 6e 20 31 35 0a 73 71 6c 69 74 65 33  ision 15.sqlite3
0c70: 5f 74 65 73 74 5f 63 6f 6e 74 72 6f 6c 5f 70 65  _test_control_pe
0c80: 6e 64 69 6e 67 5f 62 79 74 65 20 30 78 30 30 31  nding_byte 0x001
0c90: 30 30 30 30 0a 0a 0a 23 20 49 66 20 74 68 65 20  0000...# If the 
0ca0: 70 61 67 65 72 20 63 6f 64 65 63 20 69 73 20 61  pager codec is a
0cb0: 76 61 69 6c 61 62 6c 65 2c 20 63 72 65 61 74 65  vailable, create
0cc0: 20 61 20 77 72 61 70 70 65 72 20 66 6f 72 20 74   a wrapper for t
0cd0: 68 65 20 5b 73 71 6c 69 74 65 33 5d 0a 23 20 63  he [sqlite3].# c
0ce0: 6f 6d 6d 61 6e 64 20 74 68 61 74 20 61 70 70 65  ommand that appe
0cf0: 6e 64 73 20 22 2d 6b 65 79 20 7b 78 79 7a 7a 79  nds "-key {xyzzy
0d00: 7d 22 20 74 6f 20 74 68 65 20 63 6f 6d 6d 61 6e  }" to the comman
0d10: 64 20 6c 69 6e 65 2e 20 69 2e 65 2e 20 74 68 69  d line. i.e. thi
0d20: 73 3a 0a 23 0a 23 20 20 20 20 20 73 71 6c 69 74  s:.#.#     sqlit
0d30: 65 33 20 64 62 20 74 65 73 74 2e 64 62 0a 23 0a  e3 db test.db.#.
0d40: 23 20 62 65 63 6f 6d 65 73 0a 23 0a 23 20 20 20  # becomes.#.#   
0d50: 20 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73    sqlite3 db tes
0d60: 74 2e 64 62 20 2d 6b 65 79 20 7b 78 79 7a 7a 79  t.db -key {xyzzy
0d70: 7d 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f 20 63 6f  }.#.if {[info co
0d80: 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f 6f 72 69  mmand sqlite_ori
0d90: 67 5d 3d 3d 22 22 7d 20 7b 0a 20 20 72 65 6e 61  g]==""} {.  rena
0da0: 6d 65 20 73 71 6c 69 74 65 33 20 73 71 6c 69 74  me sqlite3 sqlit
0db0: 65 5f 6f 72 69 67 0a 20 20 70 72 6f 63 20 73 71  e_orig.  proc sq
0dc0: 6c 69 74 65 33 20 7b 61 72 67 73 7d 20 7b 0a 20  lite3 {args} {. 
0dd0: 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20     if {[llength 
0de0: 24 61 72 67 73 5d 3e 3d 32 20 26 26 20 5b 73 74  $args]>=2 && [st
0df0: 72 69 6e 67 20 69 6e 64 65 78 20 5b 6c 69 6e 64  ring index [lind
0e00: 65 78 20 24 61 72 67 73 20 30 5d 20 30 5d 21 3d  ex $args 0] 0]!=
0e10: 22 2d 22 7d 20 7b 0a 20 20 20 20 20 20 23 20 54  "-"} {.      # T
0e20: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 6f  his command is o
0e30: 70 65 6e 69 6e 67 20 61 20 6e 65 77 20 64 61 74  pening a new dat
0e40: 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  abase connection
0e50: 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20  ..      #.      
0e60: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
0e70: 20 3a 3a 47 28 70 65 72 6d 3a 73 71 6c 69 74 65   ::G(perm:sqlite
0e80: 33 5f 61 72 67 73 29 5d 7d 20 7b 0a 20 20 20 20  3_args)]} {.    
0e90: 20 20 20 20 73 65 74 20 61 72 67 73 20 5b 63 6f      set args [co
0ea0: 6e 63 61 74 20 24 61 72 67 73 20 24 3a 3a 47 28  ncat $args $::G(
0eb0: 70 65 72 6d 3a 73 71 6c 69 74 65 33 5f 61 72 67  perm:sqlite3_arg
0ec0: 73 29 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  s)].      }.    
0ed0: 20 20 69 66 20 7b 5b 73 71 6c 69 74 65 5f 6f 72    if {[sqlite_or
0ee0: 69 67 20 2d 68 61 73 2d 63 6f 64 65 63 5d 20 26  ig -has-codec] &
0ef0: 26 20 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  & ![info exists 
0f00: 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f 63 6f 64  ::do_not_use_cod
0f10: 65 63 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 6c  ec]} {.        l
0f20: 61 70 70 65 6e 64 20 61 72 67 73 20 2d 6b 65 79  append args -key
0f30: 20 7b 78 79 7a 7a 79 7d 0a 20 20 20 20 20 20 7d   {xyzzy}.      }
0f40: 0a 0a 20 20 20 20 20 20 73 65 74 20 72 65 73 20  ..      set res 
0f50: 5b 75 70 6c 65 76 65 6c 20 31 20 73 71 6c 69 74  [uplevel 1 sqlit
0f60: 65 5f 6f 72 69 67 20 24 61 72 67 73 5d 0a 20 20  e_orig $args].  
0f70: 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78      if {[info ex
0f80: 69 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a 70 72  ists ::G(perm:pr
0f90: 65 73 71 6c 29 5d 7d 20 7b 0a 20 20 20 20 20 20  esql)]} {.      
0fa0: 20 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20    [lindex $args 
0fb0: 30 5d 20 65 76 61 6c 20 24 3a 3a 47 28 70 65 72  0] eval $::G(per
0fc0: 6d 3a 70 72 65 73 71 6c 29 0a 20 20 20 20 20 20  m:presql).      
0fd0: 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66  }.      if {[inf
0fe0: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72  o exists ::G(per
0ff0: 6d 3a 64 62 63 6f 6e 66 69 67 29 5d 7d 20 7b 0a  m:dbconfig)]} {.
1000: 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a 64 62          set ::db
1010: 68 61 6e 64 6c 65 20 5b 6c 69 6e 64 65 78 20 24  handle [lindex $
1020: 61 72 67 73 20 30 5d 0a 20 20 20 20 20 20 20 20  args 0].        
1030: 75 70 6c 65 76 65 6c 20 23 30 20 24 3a 3a 47 28  uplevel #0 $::G(
1040: 70 65 72 6d 3a 64 62 63 6f 6e 66 69 67 29 0a 20  perm:dbconfig). 
1050: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 65 74       }.      set
1060: 20 72 65 73 0a 20 20 20 20 7d 20 65 6c 73 65 20   res.    } else 
1070: 7b 0a 20 20 20 20 20 20 23 20 54 68 69 73 20 63  {.      # This c
1080: 6f 6d 6d 61 6e 64 20 69 73 20 6e 6f 74 20 6f 70  ommand is not op
1090: 65 6e 69 6e 67 20 61 20 6e 65 77 20 64 61 74 61  ening a new data
10a0: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e  base connection.
10b0: 20 50 61 73 73 20 74 68 65 0a 20 20 20 20 20 20   Pass the.      
10c0: 23 20 61 72 67 75 6d 65 6e 74 73 20 74 68 72 6f  # arguments thro
10d0: 75 67 68 20 74 6f 20 74 68 65 20 43 20 69 6d 70  ugh to the C imp
10e0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 61 73 20 74  lementation as t
10f0: 68 65 20 61 72 65 2e 0a 20 20 20 20 20 20 23 0a  he are..      #.
1100: 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 31 20        uplevel 1 
1110: 73 71 6c 69 74 65 5f 6f 72 69 67 20 24 61 72 67  sqlite_orig $arg
1120: 73 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 70  s.    }.  }.}..p
1130: 72 6f 63 20 67 65 74 46 69 6c 65 52 65 74 72 69  roc getFileRetri
1140: 65 73 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 21 5b  es {} {.  if {![
1150: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
1160: 66 69 6c 65 2d 72 65 74 72 69 65 73 29 5d 7d 20  file-retries)]} 
1170: 7b 0a 20 20 20 20 23 0a 20 20 20 20 23 20 4e 4f  {.    #.    # NO
1180: 54 45 3a 20 52 65 74 75 72 6e 20 74 68 65 20 64  TE: Return the d
1190: 65 66 61 75 6c 74 20 6e 75 6d 62 65 72 20 6f 66  efault number of
11a0: 20 72 65 74 72 69 65 73 20 66 6f 72 20 5b 66 69   retries for [fi
11b0: 6c 65 5d 20 6f 70 65 72 61 74 69 6f 6e 73 2e 20  le] operations. 
11c0: 20 41 0a 20 20 20 20 23 20 20 20 20 20 20 20 76   A.    #       v
11d0: 61 6c 75 65 20 6f 66 20 7a 65 72 6f 20 6f 72 20  alue of zero or 
11e0: 6c 65 73 73 20 68 65 72 65 20 6d 65 61 6e 73 20  less here means 
11f0: 22 64 69 73 61 62 6c 65 64 22 2e 0a 20 20 20 20  "disabled"..    
1200: 23 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 65 78  #.    return [ex
1210: 70 72 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  pr {$::tcl_platf
1220: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 20 65 71  orm(platform) eq
1230: 20 22 77 69 6e 64 6f 77 73 22 20 3f 20 35 30 20   "windows" ? 50 
1240: 3a 20 30 7d 5d 0a 20 20 7d 0a 20 20 72 65 74 75  : 0}].  }.  retu
1250: 72 6e 20 24 3a 3a 47 28 66 69 6c 65 2d 72 65 74  rn $::G(file-ret
1260: 72 69 65 73 29 0a 7d 0a 0a 70 72 6f 63 20 67 65  ries).}..proc ge
1270: 74 46 69 6c 65 52 65 74 72 79 44 65 6c 61 79 20  tFileRetryDelay 
1280: 7b 7d 20 7b 0a 20 20 69 66 20 7b 21 5b 69 6e 66  {} {.  if {![inf
1290: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 66 69 6c  o exists ::G(fil
12a0: 65 2d 72 65 74 72 79 2d 64 65 6c 61 79 29 5d 7d  e-retry-delay)]}
12b0: 20 7b 0a 20 20 20 20 23 0a 20 20 20 20 23 20 4e   {.    #.    # N
12c0: 4f 54 45 3a 20 52 65 74 75 72 6e 20 74 68 65 20  OTE: Return the 
12d0: 64 65 66 61 75 6c 74 20 6e 75 6d 62 65 72 20 6f  default number o
12e0: 66 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73 20 74  f milliseconds t
12f0: 6f 20 77 61 69 74 20 77 68 65 6e 20 72 65 74 72  o wait when retr
1300: 79 69 6e 67 0a 20 20 20 20 23 20 20 20 20 20 20  ying.    #      
1310: 20 66 61 69 6c 65 64 20 5b 66 69 6c 65 5d 20 6f   failed [file] o
1320: 70 65 72 61 74 69 6f 6e 73 2e 20 20 41 20 76 61  perations.  A va
1330: 6c 75 65 20 6f 66 20 7a 65 72 6f 20 6f 72 20 6c  lue of zero or l
1340: 65 73 73 20 6d 65 61 6e 73 20 22 64 6f 20 6e 6f  ess means "do no
1350: 74 0a 20 20 20 20 23 20 20 20 20 20 20 20 77 61  t.    #       wa
1360: 69 74 22 2e 0a 20 20 20 20 23 0a 20 20 20 20 72  it"..    #.    r
1370: 65 74 75 72 6e 20 31 30 30 3b 20 23 20 54 4f 44  eturn 100; # TOD
1380: 4f 3a 20 47 6f 6f 64 20 64 65 66 61 75 6c 74 3f  O: Good default?
1390: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 3a  .  }.  return $:
13a0: 3a 47 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65  :G(file-retry-de
13b0: 6c 61 79 29 0a 7d 0a 0a 23 20 52 65 74 75 72 6e  lay).}..# Return
13c0: 20 74 68 65 20 73 74 72 69 6e 67 20 72 65 70 72   the string repr
13d0: 65 73 65 6e 74 69 6e 67 20 74 68 65 20 6e 61 6d  esenting the nam
13e0: 65 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74  e of the current
13f0: 20 64 69 72 65 63 74 6f 72 79 2e 20 20 4f 6e 0a   directory.  On.
1400: 23 20 57 69 6e 64 6f 77 73 2c 20 74 68 65 20 72  # Windows, the r
1410: 65 73 75 6c 74 20 69 73 20 22 6e 6f 72 6d 61 6c  esult is "normal
1420: 69 7a 65 64 22 20 74 6f 20 77 68 61 74 65 76 65  ized" to whateve
1430: 72 20 6f 75 72 20 70 61 72 65 6e 74 20 63 6f 6d  r our parent com
1440: 6d 61 6e 64 20 73 68 65 6c 6c 0a 23 20 69 73 20  mand shell.# is 
1450: 75 73 69 6e 67 20 74 6f 20 70 72 65 76 65 6e 74  using to prevent
1460: 20 63 61 73 65 2d 6d 69 73 6d 61 74 63 68 20 69   case-mismatch i
1470: 73 73 75 65 73 2e 0a 23 0a 70 72 6f 63 20 67 65  ssues..#.proc ge
1480: 74 5f 70 77 64 20 7b 7d 20 7b 0a 20 20 69 66 20  t_pwd {} {.  if 
1490: 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d  {$::tcl_platform
14a0: 28 70 6c 61 74 66 6f 72 6d 29 20 65 71 20 22 77  (platform) eq "w
14b0: 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20 20 20 23  indows"} {.    #
14c0: 0a 20 20 20 20 23 20 4e 4f 54 45 3a 20 43 61 6e  .    # NOTE: Can
14d0: 6e 6f 74 20 75 73 65 20 5b 66 69 6c 65 20 6e 6f  not use [file no
14e0: 72 6d 61 6c 69 7a 65 5d 20 68 65 72 65 20 62 65  rmalize] here be
14f0: 63 61 75 73 65 20 69 74 20 77 6f 75 6c 64 20 61  cause it would a
1500: 6c 74 65 72 20 74 68 65 0a 20 20 20 20 23 20 20  lter the.    #  
1510: 20 20 20 20 20 63 61 73 65 20 6f 66 20 74 68 65       case of the
1520: 20 72 65 73 75 6c 74 20 74 6f 20 77 68 61 74 20   result to what 
1530: 54 63 6c 20 63 6f 6e 73 69 64 65 72 73 20 63 61  Tcl considers ca
1540: 6e 6f 6e 69 63 61 6c 2c 20 77 68 69 63 68 20 77  nonical, which w
1550: 6f 75 6c 64 0a 20 20 20 20 23 20 20 20 20 20 20  ould.    #      
1560: 20 64 65 66 65 61 74 20 74 68 65 20 70 75 72 70   defeat the purp
1570: 6f 73 65 20 6f 66 20 74 68 69 73 20 70 72 6f 63  ose of this proc
1580: 65 64 75 72 65 2e 0a 20 20 20 20 23 0a 20 20 20  edure..    #.   
1590: 20 72 65 74 75 72 6e 20 5b 73 74 72 69 6e 67 20   return [string 
15a0: 6d 61 70 20 5b 6c 69 73 74 20 5c 5c 20 2f 5d 20  map [list \\ /] 
15b0: 5c 0a 20 20 20 20 20 20 20 20 5b 73 74 72 69 6e  \.        [strin
15c0: 67 20 74 72 69 6d 20 5b 65 78 65 63 20 2d 2d 20  g trim [exec -- 
15d0: 24 3a 3a 65 6e 76 28 43 6f 6d 53 70 65 63 29 20  $::env(ComSpec) 
15e0: 2f 63 20 65 63 68 6f 20 25 43 44 25 5d 5d 5d 0a  /c echo %CD%]]].
15f0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 72    } else {.    r
1600: 65 74 75 72 6e 20 5b 70 77 64 5d 0a 20 20 7d 0a  eturn [pwd].  }.
1610: 7d 0a 0a 23 20 43 6f 70 79 20 66 69 6c 65 20 24  }..# Copy file $
1620: 66 72 6f 6d 20 69 6e 74 6f 20 24 74 6f 2e 20 54  from into $to. T
1630: 68 69 73 20 69 73 20 75 73 65 64 20 62 65 63 61  his is used beca
1640: 75 73 65 20 73 6f 6d 65 20 76 65 72 73 69 6f 6e  use some version
1650: 73 20 6f 66 0a 23 20 54 43 4c 20 66 6f 72 20 77  s of.# TCL for w
1660: 69 6e 64 6f 77 73 20 28 6e 6f 74 61 62 6c 79 20  indows (notably 
1670: 74 68 65 20 38 2e 34 2e 31 20 62 69 6e 61 72 79  the 8.4.1 binary
1680: 20 70 61 63 6b 61 67 65 20 73 68 69 70 70 65 64   package shipped
1690: 20 77 69 74 68 20 74 68 65 0a 23 20 63 75 72 72   with the.# curr
16a0: 65 6e 74 20 6d 69 6e 67 77 20 72 65 6c 65 61 73  ent mingw releas
16b0: 65 29 20 68 61 76 65 20 61 20 62 72 6f 6b 65 6e  e) have a broken
16c0: 20 22 66 69 6c 65 20 63 6f 70 79 22 20 63 6f 6d   "file copy" com
16d0: 6d 61 6e 64 2e 0a 23 0a 70 72 6f 63 20 63 6f 70  mand..#.proc cop
16e0: 79 5f 66 69 6c 65 20 7b 66 72 6f 6d 20 74 6f 7d  y_file {from to}
16f0: 20 7b 0a 20 20 64 6f 5f 63 6f 70 79 5f 66 69 6c   {.  do_copy_fil
1700: 65 20 66 61 6c 73 65 20 24 66 72 6f 6d 20 24 74  e false $from $t
1710: 6f 0a 7d 0a 0a 70 72 6f 63 20 66 6f 72 63 65 63  o.}..proc forcec
1720: 6f 70 79 20 7b 66 72 6f 6d 20 74 6f 7d 20 7b 0a  opy {from to} {.
1730: 20 20 64 6f 5f 63 6f 70 79 5f 66 69 6c 65 20 74    do_copy_file t
1740: 72 75 65 20 24 66 72 6f 6d 20 24 74 6f 0a 7d 0a  rue $from $to.}.
1750: 0a 70 72 6f 63 20 64 6f 5f 63 6f 70 79 5f 66 69  .proc do_copy_fi
1760: 6c 65 20 7b 66 6f 72 63 65 20 66 72 6f 6d 20 74  le {force from t
1770: 6f 7d 20 7b 0a 20 20 73 65 74 20 6e 52 65 74 72  o} {.  set nRetr
1780: 79 20 5b 67 65 74 46 69 6c 65 52 65 74 72 69 65  y [getFileRetrie
1790: 73 5d 20 20 20 20 20 3b 23 20 4d 61 78 69 6d 75  s]     ;# Maximu
17a0: 6d 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 74 72  m number of retr
17b0: 69 65 73 2e 0a 20 20 73 65 74 20 6e 44 65 6c 61  ies..  set nDela
17c0: 79 20 5b 67 65 74 46 69 6c 65 52 65 74 72 79 44  y [getFileRetryD
17d0: 65 6c 61 79 5d 20 20 3b 23 20 44 65 6c 61 79 20  elay]  ;# Delay 
17e0: 69 6e 20 6d 73 20 62 65 66 6f 72 65 20 72 65 74  in ms before ret
17f0: 72 79 69 6e 67 2e 0a 0a 20 20 23 20 4f 6e 20 77  rying...  # On w
1800: 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74 69 6d 65  indows, sometime
1810: 73 20 65 76 65 6e 20 61 20 5b 66 69 6c 65 20 63  s even a [file c
1820: 6f 70 79 20 2d 66 6f 72 63 65 5d 20 63 61 6e 20  opy -force] can 
1830: 66 61 69 6c 2e 20 54 68 65 20 63 61 75 73 65 20  fail. The cause 
1840: 69 73 0a 20 20 23 20 75 73 75 61 6c 6c 79 20 22  is.  # usually "
1850: 74 61 67 2d 61 6c 6f 6e 67 73 22 20 2d 20 70 72  tag-alongs" - pr
1860: 6f 67 72 61 6d 73 20 6c 69 6b 65 20 61 6e 74 69  ograms like anti
1870: 2d 76 69 72 75 73 20 73 6f 66 74 77 61 72 65 2c  -virus software,
1880: 20 61 75 74 6f 6d 61 74 69 63 20 62 61 63 6b 75   automatic backu
1890: 70 0a 20 20 23 20 74 6f 6f 6c 73 20 61 6e 64 20  p.  # tools and 
18a0: 76 61 72 69 6f 75 73 20 65 78 70 6c 6f 72 65 72  various explorer
18b0: 20 65 78 74 65 6e 73 69 6f 6e 73 20 74 68 61 74   extensions that
18c0: 20 6b 65 65 70 20 61 20 66 69 6c 65 20 6f 70 65   keep a file ope
18d0: 6e 20 61 20 6c 69 74 74 6c 65 20 6c 6f 6e 67 65  n a little longe
18e0: 72 0a 20 20 23 20 74 68 61 6e 20 77 65 20 65 78  r.  # than we ex
18f0: 70 65 63 74 2c 20 63 61 75 73 69 6e 67 20 74 68  pect, causing th
1900: 65 20 64 65 6c 65 74 65 20 74 6f 20 66 61 69 6c  e delete to fail
1910: 2e 0a 20 20 23 0a 20 20 23 20 54 68 65 20 73 6f  ..  #.  # The so
1920: 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20 77 61 69  lution is to wai
1930: 74 20 61 20 73 68 6f 72 74 20 61 6d 6f 75 6e 74  t a short amount
1940: 20 6f 66 20 74 69 6d 65 20 62 65 66 6f 72 65 20   of time before 
1950: 72 65 74 72 79 69 6e 67 20 74 68 65 20 63 6f 70  retrying the cop
1960: 79 2e 0a 20 20 23 0a 20 20 69 66 20 7b 24 6e 52  y..  #.  if {$nR
1970: 65 74 72 79 20 3e 20 30 7d 20 7b 0a 20 20 20 20  etry > 0} {.    
1980: 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24  for {set i 0} {$
1990: 69 3c 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63 72  i<$nRetry} {incr
19a0: 20 69 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20   i} {.      set 
19b0: 72 63 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20  rc [catch {.    
19c0: 20 20 20 20 69 66 20 7b 24 66 6f 72 63 65 7d 20      if {$force} 
19d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 66 69 6c 65  {.          file
19e0: 20 63 6f 70 79 20 2d 66 6f 72 63 65 20 24 66 72   copy -force $fr
19f0: 6f 6d 20 24 74 6f 0a 20 20 20 20 20 20 20 20 7d  om $to.        }
1a00: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
1a10: 20 20 66 69 6c 65 20 63 6f 70 79 20 24 66 72 6f    file copy $fro
1a20: 6d 20 24 74 6f 0a 20 20 20 20 20 20 20 20 7d 0a  m $to.        }.
1a30: 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a 20 20 20        } msg].   
1a40: 20 20 20 69 66 20 7b 24 72 63 3d 3d 30 7d 20 62     if {$rc==0} b
1a50: 72 65 61 6b 0a 20 20 20 20 20 20 69 66 20 7b 24  reak.      if {$
1a60: 6e 44 65 6c 61 79 20 3e 20 30 7d 20 7b 20 61 66  nDelay > 0} { af
1a70: 74 65 72 20 24 6e 44 65 6c 61 79 20 7d 0a 20 20  ter $nDelay }.  
1a80: 20 20 7d 0a 20 20 20 20 69 66 20 7b 24 72 63 7d    }.    if {$rc}
1a90: 20 7b 20 65 72 72 6f 72 20 24 6d 73 67 20 7d 0a   { error $msg }.
1aa0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 69    } else {.    i
1ab0: 66 20 7b 24 66 6f 72 63 65 7d 20 7b 0a 20 20 20  f {$force} {.   
1ac0: 20 20 20 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f     file copy -fo
1ad0: 72 63 65 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20  rce $from $to.  
1ae0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
1af0: 20 66 69 6c 65 20 63 6f 70 79 20 24 66 72 6f 6d   file copy $from
1b00: 20 24 74 6f 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d   $to.    }.  }.}
1b10: 0a 0a 23 20 43 68 65 63 6b 20 69 66 20 61 20 66  ..# Check if a f
1b20: 69 6c 65 20 6e 61 6d 65 20 69 73 20 72 65 6c 61  ile name is rela
1b30: 74 69 76 65 0a 23 0a 70 72 6f 63 20 69 73 5f 72  tive.#.proc is_r
1b40: 65 6c 61 74 69 76 65 5f 66 69 6c 65 20 7b 20 66  elative_file { f
1b50: 69 6c 65 20 7d 20 7b 0a 20 20 72 65 74 75 72 6e  ile } {.  return
1b60: 20 5b 65 78 70 72 20 7b 5b 66 69 6c 65 20 70 61   [expr {[file pa
1b70: 74 68 74 79 70 65 20 24 66 69 6c 65 5d 20 21 3d  thtype $file] !=
1b80: 20 22 61 62 73 6f 6c 75 74 65 22 7d 5d 0a 7d 0a   "absolute"}].}.
1b90: 0a 23 20 49 66 20 74 68 65 20 56 46 53 20 73 75  .# If the VFS su
1ba0: 70 70 6f 72 74 73 20 75 73 69 6e 67 20 74 68 65  pports using the
1bb0: 20 63 75 72 72 65 6e 74 20 64 69 72 65 63 74 6f   current directo
1bc0: 72 79 2c 20 72 65 74 75 72 6e 73 20 5b 70 77 64  ry, returns [pwd
1bd0: 5d 3b 0a 23 20 6f 74 68 65 72 77 69 73 65 2c 20  ];.# otherwise, 
1be0: 69 74 20 72 65 74 75 72 6e 73 20 6f 6e 6c 79 20  it returns only 
1bf0: 74 68 65 20 70 72 6f 76 69 64 65 64 20 73 75 66  the provided suf
1c00: 66 69 78 20 73 74 72 69 6e 67 20 28 77 68 69 63  fix string (whic
1c10: 68 20 69 73 0a 23 20 65 6d 70 74 79 20 62 79 20  h is.# empty by 
1c20: 64 65 66 61 75 6c 74 29 2e 0a 23 0a 70 72 6f 63  default)..#.proc
1c30: 20 74 65 73 74 5f 70 77 64 20 7b 20 61 72 67 73   test_pwd { args
1c40: 20 7d 20 7b 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e   } {.  if {[llen
1c50: 67 74 68 20 24 61 72 67 73 5d 20 3e 20 30 7d 20  gth $args] > 0} 
1c60: 7b 0a 20 20 20 20 73 65 74 20 73 75 66 66 69 78  {.    set suffix
1c70: 31 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20  1 [lindex $args 
1c80: 30 5d 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e  0].    if {[llen
1c90: 67 74 68 20 24 61 72 67 73 5d 20 3e 20 31 7d 20  gth $args] > 1} 
1ca0: 7b 0a 20 20 20 20 20 20 73 65 74 20 73 75 66 66  {.      set suff
1cb0: 69 78 32 20 5b 6c 69 6e 64 65 78 20 24 61 72 67  ix2 [lindex $arg
1cc0: 73 20 31 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20  s 1].    } else 
1cd0: 7b 0a 20 20 20 20 20 20 73 65 74 20 73 75 66 66  {.      set suff
1ce0: 69 78 32 20 24 73 75 66 66 69 78 31 0a 20 20 20  ix2 $suffix1.   
1cf0: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
1d00: 20 20 73 65 74 20 73 75 66 66 69 78 31 20 22 22    set suffix1 ""
1d10: 3b 20 73 65 74 20 73 75 66 66 69 78 32 20 22 22  ; set suffix2 ""
1d20: 0a 20 20 7d 0a 20 20 69 66 63 61 70 61 62 6c 65  .  }.  ifcapable
1d30: 20 63 75 72 64 69 72 20 7b 0a 20 20 20 20 72 65   curdir {.    re
1d40: 74 75 72 6e 20 22 5b 67 65 74 5f 70 77 64 5d 24  turn "[get_pwd]$
1d50: 73 75 66 66 69 78 31 22 0a 20 20 7d 20 65 6c 73  suffix1".  } els
1d60: 65 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 24  e {.    return $
1d70: 73 75 66 66 69 78 32 0a 20 20 7d 0a 7d 0a 0a 23  suffix2.  }.}..#
1d80: 20 44 65 6c 65 74 65 20 61 20 66 69 6c 65 20 6f   Delete a file o
1d90: 72 20 64 69 72 65 63 74 6f 72 79 0a 23 0a 70 72  r directory.#.pr
1da0: 6f 63 20 64 65 6c 65 74 65 5f 66 69 6c 65 20 7b  oc delete_file {
1db0: 61 72 67 73 7d 20 7b 0a 20 20 64 6f 5f 64 65 6c  args} {.  do_del
1dc0: 65 74 65 5f 66 69 6c 65 20 66 61 6c 73 65 20 7b  ete_file false {
1dd0: 2a 7d 24 61 72 67 73 0a 7d 0a 0a 70 72 6f 63 20  *}$args.}..proc 
1de0: 66 6f 72 63 65 64 65 6c 65 74 65 20 7b 61 72 67  forcedelete {arg
1df0: 73 7d 20 7b 0a 20 20 64 6f 5f 64 65 6c 65 74 65  s} {.  do_delete
1e00: 5f 66 69 6c 65 20 74 72 75 65 20 7b 2a 7d 24 61  _file true {*}$a
1e10: 72 67 73 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 64  rgs.}..proc do_d
1e20: 65 6c 65 74 65 5f 66 69 6c 65 20 7b 66 6f 72 63  elete_file {forc
1e30: 65 20 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20  e args} {.  set 
1e40: 6e 52 65 74 72 79 20 5b 67 65 74 46 69 6c 65 52  nRetry [getFileR
1e50: 65 74 72 69 65 73 5d 20 20 20 20 20 3b 23 20 4d  etries]     ;# M
1e60: 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66  aximum number of
1e70: 20 72 65 74 72 69 65 73 2e 0a 20 20 73 65 74 20   retries..  set 
1e80: 6e 44 65 6c 61 79 20 5b 67 65 74 46 69 6c 65 52  nDelay [getFileR
1e90: 65 74 72 79 44 65 6c 61 79 5d 20 20 3b 23 20 44  etryDelay]  ;# D
1ea0: 65 6c 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72  elay in ms befor
1eb0: 65 20 72 65 74 72 79 69 6e 67 2e 0a 0a 20 20 66  e retrying...  f
1ec0: 6f 72 65 61 63 68 20 66 69 6c 65 6e 61 6d 65 20  oreach filename 
1ed0: 24 61 72 67 73 20 7b 0a 20 20 20 20 23 20 4f 6e  $args {.    # On
1ee0: 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74 69   windows, someti
1ef0: 6d 65 73 20 65 76 65 6e 20 61 20 5b 66 69 6c 65  mes even a [file
1f00: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 5d 20   delete -force] 
1f10: 63 61 6e 20 66 61 69 6c 20 6a 75 73 74 20 61 66  can fail just af
1f20: 74 65 72 0a 20 20 20 20 23 20 61 20 66 69 6c 65  ter.    # a file
1f30: 20 69 73 20 63 6c 6f 73 65 64 2e 20 54 68 65 20   is closed. The 
1f40: 63 61 75 73 65 20 69 73 20 75 73 75 61 6c 6c 79  cause is usually
1f50: 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22 20 2d 20   "tag-alongs" - 
1f60: 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65 0a 20 20  programs like.  
1f70: 20 20 23 20 61 6e 74 69 2d 76 69 72 75 73 20 73    # anti-virus s
1f80: 6f 66 74 77 61 72 65 2c 20 61 75 74 6f 6d 61 74  oftware, automat
1f90: 69 63 20 62 61 63 6b 75 70 20 74 6f 6f 6c 73 20  ic backup tools 
1fa0: 61 6e 64 20 76 61 72 69 6f 75 73 20 65 78 70 6c  and various expl
1fb0: 6f 72 65 72 0a 20 20 20 20 23 20 65 78 74 65 6e  orer.    # exten
1fc0: 73 69 6f 6e 73 20 74 68 61 74 20 6b 65 65 70 20  sions that keep 
1fd0: 61 20 66 69 6c 65 20 6f 70 65 6e 20 61 20 6c 69  a file open a li
1fe0: 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74 68 61 6e  ttle longer than
1ff0: 20 77 65 20 65 78 70 65 63 74 2c 20 63 61 75 73   we expect, caus
2000: 69 6e 67 0a 20 20 20 20 23 20 74 68 65 20 64 65  ing.    # the de
2010: 6c 65 74 65 20 74 6f 20 66 61 69 6c 2e 0a 20 20  lete to fail..  
2020: 20 20 23 0a 20 20 20 20 23 20 54 68 65 20 73 6f    #.    # The so
2030: 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20 77 61 69  lution is to wai
2040: 74 20 61 20 73 68 6f 72 74 20 61 6d 6f 75 6e 74  t a short amount
2050: 20 6f 66 20 74 69 6d 65 20 62 65 66 6f 72 65 20   of time before 
2060: 72 65 74 72 79 69 6e 67 20 74 68 65 0a 20 20 20  retrying the.   
2070: 20 23 20 64 65 6c 65 74 65 2e 0a 20 20 20 20 23   # delete..    #
2080: 0a 20 20 20 20 69 66 20 7b 24 6e 52 65 74 72 79  .    if {$nRetry
2090: 20 3e 20 30 7d 20 7b 0a 20 20 20 20 20 20 66 6f   > 0} {.      fo
20a0: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c  r {set i 0} {$i<
20b0: 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63 72 20 69  $nRetry} {incr i
20c0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  } {.        set 
20d0: 72 63 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20  rc [catch {.    
20e0: 20 20 20 20 20 20 69 66 20 7b 24 66 6f 72 63 65        if {$force
20f0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  } {.            
2100: 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72  file delete -for
2110: 63 65 20 24 66 69 6c 65 6e 61 6d 65 0a 20 20 20  ce $filename.   
2120: 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a         } else {.
2130: 20 20 20 20 20 20 20 20 20 20 20 20 66 69 6c 65              file
2140: 20 64 65 6c 65 74 65 20 24 66 69 6c 65 6e 61 6d   delete $filenam
2150: 65 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  e.          }.  
2160: 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a 20 20 20        } msg].   
2170: 20 20 20 20 20 69 66 20 7b 24 72 63 3d 3d 30 7d       if {$rc==0}
2180: 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 69   break.        i
2190: 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20 30 7d 20  f {$nDelay > 0} 
21a0: 7b 20 61 66 74 65 72 20 24 6e 44 65 6c 61 79 20  { after $nDelay 
21b0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
21c0: 69 66 20 7b 24 72 63 7d 20 7b 20 65 72 72 6f 72  if {$rc} { error
21d0: 20 24 6d 73 67 20 7d 0a 20 20 20 20 7d 20 65 6c   $msg }.    } el
21e0: 73 65 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 24  se {.      if {$
21f0: 66 6f 72 63 65 7d 20 7b 0a 20 20 20 20 20 20 20  force} {.       
2200: 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f   file delete -fo
2210: 72 63 65 20 24 66 69 6c 65 6e 61 6d 65 0a 20 20  rce $filename.  
2220: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
2230: 20 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65       file delete
2240: 20 24 66 69 6c 65 6e 61 6d 65 0a 20 20 20 20 20   $filename.     
2250: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a   }.    }.  }.}..
2260: 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  if {$::tcl_platf
2270: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 20 65 71  orm(platform) eq
2280: 20 22 77 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20   "windows"} {.  
2290: 70 72 6f 63 20 64 6f 5f 72 65 6d 6f 76 65 5f 77  proc do_remove_w
22a0: 69 6e 33 32 5f 64 69 72 20 7b 61 72 67 73 7d 20  in32_dir {args} 
22b0: 7b 0a 20 20 20 20 73 65 74 20 6e 52 65 74 72 79  {.    set nRetry
22c0: 20 5b 67 65 74 46 69 6c 65 52 65 74 72 69 65 73   [getFileRetries
22d0: 5d 20 20 20 20 20 3b 23 20 4d 61 78 69 6d 75 6d  ]     ;# Maximum
22e0: 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 74 72 69   number of retri
22f0: 65 73 2e 0a 20 20 20 20 73 65 74 20 6e 44 65 6c  es..    set nDel
2300: 61 79 20 5b 67 65 74 46 69 6c 65 52 65 74 72 79  ay [getFileRetry
2310: 44 65 6c 61 79 5d 20 20 3b 23 20 44 65 6c 61 79  Delay]  ;# Delay
2320: 20 69 6e 20 6d 73 20 62 65 66 6f 72 65 20 72 65   in ms before re
2330: 74 72 79 69 6e 67 2e 0a 0a 20 20 20 20 66 6f 72  trying...    for
2340: 65 61 63 68 20 64 69 72 4e 61 6d 65 20 24 61 72  each dirName $ar
2350: 67 73 20 7b 0a 20 20 20 20 20 20 23 20 4f 6e 20  gs {.      # On 
2360: 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74 69 6d  windows, sometim
2370: 65 73 20 65 76 65 6e 20 61 20 5b 72 65 6d 6f 76  es even a [remov
2380: 65 5f 77 69 6e 33 32 5f 64 69 72 5d 20 63 61 6e  e_win32_dir] can
2390: 20 66 61 69 6c 20 6a 75 73 74 20 61 66 74 65 72   fail just after
23a0: 0a 20 20 20 20 20 20 23 20 61 20 64 69 72 65 63  .      # a direc
23b0: 74 6f 72 79 20 69 73 20 65 6d 70 74 69 65 64 2e  tory is emptied.
23c0: 20 54 68 65 20 63 61 75 73 65 20 69 73 20 75 73   The cause is us
23d0: 75 61 6c 6c 79 20 22 74 61 67 2d 61 6c 6f 6e 67  ually "tag-along
23e0: 73 22 20 2d 20 70 72 6f 67 72 61 6d 73 0a 20 20  s" - programs.  
23f0: 20 20 20 20 23 20 6c 69 6b 65 20 61 6e 74 69 2d      # like anti-
2400: 76 69 72 75 73 20 73 6f 66 74 77 61 72 65 2c 20  virus software, 
2410: 61 75 74 6f 6d 61 74 69 63 20 62 61 63 6b 75 70  automatic backup
2420: 20 74 6f 6f 6c 73 20 61 6e 64 20 76 61 72 69 6f   tools and vario
2430: 75 73 20 65 78 70 6c 6f 72 65 72 0a 20 20 20 20  us explorer.    
2440: 20 20 23 20 65 78 74 65 6e 73 69 6f 6e 73 20 74    # extensions t
2450: 68 61 74 20 6b 65 65 70 20 61 20 66 69 6c 65 20  hat keep a file 
2460: 6f 70 65 6e 20 61 20 6c 69 74 74 6c 65 20 6c 6f  open a little lo
2470: 6e 67 65 72 20 74 68 61 6e 20 77 65 20 65 78 70  nger than we exp
2480: 65 63 74 2c 0a 20 20 20 20 20 20 23 20 63 61 75  ect,.      # cau
2490: 73 69 6e 67 20 74 68 65 20 64 65 6c 65 74 65 20  sing the delete 
24a0: 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 20 20 23  to fail..      #
24b0: 0a 20 20 20 20 20 20 23 20 54 68 65 20 73 6f 6c  .      # The sol
24c0: 75 74 69 6f 6e 20 69 73 20 74 6f 20 77 61 69 74  ution is to wait
24d0: 20 61 20 73 68 6f 72 74 20 61 6d 6f 75 6e 74 20   a short amount 
24e0: 6f 66 20 74 69 6d 65 20 62 65 66 6f 72 65 20 72  of time before r
24f0: 65 74 72 79 69 6e 67 20 74 68 65 0a 20 20 20 20  etrying the.    
2500: 20 20 23 20 72 65 6d 6f 76 61 6c 2e 0a 20 20 20    # removal..   
2510: 20 20 20 23 0a 20 20 20 20 20 20 69 66 20 7b 24     #.      if {$
2520: 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b 0a 20 20  nRetry > 0} {.  
2530: 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69        for {set i
2540: 20 30 7d 20 7b 24 69 20 3c 20 24 6e 52 65 74 72   0} {$i < $nRetr
2550: 79 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  y} {incr i} {.  
2560: 20 20 20 20 20 20 20 20 73 65 74 20 72 63 20 5b          set rc [
2570: 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20 20 20  catch {.        
2580: 20 20 20 20 72 65 6d 6f 76 65 5f 77 69 6e 33 32      remove_win32
2590: 5f 64 69 72 20 24 64 69 72 4e 61 6d 65 0a 20 20  _dir $dirName.  
25a0: 20 20 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a 20          } msg]. 
25b0: 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 72 63           if {$rc
25c0: 20 3d 3d 20 30 7d 20 62 72 65 61 6b 0a 20 20 20   == 0} break.   
25d0: 20 20 20 20 20 20 20 69 66 20 7b 24 6e 44 65 6c         if {$nDel
25e0: 61 79 20 3e 20 30 7d 20 7b 20 61 66 74 65 72 20  ay > 0} { after 
25f0: 24 6e 44 65 6c 61 79 20 7d 0a 20 20 20 20 20 20  $nDelay }.      
2600: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 20 7b    }.        if {
2610: 24 72 63 7d 20 7b 20 65 72 72 6f 72 20 24 6d 73  $rc} { error $ms
2620: 67 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73 65  g }.      } else
2630: 20 7b 0a 20 20 20 20 20 20 20 20 72 65 6d 6f 76   {.        remov
2640: 65 5f 77 69 6e 33 32 5f 64 69 72 20 24 64 69 72  e_win32_dir $dir
2650: 4e 61 6d 65 0a 20 20 20 20 20 20 7d 0a 20 20 20  Name.      }.   
2660: 20 7d 0a 20 20 7d 0a 0a 20 20 70 72 6f 63 20 64   }.  }..  proc d
2670: 6f 5f 64 65 6c 65 74 65 5f 77 69 6e 33 32 5f 66  o_delete_win32_f
2680: 69 6c 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 20  ile {args} {.   
2690: 20 73 65 74 20 6e 52 65 74 72 79 20 5b 67 65 74   set nRetry [get
26a0: 46 69 6c 65 52 65 74 72 69 65 73 5d 20 20 20 20  FileRetries]    
26b0: 20 3b 23 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62   ;# Maximum numb
26c0: 65 72 20 6f 66 20 72 65 74 72 69 65 73 2e 0a 20  er of retries.. 
26d0: 20 20 20 73 65 74 20 6e 44 65 6c 61 79 20 5b 67     set nDelay [g
26e0: 65 74 46 69 6c 65 52 65 74 72 79 44 65 6c 61 79  etFileRetryDelay
26f0: 5d 20 20 3b 23 20 44 65 6c 61 79 20 69 6e 20 6d  ]  ;# Delay in m
2700: 73 20 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e  s before retryin
2710: 67 2e 0a 0a 20 20 20 20 66 6f 72 65 61 63 68 20  g...    foreach 
2720: 66 69 6c 65 4e 61 6d 65 20 24 61 72 67 73 20 7b  fileName $args {
2730: 0a 20 20 20 20 20 20 23 20 4f 6e 20 77 69 6e 64  .      # On wind
2740: 6f 77 73 2c 20 73 6f 6d 65 74 69 6d 65 73 20 65  ows, sometimes e
2750: 76 65 6e 20 61 20 5b 64 65 6c 65 74 65 5f 77 69  ven a [delete_wi
2760: 6e 33 32 5f 66 69 6c 65 5d 20 63 61 6e 20 66 61  n32_file] can fa
2770: 69 6c 20 6a 75 73 74 20 61 66 74 65 72 0a 20 20  il just after.  
2780: 20 20 20 20 23 20 61 20 66 69 6c 65 20 69 73 20      # a file is 
2790: 63 6c 6f 73 65 64 2e 20 54 68 65 20 63 61 75 73  closed. The caus
27a0: 65 20 69 73 20 75 73 75 61 6c 6c 79 20 22 74 61  e is usually "ta
27b0: 67 2d 61 6c 6f 6e 67 73 22 20 2d 20 70 72 6f 67  g-alongs" - prog
27c0: 72 61 6d 73 20 6c 69 6b 65 0a 20 20 20 20 20 20  rams like.      
27d0: 23 20 61 6e 74 69 2d 76 69 72 75 73 20 73 6f 66  # anti-virus sof
27e0: 74 77 61 72 65 2c 20 61 75 74 6f 6d 61 74 69 63  tware, automatic
27f0: 20 62 61 63 6b 75 70 20 74 6f 6f 6c 73 20 61 6e   backup tools an
2800: 64 20 76 61 72 69 6f 75 73 20 65 78 70 6c 6f 72  d various explor
2810: 65 72 0a 20 20 20 20 20 20 23 20 65 78 74 65 6e  er.      # exten
2820: 73 69 6f 6e 73 20 74 68 61 74 20 6b 65 65 70 20  sions that keep 
2830: 61 20 66 69 6c 65 20 6f 70 65 6e 20 61 20 6c 69  a file open a li
2840: 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74 68 61 6e  ttle longer than
2850: 20 77 65 20 65 78 70 65 63 74 2c 0a 20 20 20 20   we expect,.    
2860: 20 20 23 20 63 61 75 73 69 6e 67 20 74 68 65 20    # causing the 
2870: 64 65 6c 65 74 65 20 74 6f 20 66 61 69 6c 2e 0a  delete to fail..
2880: 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 23 20        #.      # 
2890: 54 68 65 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20  The solution is 
28a0: 74 6f 20 77 61 69 74 20 61 20 73 68 6f 72 74 20  to wait a short 
28b0: 61 6d 6f 75 6e 74 20 6f 66 20 74 69 6d 65 20 62  amount of time b
28c0: 65 66 6f 72 65 20 72 65 74 72 79 69 6e 67 20 74  efore retrying t
28d0: 68 65 0a 20 20 20 20 20 20 23 20 64 65 6c 65 74  he.      # delet
28e0: 65 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20  e..      #.     
28f0: 20 69 66 20 7b 24 6e 52 65 74 72 79 20 3e 20 30   if {$nRetry > 0
2900: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 20  } {.        for 
2910: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20  {set i 0} {$i < 
2920: 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63 72 20 69  $nRetry} {incr i
2930: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65  } {.          se
2940: 74 20 72 63 20 5b 63 61 74 63 68 20 7b 0a 20 20  t rc [catch {.  
2950: 20 20 20 20 20 20 20 20 20 20 64 65 6c 65 74 65            delete
2960: 5f 77 69 6e 33 32 5f 66 69 6c 65 20 24 66 69 6c  _win32_file $fil
2970: 65 4e 61 6d 65 0a 20 20 20 20 20 20 20 20 20 20  eName.          
2980: 7d 20 6d 73 67 5d 0a 20 20 20 20 20 20 20 20 20  } msg].         
2990: 20 69 66 20 7b 24 72 63 20 3d 3d 20 30 7d 20 62   if {$rc == 0} b
29a0: 72 65 61 6b 0a 20 20 20 20 20 20 20 20 20 20 69  reak.          i
29b0: 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20 30 7d 20  f {$nDelay > 0} 
29c0: 7b 20 61 66 74 65 72 20 24 6e 44 65 6c 61 79 20  { after $nDelay 
29d0: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
29e0: 20 20 20 20 69 66 20 7b 24 72 63 7d 20 7b 20 65      if {$rc} { e
29f0: 72 72 6f 72 20 24 6d 73 67 20 7d 0a 20 20 20 20  rror $msg }.    
2a00: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
2a10: 20 20 20 64 65 6c 65 74 65 5f 77 69 6e 33 32 5f     delete_win32_
2a20: 66 69 6c 65 20 24 66 69 6c 65 4e 61 6d 65 0a 20  file $fileName. 
2a30: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2a40: 0a 7d 0a 0a 70 72 6f 63 20 65 78 65 63 70 72 65  .}..proc execpre
2a50: 73 71 6c 20 7b 68 61 6e 64 6c 65 20 61 72 67 73  sql {handle args
2a60: 7d 20 7b 0a 20 20 74 72 61 63 65 20 72 65 6d 6f  } {.  trace remo
2a70: 76 65 20 65 78 65 63 75 74 69 6f 6e 20 24 68 61  ve execution $ha
2a80: 6e 64 6c 65 20 65 6e 74 65 72 20 5b 6c 69 73 74  ndle enter [list
2a90: 20 65 78 65 63 70 72 65 73 71 6c 20 24 68 61 6e   execpresql $han
2aa0: 64 6c 65 5d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f  dle].  if {[info
2ab0: 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72 6d   exists ::G(perm
2ac0: 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a 20 20 20  :presql)]} {.   
2ad0: 20 24 68 61 6e 64 6c 65 20 65 76 61 6c 20 24 3a   $handle eval $:
2ae0: 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c 29 0a  :G(perm:presql).
2af0: 20 20 7d 0a 7d 0a 0a 23 20 54 68 69 73 20 63 6f    }.}..# This co
2b00: 6d 6d 61 6e 64 20 73 68 6f 75 6c 64 20 62 65 20  mmand should be 
2b10: 63 61 6c 6c 65 64 20 61 66 74 65 72 20 6c 6f 61  called after loa
2b20: 64 69 6e 67 20 74 65 73 74 65 72 2e 74 63 6c 20  ding tester.tcl 
2b30: 66 72 6f 6d 20 77 69 74 68 69 6e 0a 23 20 61 6c  from within.# al
2b40: 6c 20 74 65 73 74 20 73 63 72 69 70 74 73 20 74  l test scripts t
2b50: 68 61 74 20 61 72 65 20 69 6e 63 6f 6d 70 61 74  hat are incompat
2b60: 69 62 6c 65 20 77 69 74 68 20 65 6e 63 72 79 70  ible with encryp
2b70: 74 69 6f 6e 20 63 6f 64 65 63 73 2e 0a 23 0a 70  tion codecs..#.p
2b80: 72 6f 63 20 64 6f 5f 6e 6f 74 5f 75 73 65 5f 63  roc do_not_use_c
2b90: 6f 64 65 63 20 7b 7d 20 7b 0a 20 20 73 65 74 20  odec {} {.  set 
2ba0: 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f 63 6f 64  ::do_not_use_cod
2bb0: 65 63 20 31 0a 20 20 72 65 73 65 74 5f 64 62 0a  ec 1.  reset_db.
2bc0: 7d 0a 0a 23 20 52 65 74 75 72 6e 20 74 72 75 65  }..# Return true
2bd0: 20 69 66 20 74 68 65 20 22 72 65 73 65 72 76 65   if the "reserve
2be0: 64 5f 62 79 74 65 73 22 20 69 6e 74 65 67 65 72  d_bytes" integer
2bf0: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c   on database fil
2c00: 65 73 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a  es is non-zero..
2c10: 23 0a 70 72 6f 63 20 6e 6f 6e 7a 65 72 6f 5f 72  #.proc nonzero_r
2c20: 65 73 65 72 76 65 64 5f 62 79 74 65 73 20 7b 7d  eserved_bytes {}
2c30: 20 7b 0a 20 20 72 65 74 75 72 6e 20 5b 73 71 6c   {.  return [sql
2c40: 69 74 65 33 20 2d 68 61 73 2d 63 6f 64 65 63 5d  ite3 -has-codec]
2c50: 0a 7d 0a 0a 23 20 50 72 69 6e 74 20 61 20 48 45  .}..# Print a HE
2c60: 4c 50 20 6d 65 73 73 61 67 65 20 61 6e 64 20 65  LP message and e
2c70: 78 69 74 0a 23 0a 70 72 6f 63 20 70 72 69 6e 74  xit.#.proc print
2c80: 5f 68 65 6c 70 5f 61 6e 64 5f 71 75 69 74 20 7b  _help_and_quit {
2c90: 7d 20 7b 0a 20 20 70 75 74 73 20 7b 4f 70 74 69  } {.  puts {Opti
2ca0: 6f 6e 73 3a 0a 20 20 2d 2d 70 61 75 73 65 20 20  ons:.  --pause  
2cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2cc0: 57 61 69 74 20 66 6f 72 20 75 73 65 72 20 69 6e  Wait for user in
2cd0: 70 75 74 20 62 65 66 6f 72 65 20 63 6f 6e 74 69  put before conti
2ce0: 6e 75 69 6e 67 0a 20 20 2d 2d 73 6f 66 74 2d 68  nuing.  --soft-h
2cf0: 65 61 70 2d 6c 69 6d 69 74 3d 4e 20 20 20 20 20  eap-limit=N     
2d00: 20 53 65 74 20 74 68 65 20 73 6f 66 74 2d 68 65   Set the soft-he
2d10: 61 70 2d 6c 69 6d 69 74 20 74 6f 20 4e 0a 20 20  ap-limit to N.  
2d20: 2d 2d 6d 61 78 65 72 72 6f 72 3d 4e 20 20 20 20  --maxerror=N    
2d30: 20 20 20 20 20 20 20 20 20 51 75 69 74 20 61 66           Quit af
2d40: 74 65 72 20 4e 20 65 72 72 6f 72 73 0a 20 20 2d  ter N errors.  -
2d50: 2d 76 65 72 62 6f 73 65 3d 28 30 7c 31 29 20 20  -verbose=(0|1)  
2d60: 20 20 20 20 20 20 20 20 43 6f 6e 74 72 6f 6c 20          Control 
2d70: 74 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 6f 75  the amount of ou
2d80: 74 70 75 74 2e 20 20 44 65 66 61 75 6c 74 20 27  tput.  Default '
2d90: 31 27 0a 20 20 2d 2d 6f 75 74 70 75 74 3d 46 49  1'.  --output=FI
2da0: 4c 45 20 20 20 20 20 20 20 20 20 20 20 20 73 65  LE            se
2db0: 74 20 2d 2d 76 65 72 62 6f 73 65 3d 32 20 61 6e  t --verbose=2 an
2dc0: 64 20 6f 75 74 70 75 74 20 74 6f 20 46 49 4c 45  d output to FILE
2dd0: 2e 20 20 49 6d 70 6c 69 65 73 20 2d 71 0a 20 20  .  Implies -q.  
2de0: 2d 71 20 20 20 20 20 20 20 20 20 20 20 20 20 20  -q              
2df0: 20 20 20 20 20 20 20 20 20 53 68 6f 72 74 68 61           Shortha
2e00: 6e 64 20 66 6f 72 20 2d 2d 76 65 72 62 6f 73 65  nd for --verbose
2e10: 3d 30 0a 20 20 2d 2d 68 65 6c 70 20 20 20 20 20  =0.  --help     
2e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 68                Th
2e30: 69 73 20 6d 65 73 73 61 67 65 0a 7d 0a 20 20 65  is message.}.  e
2e40: 78 69 74 20 31 0a 7d 0a 0a 23 20 54 68 65 20 66  xit 1.}..# The f
2e50: 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 6f  ollowing block o
2e60: 6e 6c 79 20 72 75 6e 73 20 74 68 65 20 66 69 72  nly runs the fir
2e70: 73 74 20 74 69 6d 65 20 74 68 69 73 20 66 69 6c  st time this fil
2e80: 65 20 69 73 20 73 6f 75 72 63 65 64 2e 20 49 74  e is sourced. It
2e90: 0a 23 20 64 6f 65 73 20 6e 6f 74 20 72 75 6e 20  .# does not run 
2ea0: 69 6e 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72  in slave interpr
2eb0: 65 74 65 72 73 20 28 73 69 6e 63 65 20 74 68 65  eters (since the
2ec0: 20 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 61 72   ::cmdlinearg ar
2ed0: 72 61 79 20 69 73 0a 23 20 70 6f 70 75 6c 61 74  ray is.# populat
2ee0: 65 64 20 62 65 66 6f 72 65 20 74 68 65 20 74 65  ed before the te
2ef0: 73 74 20 73 63 72 69 70 74 20 69 73 20 72 75 6e  st script is run
2f00: 20 69 6e 20 73 6c 61 76 65 20 69 6e 74 65 72 70   in slave interp
2f10: 72 65 74 65 72 73 29 2e 0a 23 0a 69 66 20 7b 5b  reters)..#.if {[
2f20: 69 6e 66 6f 20 65 78 69 73 74 73 20 63 6d 64 6c  info exists cmdl
2f30: 69 6e 65 61 72 67 5d 3d 3d 30 7d 20 7b 0a 0a 20  inearg]==0} {.. 
2f40: 20 23 20 50 61 72 73 65 20 61 6e 79 20 6f 70 74   # Parse any opt
2f50: 69 6f 6e 73 20 73 70 65 63 69 66 69 65 64 20 69  ions specified i
2f60: 6e 20 74 68 65 20 24 61 72 67 76 20 61 72 72 61  n the $argv arra
2f70: 79 2e 20 54 68 69 73 20 73 63 72 69 70 74 20 61  y. This script a
2f80: 63 63 65 70 74 73 20 74 68 65 0a 20 20 23 20 66  ccepts the.  # f
2f90: 6f 6c 6c 6f 77 69 6e 67 20 6f 70 74 69 6f 6e 73  ollowing options
2fa0: 3a 0a 20 20 23 0a 20 20 23 20 20 20 2d 2d 70 61  :.  #.  #   --pa
2fb0: 75 73 65 0a 20 20 23 20 20 20 2d 2d 73 6f 66 74  use.  #   --soft
2fc0: 2d 68 65 61 70 2d 6c 69 6d 69 74 3d 4e 4e 0a 20  -heap-limit=NN. 
2fd0: 20 23 20 20 20 2d 2d 6d 61 78 65 72 72 6f 72 3d   #   --maxerror=
2fe0: 4e 4e 0a 20 20 23 20 20 20 2d 2d 6d 61 6c 6c 6f  NN.  #   --mallo
2ff0: 63 74 72 61 63 65 3d 4e 0a 20 20 23 20 20 20 2d  ctrace=N.  #   -
3000: 2d 62 61 63 6b 74 72 61 63 65 3d 4e 0a 20 20 23  -backtrace=N.  #
3010: 20 20 20 2d 2d 62 69 6e 61 72 79 6c 6f 67 3d 4e     --binarylog=N
3020: 0a 20 20 23 20 20 20 2d 2d 73 6f 61 6b 3d 4e 0a  .  #   --soak=N.
3030: 20 20 23 20 20 20 2d 2d 66 69 6c 65 2d 72 65 74    #   --file-ret
3040: 72 69 65 73 3d 4e 0a 20 20 23 20 20 20 2d 2d 66  ries=N.  #   --f
3050: 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79 3d  ile-retry-delay=
3060: 4e 0a 20 20 23 20 20 20 2d 2d 73 74 61 72 74 3d  N.  #   --start=
3070: 5b 24 70 65 72 6d 75 74 61 74 69 6f 6e 3a 5d 24  [$permutation:]$
3080: 74 65 73 74 66 69 6c 65 0a 20 20 23 20 20 20 2d  testfile.  #   -
3090: 2d 6d 61 74 63 68 3d 24 70 61 74 74 65 72 6e 0a  -match=$pattern.
30a0: 20 20 23 20 20 20 2d 2d 76 65 72 62 6f 73 65 3d    #   --verbose=
30b0: 24 76 61 6c 0a 20 20 23 20 20 20 2d 2d 6f 75 74  $val.  #   --out
30c0: 70 75 74 3d 24 66 69 6c 65 6e 61 6d 65 0a 20 20  put=$filename.  
30d0: 23 20 20 20 2d 71 20 20 20 20 20 20 20 20 20 20  #   -q          
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f0: 20 20 20 20 20 20 20 20 20 20 20 20 52 65 64 75              Redu
3100: 63 65 20 6f 75 74 70 75 74 0a 20 20 23 20 20 20  ce output.  #   
3110: 2d 2d 74 65 73 74 64 69 72 3d 24 64 69 72 20 20  --testdir=$dir  
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3130: 20 20 20 20 20 20 20 20 52 75 6e 20 74 65 73 74          Run test
3140: 73 20 69 6e 20 73 75 62 64 69 72 65 63 74 6f 72  s in subdirector
3150: 79 20 24 64 69 72 0a 20 20 23 20 20 20 2d 2d 68  y $dir.  #   --h
3160: 65 6c 70 0a 20 20 23 0a 20 20 73 65 74 20 63 6d  elp.  #.  set cm
3170: 64 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65  dlinearg(soft-he
3180: 61 70 2d 6c 69 6d 69 74 29 20 20 20 20 30 0a 20  ap-limit)    0. 
3190: 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28   set cmdlinearg(
31a0: 6d 61 78 65 72 72 6f 72 29 20 20 20 20 20 20 20  maxerror)       
31b0: 20 31 30 30 30 0a 20 20 73 65 74 20 63 6d 64 6c   1000.  set cmdl
31c0: 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61  inearg(malloctra
31d0: 63 65 29 20 20 20 20 20 20 20 20 30 0a 20 20 73  ce)        0.  s
31e0: 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 62 61  et cmdlinearg(ba
31f0: 63 6b 74 72 61 63 65 29 20 20 20 20 20 20 20 20  cktrace)        
3200: 20 31 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e   10.  set cmdlin
3210: 65 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 20  earg(binarylog) 
3220: 20 20 20 20 20 20 20 20 20 30 0a 20 20 73 65 74           0.  set
3230: 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f 61 6b   cmdlinearg(soak
3240: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
3250: 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61  0.  set cmdlinea
3260: 72 67 28 66 69 6c 65 2d 72 65 74 72 69 65 73 29  rg(file-retries)
3270: 20 20 20 20 20 20 20 30 0a 20 20 73 65 74 20 63         0.  set c
3280: 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72  mdlinearg(file-r
3290: 65 74 72 79 2d 64 65 6c 61 79 29 20 20 20 30 0a  etry-delay)   0.
32a0: 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67    set cmdlinearg
32b0: 28 73 74 61 72 74 29 20 20 20 20 20 20 20 20 20  (start)         
32c0: 20 20 20 20 22 22 0a 20 20 73 65 74 20 63 6d 64      "".  set cmd
32d0: 6c 69 6e 65 61 72 67 28 6d 61 74 63 68 29 20 20  linearg(match)  
32e0: 20 20 20 20 20 20 20 20 20 20 20 22 22 0a 20 20             "".  
32f0: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 76  set cmdlinearg(v
3300: 65 72 62 6f 73 65 29 20 20 20 20 20 20 20 20 20  erbose)         
3310: 20 20 22 22 0a 20 20 73 65 74 20 63 6d 64 6c 69    "".  set cmdli
3320: 6e 65 61 72 67 28 6f 75 74 70 75 74 29 20 20 20  nearg(output)   
3330: 20 20 20 20 20 20 20 20 20 22 22 0a 20 20 73 65           "".  se
3340: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 74 65 73  t cmdlinearg(tes
3350: 74 64 69 72 29 20 20 20 20 20 20 20 20 20 20 20  tdir)           
3360: 22 74 65 73 74 64 69 72 22 0a 0a 20 20 73 65 74  "testdir"..  set
3370: 20 6c 65 66 74 6f 76 65 72 20 5b 6c 69 73 74 5d   leftover [list]
3380: 0a 20 20 66 6f 72 65 61 63 68 20 61 20 24 61 72  .  foreach a $ar
3390: 67 76 20 7b 0a 20 20 20 20 73 77 69 74 63 68 20  gv {.    switch 
33a0: 2d 72 65 67 65 78 70 20 2d 2d 20 24 61 20 7b 0a  -regexp -- $a {.
33b0: 20 20 20 20 20 20 7b 5e 2d 2b 70 61 75 73 65 24        {^-+pause$
33c0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20 57 61  } {.        # Wa
33d0: 69 74 20 66 6f 72 20 75 73 65 72 20 69 6e 70 75  it for user inpu
33e0: 74 20 62 65 66 6f 72 65 20 63 6f 6e 74 69 6e 75  t before continu
33f0: 69 6e 67 2e 20 54 68 69 73 20 69 73 20 74 6f 20  ing. This is to 
3400: 67 69 76 65 20 74 68 65 20 75 73 65 72 20 61 6e  give the user an
3410: 0a 20 20 20 20 20 20 20 20 23 20 6f 70 70 6f 72  .        # oppor
3420: 74 75 6e 69 74 79 20 74 6f 20 63 6f 6e 6e 65 63  tunity to connec
3430: 74 20 70 72 6f 66 69 6c 69 6e 67 20 74 6f 6f 6c  t profiling tool
3440: 73 20 74 6f 20 74 68 65 20 70 72 6f 63 65 73 73  s to the process
3450: 2e 0a 20 20 20 20 20 20 20 20 70 75 74 73 20 2d  ..        puts -
3460: 6e 6f 6e 65 77 6c 69 6e 65 20 22 50 72 65 73 73  nonewline "Press
3470: 20 52 45 54 55 52 4e 20 74 6f 20 62 65 67 69 6e   RETURN to begin
3480: 2e 2e 2e 22 0a 20 20 20 20 20 20 20 20 66 6c 75  ...".        flu
3490: 73 68 20 73 74 64 6f 75 74 0a 20 20 20 20 20 20  sh stdout.      
34a0: 20 20 67 65 74 73 20 73 74 64 69 6e 0a 20 20 20    gets stdin.   
34b0: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 73     }.      {^-+s
34c0: 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d 2e  oft-heap-limit=.
34d0: 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f  +$} {.        fo
34e0: 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64  reach {dummy cmd
34f0: 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65 61  linearg(soft-hea
3500: 70 2d 6c 69 6d 69 74 29 7d 20 5b 73 70 6c 69 74  p-limit)} [split
3510: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20   $a =] break.   
3520: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 6d     }.      {^-+m
3530: 61 78 65 72 72 6f 72 3d 2e 2b 24 7d 20 7b 0a 20  axerror=.+$} {. 
3540: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
3550: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
3560: 28 6d 61 78 65 72 72 6f 72 29 7d 20 5b 73 70 6c  (maxerror)} [spl
3570: 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20  it $a =] break. 
3580: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d       }.      {^-
3590: 2b 6d 61 6c 6c 6f 63 74 72 61 63 65 3d 2e 2b 24  +malloctrace=.+$
35a0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
35b0: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
35c0: 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63  nearg(malloctrac
35d0: 65 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d  e)} [split $a =]
35e0: 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 69   break.        i
35f0: 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 6d  f {$cmdlinearg(m
3600: 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20  alloctrace)} {. 
3610: 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
3620: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74  _memdebug_log st
3630: 61 72 74 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  art.        }.  
3640: 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b      }.      {^-+
3650: 62 61 63 6b 74 72 61 63 65 3d 2e 2b 24 7d 20 7b  backtrace=.+$} {
3660: 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68  .        foreach
3670: 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61   {dummy cmdlinea
3680: 72 67 28 62 61 63 6b 74 72 61 63 65 29 7d 20 5b  rg(backtrace)} [
3690: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
36a0: 6b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  k.        sqlite
36b0: 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63 6b 74  3_memdebug_backt
36c0: 72 61 63 65 20 24 76 61 6c 75 65 0a 20 20 20 20  race $value.    
36d0: 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 62 69    }.      {^-+bi
36e0: 6e 61 72 79 6c 6f 67 3d 2e 2b 24 7d 20 7b 0a 20  narylog=.+$} {. 
36f0: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
3700: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
3710: 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 5b 73 70  (binarylog)} [sp
3720: 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a  lit $a =] break.
3730: 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64 6c          set cmdl
3740: 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f 67  inearg(binarylog
3750: 29 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a  ) [file normaliz
3760: 65 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 62 69  e $cmdlinearg(bi
3770: 6e 61 72 79 6c 6f 67 29 5d 0a 20 20 20 20 20 20  narylog)].      
3780: 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 73 6f 61 6b  }.      {^-+soak
3790: 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20  =.+$} {.        
37a0: 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63  foreach {dummy c
37b0: 6d 64 6c 69 6e 65 61 72 67 28 73 6f 61 6b 29 7d  mdlinearg(soak)}
37c0: 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72   [split $a =] br
37d0: 65 61 6b 0a 20 20 20 20 20 20 20 20 73 65 74 20  eak.        set 
37e0: 3a 3a 47 28 69 73 73 6f 61 6b 29 20 24 63 6d 64  ::G(issoak) $cmd
37f0: 6c 69 6e 65 61 72 67 28 73 6f 61 6b 29 0a 20 20  linearg(soak).  
3800: 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b      }.      {^-+
3810: 66 69 6c 65 2d 72 65 74 72 69 65 73 3d 2e 2b 24  file-retries=.+$
3820: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
3830: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
3840: 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72 69  nearg(file-retri
3850: 65 73 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  es)} [split $a =
3860: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
3870: 73 65 74 20 3a 3a 47 28 66 69 6c 65 2d 72 65 74  set ::G(file-ret
3880: 72 69 65 73 29 20 24 63 6d 64 6c 69 6e 65 61 72  ries) $cmdlinear
3890: 67 28 66 69 6c 65 2d 72 65 74 72 69 65 73 29 0a  g(file-retries).
38a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
38b0: 2d 2b 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c  -+file-retry-del
38c0: 61 79 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  ay=.+$} {.      
38d0: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
38e0: 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c 65   cmdlinearg(file
38f0: 2d 72 65 74 72 79 2d 64 65 6c 61 79 29 7d 20 5b  -retry-delay)} [
3900: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
3910: 6b 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a  k.        set ::
3920: 47 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c  G(file-retry-del
3930: 61 79 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  ay) $cmdlinearg(
3940: 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79  file-retry-delay
3950: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ).      }.      
3960: 7b 5e 2d 2b 73 74 61 72 74 3d 2e 2b 24 7d 20 7b  {^-+start=.+$} {
3970: 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68  .        foreach
3980: 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61   {dummy cmdlinea
3990: 72 67 28 73 74 61 72 74 29 7d 20 5b 73 70 6c 69  rg(start)} [spli
39a0: 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 0a 20  t $a =] break.. 
39b0: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73         set ::G(s
39c0: 74 61 72 74 3a 66 69 6c 65 29 20 24 63 6d 64 6c  tart:file) $cmdl
39d0: 69 6e 65 61 72 67 28 73 74 61 72 74 29 0a 20 20  inearg(start).  
39e0: 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78        if {[regex
39f0: 70 20 7b 28 2e 2a 29 3a 28 2e 2a 29 7d 20 24 63  p {(.*):(.*)} $c
3a00: 6d 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29  mdlinearg(start)
3a10: 20 2d 3e 20 73 2e 70 65 72 6d 20 73 2e 66 69 6c   -> s.perm s.fil
3a20: 65 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20  e]} {.          
3a30: 73 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 70 65  set ::G(start:pe
3a40: 72 6d 75 74 61 74 69 6f 6e 29 20 24 7b 73 2e 70  rmutation) ${s.p
3a50: 65 72 6d 7d 0a 20 20 20 20 20 20 20 20 20 20 73  erm}.          s
3a60: 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c  et ::G(start:fil
3a70: 65 29 20 20 20 20 20 20 20 20 24 7b 73 2e 66 69  e)        ${s.fi
3a80: 6c 65 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  le}.        }.  
3a90: 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 47 28 73        if {$::G(s
3aa0: 74 61 72 74 3a 66 69 6c 65 29 20 3d 3d 20 22 22  tart:file) == ""
3ab0: 7d 20 7b 75 6e 73 65 74 20 3a 3a 47 28 73 74 61  } {unset ::G(sta
3ac0: 72 74 3a 66 69 6c 65 29 7d 0a 20 20 20 20 20 20  rt:file)}.      
3ad0: 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 6d 61 74 63  }.      {^-+matc
3ae0: 68 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20  h=.+$} {.       
3af0: 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20   foreach {dummy 
3b00: 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 74 63 68  cmdlinearg(match
3b10: 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20  )} [split $a =] 
3b20: 62 72 65 61 6b 0a 0a 20 20 20 20 20 20 20 20 73  break..        s
3b30: 65 74 20 3a 3a 47 28 6d 61 74 63 68 29 20 24 63  et ::G(match) $c
3b40: 6d 64 6c 69 6e 65 61 72 67 28 6d 61 74 63 68 29  mdlinearg(match)
3b50: 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 3a 3a  .        if {$::
3b60: 47 28 6d 61 74 63 68 29 20 3d 3d 20 22 22 7d 20  G(match) == ""} 
3b70: 7b 75 6e 73 65 74 20 3a 3a 47 28 6d 61 74 63 68  {unset ::G(match
3b80: 29 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  )}.      }..    
3b90: 20 20 7b 5e 2d 2b 6f 75 74 70 75 74 3d 2e 2b 24    {^-+output=.+$
3ba0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
3bb0: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
3bc0: 6e 65 61 72 67 28 6f 75 74 70 75 74 29 7d 20 5b  nearg(output)} [
3bd0: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
3be0: 6b 0a 20 20 20 20 20 20 20 20 73 65 74 20 63 6d  k.        set cm
3bf0: 64 6c 69 6e 65 61 72 67 28 6f 75 74 70 75 74 29  dlinearg(output)
3c00: 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65   [file normalize
3c10: 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75 74   $cmdlinearg(out
3c20: 70 75 74 29 5d 0a 20 20 20 20 20 20 20 20 69 66  put)].        if
3c30: 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 76 65   {$cmdlinearg(ve
3c40: 72 62 6f 73 65 29 3d 3d 22 22 7d 20 7b 0a 20 20  rbose)==""} {.  
3c50: 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64 6c          set cmdl
3c60: 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 20  inearg(verbose) 
3c70: 32 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  2.        }.    
3c80: 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 76 65    }.      {^-+ve
3c90: 72 62 6f 73 65 3d 2e 2b 24 7d 20 7b 0a 20 20 20  rbose=.+$} {.   
3ca0: 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75       foreach {du
3cb0: 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 76  mmy cmdlinearg(v
3cc0: 65 72 62 6f 73 65 29 7d 20 5b 73 70 6c 69 74 20  erbose)} [split 
3cd0: 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20  $a =] break.    
3ce0: 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65      if {$cmdline
3cf0: 61 72 67 28 76 65 72 62 6f 73 65 29 3d 3d 22 66  arg(verbose)=="f
3d00: 69 6c 65 22 7d 20 7b 0a 20 20 20 20 20 20 20 20  ile"} {.        
3d10: 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67    set cmdlinearg
3d20: 28 76 65 72 62 6f 73 65 29 20 32 0a 20 20 20 20  (verbose) 2.    
3d30: 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 73      } elseif {[s
3d40: 74 72 69 6e 67 20 69 73 20 62 6f 6f 6c 65 61 6e  tring is boolean
3d50: 20 2d 73 74 72 69 63 74 20 24 63 6d 64 6c 69 6e   -strict $cmdlin
3d60: 65 61 72 67 28 76 65 72 62 6f 73 65 29 5d 3d 3d  earg(verbose)]==
3d70: 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 65  0} {.          e
3d80: 72 72 6f 72 20 22 6f 70 74 69 6f 6e 20 2d 2d 76  rror "option --v
3d90: 65 72 62 6f 73 65 3d 20 6d 75 73 74 20 62 65 20  erbose= must be 
3da0: 73 65 74 20 74 6f 20 61 20 62 6f 6f 6c 65 61 6e  set to a boolean
3db0: 20 6f 72 20 74 6f 20 5c 22 66 69 6c 65 5c 22 22   or to \"file\""
3dc0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
3dd0: 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 74 65 73   }.      {^-+tes
3de0: 74 64 69 72 3d 2e 2a 24 7d 20 7b 0a 20 20 20 20  tdir=.*$} {.    
3df0: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d      foreach {dum
3e00: 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 74 65  my cmdlinearg(te
3e10: 73 74 64 69 72 29 7d 20 5b 73 70 6c 69 74 20 24  stdir)} [split $
3e20: 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20  a =] break.     
3e30: 20 7d 0a 20 20 20 20 20 20 7b 2e 2a 68 65 6c 70   }.      {.*help
3e40: 2e 2a 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 70  .*} {.         p
3e50: 72 69 6e 74 5f 68 65 6c 70 5f 61 6e 64 5f 71 75  rint_help_and_qu
3e60: 69 74 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  it.      }.     
3e70: 20 7b 5e 2d 71 24 7d 20 7b 0a 20 20 20 20 20 20   {^-q$} {.      
3e80: 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67    set cmdlinearg
3e90: 28 6f 75 74 70 75 74 29 20 74 65 73 74 2d 6f 75  (output) test-ou
3ea0: 74 2e 74 78 74 0a 20 20 20 20 20 20 20 20 73 65  t.txt.        se
3eb0: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 76 65 72  t cmdlinearg(ver
3ec0: 62 6f 73 65 29 20 32 0a 20 20 20 20 20 20 7d 0a  bose) 2.      }.
3ed0: 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 20 7b  .      default {
3ee0: 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64  .        lappend
3ef0: 20 6c 65 66 74 6f 76 65 72 20 5b 66 69 6c 65 20   leftover [file 
3f00: 6e 6f 72 6d 61 6c 69 7a 65 20 24 61 5d 0a 20 20  normalize $a].  
3f10: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
3f20: 20 20 73 65 74 20 74 65 73 74 64 69 72 20 5b 66    set testdir [f
3f30: 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 24 74  ile normalize $t
3f40: 65 73 74 64 69 72 5d 0a 20 20 73 65 74 20 63 6d  estdir].  set cm
3f50: 64 6c 69 6e 65 61 72 67 28 54 45 53 54 46 49 58  dlinearg(TESTFIX
3f60: 54 55 52 45 5f 48 4f 4d 45 29 20 5b 70 77 64 5d  TURE_HOME) [pwd]
3f70: 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72  .  set cmdlinear
3f80: 67 28 49 4e 46 4f 5f 53 43 52 49 50 54 29 20 5b  g(INFO_SCRIPT) [
3f90: 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 5b  file normalize [
3fa0: 69 6e 66 6f 20 73 63 72 69 70 74 5d 5d 0a 20 20  info script]].  
3fb0: 73 65 74 20 61 72 67 76 30 20 5b 66 69 6c 65 20  set argv0 [file 
3fc0: 6e 6f 72 6d 61 6c 69 7a 65 20 24 61 72 67 76 30  normalize $argv0
3fd0: 5d 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65  ].  if {$cmdline
3fe0: 61 72 67 28 74 65 73 74 64 69 72 29 21 3d 22 22  arg(testdir)!=""
3ff0: 7d 20 7b 0a 20 20 20 20 66 69 6c 65 20 6d 6b 64  } {.    file mkd
4000: 69 72 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 74  ir $cmdlinearg(t
4010: 65 73 74 64 69 72 29 0a 20 20 20 20 63 64 20 24  estdir).    cd $
4020: 63 6d 64 6c 69 6e 65 61 72 67 28 74 65 73 74 64  cmdlinearg(testd
4030: 69 72 29 0a 20 20 7d 0a 20 20 73 65 74 20 61 72  ir).  }.  set ar
4040: 67 76 20 24 6c 65 66 74 6f 76 65 72 0a 0a 20 20  gv $leftover..  
4050: 23 20 49 6e 73 74 61 6c 6c 20 74 68 65 20 6d 61  # Install the ma
4060: 6c 6c 6f 63 20 6c 61 79 65 72 20 75 73 65 64 20  lloc layer used 
4070: 74 6f 20 69 6e 6a 65 63 74 20 4f 4f 4d 20 65 72  to inject OOM er
4080: 72 6f 72 73 2e 20 41 6e 64 20 74 68 65 20 27 61  rors. And the 'a
4090: 75 74 6f 6d 61 74 69 63 27 0a 20 20 23 20 65 78  utomatic'.  # ex
40a0: 74 65 6e 73 69 6f 6e 73 2e 20 54 68 69 73 20 6f  tensions. This o
40b0: 6e 6c 79 20 6e 65 65 64 73 20 74 6f 20 62 65 20  nly needs to be 
40c0: 64 6f 6e 65 20 6f 6e 63 65 20 66 6f 72 20 74 68  done once for th
40d0: 65 20 70 72 6f 63 65 73 73 2e 0a 20 20 23 0a 20  e process..  #. 
40e0: 20 73 71 6c 69 74 65 33 5f 73 68 75 74 64 6f 77   sqlite3_shutdow
40f0: 6e 0a 20 20 69 6e 73 74 61 6c 6c 5f 6d 61 6c 6c  n.  install_mall
4100: 6f 63 5f 66 61 75 6c 74 73 69 6d 20 31 0a 20 20  oc_faultsim 1.  
4110: 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69  sqlite3_initiali
4120: 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74 61 6c 6c  ze.  autoinstall
4130: 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e 73 0a  _test_functions.
4140: 0a 20 20 23 20 49 66 20 74 68 65 20 2d 2d 62 69  .  # If the --bi
4150: 6e 61 72 79 6c 6f 67 20 6f 70 74 69 6f 6e 20 77  narylog option w
4160: 61 73 20 73 70 65 63 69 66 69 65 64 2c 20 63 72  as specified, cr
4170: 65 61 74 65 20 74 68 65 20 6c 6f 67 67 69 6e 67  eate the logging
4180: 20 56 46 53 2e 20 54 68 69 73 0a 20 20 23 20 63   VFS. This.  # c
4190: 61 6c 6c 20 69 6e 73 74 61 6c 6c 73 20 74 68 65  all installs the
41a0: 20 6e 65 77 20 56 46 53 20 61 73 20 74 68 65 20   new VFS as the 
41b0: 64 65 66 61 75 6c 74 20 66 6f 72 20 61 6c 6c 20  default for all 
41c0: 53 51 4c 69 74 65 20 63 6f 6e 6e 65 63 74 69 6f  SQLite connectio
41d0: 6e 73 2e 0a 20 20 23 0a 20 20 69 66 20 7b 24 63  ns..  #.  if {$c
41e0: 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72 79  mdlinearg(binary
41f0: 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76 66 73 6c  log)} {.    vfsl
4200: 6f 67 20 6e 65 77 20 62 69 6e 61 72 79 6c 6f 67  og new binarylog
4210: 20 7b 7d 20 76 66 73 6c 6f 67 2e 62 69 6e 0a 20   {} vfslog.bin. 
4220: 20 7d 0a 0a 20 20 23 20 53 65 74 20 74 68 65 20   }..  # Set the 
4230: 62 61 63 6b 74 72 61 63 65 20 64 65 70 74 68 2c  backtrace depth,
4240: 20 69 66 20 6d 61 6c 6c 6f 63 20 74 72 61 63 69   if malloc traci
4250: 6e 67 20 69 73 20 65 6e 61 62 6c 65 64 2e 0a 20  ng is enabled.. 
4260: 20 23 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e   #.  if {$cmdlin
4270: 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65  earg(malloctrace
4280: 29 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  )} {.    sqlite3
4290: 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63 6b 74 72  _memdebug_backtr
42a0: 61 63 65 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  ace $cmdlinearg(
42b0: 62 61 63 6b 74 72 61 63 65 29 0a 20 20 7d 0a 0a  backtrace).  }..
42c0: 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72    if {$cmdlinear
42d0: 67 28 6f 75 74 70 75 74 29 21 3d 22 22 7d 20 7b  g(output)!=""} {
42e0: 0a 20 20 20 20 70 75 74 73 20 22 43 6f 70 79 69  .    puts "Copyi
42f0: 6e 67 20 6f 75 74 70 75 74 20 74 6f 20 66 69 6c  ng output to fil
4300: 65 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75  e $cmdlinearg(ou
4310: 74 70 75 74 29 22 0a 20 20 20 20 73 65 74 20 3a  tput)".    set :
4320: 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 20 5b 6f  :G(output_fd) [o
4330: 70 65 6e 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  pen $cmdlinearg(
4340: 6f 75 74 70 75 74 29 20 77 5d 0a 20 20 20 20 66  output) w].    f
4350: 63 6f 6e 66 69 67 75 72 65 20 24 3a 3a 47 28 6f  configure $::G(o
4360: 75 74 70 75 74 5f 66 64 29 20 2d 62 75 66 66 65  utput_fd) -buffe
4370: 72 69 6e 67 20 6c 69 6e 65 0a 20 20 7d 0a 0a 20  ring line.  }.. 
4380: 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67   if {$cmdlinearg
4390: 28 76 65 72 62 6f 73 65 29 3d 3d 22 22 7d 20 7b  (verbose)==""} {
43a0: 0a 20 20 20 20 73 65 74 20 63 6d 64 6c 69 6e 65  .    set cmdline
43b0: 61 72 67 28 76 65 72 62 6f 73 65 29 20 31 0a 20  arg(verbose) 1. 
43c0: 20 7d 0a 7d 0a 0a 23 20 55 70 64 61 74 65 20 74   }.}..# Update t
43d0: 68 65 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d  he soft-heap-lim
43e0: 69 74 20 65 61 63 68 20 74 69 6d 65 20 74 68 69  it each time thi
43f0: 73 20 73 63 72 69 70 74 20 69 73 20 72 75 6e 2e  s script is run.
4400: 20 49 6e 20 74 68 61 74 0a 23 20 77 61 79 20 69   In that.# way i
4410: 66 20 61 6e 20 69 6e 64 69 76 69 64 75 61 6c 20  f an individual 
4420: 74 65 73 74 20 66 69 6c 65 20 63 68 61 6e 67 65  test file change
4430: 73 20 74 68 65 20 73 6f 66 74 2d 68 65 61 70 2d  s the soft-heap-
4440: 6c 69 6d 69 74 2c 20 69 74 0a 23 20 77 69 6c 6c  limit, it.# will
4450: 20 62 65 20 72 65 73 65 74 20 61 74 20 74 68 65   be reset at the
4460: 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 6e 65   start of the ne
4470: 78 74 20 74 65 73 74 20 66 69 6c 65 2e 0a 23 0a  xt test file..#.
4480: 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68 65 61  sqlite3_soft_hea
4490: 70 5f 6c 69 6d 69 74 20 24 63 6d 64 6c 69 6e 65  p_limit $cmdline
44a0: 61 72 67 28 73 6f 66 74 2d 68 65 61 70 2d 6c 69  arg(soft-heap-li
44b0: 6d 69 74 29 0a 0a 23 20 43 72 65 61 74 65 20 61  mit)..# Create a
44c0: 20 74 65 73 74 20 64 61 74 61 62 61 73 65 0a 23   test database.#
44d0: 0a 70 72 6f 63 20 72 65 73 65 74 5f 64 62 20 7b  .proc reset_db {
44e0: 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64 62 20  } {.  catch {db 
44f0: 63 6c 6f 73 65 7d 0a 20 20 66 6f 72 63 65 64 65  close}.  forcede
4500: 6c 65 74 65 20 74 65 73 74 2e 64 62 0a 20 20 66  lete test.db.  f
4510: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e  orcedelete test.
4520: 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72  db-journal.  for
4530: 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62  cedelete test.db
4540: 2d 77 61 6c 0a 20 20 73 71 6c 69 74 65 33 20 64  -wal.  sqlite3 d
4550: 62 20 2e 2f 74 65 73 74 2e 64 62 0a 20 20 73 65  b ./test.db.  se
4560: 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 5f  t ::DB [sqlite3_
4570: 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74  connection_point
4580: 65 72 20 64 62 5d 0a 20 20 69 66 20 7b 5b 69 6e  er db].  if {[in
4590: 66 6f 20 65 78 69 73 74 73 20 3a 3a 53 45 54 55  fo exists ::SETU
45a0: 50 5f 53 51 4c 5d 7d 20 7b 0a 20 20 20 20 64 62  P_SQL]} {.    db
45b0: 20 65 76 61 6c 20 24 3a 3a 53 45 54 55 50 5f 53   eval $::SETUP_S
45c0: 51 4c 0a 20 20 7d 0a 7d 0a 72 65 73 65 74 5f 64  QL.  }.}.reset_d
45d0: 62 0a 0a 23 20 41 62 6f 72 74 20 65 61 72 6c 79  b..# Abort early
45e0: 20 69 66 20 74 68 69 73 20 73 63 72 69 70 74 20   if this script 
45f0: 68 61 73 20 62 65 65 6e 20 72 75 6e 20 62 65 66  has been run bef
4600: 6f 72 65 2e 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f  ore..#.if {[info
4610: 20 65 78 69 73 74 73 20 54 43 28 63 6f 75 6e 74   exists TC(count
4620: 29 5d 7d 20 72 65 74 75 72 6e 0a 0a 23 20 4d 61  )]} return..# Ma
4630: 6b 65 20 73 75 72 65 20 6d 65 6d 6f 72 79 20 73  ke sure memory s
4640: 74 61 74 69 73 74 69 63 73 20 61 72 65 20 65 6e  tatistics are en
4650: 61 62 6c 65 64 2e 0a 23 0a 73 71 6c 69 74 65 33  abled..#.sqlite3
4660: 5f 63 6f 6e 66 69 67 5f 6d 65 6d 73 74 61 74 75  _config_memstatu
4670: 73 20 31 0a 0a 23 20 49 6e 69 74 69 61 6c 69 7a  s 1..# Initializ
4680: 65 20 74 68 65 20 74 65 73 74 20 63 6f 75 6e 74  e the test count
4690: 65 72 73 20 61 6e 64 20 73 65 74 20 75 70 20 63  ers and set up c
46a0: 6f 6d 6d 61 6e 64 73 20 74 6f 20 61 63 63 65 73  ommands to acces
46b0: 73 20 74 68 65 6d 2e 0a 23 20 4f 72 2c 20 69 66  s them..# Or, if
46c0: 20 74 68 69 73 20 69 73 20 61 20 73 6c 61 76 65   this is a slave
46d0: 20 69 6e 74 65 72 70 72 65 74 65 72 2c 20 73 65   interpreter, se
46e0: 74 20 75 70 20 61 6c 69 61 73 65 73 20 74 6f 20  t up aliases to 
46f0: 77 72 69 74 65 20 74 68 65 0a 23 20 63 6f 75 6e  write the.# coun
4700: 74 65 72 73 20 69 6e 20 74 68 65 20 70 61 72 65  ters in the pare
4710: 6e 74 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a  nt interpreter..
4720: 23 0a 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65  #.if {0==[info e
4730: 78 69 73 74 73 20 3a 3a 53 4c 41 56 45 5d 7d 20  xists ::SLAVE]} 
4740: 7b 0a 20 20 73 65 74 20 54 43 28 65 72 72 6f 72  {.  set TC(error
4750: 73 29 20 20 20 20 30 0a 20 20 73 65 74 20 54 43  s)    0.  set TC
4760: 28 63 6f 75 6e 74 29 20 20 20 20 20 30 0a 20 20  (count)     0.  
4770: 73 65 74 20 54 43 28 66 61 69 6c 5f 6c 69 73 74  set TC(fail_list
4780: 29 20 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 54  ) [list].  set T
4790: 43 28 6f 6d 69 74 5f 6c 69 73 74 29 20 5b 6c 69  C(omit_list) [li
47a0: 73 74 5d 0a 20 20 73 65 74 20 54 43 28 77 61 72  st].  set TC(war
47b0: 6e 5f 6c 69 73 74 29 20 5b 6c 69 73 74 5d 0a 0a  n_list) [list]..
47c0: 20 20 70 72 6f 63 20 73 65 74 5f 74 65 73 74 5f    proc set_test_
47d0: 63 6f 75 6e 74 65 72 20 7b 63 6f 75 6e 74 65 72  counter {counter
47e0: 20 61 72 67 73 7d 20 7b 0a 20 20 20 20 69 66 20   args} {.    if 
47f0: 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d  {[llength $args]
4800: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a  } {.      set ::
4810: 54 43 28 24 63 6f 75 6e 74 65 72 29 20 5b 6c 69  TC($counter) [li
4820: 6e 64 65 78 20 24 61 72 67 73 20 30 5d 0a 20 20  ndex $args 0].  
4830: 20 20 7d 0a 20 20 20 20 73 65 74 20 3a 3a 54 43    }.    set ::TC
4840: 28 24 63 6f 75 6e 74 65 72 29 0a 20 20 7d 0a 7d  ($counter).  }.}
4850: 0a 0a 23 20 52 65 63 6f 72 64 20 74 68 65 20 66  ..# Record the f
4860: 61 63 74 20 74 68 61 74 20 61 20 73 65 71 75 65  act that a seque
4870: 6e 63 65 20 6f 66 20 74 65 73 74 73 20 77 65 72  nce of tests wer
4880: 65 20 6f 6d 69 74 74 65 64 2e 0a 23 0a 70 72 6f  e omitted..#.pro
4890: 63 20 6f 6d 69 74 5f 74 65 73 74 20 7b 6e 61 6d  c omit_test {nam
48a0: 65 20 72 65 61 73 6f 6e 20 7b 61 70 70 65 6e 64  e reason {append
48b0: 20 31 7d 7d 20 7b 0a 20 20 73 65 74 20 6f 6d 69   1}} {.  set omi
48c0: 74 4c 69 73 74 20 5b 73 65 74 5f 74 65 73 74 5f  tList [set_test_
48d0: 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73  counter omit_lis
48e0: 74 5d 0a 20 20 69 66 20 7b 24 61 70 70 65 6e 64  t].  if {$append
48f0: 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64 20  } {.    lappend 
4900: 6f 6d 69 74 4c 69 73 74 20 5b 6c 69 73 74 20 24  omitList [list $
4910: 6e 61 6d 65 20 24 72 65 61 73 6f 6e 5d 0a 20 20  name $reason].  
4920: 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75  }.  set_test_cou
4930: 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74 20 24  nter omit_list $
4940: 6f 6d 69 74 4c 69 73 74 0a 7d 0a 0a 23 20 52 65  omitList.}..# Re
4950: 63 6f 72 64 20 74 68 65 20 66 61 63 74 20 74 68  cord the fact th
4960: 61 74 20 61 20 74 65 73 74 20 66 61 69 6c 65 64  at a test failed
4970: 2e 0a 23 0a 70 72 6f 63 20 66 61 69 6c 5f 74 65  ..#.proc fail_te
4980: 73 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 73 65  st {name} {.  se
4990: 74 20 66 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  t f [set_test_co
49a0: 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73 74 5d  unter fail_list]
49b0: 0a 20 20 6c 61 70 70 65 6e 64 20 66 20 24 6e 61  .  lappend f $na
49c0: 6d 65 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f  me.  set_test_co
49d0: 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73 74 20  unter fail_list 
49e0: 24 66 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f  $f.  set_test_co
49f0: 75 6e 74 65 72 20 65 72 72 6f 72 73 20 5b 65 78  unter errors [ex
4a00: 70 72 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75  pr [set_test_cou
4a10: 6e 74 65 72 20 65 72 72 6f 72 73 5d 20 2b 20 31  nter errors] + 1
4a20: 5d 0a 0a 20 20 73 65 74 20 6e 46 61 69 6c 20 5b  ]..  set nFail [
4a30: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
4a40: 20 65 72 72 6f 72 73 5d 0a 20 20 69 66 20 7b 24   errors].  if {$
4a50: 6e 46 61 69 6c 3e 3d 24 3a 3a 63 6d 64 6c 69 6e  nFail>=$::cmdlin
4a60: 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29 7d 20  earg(maxerror)} 
4a70: 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 2a  {.    output2 "*
4a80: 2a 2a 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e 22  ** Giving up..."
4a90: 0a 20 20 20 20 66 69 6e 61 6c 69 7a 65 5f 74 65  .    finalize_te
4aa0: 73 74 69 6e 67 0a 20 20 7d 0a 7d 0a 0a 23 20 52  sting.  }.}..# R
4ab0: 65 6d 65 6d 62 65 72 20 61 20 77 61 72 6e 69 6e  emember a warnin
4ac0: 67 20 6d 65 73 73 61 67 65 20 74 6f 20 62 65 20  g message to be 
4ad0: 64 69 73 70 6c 61 79 65 64 20 61 74 20 74 68 65  displayed at the
4ae0: 20 63 6f 6e 63 6c 75 73 69 6f 6e 20 6f 66 20 61   conclusion of a
4af0: 6c 6c 20 74 65 73 74 69 6e 67 0a 23 0a 70 72 6f  ll testing.#.pro
4b00: 63 20 77 61 72 6e 69 6e 67 20 7b 6d 73 67 20 7b  c warning {msg {
4b10: 61 70 70 65 6e 64 20 31 7d 7d 20 7b 0a 20 20 6f  append 1}} {.  o
4b20: 75 74 70 75 74 32 20 22 57 61 72 6e 69 6e 67 3a  utput2 "Warning:
4b30: 20 24 6d 73 67 22 0a 20 20 73 65 74 20 77 61 72   $msg".  set war
4b40: 6e 4c 69 73 74 20 5b 73 65 74 5f 74 65 73 74 5f  nList [set_test_
4b50: 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73  counter warn_lis
4b60: 74 5d 0a 20 20 69 66 20 7b 24 61 70 70 65 6e 64  t].  if {$append
4b70: 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64 20  } {.    lappend 
4b80: 77 61 72 6e 4c 69 73 74 20 24 6d 73 67 0a 20 20  warnList $msg.  
4b90: 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75  }.  set_test_cou
4ba0: 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73 74 20 24  nter warn_list $
4bb0: 77 61 72 6e 4c 69 73 74 0a 7d 0a 0a 0a 23 20 49  warnList.}...# I
4bc0: 6e 63 72 65 6d 65 6e 74 20 74 68 65 20 6e 75 6d  ncrement the num
4bd0: 62 65 72 20 6f 66 20 74 65 73 74 73 20 72 75 6e  ber of tests run
4be0: 0a 23 0a 70 72 6f 63 20 69 6e 63 72 5f 6e 74 65  .#.proc incr_nte
4bf0: 73 74 20 7b 7d 20 7b 0a 20 20 73 65 74 5f 74 65  st {} {.  set_te
4c00: 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74  st_counter count
4c10: 20 5b 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74   [expr [set_test
4c20: 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74 5d 20  _counter count] 
4c30: 2b 20 31 5d 0a 7d 0a 0a 23 20 52 65 74 75 72 6e  + 1].}..# Return
4c40: 20 74 72 75 65 20 69 66 20 2d 2d 76 65 72 62 6f   true if --verbo
4c50: 73 65 3d 31 20 77 61 73 20 73 70 65 63 69 66 69  se=1 was specifi
4c60: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e  ed on the comman
4c70: 64 20 6c 69 6e 65 2e 20 4f 74 68 65 72 77 69 73  d line. Otherwis
4c80: 65 2c 0a 23 20 72 65 74 75 72 6e 20 66 61 6c 73  e,.# return fals
4c90: 65 2e 0a 23 0a 70 72 6f 63 20 76 65 72 62 6f 73  e..#.proc verbos
4ca0: 65 20 7b 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20  e {} {.  return 
4cb0: 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 76 65  $::cmdlinearg(ve
4cc0: 72 62 6f 73 65 29 0a 7d 0a 0a 23 20 55 73 65 20  rbose).}..# Use 
4cd0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f  the following co
4ce0: 6d 6d 61 6e 64 73 20 69 6e 73 74 65 61 64 20 6f  mmands instead o
4cf0: 66 20 5b 70 75 74 73 5d 20 66 6f 72 20 74 65 73  f [puts] for tes
4d00: 74 20 6f 75 74 70 75 74 20 77 69 74 68 69 6e 0a  t output within.
4d10: 23 20 74 68 69 73 20 66 69 6c 65 2e 20 54 65 73  # this file. Tes
4d20: 74 20 73 63 72 69 70 74 73 20 63 61 6e 20 73 74  t scripts can st
4d30: 69 6c 6c 20 75 73 65 20 72 65 67 75 6c 61 72 20  ill use regular 
4d40: 5b 70 75 74 73 5d 2c 20 77 68 69 63 68 20 69 73  [puts], which is
4d50: 20 64 69 72 65 63 74 65 64 0a 23 20 74 6f 20 73   directed.# to s
4d60: 74 64 6f 75 74 20 61 6e 64 2c 20 69 66 20 6f 6e  tdout and, if on
4d70: 65 20 69 73 20 6f 70 65 6e 2c 20 74 68 65 20 2d  e is open, the -
4d80: 2d 6f 75 74 70 75 74 20 66 69 6c 65 2e 0a 23 0a  -output file..#.
4d90: 23 20 6f 75 74 70 75 74 31 3a 20 6f 75 74 70 75  # output1: outpu
4da0: 74 20 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65  t that should be
4db0: 20 70 72 69 6e 74 65 64 20 69 66 20 2d 2d 76 65   printed if --ve
4dc0: 72 62 6f 73 65 3d 31 20 77 61 73 20 73 70 65 63  rbose=1 was spec
4dd0: 69 66 69 65 64 2e 0a 23 20 6f 75 74 70 75 74 32  ified..# output2
4de0: 3a 20 6f 75 74 70 75 74 20 74 68 61 74 20 73 68  : output that sh
4df0: 6f 75 6c 64 20 62 65 20 70 72 69 6e 74 65 64 20  ould be printed 
4e00: 75 6e 63 6f 6e 64 69 74 69 6f 6e 61 6c 6c 79 2e  unconditionally.
4e10: 0a 23 20 6f 75 74 70 75 74 32 5f 69 66 5f 6e 6f  .# output2_if_no
4e20: 5f 76 65 72 62 6f 73 65 3a 20 6f 75 74 70 75 74  _verbose: output
4e30: 20 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20   that should be 
4e40: 70 72 69 6e 74 65 64 20 6f 6e 6c 79 20 69 66 20  printed only if 
4e50: 2d 2d 76 65 72 62 6f 73 65 3d 30 2e 0a 23 0a 70  --verbose=0..#.p
4e60: 72 6f 63 20 6f 75 74 70 75 74 31 20 7b 61 72 67  roc output1 {arg
4e70: 73 7d 20 7b 0a 20 20 73 65 74 20 76 20 5b 76 65  s} {.  set v [ve
4e80: 72 62 6f 73 65 5d 0a 20 20 69 66 20 7b 24 76 3d  rbose].  if {$v=
4e90: 3d 31 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65  =1} {.    upleve
4ea0: 6c 20 6f 75 74 70 75 74 32 20 24 61 72 67 73 0a  l output2 $args.
4eb0: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 76 3d 3d    } elseif {$v==
4ec0: 32 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65 6c  2} {.    uplevel
4ed0: 20 70 75 74 73 20 5b 6c 72 61 6e 67 65 20 24 61   puts [lrange $a
4ee0: 72 67 73 20 30 20 65 6e 64 2d 31 5d 20 24 3a 3a  rgs 0 end-1] $::
4ef0: 47 28 6f 75 74 70 75 74 5f 66 64 29 20 5b 6c 72  G(output_fd) [lr
4f00: 61 6e 67 65 20 24 61 72 67 73 20 65 6e 64 20 65  ange $args end e
4f10: 6e 64 5d 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 6f  nd].  }.}.proc o
4f20: 75 74 70 75 74 32 20 7b 61 72 67 73 7d 20 7b 0a  utput2 {args} {.
4f30: 20 20 73 65 74 20 6e 41 72 67 20 5b 6c 6c 65 6e    set nArg [llen
4f40: 67 74 68 20 24 61 72 67 73 5d 0a 20 20 75 70 6c  gth $args].  upl
4f50: 65 76 65 6c 20 70 75 74 73 20 24 61 72 67 73 0a  evel puts $args.
4f60: 7d 0a 70 72 6f 63 20 6f 75 74 70 75 74 32 5f 69  }.proc output2_i
4f70: 66 5f 6e 6f 5f 76 65 72 62 6f 73 65 20 7b 61 72  f_no_verbose {ar
4f80: 67 73 7d 20 7b 0a 20 20 73 65 74 20 76 20 5b 76  gs} {.  set v [v
4f90: 65 72 62 6f 73 65 5d 0a 20 20 69 66 20 7b 24 76  erbose].  if {$v
4fa0: 3d 3d 30 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76  ==0} {.    uplev
4fb0: 65 6c 20 6f 75 74 70 75 74 32 20 24 61 72 67 73  el output2 $args
4fc0: 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 76 3d  .  } elseif {$v=
4fd0: 3d 32 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65  =2} {.    upleve
4fe0: 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67 65 20 24  l puts [lrange $
4ff0: 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 20 73 74  args 0 end-1] st
5000: 64 6f 75 74 20 5b 6c 72 61 6e 67 65 20 24 61 72  dout [lrange $ar
5010: 67 73 20 65 6e 64 20 65 6e 64 5d 0a 20 20 7d 0a  gs end end].  }.
5020: 7d 0a 0a 23 20 4f 76 65 72 72 69 64 65 20 74 68  }..# Override th
5030: 65 20 5b 70 75 74 73 5d 20 63 6f 6d 6d 61 6e 64  e [puts] command
5040: 20 73 6f 20 74 68 61 74 20 69 66 20 6e 6f 20 63   so that if no c
5050: 68 61 6e 6e 65 6c 20 69 73 20 65 78 70 6c 69 63  hannel is explic
5060: 69 74 6c 79 20 0a 23 20 73 70 65 63 69 66 69 65  itly .# specifie
5070: 64 20 74 68 65 20 73 74 72 69 6e 67 20 69 73 20  d the string is 
5080: 77 72 69 74 74 65 6e 20 74 6f 20 62 6f 74 68 20  written to both 
5090: 73 74 64 6f 75 74 20 61 6e 64 20 74 6f 20 74 68  stdout and to th
50a0: 65 20 66 69 6c 65 20 0a 23 20 73 70 65 63 69 66  e file .# specif
50b0: 69 65 64 20 62 79 20 22 2d 2d 6f 75 74 70 75 74  ied by "--output
50c0: 3d 22 2c 20 69 66 20 61 6e 79 2e 0a 23 0a 70 72  =", if any..#.pr
50d0: 6f 63 20 70 75 74 73 5f 6f 76 65 72 72 69 64 65  oc puts_override
50e0: 20 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20   {args} {.  set 
50f0: 6e 41 72 67 20 5b 6c 6c 65 6e 67 74 68 20 24 61  nArg [llength $a
5100: 72 67 73 5d 0a 20 20 69 66 20 7b 24 6e 41 72 67  rgs].  if {$nArg
5110: 3d 3d 31 20 7c 7c 20 28 24 6e 41 72 67 3d 3d 32  ==1 || ($nArg==2
5120: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
5130: 74 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20  t [lindex $args 
5140: 30 5d 20 2d 6e 6f 6e 65 77 6c 69 6e 65 5d 3d 3d  0] -nonewline]==
5150: 30 29 7d 20 7b 0a 20 20 20 20 75 70 6c 65 76 65  0)} {.    upleve
5160: 6c 20 70 75 74 73 5f 6f 72 69 67 69 6e 61 6c 20  l puts_original 
5170: 24 61 72 67 73 0a 20 20 20 20 69 66 20 7b 5b 69  $args.    if {[i
5180: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6f  nfo exists ::G(o
5190: 75 74 70 75 74 5f 66 64 29 5d 7d 20 7b 0a 20 20  utput_fd)]} {.  
51a0: 20 20 20 20 75 70 6c 65 76 65 6c 20 70 75 74 73      uplevel puts
51b0: 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20 30   [lrange $args 0
51c0: 20 65 6e 64 2d 31 5d 20 24 3a 3a 47 28 6f 75 74   end-1] $::G(out
51d0: 70 75 74 5f 66 64 29 20 5b 6c 72 61 6e 67 65 20  put_fd) [lrange 
51e0: 24 61 72 67 73 20 65 6e 64 20 65 6e 64 5d 0a 20  $args end end]. 
51f0: 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a     }.  } else {.
5200: 20 20 20 20 23 20 41 20 63 68 61 6e 6e 65 6c 20      # A channel 
5210: 77 61 73 20 65 78 70 6c 69 63 69 74 6c 79 20 73  was explicitly s
5220: 70 65 63 69 66 69 65 64 2e 0a 20 20 20 20 75 70  pecified..    up
5230: 6c 65 76 65 6c 20 70 75 74 73 5f 6f 72 69 67 69  level puts_origi
5240: 6e 61 6c 20 24 61 72 67 73 0a 20 20 7d 0a 7d 0a  nal $args.  }.}.
5250: 72 65 6e 61 6d 65 20 70 75 74 73 20 70 75 74 73  rename puts puts
5260: 5f 6f 72 69 67 69 6e 61 6c 0a 70 72 6f 63 20 70  _original.proc p
5270: 75 74 73 20 7b 61 72 67 73 7d 20 7b 20 75 70 6c  uts {args} { upl
5280: 65 76 65 6c 20 70 75 74 73 5f 6f 76 65 72 72 69  evel puts_overri
5290: 64 65 20 24 61 72 67 73 20 7d 0a 0a 0a 23 20 49  de $args }...# I
52a0: 6e 76 6f 6b 65 20 74 68 65 20 64 6f 5f 74 65 73  nvoke the do_tes
52b0: 74 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20 72  t procedure to r
52c0: 75 6e 20 61 20 73 69 6e 67 6c 65 20 74 65 73 74  un a single test
52d0: 0a 23 0a 70 72 6f 63 20 64 6f 5f 74 65 73 74 20  .#.proc do_test 
52e0: 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74  {name cmd expect
52f0: 65 64 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 61  ed} {.  global a
5300: 72 67 76 20 63 6d 64 6c 69 6e 65 61 72 67 0a 0a  rgv cmdlinearg..
5310: 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 6e    fix_testname n
5320: 61 6d 65 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d  ame..  sqlite3_m
5330: 65 6d 64 65 62 75 67 5f 73 65 74 74 69 74 6c 65  emdebug_settitle
5340: 20 24 6e 61 6d 65 0a 0a 23 20 20 69 66 20 7b 5b   $name..#  if {[
5350: 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 3d 3d  llength $argv]==
5360: 30 7d 20 7b 0a 23 20 20 20 20 73 65 74 20 67 6f  0} {.#    set go
5370: 20 31 0a 23 20 20 7d 20 65 6c 73 65 20 7b 0a 23   1.#  } else {.#
5380: 20 20 20 20 73 65 74 20 67 6f 20 30 0a 23 20 20      set go 0.#  
5390: 20 20 66 6f 72 65 61 63 68 20 70 61 74 74 65 72    foreach patter
53a0: 6e 20 24 61 72 67 76 20 7b 0a 23 20 20 20 20 20  n $argv {.#     
53b0: 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6d 61 74   if {[string mat
53c0: 63 68 20 24 70 61 74 74 65 72 6e 20 24 6e 61 6d  ch $pattern $nam
53d0: 65 5d 7d 20 7b 0a 23 20 20 20 20 20 20 20 20 73  e]} {.#        s
53e0: 65 74 20 67 6f 20 31 0a 23 20 20 20 20 20 20 20  et go 1.#       
53f0: 20 62 72 65 61 6b 0a 23 20 20 20 20 20 20 7d 0a   break.#      }.
5400: 23 20 20 20 20 7d 0a 23 20 20 7d 0a 0a 20 20 69  #    }.#  }..  i
5410: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
5420: 3a 3a 47 28 70 65 72 6d 3a 70 72 65 66 69 78 29  ::G(perm:prefix)
5430: 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 6e 61 6d  ]} {.    set nam
5440: 65 20 22 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65  e "$::G(perm:pre
5450: 66 69 78 29 24 6e 61 6d 65 22 0a 20 20 7d 0a 0a  fix)$name".  }..
5460: 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a 20 20 6f    incr_ntest.  o
5470: 75 74 70 75 74 31 20 2d 6e 6f 6e 65 77 6c 69 6e  utput1 -nonewlin
5480: 65 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 66 6c 75  e $name....  flu
5490: 73 68 20 73 74 64 6f 75 74 0a 0a 20 20 69 66 20  sh stdout..  if 
54a0: 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a  {![info exists :
54b0: 3a 47 28 6d 61 74 63 68 29 5d 20 7c 7c 20 5b 73  :G(match)] || [s
54c0: 74 72 69 6e 67 20 6d 61 74 63 68 20 24 3a 3a 47  tring match $::G
54d0: 28 6d 61 74 63 68 29 20 24 6e 61 6d 65 5d 7d 20  (match) $name]} 
54e0: 7b 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68  {.    if {[catch
54f0: 20 7b 75 70 6c 65 76 65 6c 20 23 30 20 22 24 63   {uplevel #0 "$c
5500: 6d 64 3b 5c 6e 22 7d 20 72 65 73 75 6c 74 5d 7d  md;\n"} result]}
5510: 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32   {.      output2
5520: 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f 73 65 20 2d  _if_no_verbose -
5530: 6e 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d 65 2e  nonewline $name.
5540: 2e 2e 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32  ...      output2
5550: 20 22 5c 6e 45 72 72 6f 72 3a 20 24 72 65 73 75   "\nError: $resu
5560: 6c 74 22 0a 20 20 20 20 20 20 66 61 69 6c 5f 74  lt".      fail_t
5570: 65 73 74 20 24 6e 61 6d 65 0a 20 20 20 20 7d 20  est $name.    } 
5580: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 69 66 20  else {.      if 
5590: 7b 5b 72 65 67 65 78 70 20 7b 5e 7e 3f 2f 2e 2a  {[regexp {^~?/.*
55a0: 2f 24 7d 20 24 65 78 70 65 63 74 65 64 5d 7d 20  /$} $expected]} 
55b0: 7b 0a 20 20 20 20 20 20 20 20 23 20 22 65 78 70  {.        # "exp
55c0: 65 63 74 65 64 22 20 69 73 20 6f 66 20 74 68 65  ected" is of the
55d0: 20 66 6f 72 6d 20 22 2f 50 41 54 54 45 52 4e 2f   form "/PATTERN/
55e0: 22 20 74 68 65 6e 20 74 68 65 20 72 65 73 75 6c  " then the resul
55f0: 74 20 69 66 20 63 6f 72 72 65 63 74 20 69 66 0a  t if correct if.
5600: 20 20 20 20 20 20 20 20 23 20 72 65 67 75 6c 61          # regula
5610: 72 20 65 78 70 72 65 73 73 69 6f 6e 20 50 41 54  r expression PAT
5620: 54 45 52 4e 20 6d 61 74 63 68 65 73 20 74 68 65  TERN matches the
5630: 20 72 65 73 75 6c 74 2e 20 20 22 7e 2f 50 41 54   result.  "~/PAT
5640: 54 45 52 4e 2f 22 20 6d 65 61 6e 73 0a 20 20 20  TERN/" means.   
5650: 20 20 20 20 20 23 20 74 68 65 20 72 65 67 75 6c       # the regul
5660: 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 6d 75  ar expression mu
5670: 73 74 20 6e 6f 74 20 6d 61 74 63 68 2e 0a 20 20  st not match..  
5680: 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e        if {[strin
5690: 67 20 69 6e 64 65 78 20 24 65 78 70 65 63 74 65  g index $expecte
56a0: 64 20 30 5d 3d 3d 22 7e 22 7d 20 7b 0a 20 20 20  d 0]=="~"} {.   
56b0: 20 20 20 20 20 20 20 73 65 74 20 72 65 20 5b 73         set re [s
56c0: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70  tring range $exp
56d0: 65 63 74 65 64 20 32 20 65 6e 64 2d 31 5d 0a 20  ected 2 end-1]. 
56e0: 20 20 20 20 20 20 20 20 20 69 66 20 7b 5b 73 74           if {[st
56f0: 72 69 6e 67 20 69 6e 64 65 78 20 24 72 65 20 30  ring index $re 0
5700: 5d 3d 3d 22 2a 22 7d 20 7b 0a 20 20 20 20 20 20  ]=="*"} {.      
5710: 20 20 20 20 20 20 23 20 49 66 20 74 68 65 20 72        # If the r
5720: 65 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f  egular expressio
5730: 6e 20 62 65 67 69 6e 73 20 77 69 74 68 20 2a 20  n begins with * 
5740: 74 68 65 6e 20 74 72 65 61 74 20 69 74 20 61 73  then treat it as
5750: 20 61 20 67 6c 6f 62 20 69 6e 73 74 65 61 64 0a   a glob instead.
5760: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
5770: 6f 6b 20 5b 73 74 72 69 6e 67 20 6d 61 74 63 68  ok [string match
5780: 20 24 72 65 20 24 72 65 73 75 6c 74 5d 0a 20 20   $re $result].  
5790: 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b          } else {
57a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74  .            set
57b0: 20 72 65 20 5b 73 74 72 69 6e 67 20 6d 61 70 20   re [string map 
57c0: 7b 23 20 7b 5b 2d 30 2d 39 2e 5d 2b 7d 7d 20 24  {# {[-0-9.]+}} $
57d0: 72 65 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  re].            
57e0: 73 65 74 20 6f 6b 20 5b 72 65 67 65 78 70 20 24  set ok [regexp $
57f0: 72 65 20 24 72 65 73 75 6c 74 5d 0a 20 20 20 20  re $result].    
5800: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
5810: 20 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b    set ok [expr {
5820: 21 24 6f 6b 7d 5d 0a 20 20 20 20 20 20 20 20 7d  !$ok}].        }
5830: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
5840: 20 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67    set re [string
5850: 20 72 61 6e 67 65 20 24 65 78 70 65 63 74 65 64   range $expected
5860: 20 31 20 65 6e 64 2d 31 5d 0a 20 20 20 20 20 20   1 end-1].      
5870: 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20      if {[string 
5880: 69 6e 64 65 78 20 24 72 65 20 30 5d 3d 3d 22 2a  index $re 0]=="*
5890: 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  "} {.           
58a0: 20 23 20 49 66 20 74 68 65 20 72 65 67 75 6c 61   # If the regula
58b0: 72 20 65 78 70 72 65 73 73 69 6f 6e 20 62 65 67  r expression beg
58c0: 69 6e 73 20 77 69 74 68 20 2a 20 74 68 65 6e 20  ins with * then 
58d0: 74 72 65 61 74 20 69 74 20 61 73 20 61 20 67 6c  treat it as a gl
58e0: 6f 62 20 69 6e 73 74 65 61 64 0a 20 20 20 20 20  ob instead.     
58f0: 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 73         set ok [s
5900: 74 72 69 6e 67 20 6d 61 74 63 68 20 24 72 65 20  tring match $re 
5910: 24 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20  $result].       
5920: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
5930: 20 20 20 20 20 20 20 20 73 65 74 20 72 65 20 5b          set re [
5940: 73 74 72 69 6e 67 20 6d 61 70 20 7b 23 20 7b 5b  string map {# {[
5950: 2d 30 2d 39 2e 5d 2b 7d 7d 20 24 72 65 5d 0a 20  -0-9.]+}} $re]. 
5960: 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f             set o
5970: 6b 20 5b 72 65 67 65 78 70 20 24 72 65 20 24 72  k [regexp $re $r
5980: 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20 20  esult].         
5990: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
59a0: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65     } elseif {[re
59b0: 67 65 78 70 20 7b 5e 7e 3f 5c 2a 2e 2a 5c 2a 24  gexp {^~?\*.*\*$
59c0: 7d 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b 0a  } $expected]} {.
59d0: 20 20 20 20 20 20 20 20 23 20 22 65 78 70 65 63          # "expec
59e0: 74 65 64 22 20 69 73 20 6f 66 20 74 68 65 20 66  ted" is of the f
59f0: 6f 72 6d 20 22 2a 47 4c 4f 42 2a 22 20 74 68 65  orm "*GLOB*" the
5a00: 6e 20 74 68 65 20 72 65 73 75 6c 74 20 69 66 20  n the result if 
5a10: 63 6f 72 72 65 63 74 20 69 66 0a 20 20 20 20 20  correct if.     
5a20: 20 20 20 23 20 67 6c 6f 62 20 70 61 74 74 65 72     # glob patter
5a30: 6e 20 47 4c 4f 42 20 6d 61 74 63 68 65 73 20 74  n GLOB matches t
5a40: 68 65 20 72 65 73 75 6c 74 2e 20 20 22 7e 2f 47  he result.  "~/G
5a50: 4c 4f 42 2f 22 20 6d 65 61 6e 73 0a 20 20 20 20  LOB/" means.    
5a60: 20 20 20 20 23 20 74 68 65 20 67 6c 6f 62 20 6d      # the glob m
5a70: 75 73 74 20 6e 6f 74 20 6d 61 74 63 68 2e 0a 20  ust not match.. 
5a80: 20 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72 69         if {[stri
5a90: 6e 67 20 69 6e 64 65 78 20 24 65 78 70 65 63 74  ng index $expect
5aa0: 65 64 20 30 5d 3d 3d 22 7e 22 7d 20 7b 0a 20 20  ed 0]=="~"} {.  
5ab0: 20 20 20 20 20 20 20 20 73 65 74 20 65 20 5b 73          set e [s
5ac0: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70  tring range $exp
5ad0: 65 63 74 65 64 20 31 20 65 6e 64 5d 0a 20 20 20  ected 1 end].   
5ae0: 20 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 65         set ok [e
5af0: 78 70 72 20 7b 21 5b 73 74 72 69 6e 67 20 6d 61  xpr {![string ma
5b00: 74 63 68 20 24 65 20 24 72 65 73 75 6c 74 5d 7d  tch $e $result]}
5b10: 5d 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65  ].        } else
5b20: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 74   {.          set
5b30: 20 6f 6b 20 5b 73 74 72 69 6e 67 20 6d 61 74 63   ok [string matc
5b40: 68 20 24 65 78 70 65 63 74 65 64 20 24 72 65 73  h $expected $res
5b50: 75 6c 74 5d 0a 20 20 20 20 20 20 20 20 7d 0a 20  ult].        }. 
5b60: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
5b70: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 65 78        set ok [ex
5b80: 70 72 20 7b 5b 73 74 72 69 6e 67 20 63 6f 6d 70  pr {[string comp
5b90: 61 72 65 20 24 72 65 73 75 6c 74 20 24 65 78 70  are $result $exp
5ba0: 65 63 74 65 64 5d 3d 3d 30 7d 5d 0a 20 20 20 20  ected]==0}].    
5bb0: 20 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 21 24    }.      if {!$
5bc0: 6f 6b 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20  ok} {.        # 
5bd0: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
5be0: 73 20 3a 3a 74 65 73 74 70 72 65 66 69 78 5d 20  s ::testprefix] 
5bf0: 7c 7c 20 24 3a 3a 74 65 73 74 70 72 65 66 69 78  || $::testprefix
5c00: 20 65 71 20 22 22 7d 20 7b 0a 20 20 20 20 20 20   eq ""} {.      
5c10: 20 20 23 20 20 20 65 72 72 6f 72 20 22 6e 6f 20    #   error "no 
5c20: 74 65 73 74 20 70 72 65 66 69 78 22 0a 20 20 20  test prefix".   
5c30: 20 20 20 20 20 23 20 7d 0a 20 20 20 20 20 20 20       # }.       
5c40: 20 6f 75 74 70 75 74 31 20 22 22 0a 20 20 20 20   output1 "".    
5c50: 20 20 20 20 6f 75 74 70 75 74 32 20 22 21 20 24      output2 "! $
5c60: 6e 61 6d 65 20 65 78 70 65 63 74 65 64 3a 20 5c  name expected: \
5c70: 5b 24 65 78 70 65 63 74 65 64 5c 5d 5c 6e 21 20  [$expected\]\n! 
5c80: 24 6e 61 6d 65 20 67 6f 74 3a 20 20 20 20 20 20  $name got:      
5c90: 5c 5b 24 72 65 73 75 6c 74 5c 5d 22 0a 20 20 20  \[$result\]".   
5ca0: 20 20 20 20 20 66 61 69 6c 5f 74 65 73 74 20 24       fail_test $
5cb0: 6e 61 6d 65 0a 20 20 20 20 20 20 7d 20 65 6c 73  name.      } els
5cc0: 65 20 7b 0a 20 20 20 20 20 20 20 20 6f 75 74 70  e {.        outp
5cd0: 75 74 31 20 22 20 4f 6b 22 0a 20 20 20 20 20 20  ut1 " Ok".      
5ce0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  }.    }.  } else
5cf0: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 31 20 22   {.    output1 "
5d00: 20 4f 6d 69 74 74 65 64 22 0a 20 20 20 20 6f 6d   Omitted".    om
5d10: 69 74 5f 74 65 73 74 20 24 6e 61 6d 65 20 22 70  it_test $name "p
5d20: 61 74 74 65 72 6e 20 6d 69 73 6d 61 74 63 68 22  attern mismatch"
5d30: 20 30 0a 20 20 7d 0a 20 20 66 6c 75 73 68 20 73   0.  }.  flush s
5d40: 74 64 6f 75 74 0a 7d 0a 0a 70 72 6f 63 20 64 75  tdout.}..proc du
5d50: 6d 70 62 79 74 65 73 20 7b 73 7d 20 7b 0a 20 20  mpbytes {s} {.  
5d60: 73 65 74 20 72 20 22 22 0a 20 20 66 6f 72 20 7b  set r "".  for {
5d70: 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b  set i 0} {$i < [
5d80: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73  string length $s
5d90: 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  ]} {incr i} {.  
5da0: 20 20 69 66 20 7b 24 69 20 3e 20 30 7d 20 7b 61    if {$i > 0} {a
5db0: 70 70 65 6e 64 20 72 20 22 20 22 7d 0a 20 20 20  ppend r " "}.   
5dc0: 20 61 70 70 65 6e 64 20 72 20 5b 66 6f 72 6d 61   append r [forma
5dd0: 74 20 25 30 32 58 20 5b 73 63 61 6e 20 5b 73 74  t %02X [scan [st
5de0: 72 69 6e 67 20 69 6e 64 65 78 20 24 73 20 24 69  ring index $s $i
5df0: 5d 20 25 63 5d 5d 0a 20 20 7d 0a 20 20 72 65 74  ] %c]].  }.  ret
5e00: 75 72 6e 20 24 72 0a 7d 0a 0a 70 72 6f 63 20 63  urn $r.}..proc c
5e10: 61 74 63 68 63 6d 64 20 7b 64 62 20 7b 63 6d 64  atchcmd {db {cmd
5e20: 20 22 22 7d 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c   ""}} {.  global
5e30: 20 43 4c 49 0a 20 20 73 65 74 20 6f 75 74 20 5b   CLI.  set out [
5e40: 6f 70 65 6e 20 63 6d 64 73 2e 74 78 74 20 77 5d  open cmds.txt w]
5e50: 0a 20 20 70 75 74 73 20 24 6f 75 74 20 24 63 6d  .  puts $out $cm
5e60: 64 0a 20 20 63 6c 6f 73 65 20 24 6f 75 74 0a 20  d.  close $out. 
5e70: 20 73 65 74 20 6c 69 6e 65 20 22 65 78 65 63 20   set line "exec 
5e80: 24 43 4c 49 20 24 64 62 20 3c 20 63 6d 64 73 2e  $CLI $db < cmds.
5e90: 74 78 74 22 0a 20 20 73 65 74 20 72 63 20 5b 63  txt".  set rc [c
5ea0: 61 74 63 68 20 7b 20 65 76 61 6c 20 24 6c 69 6e  atch { eval $lin
5eb0: 65 20 7d 20 6d 73 67 5d 0a 20 20 6c 69 73 74 20  e } msg].  list 
5ec0: 24 72 63 20 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63  $rc $msg.}..proc
5ed0: 20 63 61 74 63 68 63 6d 64 65 78 20 7b 64 62 20   catchcmdex {db 
5ee0: 7b 63 6d 64 20 22 22 7d 7d 20 7b 0a 20 20 67 6c  {cmd ""}} {.  gl
5ef0: 6f 62 61 6c 20 43 4c 49 0a 20 20 73 65 74 20 6f  obal CLI.  set o
5f00: 75 74 20 5b 6f 70 65 6e 20 63 6d 64 73 2e 74 78  ut [open cmds.tx
5f10: 74 20 77 5d 0a 20 20 66 63 6f 6e 66 69 67 75 72  t w].  fconfigur
5f20: 65 20 24 6f 75 74 20 2d 65 6e 63 6f 64 69 6e 67  e $out -encoding
5f30: 20 62 69 6e 61 72 79 20 2d 74 72 61 6e 73 6c 61   binary -transla
5f40: 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 70 75  tion binary.  pu
5f50: 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6f  ts -nonewline $o
5f60: 75 74 20 24 63 6d 64 0a 20 20 63 6c 6f 73 65 20  ut $cmd.  close 
5f70: 24 6f 75 74 0a 20 20 73 65 74 20 6c 69 6e 65 20  $out.  set line 
5f80: 22 65 78 65 63 20 2d 6b 65 65 70 6e 65 77 6c 69  "exec -keepnewli
5f90: 6e 65 20 2d 2d 20 24 43 4c 49 20 24 64 62 20 3c  ne -- $CLI $db <
5fa0: 20 63 6d 64 73 2e 74 78 74 22 0a 20 20 73 65 74   cmds.txt".  set
5fb0: 20 63 68 61 6e 73 20 5b 6c 69 73 74 20 73 74 64   chans [list std
5fc0: 69 6e 20 73 74 64 6f 75 74 20 73 74 64 65 72 72  in stdout stderr
5fd0: 5d 0a 20 20 66 6f 72 65 61 63 68 20 63 68 61 6e  ].  foreach chan
5fe0: 20 24 63 68 61 6e 73 20 7b 0a 20 20 20 20 63 61   $chans {.    ca
5ff0: 74 63 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20  tch {.      set 
6000: 6d 6f 64 65 73 28 24 63 68 61 6e 29 20 5b 66 63  modes($chan) [fc
6010: 6f 6e 66 69 67 75 72 65 20 24 63 68 61 6e 5d 0a  onfigure $chan].
6020: 20 20 20 20 20 20 66 63 6f 6e 66 69 67 75 72 65        fconfigure
6030: 20 24 63 68 61 6e 20 2d 65 6e 63 6f 64 69 6e 67   $chan -encoding
6040: 20 62 69 6e 61 72 79 20 2d 74 72 61 6e 73 6c 61   binary -transla
6050: 74 69 6f 6e 20 62 69 6e 61 72 79 20 2d 62 75 66  tion binary -buf
6060: 66 65 72 69 6e 67 20 6e 6f 6e 65 0a 20 20 20 20  fering none.    
6070: 7d 0a 20 20 7d 0a 20 20 73 65 74 20 72 63 20 5b  }.  }.  set rc [
6080: 63 61 74 63 68 20 7b 20 65 76 61 6c 20 24 6c 69  catch { eval $li
6090: 6e 65 20 7d 20 6d 73 67 5d 0a 20 20 66 6f 72 65  ne } msg].  fore
60a0: 61 63 68 20 63 68 61 6e 20 24 63 68 61 6e 73 20  ach chan $chans 
60b0: 7b 0a 20 20 20 20 63 61 74 63 68 20 7b 0a 20 20  {.    catch {.  
60c0: 20 20 20 20 65 76 61 6c 20 66 63 6f 6e 66 69 67      eval fconfig
60d0: 75 72 65 20 5b 6c 69 73 74 20 24 63 68 61 6e 5d  ure [list $chan]
60e0: 20 24 6d 6f 64 65 73 28 24 63 68 61 6e 29 0a 20   $modes($chan). 
60f0: 20 20 20 7d 0a 20 20 7d 0a 20 20 23 20 70 75 74     }.  }.  # put
6100: 73 20 5b 64 75 6d 70 62 79 74 65 73 20 24 6d 73  s [dumpbytes $ms
6110: 67 5d 0a 20 20 6c 69 73 74 20 24 72 63 20 24 6d  g].  list $rc $m
6120: 73 67 0a 7d 0a 0a 70 72 6f 63 20 66 69 6c 65 70  sg.}..proc filep
6130: 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 7b 70  ath_normalize {p
6140: 7d 20 7b 0a 20 20 23 20 74 65 73 74 20 63 61 73  } {.  # test cas
6150: 65 73 20 73 68 6f 75 6c 64 20 62 65 20 77 72 69  es should be wri
6160: 74 74 65 6e 20 74 6f 20 61 73 73 75 6d 65 20 22  tten to assume "
6170: 75 6e 69 78 22 2d 6c 69 6b 65 20 66 69 6c 65 20  unix"-like file 
6180: 70 61 74 68 73 0a 20 20 69 66 20 7b 24 3a 3a 74  paths.  if {$::t
6190: 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74  cl_platform(plat
61a0: 66 6f 72 6d 29 21 3d 22 75 6e 69 78 22 7d 20 7b  form)!="unix"} {
61b0: 0a 20 20 20 20 23 20 6c 72 65 76 65 72 73 65 2a  .    # lreverse*
61c0: 32 20 61 73 20 61 20 68 61 63 6b 20 74 6f 20 72  2 as a hack to r
61d0: 65 6d 6f 76 65 20 61 6e 79 20 75 6e 6e 65 65 64  emove any unneed
61e0: 65 64 20 7b 7d 20 61 66 74 65 72 20 74 68 65 20  ed {} after the 
61f0: 73 74 72 69 6e 67 20 6d 61 70 0a 20 20 20 20 6c  string map.    l
6200: 72 65 76 65 72 73 65 20 5b 6c 72 65 76 65 72 73  reverse [lrevers
6210: 65 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 5c  e [string map {\
6220: 5c 20 2f 7d 20 5b 72 65 67 73 75 62 20 2d 6e 6f  \ /} [regsub -no
6230: 63 61 73 65 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5d  case -all {[a-z]
6240: 3a 5b 2f 5c 5c 5d 2b 7d 20 24 70 20 7b 2f 7d 5d  :[/\\]+} $p {/}]
6250: 5d 5d 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74  ]].  } {.    set
6260: 20 70 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 6f   p.  }.}.proc do
6270: 5f 66 69 6c 65 70 61 74 68 5f 74 65 73 74 20 7b  _filepath_test {
6280: 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65  name cmd expecte
6290: 64 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 5b  d} {.  uplevel [
62a0: 6c 69 73 74 20 64 6f 5f 74 65 73 74 20 24 6e 61  list do_test $na
62b0: 6d 65 20 5b 0a 20 20 20 20 73 75 62 73 74 20 2d  me [.    subst -
62c0: 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b 20 66 69 6c  nocommands { fil
62d0: 65 70 61 74 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20  epath_normalize 
62e0: 5b 20 24 63 6d 64 20 5d 20 7d 0a 20 20 5d 20 5b  [ $cmd ] }.  ] [
62f0: 66 69 6c 65 70 61 74 68 5f 6e 6f 72 6d 61 6c 69  filepath_normali
6300: 7a 65 20 24 65 78 70 65 63 74 65 64 5d 5d 0a 7d  ze $expected]].}
6310: 0a 0a 70 72 6f 63 20 72 65 61 6c 6e 75 6d 5f 6e  ..proc realnum_n
6320: 6f 72 6d 61 6c 69 7a 65 20 7b 72 7d 20 7b 0a 20  ormalize {r} {. 
6330: 20 23 20 64 69 66 66 65 72 65 6e 74 20 54 43 4c   # different TCL
6340: 20 76 65 72 73 69 6f 6e 73 20 64 69 73 70 6c 61   versions displa
6350: 79 20 66 6c 6f 61 74 69 6e 67 20 70 6f 69 6e 74  y floating point
6360: 20 76 61 6c 75 65 73 20 64 69 66 66 65 72 65 6e   values differen
6370: 74 6c 79 2e 0a 20 20 73 74 72 69 6e 67 20 6d 61  tly..  string ma
6380: 70 20 7b 31 2e 23 49 4e 46 20 69 6e 66 20 49 6e  p {1.#INF inf In
6390: 66 20 69 6e 66 20 2e 30 65 20 65 7d 20 5b 72 65  f inf .0e e} [re
63a0: 67 73 75 62 20 2d 61 6c 6c 20 7b 28 65 5b 2b 2d  gsub -all {(e[+-
63b0: 5d 29 30 2b 7d 20 24 72 20 7b 5c 31 7d 5d 0a 7d  ])0+} $r {\1}].}
63c0: 0a 70 72 6f 63 20 64 6f 5f 72 65 61 6c 6e 75 6d  .proc do_realnum
63d0: 5f 74 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64 20  _test {name cmd 
63e0: 65 78 70 65 63 74 65 64 7d 20 7b 0a 20 20 75 70  expected} {.  up
63f0: 6c 65 76 65 6c 20 5b 6c 69 73 74 20 64 6f 5f 74  level [list do_t
6400: 65 73 74 20 24 6e 61 6d 65 20 5b 0a 20 20 20 20  est $name [.    
6410: 73 75 62 73 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64  subst -nocommand
6420: 73 20 7b 20 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d  s { realnum_norm
6430: 61 6c 69 7a 65 20 5b 20 24 63 6d 64 20 5d 20 7d  alize [ $cmd ] }
6440: 0a 20 20 5d 20 5b 72 65 61 6c 6e 75 6d 5f 6e 6f  .  ] [realnum_no
6450: 72 6d 61 6c 69 7a 65 20 24 65 78 70 65 63 74 65  rmalize $expecte
6460: 64 5d 5d 0a 7d 0a 0a 70 72 6f 63 20 66 69 78 5f  d]].}..proc fix_
6470: 74 65 73 74 6e 61 6d 65 20 7b 76 61 72 6e 61 6d  testname {varnam
6480: 65 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 76 61  e} {.  upvar $va
6490: 72 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20  rname testname. 
64a0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
64b0: 73 20 3a 3a 74 65 73 74 70 72 65 66 69 78 5d 0a  s ::testprefix].
64c0: 20 20 20 26 26 20 5b 73 74 72 69 6e 67 20 69 73     && [string is
64d0: 20 64 69 67 69 74 20 5b 73 74 72 69 6e 67 20 72   digit [string r
64e0: 61 6e 67 65 20 24 74 65 73 74 6e 61 6d 65 20 30  ange $testname 0
64f0: 20 30 5d 5d 0a 20 20 7d 20 7b 0a 20 20 20 20 73   0]].  } {.    s
6500: 65 74 20 74 65 73 74 6e 61 6d 65 20 22 24 7b 3a  et testname "${:
6510: 3a 74 65 73 74 70 72 65 66 69 78 7d 2d 24 74 65  :testprefix}-$te
6520: 73 74 6e 61 6d 65 22 0a 20 20 7d 0a 7d 0a 0a 70  stname".  }.}..p
6530: 72 6f 63 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74  roc do_execsql_t
6540: 65 73 74 20 7b 74 65 73 74 6e 61 6d 65 20 73 71  est {testname sq
6550: 6c 20 7b 72 65 73 75 6c 74 20 7b 7d 7d 7d 20 7b  l {result {}}} {
6560: 0a 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20  .  fix_testname 
6570: 74 65 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76  testname.  uplev
6580: 65 6c 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74  el do_test [list
6590: 20 24 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73   $testname] [lis
65a0: 74 20 22 65 78 65 63 73 71 6c 20 7b 24 73 71 6c  t "execsql {$sql
65b0: 7d 22 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20  }"] [list [list 
65c0: 7b 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a 7d 0a 70  {*}$result]].}.p
65d0: 72 6f 63 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f  roc do_catchsql_
65e0: 74 65 73 74 20 7b 74 65 73 74 6e 61 6d 65 20 73  test {testname s
65f0: 71 6c 20 72 65 73 75 6c 74 7d 20 7b 0a 20 20 66  ql result} {.  f
6600: 69 78 5f 74 65 73 74 6e 61 6d 65 20 74 65 73 74  ix_testname test
6610: 6e 61 6d 65 0a 20 20 75 70 6c 65 76 65 6c 20 64  name.  uplevel d
6620: 6f 5f 74 65 73 74 20 5b 6c 69 73 74 20 24 74 65  o_test [list $te
6630: 73 74 6e 61 6d 65 5d 20 5b 6c 69 73 74 20 22 63  stname] [list "c
6640: 61 74 63 68 73 71 6c 20 7b 24 73 71 6c 7d 22 5d  atchsql {$sql}"]
6650: 20 5b 6c 69 73 74 20 24 72 65 73 75 6c 74 5d 0a   [list $result].
6660: 7d 0a 70 72 6f 63 20 64 6f 5f 74 69 6d 65 64 5f  }.proc do_timed_
6670: 65 78 65 63 73 71 6c 5f 74 65 73 74 20 7b 74 65  execsql_test {te
6680: 73 74 6e 61 6d 65 20 73 71 6c 20 7b 72 65 73 75  stname sql {resu
6690: 6c 74 20 7b 7d 7d 7d 20 7b 0a 20 20 66 69 78 5f  lt {}}} {.  fix_
66a0: 74 65 73 74 6e 61 6d 65 20 74 65 73 74 6e 61 6d  testname testnam
66b0: 65 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74  e.  uplevel do_t
66c0: 65 73 74 20 5b 6c 69 73 74 20 24 74 65 73 74 6e  est [list $testn
66d0: 61 6d 65 5d 20 5b 6c 69 73 74 20 22 65 78 65 63  ame] [list "exec
66e0: 73 71 6c 5f 74 69 6d 65 64 20 7b 24 73 71 6c 7d  sql_timed {$sql}
66f0: 22 5d 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  "]\.            
6700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6710: 20 20 20 20 20 20 20 5b 6c 69 73 74 20 5b 6c 69         [list [li
6720: 73 74 20 7b 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a  st {*}$result]].
6730: 7d 0a 70 72 6f 63 20 64 6f 5f 65 71 70 5f 74 65  }.proc do_eqp_te
6740: 73 74 20 7b 6e 61 6d 65 20 73 71 6c 20 72 65 73  st {name sql res
6750: 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f  } {.  uplevel do
6760: 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 24 6e  _execsql_test $n
6770: 61 6d 65 20 5b 6c 69 73 74 20 22 45 58 50 4c 41  ame [list "EXPLA
6780: 49 4e 20 51 55 45 52 59 20 50 4c 41 4e 20 24 73  IN QUERY PLAN $s
6790: 71 6c 22 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d  ql"] [list $res]
67a0: 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .}..#-----------
67b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
67c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
67d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
67e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23  --------------.#
67f0: 20 20 20 55 73 61 67 65 3a 20 64 6f 5f 73 65 6c     Usage: do_sel
6800: 65 63 74 5f 74 65 73 74 73 20 50 52 45 46 49 58  ect_tests PREFIX
6810: 20 3f 53 57 49 54 43 48 45 53 3f 20 54 45 53 54   ?SWITCHES? TEST
6820: 4c 49 53 54 0a 23 0a 23 20 57 68 65 72 65 20 73  LIST.#.# Where s
6830: 77 69 74 63 68 65 73 20 61 72 65 3a 0a 23 0a 23  witches are:.#.#
6840: 20 20 20 2d 65 72 72 6f 72 66 6f 72 6d 61 74 20     -errorformat 
6850: 46 4d 54 53 54 52 49 4e 47 0a 23 20 20 20 2d 63  FMTSTRING.#   -c
6860: 6f 75 6e 74 0a 23 20 20 20 2d 71 75 65 72 79 20  ount.#   -query 
6870: 53 51 4c 0a 23 20 20 20 2d 74 63 6c 71 75 65 72  SQL.#   -tclquer
6880: 79 20 54 43 4c 0a 23 20 20 20 2d 72 65 70 61 69  y TCL.#   -repai
6890: 72 20 54 43 4c 0a 23 0a 70 72 6f 63 20 64 6f 5f  r TCL.#.proc do_
68a0: 73 65 6c 65 63 74 5f 74 65 73 74 73 20 7b 70 72  select_tests {pr
68b0: 65 66 69 78 20 61 72 67 73 7d 20 7b 0a 0a 20 20  efix args} {..  
68c0: 73 65 74 20 74 65 73 74 6c 69 73 74 20 5b 6c 69  set testlist [li
68d0: 6e 64 65 78 20 24 61 72 67 73 20 65 6e 64 5d 0a  ndex $args end].
68e0: 20 20 73 65 74 20 73 77 69 74 63 68 65 73 20 5b    set switches [
68f0: 6c 72 61 6e 67 65 20 24 61 72 67 73 20 30 20 65  lrange $args 0 e
6900: 6e 64 2d 31 5d 0a 0a 20 20 73 65 74 20 65 72 72  nd-1]..  set err
6910: 66 6d 74 20 22 22 0a 20 20 73 65 74 20 63 6f 75  fmt "".  set cou
6920: 6e 74 6f 6e 6c 79 20 30 0a 20 20 73 65 74 20 74  ntonly 0.  set t
6930: 63 6c 71 75 65 72 79 20 22 22 0a 20 20 73 65 74  clquery "".  set
6940: 20 72 65 70 61 69 72 20 22 22 0a 0a 20 20 66 6f   repair ""..  fo
6950: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20  r {set i 0} {$i 
6960: 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 73 77 69 74  < [llength $swit
6970: 63 68 65 73 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  ches]} {incr i} 
6980: 7b 0a 20 20 20 20 73 65 74 20 73 20 5b 6c 69 6e  {.    set s [lin
6990: 64 65 78 20 24 73 77 69 74 63 68 65 73 20 24 69  dex $switches $i
69a0: 5d 0a 20 20 20 20 73 65 74 20 6e 20 5b 73 74 72  ].    set n [str
69b0: 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 5d 0a 20  ing length $s]. 
69c0: 20 20 20 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20     if {$n>=2 && 
69d0: 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c  [string equal -l
69e0: 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 71 75  ength $n $s "-qu
69f0: 65 72 79 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73  ery"]} {.      s
6a00: 65 74 20 74 63 6c 71 75 65 72 79 20 5b 6c 69 73  et tclquery [lis
6a10: 74 20 65 78 65 63 73 71 6c 20 5b 6c 69 6e 64 65  t execsql [linde
6a20: 78 20 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63  x $switches [inc
6a30: 72 20 69 5d 5d 5d 0a 20 20 20 20 7d 20 65 6c 73  r i]]].    } els
6a40: 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73  eif {$n>=2 && [s
6a50: 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e  tring equal -len
6a60: 67 74 68 20 24 6e 20 24 73 20 22 2d 74 63 6c 71  gth $n $s "-tclq
6a70: 75 65 72 79 22 5d 7d 20 7b 0a 20 20 20 20 20 20  uery"]} {.      
6a80: 73 65 74 20 74 63 6c 71 75 65 72 79 20 5b 6c 69  set tclquery [li
6a90: 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20 5b  ndex $switches [
6aa0: 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20 65  incr i]].    } e
6ab0: 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20  lseif {$n>=2 && 
6ac0: 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c  [string equal -l
6ad0: 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 65 72  ength $n $s "-er
6ae0: 72 6f 72 66 6f 72 6d 61 74 22 5d 7d 20 7b 0a 20  rorformat"]} {. 
6af0: 20 20 20 20 20 73 65 74 20 65 72 72 66 6d 74 20       set errfmt 
6b00: 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68 65  [lindex $switche
6b10: 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20  s [incr i]].    
6b20: 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20  } elseif {$n>=2 
6b30: 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c  && [string equal
6b40: 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22   -length $n $s "
6b50: 2d 72 65 70 61 69 72 22 5d 7d 20 7b 0a 20 20 20  -repair"]} {.   
6b60: 20 20 20 73 65 74 20 72 65 70 61 69 72 20 5b 6c     set repair [l
6b70: 69 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20  index $switches 
6b80: 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20  [incr i]].    } 
6b90: 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26  elseif {$n>=2 &&
6ba0: 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d   [string equal -
6bb0: 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 63  length $n $s "-c
6bc0: 6f 75 6e 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20  ount"]} {.      
6bd0: 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79 20 31 0a  set countonly 1.
6be0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
6bf0: 20 20 20 65 72 72 6f 72 20 22 75 6e 6b 6e 6f 77     error "unknow
6c00: 6e 20 73 77 69 74 63 68 3a 20 24 73 22 0a 20 20  n switch: $s".  
6c10: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24    }.  }..  if {$
6c20: 63 6f 75 6e 74 6f 6e 6c 79 20 26 26 20 24 65 72  countonly && $er
6c30: 72 66 6d 74 21 3d 22 22 7d 20 7b 0a 20 20 20 20  rfmt!=""} {.    
6c40: 65 72 72 6f 72 20 22 43 61 6e 6e 6f 74 20 75 73  error "Cannot us
6c50: 65 20 2d 63 6f 75 6e 74 20 61 6e 64 20 2d 65 72  e -count and -er
6c60: 72 6f 72 66 6f 72 6d 61 74 20 74 6f 67 65 74 68  rorformat togeth
6c70: 65 72 22 0a 20 20 7d 0a 20 20 73 65 74 20 6e 54  er".  }.  set nT
6c80: 65 73 74 6c 69 73 74 20 5b 6c 6c 65 6e 67 74 68  estlist [llength
6c90: 20 24 74 65 73 74 6c 69 73 74 5d 0a 20 20 69 66   $testlist].  if
6ca0: 20 7b 24 6e 54 65 73 74 6c 69 73 74 25 33 20 7c   {$nTestlist%3 |
6cb0: 7c 20 24 6e 54 65 73 74 6c 69 73 74 3d 3d 30 20  | $nTestlist==0 
6cc0: 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 53  } {.    error "S
6cd0: 45 4c 45 43 54 20 74 65 73 74 20 6c 69 73 74 20  ELECT test list 
6ce0: 63 6f 6e 74 61 69 6e 73 20 5b 6c 6c 65 6e 67 74  contains [llengt
6cf0: 68 20 24 74 65 73 74 6c 69 73 74 5d 20 65 6c 65  h $testlist] ele
6d00: 6d 65 6e 74 73 22 0a 20 20 7d 0a 0a 20 20 65 76  ments".  }..  ev
6d10: 61 6c 20 24 72 65 70 61 69 72 0a 20 20 66 6f 72  al $repair.  for
6d20: 65 61 63 68 20 7b 74 6e 20 73 71 6c 20 72 65 73  each {tn sql res
6d30: 7d 20 24 74 65 73 74 6c 69 73 74 20 7b 0a 20 20  } $testlist {.  
6d40: 20 20 69 66 20 7b 24 74 63 6c 71 75 65 72 79 20    if {$tclquery 
6d50: 21 3d 20 22 22 7d 20 7b 0a 20 20 20 20 20 20 65  != ""} {.      e
6d60: 78 65 63 73 71 6c 20 24 73 71 6c 0a 20 20 20 20  xecsql $sql.    
6d70: 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73    uplevel do_tes
6d80: 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e 20  t ${prefix}.$tn 
6d90: 5b 6c 69 73 74 20 24 74 63 6c 71 75 65 72 79 5d  [list $tclquery]
6da0: 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d   [list [list {*}
6db0: 24 72 65 73 5d 5d 0a 20 20 20 20 7d 20 65 6c 73  $res]].    } els
6dc0: 65 69 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c 79 7d  eif {$countonly}
6dd0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6e 52 6f   {.      set nRo
6de0: 77 20 30 0a 20 20 20 20 20 20 64 62 20 65 76 61  w 0.      db eva
6df0: 6c 20 24 73 71 6c 20 7b 69 6e 63 72 20 6e 52 6f  l $sql {incr nRo
6e00: 77 7d 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c  w}.      uplevel
6e10: 20 64 6f 5f 74 65 73 74 20 24 7b 70 72 65 66 69   do_test ${prefi
6e20: 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20 5b 6c 69  x}.$tn [list [li
6e30: 73 74 20 73 65 74 20 7b 7d 20 24 6e 52 6f 77 5d  st set {} $nRow]
6e40: 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20  ] [list $res].  
6e50: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 65 72 72    } elseif {$err
6e60: 66 6d 74 3d 3d 22 22 7d 20 7b 0a 20 20 20 20 20  fmt==""} {.     
6e70: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63   uplevel do_exec
6e80: 73 71 6c 5f 74 65 73 74 20 24 7b 70 72 65 66 69  sql_test ${prefi
6e90: 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69 73 74 20 24  x}.${tn} [list $
6ea0: 73 71 6c 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74  sql] [list [list
6eb0: 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20 20 20 20 7d   {*}$res]].    }
6ec0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65   else {.      se
6ed0: 74 20 72 65 73 20 5b 6c 69 73 74 20 31 20 5b 73  t res [list 1 [s
6ee0: 74 72 69 6e 67 20 74 72 69 6d 20 5b 66 6f 72 6d  tring trim [form
6ef0: 61 74 20 24 65 72 72 66 6d 74 20 7b 2a 7d 24 72  at $errfmt {*}$r
6f00: 65 73 5d 5d 5d 0a 20 20 20 20 20 20 75 70 6c 65  es]]].      uple
6f10: 76 65 6c 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f  vel do_catchsql_
6f20: 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24  test ${prefix}.$
6f30: 7b 74 6e 7d 20 5b 6c 69 73 74 20 24 73 71 6c 5d  {tn} [list $sql]
6f40: 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20 20   [list $res].   
6f50: 20 7d 0a 20 20 20 20 65 76 61 6c 20 24 72 65 70   }.    eval $rep
6f60: 61 69 72 0a 20 20 7d 0a 0a 7d 0a 0a 70 72 6f 63  air.  }..}..proc
6f70: 20 64 65 6c 65 74 65 5f 61 6c 6c 5f 64 61 74 61   delete_all_data
6f80: 20 7b 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20   {} {.  db eval 
6f90: 7b 53 45 4c 45 43 54 20 74 62 6c 5f 6e 61 6d 65  {SELECT tbl_name
6fa0: 20 41 53 20 74 20 46 52 4f 4d 20 73 71 6c 69 74   AS t FROM sqlit
6fb0: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  e_master WHERE t
6fc0: 79 70 65 20 3d 20 27 74 61 62 6c 65 27 7d 20 7b  ype = 'table'} {
6fd0: 0a 20 20 20 20 64 62 20 65 76 61 6c 20 22 44 45  .    db eval "DE
6fe0: 4c 45 54 45 20 46 52 4f 4d 20 27 5b 73 74 72 69  LETE FROM '[stri
6ff0: 6e 67 20 6d 61 70 20 7b 27 20 27 27 7d 20 24 74  ng map {' ''} $t
7000: 5d 27 22 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75 6e  ]'".  }.}..# Run
7010: 20 61 6e 20 53 51 4c 20 73 63 72 69 70 74 2e 0a   an SQL script..
7020: 23 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d  # Return the num
7030: 62 65 72 20 6f 66 20 6d 69 63 72 6f 73 65 63 6f  ber of microseco
7040: 6e 64 73 20 70 65 72 20 73 74 61 74 65 6d 65 6e  nds per statemen
7050: 74 2e 0a 23 0a 70 72 6f 63 20 73 70 65 65 64 5f  t..#.proc speed_
7060: 74 72 69 61 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73  trial {name nums
7070: 74 6d 74 20 75 6e 69 74 73 20 73 71 6c 7d 20 7b  tmt units sql} {
7080: 0a 20 20 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65  .  output2 -none
7090: 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25  wline [format {%
70a0: 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e  -21.21s } $name.
70b0: 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73 74 64 6f  ..].  flush stdo
70c0: 75 74 0a 20 20 73 65 74 20 73 70 65 65 64 20 5b  ut.  set speed [
70d0: 74 69 6d 65 20 7b 73 71 6c 69 74 65 33 5f 65 78  time {sqlite3_ex
70e0: 65 63 5f 6e 72 20 64 62 20 24 73 71 6c 7d 5d 0a  ec_nr db $sql}].
70f0: 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78    set tm [lindex
7100: 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69 66 20   $speed 0].  if 
7110: 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20  {$tm == 0} {.   
7120: 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61   set rate [forma
7130: 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20  t %20s "many"]. 
7140: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
7150: 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25  t rate [format %
7160: 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31 30 30  20.5f [expr {100
7170: 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f  0000.0*$numstmt/
7180: 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74  $tm}]].  }.  set
7190: 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20 6f   u2 $units/s.  o
71a0: 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b  utput2 [format {
71b0: 25 31 32 64 20 75 53 20 25 73 20 25 73 7d 20 24  %12d uS %s %s} $
71c0: 74 6d 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20  tm $rate $u2].  
71d0: 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d  global total_tim
71e0: 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69  e.  set total_ti
71f0: 6d 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c  me [expr {$total
7200: 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61  _time+$tm}].  la
7210: 70 70 65 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72  ppend ::speed_tr
7220: 69 61 6c 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20  ial_times $name 
7230: 24 74 6d 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64  $tm.}.proc speed
7240: 5f 74 72 69 61 6c 5f 74 63 6c 20 7b 6e 61 6d 65  _trial_tcl {name
7250: 20 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73   numstmt units s
7260: 63 72 69 70 74 7d 20 7b 0a 20 20 6f 75 74 70 75  cript} {.  outpu
7270: 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66  t2 -nonewline [f
7280: 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20  ormat {%-21.21s 
7290: 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c  } $name...].  fl
72a0: 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74  ush stdout.  set
72b0: 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 65 76   speed [time {ev
72c0: 61 6c 20 24 73 63 72 69 70 74 7d 5d 0a 20 20 73  al $script}].  s
72d0: 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24 73  et tm [lindex $s
72e0: 70 65 65 64 20 30 5d 0a 20 20 69 66 20 7b 24 74  peed 0].  if {$t
72f0: 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20 20 73 65  m == 0} {.    se
7300: 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25  t rate [format %
7310: 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20 20 7d 20  20s "many"].  } 
7320: 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 72  else {.    set r
7330: 61 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 2e  ate [format %20.
7340: 35 66 20 5b 65 78 70 72 20 7b 31 30 30 30 30 30  5f [expr {100000
7350: 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f 24 74 6d  0.0*$numstmt/$tm
7360: 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74 20 75 32  }]].  }.  set u2
7370: 20 24 75 6e 69 74 73 2f 73 0a 20 20 6f 75 74 70   $units/s.  outp
7380: 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32  ut2 [format {%12
7390: 64 20 75 53 20 25 73 20 25 73 7d 20 24 74 6d 20  d uS %s %s} $tm 
73a0: 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f  $rate $u2].  glo
73b0: 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20  bal total_time. 
73c0: 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20   set total_time 
73d0: 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69  [expr {$total_ti
73e0: 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70 70 65  me+$tm}].  lappe
73f0: 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  nd ::speed_trial
7400: 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20 24 74 6d  _times $name $tm
7410: 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72  .}.proc speed_tr
7420: 69 61 6c 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20  ial_init {name} 
7430: 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  {.  global total
7440: 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61  _time.  set tota
7450: 6c 5f 74 69 6d 65 20 30 0a 20 20 73 65 74 20 3a  l_time 0.  set :
7460: 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d  :speed_trial_tim
7470: 65 73 20 5b 6c 69 73 74 5d 0a 20 20 73 71 6c 69  es [list].  sqli
7480: 74 65 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f  te3 versdb :memo
7490: 72 79 3a 0a 20 20 73 65 74 20 76 65 72 73 20 5b  ry:.  set vers [
74a0: 76 65 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45  versdb one {SELE
74b0: 43 54 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65  CT sqlite_source
74c0: 5f 69 64 28 29 7d 5d 0a 20 20 76 65 72 73 64 62  _id()}].  versdb
74d0: 20 63 6c 6f 73 65 0a 20 20 6f 75 74 70 75 74 32   close.  output2
74e0: 20 22 53 51 4c 69 74 65 20 24 76 65 72 73 22 0a   "SQLite $vers".
74f0: 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69  }.proc speed_tri
7500: 61 6c 5f 73 75 6d 6d 61 72 79 20 7b 6e 61 6d 65  al_summary {name
7510: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74  } {.  global tot
7520: 61 6c 5f 74 69 6d 65 0a 20 20 6f 75 74 70 75 74  al_time.  output
7530: 32 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e  2 [format {%-21.
7540: 32 31 73 20 25 31 32 64 20 75 53 20 54 4f 54 41  21s %12d uS TOTA
7550: 4c 7d 20 24 6e 61 6d 65 20 24 74 6f 74 61 6c 5f  L} $name $total_
7560: 74 69 6d 65 5d 0a 0a 20 20 69 66 20 7b 20 30 20  time]..  if { 0 
7570: 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 20  } {.    sqlite3 
7580: 76 65 72 73 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a  versdb :memory:.
7590: 20 20 20 20 73 65 74 20 76 65 72 73 20 5b 6c 69      set vers [li
75a0: 6e 64 65 78 20 5b 76 65 72 73 64 62 20 6f 6e 65  ndex [versdb one
75b0: 20 7b 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f   {SELECT sqlite_
75c0: 73 6f 75 72 63 65 5f 69 64 28 29 7d 5d 20 30 5d  source_id()}] 0]
75d0: 0a 20 20 20 20 76 65 72 73 64 62 20 63 6c 6f 73  .    versdb clos
75e0: 65 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 43  e.    output2 "C
75f0: 52 45 41 54 45 20 54 41 42 4c 45 20 49 46 20 4e  REATE TABLE IF N
7600: 4f 54 20 45 58 49 53 54 53 20 74 69 6d 65 28 76  OT EXISTS time(v
7610: 65 72 73 69 6f 6e 2c 20 73 63 72 69 70 74 2c 20  ersion, script, 
7620: 74 65 73 74 2c 20 75 73 29 3b 22 0a 20 20 20 20  test, us);".    
7630: 66 6f 72 65 61 63 68 20 7b 74 65 73 74 20 75 73  foreach {test us
7640: 7d 20 24 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  } $::speed_trial
7650: 5f 74 69 6d 65 73 20 7b 0a 20 20 20 20 20 20 6f  _times {.      o
7660: 75 74 70 75 74 32 20 22 49 4e 53 45 52 54 20 49  utput2 "INSERT I
7670: 4e 54 4f 20 74 69 6d 65 20 56 41 4c 55 45 53 28  NTO time VALUES(
7680: 27 24 76 65 72 73 27 2c 20 27 24 6e 61 6d 65 27  '$vers', '$name'
7690: 2c 20 27 24 74 65 73 74 27 2c 20 24 75 73 29 3b  , '$test', $us);
76a0: 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 23  ".    }.  }.}..#
76b0: 20 52 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e   Run this routin
76c0: 65 20 6c 61 73 74 0a 23 0a 70 72 6f 63 20 66 69  e last.#.proc fi
76d0: 6e 69 73 68 5f 74 65 73 74 20 7b 7d 20 7b 0a 20  nish_test {} {. 
76e0: 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65   catch {db close
76f0: 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 31 20 63  }.  catch {db1 c
7700: 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64  lose}.  catch {d
7710: 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  b2 close}.  catc
7720: 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 20 20  h {db3 close}.  
7730: 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69  if {0==[info exi
7740: 73 74 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 20  sts ::SLAVE]} { 
7750: 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67  finalize_testing
7760: 20 7d 0a 7d 0a 70 72 6f 63 20 66 69 6e 61 6c 69   }.}.proc finali
7770: 7a 65 5f 74 65 73 74 69 6e 67 20 7b 7d 20 7b 0a  ze_testing {} {.
7780: 20 20 67 6c 6f 62 61 6c 20 73 71 6c 69 74 65 5f    global sqlite_
7790: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a  open_file_count.
77a0: 0a 20 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20  .  set omitList 
77b0: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
77c0: 72 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 0a 20 20  r omit_list]..  
77d0: 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d  catch {db close}
77e0: 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c  .  catch {db2 cl
77f0: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
7800: 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 76 66 73 5f  3 close}..  vfs_
7810: 75 6e 6c 69 6e 6b 5f 74 65 73 74 0a 20 20 73 71  unlink_test.  sq
7820: 6c 69 74 65 33 20 64 62 20 7b 7d 0a 20 20 23 20  lite3 db {}.  # 
7830: 73 71 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74 73  sqlite3_clear_ts
7840: 64 5f 6d 65 6d 64 65 62 75 67 0a 20 20 64 62 20  d_memdebug.  db 
7850: 63 6c 6f 73 65 0a 20 20 73 71 6c 69 74 65 33 5f  close.  sqlite3_
7860: 72 65 73 65 74 5f 61 75 74 6f 5f 65 78 74 65 6e  reset_auto_exten
7870: 73 69 6f 6e 0a 0a 20 20 73 71 6c 69 74 65 33 5f  sion..  sqlite3_
7880: 73 6f 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20  soft_heap_limit 
7890: 30 0a 20 20 73 65 74 20 6e 54 65 73 74 20 5b 69  0.  set nTest [i
78a0: 6e 63 72 5f 6e 74 65 73 74 5d 0a 20 20 73 65 74  ncr_ntest].  set
78b0: 20 6e 45 72 72 20 5b 73 65 74 5f 74 65 73 74 5f   nErr [set_test_
78c0: 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a  counter errors].
78d0: 0a 20 20 73 65 74 20 6e 4b 6e 6f 77 6e 20 30 0a  .  set nKnown 0.
78e0: 20 20 69 66 20 7b 5b 66 69 6c 65 20 72 65 61 64    if {[file read
78f0: 61 62 6c 65 20 6b 6e 6f 77 6e 2d 70 72 6f 62 6c  able known-probl
7900: 65 6d 73 2e 74 78 74 5d 7d 20 7b 0a 20 20 20 20  ems.txt]} {.    
7910: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 6b 6e 6f  set fd [open kno
7920: 77 6e 2d 70 72 6f 62 6c 65 6d 73 2e 74 78 74 5d  wn-problems.txt]
7930: 0a 20 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74  .    set content
7940: 20 5b 72 65 61 64 20 24 66 64 5d 0a 20 20 20 20   [read $fd].    
7950: 63 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 66 6f  close $fd.    fo
7960: 72 65 61 63 68 20 78 20 24 63 6f 6e 74 65 6e 74  reach x $content
7970: 20 7b 73 65 74 20 6b 6e 6f 77 6e 5f 65 72 72 6f   {set known_erro
7980: 72 28 24 78 29 20 31 7d 0a 20 20 20 20 66 6f 72  r($x) 1}.    for
7990: 65 61 63 68 20 78 20 5b 73 65 74 5f 74 65 73 74  each x [set_test
79a0: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
79b0: 73 74 5d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b  st] {.      if {
79c0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 6b 6e 6f  [info exists kno
79d0: 77 6e 5f 65 72 72 6f 72 28 24 78 29 5d 7d 20 7b  wn_error($x)]} {
79e0: 69 6e 63 72 20 6e 4b 6e 6f 77 6e 7d 0a 20 20 20  incr nKnown}.   
79f0: 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 4b   }.  }.  if {$nK
7a00: 6e 6f 77 6e 3e 30 7d 20 7b 0a 20 20 20 20 6f 75  nown>0} {.    ou
7a10: 74 70 75 74 32 20 22 5b 65 78 70 72 20 7b 24 6e  tput2 "[expr {$n
7a20: 45 72 72 2d 24 6e 4b 6e 6f 77 6e 7d 5d 20 6e 65  Err-$nKnown}] ne
7a30: 77 20 65 72 72 6f 72 73 20 61 6e 64 20 24 6e 4b  w errors and $nK
7a40: 6e 6f 77 6e 20 6b 6e 6f 77 6e 20 65 72 72 6f 72  nown known error
7a50: 73 5c 0a 20 20 20 20 20 20 20 20 20 6f 75 74 20  s\.         out 
7a60: 6f 66 20 24 6e 54 65 73 74 20 74 65 73 74 73 22  of $nTest tests"
7a70: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
7a80: 73 65 74 20 63 70 75 69 6e 66 6f 20 7b 7d 0a 20  set cpuinfo {}. 
7a90: 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 65     if {[catch {e
7aa0: 78 65 63 20 68 6f 73 74 6e 61 6d 65 7d 20 68 6e  xec hostname} hn
7ab0: 61 6d 65 5d 3d 3d 30 7d 20 7b 73 65 74 20 63 70  ame]==0} {set cp
7ac0: 75 69 6e 66 6f 20 5b 73 74 72 69 6e 67 20 74 72  uinfo [string tr
7ad0: 69 6d 20 24 68 6e 61 6d 65 5d 7d 0a 20 20 20 20  im $hname]}.    
7ae0: 61 70 70 65 6e 64 20 63 70 75 69 6e 66 6f 20 22  append cpuinfo "
7af0: 20 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d   $::tcl_platform
7b00: 28 6f 73 29 22 0a 20 20 20 20 61 70 70 65 6e 64  (os)".    append
7b10: 20 63 70 75 69 6e 66 6f 20 22 20 5b 65 78 70 72   cpuinfo " [expr
7b20: 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72   {$::tcl_platfor
7b30: 6d 28 70 6f 69 6e 74 65 72 53 69 7a 65 29 2a 38  m(pointerSize)*8
7b40: 7d 5d 2d 62 69 74 22 0a 20 20 20 20 61 70 70 65  }]-bit".    appe
7b50: 6e 64 20 63 70 75 69 6e 66 6f 20 22 20 5b 73 74  nd cpuinfo " [st
7b60: 72 69 6e 67 20 6d 61 70 20 7b 45 20 2d 65 7d 20  ring map {E -e} 
7b70: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
7b80: 62 79 74 65 4f 72 64 65 72 29 5d 22 0a 20 20 20  byteOrder)]".   
7b90: 20 6f 75 74 70 75 74 32 20 22 53 51 4c 69 74 65   output2 "SQLite
7ba0: 20 5b 73 71 6c 69 74 65 33 20 2d 73 6f 75 72 63   [sqlite3 -sourc
7bb0: 65 69 64 5d 22 0a 20 20 20 20 6f 75 74 70 75 74  eid]".    output
7bc0: 32 20 22 24 6e 45 72 72 20 65 72 72 6f 72 73 20  2 "$nErr errors 
7bd0: 6f 75 74 20 6f 66 20 24 6e 54 65 73 74 20 74 65  out of $nTest te
7be0: 73 74 73 20 6f 6e 20 24 63 70 75 69 6e 66 6f 22  sts on $cpuinfo"
7bf0: 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72  .  }.  if {$nErr
7c00: 3e 24 6e 4b 6e 6f 77 6e 7d 20 7b 0a 20 20 20 20  >$nKnown} {.    
7c10: 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69  output2 -nonewli
7c20: 6e 65 20 22 21 46 61 69 6c 75 72 65 73 20 6f 6e  ne "!Failures on
7c30: 20 74 68 65 73 65 20 74 65 73 74 73 3a 22 0a 20   these tests:". 
7c40: 20 20 20 66 6f 72 65 61 63 68 20 78 20 5b 73 65     foreach x [se
7c50: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66  t_test_counter f
7c60: 61 69 6c 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20  ail_list] {.    
7c70: 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69    if {![info exi
7c80: 73 74 73 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28  sts known_error(
7c90: 24 78 29 5d 7d 20 7b 6f 75 74 70 75 74 32 20 2d  $x)]} {output2 -
7ca0: 6e 6f 6e 65 77 6c 69 6e 65 20 22 20 24 78 22 7d  nonewline " $x"}
7cb0: 0a 20 20 20 20 7d 0a 20 20 20 20 6f 75 74 70 75  .    }.    outpu
7cc0: 74 32 20 22 22 0a 20 20 7d 0a 20 20 66 6f 72 65  t2 "".  }.  fore
7cd0: 61 63 68 20 77 61 72 6e 69 6e 67 20 5b 73 65 74  ach warning [set
7ce0: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 77 61  _test_counter wa
7cf0: 72 6e 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20 6f  rn_list] {.    o
7d00: 75 74 70 75 74 32 20 22 57 61 72 6e 69 6e 67 3a  utput2 "Warning:
7d10: 20 24 77 61 72 6e 69 6e 67 22 0a 20 20 7d 0a 20   $warning".  }. 
7d20: 20 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74   run_thread_test
7d30: 73 20 31 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  s 1.  if {[lleng
7d40: 74 68 20 24 6f 6d 69 74 4c 69 73 74 5d 3e 30 7d  th $omitList]>0}
7d50: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22   {.    output2 "
7d60: 4f 6d 69 74 74 65 64 20 74 65 73 74 20 63 61 73  Omitted test cas
7d70: 65 73 3a 22 0a 20 20 20 20 73 65 74 20 70 72 65  es:".    set pre
7d80: 63 20 7b 7d 0a 20 20 20 20 66 6f 72 65 61 63 68  c {}.    foreach
7d90: 20 7b 72 65 63 7d 20 5b 6c 73 6f 72 74 20 24 6f   {rec} [lsort $o
7da0: 6d 69 74 4c 69 73 74 5d 20 7b 0a 20 20 20 20 20  mitList] {.     
7db0: 20 69 66 20 7b 24 72 65 63 3d 3d 24 70 72 65 63   if {$rec==$prec
7dc0: 7d 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20  } continue.     
7dd0: 20 73 65 74 20 70 72 65 63 20 24 72 65 63 0a 20   set prec $rec. 
7de0: 20 20 20 20 20 6f 75 74 70 75 74 32 20 5b 66 6f       output2 [fo
7df0: 72 6d 61 74 20 7b 2e 20 20 25 2d 31 32 73 20 25  rmat {.  %-12s %
7e00: 73 7d 20 5b 6c 69 6e 64 65 78 20 24 72 65 63 20  s} [lindex $rec 
7e10: 30 5d 20 5b 6c 69 6e 64 65 78 20 24 72 65 63 20  0] [lindex $rec 
7e20: 31 5d 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  1]].    }.  }.  
7e30: 69 66 20 7b 24 6e 45 72 72 3e 30 20 26 26 20 21  if {$nErr>0 && !
7e40: 5b 77 6f 72 6b 69 6e 67 5f 36 34 62 69 74 5f 69  [working_64bit_i
7e50: 6e 74 5d 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75  nt]} {.    outpu
7e60: 74 32 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  t2 "************
7e70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7e80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7e90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ea0: 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20 6f 75 74 70  ******".    outp
7eb0: 75 74 32 20 22 4e 2e 42 2e 3a 20 20 54 68 65 20  ut2 "N.B.:  The 
7ec0: 76 65 72 73 69 6f 6e 20 6f 66 20 54 43 4c 20 74  version of TCL t
7ed0: 68 61 74 20 79 6f 75 20 75 73 65 64 20 74 6f 20  hat you used to 
7ee0: 62 75 69 6c 64 20 74 68 69 73 20 74 65 73 74 20  build this test 
7ef0: 68 61 72 6e 65 73 73 22 0a 20 20 20 20 6f 75 74  harness".    out
7f00: 70 75 74 32 20 22 69 73 20 64 65 66 65 63 74 69  put2 "is defecti
7f10: 76 65 20 69 6e 20 74 68 61 74 20 69 74 20 64 6f  ve in that it do
7f20: 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 36  es not support 6
7f30: 34 2d 62 69 74 20 69 6e 74 65 67 65 72 73 2e 20  4-bit integers. 
7f40: 20 53 6f 6d 65 20 6f 72 22 0a 20 20 20 20 6f 75   Some or".    ou
7f50: 74 70 75 74 32 20 22 61 6c 6c 20 6f 66 20 74 68  tput2 "all of th
7f60: 65 20 74 65 73 74 20 66 61 69 6c 75 72 65 73 20  e test failures 
7f70: 61 62 6f 76 65 20 6d 69 67 68 74 20 62 65 20 61  above might be a
7f80: 20 72 65 73 75 6c 74 20 66 72 6f 6d 20 74 68 69   result from thi
7f90: 73 20 64 65 66 65 63 74 22 0a 20 20 20 20 6f 75  s defect".    ou
7fa0: 74 70 75 74 32 20 22 69 6e 20 79 6f 75 72 20 54  tput2 "in your T
7fb0: 43 4c 20 62 75 69 6c 64 2e 22 0a 20 20 20 20 6f  CL build.".    o
7fc0: 75 74 70 75 74 32 20 22 2a 2a 2a 2a 2a 2a 2a 2a  utput2 "********
7fd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7fe0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ff0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8000: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 7d 0a  **********".  }.
8010: 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65    if {$::cmdline
8020: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20  arg(binarylog)} 
8030: 7b 0a 20 20 20 20 76 66 73 6c 6f 67 20 66 69 6e  {.    vfslog fin
8040: 61 6c 69 7a 65 20 62 69 6e 61 72 79 6c 6f 67 0a  alize binarylog.
8050: 20 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c 69 74    }.  if {$sqlit
8060: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
8070: 74 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  t} {.    output2
8080: 20 22 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66   "$sqlite_open_f
8090: 69 6c 65 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20  ile_count files 
80a0: 77 65 72 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a  were left open".
80b0: 20 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20      incr nErr.  
80c0: 7d 0a 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20  }.  if {[lindex 
80d0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
80e0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41  SQLITE_STATUS_MA
80f0: 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d  LLOC_COUNT 0] 1]
8100: 3e 30 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20  >0 ||.          
8110: 20 20 20 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d      [sqlite3_mem
8120: 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20  ory_used]>0} {. 
8130: 20 20 20 6f 75 74 70 75 74 32 20 22 55 6e 66 72     output2 "Unfr
8140: 65 65 64 20 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c  eed memory: [sql
8150: 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64  ite3_memory_used
8160: 5d 20 62 79 74 65 73 20 69 6e 5c 0a 20 20 20 20  ] bytes in\.    
8170: 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 5b 73 71       [lindex [sq
8180: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
8190: 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f  ITE_STATUS_MALLO
81a0: 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d 20 61 6c  C_COUNT 0] 1] al
81b0: 6c 6f 63 61 74 69 6f 6e 73 22 0a 20 20 20 20 69  locations".    i
81c0: 6e 63 72 20 6e 45 72 72 0a 20 20 20 20 69 66 63  ncr nErr.    ifc
81d0: 61 70 61 62 6c 65 20 6d 65 6d 64 65 62 75 67 7c  apable memdebug|
81e0: 7c 6d 65 6d 35 7c 7c 28 6d 65 6d 33 26 26 64 65  |mem5||(mem3&&de
81f0: 62 75 67 29 20 7b 0a 20 20 20 20 20 20 6f 75 74  bug) {.      out
8200: 70 75 74 32 20 22 57 72 69 74 69 6e 67 20 75 6e  put2 "Writing un
8210: 66 72 65 65 64 20 6d 65 6d 6f 72 79 20 6c 6f 67  freed memory log
8220: 20 74 6f 20 5c 22 2e 2f 6d 65 6d 6c 65 61 6b 2e   to \"./memleak.
8230: 74 78 74 5c 22 22 0a 20 20 20 20 20 20 73 71 6c  txt\"".      sql
8240: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75  ite3_memdebug_du
8250: 6d 70 20 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74  mp ./memleak.txt
8260: 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20  .    }.  } else 
8270: 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 41  {.    output2 "A
8280: 6c 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  ll memory alloca
8290: 74 69 6f 6e 73 20 66 72 65 65 64 20 2d 20 6e 6f  tions freed - no
82a0: 20 6c 65 61 6b 73 22 0a 20 20 20 20 69 66 63 61   leaks".    ifca
82b0: 70 61 62 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c  pable memdebug||
82c0: 6d 65 6d 35 20 7b 0a 20 20 20 20 20 20 73 71 6c  mem5 {.      sql
82d0: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75  ite3_memdebug_du
82e0: 6d 70 20 2e 2f 6d 65 6d 75 73 61 67 65 2e 74 78  mp ./memusage.tx
82f0: 74 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 68  t.    }.  }.  sh
8300: 6f 77 5f 6d 65 6d 73 74 61 74 73 0a 20 20 6f 75  ow_memstats.  ou
8310: 74 70 75 74 32 20 22 4d 61 78 69 6d 75 6d 20 6d  tput2 "Maximum m
8320: 65 6d 6f 72 79 20 75 73 61 67 65 3a 20 5b 73 71  emory usage: [sq
8330: 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 68 69 67  lite3_memory_hig
8340: 68 77 61 74 65 72 20 31 5d 20 62 79 74 65 73 22  hwater 1] bytes"
8350: 0a 20 20 6f 75 74 70 75 74 32 20 22 43 75 72 72  .  output2 "Curr
8360: 65 6e 74 20 6d 65 6d 6f 72 79 20 75 73 61 67 65  ent memory usage
8370: 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72  : [sqlite3_memor
8380: 79 5f 68 69 67 68 77 61 74 65 72 5d 20 62 79 74  y_highwater] byt
8390: 65 73 22 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20  es".  if {[info 
83a0: 63 6f 6d 6d 61 6e 64 73 20 73 71 6c 69 74 65 33  commands sqlite3
83b0: 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63  _memdebug_malloc
83c0: 5f 63 6f 75 6e 74 5d 20 6e 65 20 22 22 7d 20 7b  _count] ne ""} {
83d0: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 4e 75  .    output2 "Nu
83e0: 6d 62 65 72 20 6f 66 20 6d 61 6c 6c 6f 63 28 29  mber of malloc()
83f0: 20 20 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d    : [sqlite3_mem
8400: 64 65 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75  debug_malloc_cou
8410: 6e 74 5d 20 63 61 6c 6c 73 22 0a 20 20 7d 0a 20  nt] calls".  }. 
8420: 20 69 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65 61   if {$::cmdlinea
8430: 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d  rg(malloctrace)}
8440: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22   {.    output2 "
8450: 57 72 69 74 69 6e 67 20 6d 61 6c 6c 6f 63 73 2e  Writing mallocs.
8460: 73 71 6c 2e 2e 2e 22 0a 20 20 20 20 6d 65 6d 64  sql...".    memd
8470: 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 0a 20 20 20  ebug_log_sql.   
8480: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
8490: 67 5f 6c 6f 67 20 73 74 6f 70 0a 20 20 20 20 73  g_log stop.    s
84a0: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
84b0: 6c 6f 67 20 63 6c 65 61 72 0a 0a 20 20 20 20 69  log clear..    i
84c0: 66 20 7b 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f  f {[sqlite3_memo
84d0: 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20 20  ry_used]>0} {.  
84e0: 20 20 20 20 6f 75 74 70 75 74 32 20 22 57 72 69      output2 "Wri
84f0: 74 69 6e 67 20 6c 65 61 6b 73 2e 73 71 6c 2e 2e  ting leaks.sql..
8500: 2e 22 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  .".      sqlite3
8510: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 79  _memdebug_log sy
8520: 6e 63 0a 20 20 20 20 20 20 6d 65 6d 64 65 62 75  nc.      memdebu
8530: 67 5f 6c 6f 67 5f 73 71 6c 20 6c 65 61 6b 73 2e  g_log_sql leaks.
8540: 73 71 6c 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  sql.    }.  }.  
8550: 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20  foreach f [glob 
8560: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74  -nocomplain test
8570: 2e 64 62 2d 2a 2d 6a 6f 75 72 6e 61 6c 5d 20 7b  .db-*-journal] {
8580: 0a 20 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65  .    forcedelete
8590: 20 24 66 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63   $f.  }.  foreac
85a0: 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
85b0: 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d 6d 6a  plain test.db-mj
85c0: 2a 5d 20 7b 0a 20 20 20 20 66 6f 72 63 65 64 65  *] {.    forcede
85d0: 6c 65 74 65 20 24 66 0a 20 20 7d 0a 20 20 65 78  lete $f.  }.  ex
85e0: 69 74 20 5b 65 78 70 72 20 7b 24 6e 45 72 72 3e  it [expr {$nErr>
85f0: 30 7d 5d 0a 7d 0a 0a 23 20 44 69 73 70 6c 61 79  0}].}..# Display
8600: 20 6d 65 6d 6f 72 79 20 73 74 61 74 69 73 74 69   memory statisti
8610: 63 73 20 66 6f 72 20 61 6e 61 6c 79 73 69 73 20  cs for analysis 
8620: 61 6e 64 20 64 65 62 75 67 67 69 6e 67 20 70 75  and debugging pu
8630: 72 70 6f 73 65 73 2e 0a 23 0a 70 72 6f 63 20 73  rposes..#.proc s
8640: 68 6f 77 5f 6d 65 6d 73 74 61 74 73 20 7b 7d 20  how_memstats {} 
8650: 7b 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74  {.  set x [sqlit
8660: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
8670: 5f 53 54 41 54 55 53 5f 4d 45 4d 4f 52 59 5f 55  _STATUS_MEMORY_U
8680: 53 45 44 20 30 5d 0a 20 20 73 65 74 20 79 20 5b  SED 0].  set y [
8690: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
86a0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c  QLITE_STATUS_MAL
86b0: 4c 4f 43 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65  LOC_SIZE 0].  se
86c0: 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e  t val [format {n
86d0: 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31 30  ow %10d  max %10
86e0: 64 20 20 6d 61 78 2d 73 69 7a 65 20 25 31 30 64  d  max-size %10d
86f0: 7d 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  } \.            
8700: 20 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20    [lindex $x 1] 
8710: 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c  [lindex $x 2] [l
8720: 69 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f  index $y 2]].  o
8730: 75 74 70 75 74 31 20 22 4d 65 6d 6f 72 79 20 75  utput1 "Memory u
8740: 73 65 64 3a 20 20 20 20 20 20 20 20 20 20 24 76  sed:          $v
8750: 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c  al".  set x [sql
8760: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
8770: 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43  TE_STATUS_MALLOC
8780: 5f 43 4f 55 4e 54 20 30 5d 0a 20 20 73 65 74 20  _COUNT 0].  set 
8790: 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77  val [format {now
87a0: 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d   %10d  max %10d}
87b0: 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b   [lindex $x 1] [
87c0: 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20  lindex $x 2]].  
87d0: 6f 75 74 70 75 74 31 20 22 41 6c 6c 6f 63 61 74  output1 "Allocat
87e0: 69 6f 6e 20 63 6f 75 6e 74 3a 20 20 20 20 20 24  ion count:     $
87f0: 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71  val".  set x [sq
8800: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
8810: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
8820: 41 43 48 45 5f 55 53 45 44 20 30 5d 0a 20 20 73  ACHE_USED 0].  s
8830: 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74  et y [sqlite3_st
8840: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
8850: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a  US_PAGECACHE_SIZ
8860: 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b  E 0].  set val [
8870: 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64  format {now %10d
8880: 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d    max %10d  max-
8890: 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20  size %10d} \.   
88a0: 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64             [lind
88b0: 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78  ex $x 1] [lindex
88c0: 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24   $x 2] [lindex $
88d0: 79 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74 31 20  y 2]].  output1 
88e0: 22 50 61 67 65 2d 63 61 63 68 65 20 75 73 65 64  "Page-cache used
88f0: 3a 20 20 20 20 20 20 24 76 61 6c 22 0a 20 20 73  :      $val".  s
8900: 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74  et x [sqlite3_st
8910: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
8920: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45  US_PAGECACHE_OVE
8930: 52 46 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 76  RFLOW 0].  set v
8940: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
8950: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20  %10d  max %10d} 
8960: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
8970: 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 6f  index $x 2]].  o
8980: 75 74 70 75 74 31 20 22 50 61 67 65 2d 63 61 63  utput1 "Page-cac
8990: 68 65 20 6f 76 65 72 66 6c 6f 77 3a 20 20 24 76  he overflow:  $v
89a0: 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c  al".  set x [sql
89b0: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
89c0: 54 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43  TE_STATUS_SCRATC
89d0: 48 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20  H_USED 0].  set 
89e0: 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77  val [format {now
89f0: 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d   %10d  max %10d}
8a00: 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b   [lindex $x 1] [
8a10: 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20  lindex $x 2]].  
8a20: 6f 75 74 70 75 74 31 20 22 53 63 72 61 74 63 68  output1 "Scratch
8a30: 20 6d 65 6d 6f 72 79 20 75 73 65 64 3a 20 20 24   memory used:  $
8a40: 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71  val".  set x [sq
8a50: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
8a60: 49 54 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54  ITE_STATUS_SCRAT
8a70: 43 48 5f 4f 56 45 52 46 4c 4f 57 20 30 5d 0a 20  CH_OVERFLOW 0]. 
8a80: 20 73 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f   set y [sqlite3_
8a90: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
8aa0: 41 54 55 53 5f 53 43 52 41 54 43 48 5f 53 49 5a  ATUS_SCRATCH_SIZ
8ab0: 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b  E 0].  set val [
8ac0: 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64  format {now %10d
8ad0: 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d    max %10d  max-
8ae0: 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20  size %10d} \.   
8af0: 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e              [lin
8b00: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
8b10: 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20  x $x 2] [lindex 
8b20: 24 79 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74 31  $y 2]].  output1
8b30: 20 22 53 63 72 61 74 63 68 20 6f 76 65 72 66 6c   "Scratch overfl
8b40: 6f 77 3a 20 20 20 20 20 24 76 61 6c 22 0a 20 20  ow:     $val".  
8b50: 69 66 63 61 70 61 62 6c 65 20 79 79 74 72 61 63  ifcapable yytrac
8b60: 6b 6d 61 78 73 74 61 63 6b 64 65 70 74 68 20 7b  kmaxstackdepth {
8b70: 0a 20 20 20 20 73 65 74 20 78 20 5b 73 71 6c 69  .    set x [sqli
8b80: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
8b90: 45 5f 53 54 41 54 55 53 5f 50 41 52 53 45 52 5f  E_STATUS_PARSER_
8ba0: 53 54 41 43 4b 20 30 5d 0a 20 20 20 20 73 65 74  STACK 0].    set
8bb0: 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 20 20   val [format {  
8bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 61 78               max
8bd0: 20 25 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24   %10d} [lindex $
8be0: 78 20 32 5d 5d 0a 20 20 20 20 6f 75 74 70 75 74  x 2]].    output
8bf0: 32 20 22 50 61 72 73 65 72 20 73 74 61 63 6b 20  2 "Parser stack 
8c00: 64 65 70 74 68 3a 20 20 20 20 24 76 61 6c 22 0a  depth:    $val".
8c10: 20 20 7d 0a 7d 0a 0a 23 20 41 20 70 72 6f 63 65    }.}..# A proce
8c20: 64 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20  dure to execute 
8c30: 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65 63 73  SQL.#.proc execs
8c40: 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d  ql {sql {db db}}
8c50: 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c   {.  # puts "SQL
8c60: 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c 65 76   = $sql".  uplev
8c70: 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61  el [list $db eva
8c80: 6c 20 24 73 71 6c 5d 0a 7d 0a 70 72 6f 63 20 65  l $sql].}.proc e
8c90: 78 65 63 73 71 6c 5f 74 69 6d 65 64 20 7b 73 71  xecsql_timed {sq
8ca0: 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73  l {db db}} {.  s
8cb0: 65 74 20 74 6d 20 5b 74 69 6d 65 20 7b 0a 20 20  et tm [time {.  
8cc0: 20 20 73 65 74 20 78 20 5b 75 70 6c 65 76 65 6c    set x [uplevel
8cd0: 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c 20   [list $db eval 
8ce0: 24 73 71 6c 5d 5d 0a 20 20 7d 20 31 5d 0a 20 20  $sql]].  } 1].  
8cf0: 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24  set tm [lindex $
8d00: 74 6d 20 30 5d 0a 20 20 6f 75 74 70 75 74 31 20  tm 0].  output1 
8d10: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 20 28 5b 65  -nonewline " ([e
8d20: 78 70 72 20 7b 24 74 6d 2a 30 2e 30 30 31 7d 5d  xpr {$tm*0.001}]
8d30: 6d 73 29 20 22 0a 20 20 73 65 74 20 78 0a 7d 0a  ms) ".  set x.}.
8d40: 0a 23 20 45 78 65 63 75 74 65 20 53 51 4c 20 61  .# Execute SQL a
8d50: 6e 64 20 63 61 74 63 68 20 65 78 63 65 70 74 69  nd catch excepti
8d60: 6f 6e 73 2e 0a 23 0a 70 72 6f 63 20 63 61 74 63  ons..#.proc catc
8d70: 68 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62  hsql {sql {db db
8d80: 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53  }} {.  # puts "S
8d90: 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 73 65 74  QL = $sql".  set
8da0: 20 72 20 5b 63 61 74 63 68 20 5b 6c 69 73 74 20   r [catch [list 
8db0: 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64  uplevel [list $d
8dc0: 62 20 65 76 61 6c 20 24 73 71 6c 5d 5d 20 6d 73  b eval $sql]] ms
8dd0: 67 5d 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24  g].  lappend r $
8de0: 6d 73 67 0a 20 20 72 65 74 75 72 6e 20 24 72 0a  msg.  return $r.
8df0: 7d 0a 0a 23 20 44 6f 20 61 6e 20 56 44 42 45 20  }..# Do an VDBE 
8e00: 63 6f 64 65 20 64 75 6d 70 20 6f 6e 20 74 68 65  code dump on the
8e10: 20 53 51 4c 20 67 69 76 65 6e 0a 23 0a 70 72 6f   SQL given.#.pro
8e20: 63 20 65 78 70 6c 61 69 6e 20 7b 73 71 6c 20 7b  c explain {sql {
8e30: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 6f 75 74 70  db db}} {.  outp
8e40: 75 74 32 20 22 22 0a 20 20 6f 75 74 70 75 74 32  ut2 "".  output2
8e50: 20 22 61 64 64 72 20 20 6f 70 63 6f 64 65 20 20   "addr  opcode  
8e60: 20 20 20 20 20 20 70 31 20 20 20 20 20 20 70 32        p1      p2
8e70: 20 20 20 20 20 20 70 33 20 20 20 20 20 20 70 34        p3      p4
8e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
8e90: 35 20 20 23 22 0a 20 20 6f 75 74 70 75 74 32 20  5  #".  output2 
8ea0: 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d  "----  ---------
8eb0: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
8ec0: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
8ed0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ------------  --
8ee0: 20 20 2d 22 0a 20 20 24 64 62 20 65 76 61 6c 20    -".  $db eval 
8ef0: 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b  "explain $sql" {
8f00: 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20  } {.    output2 
8f10: 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25  [format {%-4d  %
8f20: 2d 31 32 2e 31 32 73 20 20 25 2d 36 64 20 20 25  -12.12s  %-6d  %
8f30: 2d 36 64 20 20 25 2d 36 64 20 20 25 20 2d 31 37  -6d  %-6d  % -17
8f40: 73 20 25 73 20 20 25 73 7d 20 5c 0a 20 20 20 20  s %s  %s} \.    
8f50: 20 20 24 61 64 64 72 20 24 6f 70 63 6f 64 65 20    $addr $opcode 
8f60: 24 70 31 20 24 70 32 20 24 70 33 20 24 70 34 20  $p1 $p2 $p3 $p4 
8f70: 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20  $p5 $comment.   
8f80: 20 5d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65   ].  }.}..proc e
8f90: 78 70 6c 61 69 6e 5f 69 20 7b 73 71 6c 20 7b 64  xplain_i {sql {d
8fa0: 62 20 64 62 7d 7d 20 7b 0a 20 20 6f 75 74 70 75  b db}} {.  outpu
8fb0: 74 32 20 22 22 0a 20 20 6f 75 74 70 75 74 32 20  t2 "".  output2 
8fc0: 22 61 64 64 72 20 20 6f 70 63 6f 64 65 20 20 20  "addr  opcode   
8fd0: 20 20 20 20 20 70 31 20 20 20 20 20 20 70 32 20       p1      p2 
8fe0: 20 20 20 20 20 70 33 20 20 20 20 20 20 70 34 20       p3      p4 
8ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
9000: 35 20 20 23 22 0a 20 20 6f 75 74 70 75 74 32 20  5  #".  output2 
9010: 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d  "----  ---------
9020: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
9030: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
9040: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d  -------------  -
9050: 2d 20 20 2d 22 0a 0a 0a 20 20 23 20 53 65 74 20  -  -"...  # Set 
9060: 75 70 20 63 6f 6c 6f 72 73 20 66 6f 72 20 74 68  up colors for th
9070: 65 20 64 69 66 66 65 72 65 6e 74 20 6f 70 63 6f  e different opco
9080: 64 65 73 2e 20 53 63 68 65 6d 65 20 69 73 20 61  des. Scheme is a
9090: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20 20 23 0a 20  s follows:.  #. 
90a0: 20 23 20 20 20 52 65 64 3a 20 20 20 4f 70 63 6f   #   Red:   Opco
90b0: 64 65 73 20 74 68 61 74 20 77 72 69 74 65 20 74  des that write t
90c0: 6f 20 61 20 62 2d 74 72 65 65 2e 0a 20 20 23 20  o a b-tree..  # 
90d0: 20 20 42 6c 75 65 3a 20 20 4f 70 63 6f 64 65 73    Blue:  Opcodes
90e0: 20 74 68 61 74 20 72 65 70 6f 73 69 74 69 6f 6e   that reposition
90f0: 20 6f 72 20 73 65 65 6b 20 61 20 63 75 72 73 6f   or seek a curso
9100: 72 2e 20 0a 20 20 23 20 20 20 47 72 65 65 6e 3a  r. .  #   Green:
9110: 20 54 68 65 20 52 65 73 75 6c 74 52 6f 77 20 6f   The ResultRow o
9120: 70 63 6f 64 65 2e 0a 20 20 23 0a 20 20 69 66 20  pcode..  #.  if 
9130: 7b 20 5b 63 61 74 63 68 20 7b 66 63 6f 6e 66 69  { [catch {fconfi
9140: 67 75 72 65 20 73 74 64 6f 75 74 20 2d 6d 6f 64  gure stdout -mod
9150: 65 7d 5d 3d 3d 30 20 7d 20 7b 0a 20 20 20 20 73  e}]==0 } {.    s
9160: 65 74 20 52 20 22 5c 30 33 33 5c 5b 33 31 3b 31  et R "\033\[31;1
9170: 6d 22 20 20 20 20 20 20 20 20 3b 23 20 52 65 64  m"        ;# Red
9180: 20 66 67 0a 20 20 20 20 73 65 74 20 47 20 22 5c   fg.    set G "\
9190: 30 33 33 5c 5b 33 32 3b 31 6d 22 20 20 20 20 20  033\[32;1m"     
91a0: 20 20 20 3b 23 20 47 72 65 65 6e 20 66 67 0a 20     ;# Green fg. 
91b0: 20 20 20 73 65 74 20 42 20 22 5c 30 33 33 5c 5b     set B "\033\[
91c0: 33 34 3b 31 6d 22 20 20 20 20 20 20 20 20 3b 23  34;1m"        ;#
91d0: 20 52 65 64 20 66 67 0a 20 20 20 20 73 65 74 20   Red fg.    set 
91e0: 44 20 22 5c 30 33 33 5c 5b 33 39 3b 30 6d 22 20  D "\033\[39;0m" 
91f0: 20 20 20 20 20 20 20 3b 23 20 44 65 66 61 75 6c         ;# Defaul
9200: 74 20 66 67 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  t fg.  } else {.
9210: 20 20 20 20 73 65 74 20 52 20 22 22 0a 20 20 20      set R "".   
9220: 20 73 65 74 20 47 20 22 22 0a 20 20 20 20 73 65   set G "".    se
9230: 74 20 42 20 22 22 0a 20 20 20 20 73 65 74 20 44  t B "".    set D
9240: 20 22 22 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63   "".  }.  foreac
9250: 68 20 6f 70 63 6f 64 65 20 7b 0a 20 20 20 20 20  h opcode {.     
9260: 20 53 65 65 6b 20 53 65 65 6b 47 65 20 53 65 65   Seek SeekGe See
9270: 6b 47 74 20 53 65 65 6b 4c 65 20 53 65 65 6b 4c  kGt SeekLe SeekL
9280: 74 20 4e 6f 74 46 6f 75 6e 64 20 4c 61 73 74 20  t NotFound Last 
9290: 52 65 77 69 6e 64 0a 20 20 20 20 20 20 4e 6f 43  Rewind.      NoC
92a0: 6f 6e 66 6c 69 63 74 20 4e 65 78 74 20 50 72 65  onflict Next Pre
92b0: 76 20 56 4e 65 78 74 20 56 50 72 65 76 20 56 46  v VNext VPrev VF
92c0: 69 6c 74 65 72 0a 20 20 20 20 20 20 53 6f 72 74  ilter.      Sort
92d0: 65 72 53 6f 72 74 20 53 6f 72 74 65 72 4e 65 78  erSort SorterNex
92e0: 74 0a 20 20 7d 20 7b 0a 20 20 20 20 73 65 74 20  t.  } {.    set 
92f0: 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 24  color($opcode) $
9300: 42 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  B.  }.  foreach 
9310: 6f 70 63 6f 64 65 20 7b 52 65 73 75 6c 74 52 6f  opcode {ResultRo
9320: 77 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6c  w} {.    set col
9330: 6f 72 28 24 6f 70 63 6f 64 65 29 20 24 47 0a 20  or($opcode) $G. 
9340: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 6f 70 63   }.  foreach opc
9350: 6f 64 65 20 7b 49 64 78 49 6e 73 65 72 74 20 49  ode {IdxInsert I
9360: 6e 73 65 72 74 20 44 65 6c 65 74 65 20 49 64 78  nsert Delete Idx
9370: 44 65 6c 65 74 65 7d 20 7b 0a 20 20 20 20 73 65  Delete} {.    se
9380: 74 20 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29  t color($opcode)
9390: 20 24 52 0a 20 20 7d 0a 0a 20 20 73 65 74 20 62   $R.  }..  set b
93a0: 53 65 65 6e 47 6f 74 6f 20 30 0a 20 20 24 64 62  SeenGoto 0.  $db
93b0: 20 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24   eval "explain $
93c0: 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 73 65  sql" {} {.    se
93d0: 74 20 78 28 24 61 64 64 72 29 20 30 0a 20 20 20  t x($addr) 0.   
93e0: 20 73 65 74 20 6f 70 28 24 61 64 64 72 29 20 24   set op($addr) $
93f0: 6f 70 63 6f 64 65 0a 0a 20 20 20 20 69 66 20 7b  opcode..    if {
9400: 24 6f 70 63 6f 64 65 20 3d 3d 20 22 47 6f 74 6f  $opcode == "Goto
9410: 22 20 26 26 20 28 24 62 53 65 65 6e 47 6f 74 6f  " && ($bSeenGoto
9420: 3d 3d 30 20 7c 7c 20 28 24 70 32 20 3e 20 24 61  ==0 || ($p2 > $a
9430: 64 64 72 2b 31 30 29 29 7d 20 7b 0a 20 20 20 20  ddr+10))} {.    
9440: 20 20 73 65 74 20 6c 69 6e 65 62 72 65 61 6b 28    set linebreak(
9450: 24 70 32 29 20 31 0a 20 20 20 20 20 20 73 65 74  $p2) 1.      set
9460: 20 62 53 65 65 6e 47 6f 74 6f 20 31 0a 20 20 20   bSeenGoto 1.   
9470: 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63   }..    if {$opc
9480: 6f 64 65 3d 3d 22 4e 65 78 74 22 20 20 7c 7c 20  ode=="Next"  || 
9490: 24 6f 70 63 6f 64 65 3d 3d 22 50 72 65 76 22 20  $opcode=="Prev" 
94a0: 0a 20 20 20 20 20 7c 7c 20 24 6f 70 63 6f 64 65  .     || $opcode
94b0: 3d 3d 22 56 4e 65 78 74 22 20 7c 7c 20 24 6f 70  =="VNext" || $op
94c0: 63 6f 64 65 3d 3d 22 56 50 72 65 76 22 0a 20 20  code=="VPrev".  
94d0: 20 20 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22     || $opcode=="
94e0: 53 6f 72 74 65 72 4e 65 78 74 22 0a 20 20 20 20  SorterNext".    
94f0: 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73  } {.      for {s
9500: 65 74 20 69 20 24 70 32 7d 20 7b 24 69 3c 24 61  et i $p2} {$i<$a
9510: 64 64 72 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a  ddr} {incr i} {.
9520: 20 20 20 20 20 20 20 20 69 6e 63 72 20 78 28 24          incr x($
9530: 69 29 20 32 0a 20 20 20 20 20 20 7d 0a 20 20 20  i) 2.      }.   
9540: 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 63   }..    if {$opc
9550: 6f 64 65 20 3d 3d 20 22 47 6f 74 6f 22 20 26 26  ode == "Goto" &&
9560: 20 24 70 32 3c 24 61 64 64 72 20 26 26 20 24 6f   $p2<$addr && $o
9570: 70 28 24 70 32 29 3d 3d 22 59 69 65 6c 64 22 7d  p($p2)=="Yield"}
9580: 20 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65   {.      for {se
9590: 74 20 69 20 5b 65 78 70 72 20 24 70 32 2b 31 5d  t i [expr $p2+1]
95a0: 7d 20 7b 24 69 3c 24 61 64 64 72 7d 20 7b 69 6e  } {$i<$addr} {in
95b0: 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20  cr i} {.        
95c0: 69 6e 63 72 20 78 28 24 69 29 20 32 0a 20 20 20  incr x($i) 2.   
95d0: 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
95e0: 69 66 20 7b 24 6f 70 63 6f 64 65 20 3d 3d 20 22  if {$opcode == "
95f0: 48 61 6c 74 22 20 26 26 20 24 63 6f 6d 6d 65 6e  Halt" && $commen
9600: 74 20 3d 3d 20 22 45 6e 64 20 6f 66 20 63 6f 72  t == "End of cor
9610: 6f 75 74 69 6e 65 22 7d 20 7b 0a 20 20 20 20 20  outine"} {.     
9620: 20 73 65 74 20 6c 69 6e 65 62 72 65 61 6b 28 5b   set linebreak([
9630: 65 78 70 72 20 24 61 64 64 72 2b 31 5d 29 20 31  expr $addr+1]) 1
9640: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 24 64  .    }.  }..  $d
9650: 62 20 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20  b eval "explain 
9660: 24 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 69  $sql" {} {.    i
9670: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
9680: 6c 69 6e 65 62 72 65 61 6b 28 24 61 64 64 72 29  linebreak($addr)
9690: 5d 7d 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75  ]} {.      outpu
96a0: 74 32 20 22 22 0a 20 20 20 20 7d 0a 20 20 20 20  t2 "".    }.    
96b0: 73 65 74 20 49 20 5b 73 74 72 69 6e 67 20 72 65  set I [string re
96c0: 70 65 61 74 20 22 20 22 20 24 78 28 24 61 64 64  peat " " $x($add
96d0: 72 29 5d 0a 0a 20 20 20 20 73 65 74 20 63 6f 6c  r)]..    set col
96e0: 20 22 22 0a 20 20 20 20 63 61 74 63 68 20 7b 20   "".    catch { 
96f0: 73 65 74 20 63 6f 6c 20 24 63 6f 6c 6f 72 28 24  set col $color($
9700: 6f 70 63 6f 64 65 29 20 7d 0a 0a 20 20 20 20 6f  opcode) }..    o
9710: 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b  utput2 [format {
9720: 25 2d 34 64 20 20 25 73 25 73 25 2d 31 32 2e 31  %-4d  %s%s%-12.1
9730: 32 73 25 73 20 20 25 2d 36 64 20 20 25 2d 36 64  2s%s  %-6d  %-6d
9740: 20 20 25 2d 36 64 20 20 25 20 2d 31 37 73 20 25    %-6d  % -17s %
9750: 73 20 20 25 73 7d 20 5c 0a 20 20 20 20 20 20 24  s  %s} \.      $
9760: 61 64 64 72 20 24 49 20 24 63 6f 6c 20 24 6f 70  addr $I $col $op
9770: 63 6f 64 65 20 24 44 20 24 70 31 20 24 70 32 20  code $D $p1 $p2 
9780: 24 70 33 20 24 70 34 20 24 70 35 20 24 63 6f 6d  $p3 $p4 $p5 $com
9790: 6d 65 6e 74 0a 20 20 20 20 5d 0a 20 20 7d 0a 20  ment.    ].  }. 
97a0: 20 6f 75 74 70 75 74 32 20 22 2d 2d 2d 2d 20 20   output2 "----  
97b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ------------  --
97c0: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ----  ------  --
97d0: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----  ----------
97e0: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20 20 2d 22 0a 7d  ------  --  -".}
97f0: 0a 0a 23 20 53 68 6f 77 20 74 68 65 20 56 44 42  ..# Show the VDB
9800: 45 20 70 72 6f 67 72 61 6d 20 66 6f 72 20 61 6e  E program for an
9810: 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 62   SQL statement b
9820: 75 74 20 6f 6d 69 74 20 74 68 65 20 54 72 61 63  ut omit the Trac
9830: 65 0a 23 20 6f 70 63 6f 64 65 20 61 74 20 74 68  e.# opcode at th
9840: 65 20 62 65 67 69 6e 6e 69 6e 67 2e 20 20 54 68  e beginning.  Th
9850: 69 73 20 70 72 6f 63 65 64 75 72 65 20 63 61 6e  is procedure can
9860: 20 62 65 20 75 73 65 64 20 74 6f 20 70 72 6f 76   be used to prov
9870: 65 0a 23 20 74 68 61 74 20 64 69 66 66 65 72 65  e.# that differe
9880: 6e 74 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  nt SQL statement
9890: 73 20 67 65 6e 65 72 61 74 65 20 65 78 61 63 74  s generate exact
98a0: 6c 79 20 74 68 65 20 73 61 6d 65 20 56 44 42 45  ly the same VDBE
98b0: 20 63 6f 64 65 2e 0a 23 0a 70 72 6f 63 20 65 78   code..#.proc ex
98c0: 70 6c 61 69 6e 5f 6e 6f 5f 74 72 61 63 65 20 7b  plain_no_trace {
98d0: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 74 72 20  sql} {.  set tr 
98e0: 5b 64 62 20 65 76 61 6c 20 22 45 58 50 4c 41 49  [db eval "EXPLAI
98f0: 4e 20 24 73 71 6c 22 5d 0a 20 20 72 65 74 75 72  N $sql"].  retur
9900: 6e 20 5b 6c 72 61 6e 67 65 20 24 74 72 20 37 20  n [lrange $tr 7 
9910: 65 6e 64 5d 0a 7d 0a 0a 23 20 41 6e 6f 74 68 65  end].}..# Anothe
9920: 72 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65  r procedure to e
9930: 78 65 63 75 74 65 20 53 51 4c 2e 20 20 54 68 69  xecute SQL.  Thi
9940: 73 20 6f 6e 65 20 69 6e 63 6c 75 64 65 73 20 74  s one includes t
9950: 68 65 20 66 69 65 6c 64 0a 23 20 6e 61 6d 65 73  he field.# names
9960: 20 69 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64   in the returned
9970: 20 6c 69 73 74 2e 0a 23 0a 70 72 6f 63 20 65 78   list..#.proc ex
9980: 65 63 73 71 6c 32 20 7b 73 71 6c 7d 20 7b 0a 20  ecsql2 {sql} {. 
9990: 20 73 65 74 20 72 65 73 75 6c 74 20 7b 7d 0a 20   set result {}. 
99a0: 20 64 62 20 65 76 61 6c 20 24 73 71 6c 20 64 61   db eval $sql da
99b0: 74 61 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68  ta {.    foreach
99c0: 20 66 20 24 64 61 74 61 28 2a 29 20 7b 0a 20 20   f $data(*) {.  
99d0: 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65 73 75      lappend resu
99e0: 6c 74 20 24 66 20 24 64 61 74 61 28 24 66 29 0a  lt $f $data($f).
99f0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
9a00: 72 6e 20 24 72 65 73 75 6c 74 0a 7d 0a 0a 23 20  rn $result.}..# 
9a10: 55 73 65 20 61 20 74 65 6d 70 6f 72 61 72 79 20  Use a temporary 
9a20: 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61  in-memory databa
9a30: 73 65 20 74 6f 20 65 78 65 63 75 74 65 20 53 51  se to execute SQ
9a40: 4c 20 73 74 61 74 65 6d 65 6e 74 73 0a 23 0a 70  L statements.#.p
9a50: 72 6f 63 20 6d 65 6d 64 62 73 71 6c 20 7b 73 71  roc memdbsql {sq
9a60: 6c 7d 20 7b 0a 20 20 73 71 6c 69 74 65 33 20 6d  l} {.  sqlite3 m
9a70: 65 6d 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20  emdb :memory:.  
9a80: 73 65 74 20 72 65 73 75 6c 74 20 5b 6d 65 6d 64  set result [memd
9a90: 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 20 20 6d  b eval $sql].  m
9aa0: 65 6d 64 62 20 63 6c 6f 73 65 0a 20 20 72 65 74  emdb close.  ret
9ab0: 75 72 6e 20 24 72 65 73 75 6c 74 0a 7d 0a 0a 23  urn $result.}..#
9ac0: 20 55 73 65 20 74 68 65 20 6e 6f 6e 2d 63 61 6c   Use the non-cal
9ad0: 6c 62 61 63 6b 20 41 50 49 20 74 6f 20 65 78 65  lback API to exe
9ae0: 63 75 74 65 20 6d 75 6c 74 69 70 6c 65 20 53 51  cute multiple SQ
9af0: 4c 20 73 74 61 74 65 6d 65 6e 74 73 0a 23 0a 70  L statements.#.p
9b00: 72 6f 63 20 73 74 65 70 73 71 6c 20 7b 64 62 70  roc stepsql {dbp
9b10: 74 72 20 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20  tr sql} {.  set 
9b20: 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72 69 6d  sql [string trim
9b30: 20 24 73 71 6c 5d 0a 20 20 73 65 74 20 72 20 30   $sql].  set r 0
9b40: 0a 20 20 77 68 69 6c 65 20 7b 5b 73 74 72 69 6e  .  while {[strin
9b50: 67 20 6c 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30  g length $sql]>0
9b60: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 63 61 74  } {.    if {[cat
9b70: 63 68 20 7b 73 71 6c 69 74 65 33 5f 70 72 65 70  ch {sqlite3_prep
9b80: 61 72 65 20 24 64 62 70 74 72 20 24 73 71 6c 20  are $dbptr $sql 
9b90: 2d 31 20 73 71 6c 74 61 69 6c 7d 20 76 6d 5d 7d  -1 sqltail} vm]}
9ba0: 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20   {.      return 
9bb0: 5b 6c 69 73 74 20 31 20 24 76 6d 5d 0a 20 20 20  [list 1 $vm].   
9bc0: 20 7d 0a 20 20 20 20 73 65 74 20 73 71 6c 20 5b   }.    set sql [
9bd0: 73 74 72 69 6e 67 20 74 72 69 6d 20 24 73 71 6c  string trim $sql
9be0: 74 61 69 6c 5d 0a 23 20 20 20 20 77 68 69 6c 65  tail].#    while
9bf0: 20 7b 5b 73 71 6c 69 74 65 5f 73 74 65 70 20 24   {[sqlite_step $
9c00: 76 6d 20 4e 20 56 41 4c 20 43 4f 4c 5d 3d 3d 22  vm N VAL COL]=="
9c10: 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 23  SQLITE_ROW"} {.#
9c20: 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 76 20        foreach v 
9c30: 24 56 41 4c 20 7b 6c 61 70 70 65 6e 64 20 72 20  $VAL {lappend r 
9c40: 24 76 7d 0a 23 20 20 20 20 7d 0a 20 20 20 20 77  $v}.#    }.    w
9c50: 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65 33 5f 73  hile {[sqlite3_s
9c60: 74 65 70 20 24 76 6d 5d 3d 3d 22 53 51 4c 49 54  tep $vm]=="SQLIT
9c70: 45 5f 52 4f 57 22 7d 20 7b 0a 20 20 20 20 20 20  E_ROW"} {.      
9c80: 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24  for {set i 0} {$
9c90: 69 3c 5b 73 71 6c 69 74 65 33 5f 64 61 74 61 5f  i<[sqlite3_data_
9ca0: 63 6f 75 6e 74 20 24 76 6d 5d 7d 20 7b 69 6e 63  count $vm]} {inc
9cb0: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 6c  r i} {.        l
9cc0: 61 70 70 65 6e 64 20 72 20 5b 73 71 6c 69 74 65  append r [sqlite
9cd0: 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 20 24 76  3_column_text $v
9ce0: 6d 20 24 69 5d 0a 20 20 20 20 20 20 7d 0a 20 20  m $i].      }.  
9cf0: 20 20 7d 0a 20 20 20 20 69 66 20 7b 5b 63 61 74    }.    if {[cat
9d00: 63 68 20 7b 73 71 6c 69 74 65 33 5f 66 69 6e 61  ch {sqlite3_fina
9d10: 6c 69 7a 65 20 24 76 6d 7d 20 65 72 72 6d 73 67  lize $vm} errmsg
9d20: 5d 7d 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72  ]} {.      retur
9d30: 6e 20 5b 6c 69 73 74 20 31 20 24 65 72 72 6d 73  n [list 1 $errms
9d40: 67 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  g].    }.  }.  r
9d50: 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f  eturn $r.}..# Do
9d60: 20 61 6e 20 69 6e 74 65 67 72 69 74 79 20 63 68   an integrity ch
9d70: 65 63 6b 20 6f 66 20 74 68 65 20 65 6e 74 69 72  eck of the entir
9d80: 65 20 64 61 74 61 62 61 73 65 0a 23 0a 70 72 6f  e database.#.pro
9d90: 63 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63  c integrity_chec
9da0: 6b 20 7b 6e 61 6d 65 20 7b 64 62 20 64 62 7d 7d  k {name {db db}}
9db0: 20 7b 0a 20 20 69 66 63 61 70 61 62 6c 65 20 69   {.  ifcapable i
9dc0: 6e 74 65 67 72 69 74 79 63 6b 20 7b 0a 20 20 20  ntegrityck {.   
9dd0: 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b   do_test $name [
9de0: 6c 69 73 74 20 65 78 65 63 73 71 6c 20 7b 50 52  list execsql {PR
9df0: 41 47 4d 41 20 69 6e 74 65 67 72 69 74 79 5f 63  AGMA integrity_c
9e00: 68 65 63 6b 7d 20 24 64 62 5d 20 7b 6f 6b 7d 0a  heck} $db] {ok}.
9e10: 20 20 7d 0a 7d 0a 0a 23 20 43 68 65 63 6b 20 74    }.}..# Check t
9e20: 68 65 20 65 78 74 65 6e 64 65 64 20 65 72 72 6f  he extended erro
9e30: 72 20 63 6f 64 65 0a 23 0a 70 72 6f 63 20 76 65  r code.#.proc ve
9e40: 72 69 66 79 5f 65 78 5f 65 72 72 63 6f 64 65 20  rify_ex_errcode 
9e50: 7b 6e 61 6d 65 20 65 78 70 65 63 74 65 64 20 7b  {name expected {
9e60: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 64 6f 5f 74  db db}} {.  do_t
9e70: 65 73 74 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20  est $name [list 
9e80: 73 71 6c 69 74 65 33 5f 65 78 74 65 6e 64 65 64  sqlite3_extended
9e90: 5f 65 72 72 63 6f 64 65 20 24 64 62 5d 20 24 65  _errcode $db] $e
9ea0: 78 70 65 63 74 65 64 0a 7d 0a 0a 0a 23 20 52 65  xpected.}...# Re
9eb0: 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68 65  turn true if the
9ec0: 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 70   SQL statement p
9ed0: 61 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63  assed as the sec
9ee0: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 75 73 65  ond argument use
9ef0: 73 20 61 0a 23 20 73 74 61 74 65 6d 65 6e 74 20  s a.# statement 
9f00: 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 23 0a 70  transaction..#.p
9f10: 72 6f 63 20 73 71 6c 5f 75 73 65 73 5f 73 74 6d  roc sql_uses_stm
9f20: 74 20 7b 64 62 20 73 71 6c 7d 20 7b 0a 20 20 73  t {db sql} {.  s
9f30: 65 74 20 73 74 6d 74 20 5b 73 71 6c 69 74 65 33  et stmt [sqlite3
9f40: 5f 70 72 65 70 61 72 65 20 24 64 62 20 24 73 71  _prepare $db $sq
9f50: 6c 20 2d 31 20 64 75 6d 6d 79 5d 0a 20 20 73 65  l -1 dummy].  se
9f60: 74 20 75 73 65 73 20 5b 75 73 65 73 5f 73 74 6d  t uses [uses_stm
9f70: 74 5f 6a 6f 75 72 6e 61 6c 20 24 73 74 6d 74 5d  t_journal $stmt]
9f80: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
9f90: 69 7a 65 20 24 73 74 6d 74 0a 20 20 72 65 74 75  ize $stmt.  retu
9fa0: 72 6e 20 24 75 73 65 73 0a 7d 0a 0a 70 72 6f 63  rn $uses.}..proc
9fb0: 20 66 69 78 5f 69 66 63 61 70 61 62 6c 65 5f 65   fix_ifcapable_e
9fc0: 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a 20 20 73  xpr {expr} {.  s
9fd0: 65 74 20 72 65 74 20 22 22 0a 20 20 73 65 74 20  et ret "".  set 
9fe0: 73 74 61 74 65 20 30 0a 20 20 66 6f 72 20 7b 73  state 0.  for {s
9ff0: 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b 73  et i 0} {$i < [s
a000: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 65 78  tring length $ex
a010: 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a  pr]} {incr i} {.
a020: 20 20 20 20 73 65 74 20 63 68 61 72 20 5b 73 74      set char [st
a030: 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70 72  ring range $expr
a040: 20 24 69 20 24 69 5d 0a 20 20 20 20 73 65 74 20   $i $i].    set 
a050: 6e 65 77 73 74 61 74 65 20 5b 65 78 70 72 20 7b  newstate [expr {
a060: 5b 73 74 72 69 6e 67 20 69 73 20 61 6c 6e 75 6d  [string is alnum
a070: 20 24 63 68 61 72 5d 20 7c 7c 20 24 63 68 61 72   $char] || $char
a080: 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20 20 69 66   eq "_"}].    if
a090: 20 7b 24 6e 65 77 73 74 61 74 65 20 26 26 20 21   {$newstate && !
a0a0: 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20 20  $state} {.      
a0b0: 61 70 70 65 6e 64 20 72 65 74 20 7b 24 3a 3a 73  append ret {$::s
a0c0: 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 7d 0a  qlite_options(}.
a0d0: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 21 24      }.    if {!$
a0e0: 6e 65 77 73 74 61 74 65 20 26 26 20 24 73 74 61  newstate && $sta
a0f0: 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70 70 65  te} {.      appe
a100: 6e 64 20 72 65 74 20 29 0a 20 20 20 20 7d 0a 20  nd ret ).    }. 
a110: 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 24 63     append ret $c
a120: 68 61 72 0a 20 20 20 20 73 65 74 20 73 74 61 74  har.    set stat
a130: 65 20 24 6e 65 77 73 74 61 74 65 0a 20 20 7d 0a  e $newstate.  }.
a140: 20 20 69 66 20 7b 24 73 74 61 74 65 7d 20 7b 61    if {$state} {a
a150: 70 70 65 6e 64 20 72 65 74 20 29 7d 0a 20 20 72  ppend ret )}.  r
a160: 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23 20  eturn $ret.}..# 
a170: 52 65 74 75 72 6e 73 20 6e 6f 6e 2d 7a 65 72 6f  Returns non-zero
a180: 20 69 66 20 74 68 65 20 63 61 70 61 62 69 6c 69   if the capabili
a190: 74 69 65 73 20 61 72 65 20 70 72 65 73 65 6e 74  ties are present
a1a0: 3b 20 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65  ; zero otherwise
a1b0: 2e 0a 23 0a 70 72 6f 63 20 63 61 70 61 62 6c 65  ..#.proc capable
a1c0: 20 7b 65 78 70 72 7d 20 7b 0a 20 20 73 65 74 20   {expr} {.  set 
a1d0: 65 20 5b 66 69 78 5f 69 66 63 61 70 61 62 6c 65  e [fix_ifcapable
a1e0: 5f 65 78 70 72 20 24 65 78 70 72 5d 3b 20 72 65  _expr $expr]; re
a1f0: 74 75 72 6e 20 5b 65 78 70 72 20 28 24 65 29 5d  turn [expr ($e)]
a200: 0a 7d 0a 0a 23 20 45 76 61 6c 75 61 74 65 20 61  .}..# Evaluate a
a210: 20 62 6f 6f 6c 65 61 6e 20 65 78 70 72 65 73 73   boolean express
a220: 69 6f 6e 20 6f 66 20 63 61 70 61 62 69 6c 69 74  ion of capabilit
a230: 69 65 73 2e 20 20 49 66 20 74 72 75 65 2c 20 65  ies.  If true, e
a240: 78 65 63 75 74 65 20 74 68 65 0a 23 20 63 6f 64  xecute the.# cod
a250: 65 2e 20 20 4f 6d 69 74 20 74 68 65 20 63 6f 64  e.  Omit the cod
a260: 65 20 69 66 20 66 61 6c 73 65 2e 0a 23 0a 70 72  e if false..#.pr
a270: 6f 63 20 69 66 63 61 70 61 62 6c 65 20 7b 65 78  oc ifcapable {ex
a280: 70 72 20 63 6f 64 65 20 7b 65 6c 73 65 20 22 22  pr code {else ""
a290: 7d 20 7b 65 6c 73 65 63 6f 64 65 20 22 22 7d 7d  } {elsecode ""}}
a2a0: 20 7b 0a 20 20 23 72 65 67 73 75 62 20 2d 61 6c   {.  #regsub -al
a2b0: 6c 20 7b 5b 61 2d 7a 5f 30 2d 39 5d 2b 7d 20 24  l {[a-z_0-9]+} $
a2c0: 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f  expr {$::sqlite_
a2d0: 6f 70 74 69 6f 6e 73 28 26 29 7d 20 65 32 0a 20  options(&)} e2. 
a2e0: 20 73 65 74 20 65 32 20 5b 66 69 78 5f 69 66 63   set e2 [fix_ifc
a2f0: 61 70 61 62 6c 65 5f 65 78 70 72 20 24 65 78 70  apable_expr $exp
a300: 72 5d 0a 20 20 69 66 20 28 24 65 32 29 20 7b 0a  r].  if ($e2) {.
a310: 20 20 20 20 73 65 74 20 63 20 5b 63 61 74 63 68      set c [catch
a320: 20 7b 75 70 6c 65 76 65 6c 20 31 20 24 63 6f 64   {uplevel 1 $cod
a330: 65 7d 20 72 5d 0a 20 20 7d 20 65 6c 73 65 20 7b  e} r].  } else {
a340: 0a 20 20 20 20 73 65 74 20 63 20 5b 63 61 74 63  .    set c [catc
a350: 68 20 7b 75 70 6c 65 76 65 6c 20 31 20 24 65 6c  h {uplevel 1 $el
a360: 73 65 63 6f 64 65 7d 20 72 5d 0a 20 20 7d 0a 20  secode} r].  }. 
a370: 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 24 63   return -code $c
a380: 20 24 72 0a 7d 0a 0a 23 20 54 68 69 73 20 70 72   $r.}..# This pr
a390: 6f 63 20 65 78 65 63 73 20 61 20 73 65 70 65 72  oc execs a seper
a3a0: 61 74 65 20 70 72 6f 63 65 73 73 20 74 68 61 74  ate process that
a3b0: 20 63 72 61 73 68 65 73 20 6d 69 64 77 61 79 20   crashes midway 
a3c0: 74 68 72 6f 75 67 68 20 65 78 65 63 75 74 69 6e  through executin
a3d0: 67 0a 23 20 74 68 65 20 53 51 4c 20 73 63 72 69  g.# the SQL scri
a3e0: 70 74 20 24 73 71 6c 20 6f 6e 20 64 61 74 61 62  pt $sql on datab
a3f0: 61 73 65 20 74 65 73 74 2e 64 62 2e 0a 23 0a 23  ase test.db..#.#
a400: 20 54 68 65 20 63 72 61 73 68 20 6f 63 63 75 72   The crash occur
a410: 73 20 64 75 72 69 6e 67 20 61 20 73 79 6e 63 28  s during a sync(
a420: 29 20 6f 66 20 66 69 6c 65 20 24 63 72 61 73 68  ) of file $crash
a430: 66 69 6c 65 2e 20 57 68 65 6e 20 74 68 65 20 63  file. When the c
a440: 72 61 73 68 0a 23 20 6f 63 63 75 72 73 20 61 20  rash.# occurs a 
a450: 72 61 6e 64 6f 6d 20 73 75 62 73 65 74 20 6f 66  random subset of
a460: 20 61 6c 6c 20 75 6e 73 79 6e 63 65 64 20 77 72   all unsynced wr
a470: 69 74 65 73 20 6d 61 64 65 20 62 79 20 74 68 65  ites made by the
a480: 20 70 72 6f 63 65 73 73 20 61 72 65 0a 23 20 77   process are.# w
a490: 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20  ritten into the 
a4a0: 66 69 6c 65 73 20 6f 6e 20 64 69 73 6b 2e 20 41  files on disk. A
a4b0: 72 67 75 6d 65 6e 74 20 24 63 72 61 73 68 64 65  rgument $crashde
a4c0: 6c 61 79 20 69 6e 64 69 63 61 74 65 73 20 74 68  lay indicates th
a4d0: 65 0a 23 20 6e 75 6d 62 65 72 20 6f 66 20 66 69  e.# number of fi
a4e0: 6c 65 20 73 79 6e 63 73 20 74 6f 20 77 61 69 74  le syncs to wait
a4f0: 20 62 65 66 6f 72 65 20 63 72 61 73 68 69 6e 67   before crashing
a500: 2e 0a 23 0a 23 20 54 68 65 20 72 65 74 75 72 6e  ..#.# The return
a510: 20 76 61 6c 75 65 20 69 73 20 61 20 6c 69 73 74   value is a list
a520: 20 6f 66 20 74 77 6f 20 65 6c 65 6d 65 6e 74 73   of two elements
a530: 2e 20 54 68 65 20 66 69 72 73 74 20 65 6c 65 6d  . The first elem
a540: 65 6e 74 20 69 73 20 61 0a 23 20 62 6f 6f 6c 65  ent is a.# boole
a550: 61 6e 2c 20 69 6e 64 69 63 61 74 69 6e 67 20 77  an, indicating w
a560: 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 74 68  hether or not th
a570: 65 20 70 72 6f 63 65 73 73 20 61 63 74 75 61 6c  e process actual
a580: 6c 79 20 63 72 61 73 68 65 64 20 6f 72 0a 23 20  ly crashed or.# 
a590: 72 65 70 6f 72 74 65 64 20 73 6f 6d 65 20 6f 74  reported some ot
a5a0: 68 65 72 20 65 72 72 6f 72 2e 20 54 68 65 20 73  her error. The s
a5b0: 65 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 6e  econd element in
a5c0: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 6c 69   the returned li
a5d0: 73 74 20 69 73 20 74 68 65 0a 23 20 65 72 72 6f  st is the.# erro
a5e0: 72 20 6d 65 73 73 61 67 65 2e 20 54 68 69 73 20  r message. This 
a5f0: 69 73 20 22 63 68 69 6c 64 20 70 72 6f 63 65 73  is "child proces
a600: 73 20 65 78 69 74 65 64 20 61 62 6e 6f 72 6d 61  s exited abnorma
a610: 6c 6c 79 22 20 69 66 20 74 68 65 20 63 72 61 73  lly" if the cras
a620: 68 0a 23 20 6f 63 63 75 72 72 65 64 2e 0a 23 0a  h.# occurred..#.
a630: 23 20 20 20 63 72 61 73 68 73 71 6c 20 2d 64 65  #   crashsql -de
a640: 6c 61 79 20 43 52 41 53 48 44 45 4c 41 59 20 2d  lay CRASHDELAY -
a650: 66 69 6c 65 20 43 52 41 53 48 46 49 4c 45 20 3f  file CRASHFILE ?
a660: 2d 62 6c 6f 63 6b 73 69 7a 65 20 42 4c 4f 43 4b  -blocksize BLOCK
a670: 53 49 5a 45 3f 20 24 73 71 6c 0a 23 0a 70 72 6f  SIZE? $sql.#.pro
a680: 63 20 63 72 61 73 68 73 71 6c 20 7b 61 72 67 73  c crashsql {args
a690: 7d 20 7b 0a 0a 20 20 73 65 74 20 62 6c 6f 63 6b  } {..  set block
a6a0: 73 69 7a 65 20 22 22 0a 20 20 73 65 74 20 63 72  size "".  set cr
a6b0: 61 73 68 64 65 6c 61 79 20 31 0a 20 20 73 65 74  ashdelay 1.  set
a6c0: 20 70 72 6e 67 73 65 65 64 20 30 0a 20 20 73 65   prngseed 0.  se
a6d0: 74 20 6f 70 65 6e 64 62 20 7b 20 73 71 6c 69 74  t opendb { sqlit
a6e0: 65 33 20 64 62 20 74 65 73 74 2e 64 62 20 2d 76  e3 db test.db -v
a6f0: 66 73 20 63 72 61 73 68 20 7d 0a 20 20 73 65 74  fs crash }.  set
a700: 20 74 63 6c 62 6f 64 79 20 7b 7d 0a 20 20 73 65   tclbody {}.  se
a710: 74 20 63 72 61 73 68 66 69 6c 65 20 22 22 0a 20  t crashfile "". 
a720: 20 73 65 74 20 64 63 20 22 22 0a 20 20 73 65 74   set dc "".  set
a730: 20 73 71 6c 20 5b 6c 69 6e 64 65 78 20 24 61 72   sql [lindex $ar
a740: 67 73 20 65 6e 64 5d 0a 0a 20 20 66 6f 72 20 7b  gs end]..  for {
a750: 73 65 74 20 69 69 20 30 7d 20 7b 24 69 69 20 3c  set ii 0} {$ii <
a760: 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d   [llength $args]
a770: 2d 31 7d 20 7b 69 6e 63 72 20 69 69 20 32 7d 20  -1} {incr ii 2} 
a780: 7b 0a 20 20 20 20 73 65 74 20 7a 20 5b 6c 69 6e  {.    set z [lin
a790: 64 65 78 20 24 61 72 67 73 20 24 69 69 5d 0a 20  dex $args $ii]. 
a7a0: 20 20 20 73 65 74 20 6e 20 5b 73 74 72 69 6e 67     set n [string
a7b0: 20 6c 65 6e 67 74 68 20 24 7a 5d 0a 20 20 20 20   length $z].    
a7c0: 73 65 74 20 7a 32 20 5b 6c 69 6e 64 65 78 20 24  set z2 [lindex $
a7d0: 61 72 67 73 20 5b 65 78 70 72 20 24 69 69 2b 31  args [expr $ii+1
a7e0: 5d 5d 0a 0a 20 20 20 20 69 66 20 20 20 20 20 7b  ]]..    if     {
a7f0: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
a800: 66 69 72 73 74 20 24 7a 20 2d 64 65 6c 61 79 5d  first $z -delay]
a810: 3d 3d 30 7d 20 20 20 20 20 7b 73 65 74 20 63 72  ==0}     {set cr
a820: 61 73 68 64 65 6c 61 79 20 24 7a 32 7d 20 5c 0a  ashdelay $z2} \.
a830: 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31      elseif {$n>1
a840: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
a850: 74 20 24 7a 20 2d 6f 70 65 6e 64 62 5d 3d 3d 30  t $z -opendb]==0
a860: 7d 20 20 20 20 7b 73 65 74 20 6f 70 65 6e 64 62  }    {set opendb
a870: 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65   $z2} \.    else
a880: 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72  if {$n>1 && [str
a890: 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 73 65  ing first $z -se
a8a0: 65 64 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65  ed]==0}      {se
a8b0: 74 20 70 72 6e 67 73 65 65 64 20 24 7a 32 7d 20  t prngseed $z2} 
a8c0: 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e  \.    elseif {$n
a8d0: 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69  >1 && [string fi
a8e0: 72 73 74 20 24 7a 20 2d 66 69 6c 65 5d 3d 3d 30  rst $z -file]==0
a8f0: 7d 20 20 20 20 20 20 7b 73 65 74 20 63 72 61 73  }      {set cras
a900: 68 66 69 6c 65 20 24 7a 32 7d 20 20 5c 0a 20 20  hfile $z2}  \.  
a910: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
a920: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
a930: 24 7a 20 2d 74 63 6c 62 6f 64 79 5d 3d 3d 30 7d  $z -tclbody]==0}
a940: 20 20 20 7b 73 65 74 20 74 63 6c 62 6f 64 79 20     {set tclbody 
a950: 24 7a 32 7d 20 20 5c 0a 20 20 20 20 65 6c 73 65  $z2}  \.    else
a960: 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72  if {$n>1 && [str
a970: 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 62 6c  ing first $z -bl
a980: 6f 63 6b 73 69 7a 65 5d 3d 3d 30 7d 20 7b 73 65  ocksize]==0} {se
a990: 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22 2d 73 20  t blocksize "-s 
a9a0: 24 7a 32 22 20 7d 20 5c 0a 20 20 20 20 65 6c 73  $z2" } \.    els
a9b0: 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74  eif {$n>1 && [st
a9c0: 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 63  ring first $z -c
a9d0: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 5d 3d  haracteristics]=
a9e0: 3d 30 7d 20 7b 73 65 74 20 64 63 20 22 2d 63 20  =0} {set dc "-c 
a9f0: 7b 24 7a 32 7d 22 20 7d 20 5c 0a 20 20 20 20 65  {$z2}" } \.    e
aa00: 6c 73 65 20 20 20 7b 20 65 72 72 6f 72 20 22 55  lse   { error "U
aa10: 6e 72 65 63 6f 67 6e 69 7a 65 64 20 6f 70 74 69  nrecognized opti
aa20: 6f 6e 3a 20 24 7a 22 20 7d 0a 20 20 7d 0a 0a 20  on: $z" }.  }.. 
aa30: 20 69 66 20 7b 24 63 72 61 73 68 66 69 6c 65 20   if {$crashfile 
aa40: 65 71 20 22 22 7d 20 7b 0a 20 20 20 20 65 72 72  eq ""} {.    err
aa50: 6f 72 20 22 43 6f 6d 70 75 6c 73 6f 72 79 20 6f  or "Compulsory o
aa60: 70 74 69 6f 6e 20 2d 66 69 6c 65 20 6d 69 73 73  ption -file miss
aa70: 69 6e 67 22 0a 20 20 7d 0a 0a 20 20 23 20 24 63  ing".  }..  # $c
aa80: 72 61 73 68 66 69 6c 65 20 67 65 74 73 20 63 6f  rashfile gets co
aa90: 6d 70 61 72 65 64 20 74 6f 20 74 68 65 20 6e 61  mpared to the na
aaa0: 74 69 76 65 20 66 69 6c 65 6e 61 6d 65 20 69 6e  tive filename in
aab0: 0a 20 20 23 20 63 66 53 79 6e 63 28 29 2c 20 77  .  # cfSync(), w
aac0: 68 69 63 68 20 63 61 6e 20 62 65 20 64 69 66 66  hich can be diff
aad0: 65 72 65 6e 74 20 74 68 65 6e 20 77 68 61 74 20  erent then what 
aae0: 54 43 4c 20 75 73 65 73 20 62 79 0a 20 20 23 20  TCL uses by.  # 
aaf0: 64 65 66 61 75 6c 74 2c 20 73 6f 20 68 65 72 65  default, so here
ab00: 20 77 65 20 66 6f 72 63 65 20 69 74 20 74 6f 20   we force it to 
ab10: 74 68 65 20 22 6e 61 74 69 76 65 6e 61 6d 65 22  the "nativename"
ab20: 20 66 6f 72 6d 61 74 2e 0a 20 20 73 65 74 20 63   format..  set c
ab30: 66 69 6c 65 20 5b 73 74 72 69 6e 67 20 6d 61 70  file [string map
ab40: 20 7b 5c 5c 20 5c 5c 5c 5c 7d 20 5b 66 69 6c 65   {\\ \\\\} [file
ab50: 20 6e 61 74 69 76 65 6e 61 6d 65 20 5b 66 69 6c   nativename [fil
ab60: 65 20 6a 6f 69 6e 20 5b 67 65 74 5f 70 77 64 5d  e join [get_pwd]
ab70: 20 24 63 72 61 73 68 66 69 6c 65 5d 5d 5d 0a 0a   $crashfile]]]..
ab80: 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 63 72    set f [open cr
ab90: 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70 75 74  ash.tcl w].  put
aba0: 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f 63 72  s $f "sqlite3_cr
abb0: 61 73 68 5f 65 6e 61 62 6c 65 20 31 22 0a 20 20  ash_enable 1".  
abc0: 70 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33  puts $f "sqlite3
abd0: 5f 63 72 61 73 68 70 61 72 61 6d 73 20 24 62 6c  _crashparams $bl
abe0: 6f 63 6b 73 69 7a 65 20 24 64 63 20 24 63 72 61  ocksize $dc $cra
abf0: 73 68 64 65 6c 61 79 20 24 63 66 69 6c 65 22 0a  shdelay $cfile".
ac00: 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74    puts $f "sqlit
ac10: 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f 6c 5f  e3_test_control_
ac20: 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 24 3a 3a  pending_byte $::
ac30: 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62  sqlite_pending_b
ac40: 79 74 65 22 0a 0a 20 20 23 20 54 68 69 73 20 62  yte"..  # This b
ac50: 6c 6f 63 6b 20 73 65 74 73 20 74 68 65 20 63 61  lock sets the ca
ac60: 63 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  che size of the 
ac70: 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 74 6f  main database to
ac80: 20 31 30 0a 20 20 23 20 70 61 67 65 73 2e 20 54   10.  # pages. T
ac90: 68 69 73 20 69 73 20 64 6f 6e 65 20 69 6e 20 63  his is done in c
aca0: 61 73 65 20 74 68 65 20 62 75 69 6c 64 20 69 73  ase the build is
acb0: 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 6f   configured to o
acc0: 6d 69 74 0a 20 20 23 20 22 50 52 41 47 4d 41 20  mit.  # "PRAGMA 
acd0: 63 61 63 68 65 5f 73 69 7a 65 22 2e 0a 20 20 69  cache_size"..  i
ace0: 66 20 7b 24 6f 70 65 6e 64 62 21 3d 22 22 7d 20  f {$opendb!=""} 
acf0: 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20 24 6f  {.    puts $f $o
ad00: 70 65 6e 64 62 20 0a 20 20 20 20 70 75 74 73 20  pendb .    puts 
ad10: 24 66 20 7b 64 62 20 65 76 61 6c 20 7b 53 45 4c  $f {db eval {SEL
ad20: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
ad30: 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a 20 20 20 20  e_master;}}.    
ad40: 70 75 74 73 20 24 66 20 7b 73 65 74 20 62 74 20  puts $f {set bt 
ad50: 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64  [btree_from_db d
ad60: 62 5d 7d 0a 20 20 20 20 70 75 74 73 20 24 66 20  b]}.    puts $f 
ad70: 7b 62 74 72 65 65 5f 73 65 74 5f 63 61 63 68 65  {btree_set_cache
ad80: 5f 73 69 7a 65 20 24 62 74 20 31 30 7d 0a 20 20  _size $bt 10}.  
ad90: 7d 0a 0a 20 20 69 66 20 7b 24 70 72 6e 67 73 65  }..  if {$prngse
ada0: 65 64 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 65  ed} {.    set se
adb0: 65 64 20 5b 65 78 70 72 20 7b 24 70 72 6e 67 73  ed [expr {$prngs
adc0: 65 65 64 25 31 30 30 30 37 2b 31 7d 5d 0a 20 20  eed%10007+1}].  
add0: 20 20 23 20 70 75 74 73 20 73 65 65 64 3d 24 73    # puts seed=$s
ade0: 65 65 64 0a 20 20 20 20 70 75 74 73 20 24 66 20  eed.    puts $f 
adf0: 22 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54  "db eval {SELECT
ae00: 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 24 73 65 65   randomblob($see
ae10: 64 29 7d 22 0a 20 20 7d 0a 0a 20 20 69 66 20 7b  d)}".  }..  if {
ae20: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
ae30: 74 63 6c 62 6f 64 79 5d 3e 30 7d 20 7b 0a 20 20  tclbody]>0} {.  
ae40: 20 20 70 75 74 73 20 24 66 20 24 74 63 6c 62 6f    puts $f $tclbo
ae50: 64 79 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 73 74  dy.  }.  if {[st
ae60: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 71 6c  ring length $sql
ae70: 5d 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  ]>0} {.    puts 
ae80: 24 66 20 22 64 62 20 65 76 61 6c 20 7b 22 0a 20  $f "db eval {". 
ae90: 20 20 20 70 75 74 73 20 24 66 20 20 20 22 24 73     puts $f   "$s
aea0: 71 6c 22 0a 20 20 20 20 70 75 74 73 20 24 66 20  ql".    puts $f 
aeb0: 22 7d 22 0a 20 20 7d 0a 20 20 63 6c 6f 73 65 20  "}".  }.  close 
aec0: 24 66 0a 20 20 73 65 74 20 72 20 5b 63 61 74 63  $f.  set r [catc
aed0: 68 20 7b 0a 20 20 20 20 65 78 65 63 20 5b 69 6e  h {.    exec [in
aee0: 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 5d 20 63  fo nameofexec] c
aef0: 72 61 73 68 2e 74 63 6c 20 3e 40 73 74 64 6f 75  rash.tcl >@stdou
af00: 74 0a 20 20 7d 20 6d 73 67 5d 0a 0a 20 20 23 20  t.  } msg]..  # 
af10: 57 69 6e 64 6f 77 73 2f 41 63 74 69 76 65 53 74  Windows/ActiveSt
af20: 61 74 65 20 54 43 4c 20 72 65 74 75 72 6e 73 20  ate TCL returns 
af30: 61 20 73 6c 69 67 68 74 6c 79 20 64 69 66 66 65  a slightly diffe
af40: 72 65 6e 74 0a 20 20 23 20 65 72 72 6f 72 20 6d  rent.  # error m
af50: 65 73 73 61 67 65 2e 20 20 57 65 20 6d 61 70 20  essage.  We map 
af60: 74 68 61 74 20 74 6f 20 74 68 65 20 65 78 70 65  that to the expe
af70: 63 74 65 64 20 6d 65 73 73 61 67 65 0a 20 20 23  cted message.  #
af80: 20 73 6f 20 74 68 61 74 20 77 65 20 64 6f 6e 27   so that we don'
af90: 74 20 68 61 76 65 20 74 6f 20 63 68 61 6e 67 65  t have to change
afa0: 20 61 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74   all of the test
afb0: 0a 20 20 23 20 63 61 73 65 73 2e 0a 20 20 69 66  .  # cases..  if
afc0: 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72   {$::tcl_platfor
afd0: 6d 28 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 77 69  m(platform)=="wi
afe0: 6e 64 6f 77 73 22 7d 20 7b 0a 20 20 20 20 69 66  ndows"} {.    if
aff0: 20 7b 24 6d 73 67 3d 3d 22 63 68 69 6c 64 20 6b   {$msg=="child k
b000: 69 6c 6c 65 64 3a 20 75 6e 6b 6e 6f 77 6e 20 73  illed: unknown s
b010: 69 67 6e 61 6c 22 7d 20 7b 0a 20 20 20 20 20 20  ignal"} {.      
b020: 73 65 74 20 6d 73 67 20 22 63 68 69 6c 64 20 70  set msg "child p
b030: 72 6f 63 65 73 73 20 65 78 69 74 65 64 20 61 62  rocess exited ab
b040: 6e 6f 72 6d 61 6c 6c 79 22 0a 20 20 20 20 7d 0a  normally".    }.
b050: 20 20 7d 0a 0a 20 20 6c 61 70 70 65 6e 64 20 72    }..  lappend r
b060: 20 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20 72 75   $msg.}..proc ru
b070: 6e 5f 69 6f 65 72 72 5f 70 72 65 70 20 7b 7d 20  n_ioerr_prep {} 
b080: 7b 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65  {.  set ::sqlite
b090: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e  _io_error_pendin
b0a0: 67 20 30 0a 20 20 63 61 74 63 68 20 7b 64 62 20  g 0.  catch {db 
b0b0: 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b  close}.  catch {
b0c0: 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74  db2 close}.  cat
b0d0: 63 68 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20  ch {forcedelete 
b0e0: 74 65 73 74 2e 64 62 7d 0a 20 20 63 61 74 63 68  test.db}.  catch
b0f0: 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65   {forcedelete te
b100: 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20  st.db-journal}. 
b110: 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c   catch {forcedel
b120: 65 74 65 20 74 65 73 74 32 2e 64 62 7d 0a 20 20  ete test2.db}.  
b130: 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65  catch {forcedele
b140: 74 65 20 74 65 73 74 32 2e 64 62 2d 6a 6f 75 72  te test2.db-jour
b150: 6e 61 6c 7d 0a 20 20 73 65 74 20 3a 3a 44 42 20  nal}.  set ::DB 
b160: 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74  [sqlite3 db test
b170: 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e  .db; sqlite3_con
b180: 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20  nection_pointer 
b190: 64 62 5d 0a 20 20 73 71 6c 69 74 65 33 5f 65 78  db].  sqlite3_ex
b1a0: 74 65 6e 64 65 64 5f 72 65 73 75 6c 74 5f 63 6f  tended_result_co
b1b0: 64 65 73 20 24 3a 3a 44 42 20 24 3a 3a 69 6f 65  des $::DB $::ioe
b1c0: 72 72 6f 70 74 73 28 2d 65 72 63 29 0a 20 20 69  rropts(-erc).  i
b1d0: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
b1e0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c  ::ioerropts(-tcl
b1f0: 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 65 76  prep)]} {.    ev
b200: 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  al $::ioerropts(
b210: 2d 74 63 6c 70 72 65 70 29 0a 20 20 7d 0a 20 20  -tclprep).  }.  
b220: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
b230: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71   ::ioerropts(-sq
b240: 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 65  lprep)]} {.    e
b250: 78 65 63 73 71 6c 20 24 3a 3a 69 6f 65 72 72 6f  xecsql $::ioerro
b260: 70 74 73 28 2d 73 71 6c 70 72 65 70 29 0a 20 20  pts(-sqlprep).  
b270: 7d 0a 20 20 65 78 70 72 20 30 0a 7d 0a 0a 23 20  }.  expr 0.}..# 
b280: 55 73 61 67 65 3a 20 64 6f 5f 69 6f 65 72 72 5f  Usage: do_ioerr_
b290: 74 65 73 74 20 3c 74 65 73 74 20 6e 75 6d 62 65  test <test numbe
b2a0: 72 3e 20 3c 6f 70 74 69 6f 6e 73 2e 2e 2e 3e 0a  r> <options...>.
b2b0: 23 0a 23 20 54 68 69 73 20 70 72 6f 63 20 69 73  #.# This proc is
b2c0: 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65   used to impleme
b2d0: 6e 74 20 74 65 73 74 20 63 61 73 65 73 20 74 68  nt test cases th
b2e0: 61 74 20 63 68 65 63 6b 20 74 68 61 74 20 49 4f  at check that IO
b2f0: 20 65 72 72 6f 72 73 0a 23 20 61 72 65 20 63 6f   errors.# are co
b300: 72 72 65 63 74 6c 79 20 68 61 6e 64 6c 65 64 2e  rrectly handled.
b310: 20 54 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   The first argum
b320: 65 6e 74 2c 20 3c 74 65 73 74 20 6e 75 6d 62 65  ent, <test numbe
b330: 72 3e 2c 20 69 73 20 61 6e 20 69 6e 74 65 67 65  r>, is an intege
b340: 72 0a 23 20 75 73 65 64 20 74 6f 20 6e 61 6d 65  r.# used to name
b350: 20 74 68 65 20 74 65 73 74 73 20 65 78 65 63 75   the tests execu
b360: 74 65 64 20 62 79 20 74 68 69 73 20 70 72 6f 63  ted by this proc
b370: 2e 20 4f 70 74 69 6f 6e 73 20 61 72 65 20 61 73  . Options are as
b380: 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20 20   follows:.#.#   
b390: 20 20 2d 74 63 6c 70 72 65 70 20 20 20 20 20 20    -tclprep      
b3a0: 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20 74      TCL script t
b3b0: 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61 72 65  o run to prepare
b3c0: 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 73 71   test..#     -sq
b3d0: 6c 70 72 65 70 20 20 20 20 20 20 20 20 20 20 53  lprep          S
b3e0: 51 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e  QL script to run
b3f0: 20 74 6f 20 70 72 65 70 61 72 65 20 74 65 73 74   to prepare test
b400: 2e 0a 23 20 20 20 20 20 2d 74 63 6c 62 6f 64 79  ..#     -tclbody
b410: 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73 63            TCL sc
b420: 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69 74 68  ript to run with
b430: 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c 61   IO error simula
b440: 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 73 71 6c  tion..#     -sql
b450: 62 6f 64 79 20 20 20 20 20 20 20 20 20 20 54 43  body          TC
b460: 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20  L script to run 
b470: 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20 73 69  with IO error si
b480: 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20  mulation..#     
b490: 2d 65 78 63 6c 75 64 65 20 20 20 20 20 20 20 20  -exclude        
b4a0: 20 20 4c 69 73 74 20 6f 66 20 27 4e 27 20 76 61    List of 'N' va
b4b0: 6c 75 65 73 20 6e 6f 74 20 74 6f 20 74 65 73 74  lues not to test
b4c0: 2e 0a 23 20 20 20 20 20 2d 65 72 63 20 20 20 20  ..#     -erc    
b4d0: 20 20 20 20 20 20 20 20 20 20 55 73 65 20 65 78            Use ex
b4e0: 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f  tended result co
b4f0: 64 65 73 0a 23 20 20 20 20 20 2d 70 65 72 73 69  des.#     -persi
b500: 73 74 20 20 20 20 20 20 20 20 20 20 4d 61 6b 65  st          Make
b510: 20 73 69 6d 75 6c 61 74 65 64 20 49 2f 4f 20 65   simulated I/O e
b520: 72 72 6f 72 73 20 70 65 72 73 69 73 74 65 6e 74  rrors persistent
b530: 0a 23 20 20 20 20 20 2d 73 74 61 72 74 20 20 20  .#     -start   
b540: 20 20 20 20 20 20 20 20 20 56 61 6c 75 65 20 6f           Value o
b550: 66 20 27 4e 27 20 74 6f 20 62 65 67 69 6e 20 77  f 'N' to begin w
b560: 69 74 68 20 28 64 65 66 61 75 6c 74 20 31 29 0a  ith (default 1).
b570: 23 0a 23 20 20 20 20 20 2d 63 6b 73 75 6d 20 20  #.#     -cksum  
b580: 20 20 20 20 20 20 20 20 20 20 42 6f 6f 6c 65 61            Boolea
b590: 6e 2e 20 49 66 20 74 72 75 65 2c 20 74 65 73 74  n. If true, test
b5a0: 20 74 68 61 74 20 74 68 65 20 64 61 74 61 62 61   that the databa
b5b0: 73 65 20 64 6f 65 73 0a 23 20 20 20 20 20 20 20  se does.#       
b5c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b5d0: 6e 6f 74 20 63 68 61 6e 67 65 20 64 75 72 69 6e  not change durin
b5e0: 67 20 74 68 65 20 65 78 65 63 75 74 69 6f 6e 20  g the execution 
b5f0: 6f 66 20 74 68 65 20 74 65 73 74 20 63 61 73 65  of the test case
b600: 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 69 6f 65 72  ..#.proc do_ioer
b610: 72 5f 74 65 73 74 20 7b 74 65 73 74 6e 61 6d 65  r_test {testname
b620: 20 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20   args} {..  set 
b630: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 74 61  ::ioerropts(-sta
b640: 72 74 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f  rt) 1.  set ::io
b650: 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 20  erropts(-cksum) 
b660: 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f  0.  set ::ioerro
b670: 70 74 73 28 2d 65 72 63 29 20 30 0a 20 20 73 65  pts(-erc) 0.  se
b680: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  t ::ioerropts(-c
b690: 6f 75 6e 74 29 20 31 30 30 30 30 30 30 30 30 0a  ount) 100000000.
b6a0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
b6b0: 73 28 2d 70 65 72 73 69 73 74 29 20 31 0a 20 20  s(-persist) 1.  
b6c0: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  set ::ioerropts(
b6d0: 2d 63 6b 72 65 66 63 6f 75 6e 74 29 20 30 0a 20  -ckrefcount) 0. 
b6e0: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
b6f0: 28 2d 72 65 73 74 6f 72 65 70 72 6e 67 29 20 31  (-restoreprng) 1
b700: 0a 20 20 61 72 72 61 79 20 73 65 74 20 3a 3a 69  .  array set ::i
b710: 6f 65 72 72 6f 70 74 73 20 24 61 72 67 73 0a 0a  oerropts $args..
b720: 20 20 23 20 54 45 4d 50 4f 52 41 52 59 3a 20 46    # TEMPORARY: F
b730: 6f 72 20 33 2e 35 2e 39 2c 20 64 69 73 61 62 6c  or 3.5.9, disabl
b740: 65 20 74 65 73 74 69 6e 67 20 6f 66 20 65 78 74  e testing of ext
b750: 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64  ended result cod
b760: 65 73 2e 20 54 68 65 72 65 20 61 72 65 0a 20 20  es. There are.  
b770: 23 20 61 20 63 6f 75 70 6c 65 20 6f 66 20 6f 62  # a couple of ob
b780: 73 63 75 72 65 20 49 4f 20 65 72 72 6f 72 73 20  scure IO errors 
b790: 74 68 61 74 20 64 6f 20 6e 6f 74 20 72 65 74 75  that do not retu
b7a0: 72 6e 20 74 68 65 6d 2e 0a 20 20 73 65 74 20 3a  rn them..  set :
b7b0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
b7c0: 20 30 0a 0a 20 20 23 20 43 72 65 61 74 65 20 61   0..  # Create a
b7d0: 20 73 69 6e 67 6c 65 20 54 43 4c 20 73 63 72 69   single TCL scri
b7e0: 70 74 20 66 72 6f 6d 20 74 68 65 20 54 43 4c 20  pt from the TCL 
b7f0: 61 6e 64 20 53 51 4c 20 73 70 65 63 69 66 69 65  and SQL specifie
b800: 64 0a 20 20 23 20 61 73 20 74 68 65 20 62 6f 64  d.  # as the bod
b810: 79 20 6f 66 20 74 68 65 20 74 65 73 74 2e 0a 20  y of the test.. 
b820: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 72 62 6f   set ::ioerrorbo
b830: 64 79 20 7b 7d 0a 20 20 69 66 20 7b 5b 69 6e 66  dy {}.  if {[inf
b840: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
b850: 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5d 7d  opts(-tclbody)]}
b860: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 3a 3a   {.    append ::
b870: 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 24 3a 3a  ioerrorbody "$::
b880: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f  ioerropts(-tclbo
b890: 64 79 29 5c 6e 22 0a 20 20 7d 0a 20 20 69 66 20  dy)\n".  }.  if 
b8a0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
b8b0: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f  ioerropts(-sqlbo
b8c0: 64 79 29 5d 7d 20 7b 0a 20 20 20 20 61 70 70 65  dy)]} {.    appe
b8d0: 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  nd ::ioerrorbody
b8e0: 20 22 64 62 20 65 76 61 6c 20 7b 24 3a 3a 69 6f   "db eval {$::io
b8f0: 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79  erropts(-sqlbody
b900: 29 7d 22 0a 20 20 7d 0a 0a 20 20 73 61 76 65 5f  )}".  }..  save_
b910: 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 69 66 20  prng_state.  if 
b920: 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  {$::ioerropts(-c
b930: 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 72 75 6e  ksum)} {.    run
b940: 5f 69 6f 65 72 72 5f 70 72 65 70 0a 20 20 20 20  _ioerr_prep.    
b950: 65 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 72 62  eval $::ioerrorb
b960: 6f 64 79 0a 20 20 20 20 73 65 74 20 3a 3a 67 6f  ody.    set ::go
b970: 6f 64 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a  odcksum [cksum].
b980: 20 20 7d 0a 0a 20 20 73 65 74 20 3a 3a 67 6f 20    }..  set ::go 
b990: 31 0a 20 20 23 72 65 73 65 74 5f 70 72 6e 67 5f  1.  #reset_prng_
b9a0: 73 74 61 74 65 0a 20 20 66 6f 72 20 7b 73 65 74  state.  for {set
b9b0: 20 6e 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28   n $::ioerropts(
b9c0: 2d 73 74 61 72 74 29 7d 20 7b 24 3a 3a 67 6f 7d  -start)} {$::go}
b9d0: 20 7b 69 6e 63 72 20 6e 7d 20 7b 0a 20 20 20 20   {incr n} {.    
b9e0: 73 65 74 20 3a 3a 54 4e 20 24 6e 0a 20 20 20 20  set ::TN $n.    
b9f0: 69 6e 63 72 20 3a 3a 69 6f 65 72 72 6f 70 74 73  incr ::ioerropts
ba00: 28 2d 63 6f 75 6e 74 29 20 2d 31 0a 20 20 20 20  (-count) -1.    
ba10: 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73  if {$::ioerropts
ba20: 28 2d 63 6f 75 6e 74 29 3c 30 7d 20 62 72 65 61  (-count)<0} brea
ba30: 6b 0a 0a 20 20 20 20 23 20 53 6b 69 70 20 74 68  k..    # Skip th
ba40: 69 73 20 49 4f 20 65 72 72 6f 72 20 69 66 20 69  is IO error if i
ba50: 74 20 77 61 73 20 73 70 65 63 69 66 69 65 64 20  t was specified 
ba60: 77 69 74 68 20 74 68 65 20 22 2d 65 78 63 6c 75  with the "-exclu
ba70: 64 65 22 20 6f 70 74 69 6f 6e 2e 0a 20 20 20 20  de" option..    
ba80: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
ba90: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78   ::ioerropts(-ex
baa0: 63 6c 75 64 65 29 5d 7d 20 7b 0a 20 20 20 20 20  clude)]} {.     
bab0: 20 69 66 20 7b 5b 6c 73 65 61 72 63 68 20 24 3a   if {[lsearch $:
bac0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78 63 6c  :ioerropts(-excl
bad0: 75 64 65 29 20 24 6e 5d 21 3d 2d 31 7d 20 63 6f  ude) $n]!=-1} co
bae0: 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a 20 20 20  ntinue.    }.   
baf0: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
bb00: 73 28 2d 72 65 73 74 6f 72 65 70 72 6e 67 29 7d  s(-restoreprng)}
bb10: 20 7b 0a 20 20 20 20 20 20 72 65 73 74 6f 72 65   {.      restore
bb20: 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 20 20  _prng_state.    
bb30: 7d 0a 0a 20 20 20 20 23 20 44 65 6c 65 74 65 20  }..    # Delete 
bb40: 74 68 65 20 66 69 6c 65 73 20 74 65 73 74 2e 64  the files test.d
bb50: 62 20 61 6e 64 20 74 65 73 74 32 2e 64 62 2c 20  b and test2.db, 
bb60: 74 68 65 6e 20 65 78 65 63 75 74 65 20 74 68 65  then execute the
bb70: 20 54 43 4c 20 61 6e 64 0a 20 20 20 20 23 20 53   TCL and.    # S
bb80: 51 4c 20 28 69 6e 20 74 68 61 74 20 6f 72 64 65  QL (in that orde
bb90: 72 29 20 74 6f 20 70 72 65 70 61 72 65 20 66 6f  r) to prepare fo
bba0: 72 20 74 68 65 20 74 65 73 74 20 63 61 73 65 2e  r the test case.
bbb0: 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65  .    do_test $te
bbc0: 73 74 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a 20 20  stname.$n.1 {.  
bbd0: 20 20 20 20 72 75 6e 5f 69 6f 65 72 72 5f 70 72      run_ioerr_pr
bbe0: 65 70 0a 20 20 20 20 7d 20 7b 30 7d 0a 0a 20 20  ep.    } {0}..  
bbf0: 20 20 23 20 52 65 61 64 20 74 68 65 20 27 63 68    # Read the 'ch
bc00: 65 63 6b 73 75 6d 27 20 6f 66 20 74 68 65 20 64  ecksum' of the d
bc10: 61 74 61 62 61 73 65 2e 0a 20 20 20 20 69 66 20  atabase..    if 
bc20: 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  {$::ioerropts(-c
bc30: 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20 73  ksum)} {.      s
bc40: 65 74 20 3a 3a 63 68 65 63 6b 73 75 6d 20 5b 63  et ::checksum [c
bc50: 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a 0a 20 20 20  ksum].    }..   
bc60: 20 23 20 53 65 74 20 74 68 65 20 4e 74 68 20 49   # Set the Nth I
bc70: 4f 20 65 72 72 6f 72 20 74 6f 20 66 61 69 6c 2e  O error to fail.
bc80: 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65  .    do_test $te
bc90: 73 74 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73 75 62  stname.$n.2 [sub
bca0: 73 74 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a  st {.      set :
bcb0: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
bcc0: 5f 70 65 72 73 69 73 74 20 24 3a 3a 69 6f 65 72  _persist $::ioer
bcd0: 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74 29 0a  ropts(-persist).
bce0: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
bcf0: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64  te_io_error_pend
bd00: 69 6e 67 20 24 6e 0a 20 20 20 20 7d 5d 20 24 6e  ing $n.    }] $n
bd10: 0a 0a 20 20 20 20 23 20 45 78 65 63 75 74 65 20  ..    # Execute 
bd20: 74 68 65 20 54 43 4c 20 73 63 72 69 70 74 20 63  the TCL script c
bd30: 72 65 61 74 65 64 20 66 6f 72 20 74 68 65 20 62  reated for the b
bd40: 6f 64 79 20 6f 66 20 74 68 69 73 20 74 65 73 74  ody of this test
bd50: 2e 20 49 66 0a 20 20 20 20 23 20 61 74 20 6c 65  . If.    # at le
bd60: 61 73 74 20 4e 20 49 4f 20 6f 70 65 72 61 74 69  ast N IO operati
bd70: 6f 6e 73 20 70 65 72 66 6f 72 6d 65 64 20 62 79  ons performed by
bd80: 20 53 51 4c 69 74 65 20 61 73 20 61 20 72 65 73   SQLite as a res
bd90: 75 6c 74 20 6f 66 0a 20 20 20 20 23 20 74 68 65  ult of.    # the
bda0: 20 73 63 72 69 70 74 2c 20 74 68 65 20 4e 74 68   script, the Nth
bdb0: 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 20 20 20 20   will fail..    
bdc0: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
bdd0: 65 2e 24 6e 2e 33 20 7b 0a 20 20 20 20 20 20 73  e.$n.3 {.      s
bde0: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  et ::sqlite_io_e
bdf0: 72 72 6f 72 5f 68 69 74 20 30 0a 20 20 20 20 20  rror_hit 0.     
be00: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
be10: 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 30  _error_hardhit 0
be20: 0a 20 20 20 20 20 20 73 65 74 20 72 20 5b 63 61  .      set r [ca
be30: 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 72 62 6f  tch $::ioerrorbo
be40: 64 79 20 6d 73 67 5d 0a 20 20 20 20 20 20 73 65  dy msg].      se
be50: 74 20 3a 3a 65 72 72 73 65 65 6e 20 24 72 0a 20  t ::errseen $r. 
be60: 20 20 20 20 20 73 65 74 20 72 63 20 5b 73 71 6c       set rc [sql
be70: 69 74 65 33 5f 65 72 72 63 6f 64 65 20 24 3a 3a  ite3_errcode $::
be80: 44 42 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a  DB].      if {$:
be90: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
bea0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66  } {.        # If
beb0: 20 77 65 20 61 72 65 20 69 6e 20 65 78 74 65 6e   we are in exten
bec0: 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20  ded result code 
bed0: 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20  mode, make sure 
bee0: 61 6c 6c 20 6f 66 20 74 68 65 0a 20 20 20 20 20  all of the.     
bef0: 20 20 20 23 20 49 4f 45 52 52 73 20 77 65 20 67     # IOERRs we g
bf00: 65 74 20 62 61 63 6b 20 72 65 61 6c 6c 79 20 64  et back really d
bf10: 6f 20 68 61 76 65 20 74 68 65 69 72 20 65 78 74  o have their ext
bf20: 65 6e 64 65 64 20 63 6f 64 65 20 76 61 6c 75 65  ended code value
bf30: 73 2e 0a 20 20 20 20 20 20 20 20 23 20 49 66 20  s..        # If 
bf40: 61 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73 75  an extended resu
bf50: 6c 74 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  lt code is retur
bf60: 6e 65 64 2c 20 74 68 65 20 73 71 6c 69 74 65 33  ned, the sqlite3
bf70: 5f 65 72 72 63 6f 64 65 0a 20 20 20 20 20 20 20  _errcode.       
bf80: 20 23 20 54 43 4c 63 6f 6d 6d 61 6e 64 20 77 69   # TCLcommand wi
bf90: 6c 6c 20 72 65 74 75 72 6e 20 61 20 73 74 72 69  ll return a stri
bfa0: 6e 67 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 20  ng of the form: 
bfb0: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 2b 6e 6e   SQLITE_IOERR+nn
bfc0: 6e 6e 0a 20 20 20 20 20 20 20 20 23 20 77 68 65  nn.        # whe
bfd0: 72 65 20 6e 6e 6e 6e 20 69 73 20 61 20 6e 75 6d  re nnnn is a num
bfe0: 62 65 72 0a 20 20 20 20 20 20 20 20 69 66 20 7b  ber.        if {
bff0: 5b 72 65 67 65 78 70 20 7b 5e 53 51 4c 49 54 45  [regexp {^SQLITE
c000: 5f 49 4f 45 52 52 7d 20 24 72 63 5d 20 26 26 20  _IOERR} $rc] && 
c010: 21 5b 72 65 67 65 78 70 20 7b 49 4f 45 52 52 5c  ![regexp {IOERR\
c020: 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20  +\d} $rc]} {.   
c030: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72         return $r
c040: 63 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  c.        }.    
c050: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
c060: 20 20 20 23 20 49 66 20 77 65 20 61 72 65 20 6e     # If we are n
c070: 6f 74 20 69 6e 20 65 78 74 65 6e 64 65 64 20 72  ot in extended r
c080: 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c  esult code mode,
c090: 20 6d 61 6b 65 20 73 75 72 65 20 6e 6f 0a 20 20   make sure no.  
c0a0: 20 20 20 20 20 20 23 20 65 78 74 65 6e 64 65 64        # extended
c0b0: 20 65 72 72 6f 72 20 63 6f 64 65 73 20 61 72 65   error codes are
c0c0: 20 72 65 74 75 72 6e 65 64 2e 0a 20 20 20 20 20   returned..     
c0d0: 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b     if {[regexp {
c0e0: 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20  \+\d} $rc]} {.  
c0f0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 24          return $
c100: 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  rc.        }.   
c110: 20 20 20 7d 0a 20 20 20 20 20 20 23 20 54 68 65     }.      # The
c120: 20 74 65 73 74 20 72 65 70 65 61 74 73 20 61 73   test repeats as
c130: 20 6c 6f 6e 67 20 61 73 20 24 3a 3a 67 6f 20 69   long as $::go i
c140: 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 20 24 3a 3a  s non-zero.  $::
c150: 67 6f 20 73 74 61 72 74 73 20 6f 75 74 0a 20 20  go starts out.  
c160: 20 20 20 20 23 20 61 73 20 31 2e 20 20 57 68 65      # as 1.  Whe
c170: 6e 20 61 20 74 65 73 74 20 72 75 6e 73 20 74 6f  n a test runs to
c180: 20 63 6f 6d 70 6c 65 74 69 6f 6e 20 77 69 74 68   completion with
c190: 6f 75 74 20 68 69 74 74 69 6e 67 20 61 6e 20 49  out hitting an I
c1a0: 2f 4f 0a 20 20 20 20 20 20 23 20 65 72 72 6f 72  /O.      # error
c1b0: 2c 20 74 68 61 74 20 6d 65 61 6e 73 20 74 68 65  , that means the
c1c0: 72 65 20 69 73 20 6e 6f 20 70 6f 69 6e 74 20 69  re is no point i
c1d0: 6e 20 63 6f 6e 74 69 6e 75 69 6e 67 20 77 69 74  n continuing wit
c1e0: 68 20 74 68 69 73 20 74 65 73 74 0a 20 20 20 20  h this test.    
c1f0: 20 20 23 20 63 61 73 65 20 73 6f 20 73 65 74 20    # case so set 
c200: 24 3a 3a 67 6f 20 74 6f 20 7a 65 72 6f 2e 0a 20  $::go to zero.. 
c210: 20 20 20 20 20 23 0a 20 20 20 20 20 20 69 66 20       #.      if 
c220: 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  {$::sqlite_io_er
c230: 72 6f 72 5f 70 65 6e 64 69 6e 67 3e 30 7d 20 7b  ror_pending>0} {
c240: 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a 67  .        set ::g
c250: 6f 20 30 0a 20 20 20 20 20 20 20 20 73 65 74 20  o 0.        set 
c260: 71 20 30 0a 20 20 20 20 20 20 20 20 73 65 74 20  q 0.        set 
c270: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
c280: 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 20 20  r_pending 0.    
c290: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
c2a0: 20 20 20 73 65 74 20 71 20 31 0a 20 20 20 20 20     set q 1.     
c2b0: 20 7d 0a 0a 20 20 20 20 20 20 73 65 74 20 73 20   }..      set s 
c2c0: 5b 65 78 70 72 20 24 3a 3a 73 71 6c 69 74 65 5f  [expr $::sqlite_
c2d0: 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3d 3d 30 5d  io_error_hit==0]
c2e0: 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 73 71  .      if {$::sq
c2f0: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69  lite_io_error_hi
c300: 74 3e 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  t>$::sqlite_io_e
c310: 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20  rror_hardhit && 
c320: 24 72 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20  $r==0} {.       
c330: 20 73 65 74 20 72 20 31 0a 20 20 20 20 20 20 7d   set r 1.      }
c340: 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  .      set ::sql
c350: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74  ite_io_error_hit
c360: 20 30 0a 0a 20 20 20 20 20 20 23 20 4f 6e 65 20   0..      # One 
c370: 6f 66 20 74 77 6f 20 74 68 69 6e 67 73 20 6d 75  of two things mu
c380: 73 74 20 68 61 76 65 20 68 61 70 70 65 6e 65 64  st have happened
c390: 2e 20 65 69 74 68 65 72 0a 20 20 20 20 20 20 23  . either.      #
c3a0: 20 20 20 31 2e 20 20 57 65 20 6e 65 76 65 72 20     1.  We never 
c3b0: 68 69 74 20 74 68 65 20 49 4f 20 65 72 72 6f 72  hit the IO error
c3c0: 20 61 6e 64 20 74 68 65 20 53 51 4c 20 72 65 74   and the SQL ret
c3d0: 75 72 6e 65 64 20 4f 4b 0a 20 20 20 20 20 20 23  urned OK.      #
c3e0: 20 20 20 32 2e 20 20 41 6e 20 49 4f 20 65 72 72     2.  An IO err
c3f0: 6f 72 20 77 61 73 20 68 69 74 20 61 6e 64 20 74  or was hit and t
c400: 68 65 20 53 51 4c 20 66 61 69 6c 65 64 0a 20 20  he SQL failed.  
c410: 20 20 20 20 23 0a 20 20 20 20 20 20 23 70 75 74      #.      #put
c420: 73 20 22 73 3d 24 73 20 72 3d 24 72 20 71 3d 24  s "s=$s r=$r q=$
c430: 71 22 0a 20 20 20 20 20 20 65 78 70 72 20 7b 20  q".      expr { 
c440: 28 24 73 20 26 26 20 21 24 72 20 26 26 20 21 24  ($s && !$r && !$
c450: 71 29 20 7c 7c 20 28 21 24 73 20 26 26 20 24 72  q) || (!$s && $r
c460: 20 26 26 20 24 71 29 20 7d 0a 20 20 20 20 7d 20   && $q) }.    } 
c470: 7b 31 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73  {1}..    set ::s
c480: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
c490: 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73  it 0.    set ::s
c4a0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
c4b0: 65 6e 64 69 6e 67 20 30 0a 0a 20 20 20 20 23 20  ending 0..    # 
c4c0: 43 68 65 63 6b 20 74 68 61 74 20 6e 6f 20 70 61  Check that no pa
c4d0: 67 65 20 72 65 66 65 72 65 6e 63 65 73 20 77 65  ge references we
c4e0: 72 65 20 6c 65 61 6b 65 64 2e 20 54 68 65 72 65  re leaked. There
c4f0: 20 73 68 6f 75 6c 64 20 62 65 0a 20 20 20 20 23   should be.    #
c500: 20 61 20 73 69 6e 67 6c 65 20 72 65 66 65 72 65   a single refere
c510: 6e 63 65 20 69 66 20 74 68 65 72 65 20 69 73 20  nce if there is 
c520: 73 74 69 6c 6c 20 61 6e 20 61 63 74 69 76 65 20  still an active 
c530: 74 72 61 6e 73 61 63 74 69 6f 6e 2c 0a 20 20 20  transaction,.   
c540: 20 23 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65 72   # or zero other
c550: 77 69 73 65 2e 0a 20 20 20 20 23 0a 20 20 20 20  wise..    #.    
c560: 23 20 55 50 44 41 54 45 3a 20 49 66 20 74 68 65  # UPDATE: If the
c570: 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   IO error occurs
c580: 20 61 66 74 65 72 20 61 20 27 42 45 47 49 4e 27   after a 'BEGIN'
c590: 20 62 75 74 20 62 65 66 6f 72 65 20 61 6e 79 0a   but before any.
c5a0: 20 20 20 20 23 20 6c 6f 63 6b 73 20 61 72 65 20      # locks are 
c5b0: 65 73 74 61 62 6c 69 73 68 65 64 20 6f 6e 20 64  established on d
c5c0: 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 28 69  atabase files (i
c5d0: 2e 65 2e 20 69 66 20 74 68 65 20 65 72 72 6f 72  .e. if the error
c5e0: 0a 20 20 20 20 23 20 6f 63 63 75 72 73 20 77 68  .    # occurs wh
c5f0: 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74  ile attempting t
c600: 6f 20 64 65 74 65 63 74 20 61 20 68 6f 74 2d 6a  o detect a hot-j
c610: 6f 75 72 6e 61 6c 20 66 69 6c 65 29 2c 20 74 68  ournal file), th
c620: 65 6e 0a 20 20 20 20 23 20 74 68 65 72 65 20 6d  en.    # there m
c630: 61 79 20 30 20 70 61 67 65 20 72 65 66 65 72 65  ay 0 page refere
c640: 6e 63 65 73 20 61 6e 64 20 61 6e 20 61 63 74 69  nces and an acti
c650: 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 61  ve transaction a
c660: 63 63 6f 72 64 69 6e 67 0a 20 20 20 20 23 20 74  ccording.    # t
c670: 6f 20 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61  o [sqlite3_get_a
c680: 75 74 6f 63 6f 6d 6d 69 74 5d 2e 0a 20 20 20 20  utocommit]..    
c690: 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f 20  #.    if {$::go 
c6a0: 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  && $::sqlite_io_
c6b0: 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26 26  error_hardhit &&
c6c0: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63   $::ioerropts(-c
c6d0: 6b 72 65 66 63 6f 75 6e 74 29 7d 20 7b 0a 20 20  krefcount)} {.  
c6e0: 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73      do_test $tes
c6f0: 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b 0a 20 20 20  tname.$n.4 {.   
c700: 20 20 20 20 20 73 65 74 20 62 74 20 5b 62 74 72       set bt [btr
c710: 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a 20  ee_from_db db]. 
c720: 20 20 20 20 20 20 20 64 62 5f 65 6e 74 65 72 20         db_enter 
c730: 64 62 0a 20 20 20 20 20 20 20 20 61 72 72 61 79  db.        array
c740: 20 73 65 74 20 73 74 61 74 73 20 5b 62 74 72 65   set stats [btre
c750: 65 5f 70 61 67 65 72 5f 73 74 61 74 73 20 24 62  e_pager_stats $b
c760: 74 5d 0a 20 20 20 20 20 20 20 20 64 62 5f 6c 65  t].        db_le
c770: 61 76 65 20 64 62 0a 20 20 20 20 20 20 20 20 73  ave db.        s
c780: 65 74 20 6e 52 65 66 20 24 73 74 61 74 73 28 72  et nRef $stats(r
c790: 65 66 29 0a 20 20 20 20 20 20 20 20 65 78 70 72  ef).        expr
c7a0: 20 7b 24 6e 52 65 66 20 3d 3d 20 30 20 7c 7c 20   {$nRef == 0 || 
c7b0: 28 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61 75  ([sqlite3_get_au
c7c0: 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 3d 3d 30 20  tocommit db]==0 
c7d0: 26 26 20 24 6e 52 65 66 20 3d 3d 20 31 29 7d 0a  && $nRef == 1)}.
c7e0: 20 20 20 20 20 20 7d 20 7b 31 7d 0a 20 20 20 20        } {1}.    
c7f0: 7d 0a 0a 20 20 20 20 23 20 49 66 20 74 68 65 72  }..    # If ther
c800: 65 20 69 73 20 61 6e 20 6f 70 65 6e 20 64 61 74  e is an open dat
c810: 61 62 61 73 65 20 68 61 6e 64 6c 65 20 61 6e 64  abase handle and
c820: 20 6e 6f 20 6f 70 65 6e 20 74 72 61 6e 73 61 63   no open transac
c830: 74 69 6f 6e 2c 0a 20 20 20 20 23 20 61 6e 64 20  tion,.    # and 
c840: 74 68 65 20 70 61 67 65 72 20 69 73 20 6e 6f 74  the pager is not
c850: 20 72 75 6e 6e 69 6e 67 20 69 6e 20 65 78 63 6c   running in excl
c860: 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67 20 6d 6f  usive-locking mo
c870: 64 65 2c 0a 20 20 20 20 23 20 63 68 65 63 6b 20  de,.    # check 
c880: 74 68 61 74 20 74 68 65 20 70 61 67 65 72 20 69  that the pager i
c890: 73 20 69 6e 20 22 75 6e 6c 6f 63 6b 65 64 22 20  s in "unlocked" 
c8a0: 73 74 61 74 65 2e 20 54 68 65 6f 72 65 74 69 63  state. Theoretic
c8b0: 61 6c 6c 79 2c 0a 20 20 20 20 23 20 69 66 20 61  ally,.    # if a
c8c0: 20 63 61 6c 6c 20 74 6f 20 78 55 6e 6c 6f 63 6b   call to xUnlock
c8d0: 28 29 20 66 61 69 6c 65 64 20 64 75 65 20 74 6f  () failed due to
c8e0: 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 74 68 65   an IO error the
c8f0: 20 75 6e 64 65 72 6c 79 69 6e 67 0a 20 20 20 20   underlying.    
c900: 23 20 66 69 6c 65 20 6d 61 79 20 73 74 69 6c 6c  # file may still
c910: 20 62 65 20 6c 6f 63 6b 65 64 2e 0a 20 20 20 20   be locked..    
c920: 23 0a 20 20 20 20 69 66 63 61 70 61 62 6c 65 20  #.    ifcapable 
c930: 70 72 61 67 6d 61 20 7b 0a 20 20 20 20 20 20 69  pragma {.      i
c940: 66 20 7b 20 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e  f { [info comman
c950: 64 73 20 64 62 5d 20 6e 65 20 22 22 0a 20 20 20  ds db] ne "".   
c960: 20 20 20 20 20 26 26 20 24 3a 3a 69 6f 65 72 72       && $::ioerr
c970: 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74  opts(-ckrefcount
c980: 29 0a 20 20 20 20 20 20 20 20 26 26 20 5b 64 62  ).        && [db
c990: 20 6f 6e 65 20 7b 70 72 61 67 6d 61 20 6c 6f 63   one {pragma loc
c9a0: 6b 69 6e 67 5f 6d 6f 64 65 7d 5d 20 65 71 20 22  king_mode}] eq "
c9b0: 6e 6f 72 6d 61 6c 22 0a 20 20 20 20 20 20 20 20  normal".        
c9c0: 26 26 20 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f  && [sqlite3_get_
c9d0: 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 0a 20  autocommit db]. 
c9e0: 20 20 20 20 20 7d 20 7b 0a 20 20 20 20 20 20 20       } {.       
c9f0: 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61   do_test $testna
ca00: 6d 65 2e 24 6e 2e 35 20 7b 0a 20 20 20 20 20 20  me.$n.5 {.      
ca10: 20 20 20 20 73 65 74 20 62 74 20 5b 62 74 72 65      set bt [btre
ca20: 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a 20 20  e_from_db db].  
ca30: 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74 65 72          db_enter
ca40: 20 64 62 0a 20 20 20 20 20 20 20 20 20 20 61 72   db.          ar
ca50: 72 61 79 20 73 65 74 20 73 74 61 74 73 20 5b 62  ray set stats [b
ca60: 74 72 65 65 5f 70 61 67 65 72 5f 73 74 61 74 73  tree_pager_stats
ca70: 20 24 62 74 5d 0a 20 20 20 20 20 20 20 20 20 20   $bt].          
ca80: 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20 20 20  db_leave db.    
ca90: 20 20 20 20 20 20 73 65 74 20 73 74 61 74 73 28        set stats(
caa0: 73 74 61 74 65 29 0a 20 20 20 20 20 20 20 20 7d  state).        }
cab0: 20 30 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   0.      }.    }
cac0: 0a 0a 20 20 20 20 23 20 49 66 20 61 6e 20 49 4f  ..    # If an IO
cad0: 20 65 72 72 6f 72 20 6f 63 63 75 72 72 65 64 2c   error occurred,
cae0: 20 74 68 65 6e 20 74 68 65 20 63 68 65 63 6b 73   then the checks
caf0: 75 6d 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  um of the databa
cb00: 73 65 20 73 68 6f 75 6c 64 0a 20 20 20 20 23 20  se should.    # 
cb10: 62 65 20 74 68 65 20 73 61 6d 65 20 61 73 20 62  be the same as b
cb20: 65 66 6f 72 65 20 74 68 65 20 73 63 72 69 70 74  efore the script
cb30: 20 74 68 61 74 20 63 61 75 73 65 64 20 74 68 65   that caused the
cb40: 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20 72 75   IO error was ru
cb50: 6e 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20  n..    #.    if 
cb60: 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71 6c  {$::go && $::sql
cb70: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72  ite_io_error_har
cb80: 64 68 69 74 20 26 26 20 24 3a 3a 69 6f 65 72 72  dhit && $::ioerr
cb90: 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a  opts(-cksum)} {.
cba0: 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74        do_test $t
cbb0: 65 73 74 6e 61 6d 65 2e 24 6e 2e 36 20 7b 0a 20  estname.$n.6 {. 
cbc0: 20 20 20 20 20 20 20 63 61 74 63 68 20 7b 64 62         catch {db
cbd0: 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20 20   close}.        
cbe0: 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65  catch {db2 close
cbf0: 7d 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a  }.        set ::
cc00: 44 42 20 5b 73 71 6c 69 74 65 33 20 64 62 20 74  DB [sqlite3 db t
cc10: 65 73 74 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f  est.db; sqlite3_
cc20: 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74  connection_point
cc30: 65 72 20 64 62 5d 0a 20 20 20 20 20 20 20 20 73  er db].        s
cc40: 65 74 20 6e 6f 77 63 6b 73 75 6d 20 5b 63 6b 73  et nowcksum [cks
cc50: 75 6d 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20  um].        set 
cc60: 72 65 73 20 5b 65 78 70 72 20 7b 24 6e 6f 77 63  res [expr {$nowc
cc70: 6b 73 75 6d 3d 3d 24 3a 3a 63 68 65 63 6b 73 75  ksum==$::checksu
cc80: 6d 20 7c 7c 20 24 6e 6f 77 63 6b 73 75 6d 3d 3d  m || $nowcksum==
cc90: 24 3a 3a 67 6f 6f 64 63 6b 73 75 6d 7d 5d 0a 20  $::goodcksum}]. 
cca0: 20 20 20 20 20 20 20 69 66 20 7b 24 72 65 73 3d         if {$res=
ccb0: 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20  =0} {.          
ccc0: 6f 75 74 70 75 74 32 20 22 6e 6f 77 3d 24 6e 6f  output2 "now=$no
ccd0: 77 63 6b 73 75 6d 22 0a 20 20 20 20 20 20 20 20  wcksum".        
cce0: 20 20 6f 75 74 70 75 74 32 20 22 74 68 65 3d 24    output2 "the=$
ccf0: 3a 3a 63 68 65 63 6b 73 75 6d 22 0a 20 20 20 20  ::checksum".    
cd00: 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22 66        output2 "f
cd10: 77 64 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75 6d 22  wd=$::goodcksum"
cd20: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
cd30: 20 20 20 73 65 74 20 72 65 73 0a 20 20 20 20 20     set res.     
cd40: 20 7d 20 31 0a 20 20 20 20 7d 0a 0a 20 20 20 20   } 1.    }..    
cd50: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
cd60: 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a  error_hardhit 0.
cd70: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
cd80: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e  _io_error_pendin
cd90: 67 20 30 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66  g 0.    if {[inf
cda0: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
cdb0: 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70 29 5d 7d  opts(-cleanup)]}
cdc0: 20 7b 0a 20 20 20 20 20 20 63 61 74 63 68 20 24   {.      catch $
cdd0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65  ::ioerropts(-cle
cde0: 61 6e 75 70 29 0a 20 20 20 20 7d 0a 20 20 7d 0a  anup).    }.  }.
cdf0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
ce00: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
ce10: 30 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65  0.  set ::sqlite
ce20: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73  _io_error_persis
ce30: 74 20 30 0a 20 20 75 6e 73 65 74 20 3a 3a 69 6f  t 0.  unset ::io
ce40: 65 72 72 6f 70 74 73 0a 7d 0a 0a 23 20 52 65 74  erropts.}..# Ret
ce50: 75 72 6e 20 61 20 63 68 65 63 6b 73 75 6d 20 62  urn a checksum b
ce60: 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74  ased on the cont
ce70: 65 6e 74 73 20 6f 66 20 74 68 65 20 6d 61 69 6e  ents of the main
ce80: 20 64 61 74 61 62 61 73 65 20 61 73 73 6f 63 69   database associ
ce90: 61 74 65 64 0a 23 20 77 69 74 68 20 63 6f 6e 6e  ated.# with conn
cea0: 65 63 74 69 6f 6e 20 24 64 62 0a 23 0a 70 72 6f  ection $db.#.pro
ceb0: 63 20 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d  c cksum {{db db}
cec0: 7d 20 7b 0a 20 20 73 65 74 20 74 78 74 20 5b 24  } {.  set txt [$
ced0: 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20  db eval {.      
cee0: 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79 70  SELECT name, typ
cef0: 65 2c 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69  e, sql FROM sqli
cf00: 74 65 5f 6d 61 73 74 65 72 20 6f 72 64 65 72 20  te_master order 
cf10: 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e 0a 20  by name.  }]\n. 
cf20: 20 66 6f 72 65 61 63 68 20 74 62 6c 20 5b 24 64   foreach tbl [$d
cf30: 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53  b eval {.      S
cf40: 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20  ELECT name FROM 
cf50: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
cf60: 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27  ERE type='table'
cf70: 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20   order by name. 
cf80: 20 7d 5d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64   }] {.    append
cf90: 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22   txt [$db eval "
cfa0: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 74  SELECT * FROM $t
cfb0: 62 6c 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66 6f 72  bl"]\n.  }.  for
cfc0: 65 61 63 68 20 70 72 61 67 20 7b 64 65 66 61 75  each prag {defau
cfd0: 6c 74 5f 73 79 6e 63 68 72 6f 6e 6f 75 73 20 64  lt_synchronous d
cfe0: 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a  efault_cache_siz
cff0: 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20  e} {.    append 
d000: 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65  txt $prag-[$db e
d010: 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61  val "PRAGMA $pra
d020: 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65 74 20  g"]\n.  }.  set 
d030: 63 6b 73 75 6d 20 5b 73 74 72 69 6e 67 20 6c 65  cksum [string le
d040: 6e 67 74 68 20 24 74 78 74 5d 2d 5b 6d 64 35 20  ngth $txt]-[md5 
d050: 24 74 78 74 5d 0a 20 20 23 20 70 75 74 73 20 24  $txt].  # puts $
d060: 63 6b 73 75 6d 2d 5b 66 69 6c 65 20 73 69 7a 65  cksum-[file size
d070: 20 74 65 73 74 2e 64 62 5d 0a 20 20 72 65 74 75   test.db].  retu
d080: 72 6e 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23 20 47  rn $cksum.}..# G
d090: 65 6e 65 72 61 74 65 20 61 20 63 68 65 63 6b 73  enerate a checks
d0a0: 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20  um based on the 
d0b0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20  contents of the 
d0c0: 6d 61 69 6e 20 61 6e 64 20 74 65 6d 70 20 74 61  main and temp ta
d0d0: 62 6c 65 73 0a 23 20 64 61 74 61 62 61 73 65 20  bles.# database 
d0e0: 24 64 62 2e 20 49 66 20 74 68 65 20 63 68 65 63  $db. If the chec
d0f0: 6b 73 75 6d 20 6f 66 20 74 77 6f 20 64 61 74 61  ksum of two data
d100: 62 61 73 65 73 20 69 73 20 74 68 65 20 73 61 6d  bases is the sam
d110: 65 2c 20 61 6e 64 20 74 68 65 0a 23 20 69 6e 74  e, and the.# int
d120: 65 67 72 69 74 79 2d 63 68 65 63 6b 20 70 61 73  egrity-check pas
d130: 73 65 73 20 66 6f 72 20 62 6f 74 68 2c 20 74 68  ses for both, th
d140: 65 20 74 77 6f 20 64 61 74 61 62 61 73 65 73 20  e two databases 
d150: 61 72 65 20 69 64 65 6e 74 69 63 61 6c 2e 0a 23  are identical..#
d160: 0a 70 72 6f 63 20 61 6c 6c 63 6b 73 75 6d 20 7b  .proc allcksum {
d170: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74  {db db}} {.  set
d180: 20 72 65 74 20 5b 6c 69 73 74 5d 0a 20 20 69 66   ret [list].  if
d190: 63 61 70 61 62 6c 65 20 74 65 6d 70 64 62 20 7b  capable tempdb {
d1a0: 0a 20 20 20 20 73 65 74 20 73 71 6c 20 7b 0a 20  .    set sql {. 
d1b0: 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65       SELECT name
d1c0: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
d1d0: 74 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d  ter WHERE type =
d1e0: 20 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20   'table' UNION. 
d1f0: 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65       SELECT name
d200: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 74 65 6d   FROM sqlite_tem
d210: 70 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  p_master WHERE t
d220: 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e  ype = 'table' UN
d230: 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54  ION.      SELECT
d240: 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27   'sqlite_master'
d250: 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c   UNION.      SEL
d260: 45 43 54 20 27 73 71 6c 69 74 65 5f 74 65 6d 70  ECT 'sqlite_temp
d270: 5f 6d 61 73 74 65 72 27 20 4f 52 44 45 52 20 42  _master' ORDER B
d280: 59 20 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c  Y 1.    }.  } el
d290: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 73 71 6c  se {.    set sql
d2a0: 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20   {.      SELECT 
d2b0: 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65  name FROM sqlite
d2c0: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  _master WHERE ty
d2d0: 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49  pe = 'table' UNI
d2e0: 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20  ON.      SELECT 
d2f0: 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20  'sqlite_master' 
d300: 4f 52 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d  ORDER BY 1.    }
d310: 0a 20 20 7d 0a 20 20 73 65 74 20 74 62 6c 6c 69  .  }.  set tblli
d320: 73 74 20 5b 24 64 62 20 65 76 61 6c 20 24 73 71  st [$db eval $sq
d330: 6c 5d 0a 20 20 73 65 74 20 74 78 74 20 7b 7d 0a  l].  set txt {}.
d340: 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20 24 74    foreach tbl $t
d350: 62 6c 6c 69 73 74 20 7b 0a 20 20 20 20 61 70 70  bllist {.    app
d360: 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76 61  end txt [$db eva
d370: 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  l "SELECT * FROM
d380: 20 24 74 62 6c 22 5d 0a 20 20 7d 0a 20 20 66 6f   $tbl"].  }.  fo
d390: 72 65 61 63 68 20 70 72 61 67 20 7b 64 65 66 61  reach prag {defa
d3a0: 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d 20  ult_cache_size} 
d3b0: 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78 74  {.    append txt
d3c0: 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76 61 6c   $prag-[$db eval
d3d0: 20 22 50 52 41 47 4d 41 20 24 70 72 61 67 22 5d   "PRAGMA $prag"]
d3e0: 5c 6e 0a 20 20 7d 0a 20 20 23 20 70 75 74 73 20  \n.  }.  # puts 
d3f0: 74 78 74 3d 24 74 78 74 0a 20 20 72 65 74 75 72  txt=$txt.  retur
d400: 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a  n [md5 $txt].}..
d410: 23 20 47 65 6e 65 72 61 74 65 20 61 20 63 68 65  # Generate a che
d420: 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74  cksum based on t
d430: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61  he contents of a
d440: 20 73 69 6e 67 6c 65 20 64 61 74 61 62 61 73 65   single database
d450: 20 77 69 74 68 0a 23 20 61 20 64 61 74 61 62 61   with.# a databa
d460: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20 20  se connection.  
d470: 54 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  The name of the 
d480: 64 61 74 61 62 61 73 65 20 69 73 20 24 64 62 6e  database is $dbn
d490: 61 6d 65 2e 0a 23 20 45 78 61 6d 70 6c 65 73 20  ame..# Examples 
d4a0: 6f 66 20 24 64 62 6e 61 6d 65 20 61 72 65 20 22  of $dbname are "
d4b0: 74 65 6d 70 22 20 6f 72 20 22 6d 61 69 6e 22 2e  temp" or "main".
d4c0: 0a 23 0a 70 72 6f 63 20 64 62 63 6b 73 75 6d 20  .#.proc dbcksum 
d4d0: 7b 64 62 20 64 62 6e 61 6d 65 7d 20 7b 0a 20 20  {db dbname} {.  
d4e0: 69 66 20 7b 24 64 62 6e 61 6d 65 3d 3d 22 74 65  if {$dbname=="te
d4f0: 6d 70 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 6d  mp"} {.    set m
d500: 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74 65 6d  aster sqlite_tem
d510: 70 5f 6d 61 73 74 65 72 0a 20 20 7d 20 65 6c 73  p_master.  } els
d520: 65 20 7b 0a 20 20 20 20 73 65 74 20 6d 61 73 74  e {.    set mast
d530: 65 72 20 24 64 62 6e 61 6d 65 2e 73 71 6c 69 74  er $dbname.sqlit
d540: 65 5f 6d 61 73 74 65 72 0a 20 20 7d 0a 20 20 73  e_master.  }.  s
d550: 65 74 20 61 6c 6c 74 61 62 20 5b 24 64 62 20 65  et alltab [$db e
d560: 76 61 6c 20 22 53 45 4c 45 43 54 20 6e 61 6d 65  val "SELECT name
d570: 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 20 57 48   FROM $master WH
d580: 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27  ERE type='table'
d590: 22 5d 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64  "].  set txt [$d
d5a0: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a  b eval "SELECT *
d5b0: 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 22 5d 5c   FROM $master"]\
d5c0: 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 61 62 20  n.  foreach tab 
d5d0: 24 61 6c 6c 74 61 62 20 7b 0a 20 20 20 20 61 70  $alltab {.    ap
d5e0: 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76  pend txt [$db ev
d5f0: 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  al "SELECT * FRO
d600: 4d 20 24 64 62 6e 61 6d 65 2e 24 74 61 62 22 5d  M $dbname.$tab"]
d610: 5c 6e 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  \n.  }.  return 
d620: 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 70 72  [md5 $txt].}..pr
d630: 6f 63 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f  oc memdebug_log_
d640: 73 71 6c 20 7b 7b 66 69 6c 65 6e 61 6d 65 20 6d  sql {{filename m
d650: 61 6c 6c 6f 63 73 2e 73 71 6c 7d 7d 20 7b 0a 0a  allocs.sql}} {..
d660: 20 20 73 65 74 20 64 61 74 61 20 5b 73 71 6c 69    set data [sqli
d670: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67  te3_memdebug_log
d680: 20 64 75 6d 70 5d 0a 20 20 73 65 74 20 6e 46 72   dump].  set nFr
d690: 61 6d 65 20 5b 65 78 70 72 20 5b 6c 6c 65 6e 67  ame [expr [lleng
d6a0: 74 68 20 5b 6c 69 6e 64 65 78 20 24 64 61 74 61  th [lindex $data
d6b0: 20 30 5d 5d 2d 32 5d 0a 20 20 69 66 20 7b 24 6e   0]]-2].  if {$n
d6c0: 46 72 61 6d 65 20 3c 20 30 7d 20 7b 20 72 65 74  Frame < 0} { ret
d6d0: 75 72 6e 20 22 22 20 7d 0a 0a 20 20 73 65 74 20  urn "" }..  set 
d6e0: 64 61 74 61 62 61 73 65 20 74 65 6d 70 0a 0a 20  database temp.. 
d6f0: 20 73 65 74 20 74 62 6c 20 22 43 52 45 41 54 45   set tbl "CREATE
d700: 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73   TABLE ${databas
d710: 65 7d 2e 6d 61 6c 6c 6f 63 28 7a 54 65 73 74 2c  e}.malloc(zTest,
d720: 20 6e 43 61 6c 6c 2c 20 6e 42 79 74 65 2c 20 6c   nCall, nByte, l
d730: 53 74 61 63 6b 29 3b 22 0a 0a 20 20 73 65 74 20  Stack);"..  set 
d740: 73 71 6c 20 22 22 0a 20 20 66 6f 72 65 61 63 68  sql "".  foreach
d750: 20 65 20 24 64 61 74 61 20 7b 0a 20 20 20 20 73   e $data {.    s
d760: 65 74 20 6e 43 61 6c 6c 20 5b 6c 69 6e 64 65 78  et nCall [lindex
d770: 20 24 65 20 30 5d 0a 20 20 20 20 73 65 74 20 6e   $e 0].    set n
d780: 42 79 74 65 20 5b 6c 69 6e 64 65 78 20 24 65 20  Byte [lindex $e 
d790: 31 5d 0a 20 20 20 20 73 65 74 20 6c 53 74 61 63  1].    set lStac
d7a0: 6b 20 5b 6c 72 61 6e 67 65 20 24 65 20 32 20 65  k [lrange $e 2 e
d7b0: 6e 64 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73  nd].    append s
d7c0: 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20  ql "INSERT INTO 
d7d0: 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c 6c  ${database}.mall
d7e0: 6f 63 20 56 41 4c 55 45 53 22 0a 20 20 20 20 61  oc VALUES".    a
d7f0: 70 70 65 6e 64 20 73 71 6c 20 22 28 27 74 65 73  ppend sql "('tes
d800: 74 27 2c 20 24 6e 43 61 6c 6c 2c 20 24 6e 42 79  t', $nCall, $nBy
d810: 74 65 2c 20 27 24 6c 53 74 61 63 6b 27 29 3b 5c  te, '$lStack');\
d820: 6e 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66  n".    foreach f
d830: 20 24 6c 53 74 61 63 6b 20 7b 0a 20 20 20 20 20   $lStack {.     
d840: 20 73 65 74 20 66 72 61 6d 65 73 28 24 66 29 20   set frames($f) 
d850: 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73  1.    }.  }..  s
d860: 65 74 20 74 62 6c 32 20 22 43 52 45 41 54 45 20  et tbl2 "CREATE 
d870: 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65  TABLE ${database
d880: 7d 2e 66 72 61 6d 65 28 66 72 61 6d 65 20 49 4e  }.frame(frame IN
d890: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45  TEGER PRIMARY KE
d8a0: 59 2c 20 6c 69 6e 65 29 3b 5c 6e 22 0a 20 20 73  Y, line);\n".  s
d8b0: 65 74 20 74 62 6c 33 20 22 43 52 45 41 54 45 20  et tbl3 "CREATE 
d8c0: 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65  TABLE ${database
d8d0: 7d 2e 66 69 6c 65 28 6e 61 6d 65 20 50 52 49 4d  }.file(name PRIM
d8e0: 41 52 59 20 4b 45 59 2c 20 63 6f 6e 74 65 6e 74  ARY KEY, content
d8f0: 29 3b 5c 6e 22 0a 0a 20 20 66 6f 72 65 61 63 68  );\n"..  foreach
d900: 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20   f [array names 
d910: 66 72 61 6d 65 73 5d 20 7b 0a 20 20 20 20 73 65  frames] {.    se
d920: 74 20 61 64 64 72 20 5b 66 6f 72 6d 61 74 20 25  t addr [format %
d930: 78 20 24 66 5d 0a 20 20 20 20 73 65 74 20 63 6d  x $f].    set cm
d940: 64 20 22 61 64 64 72 32 6c 69 6e 65 20 2d 65 20  d "addr2line -e 
d950: 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63  [info nameofexec
d960: 5d 20 24 61 64 64 72 22 0a 20 20 20 20 73 65 74  ] $addr".    set
d970: 20 6c 69 6e 65 20 5b 65 76 61 6c 20 65 78 65 63   line [eval exec
d980: 20 24 63 6d 64 5d 0a 20 20 20 20 61 70 70 65 6e   $cmd].    appen
d990: 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e  d sql "INSERT IN
d9a0: 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66  TO ${database}.f
d9b0: 72 61 6d 65 20 56 41 4c 55 45 53 28 24 66 2c 20  rame VALUES($f, 
d9c0: 27 24 6c 69 6e 65 27 29 3b 5c 6e 22 0a 0a 20 20  '$line');\n"..  
d9d0: 20 20 73 65 74 20 66 69 6c 65 20 5b 6c 69 6e 64    set file [lind
d9e0: 65 78 20 5b 73 70 6c 69 74 20 24 6c 69 6e 65 20  ex [split $line 
d9f0: 3a 5d 20 30 5d 0a 20 20 20 20 73 65 74 20 66 69  :] 0].    set fi
da00: 6c 65 73 28 24 66 69 6c 65 29 20 31 0a 20 20 7d  les($file) 1.  }
da10: 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 61  ..  foreach f [a
da20: 72 72 61 79 20 6e 61 6d 65 73 20 66 69 6c 65 73  rray names files
da30: 5d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6e 74  ] {.    set cont
da40: 65 6e 74 73 20 22 22 0a 20 20 20 20 63 61 74 63  ents "".    catc
da50: 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66 64  h {.      set fd
da60: 20 5b 6f 70 65 6e 20 24 66 5d 0a 20 20 20 20 20   [open $f].     
da70: 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 5b 72   set contents [r
da80: 65 61 64 20 24 66 64 5d 0a 20 20 20 20 20 20 63  ead $fd].      c
da90: 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 7d 0a 20  lose $fd.    }. 
daa0: 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20     set contents 
dab0: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27  [string map {' '
dac0: 27 7d 20 24 63 6f 6e 74 65 6e 74 73 5d 0a 20 20  '} $contents].  
dad0: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e    append sql "IN
dae0: 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61  SERT INTO ${data
daf0: 62 61 73 65 7d 2e 66 69 6c 65 20 56 41 4c 55 45  base}.file VALUE
db00: 53 28 27 24 66 27 2c 20 27 24 63 6f 6e 74 65 6e  S('$f', '$conten
db10: 74 73 27 29 3b 5c 6e 22 0a 20 20 7d 0a 0a 20 20  ts');\n".  }..  
db20: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66 69  set fd [open $fi
db30: 6c 65 6e 61 6d 65 20 77 5d 0a 20 20 70 75 74 73  lename w].  puts
db40: 20 24 66 64 20 22 42 45 47 49 4e 3b 20 24 7b 74   $fd "BEGIN; ${t
db50: 62 6c 7d 24 7b 74 62 6c 32 7d 24 7b 74 62 6c 33  bl}${tbl2}${tbl3
db60: 7d 24 7b 73 71 6c 7d 20 3b 20 43 4f 4d 4d 49 54  }${sql} ; COMMIT
db70: 3b 22 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 7d  ;".  close $fd.}
db80: 0a 0a 23 20 44 72 6f 70 20 61 6c 6c 20 74 61 62  ..# Drop all tab
db90: 6c 65 73 20 69 6e 20 64 61 74 61 62 61 73 65 20  les in database 
dba0: 5b 64 62 5d 0a 70 72 6f 63 20 64 72 6f 70 5f 61  [db].proc drop_a
dbb0: 6c 6c 5f 74 61 62 6c 65 73 20 7b 7b 64 62 20 64  ll_tables {{db d
dbc0: 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61 62 6c  b}} {.  ifcapabl
dbd0: 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65 69  e trigger&&forei
dbe0: 67 6e 6b 65 79 20 7b 0a 20 20 20 20 73 65 74 20  gnkey {.    set 
dbf0: 70 6b 20 5b 24 64 62 20 6f 6e 65 20 22 50 52 41  pk [$db one "PRA
dc00: 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73  GMA foreign_keys
dc10: 22 5d 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20  "].    $db eval 
dc20: 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f  "PRAGMA foreign_
dc30: 6b 65 79 73 20 3d 20 4f 46 46 22 0a 20 20 7d 0a  keys = OFF".  }.
dc40: 20 20 66 6f 72 65 61 63 68 20 7b 69 64 78 20 6e    foreach {idx n
dc50: 61 6d 65 20 66 69 6c 65 7d 20 5b 64 62 20 65 76  ame file} [db ev
dc60: 61 6c 20 7b 50 52 41 47 4d 41 20 64 61 74 61 62  al {PRAGMA datab
dc70: 61 73 65 5f 6c 69 73 74 7d 5d 20 7b 0a 20 20 20  ase_list}] {.   
dc80: 20 69 66 20 7b 24 69 64 78 3d 3d 31 7d 20 7b 0a   if {$idx==1} {.
dc90: 20 20 20 20 20 20 73 65 74 20 6d 61 73 74 65 72        set master
dca0: 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73   sqlite_temp_mas
dcb0: 74 65 72 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  ter.    } else {
dcc0: 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74 65  .      set maste
dcd0: 72 20 24 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d  r $name.sqlite_m
dce0: 61 73 74 65 72 0a 20 20 20 20 7d 0a 20 20 20 20  aster.    }.    
dcf0: 66 6f 72 65 61 63 68 20 7b 74 20 74 79 70 65 7d  foreach {t type}
dd00: 20 5b 24 64 62 20 65 76 61 6c 20 22 0a 20 20 20   [$db eval ".   
dd10: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20     SELECT name, 
dd20: 74 79 70 65 20 46 52 4f 4d 20 24 6d 61 73 74 65  type FROM $maste
dd30: 72 0a 20 20 20 20 20 20 57 48 45 52 45 20 74 79  r.      WHERE ty
dd40: 70 65 20 49 4e 28 27 74 61 62 6c 65 27 2c 20 27  pe IN('table', '
dd50: 76 69 65 77 27 29 20 41 4e 44 20 6e 61 6d 65 20  view') AND name 
dd60: 4e 4f 54 20 4c 49 4b 45 20 27 73 71 6c 69 74 65  NOT LIKE 'sqlite
dd70: 58 5f 25 27 20 45 53 43 41 50 45 20 27 58 27 0a  X_%' ESCAPE 'X'.
dd80: 20 20 20 20 22 5d 20 7b 0a 20 20 20 20 20 20 24      "] {.      $
dd90: 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20 24 74  db eval "DROP $t
dda0: 79 70 65 20 5c 22 24 74 5c 22 22 0a 20 20 20 20  ype \"$t\"".    
ddb0: 7d 0a 20 20 7d 0a 20 20 69 66 63 61 70 61 62 6c  }.  }.  ifcapabl
ddc0: 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65 69  e trigger&&forei
ddd0: 67 6e 6b 65 79 20 7b 0a 20 20 20 20 24 64 62 20  gnkey {.    $db 
dde0: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66 6f 72  eval "PRAGMA for
ddf0: 65 69 67 6e 5f 6b 65 79 73 20 3d 20 24 70 6b 22  eign_keys = $pk"
de00: 0a 20 20 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  .  }.}..#-------
de10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de50: 2d 2d 0a 23 20 49 66 20 61 20 74 65 73 74 20 73  --.# If a test s
de60: 63 72 69 70 74 20 69 73 20 65 78 65 63 75 74 65  cript is execute
de70: 64 20 77 69 74 68 20 67 6c 6f 62 61 6c 20 76 61  d with global va
de80: 72 69 61 62 6c 65 20 24 3a 3a 47 28 70 65 72 6d  riable $::G(perm
de90: 3a 6e 61 6d 65 29 20 73 65 74 20 74 6f 0a 23 20  :name) set to.# 
dea0: 22 77 61 6c 22 2c 20 74 68 65 6e 20 74 68 65 20  "wal", then the 
deb0: 74 65 73 74 73 20 61 72 65 20 72 75 6e 20 69 6e  tests are run in
dec0: 20 57 41 4c 20 6d 6f 64 65 2e 20 4f 74 68 65 72   WAL mode. Other
ded0: 77 69 73 65 2c 20 74 68 65 79 20 73 68 6f 75 6c  wise, they shoul
dee0: 64 20 62 65 20 72 75 6e 0a 23 20 69 6e 20 72 6f  d be run.# in ro
def0: 6c 6c 62 61 63 6b 20 6d 6f 64 65 2e 20 54 68 65  llback mode. The
df00: 20 66 6f 6c 6c 6f 77 69 6e 67 20 54 63 6c 20 70   following Tcl p
df10: 72 6f 63 73 20 61 72 65 20 75 73 65 64 20 74 6f  rocs are used to
df20: 20 6d 61 6b 65 20 74 68 69 73 20 6c 65 73 73 0a   make this less.
df30: 23 20 69 6e 74 72 75 73 69 76 65 3a 0a 23 0a 23  # intrusive:.#.#
df40: 20 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e     wal_set_journ
df50: 61 6c 5f 6d 6f 64 65 20 3f 44 42 3f 0a 23 0a 23  al_mode ?DB?.#.#
df60: 20 20 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20       If running 
df70: 61 20 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63  a WAL test, exec
df80: 75 74 65 20 22 50 52 41 47 4d 41 20 6a 6f 75 72  ute "PRAGMA jour
df90: 6e 61 6c 5f 6d 6f 64 65 20 3d 20 77 61 6c 22 20  nal_mode = wal" 
dfa0: 75 73 69 6e 67 0a 23 20 20 20 20 20 63 6f 6e 6e  using.#     conn
dfb0: 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42  ection handle DB
dfc0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74 68 69  . Otherwise, thi
dfd0: 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61 20 6e  s command is a n
dfe0: 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f  o-op..#.#   wal_
dff0: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
e000: 64 65 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f  de TESTNAME ?DB?
e010: 0a 23 0a 23 20 20 20 20 20 49 66 20 72 75 6e 6e  .#.#     If runn
e020: 69 6e 67 20 61 20 57 41 4c 20 74 65 73 74 2c 20  ing a WAL test, 
e030: 65 78 65 63 75 74 65 20 61 20 74 65 73 74 73 20  execute a tests 
e040: 63 61 73 65 20 74 68 61 74 20 66 61 69 6c 73 20  case that fails 
e050: 69 66 20 74 68 65 20 6d 61 69 6e 0a 23 20 20 20  if the main.#   
e060: 20 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 63    database for c
e070: 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65  onnection handle
e080: 20 44 42 20 69 73 20 6e 6f 74 20 63 75 72 72 65   DB is not curre
e090: 6e 74 6c 79 20 61 20 57 41 4c 20 64 61 74 61 62  ntly a WAL datab
e0a0: 61 73 65 2e 0a 23 20 20 20 20 20 4f 74 68 65 72  ase..#     Other
e0b0: 77 69 73 65 20 28 69 66 20 6e 6f 74 20 72 75 6e  wise (if not run
e0c0: 6e 69 6e 67 20 61 20 57 41 4c 20 70 65 72 6d 75  ning a WAL permu
e0d0: 74 61 74 69 6f 6e 29 20 74 68 69 73 20 69 73 20  tation) this is 
e0e0: 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77  a no-op..#.#   w
e0f0: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23  al_is_wal_mode.#
e100: 0a 23 20 20 20 20 20 52 65 74 75 72 6e 73 20 74  .#     Returns t
e110: 72 75 65 20 69 66 20 74 68 69 73 20 74 65 73 74  rue if this test
e120: 20 73 68 6f 75 6c 64 20 62 65 20 72 75 6e 20 69   should be run i
e130: 6e 20 57 41 4c 20 6d 6f 64 65 2e 20 46 61 6c 73  n WAL mode. Fals
e140: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 23 0a 70  e otherwise..#.p
e150: 72 6f 63 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d  roc wal_is_wal_m
e160: 6f 64 65 20 7b 7d 20 7b 0a 20 20 65 78 70 72 20  ode {} {.  expr 
e170: 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20 65  {[permutation] e
e180: 71 20 22 77 61 6c 22 7d 0a 7d 0a 70 72 6f 63 20  q "wal"}.}.proc 
e190: 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f  wal_set_journal_
e1a0: 6d 6f 64 65 20 7b 7b 64 62 20 64 62 7d 7d 20 7b  mode {{db db}} {
e1b0: 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f  .  if { [wal_is_
e1c0: 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20  wal_mode] } {.  
e1d0: 20 20 24 64 62 20 65 76 61 6c 20 22 50 52 41 47    $db eval "PRAG
e1e0: 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  MA journal_mode 
e1f0: 3d 20 57 41 4c 22 0a 20 20 7d 0a 7d 0a 70 72 6f  = WAL".  }.}.pro
e200: 63 20 77 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72  c wal_check_jour
e210: 6e 61 6c 5f 6d 6f 64 65 20 7b 74 65 73 74 6e 61  nal_mode {testna
e220: 6d 65 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  me {db db}} {.  
e230: 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c  if { [wal_is_wal
e240: 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24  _mode] } {.    $
e250: 64 62 20 65 76 61 6c 20 7b 20 53 45 4c 45 43 54  db eval { SELECT
e260: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
e270: 61 73 74 65 72 20 7d 0a 20 20 20 20 64 6f 5f 74  aster }.    do_t
e280: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 20 5b 6c  est $testname [l
e290: 69 73 74 20 24 64 62 20 65 76 61 6c 20 22 50 52  ist $db eval "PR
e2a0: 41 47 4d 41 20 6d 61 69 6e 2e 6a 6f 75 72 6e 61  AGMA main.journa
e2b0: 6c 5f 6d 6f 64 65 22 5d 20 7b 77 61 6c 7d 0a 20  l_mode"] {wal}. 
e2c0: 20 7d 0a 7d 0a 0a 70 72 6f 63 20 70 65 72 6d 75   }.}..proc permu
e2d0: 74 61 74 69 6f 6e 20 7b 7d 20 7b 0a 20 20 73 65  tation {} {.  se
e2e0: 74 20 70 65 72 6d 20 22 22 0a 20 20 63 61 74 63  t perm "".  catc
e2f0: 68 20 7b 73 65 74 20 70 65 72 6d 20 24 3a 3a 47  h {set perm $::G
e300: 28 70 65 72 6d 3a 6e 61 6d 65 29 7d 0a 20 20 73  (perm:name)}.  s
e310: 65 74 20 70 65 72 6d 0a 7d 0a 70 72 6f 63 20 70  et perm.}.proc p
e320: 72 65 73 71 6c 20 7b 7d 20 7b 0a 20 20 73 65 74  resql {} {.  set
e330: 20 70 72 65 73 71 6c 20 22 22 0a 20 20 63 61 74   presql "".  cat
e340: 63 68 20 7b 73 65 74 20 70 72 65 73 71 6c 20 24  ch {set presql $
e350: 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c 29  ::G(perm:presql)
e360: 7d 0a 20 20 73 65 74 20 70 72 65 73 71 6c 0a 7d  }.  set presql.}
e370: 0a 0a 70 72 6f 63 20 69 73 71 75 69 63 6b 20 7b  ..proc isquick {
e380: 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 30 0a  } {.  set ret 0.
e390: 20 20 63 61 74 63 68 20 7b 73 65 74 20 72 65 74    catch {set ret
e3a0: 20 24 3a 3a 47 28 69 73 71 75 69 63 6b 29 7d 0a   $::G(isquick)}.
e3b0: 20 20 73 65 74 20 72 65 74 0a 7d 0a 0a 23 2d 2d    set ret.}..#--
e3c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e3d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e3e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e3f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e400: 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72 6f 63 20 73  -------.#.proc s
e410: 6c 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70 74  lave_test_script
e420: 20 7b 73 63 72 69 70 74 7d 20 7b 0a 0a 20 20 23   {script} {..  #
e430: 20 43 72 65 61 74 65 20 74 68 65 20 69 6e 74 65   Create the inte
e440: 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f 20  rpreter used to 
e450: 72 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  run the test scr
e460: 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 63 72  ipt..  interp cr
e470: 65 61 74 65 20 74 69 6e 74 65 72 70 0a 0a 20 20  eate tinterp..  
e480: 23 20 50 6f 70 75 6c 61 74 65 20 73 6f 6d 65 20  # Populate some 
e490: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  global variables
e4a0: 20 74 68 61 74 20 74 65 73 74 65 72 2e 74 63 6c   that tester.tcl
e4b0: 20 65 78 70 65 63 74 73 20 74 6f 20 73 65 65 2e   expects to see.
e4c0: 0a 20 20 66 6f 72 65 61 63 68 20 7b 76 61 72 20  .  foreach {var 
e4d0: 76 61 6c 75 65 7d 20 5b 6c 69 73 74 20 20 20 20  value} [list    
e4e0: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
e4f0: 3a 3a 61 72 67 76 30 20 24 3a 3a 61 72 67 76 30  ::argv0 $::argv0
e500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e510: 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72 67       \.    ::arg
e520: 76 20 20 7b 7d 20 20 20 20 20 20 20 20 20 20 20  v  {}           
e530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e540: 5c 0a 20 20 20 20 3a 3a 53 4c 41 56 45 20 31 20  \.    ::SLAVE 1 
e550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e560: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 5d             \.  ]
e570: 20 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 65 76   {.    interp ev
e580: 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73 74  al tinterp [list
e590: 20 73 65 74 20 24 76 61 72 20 24 76 61 6c 75 65   set $var $value
e5a0: 5d 0a 20 20 7d 0a 0a 20 20 23 20 49 66 20 6f 75  ].  }..  # If ou
e5b0: 74 70 75 74 20 69 73 20 62 65 69 6e 67 20 63 6f  tput is being co
e5c0: 70 69 65 64 20 69 6e 74 6f 20 61 20 66 69 6c 65  pied into a file
e5d0: 2c 20 73 68 61 72 65 20 74 68 65 20 66 69 6c 65  , share the file
e5e0: 2d 64 65 73 63 72 69 70 74 6f 72 20 77 69 74 68  -descriptor with
e5f0: 0a 20 20 23 20 74 68 65 20 69 6e 74 65 72 70 72  .  # the interpr
e600: 65 74 65 72 2e 0a 20 20 69 66 20 7b 5b 69 6e 66  eter..  if {[inf
e610: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6f 75 74  o exists ::G(out
e620: 70 75 74 5f 66 64 29 5d 7d 20 7b 0a 20 20 20 20  put_fd)]} {.    
e630: 69 6e 74 65 72 70 20 73 68 61 72 65 20 7b 7d 20  interp share {} 
e640: 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 20  $::G(output_fd) 
e650: 74 69 6e 74 65 72 70 0a 20 20 7d 0a 0a 20 20 23  tinterp.  }..  #
e660: 20 54 68 65 20 61 6c 69 61 73 20 75 73 65 64 20   The alias used 
e670: 74 6f 20 61 63 63 65 73 73 20 74 68 65 20 67 6c  to access the gl
e680: 6f 62 61 6c 20 74 65 73 74 20 63 6f 75 6e 74 65  obal test counte
e690: 72 73 2e 0a 20 20 74 69 6e 74 65 72 70 20 61 6c  rs..  tinterp al
e6a0: 69 61 73 20 73 65 74 5f 74 65 73 74 5f 63 6f 75  ias set_test_cou
e6b0: 6e 74 65 72 20 73 65 74 5f 74 65 73 74 5f 63 6f  nter set_test_co
e6c0: 75 6e 74 65 72 0a 0a 20 20 23 20 53 65 74 20 75  unter..  # Set u
e6d0: 70 20 74 68 65 20 3a 3a 63 6d 64 6c 69 6e 65 61  p the ::cmdlinea
e6e0: 72 67 20 61 72 72 61 79 20 69 6e 20 74 68 65 20  rg array in the 
e6f0: 73 6c 61 76 65 2e 0a 20 20 69 6e 74 65 72 70 20  slave..  interp 
e700: 65 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69  eval tinterp [li
e710: 73 74 20 61 72 72 61 79 20 73 65 74 20 3a 3a 63  st array set ::c
e720: 6d 64 6c 69 6e 65 61 72 67 20 5b 61 72 72 61 79  mdlinearg [array
e730: 20 67 65 74 20 3a 3a 63 6d 64 6c 69 6e 65 61 72   get ::cmdlinear
e740: 67 5d 5d 0a 0a 20 20 23 20 53 65 74 20 75 70 20  g]]..  # Set up 
e750: 74 68 65 20 3a 3a 47 20 61 72 72 61 79 20 69 6e  the ::G array in
e760: 20 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69 6e   the slave..  in
e770: 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72  terp eval tinter
e780: 70 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73 65  p [list array se
e790: 74 20 3a 3a 47 20 5b 61 72 72 61 79 20 67 65 74  t ::G [array get
e7a0: 20 3a 3a 47 5d 5d 0a 0a 20 20 23 20 4c 6f 61 64   ::G]]..  # Load
e7b0: 20 74 68 65 20 76 61 72 69 6f 75 73 20 74 65 73   the various tes
e7c0: 74 20 69 6e 74 65 72 66 61 63 65 73 20 69 6d 70  t interfaces imp
e7d0: 6c 65 6d 65 6e 74 65 64 20 69 6e 20 43 2e 0a 20  lemented in C.. 
e7e0: 20 6c 6f 61 64 5f 74 65 73 74 66 69 78 74 75 72   load_testfixtur
e7f0: 65 5f 65 78 74 65 6e 73 69 6f 6e 73 20 74 69 6e  e_extensions tin
e800: 74 65 72 70 0a 0a 20 20 23 20 52 75 6e 20 74 68  terp..  # Run th
e810: 65 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20  e test script.. 
e820: 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e   interp eval tin
e830: 74 65 72 70 20 24 73 63 72 69 70 74 0a 0a 20 20  terp $script..  
e840: 23 20 43 68 65 63 6b 20 69 66 20 74 68 65 20 69  # Check if the i
e850: 6e 74 65 72 70 72 65 74 65 72 20 63 61 6c 6c 20  nterpreter call 
e860: 5b 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74  [run_thread_test
e870: 73 5d 0a 20 20 69 66 20 7b 20 5b 69 6e 74 65 72  s].  if { [inter
e880: 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20 7b  p eval tinterp {
e890: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72 75  info exists ::ru
e8a0: 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63  n_thread_tests_c
e8b0: 61 6c 6c 65 64 7d 5d 20 7d 20 7b 0a 20 20 20 20  alled}] } {.    
e8c0: 73 65 74 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64  set ::run_thread
e8d0: 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 20 31 0a  _tests_called 1.
e8e0: 20 20 7d 0a 0a 20 20 23 20 44 65 6c 65 74 65 20    }..  # Delete 
e8f0: 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72 20  the interpreter 
e900: 75 73 65 64 20 74 6f 20 72 75 6e 20 74 68 65 20  used to run the 
e910: 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20 69  test script..  i
e920: 6e 74 65 72 70 20 64 65 6c 65 74 65 20 74 69 6e  nterp delete tin
e930: 74 65 72 70 0a 7d 0a 0a 70 72 6f 63 20 73 6c 61  terp.}..proc sla
e940: 76 65 5f 74 65 73 74 5f 66 69 6c 65 20 7b 7a 46  ve_test_file {zF
e950: 69 6c 65 7d 20 7b 0a 20 20 73 65 74 20 74 61 69  ile} {.  set tai
e960: 6c 20 5b 66 69 6c 65 20 74 61 69 6c 20 24 7a 46  l [file tail $zF
e970: 69 6c 65 5d 0a 0a 20 20 69 66 20 7b 5b 69 6e 66  ile]..  if {[inf
e980: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73 74 61  o exists ::G(sta
e990: 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 5d  rt:permutation)]
e9a0: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 70 65 72  } {.    if {[per
e9b0: 6d 75 74 61 74 69 6f 6e 5d 20 21 3d 20 24 3a 3a  mutation] != $::
e9c0: 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74  G(start:permutat
e9d0: 69 6f 6e 29 7d 20 72 65 74 75 72 6e 0a 20 20 20  ion)} return.   
e9e0: 20 75 6e 73 65 74 20 3a 3a 47 28 73 74 61 72 74   unset ::G(start
e9f0: 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 0a 20 20  :permutation).  
ea00: 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  }.  if {[info ex
ea10: 69 73 74 73 20 3a 3a 47 28 73 74 61 72 74 3a 66  ists ::G(start:f
ea20: 69 6c 65 29 5d 7d 20 7b 0a 20 20 20 20 69 66 20  ile)]} {.    if 
ea30: 7b 24 74 61 69 6c 20 21 3d 20 24 3a 3a 47 28 73  {$tail != $::G(s
ea40: 74 61 72 74 3a 66 69 6c 65 29 20 26 26 20 24 74  tart:file) && $t
ea50: 61 69 6c 21 3d 22 24 3a 3a 47 28 73 74 61 72 74  ail!="$::G(start
ea60: 3a 66 69 6c 65 29 2e 74 65 73 74 22 7d 20 72 65  :file).test"} re
ea70: 74 75 72 6e 0a 20 20 20 20 75 6e 73 65 74 20 3a  turn.    unset :
ea80: 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 0a 20  :G(start:file). 
ea90: 20 7d 0a 0a 20 20 23 20 52 65 6d 65 6d 62 65 72   }..  # Remember
eaa0: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68   the value of th
eab0: 65 20 73 68 61 72 65 64 2d 63 61 63 68 65 20 73  e shared-cache s
eac0: 65 74 74 69 6e 67 2e 20 53 6f 20 74 68 61 74 20  etting. So that 
ead0: 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65 0a 20  it is possible. 
eae0: 20 23 20 74 6f 20 63 68 65 63 6b 20 61 66 74 65   # to check afte
eaf0: 72 77 61 72 64 73 20 74 68 61 74 20 69 74 20 77  rwards that it w
eb00: 61 73 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64 20  as not modified 
eb10: 62 79 20 74 68 65 20 74 65 73 74 20 73 63 72 69  by the test scri
eb20: 70 74 2e 0a 20 20 23 0a 20 20 69 66 63 61 70 61  pt..  #.  ifcapa
eb30: 62 6c 65 20 73 68 61 72 65 64 5f 63 61 63 68 65  ble shared_cache
eb40: 20 7b 20 73 65 74 20 73 63 73 20 5b 73 71 6c 69   { set scs [sqli
eb50: 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65  te3_enable_share
eb60: 64 5f 63 61 63 68 65 5d 20 7d 0a 0a 20 20 23 20  d_cache] }..  # 
eb70: 52 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72  Run the test scr
eb80: 69 70 74 20 69 6e 20 61 20 73 6c 61 76 65 20 69  ipt in a slave i
eb90: 6e 74 65 72 70 72 65 74 65 72 2e 0a 20 20 23 0a  nterpreter..  #.
eba0: 20 20 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c    unset -nocompl
ebb0: 61 69 6e 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64  ain ::run_thread
ebc0: 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 0a 20 20  _tests_called.  
ebd0: 72 65 73 65 74 5f 70 72 6e 67 5f 73 74 61 74 65  reset_prng_state
ebe0: 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f  .  set ::sqlite_
ebf0: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20  open_file_count 
ec00: 30 0a 20 20 73 65 74 20 74 69 6d 65 20 5b 74 69  0.  set time [ti
ec10: 6d 65 20 7b 20 73 6c 61 76 65 5f 74 65 73 74 5f  me { slave_test_
ec20: 73 63 72 69 70 74 20 5b 6c 69 73 74 20 73 6f 75  script [list sou
ec30: 72 63 65 20 24 7a 46 69 6c 65 5d 20 7d 5d 0a 20  rce $zFile] }]. 
ec40: 20 73 65 74 20 6d 73 20 5b 65 78 70 72 20 5b 6c   set ms [expr [l
ec50: 69 6e 64 65 78 20 24 74 69 6d 65 20 30 5d 20 2f  index $time 0] /
ec60: 20 31 30 30 30 5d 0a 0a 20 20 23 20 54 65 73 74   1000]..  # Test
ec70: 20 74 68 61 74 20 61 6c 6c 20 66 69 6c 65 73 20   that all files 
ec80: 6f 70 65 6e 65 64 20 62 79 20 74 68 65 20 74 65  opened by the te
ec90: 73 74 20 73 63 72 69 70 74 20 77 65 72 65 20 63  st script were c
eca0: 6c 6f 73 65 64 2e 20 4f 6d 69 74 20 74 68 69 73  losed. Omit this
ecb0: 0a 20 20 23 20 69 66 20 74 68 65 20 74 65 73 74  .  # if the test
ecc0: 20 73 63 72 69 70 74 20 68 61 73 20 22 74 68 72   script has "thr
ecd0: 65 61 64 22 20 69 6e 20 69 74 73 20 6e 61 6d 65  ead" in its name
ece0: 2e 20 54 68 65 20 6f 70 65 6e 20 66 69 6c 65 20  . The open file 
ecf0: 63 6f 75 6e 74 65 72 0a 20 20 23 20 69 73 20 6e  counter.  # is n
ed00: 6f 74 20 74 68 72 65 61 64 2d 73 61 66 65 2e 0a  ot thread-safe..
ed10: 20 20 23 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20    #.  if {[info 
ed20: 65 78 69 73 74 73 20 3a 3a 72 75 6e 5f 74 68 72  exists ::run_thr
ed30: 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64  ead_tests_called
ed40: 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 64 6f 5f 74  ]==0} {.    do_t
ed50: 65 73 74 20 24 7b 74 61 69 6c 7d 2d 63 6c 6f 73  est ${tail}-clos
ed60: 65 61 6c 6c 66 69 6c 65 73 20 7b 20 65 78 70 72  eallfiles { expr
ed70: 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e   {$::sqlite_open
ed80: 5f 66 69 6c 65 5f 63 6f 75 6e 74 3e 30 7d 20 7d  _file_count>0} }
ed90: 20 7b 30 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a   {0}.  }.  set :
eda0: 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c  :sqlite_open_fil
edb0: 65 5f 63 6f 75 6e 74 20 30 0a 0a 20 20 23 20 54  e_count 0..  # T
edc0: 65 73 74 20 74 68 61 74 20 74 68 65 20 67 6c 6f  est that the glo
edd0: 62 61 6c 20 22 73 68 61 72 65 64 2d 63 61 63 68  bal "shared-cach
ede0: 65 22 20 73 65 74 74 69 6e 67 20 77 61 73 20 6e  e" setting was n
edf0: 6f 74 20 61 6c 74 65 72 65 64 20 62 79 0a 20 20  ot altered by.  
ee00: 23 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  # the test scrip
ee10: 74 2e 0a 20 20 23 0a 20 20 69 66 63 61 70 61 62  t..  #.  ifcapab
ee20: 6c 65 20 73 68 61 72 65 64 5f 63 61 63 68 65 20  le shared_cache 
ee30: 7b 0a 20 20 20 20 73 65 74 20 72 65 73 20 5b 65  {.    set res [e
ee40: 78 70 72 20 7b 5b 73 71 6c 69 74 65 33 5f 65 6e  xpr {[sqlite3_en
ee50: 61 62 6c 65 5f 73 68 61 72 65 64 5f 63 61 63 68  able_shared_cach
ee60: 65 5d 20 3d 3d 20 24 73 63 73 7d 5d 0a 20 20 20  e] == $scs}].   
ee70: 20 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c 7d   do_test ${tail}
ee80: 2d 73 68 61 72 65 64 63 61 63 68 65 73 65 74 74  -sharedcachesett
ee90: 69 6e 67 20 5b 6c 69 73 74 20 73 65 74 20 7b 7d  ing [list set {}
eea0: 20 24 72 65 73 5d 20 31 0a 20 20 7d 0a 0a 20 20   $res] 1.  }..  
eeb0: 23 20 41 64 64 20 73 6f 6d 65 20 69 6e 66 6f 20  # Add some info 
eec0: 74 6f 20 74 68 65 20 6f 75 74 70 75 74 2e 0a 20  to the output.. 
eed0: 20 23 0a 20 20 6f 75 74 70 75 74 32 20 22 54 69   #.  output2 "Ti
eee0: 6d 65 3a 20 24 74 61 69 6c 20 24 6d 73 20 6d 73  me: $tail $ms ms
eef0: 22 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74  ".  show_memstat
ef00: 73 0a 7d 0a 0a 23 20 4f 70 65 6e 20 61 20 6e 65  s.}..# Open a ne
ef10: 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6f 6e 20  w connection on 
ef20: 64 61 74 61 62 61 73 65 20 74 65 73 74 2e 64 62  database test.db
ef30: 20 61 6e 64 20 65 78 65 63 75 74 65 20 74 68 65   and execute the
ef40: 20 53 51 4c 20 73 63 72 69 70 74 0a 23 20 73 75   SQL script.# su
ef50: 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67  pplied as an arg
ef60: 75 6d 65 6e 74 2e 20 42 65 66 6f 72 65 20 72 65  ument. Before re
ef70: 74 75 72 6e 69 6e 67 2c 20 63 6c 6f 73 65 20 74  turning, close t
ef80: 68 65 20 6e 65 77 20 63 6f 6e 65 63 74 69 6f 6e  he new conection
ef90: 20 61 6e 64 0a 23 20 72 65 73 74 6f 72 65 20 74   and.# restore t
efa0: 68 65 20 34 20 62 79 74 65 20 66 69 65 6c 64 73  he 4 byte fields
efb0: 20 73 74 61 72 74 69 6e 67 20 61 74 20 68 65 61   starting at hea
efc0: 64 65 72 20 6f 66 66 73 65 74 73 20 32 38 2c 20  der offsets 28, 
efd0: 39 32 20 61 6e 64 20 39 36 0a 23 20 74 6f 20 74  92 and 96.# to t
efe0: 68 65 20 76 61 6c 75 65 73 20 74 68 65 79 20 68  he values they h
eff0: 65 6c 64 20 62 65 66 6f 72 65 20 74 68 65 20 53  eld before the S
f000: 51 4c 20 77 61 73 20 65 78 65 63 75 74 65 64 2e  QL was executed.
f010: 20 54 68 69 73 20 73 69 6d 75 6c 61 74 65 73 0a   This simulates.
f020: 23 20 61 20 77 72 69 74 65 20 62 79 20 61 20 70  # a write by a p
f030: 72 65 2d 33 2e 37 2e 30 20 63 6c 69 65 6e 74 2e  re-3.7.0 client.
f040: 0a 23 0a 70 72 6f 63 20 73 71 6c 33 36 32 33 31  .#.proc sql36231
f050: 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 42   {sql} {.  set B
f060: 20 5b 68 65 78 69 6f 5f 72 65 61 64 20 74 65 73   [hexio_read tes
f070: 74 2e 64 62 20 39 32 20 38 5d 0a 20 20 73 65 74  t.db 92 8].  set
f080: 20 41 20 5b 68 65 78 69 6f 5f 72 65 61 64 20 74   A [hexio_read t
f090: 65 73 74 2e 64 62 20 32 38 20 34 5d 0a 20 20 73  est.db 28 4].  s
f0a0: 71 6c 69 74 65 33 20 64 62 33 36 32 33 31 20 74  qlite3 db36231 t
f0b0: 65 73 74 2e 64 62 0a 20 20 63 61 74 63 68 20 7b  est.db.  catch {
f0c0: 20 64 62 33 36 32 33 31 20 66 75 6e 63 20 61 5f   db36231 func a_
f0d0: 73 74 72 69 6e 67 20 61 5f 73 74 72 69 6e 67 20  string a_string 
f0e0: 7d 0a 20 20 65 78 65 63 73 71 6c 20 24 73 71 6c  }.  execsql $sql
f0f0: 20 64 62 33 36 32 33 31 0a 20 20 64 62 33 36 32   db36231.  db362
f100: 33 31 20 63 6c 6f 73 65 0a 20 20 68 65 78 69 6f  31 close.  hexio
f110: 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62 20 32  _write test.db 2
f120: 38 20 24 41 0a 20 20 68 65 78 69 6f 5f 77 72 69  8 $A.  hexio_wri
f130: 74 65 20 74 65 73 74 2e 64 62 20 39 32 20 24 42  te test.db 92 $B
f140: 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d 0a 0a  .  return "".}..
f150: 70 72 6f 63 20 64 62 5f 73 61 76 65 20 7b 7d 20  proc db_save {} 
f160: 7b 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  {.  foreach f [g
f170: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
f180: 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b 20 66  sv_test.db*] { f
f190: 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20 7d 0a  orcedelete $f }.
f1a0: 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f    foreach f [glo
f1b0: 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65  b -nocomplain te
f1c0: 73 74 2e 64 62 2a 5d 20 7b 0a 20 20 20 20 73 65  st.db*] {.    se
f1d0: 74 20 66 32 20 22 73 76 5f 24 66 22 0a 20 20 20  t f2 "sv_$f".   
f1e0: 20 66 6f 72 63 65 63 6f 70 79 20 24 66 20 24 66   forcecopy $f $f
f1f0: 32 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 62 5f  2.  }.}.proc db_
f200: 73 61 76 65 5f 61 6e 64 5f 63 6c 6f 73 65 20 7b  save_and_close {
f210: 7d 20 7b 0a 20 20 64 62 5f 73 61 76 65 0a 20 20  } {.  db_save.  
f220: 63 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65  catch { db close
f230: 20 7d 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d   }.  return "".}
f240: 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f 72 65  .proc db_restore
f250: 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20   {} {.  foreach 
f260: 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
f270: 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b 20  ain test.db*] { 
f280: 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20 7d  forcedelete $f }
f290: 0a 20 20 66 6f 72 65 61 63 68 20 66 32 20 5b 67  .  foreach f2 [g
f2a0: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
f2b0: 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b 0a 20  sv_test.db*] {. 
f2c0: 20 20 20 73 65 74 20 66 20 5b 73 74 72 69 6e 67     set f [string
f2d0: 20 72 61 6e 67 65 20 24 66 32 20 33 20 65 6e 64   range $f2 3 end
f2e0: 5d 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79 20  ].    forcecopy 
f2f0: 24 66 32 20 24 66 0a 20 20 7d 0a 7d 0a 70 72 6f  $f2 $f.  }.}.pro
f300: 63 20 64 62 5f 72 65 73 74 6f 72 65 5f 61 6e 64  c db_restore_and
f310: 5f 72 65 6f 70 65 6e 20 7b 7b 64 62 66 69 6c 65  _reopen {{dbfile
f320: 20 74 65 73 74 2e 64 62 7d 7d 20 7b 0a 20 20 63   test.db}} {.  c
f330: 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65 20  atch { db close 
f340: 7d 0a 20 20 64 62 5f 72 65 73 74 6f 72 65 0a 20  }.  db_restore. 
f350: 20 73 71 6c 69 74 65 33 20 64 62 20 24 64 62 66   sqlite3 db $dbf
f360: 69 6c 65 0a 7d 0a 70 72 6f 63 20 64 62 5f 64 65  ile.}.proc db_de
f370: 6c 65 74 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20  lete_and_reopen 
f380: 7b 7b 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d  {{file test.db}}
f390: 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20   {.  catch { db 
f3a0: 63 6c 6f 73 65 20 7d 0a 20 20 66 6f 72 65 61 63  close }.  foreac
f3b0: 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
f3c0: 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20  plain test.db*] 
f3d0: 7b 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66  { forcedelete $f
f3e0: 20 7d 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20   }.  sqlite3 db 
f3f0: 24 66 69 6c 65 0a 7d 0a 0a 23 20 43 6c 6f 73 65  $file.}..# Close
f400: 20 61 6e 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 73   any connections
f410: 20 6e 61 6d 65 64 20 5b 64 62 5d 2c 20 5b 64 62   named [db], [db
f420: 32 5d 20 6f 72 20 5b 64 62 33 5d 2e 20 54 68 65  2] or [db3]. The
f430: 6e 20 75 73 65 20 73 71 6c 69 74 65 33 5f 63 6f  n use sqlite3_co
f440: 6e 66 69 67 0a 23 20 74 6f 20 63 6f 6e 66 69 67  nfig.# to config
f450: 75 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ure the size of 
f460: 74 68 65 20 50 41 47 45 43 41 43 48 45 20 61 6c  the PAGECACHE al
f470: 6c 6f 63 61 74 69 6f 6e 20 75 73 69 6e 67 20 74  location using t
f480: 68 65 20 70 61 72 61 6d 65 74 65 72 73 0a 23 20  he parameters.# 
f490: 70 72 6f 76 69 64 65 64 20 74 6f 20 74 68 69 73  provided to this
f4a0: 20 63 6f 6d 6d 61 6e 64 2e 20 53 61 76 65 20 74   command. Save t
f4b0: 68 65 20 6f 6c 64 20 50 41 47 45 43 41 43 48 45  he old PAGECACHE
f4c0: 20 70 61 72 61 6d 65 74 65 72 73 20 69 6e 20 61   parameters in a
f4d0: 20 67 6c 6f 62 61 6c 20 0a 23 20 76 61 72 69 61   global .# varia
f4e0: 62 6c 65 20 73 6f 20 74 68 61 74 20 5b 74 65 73  ble so that [tes
f4f0: 74 5f 72 65 73 74 6f 72 65 5f 63 6f 6e 66 69 67  t_restore_config
f500: 5f 70 61 67 65 63 61 63 68 65 5d 20 63 61 6e 20  _pagecache] can 
f510: 72 65 73 74 6f 72 65 20 74 68 65 20 70 72 65 76  restore the prev
f520: 69 6f 75 73 0a 23 20 63 6f 6e 66 69 67 75 72 61  ious.# configura
f530: 74 69 6f 6e 2e 0a 23 0a 23 20 42 65 66 6f 72 65  tion..#.# Before
f540: 20 72 65 74 75 72 6e 69 6e 67 2c 20 72 65 6f 70   returning, reop
f550: 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64  en connection [d
f560: 62 5d 20 6f 6e 20 66 69 6c 65 20 74 65 73 74 2e  b] on file test.
f570: 64 62 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f  db..#.proc test_
f580: 73 65 74 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63  set_config_pagec
f590: 61 63 68 65 20 7b 73 7a 20 6e 50 67 7d 20 7b 0a  ache {sz nPg} {.
f5a0: 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73    catch {db clos
f5b0: 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20  e}.  catch {db2 
f5c0: 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b  close}.  catch {
f5d0: 64 62 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 73 71  db3 close}..  sq
f5e0: 6c 69 74 65 33 5f 73 68 75 74 64 6f 77 6e 0a 20  lite3_shutdown. 
f5f0: 20 73 65 74 20 3a 3a 6f 6c 64 5f 70 61 67 65 63   set ::old_pagec
f600: 61 63 68 65 5f 63 6f 6e 66 69 67 20 5b 73 71 6c  ache_config [sql
f610: 69 74 65 33 5f 63 6f 6e 66 69 67 5f 70 61 67 65  ite3_config_page
f620: 63 61 63 68 65 20 24 73 7a 20 24 6e 50 67 5d 0a  cache $sz $nPg].
f630: 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61    sqlite3_initia
f640: 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74 61  lize.  autoinsta
f650: 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e  ll_test_function
f660: 73 0a 20 20 72 65 73 65 74 5f 64 62 0a 7d 0a 0a  s.  reset_db.}..
f670: 23 20 43 6c 6f 73 65 20 61 6e 79 20 63 6f 6e 6e  # Close any conn
f680: 65 63 74 69 6f 6e 73 20 6e 61 6d 65 64 20 5b 64  ections named [d
f690: 62 5d 2c 20 5b 64 62 32 5d 20 6f 72 20 5b 64 62  b], [db2] or [db
f6a0: 33 5d 2e 20 54 68 65 6e 20 75 73 65 20 73 71 6c  3]. Then use sql
f6b0: 69 74 65 33 5f 63 6f 6e 66 69 67 0a 23 20 74 6f  ite3_config.# to
f6c0: 20 63 6f 6e 66 69 67 75 72 65 20 74 68 65 20 73   configure the s
f6d0: 69 7a 65 20 6f 66 20 74 68 65 20 50 41 47 45 43  ize of the PAGEC
f6e0: 41 43 48 45 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  ACHE allocation 
f6f0: 74 6f 20 74 68 65 20 73 69 7a 65 20 73 61 76 65  to the size save
f700: 64 20 69 6e 0a 23 20 74 68 65 20 67 6c 6f 62 61  d in.# the globa
f710: 6c 20 76 61 72 69 61 62 6c 65 20 62 79 20 61 6e  l variable by an
f720: 20 65 61 72 6c 69 65 72 20 63 61 6c 6c 20 74 6f   earlier call to
f730: 20 5b 74 65 73 74 5f 73 65 74 5f 63 6f 6e 66 69   [test_set_confi
f740: 67 5f 70 61 67 65 63 61 63 68 65 5d 2e 0a 23 0a  g_pagecache]..#.
f750: 23 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69  # Before returni
f760: 6e 67 2c 20 72 65 6f 70 65 6e 20 63 6f 6e 6e 65  ng, reopen conne
f770: 63 74 69 6f 6e 20 5b 64 62 5d 20 6f 6e 20 66 69  ction [db] on fi
f780: 6c 65 20 74 65 73 74 2e 64 62 2e 0a 23 0a 70 72  le test.db..#.pr
f790: 6f 63 20 74 65 73 74 5f 72 65 73 74 6f 72 65 5f  oc test_restore_
f7a0: 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65  config_pagecache
f7b0: 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64   {} {.  catch {d
f7c0: 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
f7d0: 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
f7e0: 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d  atch {db3 close}
f7f0: 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  ..  sqlite3_shut
f800: 64 6f 77 6e 0a 20 20 65 76 61 6c 20 73 71 6c 69  down.  eval sqli
f810: 74 65 33 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63  te3_config_pagec
f820: 61 63 68 65 20 24 3a 3a 6f 6c 64 5f 70 61 67 65  ache $::old_page
f830: 63 61 63 68 65 5f 63 6f 6e 66 69 67 0a 20 20 75  cache_config.  u
f840: 6e 73 65 74 20 3a 3a 6f 6c 64 5f 70 61 67 65 63  nset ::old_pagec
f850: 61 63 68 65 5f 63 6f 6e 66 69 67 20 0a 20 20 73  ache_config .  s
f860: 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a  qlite3_initializ
f870: 65 0a 20 20 61 75 74 6f 69 6e 73 74 61 6c 6c 5f  e.  autoinstall_
f880: 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e 73 0a 20  test_functions. 
f890: 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74   sqlite3 db test
f8a0: 2e 64 62 0a 7d 0a 0a 70 72 6f 63 20 74 65 73 74  .db.}..proc test
f8b0: 5f 66 69 6e 64 5f 62 69 6e 61 72 79 20 7b 6e 6d  _find_binary {nm
f8c0: 7d 20 7b 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c  } {.  if {$::tcl
f8d0: 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f  _platform(platfo
f8e0: 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d 20  rm)=="windows"} 
f8f0: 7b 0a 20 20 20 20 73 65 74 20 72 65 74 20 22 24  {.    set ret "$
f900: 6e 6d 2e 65 78 65 22 0a 20 20 7d 20 65 6c 73 65  nm.exe".  } else
f910: 20 7b 0a 20 20 20 20 73 65 74 20 72 65 74 20 24   {.    set ret $
f920: 6e 6d 0a 20 20 7d 0a 20 20 73 65 74 20 72 65 74  nm.  }.  set ret
f930: 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65   [file normalize
f940: 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 24 3a 3a 63   [file join $::c
f950: 6d 64 6c 69 6e 65 61 72 67 28 54 45 53 54 46 49  mdlinearg(TESTFI
f960: 58 54 55 52 45 5f 48 4f 4d 45 29 20 24 72 65 74  XTURE_HOME) $ret
f970: 5d 5d 0a 20 20 69 66 20 7b 21 5b 66 69 6c 65 20  ]].  if {![file 
f980: 65 78 65 63 75 74 61 62 6c 65 20 24 72 65 74 5d  executable $ret]
f990: 7d 20 7b 0a 20 20 20 20 66 69 6e 69 73 68 5f 74  } {.    finish_t
f9a0: 65 73 74 0a 20 20 20 20 72 65 74 75 72 6e 20 22  est.    return "
f9b0: 22 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  ".  }.  return $
f9c0: 72 65 74 0a 7d 0a 0a 23 20 46 69 6e 64 20 74 68  ret.}..# Find th
f9d0: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 27 73  e name of the 's
f9e0: 68 65 6c 6c 27 20 65 78 65 63 75 74 61 62 6c 65  hell' executable
f9f0: 20 28 65 2e 67 2e 20 22 73 71 6c 69 74 65 33 2e   (e.g. "sqlite3.
fa00: 65 78 65 22 29 20 74 6f 20 75 73 65 20 66 6f 72  exe") to use for
fa10: 0a 23 20 74 68 65 20 74 65 73 74 73 20 69 6e 20  .# the tests in 
fa20: 73 68 65 6c 6c 5b 31 2d 35 5d 2e 74 65 73 74 2e  shell[1-5].test.
fa30: 20 49 66 20 6e 6f 20 73 75 63 68 20 65 78 65 63   If no such exec
fa40: 75 74 61 62 6c 65 20 63 61 6e 20 62 65 20 66 6f  utable can be fo
fa50: 75 6e 64 2c 20 69 6e 76 6f 6b 65 0a 23 20 5b 66  und, invoke.# [f
fa60: 69 6e 69 73 68 5f 74 65 73 74 20 3b 20 72 65 74  inish_test ; ret
fa70: 75 72 6e 5d 20 69 6e 20 74 68 65 20 63 61 6c 6c  urn] in the call
fa80: 65 72 73 20 63 6f 6e 74 65 78 74 2e 0a 23 0a 70  ers context..#.p
fa90: 72 6f 63 20 74 65 73 74 5f 66 69 6e 64 5f 63 6c  roc test_find_cl
faa0: 69 20 7b 7d 20 7b 0a 20 20 73 65 74 20 70 72 6f  i {} {.  set pro
fab0: 67 20 5b 74 65 73 74 5f 66 69 6e 64 5f 62 69 6e  g [test_find_bin
fac0: 61 72 79 20 73 71 6c 69 74 65 33 5d 0a 20 20 69  ary sqlite3].  i
fad0: 66 20 7b 24 70 72 6f 67 3d 3d 22 22 7d 20 7b 20  f {$prog==""} { 
fae0: 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 72 65 74  return -code ret
faf0: 75 72 6e 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  urn }.  return $
fb00: 70 72 6f 67 0a 7d 0a 0a 23 20 46 69 6e 64 20 74  prog.}..# Find t
fb10: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 27  he name of the '
fb20: 73 71 6c 64 69 66 66 27 20 65 78 65 63 75 74 61  sqldiff' executa
fb30: 62 6c 65 20 28 65 2e 67 2e 20 22 73 71 6c 69 74  ble (e.g. "sqlit
fb40: 65 33 2e 65 78 65 22 29 20 74 6f 20 75 73 65 20  e3.exe") to use 
fb50: 66 6f 72 0a 23 20 74 68 65 20 74 65 73 74 73 20  for.# the tests 
fb60: 69 6e 20 73 71 6c 64 69 66 66 20 74 65 73 74 73  in sqldiff tests
fb70: 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 65 78 65  . If no such exe
fb80: 63 75 74 61 62 6c 65 20 63 61 6e 20 62 65 20 66  cutable can be f
fb90: 6f 75 6e 64 2c 20 69 6e 76 6f 6b 65 0a 23 20 5b  ound, invoke.# [
fba0: 66 69 6e 69 73 68 5f 74 65 73 74 20 3b 20 72 65  finish_test ; re
fbb0: 74 75 72 6e 5d 20 69 6e 20 74 68 65 20 63 61 6c  turn] in the cal
fbc0: 6c 65 72 73 20 63 6f 6e 74 65 78 74 2e 0a 23 0a  lers context..#.
fbd0: 70 72 6f 63 20 74 65 73 74 5f 66 69 6e 64 5f 73  proc test_find_s
fbe0: 71 6c 64 69 66 66 20 7b 7d 20 7b 0a 20 20 73 65  qldiff {} {.  se
fbf0: 74 20 70 72 6f 67 20 5b 74 65 73 74 5f 66 69 6e  t prog [test_fin
fc00: 64 5f 62 69 6e 61 72 79 20 73 71 6c 64 69 66 66  d_binary sqldiff
fc10: 5d 0a 20 20 69 66 20 7b 24 70 72 6f 67 3d 3d 22  ].  if {$prog=="
fc20: 22 7d 20 7b 20 72 65 74 75 72 6e 20 2d 63 6f 64  "} { return -cod
fc30: 65 20 72 65 74 75 72 6e 20 7d 0a 20 20 72 65 74  e return }.  ret
fc40: 75 72 6e 20 24 70 72 6f 67 0a 7d 0a 0a 0a 23 20  urn $prog.}...# 
fc50: 49 66 20 74 68 65 20 6c 69 62 72 61 72 79 20 69  If the library i
fc60: 73 20 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20  s compiled with 
fc70: 74 68 65 20 53 51 4c 49 54 45 5f 44 45 46 41 55  the SQLITE_DEFAU
fc80: 4c 54 5f 41 55 54 4f 56 41 43 55 55 4d 20 6d 61  LT_AUTOVACUUM ma
fc90: 63 72 6f 20 73 65 74 0a 23 20 74 6f 20 6e 6f 6e  cro set.# to non
fca0: 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 73 65 74 20  -zero, then set 
fcb0: 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  the global varia
fcc0: 62 6c 65 20 24 41 55 54 4f 56 41 43 55 55 4d 20  ble $AUTOVACUUM 
fcd0: 74 6f 20 31 2e 0a 73 65 74 20 41 55 54 4f 56 41  to 1..set AUTOVA
fce0: 43 55 55 4d 20 24 73 71 6c 69 74 65 5f 6f 70 74  CUUM $sqlite_opt
fcf0: 69 6f 6e 73 28 64 65 66 61 75 6c 74 5f 61 75 74  ions(default_aut
fd00: 6f 76 61 63 75 75 6d 29 0a 0a 23 20 4d 61 6b 65  ovacuum)..# Make
fd10: 20 73 75 72 65 20 74 68 65 20 46 54 53 20 65 6e   sure the FTS en
fd20: 68 61 6e 63 65 64 20 71 75 65 72 79 20 73 79 6e  hanced query syn
fd30: 74 61 78 20 69 73 20 64 69 73 61 62 6c 65 64 2e  tax is disabled.
fd40: 0a 73 65 74 20 73 71 6c 69 74 65 5f 66 74 73 33  .set sqlite_fts3
fd50: 5f 65 6e 61 62 6c 65 5f 70 61 72 65 6e 74 68 65  _enable_parenthe
fd60: 73 65 73 20 30 0a 0a 23 20 44 75 72 69 6e 67 20  ses 0..# During 
fd70: 74 65 73 74 69 6e 67 2c 20 61 73 73 75 6d 65 20  testing, assume 
fd80: 74 68 61 74 20 61 6c 6c 20 64 61 74 61 62 61 73  that all databas
fd90: 65 20 66 69 6c 65 73 20 61 72 65 20 77 65 6c 6c  e files are well
fda0: 2d 66 6f 72 6d 65 64 2e 20 20 54 68 65 0a 23 20  -formed.  The.# 
fdb0: 66 65 77 20 74 65 73 74 20 63 61 73 65 73 20 74  few test cases t
fdc0: 68 61 74 20 64 65 6c 69 62 65 72 61 74 65 6c 79  hat deliberately
fdd0: 20 63 6f 72 72 75 70 74 20 64 61 74 61 62 61 73   corrupt databas
fde0: 65 20 66 69 6c 65 73 20 73 68 6f 75 6c 64 20 72  e files should r
fdf0: 65 73 63 69 6e 64 20 0a 23 20 74 68 69 73 20 73  escind .# this s
fe00: 65 74 74 69 6e 67 20 62 79 20 69 6e 76 6f 6b 69  etting by invoki
fe10: 6e 67 20 22 64 61 74 61 62 61 73 65 5f 63 61 6e  ng "database_can
fe20: 5f 62 65 5f 63 6f 72 72 75 70 74 22 0a 23 0a 64  _be_corrupt".#.d
fe30: 61 74 61 62 61 73 65 5f 6e 65 76 65 72 5f 63 6f  atabase_never_co
fe40: 72 72 75 70 74 0a 0a 73 6f 75 72 63 65 20 24 74  rrupt..source $t
fe50: 65 73 74 64 69 72 2f 74 68 72 65 61 64 5f 63 6f  estdir/thread_co
fe60: 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f 75 72 63 65 20  mmon.tcl.source 
fe70: 24 74 65 73 74 64 69 72 2f 6d 61 6c 6c 6f 63 5f  $testdir/malloc_
fe80: 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a                 common.tcl.