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

Artifact 7b740ee852c55e1e72b6ebe5044acee7aa4e5553:


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 6e 6f 72 6d 61 6c 69 7a 65 5f 6c 69  roc normalize_li
6540: 73 74 20 7b 4c 7d 20 7b 0a 20 20 73 65 74 20 4c  st {L} {.  set L
6550: 32 20 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61  2 [list].  forea
6560: 63 68 20 6c 20 24 4c 20 7b 6c 61 70 70 65 6e 64  ch l $L {lappend
6570: 20 4c 32 20 24 6c 7d 0a 20 20 73 65 74 20 4c 32   L2 $l}.  set L2
6580: 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 65 78 65 63  .}..proc do_exec
6590: 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e 61  sql_test {testna
65a0: 6d 65 20 73 71 6c 20 7b 72 65 73 75 6c 74 20 7b  me sql {result {
65b0: 7d 7d 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73 74  }}} {.  fix_test
65c0: 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20  name testname.  
65d0: 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20  uplevel do_test 
65e0: 5b 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d  [list $testname]
65f0: 20 5b 6c 69 73 74 20 22 65 78 65 63 73 71 6c 20   [list "execsql 
6600: 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69 73 74 20 5b  {$sql}"] [list [
6610: 6c 69 73 74 20 7b 2a 7d 24 72 65 73 75 6c 74 5d  list {*}$result]
6620: 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 63 61 74 63  ].}.proc do_catc
6630: 68 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e  hsql_test {testn
6640: 61 6d 65 20 73 71 6c 20 72 65 73 75 6c 74 7d 20  ame sql result} 
6650: 7b 0a 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65  {.  fix_testname
6660: 20 74 65 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65   testname.  uple
6670: 76 65 6c 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73  vel do_test [lis
6680: 74 20 24 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69  t $testname] [li
6690: 73 74 20 22 63 61 74 63 68 73 71 6c 20 7b 24 73  st "catchsql {$s
66a0: 71 6c 7d 22 5d 20 5b 6c 69 73 74 20 24 72 65 73  ql}"] [list $res
66b0: 75 6c 74 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 74  ult].}.proc do_t
66c0: 69 6d 65 64 5f 65 78 65 63 73 71 6c 5f 74 65 73  imed_execsql_tes
66d0: 74 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 20  t {testname sql 
66e0: 7b 72 65 73 75 6c 74 20 7b 7d 7d 7d 20 7b 0a 20  {result {}}} {. 
66f0: 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 74 65   fix_testname te
6700: 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76 65 6c  stname.  uplevel
6710: 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74 20 24   do_test [list $
6720: 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73 74 20  testname] [list 
6730: 22 65 78 65 63 73 71 6c 5f 74 69 6d 65 64 20 7b  "execsql_timed {
6740: 24 73 71 6c 7d 22 5d 5c 0a 20 20 20 20 20 20 20  $sql}"]\.       
6750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6760: 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 73              [lis
6770: 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 75  t [list {*}$resu
6780: 6c 74 5d 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 65  lt]].}.proc do_e
6790: 71 70 5f 74 65 73 74 20 7b 6e 61 6d 65 20 73 71  qp_test {name sq
67a0: 6c 20 72 65 73 7d 20 7b 0a 20 20 75 70 6c 65 76  l res} {.  uplev
67b0: 65 6c 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65  el do_execsql_te
67c0: 73 74 20 24 6e 61 6d 65 20 5b 6c 69 73 74 20 22  st $name [list "
67d0: 45 58 50 4c 41 49 4e 20 51 55 45 52 59 20 50 4c  EXPLAIN QUERY PL
67e0: 41 4e 20 24 73 71 6c 22 5d 20 5b 6c 69 73 74 20  AN $sql"] [list 
67f0: 24 72 65 73 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d  $res].}..#------
6800: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6810: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6820: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6830: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6840: 2d 2d 2d 0a 23 20 20 20 55 73 61 67 65 3a 20 64  ---.#   Usage: d
6850: 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74 73 20 50  o_select_tests P
6860: 52 45 46 49 58 20 3f 53 57 49 54 43 48 45 53 3f  REFIX ?SWITCHES?
6870: 20 54 45 53 54 4c 49 53 54 0a 23 0a 23 20 57 68   TESTLIST.#.# Wh
6880: 65 72 65 20 73 77 69 74 63 68 65 73 20 61 72 65  ere switches are
6890: 3a 0a 23 0a 23 20 20 20 2d 65 72 72 6f 72 66 6f  :.#.#   -errorfo
68a0: 72 6d 61 74 20 46 4d 54 53 54 52 49 4e 47 0a 23  rmat FMTSTRING.#
68b0: 20 20 20 2d 63 6f 75 6e 74 0a 23 20 20 20 2d 71     -count.#   -q
68c0: 75 65 72 79 20 53 51 4c 0a 23 20 20 20 2d 74 63  uery SQL.#   -tc
68d0: 6c 71 75 65 72 79 20 54 43 4c 0a 23 20 20 20 2d  lquery TCL.#   -
68e0: 72 65 70 61 69 72 20 54 43 4c 0a 23 0a 70 72 6f  repair TCL.#.pro
68f0: 63 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74  c do_select_test
6900: 73 20 7b 70 72 65 66 69 78 20 61 72 67 73 7d 20  s {prefix args} 
6910: 7b 0a 0a 20 20 73 65 74 20 74 65 73 74 6c 69 73  {..  set testlis
6920: 74 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20  t [lindex $args 
6930: 65 6e 64 5d 0a 20 20 73 65 74 20 73 77 69 74 63  end].  set switc
6940: 68 65 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67  hes [lrange $arg
6950: 73 20 30 20 65 6e 64 2d 31 5d 0a 0a 20 20 73 65  s 0 end-1]..  se
6960: 74 20 65 72 72 66 6d 74 20 22 22 0a 20 20 73 65  t errfmt "".  se
6970: 74 20 63 6f 75 6e 74 6f 6e 6c 79 20 30 0a 20 20  t countonly 0.  
6980: 73 65 74 20 74 63 6c 71 75 65 72 79 20 22 22 0a  set tclquery "".
6990: 20 20 73 65 74 20 72 65 70 61 69 72 20 22 22 0a    set repair "".
69a0: 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d  .  for {set i 0}
69b0: 20 7b 24 69 20 3c 20 5b 6c 6c 65 6e 67 74 68 20   {$i < [llength 
69c0: 24 73 77 69 74 63 68 65 73 5d 7d 20 7b 69 6e 63  $switches]} {inc
69d0: 72 20 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 73  r i} {.    set s
69e0: 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68   [lindex $switch
69f0: 65 73 20 24 69 5d 0a 20 20 20 20 73 65 74 20 6e  es $i].    set n
6a00: 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20   [string length 
6a10: 24 73 5d 0a 20 20 20 20 69 66 20 7b 24 6e 3e 3d  $s].    if {$n>=
6a20: 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75  2 && [string equ
6a30: 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73  al -length $n $s
6a40: 20 22 2d 71 75 65 72 79 22 5d 7d 20 7b 0a 20 20   "-query"]} {.  
6a50: 20 20 20 20 73 65 74 20 74 63 6c 71 75 65 72 79      set tclquery
6a60: 20 5b 6c 69 73 74 20 65 78 65 63 73 71 6c 20 5b   [list execsql [
6a70: 6c 69 6e 64 65 78 20 24 73 77 69 74 63 68 65 73  lindex $switches
6a80: 20 5b 69 6e 63 72 20 69 5d 5d 5d 0a 20 20 20 20   [incr i]]].    
6a90: 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20  } elseif {$n>=2 
6aa0: 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c  && [string equal
6ab0: 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22   -length $n $s "
6ac0: 2d 74 63 6c 71 75 65 72 79 22 5d 7d 20 7b 0a 20  -tclquery"]} {. 
6ad0: 20 20 20 20 20 73 65 74 20 74 63 6c 71 75 65 72       set tclquer
6ae0: 79 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63  y [lindex $switc
6af0: 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20 20  hes [incr i]].  
6b00: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e 3d    } elseif {$n>=
6b10: 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71 75  2 && [string equ
6b20: 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24 73  al -length $n $s
6b30: 20 22 2d 65 72 72 6f 72 66 6f 72 6d 61 74 22 5d   "-errorformat"]
6b40: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 65 72  } {.      set er
6b50: 72 66 6d 74 20 5b 6c 69 6e 64 65 78 20 24 73 77  rfmt [lindex $sw
6b60: 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d  itches [incr i]]
6b70: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
6b80: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
6b90: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
6ba0: 20 24 73 20 22 2d 72 65 70 61 69 72 22 5d 7d 20   $s "-repair"]} 
6bb0: 7b 0a 20 20 20 20 20 20 73 65 74 20 72 65 70 61  {.      set repa
6bc0: 69 72 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74  ir [lindex $swit
6bd0: 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 0a 20  ches [incr i]]. 
6be0: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e     } elseif {$n>
6bf0: 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71  =2 && [string eq
6c00: 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24  ual -length $n $
6c10: 73 20 22 2d 63 6f 75 6e 74 22 5d 7d 20 7b 0a 20  s "-count"]} {. 
6c20: 20 20 20 20 20 73 65 74 20 63 6f 75 6e 74 6f 6e       set counton
6c30: 6c 79 20 31 0a 20 20 20 20 7d 20 65 6c 73 65 20  ly 1.    } else 
6c40: 7b 0a 20 20 20 20 20 20 65 72 72 6f 72 20 22 75  {.      error "u
6c50: 6e 6b 6e 6f 77 6e 20 73 77 69 74 63 68 3a 20 24  nknown switch: $
6c60: 73 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  s".    }.  }..  
6c70: 69 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c 79 20 26  if {$countonly &
6c80: 26 20 24 65 72 72 66 6d 74 21 3d 22 22 7d 20 7b  & $errfmt!=""} {
6c90: 0a 20 20 20 20 65 72 72 6f 72 20 22 43 61 6e 6e  .    error "Cann
6ca0: 6f 74 20 75 73 65 20 2d 63 6f 75 6e 74 20 61 6e  ot use -count an
6cb0: 64 20 2d 65 72 72 6f 72 66 6f 72 6d 61 74 20 74  d -errorformat t
6cc0: 6f 67 65 74 68 65 72 22 0a 20 20 7d 0a 20 20 73  ogether".  }.  s
6cd0: 65 74 20 6e 54 65 73 74 6c 69 73 74 20 5b 6c 6c  et nTestlist [ll
6ce0: 65 6e 67 74 68 20 24 74 65 73 74 6c 69 73 74 5d  ength $testlist]
6cf0: 0a 20 20 69 66 20 7b 24 6e 54 65 73 74 6c 69 73  .  if {$nTestlis
6d00: 74 25 33 20 7c 7c 20 24 6e 54 65 73 74 6c 69 73  t%3 || $nTestlis
6d10: 74 3d 3d 30 20 7d 20 7b 0a 20 20 20 20 65 72 72  t==0 } {.    err
6d20: 6f 72 20 22 53 45 4c 45 43 54 20 74 65 73 74 20  or "SELECT test 
6d30: 6c 69 73 74 20 63 6f 6e 74 61 69 6e 73 20 5b 6c  list contains [l
6d40: 6c 65 6e 67 74 68 20 24 74 65 73 74 6c 69 73 74  length $testlist
6d50: 5d 20 65 6c 65 6d 65 6e 74 73 22 0a 20 20 7d 0a  ] elements".  }.
6d60: 0a 20 20 65 76 61 6c 20 24 72 65 70 61 69 72 0a  .  eval $repair.
6d70: 20 20 66 6f 72 65 61 63 68 20 7b 74 6e 20 73 71    foreach {tn sq
6d80: 6c 20 72 65 73 7d 20 24 74 65 73 74 6c 69 73 74  l res} $testlist
6d90: 20 7b 0a 20 20 20 20 69 66 20 7b 24 74 63 6c 71   {.    if {$tclq
6da0: 75 65 72 79 20 21 3d 20 22 22 7d 20 7b 0a 20 20  uery != ""} {.  
6db0: 20 20 20 20 65 78 65 63 73 71 6c 20 24 73 71 6c      execsql $sql
6dc0: 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64  .      uplevel d
6dd0: 6f 5f 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d  o_test ${prefix}
6de0: 2e 24 74 6e 20 5b 6c 69 73 74 20 24 74 63 6c 71  .$tn [list $tclq
6df0: 75 65 72 79 5d 20 5b 6c 69 73 74 20 5b 6c 69 73  uery] [list [lis
6e00: 74 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20 20 20 20  t {*}$res]].    
6e10: 7d 20 65 6c 73 65 69 66 20 7b 24 63 6f 75 6e 74  } elseif {$count
6e20: 6f 6e 6c 79 7d 20 7b 0a 20 20 20 20 20 20 73 65  only} {.      se
6e30: 74 20 6e 52 6f 77 20 30 0a 20 20 20 20 20 20 64  t nRow 0.      d
6e40: 62 20 65 76 61 6c 20 24 73 71 6c 20 7b 69 6e 63  b eval $sql {inc
6e50: 72 20 6e 52 6f 77 7d 0a 20 20 20 20 20 20 75 70  r nRow}.      up
6e60: 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 7b  level do_test ${
6e70: 70 72 65 66 69 78 7d 2e 24 74 6e 20 5b 6c 69 73  prefix}.$tn [lis
6e80: 74 20 5b 6c 69 73 74 20 73 65 74 20 7b 7d 20 24  t [list set {} $
6e90: 6e 52 6f 77 5d 5d 20 5b 6c 69 73 74 20 24 72 65  nRow]] [list $re
6ea0: 73 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20  s].    } elseif 
6eb0: 7b 24 65 72 72 66 6d 74 3d 3d 22 22 7d 20 7b 0a  {$errfmt==""} {.
6ec0: 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f        uplevel do
6ed0: 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 24 7b  _execsql_test ${
6ee0: 70 72 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b 6c  prefix}.${tn} [l
6ef0: 69 73 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74 20  ist $sql] [list 
6f00: 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d 0a  [list {*}$res]].
6f10: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
6f20: 20 20 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74     set res [list
6f30: 20 31 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20   1 [string trim 
6f40: 5b 66 6f 72 6d 61 74 20 24 65 72 72 66 6d 74 20  [format $errfmt 
6f50: 7b 2a 7d 24 72 65 73 5d 5d 5d 0a 20 20 20 20 20  {*}$res]]].     
6f60: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 63 61 74 63   uplevel do_catc
6f70: 68 73 71 6c 5f 74 65 73 74 20 24 7b 70 72 65 66  hsql_test ${pref
6f80: 69 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69 73 74 20  ix}.${tn} [list 
6f90: 24 73 71 6c 5d 20 5b 6c 69 73 74 20 24 72 65 73  $sql] [list $res
6fa0: 5d 0a 20 20 20 20 7d 0a 20 20 20 20 65 76 61 6c  ].    }.    eval
6fb0: 20 24 72 65 70 61 69 72 0a 20 20 7d 0a 0a 7d 0a   $repair.  }..}.
6fc0: 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f 61 6c 6c  .proc delete_all
6fd0: 5f 64 61 74 61 20 7b 7d 20 7b 0a 20 20 64 62 20  _data {} {.  db 
6fe0: 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 74 62 6c  eval {SELECT tbl
6ff0: 5f 6e 61 6d 65 20 41 53 20 74 20 46 52 4f 4d 20  _name AS t FROM 
7000: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
7010: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
7020: 65 27 7d 20 7b 0a 20 20 20 20 64 62 20 65 76 61  e'} {.    db eva
7030: 6c 20 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 27  l "DELETE FROM '
7040: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27  [string map {' '
7050: 27 7d 20 24 74 5d 27 22 0a 20 20 7d 0a 7d 0a 0a  '} $t]'".  }.}..
7060: 23 20 52 75 6e 20 61 6e 20 53 51 4c 20 73 63 72  # Run an SQL scr
7070: 69 70 74 2e 0a 23 20 52 65 74 75 72 6e 20 74 68  ipt..# Return th
7080: 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69 63 72  e number of micr
7090: 6f 73 65 63 6f 6e 64 73 20 70 65 72 20 73 74 61  oseconds per sta
70a0: 74 65 6d 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73  tement..#.proc s
70b0: 70 65 65 64 5f 74 72 69 61 6c 20 7b 6e 61 6d 65  peed_trial {name
70c0: 20 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73   numstmt units s
70d0: 71 6c 7d 20 7b 0a 20 20 6f 75 74 70 75 74 32 20  ql} {.  output2 
70e0: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f 72 6d  -nonewline [form
70f0: 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d 20 24  at {%-21.21s } $
7100: 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68  name...].  flush
7110: 20 73 74 64 6f 75 74 0a 20 20 73 65 74 20 73 70   stdout.  set sp
7120: 65 65 64 20 5b 74 69 6d 65 20 7b 73 71 6c 69 74  eed [time {sqlit
7130: 65 33 5f 65 78 65 63 5f 6e 72 20 64 62 20 24 73  e3_exec_nr db $s
7140: 71 6c 7d 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c  ql}].  set tm [l
7150: 69 6e 64 65 78 20 24 73 70 65 65 64 20 30 5d 0a  index $speed 0].
7160: 20 20 69 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20    if {$tm == 0} 
7170: 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b  {.    set rate [
7180: 66 6f 72 6d 61 74 20 25 32 30 73 20 22 6d 61 6e  format %20s "man
7190: 79 22 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  y"].  } else {. 
71a0: 20 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72     set rate [for
71b0: 6d 61 74 20 25 32 30 2e 35 66 20 5b 65 78 70 72  mat %20.5f [expr
71c0: 20 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d   {1000000.0*$num
71d0: 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a  stmt/$tm}]].  }.
71e0: 20 20 73 65 74 20 75 32 20 24 75 6e 69 74 73 2f    set u2 $units/
71f0: 73 0a 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72  s.  output2 [for
7200: 6d 61 74 20 7b 25 31 32 64 20 75 53 20 25 73 20  mat {%12d uS %s 
7210: 25 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24 75  %s} $tm $rate $u
7220: 32 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61  2].  global tota
7230: 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74  l_time.  set tot
7240: 61 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b 24  al_time [expr {$
7250: 74 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d  total_time+$tm}]
7260: 0a 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73 70 65  .  lappend ::spe
7270: 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 24  ed_trial_times $
7280: 6e 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f 63 20  name $tm.}.proc 
7290: 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 63 6c 20  speed_trial_tcl 
72a0: 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e  {name numstmt un
72b0: 69 74 73 20 73 63 72 69 70 74 7d 20 7b 0a 20 20  its script} {.  
72c0: 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69  output2 -nonewli
72d0: 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31  ne [format {%-21
72e0: 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d  .21s } $name...]
72f0: 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a  .  flush stdout.
7300: 20 20 73 65 74 20 73 70 65 65 64 20 5b 74 69 6d    set speed [tim
7310: 65 20 7b 65 76 61 6c 20 24 73 63 72 69 70 74 7d  e {eval $script}
7320: 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64  ].  set tm [lind
7330: 65 78 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69  ex $speed 0].  i
7340: 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20  f {$tm == 0} {. 
7350: 20 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72     set rate [for
7360: 6d 61 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d  mat %20s "many"]
7370: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
7380: 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74  set rate [format
7390: 20 25 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31   %20.5f [expr {1
73a0: 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d  000000.0*$numstm
73b0: 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73  t/$tm}]].  }.  s
73c0: 65 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20  et u2 $units/s. 
73d0: 20 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74   output2 [format
73e0: 20 7b 25 31 32 64 20 75 53 20 25 73 20 25 73 7d   {%12d uS %s %s}
73f0: 20 24 74 6d 20 24 72 61 74 65 20 24 75 32 5d 0a   $tm $rate $u2].
7400: 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74    global total_t
7410: 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f  ime.  set total_
7420: 74 69 6d 65 20 5b 65 78 70 72 20 7b 24 74 6f 74  time [expr {$tot
7430: 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a 20 20  al_time+$tm}].  
7440: 6c 61 70 70 65 6e 64 20 3a 3a 73 70 65 65 64 5f  lappend ::speed_
7450: 74 72 69 61 6c 5f 74 69 6d 65 73 20 24 6e 61 6d  trial_times $nam
7460: 65 20 24 74 6d 0a 7d 0a 70 72 6f 63 20 73 70 65  e $tm.}.proc spe
7470: 65 64 5f 74 72 69 61 6c 5f 69 6e 69 74 20 7b 6e  ed_trial_init {n
7480: 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20  ame} {.  global 
7490: 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74  total_time.  set
74a0: 20 74 6f 74 61 6c 5f 74 69 6d 65 20 30 0a 20 20   total_time 0.  
74b0: 73 65 74 20 3a 3a 73 70 65 65 64 5f 74 72 69 61  set ::speed_tria
74c0: 6c 5f 74 69 6d 65 73 20 5b 6c 69 73 74 5d 0a 20  l_times [list]. 
74d0: 20 73 71 6c 69 74 65 33 20 76 65 72 73 64 62 20   sqlite3 versdb 
74e0: 3a 6d 65 6d 6f 72 79 3a 0a 20 20 73 65 74 20 76  :memory:.  set v
74f0: 65 72 73 20 5b 76 65 72 73 64 62 20 6f 6e 65 20  ers [versdb one 
7500: 7b 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f 73  {SELECT sqlite_s
7510: 6f 75 72 63 65 5f 69 64 28 29 7d 5d 0a 20 20 76  ource_id()}].  v
7520: 65 72 73 64 62 20 63 6c 6f 73 65 0a 20 20 6f 75  ersdb close.  ou
7530: 74 70 75 74 32 20 22 53 51 4c 69 74 65 20 24 76  tput2 "SQLite $v
7540: 65 72 73 22 0a 7d 0a 70 72 6f 63 20 73 70 65 65  ers".}.proc spee
7550: 64 5f 74 72 69 61 6c 5f 73 75 6d 6d 61 72 79 20  d_trial_summary 
7560: 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61  {name} {.  globa
7570: 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 6f  l total_time.  o
7580: 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b  utput2 [format {
7590: 25 2d 32 31 2e 32 31 73 20 25 31 32 64 20 75 53  %-21.21s %12d uS
75a0: 20 54 4f 54 41 4c 7d 20 24 6e 61 6d 65 20 24 74   TOTAL} $name $t
75b0: 6f 74 61 6c 5f 74 69 6d 65 5d 0a 0a 20 20 69 66  otal_time]..  if
75c0: 20 7b 20 30 20 7d 20 7b 0a 20 20 20 20 73 71 6c   { 0 } {.    sql
75d0: 69 74 65 33 20 76 65 72 73 64 62 20 3a 6d 65 6d  ite3 versdb :mem
75e0: 6f 72 79 3a 0a 20 20 20 20 73 65 74 20 76 65 72  ory:.    set ver
75f0: 73 20 5b 6c 69 6e 64 65 78 20 5b 76 65 72 73 64  s [lindex [versd
7600: 62 20 6f 6e 65 20 7b 53 45 4c 45 43 54 20 73 71  b one {SELECT sq
7610: 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69 64 28 29  lite_source_id()
7620: 7d 5d 20 30 5d 0a 20 20 20 20 76 65 72 73 64 62  }] 0].    versdb
7630: 20 63 6c 6f 73 65 0a 20 20 20 20 6f 75 74 70 75   close.    outpu
7640: 74 32 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  t2 "CREATE TABLE
7650: 20 49 46 20 4e 4f 54 20 45 58 49 53 54 53 20 74   IF NOT EXISTS t
7660: 69 6d 65 28 76 65 72 73 69 6f 6e 2c 20 73 63 72  ime(version, scr
7670: 69 70 74 2c 20 74 65 73 74 2c 20 75 73 29 3b 22  ipt, test, us);"
7680: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 65  .    foreach {te
7690: 73 74 20 75 73 7d 20 24 3a 3a 73 70 65 65 64 5f  st us} $::speed_
76a0: 74 72 69 61 6c 5f 74 69 6d 65 73 20 7b 0a 20 20  trial_times {.  
76b0: 20 20 20 20 6f 75 74 70 75 74 32 20 22 49 4e 53      output2 "INS
76c0: 45 52 54 20 49 4e 54 4f 20 74 69 6d 65 20 56 41  ERT INTO time VA
76d0: 4c 55 45 53 28 27 24 76 65 72 73 27 2c 20 27 24  LUES('$vers', '$
76e0: 6e 61 6d 65 27 2c 20 27 24 74 65 73 74 27 2c 20  name', '$test', 
76f0: 24 75 73 29 3b 22 0a 20 20 20 20 7d 0a 20 20 7d  $us);".    }.  }
7700: 0a 7d 0a 0a 23 20 52 75 6e 20 74 68 69 73 20 72  .}..# Run this r
7710: 6f 75 74 69 6e 65 20 6c 61 73 74 0a 23 0a 70 72  outine last.#.pr
7720: 6f 63 20 66 69 6e 69 73 68 5f 74 65 73 74 20 7b  oc finish_test {
7730: 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64 62 20  } {.  catch {db 
7740: 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b  close}.  catch {
7750: 64 62 31 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74  db1 close}.  cat
7760: 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20  ch {db2 close}. 
7770: 20 63 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73   catch {db3 clos
7780: 65 7d 0a 20 20 69 66 20 7b 30 3d 3d 5b 69 6e 66  e}.  if {0==[inf
7790: 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c 41 56 45  o exists ::SLAVE
77a0: 5d 7d 20 7b 20 66 69 6e 61 6c 69 7a 65 5f 74 65  ]} { finalize_te
77b0: 73 74 69 6e 67 20 7d 0a 7d 0a 70 72 6f 63 20 66  sting }.}.proc f
77c0: 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 20  inalize_testing 
77d0: 7b 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 73 71  {} {.  global sq
77e0: 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63  lite_open_file_c
77f0: 6f 75 6e 74 0a 0a 20 20 73 65 74 20 6f 6d 69 74  ount..  set omit
7800: 4c 69 73 74 20 5b 73 65 74 5f 74 65 73 74 5f 63  List [set_test_c
7810: 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74  ounter omit_list
7820: 5d 0a 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63  ]..  catch {db c
7830: 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64  lose}.  catch {d
7840: 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  b2 close}.  catc
7850: 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 0a 20  h {db3 close}.. 
7860: 20 76 66 73 5f 75 6e 6c 69 6e 6b 5f 74 65 73 74   vfs_unlink_test
7870: 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20 7b 7d  .  sqlite3 db {}
7880: 0a 20 20 23 20 73 71 6c 69 74 65 33 5f 63 6c 65  .  # sqlite3_cle
7890: 61 72 5f 74 73 64 5f 6d 65 6d 64 65 62 75 67 0a  ar_tsd_memdebug.
78a0: 20 20 64 62 20 63 6c 6f 73 65 0a 20 20 73 71 6c    db close.  sql
78b0: 69 74 65 33 5f 72 65 73 65 74 5f 61 75 74 6f 5f  ite3_reset_auto_
78c0: 65 78 74 65 6e 73 69 6f 6e 0a 0a 20 20 73 71 6c  extension..  sql
78d0: 69 74 65 33 5f 73 6f 66 74 5f 68 65 61 70 5f 6c  ite3_soft_heap_l
78e0: 69 6d 69 74 20 30 0a 20 20 73 65 74 20 6e 54 65  imit 0.  set nTe
78f0: 73 74 20 5b 69 6e 63 72 5f 6e 74 65 73 74 5d 0a  st [incr_ntest].
7900: 20 20 73 65 74 20 6e 45 72 72 20 5b 73 65 74 5f    set nErr [set_
7910: 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 65 72 72  test_counter err
7920: 6f 72 73 5d 0a 0a 20 20 73 65 74 20 6e 4b 6e 6f  ors]..  set nKno
7930: 77 6e 20 30 0a 20 20 69 66 20 7b 5b 66 69 6c 65  wn 0.  if {[file
7940: 20 72 65 61 64 61 62 6c 65 20 6b 6e 6f 77 6e 2d   readable known-
7950: 70 72 6f 62 6c 65 6d 73 2e 74 78 74 5d 7d 20 7b  problems.txt]} {
7960: 0a 20 20 20 20 73 65 74 20 66 64 20 5b 6f 70 65  .    set fd [ope
7970: 6e 20 6b 6e 6f 77 6e 2d 70 72 6f 62 6c 65 6d 73  n known-problems
7980: 2e 74 78 74 5d 0a 20 20 20 20 73 65 74 20 63 6f  .txt].    set co
7990: 6e 74 65 6e 74 20 5b 72 65 61 64 20 24 66 64 5d  ntent [read $fd]
79a0: 0a 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a 20  .    close $fd. 
79b0: 20 20 20 66 6f 72 65 61 63 68 20 78 20 24 63 6f     foreach x $co
79c0: 6e 74 65 6e 74 20 7b 73 65 74 20 6b 6e 6f 77 6e  ntent {set known
79d0: 5f 65 72 72 6f 72 28 24 78 29 20 31 7d 0a 20 20  _error($x) 1}.  
79e0: 20 20 66 6f 72 65 61 63 68 20 78 20 5b 73 65 74    foreach x [set
79f0: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66 61  _test_counter fa
7a00: 69 6c 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20 20  il_list] {.     
7a10: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
7a20: 73 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28 24 78  s known_error($x
7a30: 29 5d 7d 20 7b 69 6e 63 72 20 6e 4b 6e 6f 77 6e  )]} {incr nKnown
7a40: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  }.    }.  }.  if
7a50: 20 7b 24 6e 4b 6e 6f 77 6e 3e 30 7d 20 7b 0a 20   {$nKnown>0} {. 
7a60: 20 20 20 6f 75 74 70 75 74 32 20 22 5b 65 78 70     output2 "[exp
7a70: 72 20 7b 24 6e 45 72 72 2d 24 6e 4b 6e 6f 77 6e  r {$nErr-$nKnown
7a80: 7d 5d 20 6e 65 77 20 65 72 72 6f 72 73 20 61 6e  }] new errors an
7a90: 64 20 24 6e 4b 6e 6f 77 6e 20 6b 6e 6f 77 6e 20  d $nKnown known 
7aa0: 65 72 72 6f 72 73 5c 0a 20 20 20 20 20 20 20 20  errors\.        
7ab0: 20 6f 75 74 20 6f 66 20 24 6e 54 65 73 74 20 74   out of $nTest t
7ac0: 65 73 74 73 22 0a 20 20 7d 20 65 6c 73 65 20 7b  ests".  } else {
7ad0: 0a 20 20 20 20 73 65 74 20 63 70 75 69 6e 66 6f  .    set cpuinfo
7ae0: 20 7b 7d 0a 20 20 20 20 69 66 20 7b 5b 63 61 74   {}.    if {[cat
7af0: 63 68 20 7b 65 78 65 63 20 68 6f 73 74 6e 61 6d  ch {exec hostnam
7b00: 65 7d 20 68 6e 61 6d 65 5d 3d 3d 30 7d 20 7b 73  e} hname]==0} {s
7b10: 65 74 20 63 70 75 69 6e 66 6f 20 5b 73 74 72 69  et cpuinfo [stri
7b20: 6e 67 20 74 72 69 6d 20 24 68 6e 61 6d 65 5d 7d  ng trim $hname]}
7b30: 0a 20 20 20 20 61 70 70 65 6e 64 20 63 70 75 69  .    append cpui
7b40: 6e 66 6f 20 22 20 24 3a 3a 74 63 6c 5f 70 6c 61  nfo " $::tcl_pla
7b50: 74 66 6f 72 6d 28 6f 73 29 22 0a 20 20 20 20 61  tform(os)".    a
7b60: 70 70 65 6e 64 20 63 70 75 69 6e 66 6f 20 22 20  ppend cpuinfo " 
7b70: 5b 65 78 70 72 20 7b 24 3a 3a 74 63 6c 5f 70 6c  [expr {$::tcl_pl
7b80: 61 74 66 6f 72 6d 28 70 6f 69 6e 74 65 72 53 69  atform(pointerSi
7b90: 7a 65 29 2a 38 7d 5d 2d 62 69 74 22 0a 20 20 20  ze)*8}]-bit".   
7ba0: 20 61 70 70 65 6e 64 20 63 70 75 69 6e 66 6f 20   append cpuinfo 
7bb0: 22 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 45  " [string map {E
7bc0: 20 2d 65 7d 20 24 3a 3a 74 63 6c 5f 70 6c 61 74   -e} $::tcl_plat
7bd0: 66 6f 72 6d 28 62 79 74 65 4f 72 64 65 72 29 5d  form(byteOrder)]
7be0: 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 53  ".    output2 "S
7bf0: 51 4c 69 74 65 20 5b 73 71 6c 69 74 65 33 20 2d  QLite [sqlite3 -
7c00: 73 6f 75 72 63 65 69 64 5d 22 0a 20 20 20 20 6f  sourceid]".    o
7c10: 75 74 70 75 74 32 20 22 24 6e 45 72 72 20 65 72  utput2 "$nErr er
7c20: 72 6f 72 73 20 6f 75 74 20 6f 66 20 24 6e 54 65  rors out of $nTe
7c30: 73 74 20 74 65 73 74 73 20 6f 6e 20 24 63 70 75  st tests on $cpu
7c40: 69 6e 66 6f 22 0a 20 20 7d 0a 20 20 69 66 20 7b  info".  }.  if {
7c50: 24 6e 45 72 72 3e 24 6e 4b 6e 6f 77 6e 7d 20 7b  $nErr>$nKnown} {
7c60: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 2d 6e 6f  .    output2 -no
7c70: 6e 65 77 6c 69 6e 65 20 22 21 46 61 69 6c 75 72  newline "!Failur
7c80: 65 73 20 6f 6e 20 74 68 65 73 65 20 74 65 73 74  es on these test
7c90: 73 3a 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20  s:".    foreach 
7ca0: 78 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  x [set_test_coun
7cb0: 74 65 72 20 66 61 69 6c 5f 6c 69 73 74 5d 20 7b  ter fail_list] {
7cc0: 0a 20 20 20 20 20 20 69 66 20 7b 21 5b 69 6e 66  .      if {![inf
7cd0: 6f 20 65 78 69 73 74 73 20 6b 6e 6f 77 6e 5f 65  o exists known_e
7ce0: 72 72 6f 72 28 24 78 29 5d 7d 20 7b 6f 75 74 70  rror($x)]} {outp
7cf0: 75 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22  ut2 -nonewline "
7d00: 20 24 78 22 7d 0a 20 20 20 20 7d 0a 20 20 20 20   $x"}.    }.    
7d10: 6f 75 74 70 75 74 32 20 22 22 0a 20 20 7d 0a 20  output2 "".  }. 
7d20: 20 66 6f 72 65 61 63 68 20 77 61 72 6e 69 6e 67   foreach warning
7d30: 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74   [set_test_count
7d40: 65 72 20 77 61 72 6e 5f 6c 69 73 74 5d 20 7b 0a  er warn_list] {.
7d50: 20 20 20 20 6f 75 74 70 75 74 32 20 22 57 61 72      output2 "War
7d60: 6e 69 6e 67 3a 20 24 77 61 72 6e 69 6e 67 22 0a  ning: $warning".
7d70: 20 20 7d 0a 20 20 72 75 6e 5f 74 68 72 65 61 64    }.  run_thread
7d80: 5f 74 65 73 74 73 20 31 0a 20 20 69 66 20 7b 5b  _tests 1.  if {[
7d90: 6c 6c 65 6e 67 74 68 20 24 6f 6d 69 74 4c 69 73  llength $omitLis
7da0: 74 5d 3e 30 7d 20 7b 0a 20 20 20 20 6f 75 74 70  t]>0} {.    outp
7db0: 75 74 32 20 22 4f 6d 69 74 74 65 64 20 74 65 73  ut2 "Omitted tes
7dc0: 74 20 63 61 73 65 73 3a 22 0a 20 20 20 20 73 65  t cases:".    se
7dd0: 74 20 70 72 65 63 20 7b 7d 0a 20 20 20 20 66 6f  t prec {}.    fo
7de0: 72 65 61 63 68 20 7b 72 65 63 7d 20 5b 6c 73 6f  reach {rec} [lso
7df0: 72 74 20 24 6f 6d 69 74 4c 69 73 74 5d 20 7b 0a  rt $omitList] {.
7e00: 20 20 20 20 20 20 69 66 20 7b 24 72 65 63 3d 3d        if {$rec==
7e10: 24 70 72 65 63 7d 20 63 6f 6e 74 69 6e 75 65 0a  $prec} continue.
7e20: 20 20 20 20 20 20 73 65 74 20 70 72 65 63 20 24        set prec $
7e30: 72 65 63 0a 20 20 20 20 20 20 6f 75 74 70 75 74  rec.      output
7e40: 32 20 5b 66 6f 72 6d 61 74 20 7b 2e 20 20 25 2d  2 [format {.  %-
7e50: 31 32 73 20 25 73 7d 20 5b 6c 69 6e 64 65 78 20  12s %s} [lindex 
7e60: 24 72 65 63 20 30 5d 20 5b 6c 69 6e 64 65 78 20  $rec 0] [lindex 
7e70: 24 72 65 63 20 31 5d 5d 0a 20 20 20 20 7d 0a 20  $rec 1]].    }. 
7e80: 20 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 30   }.  if {$nErr>0
7e90: 20 26 26 20 21 5b 77 6f 72 6b 69 6e 67 5f 36 34   && ![working_64
7ea0: 62 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20 20 20 20  bit_int]} {.    
7eb0: 6f 75 74 70 75 74 32 20 22 2a 2a 2a 2a 2a 2a 2a  output2 "*******
7ec0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ed0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ee0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ef0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20  ***********".   
7f00: 20 6f 75 74 70 75 74 32 20 22 4e 2e 42 2e 3a 20   output2 "N.B.: 
7f10: 20 54 68 65 20 76 65 72 73 69 6f 6e 20 6f 66 20   The version of 
7f20: 54 43 4c 20 74 68 61 74 20 79 6f 75 20 75 73 65  TCL that you use
7f30: 64 20 74 6f 20 62 75 69 6c 64 20 74 68 69 73 20  d to build this 
7f40: 74 65 73 74 20 68 61 72 6e 65 73 73 22 0a 20 20  test harness".  
7f50: 20 20 6f 75 74 70 75 74 32 20 22 69 73 20 64 65    output2 "is de
7f60: 66 65 63 74 69 76 65 20 69 6e 20 74 68 61 74 20  fective in that 
7f70: 69 74 20 64 6f 65 73 20 6e 6f 74 20 73 75 70 70  it does not supp
7f80: 6f 72 74 20 36 34 2d 62 69 74 20 69 6e 74 65 67  ort 64-bit integ
7f90: 65 72 73 2e 20 20 53 6f 6d 65 20 6f 72 22 0a 20  ers.  Some or". 
7fa0: 20 20 20 6f 75 74 70 75 74 32 20 22 61 6c 6c 20     output2 "all 
7fb0: 6f 66 20 74 68 65 20 74 65 73 74 20 66 61 69 6c  of the test fail
7fc0: 75 72 65 73 20 61 62 6f 76 65 20 6d 69 67 68 74  ures above might
7fd0: 20 62 65 20 61 20 72 65 73 75 6c 74 20 66 72 6f   be a result fro
7fe0: 6d 20 74 68 69 73 20 64 65 66 65 63 74 22 0a 20  m this defect". 
7ff0: 20 20 20 6f 75 74 70 75 74 32 20 22 69 6e 20 79     output2 "in y
8000: 6f 75 72 20 54 43 4c 20 62 75 69 6c 64 2e 22 0a  our TCL build.".
8010: 20 20 20 20 6f 75 74 70 75 74 32 20 22 2a 2a 2a      output2 "***
8020: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8030: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8040: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8050: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22  ***************"
8060: 0a 20 20 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d  .  }.  if {$::cm
8070: 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c  dlinearg(binaryl
8080: 6f 67 29 7d 20 7b 0a 20 20 20 20 76 66 73 6c 6f  og)} {.    vfslo
8090: 67 20 66 69 6e 61 6c 69 7a 65 20 62 69 6e 61 72  g finalize binar
80a0: 79 6c 6f 67 0a 20 20 7d 0a 20 20 69 66 20 7b 24  ylog.  }.  if {$
80b0: 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65  sqlite_open_file
80c0: 5f 63 6f 75 6e 74 7d 20 7b 0a 20 20 20 20 6f 75  _count} {.    ou
80d0: 74 70 75 74 32 20 22 24 73 71 6c 69 74 65 5f 6f  tput2 "$sqlite_o
80e0: 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 66  pen_file_count f
80f0: 69 6c 65 73 20 77 65 72 65 20 6c 65 66 74 20 6f  iles were left o
8100: 70 65 6e 22 0a 20 20 20 20 69 6e 63 72 20 6e 45  pen".    incr nE
8110: 72 72 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 6c 69  rr.  }.  if {[li
8120: 6e 64 65 78 20 5b 73 71 6c 69 74 65 33 5f 73 74  ndex [sqlite3_st
8130: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
8140: 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20  US_MALLOC_COUNT 
8150: 30 5d 20 31 5d 3e 30 20 7c 7c 0a 20 20 20 20 20  0] 1]>0 ||.     
8160: 20 20 20 20 20 20 20 20 20 5b 73 71 6c 69 74 65           [sqlite
8170: 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e 30  3_memory_used]>0
8180: 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20  } {.    output2 
8190: 22 55 6e 66 72 65 65 64 20 6d 65 6d 6f 72 79 3a  "Unfreed memory:
81a0: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79   [sqlite3_memory
81b0: 5f 75 73 65 64 5d 20 62 79 74 65 73 20 69 6e 5c  _used] bytes in\
81c0: 0a 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65  .         [linde
81d0: 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75  x [sqlite3_statu
81e0: 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  s SQLITE_STATUS_
81f0: 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 20  MALLOC_COUNT 0] 
8200: 31 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 22 0a  1] allocations".
8210: 20 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20      incr nErr.  
8220: 20 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64    ifcapable memd
8230: 65 62 75 67 7c 7c 6d 65 6d 35 7c 7c 28 6d 65 6d  ebug||mem5||(mem
8240: 33 26 26 64 65 62 75 67 29 20 7b 0a 20 20 20 20  3&&debug) {.    
8250: 20 20 6f 75 74 70 75 74 32 20 22 57 72 69 74 69    output2 "Writi
8260: 6e 67 20 75 6e 66 72 65 65 64 20 6d 65 6d 6f 72  ng unfreed memor
8270: 79 20 6c 6f 67 20 74 6f 20 5c 22 2e 2f 6d 65 6d  y log to \"./mem
8280: 6c 65 61 6b 2e 74 78 74 5c 22 22 0a 20 20 20 20  leak.txt\"".    
8290: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
82a0: 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 6c 65 61  ug_dump ./memlea
82b0: 6b 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d 20  k.txt.    }.  } 
82c0: 65 6c 73 65 20 7b 0a 20 20 20 20 6f 75 74 70 75  else {.    outpu
82d0: 74 32 20 22 41 6c 6c 20 6d 65 6d 6f 72 79 20 61  t2 "All memory a
82e0: 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 72 65 65 64  llocations freed
82f0: 20 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a 20 20 20   - no leaks".   
8300: 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64 65   ifcapable memde
8310: 62 75 67 7c 7c 6d 65 6d 35 20 7b 0a 20 20 20 20  bug||mem5 {.    
8320: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
8330: 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 75 73 61  ug_dump ./memusa
8340: 67 65 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d  ge.txt.    }.  }
8350: 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73  .  show_memstats
8360: 0a 20 20 6f 75 74 70 75 74 32 20 22 4d 61 78 69  .  output2 "Maxi
8370: 6d 75 6d 20 6d 65 6d 6f 72 79 20 75 73 61 67 65  mum memory usage
8380: 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72  : [sqlite3_memor
8390: 79 5f 68 69 67 68 77 61 74 65 72 20 31 5d 20 62  y_highwater 1] b
83a0: 79 74 65 73 22 0a 20 20 6f 75 74 70 75 74 32 20  ytes".  output2 
83b0: 22 43 75 72 72 65 6e 74 20 6d 65 6d 6f 72 79 20  "Current memory 
83c0: 75 73 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f  usage: [sqlite3_
83d0: 6d 65 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72  memory_highwater
83e0: 5d 20 62 79 74 65 73 22 0a 20 20 69 66 20 7b 5b  ] bytes".  if {[
83f0: 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20 73 71  info commands sq
8400: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6d  lite3_memdebug_m
8410: 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20 6e 65 20  alloc_count] ne 
8420: 22 22 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74  ""} {.    output
8430: 32 20 22 4e 75 6d 62 65 72 20 6f 66 20 6d 61 6c  2 "Number of mal
8440: 6c 6f 63 28 29 20 20 3a 20 5b 73 71 6c 69 74 65  loc()  : [sqlite
8450: 33 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f  3_memdebug_mallo
8460: 63 5f 63 6f 75 6e 74 5d 20 63 61 6c 6c 73 22 0a  c_count] calls".
8470: 20 20 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64    }.  if {$::cmd
8480: 6c 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72  linearg(malloctr
8490: 61 63 65 29 7d 20 7b 0a 20 20 20 20 6f 75 74 70  ace)} {.    outp
84a0: 75 74 32 20 22 57 72 69 74 69 6e 67 20 6d 61 6c  ut2 "Writing mal
84b0: 6c 6f 63 73 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20  locs.sql...".   
84c0: 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71   memdebug_log_sq
84d0: 6c 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65  l.    sqlite3_me
84e0: 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74 6f 70 0a  mdebug_log stop.
84f0: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64      sqlite3_memd
8500: 65 62 75 67 5f 6c 6f 67 20 63 6c 65 61 72 0a 0a  ebug_log clear..
8510: 20 20 20 20 69 66 20 7b 5b 73 71 6c 69 74 65 33      if {[sqlite3
8520: 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e 30 7d  _memory_used]>0}
8530: 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75 74 32   {.      output2
8540: 20 22 57 72 69 74 69 6e 67 20 6c 65 61 6b 73 2e   "Writing leaks.
8550: 73 71 6c 2e 2e 2e 22 0a 20 20 20 20 20 20 73 71  sql...".      sq
8560: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c  lite3_memdebug_l
8570: 6f 67 20 73 79 6e 63 0a 20 20 20 20 20 20 6d 65  og sync.      me
8580: 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 20 6c  mdebug_log_sql l
8590: 65 61 6b 73 2e 73 71 6c 0a 20 20 20 20 7d 0a 20  eaks.sql.    }. 
85a0: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b   }.  foreach f [
85b0: 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  glob -nocomplain
85c0: 20 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75 72 6e   test.db-*-journ
85d0: 61 6c 5d 20 7b 0a 20 20 20 20 66 6f 72 63 65 64  al] {.    forced
85e0: 65 6c 65 74 65 20 24 66 0a 20 20 7d 0a 20 20 66  elete $f.  }.  f
85f0: 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d  oreach f [glob -
8600: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e  nocomplain test.
8610: 64 62 2d 6d 6a 2a 5d 20 7b 0a 20 20 20 20 66 6f  db-mj*] {.    fo
8620: 72 63 65 64 65 6c 65 74 65 20 24 66 0a 20 20 7d  rcedelete $f.  }
8630: 0a 20 20 65 78 69 74 20 5b 65 78 70 72 20 7b 24  .  exit [expr {$
8640: 6e 45 72 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 44 69  nErr>0}].}..# Di
8650: 73 70 6c 61 79 20 6d 65 6d 6f 72 79 20 73 74 61  splay memory sta
8660: 74 69 73 74 69 63 73 20 66 6f 72 20 61 6e 61 6c  tistics for anal
8670: 79 73 69 73 20 61 6e 64 20 64 65 62 75 67 67 69  ysis and debuggi
8680: 6e 67 20 70 75 72 70 6f 73 65 73 2e 0a 23 0a 70  ng purposes..#.p
8690: 72 6f 63 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74  roc show_memstat
86a0: 73 20 7b 7d 20 7b 0a 20 20 73 65 74 20 78 20 5b  s {} {.  set x [
86b0: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
86c0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 45 4d  QLITE_STATUS_MEM
86d0: 4f 52 59 5f 55 53 45 44 20 30 5d 0a 20 20 73 65  ORY_USED 0].  se
86e0: 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  t y [sqlite3_sta
86f0: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
8700: 53 5f 4d 41 4c 4c 4f 43 5f 53 49 5a 45 20 30 5d  S_MALLOC_SIZE 0]
8710: 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d  .  set val [form
8720: 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61  at {now %10d  ma
8730: 78 20 25 31 30 64 20 20 6d 61 78 2d 73 69 7a 65  x %10d  max-size
8740: 20 25 31 30 64 7d 20 5c 0a 20 20 20 20 20 20 20   %10d} \.       
8750: 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24         [lindex $
8760: 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20  x 1] [lindex $x 
8770: 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d  2] [lindex $y 2]
8780: 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 4d 65 6d  ].  output1 "Mem
8790: 6f 72 79 20 75 73 65 64 3a 20 20 20 20 20 20 20  ory used:       
87a0: 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78     $val".  set x
87b0: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
87c0: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d   SQLITE_STATUS_M
87d0: 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 0a 20  ALLOC_COUNT 0]. 
87e0: 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74   set val [format
87f0: 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20   {now %10d  max 
8800: 25 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78  %10d} [lindex $x
8810: 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32   1] [lindex $x 2
8820: 5d 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 41 6c  ]].  output1 "Al
8830: 6c 6f 63 61 74 69 6f 6e 20 63 6f 75 6e 74 3a 20  location count: 
8840: 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20      $val".  set 
8850: 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75  x [sqlite3_statu
8860: 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  s SQLITE_STATUS_
8870: 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 20 30  PAGECACHE_USED 0
8880: 5d 0a 20 20 73 65 74 20 79 20 5b 73 71 6c 69 74  ].  set y [sqlit
8890: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
88a0: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
88b0: 45 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74 20  E_SIZE 0].  set 
88c0: 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77  val [format {now
88d0: 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 20   %10d  max %10d 
88e0: 20 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d 20   max-size %10d} 
88f0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
8900: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
8910: 69 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e  index $x 2] [lin
8920: 64 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f 75 74  dex $y 2]].  out
8930: 70 75 74 31 20 22 50 61 67 65 2d 63 61 63 68 65  put1 "Page-cache
8940: 20 75 73 65 64 3a 20 20 20 20 20 20 24 76 61 6c   used:      $val
8950: 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74  ".  set x [sqlit
8960: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
8970: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
8980: 45 5f 4f 56 45 52 46 4c 4f 57 20 30 5d 0a 20 20  E_OVERFLOW 0].  
8990: 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20  set val [format 
89a0: 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25  {now %10d  max %
89b0: 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20  10d} [lindex $x 
89c0: 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d  1] [lindex $x 2]
89d0: 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 50 61 67  ].  output1 "Pag
89e0: 65 2d 63 61 63 68 65 20 6f 76 65 72 66 6c 6f 77  e-cache overflow
89f0: 3a 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78  :  $val".  set x
8a00: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
8a10: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 53   SQLITE_STATUS_S
8a20: 43 52 41 54 43 48 5f 55 53 45 44 20 30 5d 0a 20  CRATCH_USED 0]. 
8a30: 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74   set val [format
8a40: 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20   {now %10d  max 
8a50: 25 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78  %10d} [lindex $x
8a60: 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32   1] [lindex $x 2
8a70: 5d 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 53 63  ]].  output1 "Sc
8a80: 72 61 74 63 68 20 6d 65 6d 6f 72 79 20 75 73 65  ratch memory use
8a90: 64 3a 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20  d:  $val".  set 
8aa0: 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75  x [sqlite3_statu
8ab0: 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  s SQLITE_STATUS_
8ac0: 53 43 52 41 54 43 48 5f 4f 56 45 52 46 4c 4f 57  SCRATCH_OVERFLOW
8ad0: 20 30 5d 0a 20 20 73 65 74 20 79 20 5b 73 71 6c   0].  set y [sql
8ae0: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
8af0: 54 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43  TE_STATUS_SCRATC
8b00: 48 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74 20  H_SIZE 0].  set 
8b10: 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77  val [format {now
8b20: 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 20   %10d  max %10d 
8b30: 20 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d 20   max-size %10d} 
8b40: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
8b50: 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b   [lindex $x 1] [
8b60: 6c 69 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69  lindex $x 2] [li
8b70: 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f 75  ndex $y 2]].  ou
8b80: 74 70 75 74 31 20 22 53 63 72 61 74 63 68 20 6f  tput1 "Scratch o
8b90: 76 65 72 66 6c 6f 77 3a 20 20 20 20 20 24 76 61  verflow:     $va
8ba0: 6c 22 0a 20 20 69 66 63 61 70 61 62 6c 65 20 79  l".  ifcapable y
8bb0: 79 74 72 61 63 6b 6d 61 78 73 74 61 63 6b 64 65  ytrackmaxstackde
8bc0: 70 74 68 20 7b 0a 20 20 20 20 73 65 74 20 78 20  pth {.    set x 
8bd0: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
8be0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
8bf0: 52 53 45 52 5f 53 54 41 43 4b 20 30 5d 0a 20 20  RSER_STACK 0].  
8c00: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
8c10: 74 20 7b 20 20 20 20 20 20 20 20 20 20 20 20 20  t {             
8c20: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
8c30: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 20 20 6f  dex $x 2]].    o
8c40: 75 74 70 75 74 32 20 22 50 61 72 73 65 72 20 73  utput2 "Parser s
8c50: 74 61 63 6b 20 64 65 70 74 68 3a 20 20 20 20 24  tack depth:    $
8c60: 76 61 6c 22 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20  val".  }.}..# A 
8c70: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65  procedure to exe
8c80: 63 75 74 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20  cute SQL.#.proc 
8c90: 65 78 65 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62  execsql {sql {db
8ca0: 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73   db}} {.  # puts
8cb0: 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20   "SQL = $sql".  
8cc0: 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64  uplevel [list $d
8cd0: 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 70  b eval $sql].}.p
8ce0: 72 6f 63 20 65 78 65 63 73 71 6c 5f 74 69 6d 65  roc execsql_time
8cf0: 64 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20  d {sql {db db}} 
8d00: 7b 0a 20 20 73 65 74 20 74 6d 20 5b 74 69 6d 65  {.  set tm [time
8d10: 20 7b 0a 20 20 20 20 73 65 74 20 78 20 5b 75 70   {.    set x [up
8d20: 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20  level [list $db 
8d30: 65 76 61 6c 20 24 73 71 6c 5d 5d 0a 20 20 7d 20  eval $sql]].  } 
8d40: 31 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e  1].  set tm [lin
8d50: 64 65 78 20 24 74 6d 20 30 5d 0a 20 20 6f 75 74  dex $tm 0].  out
8d60: 70 75 74 31 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  put1 -nonewline 
8d70: 22 20 28 5b 65 78 70 72 20 7b 24 74 6d 2a 30 2e  " ([expr {$tm*0.
8d80: 30 30 31 7d 5d 6d 73 29 20 22 0a 20 20 73 65 74  001}]ms) ".  set
8d90: 20 78 0a 7d 0a 0a 23 20 45 78 65 63 75 74 65 20   x.}..# Execute 
8da0: 53 51 4c 20 61 6e 64 20 63 61 74 63 68 20 65 78  SQL and catch ex
8db0: 63 65 70 74 69 6f 6e 73 2e 0a 23 0a 70 72 6f 63  ceptions..#.proc
8dc0: 20 63 61 74 63 68 73 71 6c 20 7b 73 71 6c 20 7b   catchsql {sql {
8dd0: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75  db db}} {.  # pu
8de0: 74 73 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a  ts "SQL = $sql".
8df0: 20 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 5b    set r [catch [
8e00: 6c 69 73 74 20 75 70 6c 65 76 65 6c 20 5b 6c 69  list uplevel [li
8e10: 73 74 20 24 64 62 20 65 76 61 6c 20 24 73 71 6c  st $db eval $sql
8e20: 5d 5d 20 6d 73 67 5d 0a 20 20 6c 61 70 70 65 6e  ]] msg].  lappen
8e30: 64 20 72 20 24 6d 73 67 0a 20 20 72 65 74 75 72  d r $msg.  retur
8e40: 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20  n $r.}..# Do an 
8e50: 56 44 42 45 20 63 6f 64 65 20 64 75 6d 70 20 6f  VDBE code dump o
8e60: 6e 20 74 68 65 20 53 51 4c 20 67 69 76 65 6e 0a  n the SQL given.
8e70: 23 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 20 7b  #.proc explain {
8e80: 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20  sql {db db}} {. 
8e90: 20 6f 75 74 70 75 74 32 20 22 22 0a 20 20 6f 75   output2 "".  ou
8ea0: 74 70 75 74 32 20 22 61 64 64 72 20 20 6f 70 63  tput2 "addr  opc
8eb0: 6f 64 65 20 20 20 20 20 20 20 20 70 31 20 20 20  ode        p1   
8ec0: 20 20 20 70 32 20 20 20 20 20 20 70 33 20 20 20     p2      p3   
8ed0: 20 20 20 70 34 20 20 20 20 20 20 20 20 20 20 20     p4           
8ee0: 20 20 20 20 70 35 20 20 23 22 0a 20 20 6f 75 74      p5  #".  out
8ef0: 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d  put2 "----  ----
8f00: 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  --------  ------
8f10: 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d    ------  ------
8f20: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
8f30: 2d 20 20 2d 2d 20 20 2d 22 0a 20 20 24 64 62 20  -  --  -".  $db 
8f40: 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73  eval "explain $s
8f50: 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 6f 75 74  ql" {} {.    out
8f60: 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 2d  put2 [format {%-
8f70: 34 64 20 20 25 2d 31 32 2e 31 32 73 20 20 25 2d  4d  %-12.12s  %-
8f80: 36 64 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20  6d  %-6d  %-6d  
8f90: 25 20 2d 31 37 73 20 25 73 20 20 25 73 7d 20 5c  % -17s %s  %s} \
8fa0: 0a 20 20 20 20 20 20 24 61 64 64 72 20 24 6f 70  .      $addr $op
8fb0: 63 6f 64 65 20 24 70 31 20 24 70 32 20 24 70 33  code $p1 $p2 $p3
8fc0: 20 24 70 34 20 24 70 35 20 24 63 6f 6d 6d 65 6e   $p4 $p5 $commen
8fd0: 74 0a 20 20 20 20 5d 0a 20 20 7d 0a 7d 0a 0a 70  t.    ].  }.}..p
8fe0: 72 6f 63 20 65 78 70 6c 61 69 6e 5f 69 20 7b 73  roc explain_i {s
8ff0: 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  ql {db db}} {.  
9000: 6f 75 74 70 75 74 32 20 22 22 0a 20 20 6f 75 74  output2 "".  out
9010: 70 75 74 32 20 22 61 64 64 72 20 20 6f 70 63 6f  put2 "addr  opco
9020: 64 65 20 20 20 20 20 20 20 20 70 31 20 20 20 20  de        p1    
9030: 20 20 70 32 20 20 20 20 20 20 70 33 20 20 20 20    p2      p3    
9040: 20 20 70 34 20 20 20 20 20 20 20 20 20 20 20 20    p4            
9050: 20 20 20 20 70 35 20 20 23 22 0a 20 20 6f 75 74      p5  #".  out
9060: 70 75 74 32 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d  put2 "----  ----
9070: 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  --------  ------
9080: 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d    ------  ------
9090: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
90a0: 2d 2d 20 20 2d 2d 20 20 2d 22 0a 0a 0a 20 20 23  --  --  -"...  #
90b0: 20 53 65 74 20 75 70 20 63 6f 6c 6f 72 73 20 66   Set up colors f
90c0: 6f 72 20 74 68 65 20 64 69 66 66 65 72 65 6e 74  or the different
90d0: 20 6f 70 63 6f 64 65 73 2e 20 53 63 68 65 6d 65   opcodes. Scheme
90e0: 20 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a   is as follows:.
90f0: 20 20 23 0a 20 20 23 20 20 20 52 65 64 3a 20 20    #.  #   Red:  
9100: 20 4f 70 63 6f 64 65 73 20 74 68 61 74 20 77 72   Opcodes that wr
9110: 69 74 65 20 74 6f 20 61 20 62 2d 74 72 65 65 2e  ite to a b-tree.
9120: 0a 20 20 23 20 20 20 42 6c 75 65 3a 20 20 4f 70  .  #   Blue:  Op
9130: 63 6f 64 65 73 20 74 68 61 74 20 72 65 70 6f 73  codes that repos
9140: 69 74 69 6f 6e 20 6f 72 20 73 65 65 6b 20 61 20  ition or seek a 
9150: 63 75 72 73 6f 72 2e 20 0a 20 20 23 20 20 20 47  cursor. .  #   G
9160: 72 65 65 6e 3a 20 54 68 65 20 52 65 73 75 6c 74  reen: The Result
9170: 52 6f 77 20 6f 70 63 6f 64 65 2e 0a 20 20 23 0a  Row opcode..  #.
9180: 20 20 69 66 20 7b 20 5b 63 61 74 63 68 20 7b 66    if { [catch {f
9190: 63 6f 6e 66 69 67 75 72 65 20 73 74 64 6f 75 74  configure stdout
91a0: 20 2d 6d 6f 64 65 7d 5d 3d 3d 30 20 7d 20 7b 0a   -mode}]==0 } {.
91b0: 20 20 20 20 73 65 74 20 52 20 22 5c 30 33 33 5c      set R "\033\
91c0: 5b 33 31 3b 31 6d 22 20 20 20 20 20 20 20 20 3b  [31;1m"        ;
91d0: 23 20 52 65 64 20 66 67 0a 20 20 20 20 73 65 74  # Red fg.    set
91e0: 20 47 20 22 5c 30 33 33 5c 5b 33 32 3b 31 6d 22   G "\033\[32;1m"
91f0: 20 20 20 20 20 20 20 20 3b 23 20 47 72 65 65 6e          ;# Green
9200: 20 66 67 0a 20 20 20 20 73 65 74 20 42 20 22 5c   fg.    set B "\
9210: 30 33 33 5c 5b 33 34 3b 31 6d 22 20 20 20 20 20  033\[34;1m"     
9220: 20 20 20 3b 23 20 52 65 64 20 66 67 0a 20 20 20     ;# Red fg.   
9230: 20 73 65 74 20 44 20 22 5c 30 33 33 5c 5b 33 39   set D "\033\[39
9240: 3b 30 6d 22 20 20 20 20 20 20 20 20 3b 23 20 44  ;0m"        ;# D
9250: 65 66 61 75 6c 74 20 66 67 0a 20 20 7d 20 65 6c  efault fg.  } el
9260: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 52 20 22  se {.    set R "
9270: 22 0a 20 20 20 20 73 65 74 20 47 20 22 22 0a 20  ".    set G "". 
9280: 20 20 20 73 65 74 20 42 20 22 22 0a 20 20 20 20     set B "".    
9290: 73 65 74 20 44 20 22 22 0a 20 20 7d 0a 20 20 66  set D "".  }.  f
92a0: 6f 72 65 61 63 68 20 6f 70 63 6f 64 65 20 7b 0a  oreach opcode {.
92b0: 20 20 20 20 20 20 53 65 65 6b 20 53 65 65 6b 47        Seek SeekG
92c0: 65 20 53 65 65 6b 47 74 20 53 65 65 6b 4c 65 20  e SeekGt SeekLe 
92d0: 53 65 65 6b 4c 74 20 4e 6f 74 46 6f 75 6e 64 20  SeekLt NotFound 
92e0: 4c 61 73 74 20 52 65 77 69 6e 64 0a 20 20 20 20  Last Rewind.    
92f0: 20 20 4e 6f 43 6f 6e 66 6c 69 63 74 20 4e 65 78    NoConflict Nex
9300: 74 20 50 72 65 76 20 56 4e 65 78 74 20 56 50 72  t Prev VNext VPr
9310: 65 76 20 56 46 69 6c 74 65 72 0a 20 20 20 20 20  ev VFilter.     
9320: 20 53 6f 72 74 65 72 53 6f 72 74 20 53 6f 72 74   SorterSort Sort
9330: 65 72 4e 65 78 74 0a 20 20 7d 20 7b 0a 20 20 20  erNext.  } {.   
9340: 20 73 65 74 20 63 6f 6c 6f 72 28 24 6f 70 63 6f   set color($opco
9350: 64 65 29 20 24 42 0a 20 20 7d 0a 20 20 66 6f 72  de) $B.  }.  for
9360: 65 61 63 68 20 6f 70 63 6f 64 65 20 7b 52 65 73  each opcode {Res
9370: 75 6c 74 52 6f 77 7d 20 7b 0a 20 20 20 20 73 65  ultRow} {.    se
9380: 74 20 63 6f 6c 6f 72 28 24 6f 70 63 6f 64 65 29  t color($opcode)
9390: 20 24 47 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63   $G.  }.  foreac
93a0: 68 20 6f 70 63 6f 64 65 20 7b 49 64 78 49 6e 73  h opcode {IdxIns
93b0: 65 72 74 20 49 6e 73 65 72 74 20 44 65 6c 65 74  ert Insert Delet
93c0: 65 20 49 64 78 44 65 6c 65 74 65 7d 20 7b 0a 20  e IdxDelete} {. 
93d0: 20 20 20 73 65 74 20 63 6f 6c 6f 72 28 24 6f 70     set color($op
93e0: 63 6f 64 65 29 20 24 52 0a 20 20 7d 0a 0a 20 20  code) $R.  }..  
93f0: 73 65 74 20 62 53 65 65 6e 47 6f 74 6f 20 30 0a  set bSeenGoto 0.
9400: 20 20 24 64 62 20 65 76 61 6c 20 22 65 78 70 6c    $db eval "expl
9410: 61 69 6e 20 24 73 71 6c 22 20 7b 7d 20 7b 0a 20  ain $sql" {} {. 
9420: 20 20 20 73 65 74 20 78 28 24 61 64 64 72 29 20     set x($addr) 
9430: 30 0a 20 20 20 20 73 65 74 20 6f 70 28 24 61 64  0.    set op($ad
9440: 64 72 29 20 24 6f 70 63 6f 64 65 0a 0a 20 20 20  dr) $opcode..   
9450: 20 69 66 20 7b 24 6f 70 63 6f 64 65 20 3d 3d 20   if {$opcode == 
9460: 22 47 6f 74 6f 22 20 26 26 20 28 24 62 53 65 65  "Goto" && ($bSee
9470: 6e 47 6f 74 6f 3d 3d 30 20 7c 7c 20 28 24 70 32  nGoto==0 || ($p2
9480: 20 3e 20 24 61 64 64 72 2b 31 30 29 29 7d 20 7b   > $addr+10))} {
9490: 0a 20 20 20 20 20 20 73 65 74 20 6c 69 6e 65 62  .      set lineb
94a0: 72 65 61 6b 28 24 70 32 29 20 31 0a 20 20 20 20  reak($p2) 1.    
94b0: 20 20 73 65 74 20 62 53 65 65 6e 47 6f 74 6f 20    set bSeenGoto 
94c0: 31 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20  1.    }..    if 
94d0: 7b 24 6f 70 63 6f 64 65 3d 3d 22 4e 65 78 74 22  {$opcode=="Next"
94e0: 20 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22 50    || $opcode=="P
94f0: 72 65 76 22 20 0a 20 20 20 20 20 7c 7c 20 24 6f  rev" .     || $o
9500: 70 63 6f 64 65 3d 3d 22 56 4e 65 78 74 22 20 7c  pcode=="VNext" |
9510: 7c 20 24 6f 70 63 6f 64 65 3d 3d 22 56 50 72 65  | $opcode=="VPre
9520: 76 22 0a 20 20 20 20 20 7c 7c 20 24 6f 70 63 6f  v".     || $opco
9530: 64 65 3d 3d 22 53 6f 72 74 65 72 4e 65 78 74 22  de=="SorterNext"
9540: 0a 20 20 20 20 7d 20 7b 0a 20 20 20 20 20 20 66  .    } {.      f
9550: 6f 72 20 7b 73 65 74 20 69 20 24 70 32 7d 20 7b  or {set i $p2} {
9560: 24 69 3c 24 61 64 64 72 7d 20 7b 69 6e 63 72 20  $i<$addr} {incr 
9570: 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 69 6e 63  i} {.        inc
9580: 72 20 78 28 24 69 29 20 32 0a 20 20 20 20 20 20  r x($i) 2.      
9590: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20  }.    }..    if 
95a0: 7b 24 6f 70 63 6f 64 65 20 3d 3d 20 22 47 6f 74  {$opcode == "Got
95b0: 6f 22 20 26 26 20 24 70 32 3c 24 61 64 64 72 20  o" && $p2<$addr 
95c0: 26 26 20 24 6f 70 28 24 70 32 29 3d 3d 22 59 69  && $op($p2)=="Yi
95d0: 65 6c 64 22 7d 20 7b 0a 20 20 20 20 20 20 66 6f  eld"} {.      fo
95e0: 72 20 7b 73 65 74 20 69 20 5b 65 78 70 72 20 24  r {set i [expr $
95f0: 70 32 2b 31 5d 7d 20 7b 24 69 3c 24 61 64 64 72  p2+1]} {$i<$addr
9600: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
9610: 20 20 20 20 20 69 6e 63 72 20 78 28 24 69 29 20       incr x($i) 
9620: 32 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  2.      }.    }.
9630: 0a 20 20 20 20 69 66 20 7b 24 6f 70 63 6f 64 65  .    if {$opcode
9640: 20 3d 3d 20 22 48 61 6c 74 22 20 26 26 20 24 63   == "Halt" && $c
9650: 6f 6d 6d 65 6e 74 20 3d 3d 20 22 45 6e 64 20 6f  omment == "End o
9660: 66 20 63 6f 72 6f 75 74 69 6e 65 22 7d 20 7b 0a  f coroutine"} {.
9670: 20 20 20 20 20 20 73 65 74 20 6c 69 6e 65 62 72        set linebr
9680: 65 61 6b 28 5b 65 78 70 72 20 24 61 64 64 72 2b  eak([expr $addr+
9690: 31 5d 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a  1]) 1.    }.  }.
96a0: 0a 20 20 24 64 62 20 65 76 61 6c 20 22 65 78 70  .  $db eval "exp
96b0: 6c 61 69 6e 20 24 73 71 6c 22 20 7b 7d 20 7b 0a  lain $sql" {} {.
96c0: 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78      if {[info ex
96d0: 69 73 74 73 20 6c 69 6e 65 62 72 65 61 6b 28 24  ists linebreak($
96e0: 61 64 64 72 29 5d 7d 20 7b 0a 20 20 20 20 20 20  addr)]} {.      
96f0: 6f 75 74 70 75 74 32 20 22 22 0a 20 20 20 20 7d  output2 "".    }
9700: 0a 20 20 20 20 73 65 74 20 49 20 5b 73 74 72 69  .    set I [stri
9710: 6e 67 20 72 65 70 65 61 74 20 22 20 22 20 24 78  ng repeat " " $x
9720: 28 24 61 64 64 72 29 5d 0a 0a 20 20 20 20 73 65  ($addr)]..    se
9730: 74 20 63 6f 6c 20 22 22 0a 20 20 20 20 63 61 74  t col "".    cat
9740: 63 68 20 7b 20 73 65 74 20 63 6f 6c 20 24 63 6f  ch { set col $co
9750: 6c 6f 72 28 24 6f 70 63 6f 64 65 29 20 7d 0a 0a  lor($opcode) }..
9760: 20 20 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72      output2 [for
9770: 6d 61 74 20 7b 25 2d 34 64 20 20 25 73 25 73 25  mat {%-4d  %s%s%
9780: 2d 31 32 2e 31 32 73 25 73 20 20 25 2d 36 64 20  -12.12s%s  %-6d 
9790: 20 25 2d 36 64 20 20 25 2d 36 64 20 20 25 20 2d   %-6d  %-6d  % -
97a0: 31 37 73 20 25 73 20 20 25 73 7d 20 5c 0a 20 20  17s %s  %s} \.  
97b0: 20 20 20 20 24 61 64 64 72 20 24 49 20 24 63 6f      $addr $I $co
97c0: 6c 20 24 6f 70 63 6f 64 65 20 24 44 20 24 70 31  l $opcode $D $p1
97d0: 20 24 70 32 20 24 70 33 20 24 70 34 20 24 70 35   $p2 $p3 $p4 $p5
97e0: 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 5d 0a   $comment.    ].
97f0: 20 20 7d 0a 20 20 6f 75 74 70 75 74 32 20 22 2d    }.  output2 "-
9800: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ---  -----------
9810: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
9820: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
9830: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20  -----------  -- 
9840: 20 2d 22 0a 7d 0a 0a 23 20 53 68 6f 77 20 74 68   -".}..# Show th
9850: 65 20 56 44 42 45 20 70 72 6f 67 72 61 6d 20 66  e VDBE program f
9860: 6f 72 20 61 6e 20 53 51 4c 20 73 74 61 74 65 6d  or an SQL statem
9870: 65 6e 74 20 62 75 74 20 6f 6d 69 74 20 74 68 65  ent but omit the
9880: 20 54 72 61 63 65 0a 23 20 6f 70 63 6f 64 65 20   Trace.# opcode 
9890: 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67  at the beginning
98a0: 2e 20 20 54 68 69 73 20 70 72 6f 63 65 64 75 72  .  This procedur
98b0: 65 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f  e can be used to
98c0: 20 70 72 6f 76 65 0a 23 20 74 68 61 74 20 64 69   prove.# that di
98d0: 66 66 65 72 65 6e 74 20 53 51 4c 20 73 74 61 74  fferent SQL stat
98e0: 65 6d 65 6e 74 73 20 67 65 6e 65 72 61 74 65 20  ements generate 
98f0: 65 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65  exactly the same
9900: 20 56 44 42 45 20 63 6f 64 65 2e 0a 23 0a 70 72   VDBE code..#.pr
9910: 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f 5f 74 72  oc explain_no_tr
9920: 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65  ace {sql} {.  se
9930: 74 20 74 72 20 5b 64 62 20 65 76 61 6c 20 22 45  t tr [db eval "E
9940: 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d 0a 20 20  XPLAIN $sql"].  
9950: 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67 65 20 24  return [lrange $
9960: 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a 23 20 41  tr 7 end].}..# A
9970: 6e 6f 74 68 65 72 20 70 72 6f 63 65 64 75 72 65  nother procedure
9980: 20 74 6f 20 65 78 65 63 75 74 65 20 53 51 4c 2e   to execute SQL.
9990: 20 20 54 68 69 73 20 6f 6e 65 20 69 6e 63 6c 75    This one inclu
99a0: 64 65 73 20 74 68 65 20 66 69 65 6c 64 0a 23 20  des the field.# 
99b0: 6e 61 6d 65 73 20 69 6e 20 74 68 65 20 72 65 74  names in the ret
99c0: 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23 0a 70 72  urned list..#.pr
99d0: 6f 63 20 65 78 65 63 73 71 6c 32 20 7b 73 71 6c  oc execsql2 {sql
99e0: 7d 20 7b 0a 20 20 73 65 74 20 72 65 73 75 6c 74  } {.  set result
99f0: 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c 20 24 73   {}.  db eval $s
9a00: 71 6c 20 64 61 74 61 20 7b 0a 20 20 20 20 66 6f  ql data {.    fo
9a10: 72 65 61 63 68 20 66 20 24 64 61 74 61 28 2a 29  reach f $data(*)
9a20: 20 7b 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64   {.      lappend
9a30: 20 72 65 73 75 6c 74 20 24 66 20 24 64 61 74 61   result $f $data
9a40: 28 24 66 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  ($f).    }.  }. 
9a50: 20 72 65 74 75 72 6e 20 24 72 65 73 75 6c 74 0a   return $result.
9a60: 7d 0a 0a 23 20 55 73 65 20 61 20 74 65 6d 70 6f  }..# Use a tempo
9a70: 72 61 72 79 20 69 6e 2d 6d 65 6d 6f 72 79 20 64  rary in-memory d
9a80: 61 74 61 62 61 73 65 20 74 6f 20 65 78 65 63 75  atabase to execu
9a90: 74 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  te SQL statement
9aa0: 73 0a 23 0a 70 72 6f 63 20 6d 65 6d 64 62 73 71  s.#.proc memdbsq
9ab0: 6c 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 71 6c 69  l {sql} {.  sqli
9ac0: 74 65 33 20 6d 65 6d 64 62 20 3a 6d 65 6d 6f 72  te3 memdb :memor
9ad0: 79 3a 0a 20 20 73 65 74 20 72 65 73 75 6c 74 20  y:.  set result 
9ae0: 5b 6d 65 6d 64 62 20 65 76 61 6c 20 24 73 71 6c  [memdb eval $sql
9af0: 5d 0a 20 20 6d 65 6d 64 62 20 63 6c 6f 73 65 0a  ].  memdb close.
9b00: 20 20 72 65 74 75 72 6e 20 24 72 65 73 75 6c 74    return $result
9b10: 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65 20 6e 6f  .}..# Use the no
9b20: 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49 20 74  n-callback API t
9b30: 6f 20 65 78 65 63 75 74 65 20 6d 75 6c 74 69 70  o execute multip
9b40: 6c 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  le SQL statement
9b50: 73 0a 23 0a 70 72 6f 63 20 73 74 65 70 73 71 6c  s.#.proc stepsql
9b60: 20 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b 0a 20   {dbptr sql} {. 
9b70: 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69 6e 67   set sql [string
9b80: 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20 73 65   trim $sql].  se
9b90: 74 20 72 20 30 0a 20 20 77 68 69 6c 65 20 7b 5b  t r 0.  while {[
9ba0: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73  string length $s
9bb0: 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69 66 20  ql]>0} {.    if 
9bc0: 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33  {[catch {sqlite3
9bd0: 5f 70 72 65 70 61 72 65 20 24 64 62 70 74 72 20  _prepare $dbptr 
9be0: 24 73 71 6c 20 2d 31 20 73 71 6c 74 61 69 6c 7d  $sql -1 sqltail}
9bf0: 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20 72 65   vm]} {.      re
9c00: 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24 76 6d  turn [list 1 $vm
9c10: 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20  ].    }.    set 
9c20: 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72 69 6d  sql [string trim
9c30: 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20 20 20   $sqltail].#    
9c40: 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65 5f 73  while {[sqlite_s
9c50: 74 65 70 20 24 76 6d 20 4e 20 56 41 4c 20 43 4f  tep $vm N VAL CO
9c60: 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22  L]=="SQLITE_ROW"
9c70: 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f 72 65 61  } {.#      forea
9c80: 63 68 20 76 20 24 56 41 4c 20 7b 6c 61 70 70 65  ch v $VAL {lappe
9c90: 6e 64 20 72 20 24 76 7d 0a 23 20 20 20 20 7d 0a  nd r $v}.#    }.
9ca0: 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69      while {[sqli
9cb0: 74 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d 3d 22  te3_step $vm]=="
9cc0: 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 20  SQLITE_ROW"} {. 
9cd0: 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20       for {set i 
9ce0: 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65 33 5f  0} {$i<[sqlite3_
9cf0: 64 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d 5d 7d  data_count $vm]}
9d00: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
9d10: 20 20 20 20 6c 61 70 70 65 6e 64 20 72 20 5b 73      lappend r [s
9d20: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65  qlite3_column_te
9d30: 78 74 20 24 76 6d 20 24 69 5d 0a 20 20 20 20 20  xt $vm $i].     
9d40: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20   }.    }.    if 
9d50: 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33  {[catch {sqlite3
9d60: 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d 20 65  _finalize $vm} e
9d70: 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20 20 20  rrmsg]} {.      
9d80: 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24  return [list 1 $
9d90: 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a 20 20  errmsg].    }.  
9da0: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a  }.  return $r.}.
9db0: 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67 72 69  .# Do an integri
9dc0: 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68 65 20  ty check of the 
9dd0: 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65 0a  entire database.
9de0: 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69 74 79  #.proc integrity
9df0: 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20 7b 64 62  _check {name {db
9e00: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61   db}} {.  ifcapa
9e10: 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20  ble integrityck 
9e20: 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e  {.    do_test $n
9e30: 61 6d 65 20 5b 6c 69 73 74 20 65 78 65 63 73 71  ame [list execsq
9e40: 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72  l {PRAGMA integr
9e50: 69 74 79 5f 63 68 65 63 6b 7d 20 24 64 62 5d 20  ity_check} $db] 
9e60: 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 43 68  {ok}.  }.}..# Ch
9e70: 65 63 6b 20 74 68 65 20 65 78 74 65 6e 64 65 64  eck the extended
9e80: 20 65 72 72 6f 72 20 63 6f 64 65 0a 23 0a 70 72   error code.#.pr
9e90: 6f 63 20 76 65 72 69 66 79 5f 65 78 5f 65 72 72  oc verify_ex_err
9ea0: 63 6f 64 65 20 7b 6e 61 6d 65 20 65 78 70 65 63  code {name expec
9eb0: 74 65 64 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20  ted {db db}} {. 
9ec0: 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b   do_test $name [
9ed0: 6c 69 73 74 20 73 71 6c 69 74 65 33 5f 65 78 74  list sqlite3_ext
9ee0: 65 6e 64 65 64 5f 65 72 72 63 6f 64 65 20 24 64  ended_errcode $d
9ef0: 62 5d 20 24 65 78 70 65 63 74 65 64 0a 7d 0a 0a  b] $expected.}..
9f00: 0a 23 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  .# Return true i
9f10: 66 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  f the SQL statem
9f20: 65 6e 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ent passed as th
9f30: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
9f40: 74 20 75 73 65 73 20 61 0a 23 20 73 74 61 74 65  t uses a.# state
9f50: 6d 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f 6e  ment transaction
9f60: 2e 0a 23 0a 70 72 6f 63 20 73 71 6c 5f 75 73 65  ..#.proc sql_use
9f70: 73 5f 73 74 6d 74 20 7b 64 62 20 73 71 6c 7d 20  s_stmt {db sql} 
9f80: 7b 0a 20 20 73 65 74 20 73 74 6d 74 20 5b 73 71  {.  set stmt [sq
9f90: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 20 24 64  lite3_prepare $d
9fa0: 62 20 24 73 71 6c 20 2d 31 20 64 75 6d 6d 79 5d  b $sql -1 dummy]
9fb0: 0a 20 20 73 65 74 20 75 73 65 73 20 5b 75 73 65  .  set uses [use
9fc0: 73 5f 73 74 6d 74 5f 6a 6f 75 72 6e 61 6c 20 24  s_stmt_journal $
9fd0: 73 74 6d 74 5d 0a 20 20 73 71 6c 69 74 65 33 5f  stmt].  sqlite3_
9fe0: 66 69 6e 61 6c 69 7a 65 20 24 73 74 6d 74 0a 20  finalize $stmt. 
9ff0: 20 72 65 74 75 72 6e 20 24 75 73 65 73 0a 7d 0a   return $uses.}.
a000: 0a 70 72 6f 63 20 66 69 78 5f 69 66 63 61 70 61  .proc fix_ifcapa
a010: 62 6c 65 5f 65 78 70 72 20 7b 65 78 70 72 7d 20  ble_expr {expr} 
a020: 7b 0a 20 20 73 65 74 20 72 65 74 20 22 22 0a 20  {.  set ret "". 
a030: 20 73 65 74 20 73 74 61 74 65 20 30 0a 20 20 66   set state 0.  f
a040: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
a050: 20 3c 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74   < [string lengt
a060: 68 20 24 65 78 70 72 5d 7d 20 7b 69 6e 63 72 20  h $expr]} {incr 
a070: 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 68 61  i} {.    set cha
a080: 72 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  r [string range 
a090: 24 65 78 70 72 20 24 69 20 24 69 5d 0a 20 20 20  $expr $i $i].   
a0a0: 20 73 65 74 20 6e 65 77 73 74 61 74 65 20 5b 65   set newstate [e
a0b0: 78 70 72 20 7b 5b 73 74 72 69 6e 67 20 69 73 20  xpr {[string is 
a0c0: 61 6c 6e 75 6d 20 24 63 68 61 72 5d 20 7c 7c 20  alnum $char] || 
a0d0: 24 63 68 61 72 20 65 71 20 22 5f 22 7d 5d 0a 20  $char eq "_"}]. 
a0e0: 20 20 20 69 66 20 7b 24 6e 65 77 73 74 61 74 65     if {$newstate
a0f0: 20 26 26 20 21 24 73 74 61 74 65 7d 20 7b 0a 20   && !$state} {. 
a100: 20 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20       append ret 
a110: 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f  {$::sqlite_optio
a120: 6e 73 28 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69  ns(}.    }.    i
a130: 66 20 7b 21 24 6e 65 77 73 74 61 74 65 20 26 26  f {!$newstate &&
a140: 20 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20   $state} {.     
a150: 20 61 70 70 65 6e 64 20 72 65 74 20 29 0a 20 20   append ret ).  
a160: 20 20 7d 0a 20 20 20 20 61 70 70 65 6e 64 20 72    }.    append r
a170: 65 74 20 24 63 68 61 72 0a 20 20 20 20 73 65 74  et $char.    set
a180: 20 73 74 61 74 65 20 24 6e 65 77 73 74 61 74 65   state $newstate
a190: 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73 74 61 74  .  }.  if {$stat
a1a0: 65 7d 20 7b 61 70 70 65 6e 64 20 72 65 74 20 29  e} {append ret )
a1b0: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 74 0a  }.  return $ret.
a1c0: 7d 0a 0a 23 20 52 65 74 75 72 6e 73 20 6e 6f 6e  }..# Returns non
a1d0: 2d 7a 65 72 6f 20 69 66 20 74 68 65 20 63 61 70  -zero if the cap
a1e0: 61 62 69 6c 69 74 69 65 73 20 61 72 65 20 70 72  abilities are pr
a1f0: 65 73 65 6e 74 3b 20 7a 65 72 6f 20 6f 74 68 65  esent; zero othe
a200: 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63 20 63 61  rwise..#.proc ca
a210: 70 61 62 6c 65 20 7b 65 78 70 72 7d 20 7b 0a 20  pable {expr} {. 
a220: 20 73 65 74 20 65 20 5b 66 69 78 5f 69 66 63 61   set e [fix_ifca
a230: 70 61 62 6c 65 5f 65 78 70 72 20 24 65 78 70 72  pable_expr $expr
a240: 5d 3b 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20  ]; return [expr 
a250: 28 24 65 29 5d 0a 7d 0a 0a 23 20 45 76 61 6c 75  ($e)].}..# Evalu
a260: 61 74 65 20 61 20 62 6f 6f 6c 65 61 6e 20 65 78  ate a boolean ex
a270: 70 72 65 73 73 69 6f 6e 20 6f 66 20 63 61 70 61  pression of capa
a280: 62 69 6c 69 74 69 65 73 2e 20 20 49 66 20 74 72  bilities.  If tr
a290: 75 65 2c 20 65 78 65 63 75 74 65 20 74 68 65 0a  ue, execute the.
a2a0: 23 20 63 6f 64 65 2e 20 20 4f 6d 69 74 20 74 68  # code.  Omit th
a2b0: 65 20 63 6f 64 65 20 69 66 20 66 61 6c 73 65 2e  e code if false.
a2c0: 0a 23 0a 70 72 6f 63 20 69 66 63 61 70 61 62 6c  .#.proc ifcapabl
a2d0: 65 20 7b 65 78 70 72 20 63 6f 64 65 20 7b 65 6c  e {expr code {el
a2e0: 73 65 20 22 22 7d 20 7b 65 6c 73 65 63 6f 64 65  se ""} {elsecode
a2f0: 20 22 22 7d 7d 20 7b 0a 20 20 23 72 65 67 73 75   ""}} {.  #regsu
a300: 62 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5f 30 2d 39  b -all {[a-z_0-9
a310: 5d 2b 7d 20 24 65 78 70 72 20 7b 24 3a 3a 73 71  ]+} $expr {$::sq
a320: 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 26 29 7d  lite_options(&)}
a330: 20 65 32 0a 20 20 73 65 74 20 65 32 20 5b 66 69   e2.  set e2 [fi
a340: 78 5f 69 66 63 61 70 61 62 6c 65 5f 65 78 70 72  x_ifcapable_expr
a350: 20 24 65 78 70 72 5d 0a 20 20 69 66 20 28 24 65   $expr].  if ($e
a360: 32 29 20 7b 0a 20 20 20 20 73 65 74 20 63 20 5b  2) {.    set c [
a370: 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 31  catch {uplevel 1
a380: 20 24 63 6f 64 65 7d 20 72 5d 0a 20 20 7d 20 65   $code} r].  } e
a390: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 63 20  lse {.    set c 
a3a0: 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20  [catch {uplevel 
a3b0: 31 20 24 65 6c 73 65 63 6f 64 65 7d 20 72 5d 0a  1 $elsecode} r].
a3c0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2d 63 6f    }.  return -co
a3d0: 64 65 20 24 63 20 24 72 0a 7d 0a 0a 23 20 54 68  de $c $r.}..# Th
a3e0: 69 73 20 70 72 6f 63 20 65 78 65 63 73 20 61 20  is proc execs a 
a3f0: 73 65 70 65 72 61 74 65 20 70 72 6f 63 65 73 73  seperate process
a400: 20 74 68 61 74 20 63 72 61 73 68 65 73 20 6d 69   that crashes mi
a410: 64 77 61 79 20 74 68 72 6f 75 67 68 20 65 78 65  dway through exe
a420: 63 75 74 69 6e 67 0a 23 20 74 68 65 20 53 51 4c  cuting.# the SQL
a430: 20 73 63 72 69 70 74 20 24 73 71 6c 20 6f 6e 20   script $sql on 
a440: 64 61 74 61 62 61 73 65 20 74 65 73 74 2e 64 62  database test.db
a450: 2e 0a 23 0a 23 20 54 68 65 20 63 72 61 73 68 20  ..#.# The crash 
a460: 6f 63 63 75 72 73 20 64 75 72 69 6e 67 20 61 20  occurs during a 
a470: 73 79 6e 63 28 29 20 6f 66 20 66 69 6c 65 20 24  sync() of file $
a480: 63 72 61 73 68 66 69 6c 65 2e 20 57 68 65 6e 20  crashfile. When 
a490: 74 68 65 20 63 72 61 73 68 0a 23 20 6f 63 63 75  the crash.# occu
a4a0: 72 73 20 61 20 72 61 6e 64 6f 6d 20 73 75 62 73  rs a random subs
a4b0: 65 74 20 6f 66 20 61 6c 6c 20 75 6e 73 79 6e 63  et of all unsync
a4c0: 65 64 20 77 72 69 74 65 73 20 6d 61 64 65 20 62  ed writes made b
a4d0: 79 20 74 68 65 20 70 72 6f 63 65 73 73 20 61 72  y the process ar
a4e0: 65 0a 23 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  e.# written into
a4f0: 20 74 68 65 20 66 69 6c 65 73 20 6f 6e 20 64 69   the files on di
a500: 73 6b 2e 20 41 72 67 75 6d 65 6e 74 20 24 63 72  sk. Argument $cr
a510: 61 73 68 64 65 6c 61 79 20 69 6e 64 69 63 61 74  ashdelay indicat
a520: 65 73 20 74 68 65 0a 23 20 6e 75 6d 62 65 72 20  es the.# number 
a530: 6f 66 20 66 69 6c 65 20 73 79 6e 63 73 20 74 6f  of file syncs to
a540: 20 77 61 69 74 20 62 65 66 6f 72 65 20 63 72 61   wait before cra
a550: 73 68 69 6e 67 2e 0a 23 0a 23 20 54 68 65 20 72  shing..#.# The r
a560: 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 61  eturn value is a
a570: 20 6c 69 73 74 20 6f 66 20 74 77 6f 20 65 6c 65   list of two ele
a580: 6d 65 6e 74 73 2e 20 54 68 65 20 66 69 72 73 74  ments. The first
a590: 20 65 6c 65 6d 65 6e 74 20 69 73 20 61 0a 23 20   element is a.# 
a5a0: 62 6f 6f 6c 65 61 6e 2c 20 69 6e 64 69 63 61 74  boolean, indicat
a5b0: 69 6e 67 20 77 68 65 74 68 65 72 20 6f 72 20 6e  ing whether or n
a5c0: 6f 74 20 74 68 65 20 70 72 6f 63 65 73 73 20 61  ot the process a
a5d0: 63 74 75 61 6c 6c 79 20 63 72 61 73 68 65 64 20  ctually crashed 
a5e0: 6f 72 0a 23 20 72 65 70 6f 72 74 65 64 20 73 6f  or.# reported so
a5f0: 6d 65 20 6f 74 68 65 72 20 65 72 72 6f 72 2e 20  me other error. 
a600: 54 68 65 20 73 65 63 6f 6e 64 20 65 6c 65 6d 65  The second eleme
a610: 6e 74 20 69 6e 20 74 68 65 20 72 65 74 75 72 6e  nt in the return
a620: 65 64 20 6c 69 73 74 20 69 73 20 74 68 65 0a 23  ed list is the.#
a630: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e 20   error message. 
a640: 54 68 69 73 20 69 73 20 22 63 68 69 6c 64 20 70  This is "child p
a650: 72 6f 63 65 73 73 20 65 78 69 74 65 64 20 61 62  rocess exited ab
a660: 6e 6f 72 6d 61 6c 6c 79 22 20 69 66 20 74 68 65  normally" if the
a670: 20 63 72 61 73 68 0a 23 20 6f 63 63 75 72 72 65   crash.# occurre
a680: 64 2e 0a 23 0a 23 20 20 20 63 72 61 73 68 73 71  d..#.#   crashsq
a690: 6c 20 2d 64 65 6c 61 79 20 43 52 41 53 48 44 45  l -delay CRASHDE
a6a0: 4c 41 59 20 2d 66 69 6c 65 20 43 52 41 53 48 46  LAY -file CRASHF
a6b0: 49 4c 45 20 3f 2d 62 6c 6f 63 6b 73 69 7a 65 20  ILE ?-blocksize 
a6c0: 42 4c 4f 43 4b 53 49 5a 45 3f 20 24 73 71 6c 0a  BLOCKSIZE? $sql.
a6d0: 23 0a 70 72 6f 63 20 63 72 61 73 68 73 71 6c 20  #.proc crashsql 
a6e0: 7b 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20  {args} {..  set 
a6f0: 62 6c 6f 63 6b 73 69 7a 65 20 22 22 0a 20 20 73  blocksize "".  s
a700: 65 74 20 63 72 61 73 68 64 65 6c 61 79 20 31 0a  et crashdelay 1.
a710: 20 20 73 65 74 20 70 72 6e 67 73 65 65 64 20 30    set prngseed 0
a720: 0a 20 20 73 65 74 20 6f 70 65 6e 64 62 20 7b 20  .  set opendb { 
a730: 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e  sqlite3 db test.
a740: 64 62 20 2d 76 66 73 20 63 72 61 73 68 20 7d 0a  db -vfs crash }.
a750: 20 20 73 65 74 20 74 63 6c 62 6f 64 79 20 7b 7d    set tclbody {}
a760: 0a 20 20 73 65 74 20 63 72 61 73 68 66 69 6c 65  .  set crashfile
a770: 20 22 22 0a 20 20 73 65 74 20 64 63 20 22 22 0a   "".  set dc "".
a780: 20 20 73 65 74 20 73 71 6c 20 5b 6c 69 6e 64 65    set sql [linde
a790: 78 20 24 61 72 67 73 20 65 6e 64 5d 0a 0a 20 20  x $args end]..  
a7a0: 66 6f 72 20 7b 73 65 74 20 69 69 20 30 7d 20 7b  for {set ii 0} {
a7b0: 24 69 69 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24  $ii < [llength $
a7c0: 61 72 67 73 5d 2d 31 7d 20 7b 69 6e 63 72 20 69  args]-1} {incr i
a7d0: 69 20 32 7d 20 7b 0a 20 20 20 20 73 65 74 20 7a  i 2} {.    set z
a7e0: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 24   [lindex $args $
a7f0: 69 69 5d 0a 20 20 20 20 73 65 74 20 6e 20 5b 73  ii].    set n [s
a800: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 7a 5d  tring length $z]
a810: 0a 20 20 20 20 73 65 74 20 7a 32 20 5b 6c 69 6e  .    set z2 [lin
a820: 64 65 78 20 24 61 72 67 73 20 5b 65 78 70 72 20  dex $args [expr 
a830: 24 69 69 2b 31 5d 5d 0a 0a 20 20 20 20 69 66 20  $ii+1]]..    if 
a840: 20 20 20 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74      {$n>1 && [st
a850: 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 64  ring first $z -d
a860: 65 6c 61 79 5d 3d 3d 30 7d 20 20 20 20 20 7b 73  elay]==0}     {s
a870: 65 74 20 63 72 61 73 68 64 65 6c 61 79 20 24 7a  et crashdelay $z
a880: 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20  2} \.    elseif 
a890: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
a8a0: 20 66 69 72 73 74 20 24 7a 20 2d 6f 70 65 6e 64   first $z -opend
a8b0: 62 5d 3d 3d 30 7d 20 20 20 20 7b 73 65 74 20 6f  b]==0}    {set o
a8c0: 70 65 6e 64 62 20 24 7a 32 7d 20 5c 0a 20 20 20  pendb $z2} \.   
a8d0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
a8e0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
a8f0: 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20 20 20  z -seed]==0}    
a900: 20 20 7b 73 65 74 20 70 72 6e 67 73 65 65 64 20    {set prngseed 
a910: 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69  $z2} \.    elsei
a920: 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69  f {$n>1 && [stri
a930: 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66 69 6c  ng first $z -fil
a940: 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65 74  e]==0}      {set
a950: 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32 7d 20   crashfile $z2} 
a960: 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24   \.    elseif {$
a970: 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66  n>1 && [string f
a980: 69 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f 64 79  irst $z -tclbody
a990: 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74 63 6c  ]==0}   {set tcl
a9a0: 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20 20 20  body $z2}  \.   
a9b0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
a9c0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
a9d0: 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30  z -blocksize]==0
a9e0: 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  } {set blocksize
a9f0: 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a 20 20   "-s $z2" } \.  
aa00: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
aa10: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
aa20: 24 7a 20 2d 63 68 61 72 61 63 74 65 72 69 73 74  $z -characterist
aa30: 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 63  ics]==0} {set dc
aa40: 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 20 5c 0a   "-c {$z2}" } \.
aa50: 20 20 20 20 65 6c 73 65 20 20 20 7b 20 65 72 72      else   { err
aa60: 6f 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a 65 64  or "Unrecognized
aa70: 20 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a 20   option: $z" }. 
aa80: 20 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61 73 68   }..  if {$crash
aa90: 66 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a 20 20  file eq ""} {.  
aaa0: 20 20 65 72 72 6f 72 20 22 43 6f 6d 70 75 6c 73    error "Compuls
aab0: 6f 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69 6c 65  ory option -file
aac0: 20 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a 0a 20   missing".  }.. 
aad0: 20 23 20 24 63 72 61 73 68 66 69 6c 65 20 67 65   # $crashfile ge
aae0: 74 73 20 63 6f 6d 70 61 72 65 64 20 74 6f 20 74  ts compared to t
aaf0: 68 65 20 6e 61 74 69 76 65 20 66 69 6c 65 6e 61  he native filena
ab00: 6d 65 20 69 6e 0a 20 20 23 20 63 66 53 79 6e 63  me in.  # cfSync
ab10: 28 29 2c 20 77 68 69 63 68 20 63 61 6e 20 62 65  (), which can be
ab20: 20 64 69 66 66 65 72 65 6e 74 20 74 68 65 6e 20   different then 
ab30: 77 68 61 74 20 54 43 4c 20 75 73 65 73 20 62 79  what TCL uses by
ab40: 0a 20 20 23 20 64 65 66 61 75 6c 74 2c 20 73 6f  .  # default, so
ab50: 20 68 65 72 65 20 77 65 20 66 6f 72 63 65 20 69   here we force i
ab60: 74 20 74 6f 20 74 68 65 20 22 6e 61 74 69 76 65  t to the "native
ab70: 6e 61 6d 65 22 20 66 6f 72 6d 61 74 2e 0a 20 20  name" format..  
ab80: 73 65 74 20 63 66 69 6c 65 20 5b 73 74 72 69 6e  set cfile [strin
ab90: 67 20 6d 61 70 20 7b 5c 5c 20 5c 5c 5c 5c 7d 20  g map {\\ \\\\} 
aba0: 5b 66 69 6c 65 20 6e 61 74 69 76 65 6e 61 6d 65  [file nativename
abb0: 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b 67 65 74   [file join [get
abc0: 5f 70 77 64 5d 20 24 63 72 61 73 68 66 69 6c 65  _pwd] $crashfile
abd0: 5d 5d 5d 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70  ]]]..  set f [op
abe0: 65 6e 20 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a  en crash.tcl w].
abf0: 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74    puts $f "sqlit
ac00: 65 33 5f 63 72 61 73 68 5f 65 6e 61 62 6c 65 20  e3_crash_enable 
ac10: 31 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 71  1".  puts $f "sq
ac20: 6c 69 74 65 33 5f 63 72 61 73 68 70 61 72 61 6d  lite3_crashparam
ac30: 73 20 24 62 6c 6f 63 6b 73 69 7a 65 20 24 64 63  s $blocksize $dc
ac40: 20 24 63 72 61 73 68 64 65 6c 61 79 20 24 63 66   $crashdelay $cf
ac50: 69 6c 65 22 0a 20 20 70 75 74 73 20 24 66 20 22  ile".  puts $f "
ac60: 73 71 6c 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e  sqlite3_test_con
ac70: 74 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74  trol_pending_byt
ac80: 65 20 24 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64  e $::sqlite_pend
ac90: 69 6e 67 5f 62 79 74 65 22 0a 0a 20 20 23 20 54  ing_byte"..  # T
aca0: 68 69 73 20 62 6c 6f 63 6b 20 73 65 74 73 20 74  his block sets t
acb0: 68 65 20 63 61 63 68 65 20 73 69 7a 65 20 6f 66  he cache size of
acc0: 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61   the main databa
acd0: 73 65 20 74 6f 20 31 30 0a 20 20 23 20 70 61 67  se to 10.  # pag
ace0: 65 73 2e 20 54 68 69 73 20 69 73 20 64 6f 6e 65  es. This is done
acf0: 20 69 6e 20 63 61 73 65 20 74 68 65 20 62 75 69   in case the bui
ad00: 6c 64 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64  ld is configured
ad10: 20 74 6f 20 6f 6d 69 74 0a 20 20 23 20 22 50 52   to omit.  # "PR
ad20: 41 47 4d 41 20 63 61 63 68 65 5f 73 69 7a 65 22  AGMA cache_size"
ad30: 2e 0a 20 20 69 66 20 7b 24 6f 70 65 6e 64 62 21  ..  if {$opendb!
ad40: 3d 22 22 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  =""} {.    puts 
ad50: 24 66 20 24 6f 70 65 6e 64 62 20 0a 20 20 20 20  $f $opendb .    
ad60: 70 75 74 73 20 24 66 20 7b 64 62 20 65 76 61 6c  puts $f {db eval
ad70: 20 7b 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   {SELECT * FROM 
ad80: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 7d 7d  sqlite_master;}}
ad90: 0a 20 20 20 20 70 75 74 73 20 24 66 20 7b 73 65  .    puts $f {se
ada0: 74 20 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d  t bt [btree_from
adb0: 5f 64 62 20 64 62 5d 7d 0a 20 20 20 20 70 75 74  _db db]}.    put
adc0: 73 20 24 66 20 7b 62 74 72 65 65 5f 73 65 74 5f  s $f {btree_set_
add0: 63 61 63 68 65 5f 73 69 7a 65 20 24 62 74 20 31  cache_size $bt 1
ade0: 30 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24 70  0}.  }..  if {$p
adf0: 72 6e 67 73 65 65 64 7d 20 7b 0a 20 20 20 20 73  rngseed} {.    s
ae00: 65 74 20 73 65 65 64 20 5b 65 78 70 72 20 7b 24  et seed [expr {$
ae10: 70 72 6e 67 73 65 65 64 25 31 30 30 30 37 2b 31  prngseed%10007+1
ae20: 7d 5d 0a 20 20 20 20 23 20 70 75 74 73 20 73 65  }].    # puts se
ae30: 65 64 3d 24 73 65 65 64 0a 20 20 20 20 70 75 74  ed=$seed.    put
ae40: 73 20 24 66 20 22 64 62 20 65 76 61 6c 20 7b 53  s $f "db eval {S
ae50: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
ae60: 28 24 73 65 65 64 29 7d 22 0a 20 20 7d 0a 0a 20  ($seed)}".  }.. 
ae70: 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e   if {[string len
ae80: 67 74 68 20 24 74 63 6c 62 6f 64 79 5d 3e 30 7d  gth $tclbody]>0}
ae90: 20 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20 24   {.    puts $f $
aea0: 74 63 6c 62 6f 64 79 0a 20 20 7d 0a 20 20 69 66  tclbody.  }.  if
aeb0: 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68   {[string length
aec0: 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20   $sql]>0} {.    
aed0: 70 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c  puts $f "db eval
aee0: 20 7b 22 0a 20 20 20 20 70 75 74 73 20 24 66 20   {".    puts $f 
aef0: 20 20 22 24 73 71 6c 22 0a 20 20 20 20 70 75 74    "$sql".    put
af00: 73 20 24 66 20 22 7d 22 0a 20 20 7d 0a 20 20 63  s $f "}".  }.  c
af10: 6c 6f 73 65 20 24 66 0a 20 20 73 65 74 20 72 20  lose $f.  set r 
af20: 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 65 78 65  [catch {.    exe
af30: 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78  c [info nameofex
af40: 65 63 5d 20 63 72 61 73 68 2e 74 63 6c 20 3e 40  ec] crash.tcl >@
af50: 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67 5d 0a  stdout.  } msg].
af60: 0a 20 20 23 20 57 69 6e 64 6f 77 73 2f 41 63 74  .  # Windows/Act
af70: 69 76 65 53 74 61 74 65 20 54 43 4c 20 72 65 74  iveState TCL ret
af80: 75 72 6e 73 20 61 20 73 6c 69 67 68 74 6c 79 20  urns a slightly 
af90: 64 69 66 66 65 72 65 6e 74 0a 20 20 23 20 65 72  different.  # er
afa0: 72 6f 72 20 6d 65 73 73 61 67 65 2e 20 20 57 65  ror message.  We
afb0: 20 6d 61 70 20 74 68 61 74 20 74 6f 20 74 68 65   map that to the
afc0: 20 65 78 70 65 63 74 65 64 20 6d 65 73 73 61 67   expected messag
afd0: 65 0a 20 20 23 20 73 6f 20 74 68 61 74 20 77 65  e.  # so that we
afe0: 20 64 6f 6e 27 74 20 68 61 76 65 20 74 6f 20 63   don't have to c
aff0: 68 61 6e 67 65 20 61 6c 6c 20 6f 66 20 74 68 65  hange all of the
b000: 20 74 65 73 74 0a 20 20 23 20 63 61 73 65 73 2e   test.  # cases.
b010: 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c  .  if {$::tcl_pl
b020: 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29  atform(platform)
b030: 3d 3d 22 77 69 6e 64 6f 77 73 22 7d 20 7b 0a 20  =="windows"} {. 
b040: 20 20 20 69 66 20 7b 24 6d 73 67 3d 3d 22 63 68     if {$msg=="ch
b050: 69 6c 64 20 6b 69 6c 6c 65 64 3a 20 75 6e 6b 6e  ild killed: unkn
b060: 6f 77 6e 20 73 69 67 6e 61 6c 22 7d 20 7b 0a 20  own signal"} {. 
b070: 20 20 20 20 20 73 65 74 20 6d 73 67 20 22 63 68       set msg "ch
b080: 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78 69 74  ild process exit
b090: 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 0a 20  ed abnormally". 
b0a0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 6c 61 70 70     }.  }..  lapp
b0b0: 65 6e 64 20 72 20 24 6d 73 67 0a 7d 0a 0a 70 72  end r $msg.}..pr
b0c0: 6f 63 20 72 75 6e 5f 69 6f 65 72 72 5f 70 72 65  oc run_ioerr_pre
b0d0: 70 20 7b 7d 20 7b 0a 20 20 73 65 74 20 3a 3a 73  p {} {.  set ::s
b0e0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
b0f0: 65 6e 64 69 6e 67 20 30 0a 20 20 63 61 74 63 68  ending 0.  catch
b100: 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61   {db close}.  ca
b110: 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a  tch {db2 close}.
b120: 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65    catch {forcede
b130: 6c 65 74 65 20 74 65 73 74 2e 64 62 7d 0a 20 20  lete test.db}.  
b140: 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65  catch {forcedele
b150: 74 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e  te test.db-journ
b160: 61 6c 7d 0a 20 20 63 61 74 63 68 20 7b 66 6f 72  al}.  catch {for
b170: 63 65 64 65 6c 65 74 65 20 74 65 73 74 32 2e 64  cedelete test2.d
b180: 62 7d 0a 20 20 63 61 74 63 68 20 7b 66 6f 72 63  b}.  catch {forc
b190: 65 64 65 6c 65 74 65 20 74 65 73 74 32 2e 64 62  edelete test2.db
b1a0: 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 73 65 74 20  -journal}.  set 
b1b0: 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 20 64 62  ::DB [sqlite3 db
b1c0: 20 74 65 73 74 2e 64 62 3b 20 73 71 6c 69 74 65   test.db; sqlite
b1d0: 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69  3_connection_poi
b1e0: 6e 74 65 72 20 64 62 5d 0a 20 20 73 71 6c 69 74  nter db].  sqlit
b1f0: 65 33 5f 65 78 74 65 6e 64 65 64 5f 72 65 73 75  e3_extended_resu
b200: 6c 74 5f 63 6f 64 65 73 20 24 3a 3a 44 42 20 24  lt_codes $::DB $
b210: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63  ::ioerropts(-erc
b220: 29 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  ).  if {[info ex
b230: 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73  ists ::ioerropts
b240: 28 2d 74 63 6c 70 72 65 70 29 5d 7d 20 7b 0a 20  (-tclprep)]} {. 
b250: 20 20 20 65 76 61 6c 20 24 3a 3a 69 6f 65 72 72     eval $::ioerr
b260: 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29 0a 20  opts(-tclprep). 
b270: 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65   }.  if {[info e
b280: 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74  xists ::ioerropt
b290: 73 28 2d 73 71 6c 70 72 65 70 29 5d 7d 20 7b 0a  s(-sqlprep)]} {.
b2a0: 20 20 20 20 65 78 65 63 73 71 6c 20 24 3a 3a 69      execsql $::i
b2b0: 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 70 72 65  oerropts(-sqlpre
b2c0: 70 29 0a 20 20 7d 0a 20 20 65 78 70 72 20 30 0a  p).  }.  expr 0.
b2d0: 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64 6f 5f 69  }..# Usage: do_i
b2e0: 6f 65 72 72 5f 74 65 73 74 20 3c 74 65 73 74 20  oerr_test <test 
b2f0: 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69 6f 6e 73  number> <options
b300: 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73 20 70 72  ...>.#.# This pr
b310: 6f 63 20 69 73 20 75 73 65 64 20 74 6f 20 69 6d  oc is used to im
b320: 70 6c 65 6d 65 6e 74 20 74 65 73 74 20 63 61 73  plement test cas
b330: 65 73 20 74 68 61 74 20 63 68 65 63 6b 20 74 68  es that check th
b340: 61 74 20 49 4f 20 65 72 72 6f 72 73 0a 23 20 61  at IO errors.# a
b350: 72 65 20 63 6f 72 72 65 63 74 6c 79 20 68 61 6e  re correctly han
b360: 64 6c 65 64 2e 20 54 68 65 20 66 69 72 73 74 20  dled. The first 
b370: 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65 73 74 20  argument, <test 
b380: 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61 6e 20 69  number>, is an i
b390: 6e 74 65 67 65 72 0a 23 20 75 73 65 64 20 74 6f  nteger.# used to
b3a0: 20 6e 61 6d 65 20 74 68 65 20 74 65 73 74 73 20   name the tests 
b3b0: 65 78 65 63 75 74 65 64 20 62 79 20 74 68 69 73  executed by this
b3c0: 20 70 72 6f 63 2e 20 4f 70 74 69 6f 6e 73 20 61   proc. Options a
b3d0: 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23  re as follows:.#
b3e0: 0a 23 20 20 20 20 20 2d 74 63 6c 70 72 65 70 20  .#     -tclprep 
b3f0: 20 20 20 20 20 20 20 20 20 54 43 4c 20 73 63 72           TCL scr
b400: 69 70 74 20 74 6f 20 72 75 6e 20 74 6f 20 70 72  ipt to run to pr
b410: 65 70 61 72 65 20 74 65 73 74 2e 0a 23 20 20 20  epare test..#   
b420: 20 20 2d 73 71 6c 70 72 65 70 20 20 20 20 20 20    -sqlprep      
b430: 20 20 20 20 53 51 4c 20 73 63 72 69 70 74 20 74      SQL script t
b440: 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61 72 65  o run to prepare
b450: 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 74 63   test..#     -tc
b460: 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20 20 54  lbody          T
b470: 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e  CL script to run
b480: 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20 73   with IO error s
b490: 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20  imulation..#    
b4a0: 20 2d 73 71 6c 62 6f 64 79 20 20 20 20 20 20 20   -sqlbody       
b4b0: 20 20 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f     TCL script to
b4c0: 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72   run with IO err
b4d0: 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23  or simulation..#
b4e0: 20 20 20 20 20 2d 65 78 63 6c 75 64 65 20 20 20       -exclude   
b4f0: 20 20 20 20 20 20 20 4c 69 73 74 20 6f 66 20 27         List of '
b500: 4e 27 20 76 61 6c 75 65 73 20 6e 6f 74 20 74 6f  N' values not to
b510: 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 65 72   test..#     -er
b520: 63 20 20 20 20 20 20 20 20 20 20 20 20 20 20 55  c              U
b530: 73 65 20 65 78 74 65 6e 64 65 64 20 72 65 73 75  se extended resu
b540: 6c 74 20 63 6f 64 65 73 0a 23 20 20 20 20 20 2d  lt codes.#     -
b550: 70 65 72 73 69 73 74 20 20 20 20 20 20 20 20 20  persist         
b560: 20 4d 61 6b 65 20 73 69 6d 75 6c 61 74 65 64 20   Make simulated 
b570: 49 2f 4f 20 65 72 72 6f 72 73 20 70 65 72 73 69  I/O errors persi
b580: 73 74 65 6e 74 0a 23 20 20 20 20 20 2d 73 74 61  stent.#     -sta
b590: 72 74 20 20 20 20 20 20 20 20 20 20 20 20 56 61  rt            Va
b5a0: 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f 20 62 65  lue of 'N' to be
b5b0: 67 69 6e 20 77 69 74 68 20 28 64 65 66 61 75 6c  gin with (defaul
b5c0: 74 20 31 29 0a 23 0a 23 20 20 20 20 20 2d 63 6b  t 1).#.#     -ck
b5d0: 73 75 6d 20 20 20 20 20 20 20 20 20 20 20 20 42  sum            B
b5e0: 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72 75 65 2c  oolean. If true,
b5f0: 20 74 65 73 74 20 74 68 61 74 20 74 68 65 20 64   test that the d
b600: 61 74 61 62 61 73 65 20 64 6f 65 73 0a 23 20 20  atabase does.#  
b610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b620: 20 20 20 20 20 6e 6f 74 20 63 68 61 6e 67 65 20       not change 
b630: 64 75 72 69 6e 67 20 74 68 65 20 65 78 65 63 75  during the execu
b640: 74 69 6f 6e 20 6f 66 20 74 68 65 20 74 65 73 74  tion of the test
b650: 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63 20 64 6f   case..#.proc do
b660: 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b 74 65 73  _ioerr_test {tes
b670: 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b 0a 0a 20  tname args} {.. 
b680: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
b690: 28 2d 73 74 61 72 74 29 20 31 0a 20 20 73 65 74  (-start) 1.  set
b6a0: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b   ::ioerropts(-ck
b6b0: 73 75 6d 29 20 30 0a 20 20 73 65 74 20 3a 3a 69  sum) 0.  set ::i
b6c0: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 20 30  oerropts(-erc) 0
b6d0: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
b6e0: 74 73 28 2d 63 6f 75 6e 74 29 20 31 30 30 30 30  ts(-count) 10000
b6f0: 30 30 30 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65  0000.  set ::ioe
b700: 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74 29  rropts(-persist)
b710: 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   1.  set ::ioerr
b720: 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74  opts(-ckrefcount
b730: 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  ) 0.  set ::ioer
b740: 72 6f 70 74 73 28 2d 72 65 73 74 6f 72 65 70 72  ropts(-restorepr
b750: 6e 67 29 20 31 0a 20 20 61 72 72 61 79 20 73 65  ng) 1.  array se
b760: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 20 24 61  t ::ioerropts $a
b770: 72 67 73 0a 0a 20 20 23 20 54 45 4d 50 4f 52 41  rgs..  # TEMPORA
b780: 52 59 3a 20 46 6f 72 20 33 2e 35 2e 39 2c 20 64  RY: For 3.5.9, d
b790: 69 73 61 62 6c 65 20 74 65 73 74 69 6e 67 20 6f  isable testing o
b7a0: 66 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c  f extended resul
b7b0: 74 20 63 6f 64 65 73 2e 20 54 68 65 72 65 20 61  t codes. There a
b7c0: 72 65 0a 20 20 23 20 61 20 63 6f 75 70 6c 65 20  re.  # a couple 
b7d0: 6f 66 20 6f 62 73 63 75 72 65 20 49 4f 20 65 72  of obscure IO er
b7e0: 72 6f 72 73 20 74 68 61 74 20 64 6f 20 6e 6f 74  rors that do not
b7f0: 20 72 65 74 75 72 6e 20 74 68 65 6d 2e 0a 20 20   return them..  
b800: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  set ::ioerropts(
b810: 2d 65 72 63 29 20 30 0a 0a 20 20 23 20 43 72 65  -erc) 0..  # Cre
b820: 61 74 65 20 61 20 73 69 6e 67 6c 65 20 54 43 4c  ate a single TCL
b830: 20 73 63 72 69 70 74 20 66 72 6f 6d 20 74 68 65   script from the
b840: 20 54 43 4c 20 61 6e 64 20 53 51 4c 20 73 70 65   TCL and SQL spe
b850: 63 69 66 69 65 64 0a 20 20 23 20 61 73 20 74 68  cified.  # as th
b860: 65 20 62 6f 64 79 20 6f 66 20 74 68 65 20 74 65  e body of the te
b870: 73 74 2e 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  st..  set ::ioer
b880: 72 6f 72 62 6f 64 79 20 7b 7d 0a 20 20 69 66 20  rorbody {}.  if 
b890: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
b8a0: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f  ioerropts(-tclbo
b8b0: 64 79 29 5d 7d 20 7b 0a 20 20 20 20 61 70 70 65  dy)]} {.    appe
b8c0: 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  nd ::ioerrorbody
b8d0: 20 22 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   "$::ioerropts(-
b8e0: 74 63 6c 62 6f 64 79 29 5c 6e 22 0a 20 20 7d 0a  tclbody)\n".  }.
b8f0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
b900: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
b910: 73 71 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20  sqlbody)]} {.   
b920: 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f   append ::ioerro
b930: 72 62 6f 64 79 20 22 64 62 20 65 76 61 6c 20 7b  rbody "db eval {
b940: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71  $::ioerropts(-sq
b950: 6c 62 6f 64 79 29 7d 22 0a 20 20 7d 0a 0a 20 20  lbody)}".  }..  
b960: 73 61 76 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a  save_prng_state.
b970: 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70    if {$::ioerrop
b980: 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20  ts(-cksum)} {.  
b990: 20 20 72 75 6e 5f 69 6f 65 72 72 5f 70 72 65 70    run_ioerr_prep
b9a0: 0a 20 20 20 20 65 76 61 6c 20 24 3a 3a 69 6f 65  .    eval $::ioe
b9b0: 72 72 6f 72 62 6f 64 79 0a 20 20 20 20 73 65 74  rrorbody.    set
b9c0: 20 3a 3a 67 6f 6f 64 63 6b 73 75 6d 20 5b 63 6b   ::goodcksum [ck
b9d0: 73 75 6d 5d 0a 20 20 7d 0a 0a 20 20 73 65 74 20  sum].  }..  set 
b9e0: 3a 3a 67 6f 20 31 0a 20 20 23 72 65 73 65 74 5f  ::go 1.  #reset_
b9f0: 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 66 6f 72  prng_state.  for
ba00: 20 7b 73 65 74 20 6e 20 24 3a 3a 69 6f 65 72 72   {set n $::ioerr
ba10: 6f 70 74 73 28 2d 73 74 61 72 74 29 7d 20 7b 24  opts(-start)} {$
ba20: 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20 6e 7d 20 7b  ::go} {incr n} {
ba30: 0a 20 20 20 20 73 65 74 20 3a 3a 54 4e 20 24 6e  .    set ::TN $n
ba40: 0a 20 20 20 20 69 6e 63 72 20 3a 3a 69 6f 65 72  .    incr ::ioer
ba50: 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20 2d 31  ropts(-count) -1
ba60: 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72  .    if {$::ioer
ba70: 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 3c 30 7d  ropts(-count)<0}
ba80: 20 62 72 65 61 6b 0a 0a 20 20 20 20 23 20 53 6b   break..    # Sk
ba90: 69 70 20 74 68 69 73 20 49 4f 20 65 72 72 6f 72  ip this IO error
baa0: 20 69 66 20 69 74 20 77 61 73 20 73 70 65 63 69   if it was speci
bab0: 66 69 65 64 20 77 69 74 68 20 74 68 65 20 22 2d  fied with the "-
bac0: 65 78 63 6c 75 64 65 22 20 6f 70 74 69 6f 6e 2e  exclude" option.
bad0: 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65  .    if {[info e
bae0: 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74  xists ::ioerropt
baf0: 73 28 2d 65 78 63 6c 75 64 65 29 5d 7d 20 7b 0a  s(-exclude)]} {.
bb00: 20 20 20 20 20 20 69 66 20 7b 5b 6c 73 65 61 72        if {[lsear
bb10: 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  ch $::ioerropts(
bb20: 2d 65 78 63 6c 75 64 65 29 20 24 6e 5d 21 3d 2d  -exclude) $n]!=-
bb30: 31 7d 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20  1} continue.    
bb40: 7d 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65  }.    if {$::ioe
bb50: 72 72 6f 70 74 73 28 2d 72 65 73 74 6f 72 65 70  rropts(-restorep
bb60: 72 6e 67 29 7d 20 7b 0a 20 20 20 20 20 20 72 65  rng)} {.      re
bb70: 73 74 6f 72 65 5f 70 72 6e 67 5f 73 74 61 74 65  store_prng_state
bb80: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 44 65  .    }..    # De
bb90: 6c 65 74 65 20 74 68 65 20 66 69 6c 65 73 20 74  lete the files t
bba0: 65 73 74 2e 64 62 20 61 6e 64 20 74 65 73 74 32  est.db and test2
bbb0: 2e 64 62 2c 20 74 68 65 6e 20 65 78 65 63 75 74  .db, then execut
bbc0: 65 20 74 68 65 20 54 43 4c 20 61 6e 64 0a 20 20  e the TCL and.  
bbd0: 20 20 23 20 53 51 4c 20 28 69 6e 20 74 68 61 74    # SQL (in that
bbe0: 20 6f 72 64 65 72 29 20 74 6f 20 70 72 65 70 61   order) to prepa
bbf0: 72 65 20 66 6f 72 20 74 68 65 20 74 65 73 74 20  re for the test 
bc00: 63 61 73 65 2e 0a 20 20 20 20 64 6f 5f 74 65 73  case..    do_tes
bc10: 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 31  t $testname.$n.1
bc20: 20 7b 0a 20 20 20 20 20 20 72 75 6e 5f 69 6f 65   {.      run_ioe
bc30: 72 72 5f 70 72 65 70 0a 20 20 20 20 7d 20 7b 30  rr_prep.    } {0
bc40: 7d 0a 0a 20 20 20 20 23 20 52 65 61 64 20 74 68  }..    # Read th
bc50: 65 20 27 63 68 65 63 6b 73 75 6d 27 20 6f 66 20  e 'checksum' of 
bc60: 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 20 20  the database..  
bc70: 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70    if {$::ioerrop
bc80: 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20  ts(-cksum)} {.  
bc90: 20 20 20 20 73 65 74 20 3a 3a 63 68 65 63 6b 73      set ::checks
bca0: 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 20 20 7d  um [cksum].    }
bcb0: 0a 0a 20 20 20 20 23 20 53 65 74 20 74 68 65 20  ..    # Set the 
bcc0: 4e 74 68 20 49 4f 20 65 72 72 6f 72 20 74 6f 20  Nth IO error to 
bcd0: 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73  fail..    do_tes
bce0: 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 32  t $testname.$n.2
bcf0: 20 5b 73 75 62 73 74 20 7b 0a 20 20 20 20 20 20   [subst {.      
bd00: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
bd10: 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20 24 3a  error_persist $:
bd20: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70 65 72 73  :ioerropts(-pers
bd30: 69 73 74 29 0a 20 20 20 20 20 20 73 65 74 20 3a  ist).      set :
bd40: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
bd50: 5f 70 65 6e 64 69 6e 67 20 24 6e 0a 20 20 20 20  _pending $n.    
bd60: 7d 5d 20 24 6e 0a 0a 20 20 20 20 23 20 45 78 65  }] $n..    # Exe
bd70: 63 75 74 65 20 74 68 65 20 54 43 4c 20 73 63 72  cute the TCL scr
bd80: 69 70 74 20 63 72 65 61 74 65 64 20 66 6f 72 20  ipt created for 
bd90: 74 68 65 20 62 6f 64 79 20 6f 66 20 74 68 69 73  the body of this
bda0: 20 74 65 73 74 2e 20 49 66 0a 20 20 20 20 23 20   test. If.    # 
bdb0: 61 74 20 6c 65 61 73 74 20 4e 20 49 4f 20 6f 70  at least N IO op
bdc0: 65 72 61 74 69 6f 6e 73 20 70 65 72 66 6f 72 6d  erations perform
bdd0: 65 64 20 62 79 20 53 51 4c 69 74 65 20 61 73 20  ed by SQLite as 
bde0: 61 20 72 65 73 75 6c 74 20 6f 66 0a 20 20 20 20  a result of.    
bdf0: 23 20 74 68 65 20 73 63 72 69 70 74 2c 20 74 68  # the script, th
be00: 65 20 4e 74 68 20 77 69 6c 6c 20 66 61 69 6c 2e  e Nth will fail.
be10: 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65  .    do_test $te
be20: 73 74 6e 61 6d 65 2e 24 6e 2e 33 20 7b 0a 20 20  stname.$n.3 {.  
be30: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
be40: 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a  _io_error_hit 0.
be50: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
be60: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64  te_io_error_hard
be70: 68 69 74 20 30 0a 20 20 20 20 20 20 73 65 74 20  hit 0.      set 
be80: 72 20 5b 63 61 74 63 68 20 24 3a 3a 69 6f 65 72  r [catch $::ioer
be90: 72 6f 72 62 6f 64 79 20 6d 73 67 5d 0a 20 20 20  rorbody msg].   
bea0: 20 20 20 73 65 74 20 3a 3a 65 72 72 73 65 65 6e     set ::errseen
beb0: 20 24 72 0a 20 20 20 20 20 20 73 65 74 20 72 63   $r.      set rc
bec0: 20 5b 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64   [sqlite3_errcod
bed0: 65 20 24 3a 3a 44 42 5d 0a 20 20 20 20 20 20 69  e $::DB].      i
bee0: 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  f {$::ioerropts(
bef0: 2d 65 72 63 29 7d 20 7b 0a 20 20 20 20 20 20 20  -erc)} {.       
bf00: 20 23 20 49 66 20 77 65 20 61 72 65 20 69 6e 20   # If we are in 
bf10: 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20  extended result 
bf20: 63 6f 64 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20  code mode, make 
bf30: 73 75 72 65 20 61 6c 6c 20 6f 66 20 74 68 65 0a  sure all of the.
bf40: 20 20 20 20 20 20 20 20 23 20 49 4f 45 52 52 73          # IOERRs
bf50: 20 77 65 20 67 65 74 20 62 61 63 6b 20 72 65 61   we get back rea
bf60: 6c 6c 79 20 64 6f 20 68 61 76 65 20 74 68 65 69  lly do have thei
bf70: 72 20 65 78 74 65 6e 64 65 64 20 63 6f 64 65 20  r extended code 
bf80: 76 61 6c 75 65 73 2e 0a 20 20 20 20 20 20 20 20  values..        
bf90: 23 20 49 66 20 61 6e 20 65 78 74 65 6e 64 65 64  # If an extended
bfa0: 20 72 65 73 75 6c 74 20 63 6f 64 65 20 69 73 20   result code is 
bfb0: 72 65 74 75 72 6e 65 64 2c 20 74 68 65 20 73 71  returned, the sq
bfc0: 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 0a 20 20  lite3_errcode.  
bfd0: 20 20 20 20 20 20 23 20 54 43 4c 63 6f 6d 6d 61        # TCLcomma
bfe0: 6e 64 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 61  nd will return a
bff0: 20 73 74 72 69 6e 67 20 6f 66 20 74 68 65 20 66   string of the f
c000: 6f 72 6d 3a 20 20 53 51 4c 49 54 45 5f 49 4f 45  orm:  SQLITE_IOE
c010: 52 52 2b 6e 6e 6e 6e 0a 20 20 20 20 20 20 20 20  RR+nnnn.        
c020: 23 20 77 68 65 72 65 20 6e 6e 6e 6e 20 69 73 20  # where nnnn is 
c030: 61 20 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 20  a number.       
c040: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 53   if {[regexp {^S
c050: 51 4c 49 54 45 5f 49 4f 45 52 52 7d 20 24 72 63  QLITE_IOERR} $rc
c060: 5d 20 26 26 20 21 5b 72 65 67 65 78 70 20 7b 49  ] && ![regexp {I
c070: 4f 45 52 52 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20  OERR\+\d} $rc]} 
c080: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75  {.          retu
c090: 72 6e 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d  rn $rc.        }
c0a0: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  .      } else {.
c0b0: 20 20 20 20 20 20 20 20 23 20 49 66 20 77 65 20          # If we 
c0c0: 61 72 65 20 6e 6f 74 20 69 6e 20 65 78 74 65 6e  are not in exten
c0d0: 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20  ded result code 
c0e0: 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20  mode, make sure 
c0f0: 6e 6f 0a 20 20 20 20 20 20 20 20 23 20 65 78 74  no.        # ext
c100: 65 6e 64 65 64 20 65 72 72 6f 72 20 63 6f 64 65  ended error code
c110: 73 20 61 72 65 20 72 65 74 75 72 6e 65 64 2e 0a  s are returned..
c120: 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67          if {[reg
c130: 65 78 70 20 7b 5c 2b 5c 64 7d 20 24 72 63 5d 7d  exp {\+\d} $rc]}
c140: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74   {.          ret
c150: 75 72 6e 20 24 72 63 0a 20 20 20 20 20 20 20 20  urn $rc.        
c160: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
c170: 23 20 54 68 65 20 74 65 73 74 20 72 65 70 65 61  # The test repea
c180: 74 73 20 61 73 20 6c 6f 6e 67 20 61 73 20 24 3a  ts as long as $:
c190: 3a 67 6f 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e  :go is non-zero.
c1a0: 20 20 24 3a 3a 67 6f 20 73 74 61 72 74 73 20 6f    $::go starts o
c1b0: 75 74 0a 20 20 20 20 20 20 23 20 61 73 20 31 2e  ut.      # as 1.
c1c0: 20 20 57 68 65 6e 20 61 20 74 65 73 74 20 72 75    When a test ru
c1d0: 6e 73 20 74 6f 20 63 6f 6d 70 6c 65 74 69 6f 6e  ns to completion
c1e0: 20 77 69 74 68 6f 75 74 20 68 69 74 74 69 6e 67   without hitting
c1f0: 20 61 6e 20 49 2f 4f 0a 20 20 20 20 20 20 23 20   an I/O.      # 
c200: 65 72 72 6f 72 2c 20 74 68 61 74 20 6d 65 61 6e  error, that mean
c210: 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f  s there is no po
c220: 69 6e 74 20 69 6e 20 63 6f 6e 74 69 6e 75 69 6e  int in continuin
c230: 67 20 77 69 74 68 20 74 68 69 73 20 74 65 73 74  g with this test
c240: 0a 20 20 20 20 20 20 23 20 63 61 73 65 20 73 6f  .      # case so
c250: 20 73 65 74 20 24 3a 3a 67 6f 20 74 6f 20 7a 65   set $::go to ze
c260: 72 6f 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20  ro..      #.    
c270: 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74 65 5f    if {$::sqlite_
c280: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
c290: 3e 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  >0} {.        se
c2a0: 74 20 3a 3a 67 6f 20 30 0a 20 20 20 20 20 20 20  t ::go 0.       
c2b0: 20 73 65 74 20 71 20 30 0a 20 20 20 20 20 20 20   set q 0.       
c2c0: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
c2d0: 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30  _error_pending 0
c2e0: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  .      } else {.
c2f0: 20 20 20 20 20 20 20 20 73 65 74 20 71 20 31 0a          set q 1.
c300: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 73        }..      s
c310: 65 74 20 73 20 5b 65 78 70 72 20 24 3a 3a 73 71  et s [expr $::sq
c320: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69  lite_io_error_hi
c330: 74 3d 3d 30 5d 0a 20 20 20 20 20 20 69 66 20 7b  t==0].      if {
c340: 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72  $::sqlite_io_err
c350: 6f 72 5f 68 69 74 3e 24 3a 3a 73 71 6c 69 74 65  or_hit>$::sqlite
c360: 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69  _io_error_hardhi
c370: 74 20 26 26 20 24 72 3d 3d 30 7d 20 7b 0a 20 20  t && $r==0} {.  
c380: 20 20 20 20 20 20 73 65 74 20 72 20 31 0a 20 20        set r 1.  
c390: 20 20 20 20 7d 0a 20 20 20 20 20 20 73 65 74 20      }.      set 
c3a0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
c3b0: 72 5f 68 69 74 20 30 0a 0a 20 20 20 20 20 20 23  r_hit 0..      #
c3c0: 20 4f 6e 65 20 6f 66 20 74 77 6f 20 74 68 69 6e   One of two thin
c3d0: 67 73 20 6d 75 73 74 20 68 61 76 65 20 68 61 70  gs must have hap
c3e0: 70 65 6e 65 64 2e 20 65 69 74 68 65 72 0a 20 20  pened. either.  
c3f0: 20 20 20 20 23 20 20 20 31 2e 20 20 57 65 20 6e      #   1.  We n
c400: 65 76 65 72 20 68 69 74 20 74 68 65 20 49 4f 20  ever hit the IO 
c410: 65 72 72 6f 72 20 61 6e 64 20 74 68 65 20 53 51  error and the SQ
c420: 4c 20 72 65 74 75 72 6e 65 64 20 4f 4b 0a 20 20  L returned OK.  
c430: 20 20 20 20 23 20 20 20 32 2e 20 20 41 6e 20 49      #   2.  An I
c440: 4f 20 65 72 72 6f 72 20 77 61 73 20 68 69 74 20  O error was hit 
c450: 61 6e 64 20 74 68 65 20 53 51 4c 20 66 61 69 6c  and the SQL fail
c460: 65 64 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20  ed.      #.     
c470: 20 23 70 75 74 73 20 22 73 3d 24 73 20 72 3d 24   #puts "s=$s r=$
c480: 72 20 71 3d 24 71 22 0a 20 20 20 20 20 20 65 78  r q=$q".      ex
c490: 70 72 20 7b 20 28 24 73 20 26 26 20 21 24 72 20  pr { ($s && !$r 
c4a0: 26 26 20 21 24 71 29 20 7c 7c 20 28 21 24 73 20  && !$q) || (!$s 
c4b0: 26 26 20 24 72 20 26 26 20 24 71 29 20 7d 0a 20  && $r && $q) }. 
c4c0: 20 20 20 7d 20 7b 31 7d 0a 0a 20 20 20 20 73 65     } {1}..    se
c4d0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
c4e0: 72 6f 72 5f 68 69 74 20 30 0a 20 20 20 20 73 65  ror_hit 0.    se
c4f0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
c500: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 0a 20  ror_pending 0.. 
c510: 20 20 20 23 20 43 68 65 63 6b 20 74 68 61 74 20     # Check that 
c520: 6e 6f 20 70 61 67 65 20 72 65 66 65 72 65 6e 63  no page referenc
c530: 65 73 20 77 65 72 65 20 6c 65 61 6b 65 64 2e 20  es were leaked. 
c540: 54 68 65 72 65 20 73 68 6f 75 6c 64 20 62 65 0a  There should be.
c550: 20 20 20 20 23 20 61 20 73 69 6e 67 6c 65 20 72      # a single r
c560: 65 66 65 72 65 6e 63 65 20 69 66 20 74 68 65 72  eference if ther
c570: 65 20 69 73 20 73 74 69 6c 6c 20 61 6e 20 61 63  e is still an ac
c580: 74 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  tive transaction
c590: 2c 0a 20 20 20 20 23 20 6f 72 20 7a 65 72 6f 20  ,.    # or zero 
c5a0: 6f 74 68 65 72 77 69 73 65 2e 0a 20 20 20 20 23  otherwise..    #
c5b0: 0a 20 20 20 20 23 20 55 50 44 41 54 45 3a 20 49  .    # UPDATE: I
c5c0: 66 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 6f  f the IO error o
c5d0: 63 63 75 72 73 20 61 66 74 65 72 20 61 20 27 42  ccurs after a 'B
c5e0: 45 47 49 4e 27 20 62 75 74 20 62 65 66 6f 72 65  EGIN' but before
c5f0: 20 61 6e 79 0a 20 20 20 20 23 20 6c 6f 63 6b 73   any.    # locks
c600: 20 61 72 65 20 65 73 74 61 62 6c 69 73 68 65 64   are established
c610: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c   on database fil
c620: 65 73 20 28 69 2e 65 2e 20 69 66 20 74 68 65 20  es (i.e. if the 
c630: 65 72 72 6f 72 0a 20 20 20 20 23 20 6f 63 63 75  error.    # occu
c640: 72 73 20 77 68 69 6c 65 20 61 74 74 65 6d 70 74  rs while attempt
c650: 69 6e 67 20 74 6f 20 64 65 74 65 63 74 20 61 20  ing to detect a 
c660: 68 6f 74 2d 6a 6f 75 72 6e 61 6c 20 66 69 6c 65  hot-journal file
c670: 29 2c 20 74 68 65 6e 0a 20 20 20 20 23 20 74 68  ), then.    # th
c680: 65 72 65 20 6d 61 79 20 30 20 70 61 67 65 20 72  ere may 0 page r
c690: 65 66 65 72 65 6e 63 65 73 20 61 6e 64 20 61 6e  eferences and an
c6a0: 20 61 63 74 69 76 65 20 74 72 61 6e 73 61 63 74   active transact
c6b0: 69 6f 6e 20 61 63 63 6f 72 64 69 6e 67 0a 20 20  ion according.  
c6c0: 20 20 23 20 74 6f 20 5b 73 71 6c 69 74 65 33 5f    # to [sqlite3_
c6d0: 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 5d 2e  get_autocommit].
c6e0: 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b 24  .    #.    if {$
c6f0: 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71 6c 69 74  ::go && $::sqlit
c700: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68  e_io_error_hardh
c710: 69 74 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70  it && $::ioerrop
c720: 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29 7d  ts(-ckrefcount)}
c730: 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74   {.      do_test
c740: 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 34 20   $testname.$n.4 
c750: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 62 74  {.        set bt
c760: 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20   [btree_from_db 
c770: 64 62 5d 0a 20 20 20 20 20 20 20 20 64 62 5f 65  db].        db_e
c780: 6e 74 65 72 20 64 62 0a 20 20 20 20 20 20 20 20  nter db.        
c790: 61 72 72 61 79 20 73 65 74 20 73 74 61 74 73 20  array set stats 
c7a0: 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73 74 61  [btree_pager_sta
c7b0: 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20 20 20  ts $bt].        
c7c0: 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20 20 20  db_leave db.    
c7d0: 20 20 20 20 73 65 74 20 6e 52 65 66 20 24 73 74      set nRef $st
c7e0: 61 74 73 28 72 65 66 29 0a 20 20 20 20 20 20 20  ats(ref).       
c7f0: 20 65 78 70 72 20 7b 24 6e 52 65 66 20 3d 3d 20   expr {$nRef == 
c800: 30 20 7c 7c 20 28 5b 73 71 6c 69 74 65 33 5f 67  0 || ([sqlite3_g
c810: 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62  et_autocommit db
c820: 5d 3d 3d 30 20 26 26 20 24 6e 52 65 66 20 3d 3d  ]==0 && $nRef ==
c830: 20 31 29 7d 0a 20 20 20 20 20 20 7d 20 7b 31 7d   1)}.      } {1}
c840: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49 66  .    }..    # If
c850: 20 74 68 65 72 65 20 69 73 20 61 6e 20 6f 70 65   there is an ope
c860: 6e 20 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c  n database handl
c870: 65 20 61 6e 64 20 6e 6f 20 6f 70 65 6e 20 74 72  e and no open tr
c880: 61 6e 73 61 63 74 69 6f 6e 2c 0a 20 20 20 20 23  ansaction,.    #
c890: 20 61 6e 64 20 74 68 65 20 70 61 67 65 72 20 69   and the pager i
c8a0: 73 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20 69 6e  s not running in
c8b0: 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69   exclusive-locki
c8c0: 6e 67 20 6d 6f 64 65 2c 0a 20 20 20 20 23 20 63  ng mode,.    # c
c8d0: 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 70 61  heck that the pa
c8e0: 67 65 72 20 69 73 20 69 6e 20 22 75 6e 6c 6f 63  ger is in "unloc
c8f0: 6b 65 64 22 20 73 74 61 74 65 2e 20 54 68 65 6f  ked" state. Theo
c900: 72 65 74 69 63 61 6c 6c 79 2c 0a 20 20 20 20 23  retically,.    #
c910: 20 69 66 20 61 20 63 61 6c 6c 20 74 6f 20 78 55   if a call to xU
c920: 6e 6c 6f 63 6b 28 29 20 66 61 69 6c 65 64 20 64  nlock() failed d
c930: 75 65 20 74 6f 20 61 6e 20 49 4f 20 65 72 72 6f  ue to an IO erro
c940: 72 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  r the underlying
c950: 0a 20 20 20 20 23 20 66 69 6c 65 20 6d 61 79 20  .    # file may 
c960: 73 74 69 6c 6c 20 62 65 20 6c 6f 63 6b 65 64 2e  still be locked.
c970: 0a 20 20 20 20 23 0a 20 20 20 20 69 66 63 61 70  .    #.    ifcap
c980: 61 62 6c 65 20 70 72 61 67 6d 61 20 7b 0a 20 20  able pragma {.  
c990: 20 20 20 20 69 66 20 7b 20 5b 69 6e 66 6f 20 63      if { [info c
c9a0: 6f 6d 6d 61 6e 64 73 20 64 62 5d 20 6e 65 20 22  ommands db] ne "
c9b0: 22 0a 20 20 20 20 20 20 20 20 26 26 20 24 3a 3a  ".        && $::
c9c0: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72 65 66  ioerropts(-ckref
c9d0: 63 6f 75 6e 74 29 0a 20 20 20 20 20 20 20 20 26  count).        &
c9e0: 26 20 5b 64 62 20 6f 6e 65 20 7b 70 72 61 67 6d  & [db one {pragm
c9f0: 61 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 7d 5d  a locking_mode}]
ca00: 20 65 71 20 22 6e 6f 72 6d 61 6c 22 0a 20 20 20   eq "normal".   
ca10: 20 20 20 20 20 26 26 20 5b 73 71 6c 69 74 65 33       && [sqlite3
ca20: 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20  _get_autocommit 
ca30: 64 62 5d 0a 20 20 20 20 20 20 7d 20 7b 0a 20 20  db].      } {.  
ca40: 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74        do_test $t
ca50: 65 73 74 6e 61 6d 65 2e 24 6e 2e 35 20 7b 0a 20  estname.$n.5 {. 
ca60: 20 20 20 20 20 20 20 20 20 73 65 74 20 62 74 20           set bt 
ca70: 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64  [btree_from_db d
ca80: 62 5d 0a 20 20 20 20 20 20 20 20 20 20 64 62 5f  b].          db_
ca90: 65 6e 74 65 72 20 64 62 0a 20 20 20 20 20 20 20  enter db.       
caa0: 20 20 20 61 72 72 61 79 20 73 65 74 20 73 74 61     array set sta
cab0: 74 73 20 5b 62 74 72 65 65 5f 70 61 67 65 72 5f  ts [btree_pager_
cac0: 73 74 61 74 73 20 24 62 74 5d 0a 20 20 20 20 20  stats $bt].     
cad0: 20 20 20 20 20 64 62 5f 6c 65 61 76 65 20 64 62       db_leave db
cae0: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 73  .          set s
caf0: 74 61 74 73 28 73 74 61 74 65 29 0a 20 20 20 20  tats(state).    
cb00: 20 20 20 20 7d 20 30 0a 20 20 20 20 20 20 7d 0a      } 0.      }.
cb10: 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49 66 20      }..    # If 
cb20: 61 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75  an IO error occu
cb30: 72 72 65 64 2c 20 74 68 65 6e 20 74 68 65 20 63  rred, then the c
cb40: 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 64  hecksum of the d
cb50: 61 74 61 62 61 73 65 20 73 68 6f 75 6c 64 0a 20  atabase should. 
cb60: 20 20 20 23 20 62 65 20 74 68 65 20 73 61 6d 65     # be the same
cb70: 20 61 73 20 62 65 66 6f 72 65 20 74 68 65 20 73   as before the s
cb80: 63 72 69 70 74 20 74 68 61 74 20 63 61 75 73 65  cript that cause
cb90: 64 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 77  d the IO error w
cba0: 61 73 20 72 75 6e 2e 0a 20 20 20 20 23 0a 20 20  as run..    #.  
cbb0: 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20 24    if {$::go && $
cbc0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
cbd0: 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 3a 3a  r_hardhit && $::
cbe0: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d  ioerropts(-cksum
cbf0: 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65  )} {.      do_te
cc00: 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e  st $testname.$n.
cc10: 36 20 7b 0a 20 20 20 20 20 20 20 20 63 61 74 63  6 {.        catc
cc20: 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20  h {db close}.   
cc30: 20 20 20 20 20 63 61 74 63 68 20 7b 64 62 32 20       catch {db2 
cc40: 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20 20 73  close}.        s
cc50: 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33  et ::DB [sqlite3
cc60: 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73 71 6c   db test.db; sql
cc70: 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f  ite3_connection_
cc80: 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 20 20  pointer db].    
cc90: 20 20 20 20 73 65 74 20 6e 6f 77 63 6b 73 75 6d      set nowcksum
cca0: 20 5b 63 6b 73 75 6d 5d 0a 20 20 20 20 20 20 20   [cksum].       
ccb0: 20 73 65 74 20 72 65 73 20 5b 65 78 70 72 20 7b   set res [expr {
ccc0: 24 6e 6f 77 63 6b 73 75 6d 3d 3d 24 3a 3a 63 68  $nowcksum==$::ch
ccd0: 65 63 6b 73 75 6d 20 7c 7c 20 24 6e 6f 77 63 6b  ecksum || $nowck
cce0: 73 75 6d 3d 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75  sum==$::goodcksu
ccf0: 6d 7d 5d 0a 20 20 20 20 20 20 20 20 69 66 20 7b  m}].        if {
cd00: 24 72 65 73 3d 3d 30 7d 20 7b 0a 20 20 20 20 20  $res==0} {.     
cd10: 20 20 20 20 20 6f 75 74 70 75 74 32 20 22 6e 6f       output2 "no
cd20: 77 3d 24 6e 6f 77 63 6b 73 75 6d 22 0a 20 20 20  w=$nowcksum".   
cd30: 20 20 20 20 20 20 20 6f 75 74 70 75 74 32 20 22         output2 "
cd40: 74 68 65 3d 24 3a 3a 63 68 65 63 6b 73 75 6d 22  the=$::checksum"
cd50: 0a 20 20 20 20 20 20 20 20 20 20 6f 75 74 70 75  .          outpu
cd60: 74 32 20 22 66 77 64 3d 24 3a 3a 67 6f 6f 64 63  t2 "fwd=$::goodc
cd70: 6b 73 75 6d 22 0a 20 20 20 20 20 20 20 20 7d 0a  ksum".        }.
cd80: 20 20 20 20 20 20 20 20 73 65 74 20 72 65 73 0a          set res.
cd90: 20 20 20 20 20 20 7d 20 31 0a 20 20 20 20 7d 0a        } 1.    }.
cda0: 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74  .    set ::sqlit
cdb0: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68  e_io_error_hardh
cdc0: 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73  it 0.    set ::s
cdd0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
cde0: 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 69 66 20  ending 0.    if 
cdf0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
ce00: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e  ioerropts(-clean
ce10: 75 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20 63 61  up)]} {.      ca
ce20: 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  tch $::ioerropts
ce30: 28 2d 63 6c 65 61 6e 75 70 29 0a 20 20 20 20 7d  (-cleanup).    }
ce40: 0a 20 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c  .  }.  set ::sql
ce50: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
ce60: 64 69 6e 67 20 30 0a 20 20 73 65 74 20 3a 3a 73  ding 0.  set ::s
ce70: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
ce80: 65 72 73 69 73 74 20 30 0a 20 20 75 6e 73 65 74  ersist 0.  unset
ce90: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 0a 7d 0a 0a   ::ioerropts.}..
cea0: 23 20 52 65 74 75 72 6e 20 61 20 63 68 65 63 6b  # Return a check
ceb0: 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65  sum based on the
cec0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
ced0: 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 61   main database a
cee0: 73 73 6f 63 69 61 74 65 64 0a 23 20 77 69 74 68  ssociated.# with
cef0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 24 64 62 0a   connection $db.
cf00: 23 0a 70 72 6f 63 20 63 6b 73 75 6d 20 7b 7b 64  #.proc cksum {{d
cf10: 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 74  b db}} {.  set t
cf20: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20  xt [$db eval {. 
cf30: 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65       SELECT name
cf40: 2c 20 74 79 70 65 2c 20 73 71 6c 20 46 52 4f 4d  , type, sql FROM
cf50: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 6f   sqlite_master o
cf60: 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d  rder by name.  }
cf70: 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 62  ]\n.  foreach tb
cf80: 6c 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20  l [$db eval {.  
cf90: 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20      SELECT name 
cfa0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
cfb0: 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27 74  er WHERE type='t
cfc0: 61 62 6c 65 27 20 6f 72 64 65 72 20 62 79 20 6e  able' order by n
cfd0: 61 6d 65 0a 20 20 7d 5d 20 7b 0a 20 20 20 20 61  ame.  }] {.    a
cfe0: 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65  ppend txt [$db e
cff0: 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  val "SELECT * FR
d000: 4f 4d 20 24 74 62 6c 22 5d 5c 6e 0a 20 20 7d 0a  OM $tbl"]\n.  }.
d010: 20 20 66 6f 72 65 61 63 68 20 70 72 61 67 20 7b    foreach prag {
d020: 64 65 66 61 75 6c 74 5f 73 79 6e 63 68 72 6f 6e  default_synchron
d030: 6f 75 73 20 64 65 66 61 75 6c 74 5f 63 61 63 68  ous default_cach
d040: 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70  e_size} {.    ap
d050: 70 65 6e 64 20 74 78 74 20 24 70 72 61 67 2d 5b  pend txt $prag-[
d060: 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41  $db eval "PRAGMA
d070: 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20   $prag"]\n.  }. 
d080: 20 73 65 74 20 63 6b 73 75 6d 20 5b 73 74 72 69   set cksum [stri
d090: 6e 67 20 6c 65 6e 67 74 68 20 24 74 78 74 5d 2d  ng length $txt]-
d0a0: 5b 6d 64 35 20 24 74 78 74 5d 0a 20 20 23 20 70  [md5 $txt].  # p
d0b0: 75 74 73 20 24 63 6b 73 75 6d 2d 5b 66 69 6c 65  uts $cksum-[file
d0c0: 20 73 69 7a 65 20 74 65 73 74 2e 64 62 5d 0a 20   size test.db]. 
d0d0: 20 72 65 74 75 72 6e 20 24 63 6b 73 75 6d 0a 7d   return $cksum.}
d0e0: 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 63  ..# Generate a c
d0f0: 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e  hecksum based on
d100: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
d110: 20 74 68 65 20 6d 61 69 6e 20 61 6e 64 20 74 65   the main and te
d120: 6d 70 20 74 61 62 6c 65 73 0a 23 20 64 61 74 61  mp tables.# data
d130: 62 61 73 65 20 24 64 62 2e 20 49 66 20 74 68 65  base $db. If the
d140: 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 77 6f   checksum of two
d150: 20 64 61 74 61 62 61 73 65 73 20 69 73 20 74 68   databases is th
d160: 65 20 73 61 6d 65 2c 20 61 6e 64 20 74 68 65 0a  e same, and the.
d170: 23 20 69 6e 74 65 67 72 69 74 79 2d 63 68 65 63  # integrity-chec
d180: 6b 20 70 61 73 73 65 73 20 66 6f 72 20 62 6f 74  k passes for bot
d190: 68 2c 20 74 68 65 20 74 77 6f 20 64 61 74 61 62  h, the two datab
d1a0: 61 73 65 73 20 61 72 65 20 69 64 65 6e 74 69 63  ases are identic
d1b0: 61 6c 2e 0a 23 0a 70 72 6f 63 20 61 6c 6c 63 6b  al..#.proc allck
d1c0: 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a  sum {{db db}} {.
d1d0: 20 20 73 65 74 20 72 65 74 20 5b 6c 69 73 74 5d    set ret [list]
d1e0: 0a 20 20 69 66 63 61 70 61 62 6c 65 20 74 65 6d  .  ifcapable tem
d1f0: 70 64 62 20 7b 0a 20 20 20 20 73 65 74 20 73 71  pdb {.    set sq
d200: 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l {.      SELECT
d210: 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74   name FROM sqlit
d220: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  e_master WHERE t
d230: 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e  ype = 'table' UN
d240: 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54  ION.      SELECT
d250: 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74   name FROM sqlit
d260: 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 20 57 48  e_temp_master WH
d270: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
d280: 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53  e' UNION.      S
d290: 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 6d 61  ELECT 'sqlite_ma
d2a0: 73 74 65 72 27 20 55 4e 49 4f 4e 0a 20 20 20 20  ster' UNION.    
d2b0: 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65    SELECT 'sqlite
d2c0: 5f 74 65 6d 70 5f 6d 61 73 74 65 72 27 20 4f 52  _temp_master' OR
d2d0: 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d 0a 20  DER BY 1.    }. 
d2e0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
d2f0: 74 20 73 71 6c 20 7b 0a 20 20 20 20 20 20 53 45  t sql {.      SE
d300: 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73  LECT name FROM s
d310: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45  qlite_master WHE
d320: 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65  RE type = 'table
d330: 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45  ' UNION.      SE
d340: 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 6d 61 73  LECT 'sqlite_mas
d350: 74 65 72 27 20 4f 52 44 45 52 20 42 59 20 31 0a  ter' ORDER BY 1.
d360: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20      }.  }.  set 
d370: 74 62 6c 6c 69 73 74 20 5b 24 64 62 20 65 76 61  tbllist [$db eva
d380: 6c 20 24 73 71 6c 5d 0a 20 20 73 65 74 20 74 78  l $sql].  set tx
d390: 74 20 7b 7d 0a 20 20 66 6f 72 65 61 63 68 20 74  t {}.  foreach t
d3a0: 62 6c 20 24 74 62 6c 6c 69 73 74 20 7b 0a 20 20  bl $tbllist {.  
d3b0: 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64    append txt [$d
d3c0: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a  b eval "SELECT *
d3d0: 20 46 52 4f 4d 20 24 74 62 6c 22 5d 0a 20 20 7d   FROM $tbl"].  }
d3e0: 0a 20 20 66 6f 72 65 61 63 68 20 70 72 61 67 20  .  foreach prag 
d3f0: 7b 64 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73  {default_cache_s
d400: 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e  ize} {.    appen
d410: 64 20 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62  d txt $prag-[$db
d420: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70   eval "PRAGMA $p
d430: 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 23 20  rag"]\n.  }.  # 
d440: 70 75 74 73 20 74 78 74 3d 24 74 78 74 0a 20 20  puts txt=$txt.  
d450: 72 65 74 75 72 6e 20 5b 6d 64 35 20 24 74 78 74  return [md5 $txt
d460: 5d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20  ].}..# Generate 
d470: 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64  a checksum based
d480: 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   on the contents
d490: 20 6f 66 20 61 20 73 69 6e 67 6c 65 20 64 61 74   of a single dat
d4a0: 61 62 61 73 65 20 77 69 74 68 0a 23 20 61 20 64  abase with.# a d
d4b0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
d4c0: 6f 6e 2e 20 20 54 68 65 20 6e 61 6d 65 20 6f 66  on.  The name of
d4d0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 69 73   the database is
d4e0: 20 24 64 62 6e 61 6d 65 2e 0a 23 20 45 78 61 6d   $dbname..# Exam
d4f0: 70 6c 65 73 20 6f 66 20 24 64 62 6e 61 6d 65 20  ples of $dbname 
d500: 61 72 65 20 22 74 65 6d 70 22 20 6f 72 20 22 6d  are "temp" or "m
d510: 61 69 6e 22 2e 0a 23 0a 70 72 6f 63 20 64 62 63  ain"..#.proc dbc
d520: 6b 73 75 6d 20 7b 64 62 20 64 62 6e 61 6d 65 7d  ksum {db dbname}
d530: 20 7b 0a 20 20 69 66 20 7b 24 64 62 6e 61 6d 65   {.  if {$dbname
d540: 3d 3d 22 74 65 6d 70 22 7d 20 7b 0a 20 20 20 20  =="temp"} {.    
d550: 73 65 74 20 6d 61 73 74 65 72 20 73 71 6c 69 74  set master sqlit
d560: 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 0a 20 20  e_temp_master.  
d570: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
d580: 20 6d 61 73 74 65 72 20 24 64 62 6e 61 6d 65 2e   master $dbname.
d590: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 0a 20 20  sqlite_master.  
d5a0: 7d 0a 20 20 73 65 74 20 61 6c 6c 74 61 62 20 5b  }.  set alltab [
d5b0: 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54  $db eval "SELECT
d5c0: 20 6e 61 6d 65 20 46 52 4f 4d 20 24 6d 61 73 74   name FROM $mast
d5d0: 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27 74  er WHERE type='t
d5e0: 61 62 6c 65 27 22 5d 0a 20 20 73 65 74 20 74 78  able'"].  set tx
d5f0: 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c  t [$db eval "SEL
d600: 45 43 54 20 2a 20 46 52 4f 4d 20 24 6d 61 73 74  ECT * FROM $mast
d610: 65 72 22 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68  er"]\n.  foreach
d620: 20 74 61 62 20 24 61 6c 6c 74 61 62 20 7b 0a 20   tab $alltab {. 
d630: 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24     append txt [$
d640: 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20  db eval "SELECT 
d650: 2a 20 46 52 4f 4d 20 24 64 62 6e 61 6d 65 2e 24  * FROM $dbname.$
d660: 74 61 62 22 5d 5c 6e 0a 20 20 7d 0a 20 20 72 65  tab"]\n.  }.  re
d670: 74 75 72 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a  turn [md5 $txt].
d680: 7d 0a 0a 70 72 6f 63 20 6d 65 6d 64 65 62 75 67  }..proc memdebug
d690: 5f 6c 6f 67 5f 73 71 6c 20 7b 7b 66 69 6c 65 6e  _log_sql {{filen
d6a0: 61 6d 65 20 6d 61 6c 6c 6f 63 73 2e 73 71 6c 7d  ame mallocs.sql}
d6b0: 7d 20 7b 0a 0a 20 20 73 65 74 20 64 61 74 61 20  } {..  set data 
d6c0: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75  [sqlite3_memdebu
d6d0: 67 5f 6c 6f 67 20 64 75 6d 70 5d 0a 20 20 73 65  g_log dump].  se
d6e0: 74 20 6e 46 72 61 6d 65 20 5b 65 78 70 72 20 5b  t nFrame [expr [
d6f0: 6c 6c 65 6e 67 74 68 20 5b 6c 69 6e 64 65 78 20  llength [lindex 
d700: 24 64 61 74 61 20 30 5d 5d 2d 32 5d 0a 20 20 69  $data 0]]-2].  i
d710: 66 20 7b 24 6e 46 72 61 6d 65 20 3c 20 30 7d 20  f {$nFrame < 0} 
d720: 7b 20 72 65 74 75 72 6e 20 22 22 20 7d 0a 0a 20  { return "" }.. 
d730: 20 73 65 74 20 64 61 74 61 62 61 73 65 20 74 65   set database te
d740: 6d 70 0a 0a 20 20 73 65 74 20 74 62 6c 20 22 43  mp..  set tbl "C
d750: 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64 61  REATE TABLE ${da
d760: 74 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63 28 7a  tabase}.malloc(z
d770: 54 65 73 74 2c 20 6e 43 61 6c 6c 2c 20 6e 42 79  Test, nCall, nBy
d780: 74 65 2c 20 6c 53 74 61 63 6b 29 3b 22 0a 0a 20  te, lStack);".. 
d790: 20 73 65 74 20 73 71 6c 20 22 22 0a 20 20 66 6f   set sql "".  fo
d7a0: 72 65 61 63 68 20 65 20 24 64 61 74 61 20 7b 0a  reach e $data {.
d7b0: 20 20 20 20 73 65 74 20 6e 43 61 6c 6c 20 5b 6c      set nCall [l
d7c0: 69 6e 64 65 78 20 24 65 20 30 5d 0a 20 20 20 20  index $e 0].    
d7d0: 73 65 74 20 6e 42 79 74 65 20 5b 6c 69 6e 64 65  set nByte [linde
d7e0: 78 20 24 65 20 31 5d 0a 20 20 20 20 73 65 74 20  x $e 1].    set 
d7f0: 6c 53 74 61 63 6b 20 5b 6c 72 61 6e 67 65 20 24  lStack [lrange $
d800: 65 20 32 20 65 6e 64 5d 0a 20 20 20 20 61 70 70  e 2 end].    app
d810: 65 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20  end sql "INSERT 
d820: 49 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d  INTO ${database}
d830: 2e 6d 61 6c 6c 6f 63 20 56 41 4c 55 45 53 22 0a  .malloc VALUES".
d840: 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22      append sql "
d850: 28 27 74 65 73 74 27 2c 20 24 6e 43 61 6c 6c 2c  ('test', $nCall,
d860: 20 24 6e 42 79 74 65 2c 20 27 24 6c 53 74 61 63   $nByte, '$lStac
d870: 6b 27 29 3b 5c 6e 22 0a 20 20 20 20 66 6f 72 65  k');\n".    fore
d880: 61 63 68 20 66 20 24 6c 53 74 61 63 6b 20 7b 0a  ach f $lStack {.
d890: 20 20 20 20 20 20 73 65 74 20 66 72 61 6d 65 73        set frames
d8a0: 28 24 66 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d  ($f) 1.    }.  }
d8b0: 0a 0a 20 20 73 65 74 20 74 62 6c 32 20 22 43 52  ..  set tbl2 "CR
d8c0: 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64 61 74  EATE TABLE ${dat
d8d0: 61 62 61 73 65 7d 2e 66 72 61 6d 65 28 66 72 61  abase}.frame(fra
d8e0: 6d 65 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41  me INTEGER PRIMA
d8f0: 52 59 20 4b 45 59 2c 20 6c 69 6e 65 29 3b 5c 6e  RY KEY, line);\n
d900: 22 0a 20 20 73 65 74 20 74 62 6c 33 20 22 43 52  ".  set tbl3 "CR
d910: 45 41 54 45 20 54 41 42 4c 45 20 24 7b 64 61 74  EATE TABLE ${dat
d920: 61 62 61 73 65 7d 2e 66 69 6c 65 28 6e 61 6d 65  abase}.file(name
d930: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 6f   PRIMARY KEY, co
d940: 6e 74 65 6e 74 29 3b 5c 6e 22 0a 0a 20 20 66 6f  ntent);\n"..  fo
d950: 72 65 61 63 68 20 66 20 5b 61 72 72 61 79 20 6e  reach f [array n
d960: 61 6d 65 73 20 66 72 61 6d 65 73 5d 20 7b 0a 20  ames frames] {. 
d970: 20 20 20 73 65 74 20 61 64 64 72 20 5b 66 6f 72     set addr [for
d980: 6d 61 74 20 25 78 20 24 66 5d 0a 20 20 20 20 73  mat %x $f].    s
d990: 65 74 20 63 6d 64 20 22 61 64 64 72 32 6c 69 6e  et cmd "addr2lin
d9a0: 65 20 2d 65 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f  e -e [info nameo
d9b0: 66 65 78 65 63 5d 20 24 61 64 64 72 22 0a 20 20  fexec] $addr".  
d9c0: 20 20 73 65 74 20 6c 69 6e 65 20 5b 65 76 61 6c    set line [eval
d9d0: 20 65 78 65 63 20 24 63 6d 64 5d 0a 20 20 20 20   exec $cmd].    
d9e0: 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e 53 45  append sql "INSE
d9f0: 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61 62 61  RT INTO ${databa
da00: 73 65 7d 2e 66 72 61 6d 65 20 56 41 4c 55 45 53  se}.frame VALUES
da10: 28 24 66 2c 20 27 24 6c 69 6e 65 27 29 3b 5c 6e  ($f, '$line');\n
da20: 22 0a 0a 20 20 20 20 73 65 74 20 66 69 6c 65 20  "..    set file 
da30: 5b 6c 69 6e 64 65 78 20 5b 73 70 6c 69 74 20 24  [lindex [split $
da40: 6c 69 6e 65 20 3a 5d 20 30 5d 0a 20 20 20 20 73  line :] 0].    s
da50: 65 74 20 66 69 6c 65 73 28 24 66 69 6c 65 29 20  et files($file) 
da60: 31 0a 20 20 7d 0a 0a 20 20 66 6f 72 65 61 63 68  1.  }..  foreach
da70: 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20   f [array names 
da80: 66 69 6c 65 73 5d 20 7b 0a 20 20 20 20 73 65 74  files] {.    set
da90: 20 63 6f 6e 74 65 6e 74 73 20 22 22 0a 20 20 20   contents "".   
daa0: 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20 73   catch {.      s
dab0: 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66 5d 0a  et fd [open $f].
dac0: 20 20 20 20 20 20 73 65 74 20 63 6f 6e 74 65 6e        set conten
dad0: 74 73 20 5b 72 65 61 64 20 24 66 64 5d 0a 20 20  ts [read $fd].  
dae0: 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a 20 20      close $fd.  
daf0: 20 20 7d 0a 20 20 20 20 73 65 74 20 63 6f 6e 74    }.    set cont
db00: 65 6e 74 73 20 5b 73 74 72 69 6e 67 20 6d 61 70  ents [string map
db10: 20 7b 27 20 27 27 7d 20 24 63 6f 6e 74 65 6e 74   {' ''} $content
db20: 73 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73 71  s].    append sq
db30: 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 24  l "INSERT INTO $
db40: 7b 64 61 74 61 62 61 73 65 7d 2e 66 69 6c 65 20  {database}.file 
db50: 56 41 4c 55 45 53 28 27 24 66 27 2c 20 27 24 63  VALUES('$f', '$c
db60: 6f 6e 74 65 6e 74 73 27 29 3b 5c 6e 22 0a 20 20  ontents');\n".  
db70: 7d 0a 0a 20 20 73 65 74 20 66 64 20 5b 6f 70 65  }..  set fd [ope
db80: 6e 20 24 66 69 6c 65 6e 61 6d 65 20 77 5d 0a 20  n $filename w]. 
db90: 20 70 75 74 73 20 24 66 64 20 22 42 45 47 49 4e   puts $fd "BEGIN
dba0: 3b 20 24 7b 74 62 6c 7d 24 7b 74 62 6c 32 7d 24  ; ${tbl}${tbl2}$
dbb0: 7b 74 62 6c 33 7d 24 7b 73 71 6c 7d 20 3b 20 43  {tbl3}${sql} ; C
dbc0: 4f 4d 4d 49 54 3b 22 0a 20 20 63 6c 6f 73 65 20  OMMIT;".  close 
dbd0: 24 66 64 0a 7d 0a 0a 23 20 44 72 6f 70 20 61 6c  $fd.}..# Drop al
dbe0: 6c 20 74 61 62 6c 65 73 20 69 6e 20 64 61 74 61  l tables in data
dbf0: 62 61 73 65 20 5b 64 62 5d 0a 70 72 6f 63 20 64  base [db].proc d
dc00: 72 6f 70 5f 61 6c 6c 5f 74 61 62 6c 65 73 20 7b  rop_all_tables {
dc10: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63  {db db}} {.  ifc
dc20: 61 70 61 62 6c 65 20 74 72 69 67 67 65 72 26 26  apable trigger&&
dc30: 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20 20 20  foreignkey {.   
dc40: 20 73 65 74 20 70 6b 20 5b 24 64 62 20 6f 6e 65   set pk [$db one
dc50: 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67 6e   "PRAGMA foreign
dc60: 5f 6b 65 79 73 22 5d 0a 20 20 20 20 24 64 62 20  _keys"].    $db 
dc70: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66 6f 72  eval "PRAGMA for
dc80: 65 69 67 6e 5f 6b 65 79 73 20 3d 20 4f 46 46 22  eign_keys = OFF"
dc90: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 7b  .  }.  foreach {
dca0: 69 64 78 20 6e 61 6d 65 20 66 69 6c 65 7d 20 5b  idx name file} [
dcb0: 64 62 20 65 76 61 6c 20 7b 50 52 41 47 4d 41 20  db eval {PRAGMA 
dcc0: 64 61 74 61 62 61 73 65 5f 6c 69 73 74 7d 5d 20  database_list}] 
dcd0: 7b 0a 20 20 20 20 69 66 20 7b 24 69 64 78 3d 3d  {.    if {$idx==
dce0: 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d  1} {.      set m
dcf0: 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74 65 6d  aster sqlite_tem
dd00: 70 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d 20 65  p_master.    } e
dd10: 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20  lse {.      set 
dd20: 6d 61 73 74 65 72 20 24 6e 61 6d 65 2e 73 71 6c  master $name.sql
dd30: 69 74 65 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d  ite_master.    }
dd40: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 20  .    foreach {t 
dd50: 74 79 70 65 7d 20 5b 24 64 62 20 65 76 61 6c 20  type} [$db eval 
dd60: 22 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e  ".      SELECT n
dd70: 61 6d 65 2c 20 74 79 70 65 20 46 52 4f 4d 20 24  ame, type FROM $
dd80: 6d 61 73 74 65 72 0a 20 20 20 20 20 20 57 48 45  master.      WHE
dd90: 52 45 20 74 79 70 65 20 49 4e 28 27 74 61 62 6c  RE type IN('tabl
dda0: 65 27 2c 20 27 76 69 65 77 27 29 20 41 4e 44 20  e', 'view') AND 
ddb0: 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20 27 73  name NOT LIKE 's
ddc0: 71 6c 69 74 65 58 5f 25 27 20 45 53 43 41 50 45  qliteX_%' ESCAPE
ddd0: 20 27 58 27 0a 20 20 20 20 22 5d 20 7b 0a 20 20   'X'.    "] {.  
dde0: 20 20 20 20 24 64 62 20 65 76 61 6c 20 22 44 52      $db eval "DR
ddf0: 4f 50 20 24 74 79 70 65 20 5c 22 24 74 5c 22 22  OP $type \"$t\""
de00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 63  .    }.  }.  ifc
de10: 61 70 61 62 6c 65 20 74 72 69 67 67 65 72 26 26  apable trigger&&
de20: 66 6f 72 65 69 67 6e 6b 65 79 20 7b 0a 20 20 20  foreignkey {.   
de30: 20 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d   $db eval "PRAGM
de40: 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73 20 3d  A foreign_keys =
de50: 20 24 70 6b 22 0a 20 20 7d 0a 7d 0a 0a 23 2d 2d   $pk".  }.}..#--
de60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
de90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
dea0: 2d 2d 2d 2d 2d 2d 2d 0a 23 20 49 66 20 61 20 74  -------.# If a t
deb0: 65 73 74 20 73 63 72 69 70 74 20 69 73 20 65 78  est script is ex
dec0: 65 63 75 74 65 64 20 77 69 74 68 20 67 6c 6f 62  ecuted with glob
ded0: 61 6c 20 76 61 72 69 61 62 6c 65 20 24 3a 3a 47  al variable $::G
dee0: 28 70 65 72 6d 3a 6e 61 6d 65 29 20 73 65 74 20  (perm:name) set 
def0: 74 6f 0a 23 20 22 77 61 6c 22 2c 20 74 68 65 6e  to.# "wal", then
df00: 20 74 68 65 20 74 65 73 74 73 20 61 72 65 20 72   the tests are r
df10: 75 6e 20 69 6e 20 57 41 4c 20 6d 6f 64 65 2e 20  un in WAL mode. 
df20: 4f 74 68 65 72 77 69 73 65 2c 20 74 68 65 79 20  Otherwise, they 
df30: 73 68 6f 75 6c 64 20 62 65 20 72 75 6e 0a 23 20  should be run.# 
df40: 69 6e 20 72 6f 6c 6c 62 61 63 6b 20 6d 6f 64 65  in rollback mode
df50: 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  . The following 
df60: 54 63 6c 20 70 72 6f 63 73 20 61 72 65 20 75 73  Tcl procs are us
df70: 65 64 20 74 6f 20 6d 61 6b 65 20 74 68 69 73 20  ed to make this 
df80: 6c 65 73 73 0a 23 20 69 6e 74 72 75 73 69 76 65  less.# intrusive
df90: 3a 0a 23 0a 23 20 20 20 77 61 6c 5f 73 65 74 5f  :.#.#   wal_set_
dfa0: 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3f 44 42  journal_mode ?DB
dfb0: 3f 0a 23 0a 23 20 20 20 20 20 49 66 20 72 75 6e  ?.#.#     If run
dfc0: 6e 69 6e 67 20 61 20 57 41 4c 20 74 65 73 74 2c  ning a WAL test,
dfd0: 20 65 78 65 63 75 74 65 20 22 50 52 41 47 4d 41   execute "PRAGMA
dfe0: 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20   journal_mode = 
dff0: 77 61 6c 22 20 75 73 69 6e 67 0a 23 20 20 20 20  wal" using.#    
e000: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64   connection hand
e010: 6c 65 20 44 42 2e 20 4f 74 68 65 72 77 69 73 65  le DB. Otherwise
e020: 2c 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69  , this command i
e030: 73 20 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20  s a no-op..#.#  
e040: 20 77 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72 6e   wal_check_journ
e050: 61 6c 5f 6d 6f 64 65 20 54 45 53 54 4e 41 4d 45  al_mode TESTNAME
e060: 20 3f 44 42 3f 0a 23 0a 23 20 20 20 20 20 49 66   ?DB?.#.#     If
e070: 20 72 75 6e 6e 69 6e 67 20 61 20 57 41 4c 20 74   running a WAL t
e080: 65 73 74 2c 20 65 78 65 63 75 74 65 20 61 20 74  est, execute a t
e090: 65 73 74 73 20 63 61 73 65 20 74 68 61 74 20 66  ests case that f
e0a0: 61 69 6c 73 20 69 66 20 74 68 65 20 6d 61 69 6e  ails if the main
e0b0: 0a 23 20 20 20 20 20 64 61 74 61 62 61 73 65 20  .#     database 
e0c0: 66 6f 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68  for connection h
e0d0: 61 6e 64 6c 65 20 44 42 20 69 73 20 6e 6f 74 20  andle DB is not 
e0e0: 63 75 72 72 65 6e 74 6c 79 20 61 20 57 41 4c 20  currently a WAL 
e0f0: 64 61 74 61 62 61 73 65 2e 0a 23 20 20 20 20 20  database..#     
e100: 4f 74 68 65 72 77 69 73 65 20 28 69 66 20 6e 6f  Otherwise (if no
e110: 74 20 72 75 6e 6e 69 6e 67 20 61 20 57 41 4c 20  t running a WAL 
e120: 70 65 72 6d 75 74 61 74 69 6f 6e 29 20 74 68 69  permutation) thi
e130: 73 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 23 0a  s is a no-op..#.
e140: 23 20 20 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d  #   wal_is_wal_m
e150: 6f 64 65 0a 23 0a 23 20 20 20 20 20 52 65 74 75  ode.#.#     Retu
e160: 72 6e 73 20 74 72 75 65 20 69 66 20 74 68 69 73  rns true if this
e170: 20 74 65 73 74 20 73 68 6f 75 6c 64 20 62 65 20   test should be 
e180: 72 75 6e 20 69 6e 20 57 41 4c 20 6d 6f 64 65 2e  run in WAL mode.
e190: 20 46 61 6c 73 65 20 6f 74 68 65 72 77 69 73 65   False otherwise
e1a0: 2e 0a 23 0a 70 72 6f 63 20 77 61 6c 5f 69 73 5f  ..#.proc wal_is_
e1b0: 77 61 6c 5f 6d 6f 64 65 20 7b 7d 20 7b 0a 20 20  wal_mode {} {.  
e1c0: 65 78 70 72 20 7b 5b 70 65 72 6d 75 74 61 74 69  expr {[permutati
e1d0: 6f 6e 5d 20 65 71 20 22 77 61 6c 22 7d 0a 7d 0a  on] eq "wal"}.}.
e1e0: 70 72 6f 63 20 77 61 6c 5f 73 65 74 5f 6a 6f 75  proc wal_set_jou
e1f0: 72 6e 61 6c 5f 6d 6f 64 65 20 7b 7b 64 62 20 64  rnal_mode {{db d
e200: 62 7d 7d 20 7b 0a 20 20 69 66 20 7b 20 5b 77 61  b}} {.  if { [wa
e210: 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d 20 7d  l_is_wal_mode] }
e220: 20 7b 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20   {.    $db eval 
e230: 22 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f  "PRAGMA journal_
e240: 6d 6f 64 65 20 3d 20 57 41 4c 22 0a 20 20 7d 0a  mode = WAL".  }.
e250: 7d 0a 70 72 6f 63 20 77 61 6c 5f 63 68 65 63 6b  }.proc wal_check
e260: 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b 74  _journal_mode {t
e270: 65 73 74 6e 61 6d 65 20 7b 64 62 20 64 62 7d 7d  estname {db db}}
e280: 20 7b 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f 69   {.  if { [wal_i
e290: 73 5f 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b 0a  s_wal_mode] } {.
e2a0: 20 20 20 20 24 64 62 20 65 76 61 6c 20 7b 20 53      $db eval { S
e2b0: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c  ELECT * FROM sql
e2c0: 69 74 65 5f 6d 61 73 74 65 72 20 7d 0a 20 20 20  ite_master }.   
e2d0: 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61   do_test $testna
e2e0: 6d 65 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61  me [list $db eva
e2f0: 6c 20 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 6a  l "PRAGMA main.j
e300: 6f 75 72 6e 61 6c 5f 6d 6f 64 65 22 5d 20 7b 77  ournal_mode"] {w
e310: 61 6c 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20  al}.  }.}..proc 
e320: 70 65 72 6d 75 74 61 74 69 6f 6e 20 7b 7d 20 7b  permutation {} {
e330: 0a 20 20 73 65 74 20 70 65 72 6d 20 22 22 0a 20  .  set perm "". 
e340: 20 63 61 74 63 68 20 7b 73 65 74 20 70 65 72 6d   catch {set perm
e350: 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65 29   $::G(perm:name)
e360: 7d 0a 20 20 73 65 74 20 70 65 72 6d 0a 7d 0a 70  }.  set perm.}.p
e370: 72 6f 63 20 70 72 65 73 71 6c 20 7b 7d 20 7b 0a  roc presql {} {.
e380: 20 20 73 65 74 20 70 72 65 73 71 6c 20 22 22 0a    set presql "".
e390: 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 72 65    catch {set pre
e3a0: 73 71 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72  sql $::G(perm:pr
e3b0: 65 73 71 6c 29 7d 0a 20 20 73 65 74 20 70 72 65  esql)}.  set pre
e3c0: 73 71 6c 0a 7d 0a 0a 70 72 6f 63 20 69 73 71 75  sql.}..proc isqu
e3d0: 69 63 6b 20 7b 7d 20 7b 0a 20 20 73 65 74 20 72  ick {} {.  set r
e3e0: 65 74 20 30 0a 20 20 63 61 74 63 68 20 7b 73 65  et 0.  catch {se
e3f0: 74 20 72 65 74 20 24 3a 3a 47 28 69 73 71 75 69  t ret $::G(isqui
e400: 63 6b 29 7d 0a 20 20 73 65 74 20 72 65 74 0a 7d  ck)}.  set ret.}
e410: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
e420: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e430: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e440: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e450: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70  ------------.#.p
e460: 72 6f 63 20 73 6c 61 76 65 5f 74 65 73 74 5f 73  roc slave_test_s
e470: 63 72 69 70 74 20 7b 73 63 72 69 70 74 7d 20 7b  cript {script} {
e480: 0a 0a 20 20 23 20 43 72 65 61 74 65 20 74 68 65  ..  # Create the
e490: 20 69 6e 74 65 72 70 72 65 74 65 72 20 75 73 65   interpreter use
e4a0: 64 20 74 6f 20 72 75 6e 20 74 68 65 20 74 65 73  d to run the tes
e4b0: 74 20 73 63 72 69 70 74 2e 0a 20 20 69 6e 74 65  t script..  inte
e4c0: 72 70 20 63 72 65 61 74 65 20 74 69 6e 74 65 72  rp create tinter
e4d0: 70 0a 0a 20 20 23 20 50 6f 70 75 6c 61 74 65 20  p..  # Populate 
e4e0: 73 6f 6d 65 20 67 6c 6f 62 61 6c 20 76 61 72 69  some global vari
e4f0: 61 62 6c 65 73 20 74 68 61 74 20 74 65 73 74 65  ables that teste
e500: 72 2e 74 63 6c 20 65 78 70 65 63 74 73 20 74 6f  r.tcl expects to
e510: 20 73 65 65 2e 0a 20 20 66 6f 72 65 61 63 68 20   see..  foreach 
e520: 7b 76 61 72 20 76 61 6c 75 65 7d 20 5b 6c 69 73  {var value} [lis
e530: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c  t              \
e540: 0a 20 20 20 20 3a 3a 61 72 67 76 30 20 24 3a 3a  .    ::argv0 $::
e550: 61 72 67 76 30 20 20 20 20 20 20 20 20 20 20 20  argv0           
e560: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
e570: 3a 3a 61 72 67 76 20 20 7b 7d 20 20 20 20 20 20  ::argv  {}      
e580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e590: 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 53 4c 41       \.    ::SLA
e5a0: 56 45 20 31 20 20 20 20 20 20 20 20 20 20 20 20  VE 1            
e5b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e5c0: 5c 0a 20 20 5d 20 7b 0a 20 20 20 20 69 6e 74 65  \.  ] {.    inte
e5d0: 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20  rp eval tinterp 
e5e0: 5b 6c 69 73 74 20 73 65 74 20 24 76 61 72 20 24  [list set $var $
e5f0: 76 61 6c 75 65 5d 0a 20 20 7d 0a 0a 20 20 23 20  value].  }..  # 
e600: 49 66 20 6f 75 74 70 75 74 20 69 73 20 62 65 69  If output is bei
e610: 6e 67 20 63 6f 70 69 65 64 20 69 6e 74 6f 20 61  ng copied into a
e620: 20 66 69 6c 65 2c 20 73 68 61 72 65 20 74 68 65   file, share the
e630: 20 66 69 6c 65 2d 64 65 73 63 72 69 70 74 6f 72   file-descriptor
e640: 20 77 69 74 68 0a 20 20 23 20 74 68 65 20 69 6e   with.  # the in
e650: 74 65 72 70 72 65 74 65 72 2e 0a 20 20 69 66 20  terpreter..  if 
e660: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
e670: 47 28 6f 75 74 70 75 74 5f 66 64 29 5d 7d 20 7b  G(output_fd)]} {
e680: 0a 20 20 20 20 69 6e 74 65 72 70 20 73 68 61 72  .    interp shar
e690: 65 20 7b 7d 20 24 3a 3a 47 28 6f 75 74 70 75 74  e {} $::G(output
e6a0: 5f 66 64 29 20 74 69 6e 74 65 72 70 0a 20 20 7d  _fd) tinterp.  }
e6b0: 0a 0a 20 20 23 20 54 68 65 20 61 6c 69 61 73 20  ..  # The alias 
e6c0: 75 73 65 64 20 74 6f 20 61 63 63 65 73 73 20 74  used to access t
e6d0: 68 65 20 67 6c 6f 62 61 6c 20 74 65 73 74 20 63  he global test c
e6e0: 6f 75 6e 74 65 72 73 2e 0a 20 20 74 69 6e 74 65  ounters..  tinte
e6f0: 72 70 20 61 6c 69 61 73 20 73 65 74 5f 74 65 73  rp alias set_tes
e700: 74 5f 63 6f 75 6e 74 65 72 20 73 65 74 5f 74 65  t_counter set_te
e710: 73 74 5f 63 6f 75 6e 74 65 72 0a 0a 20 20 23 20  st_counter..  # 
e720: 53 65 74 20 75 70 20 74 68 65 20 3a 3a 63 6d 64  Set up the ::cmd
e730: 6c 69 6e 65 61 72 67 20 61 72 72 61 79 20 69 6e  linearg array in
e740: 20 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69 6e   the slave..  in
e750: 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72  terp eval tinter
e760: 70 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73 65  p [list array se
e770: 74 20 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 5b  t ::cmdlinearg [
e780: 61 72 72 61 79 20 67 65 74 20 3a 3a 63 6d 64 6c  array get ::cmdl
e790: 69 6e 65 61 72 67 5d 5d 0a 0a 20 20 23 20 53 65  inearg]]..  # Se
e7a0: 74 20 75 70 20 74 68 65 20 3a 3a 47 20 61 72 72  t up the ::G arr
e7b0: 61 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65 2e  ay in the slave.
e7c0: 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74  .  interp eval t
e7d0: 69 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72 72  interp [list arr
e7e0: 61 79 20 73 65 74 20 3a 3a 47 20 5b 61 72 72 61  ay set ::G [arra
e7f0: 79 20 67 65 74 20 3a 3a 47 5d 5d 0a 0a 20 20 23  y get ::G]]..  #
e800: 20 4c 6f 61 64 20 74 68 65 20 76 61 72 69 6f 75   Load the variou
e810: 73 20 74 65 73 74 20 69 6e 74 65 72 66 61 63 65  s test interface
e820: 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 69 6e  s implemented in
e830: 20 43 2e 0a 20 20 6c 6f 61 64 5f 74 65 73 74 66   C..  load_testf
e840: 69 78 74 75 72 65 5f 65 78 74 65 6e 73 69 6f 6e  ixture_extension
e850: 73 20 74 69 6e 74 65 72 70 0a 0a 20 20 23 20 52  s tinterp..  # R
e860: 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72 69  un the test scri
e870: 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 65 76 61  pt..  interp eva
e880: 6c 20 74 69 6e 74 65 72 70 20 24 73 63 72 69 70  l tinterp $scrip
e890: 74 0a 0a 20 20 23 20 43 68 65 63 6b 20 69 66 20  t..  # Check if 
e8a0: 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72 20  the interpreter 
e8b0: 63 61 6c 6c 20 5b 72 75 6e 5f 74 68 72 65 61 64  call [run_thread
e8c0: 5f 74 65 73 74 73 5d 0a 20 20 69 66 20 7b 20 5b  _tests].  if { [
e8d0: 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74  interp eval tint
e8e0: 65 72 70 20 7b 69 6e 66 6f 20 65 78 69 73 74 73  erp {info exists
e8f0: 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65   ::run_thread_te
e900: 73 74 73 5f 63 61 6c 6c 65 64 7d 5d 20 7d 20 7b  sts_called}] } {
e910: 0a 20 20 20 20 73 65 74 20 3a 3a 72 75 6e 5f 74  .    set ::run_t
e920: 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c  hread_tests_call
e930: 65 64 20 31 0a 20 20 7d 0a 0a 20 20 23 20 44 65  ed 1.  }..  # De
e940: 6c 65 74 65 20 74 68 65 20 69 6e 74 65 72 70 72  lete the interpr
e950: 65 74 65 72 20 75 73 65 64 20 74 6f 20 72 75 6e  eter used to run
e960: 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74   the test script
e970: 2e 0a 20 20 69 6e 74 65 72 70 20 64 65 6c 65 74  ..  interp delet
e980: 65 20 74 69 6e 74 65 72 70 0a 7d 0a 0a 70 72 6f  e tinterp.}..pro
e990: 63 20 73 6c 61 76 65 5f 74 65 73 74 5f 66 69 6c  c slave_test_fil
e9a0: 65 20 7b 7a 46 69 6c 65 7d 20 7b 0a 20 20 73 65  e {zFile} {.  se
e9b0: 74 20 74 61 69 6c 20 5b 66 69 6c 65 20 74 61 69  t tail [file tai
e9c0: 6c 20 24 7a 46 69 6c 65 5d 0a 0a 20 20 69 66 20  l $zFile]..  if 
e9d0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
e9e0: 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74  G(start:permutat
e9f0: 69 6f 6e 29 5d 7d 20 7b 0a 20 20 20 20 69 66 20  ion)]} {.    if 
ea00: 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20 21  {[permutation] !
ea10: 3d 20 24 3a 3a 47 28 73 74 61 72 74 3a 70 65 72  = $::G(start:per
ea20: 6d 75 74 61 74 69 6f 6e 29 7d 20 72 65 74 75 72  mutation)} retur
ea30: 6e 0a 20 20 20 20 75 6e 73 65 74 20 3a 3a 47 28  n.    unset ::G(
ea40: 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f  start:permutatio
ea50: 6e 29 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69 6e  n).  }.  if {[in
ea60: 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73 74  fo exists ::G(st
ea70: 61 72 74 3a 66 69 6c 65 29 5d 7d 20 7b 0a 20 20  art:file)]} {.  
ea80: 20 20 69 66 20 7b 24 74 61 69 6c 20 21 3d 20 24    if {$tail != $
ea90: 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 20  ::G(start:file) 
eaa0: 26 26 20 24 74 61 69 6c 21 3d 22 24 3a 3a 47 28  && $tail!="$::G(
eab0: 73 74 61 72 74 3a 66 69 6c 65 29 2e 74 65 73 74  start:file).test
eac0: 22 7d 20 72 65 74 75 72 6e 0a 20 20 20 20 75 6e  "} return.    un
ead0: 73 65 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69  set ::G(start:fi
eae0: 6c 65 29 0a 20 20 7d 0a 0a 20 20 23 20 52 65 6d  le).  }..  # Rem
eaf0: 65 6d 62 65 72 20 74 68 65 20 76 61 6c 75 65 20  ember the value 
eb00: 6f 66 20 74 68 65 20 73 68 61 72 65 64 2d 63 61  of the shared-ca
eb10: 63 68 65 20 73 65 74 74 69 6e 67 2e 20 53 6f 20  che setting. So 
eb20: 74 68 61 74 20 69 74 20 69 73 20 70 6f 73 73 69  that it is possi
eb30: 62 6c 65 0a 20 20 23 20 74 6f 20 63 68 65 63 6b  ble.  # to check
eb40: 20 61 66 74 65 72 77 61 72 64 73 20 74 68 61 74   afterwards that
eb50: 20 69 74 20 77 61 73 20 6e 6f 74 20 6d 6f 64 69   it was not modi
eb60: 66 69 65 64 20 62 79 20 74 68 65 20 74 65 73 74  fied by the test
eb70: 20 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69   script..  #.  i
eb80: 66 63 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f  fcapable shared_
eb90: 63 61 63 68 65 20 7b 20 73 65 74 20 73 63 73 20  cache { set scs 
eba0: 5b 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f  [sqlite3_enable_
ebb0: 73 68 61 72 65 64 5f 63 61 63 68 65 5d 20 7d 0a  shared_cache] }.
ebc0: 0a 20 20 23 20 52 75 6e 20 74 68 65 20 74 65 73  .  # Run the tes
ebd0: 74 20 73 63 72 69 70 74 20 69 6e 20 61 20 73 6c  t script in a sl
ebe0: 61 76 65 20 69 6e 74 65 72 70 72 65 74 65 72 2e  ave interpreter.
ebf0: 0a 20 20 23 0a 20 20 75 6e 73 65 74 20 2d 6e 6f  .  #.  unset -no
ec00: 63 6f 6d 70 6c 61 69 6e 20 3a 3a 72 75 6e 5f 74  complain ::run_t
ec10: 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c  hread_tests_call
ec20: 65 64 0a 20 20 72 65 73 65 74 5f 70 72 6e 67 5f  ed.  reset_prng_
ec30: 73 74 61 74 65 0a 20 20 73 65 74 20 3a 3a 73 71  state.  set ::sq
ec40: 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63  lite_open_file_c
ec50: 6f 75 6e 74 20 30 0a 20 20 73 65 74 20 74 69 6d  ount 0.  set tim
ec60: 65 20 5b 74 69 6d 65 20 7b 20 73 6c 61 76 65 5f  e [time { slave_
ec70: 74 65 73 74 5f 73 63 72 69 70 74 20 5b 6c 69 73  test_script [lis
ec80: 74 20 73 6f 75 72 63 65 20 24 7a 46 69 6c 65 5d  t source $zFile]
ec90: 20 7d 5d 0a 20 20 73 65 74 20 6d 73 20 5b 65 78   }].  set ms [ex
eca0: 70 72 20 5b 6c 69 6e 64 65 78 20 24 74 69 6d 65  pr [lindex $time
ecb0: 20 30 5d 20 2f 20 31 30 30 30 5d 0a 0a 20 20 23   0] / 1000]..  #
ecc0: 20 54 65 73 74 20 74 68 61 74 20 61 6c 6c 20 66   Test that all f
ecd0: 69 6c 65 73 20 6f 70 65 6e 65 64 20 62 79 20 74  iles opened by t
ece0: 68 65 20 74 65 73 74 20 73 63 72 69 70 74 20 77  he test script w
ecf0: 65 72 65 20 63 6c 6f 73 65 64 2e 20 4f 6d 69 74  ere closed. Omit
ed00: 20 74 68 69 73 0a 20 20 23 20 69 66 20 74 68 65   this.  # if the
ed10: 20 74 65 73 74 20 73 63 72 69 70 74 20 68 61 73   test script has
ed20: 20 22 74 68 72 65 61 64 22 20 69 6e 20 69 74 73   "thread" in its
ed30: 20 6e 61 6d 65 2e 20 54 68 65 20 6f 70 65 6e 20   name. The open 
ed40: 66 69 6c 65 20 63 6f 75 6e 74 65 72 0a 20 20 23  file counter.  #
ed50: 20 69 73 20 6e 6f 74 20 74 68 72 65 61 64 2d 73   is not thread-s
ed60: 61 66 65 2e 0a 20 20 23 0a 20 20 69 66 20 7b 5b  afe..  #.  if {[
ed70: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72 75  info exists ::ru
ed80: 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63  n_thread_tests_c
ed90: 61 6c 6c 65 64 5d 3d 3d 30 7d 20 7b 0a 20 20 20  alled]==0} {.   
eda0: 20 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c 7d   do_test ${tail}
edb0: 2d 63 6c 6f 73 65 61 6c 6c 66 69 6c 65 73 20 7b  -closeallfiles {
edc0: 20 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74 65   expr {$::sqlite
edd0: 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74  _open_file_count
ede0: 3e 30 7d 20 7d 20 7b 30 7d 0a 20 20 7d 0a 20 20  >0} } {0}.  }.  
edf0: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 6f 70 65  set ::sqlite_ope
ee00: 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 30 0a 0a  n_file_count 0..
ee10: 20 20 23 20 54 65 73 74 20 74 68 61 74 20 74 68    # Test that th
ee20: 65 20 67 6c 6f 62 61 6c 20 22 73 68 61 72 65 64  e global "shared
ee30: 2d 63 61 63 68 65 22 20 73 65 74 74 69 6e 67 20  -cache" setting 
ee40: 77 61 73 20 6e 6f 74 20 61 6c 74 65 72 65 64 20  was not altered 
ee50: 62 79 0a 20 20 23 20 74 68 65 20 74 65 73 74 20  by.  # the test 
ee60: 73 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69 66  script..  #.  if
ee70: 63 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f 63  capable shared_c
ee80: 61 63 68 65 20 7b 0a 20 20 20 20 73 65 74 20 72  ache {.    set r
ee90: 65 73 20 5b 65 78 70 72 20 7b 5b 73 71 6c 69 74  es [expr {[sqlit
eea0: 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65 64  e3_enable_shared
eeb0: 5f 63 61 63 68 65 5d 20 3d 3d 20 24 73 63 73 7d  _cache] == $scs}
eec0: 5d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 7b  ].    do_test ${
eed0: 74 61 69 6c 7d 2d 73 68 61 72 65 64 63 61 63 68  tail}-sharedcach
eee0: 65 73 65 74 74 69 6e 67 20 5b 6c 69 73 74 20 73  esetting [list s
eef0: 65 74 20 7b 7d 20 24 72 65 73 5d 20 31 0a 20 20  et {} $res] 1.  
ef00: 7d 0a 0a 20 20 23 20 41 64 64 20 73 6f 6d 65 20  }..  # Add some 
ef10: 69 6e 66 6f 20 74 6f 20 74 68 65 20 6f 75 74 70  info to the outp
ef20: 75 74 2e 0a 20 20 23 0a 20 20 6f 75 74 70 75 74  ut..  #.  output
ef30: 32 20 22 54 69 6d 65 3a 20 24 74 61 69 6c 20 24  2 "Time: $tail $
ef40: 6d 73 20 6d 73 22 0a 20 20 73 68 6f 77 5f 6d 65  ms ms".  show_me
ef50: 6d 73 74 61 74 73 0a 7d 0a 0a 23 20 4f 70 65 6e  mstats.}..# Open
ef60: 20 61 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f   a new connectio
ef70: 6e 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74 65  n on database te
ef80: 73 74 2e 64 62 20 61 6e 64 20 65 78 65 63 75 74  st.db and execut
ef90: 65 20 74 68 65 20 53 51 4c 20 73 63 72 69 70 74  e the SQL script
efa0: 0a 23 20 73 75 70 70 6c 69 65 64 20 61 73 20 61  .# supplied as a
efb0: 6e 20 61 72 67 75 6d 65 6e 74 2e 20 42 65 66 6f  n argument. Befo
efc0: 72 65 20 72 65 74 75 72 6e 69 6e 67 2c 20 63 6c  re returning, cl
efd0: 6f 73 65 20 74 68 65 20 6e 65 77 20 63 6f 6e 65  ose the new cone
efe0: 63 74 69 6f 6e 20 61 6e 64 0a 23 20 72 65 73 74  ction and.# rest
eff0: 6f 72 65 20 74 68 65 20 34 20 62 79 74 65 20 66  ore the 4 byte f
f000: 69 65 6c 64 73 20 73 74 61 72 74 69 6e 67 20 61  ields starting a
f010: 74 20 68 65 61 64 65 72 20 6f 66 66 73 65 74 73  t header offsets
f020: 20 32 38 2c 20 39 32 20 61 6e 64 20 39 36 0a 23   28, 92 and 96.#
f030: 20 74 6f 20 74 68 65 20 76 61 6c 75 65 73 20 74   to the values t
f040: 68 65 79 20 68 65 6c 64 20 62 65 66 6f 72 65 20  hey held before 
f050: 74 68 65 20 53 51 4c 20 77 61 73 20 65 78 65 63  the SQL was exec
f060: 75 74 65 64 2e 20 54 68 69 73 20 73 69 6d 75 6c  uted. This simul
f070: 61 74 65 73 0a 23 20 61 20 77 72 69 74 65 20 62  ates.# a write b
f080: 79 20 61 20 70 72 65 2d 33 2e 37 2e 30 20 63 6c  y a pre-3.7.0 cl
f090: 69 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 71 6c  ient..#.proc sql
f0a0: 33 36 32 33 31 20 7b 73 71 6c 7d 20 7b 0a 20 20  36231 {sql} {.  
f0b0: 73 65 74 20 42 20 5b 68 65 78 69 6f 5f 72 65 61  set B [hexio_rea
f0c0: 64 20 74 65 73 74 2e 64 62 20 39 32 20 38 5d 0a  d test.db 92 8].
f0d0: 20 20 73 65 74 20 41 20 5b 68 65 78 69 6f 5f 72    set A [hexio_r
f0e0: 65 61 64 20 74 65 73 74 2e 64 62 20 32 38 20 34  ead test.db 28 4
f0f0: 5d 0a 20 20 73 71 6c 69 74 65 33 20 64 62 33 36  ].  sqlite3 db36
f100: 32 33 31 20 74 65 73 74 2e 64 62 0a 20 20 63 61  231 test.db.  ca
f110: 74 63 68 20 7b 20 64 62 33 36 32 33 31 20 66 75  tch { db36231 fu
f120: 6e 63 20 61 5f 73 74 72 69 6e 67 20 61 5f 73 74  nc a_string a_st
f130: 72 69 6e 67 20 7d 0a 20 20 65 78 65 63 73 71 6c  ring }.  execsql
f140: 20 24 73 71 6c 20 64 62 33 36 32 33 31 0a 20 20   $sql db36231.  
f150: 64 62 33 36 32 33 31 20 63 6c 6f 73 65 0a 20 20  db36231 close.  
f160: 68 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73 74  hexio_write test
f170: 2e 64 62 20 32 38 20 24 41 0a 20 20 68 65 78 69  .db 28 $A.  hexi
f180: 6f 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62 20  o_write test.db 
f190: 39 32 20 24 42 0a 20 20 72 65 74 75 72 6e 20 22  92 $B.  return "
f1a0: 22 0a 7d 0a 0a 70 72 6f 63 20 64 62 5f 73 61 76  ".}..proc db_sav
f1b0: 65 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68  e {} {.  foreach
f1c0: 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70   f [glob -nocomp
f1d0: 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62 2a  lain sv_test.db*
f1e0: 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65 20  ] { forcedelete 
f1f0: 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66  $f }.  foreach f
f200: 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61   [glob -nocompla
f210: 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b 0a 20  in test.db*] {. 
f220: 20 20 20 73 65 74 20 66 32 20 22 73 76 5f 24 66     set f2 "sv_$f
f230: 22 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79 20  ".    forcecopy 
f240: 24 66 20 24 66 32 0a 20 20 7d 0a 7d 0a 70 72 6f  $f $f2.  }.}.pro
f250: 63 20 64 62 5f 73 61 76 65 5f 61 6e 64 5f 63 6c  c db_save_and_cl
f260: 6f 73 65 20 7b 7d 20 7b 0a 20 20 64 62 5f 73 61  ose {} {.  db_sa
f270: 76 65 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20  ve.  catch { db 
f280: 63 6c 6f 73 65 20 7d 0a 20 20 72 65 74 75 72 6e  close }.  return
f290: 20 22 22 0a 7d 0a 70 72 6f 63 20 64 62 5f 72 65   "".}.proc db_re
f2a0: 73 74 6f 72 65 20 7b 7d 20 7b 0a 20 20 66 6f 72  store {} {.  for
f2b0: 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f  each f [glob -no
f2c0: 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62  complain test.db
f2d0: 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65  *] { forcedelete
f2e0: 20 24 66 20 7d 0a 20 20 66 6f 72 65 61 63 68 20   $f }.  foreach 
f2f0: 66 32 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70  f2 [glob -nocomp
f300: 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e 64 62 2a  lain sv_test.db*
f310: 5d 20 7b 0a 20 20 20 20 73 65 74 20 66 20 5b 73  ] {.    set f [s
f320: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 66 32 20  tring range $f2 
f330: 33 20 65 6e 64 5d 0a 20 20 20 20 66 6f 72 63 65  3 end].    force
f340: 63 6f 70 79 20 24 66 32 20 24 66 0a 20 20 7d 0a  copy $f2 $f.  }.
f350: 7d 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f 72  }.proc db_restor
f360: 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20 7b 7b 64  e_and_reopen {{d
f370: 62 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d 20  bfile test.db}} 
f380: 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20 63  {.  catch { db c
f390: 6c 6f 73 65 20 7d 0a 20 20 64 62 5f 72 65 73 74  lose }.  db_rest
f3a0: 6f 72 65 0a 20 20 73 71 6c 69 74 65 33 20 64 62  ore.  sqlite3 db
f3b0: 20 24 64 62 66 69 6c 65 0a 7d 0a 70 72 6f 63 20   $dbfile.}.proc 
f3c0: 64 62 5f 64 65 6c 65 74 65 5f 61 6e 64 5f 72 65  db_delete_and_re
f3d0: 6f 70 65 6e 20 7b 7b 66 69 6c 65 20 74 65 73 74  open {{file test
f3e0: 2e 64 62 7d 7d 20 7b 0a 20 20 63 61 74 63 68 20  .db}} {.  catch 
f3f0: 7b 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20 66  { db close }.  f
f400: 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d  oreach f [glob -
f410: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e  nocomplain test.
f420: 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65  db*] { forcedele
f430: 74 65 20 24 66 20 7d 0a 20 20 73 71 6c 69 74 65  te $f }.  sqlite
f440: 33 20 64 62 20 24 66 69 6c 65 0a 7d 0a 0a 23 20  3 db $file.}..# 
f450: 43 6c 6f 73 65 20 61 6e 79 20 63 6f 6e 6e 65 63  Close any connec
f460: 74 69 6f 6e 73 20 6e 61 6d 65 64 20 5b 64 62 5d  tions named [db]
f470: 2c 20 5b 64 62 32 5d 20 6f 72 20 5b 64 62 33 5d  , [db2] or [db3]
f480: 2e 20 54 68 65 6e 20 75 73 65 20 73 71 6c 69 74  . Then use sqlit
f490: 65 33 5f 63 6f 6e 66 69 67 0a 23 20 74 6f 20 63  e3_config.# to c
f4a0: 6f 6e 66 69 67 75 72 65 20 74 68 65 20 73 69 7a  onfigure the siz
f4b0: 65 20 6f 66 20 74 68 65 20 50 41 47 45 43 41 43  e of the PAGECAC
f4c0: 48 45 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 75 73  HE allocation us
f4d0: 69 6e 67 20 74 68 65 20 70 61 72 61 6d 65 74 65  ing the paramete
f4e0: 72 73 0a 23 20 70 72 6f 76 69 64 65 64 20 74 6f  rs.# provided to
f4f0: 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 2e 20 53   this command. S
f500: 61 76 65 20 74 68 65 20 6f 6c 64 20 50 41 47 45  ave the old PAGE
f510: 43 41 43 48 45 20 70 61 72 61 6d 65 74 65 72 73  CACHE parameters
f520: 20 69 6e 20 61 20 67 6c 6f 62 61 6c 20 0a 23 20   in a global .# 
f530: 76 61 72 69 61 62 6c 65 20 73 6f 20 74 68 61 74  variable so that
f540: 20 5b 74 65 73 74 5f 72 65 73 74 6f 72 65 5f 63   [test_restore_c
f550: 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65 5d  onfig_pagecache]
f560: 20 63 61 6e 20 72 65 73 74 6f 72 65 20 74 68 65   can restore the
f570: 20 70 72 65 76 69 6f 75 73 0a 23 20 63 6f 6e 66   previous.# conf
f580: 69 67 75 72 61 74 69 6f 6e 2e 0a 23 0a 23 20 42  iguration..#.# B
f590: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c  efore returning,
f5a0: 20 72 65 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69   reopen connecti
f5b0: 6f 6e 20 5b 64 62 5d 20 6f 6e 20 66 69 6c 65 20  on [db] on file 
f5c0: 74 65 73 74 2e 64 62 2e 0a 23 0a 70 72 6f 63 20  test.db..#.proc 
f5d0: 74 65 73 74 5f 73 65 74 5f 63 6f 6e 66 69 67 5f  test_set_config_
f5e0: 70 61 67 65 63 61 63 68 65 20 7b 73 7a 20 6e 50  pagecache {sz nP
f5f0: 67 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 64 62  g} {.  catch {db
f600: 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20   close}.  catch 
f610: 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61  {db2 close}.  ca
f620: 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a  tch {db3 close}.
f630: 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74 64  .  sqlite3_shutd
f640: 6f 77 6e 0a 20 20 73 65 74 20 3a 3a 6f 6c 64 5f  own.  set ::old_
f650: 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69 67  pagecache_config
f660: 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67   [sqlite3_config
f670: 5f 70 61 67 65 63 61 63 68 65 20 24 73 7a 20 24  _pagecache $sz $
f680: 6e 50 67 5d 0a 20 20 73 71 6c 69 74 65 33 5f 69  nPg].  sqlite3_i
f690: 6e 69 74 69 61 6c 69 7a 65 0a 20 20 61 75 74 6f  nitialize.  auto
f6a0: 69 6e 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75 6e  install_test_fun
f6b0: 63 74 69 6f 6e 73 0a 20 20 72 65 73 65 74 5f 64  ctions.  reset_d
f6c0: 62 0a 7d 0a 0a 23 20 43 6c 6f 73 65 20 61 6e 79  b.}..# Close any
f6d0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 6e 61 6d   connections nam
f6e0: 65 64 20 5b 64 62 5d 2c 20 5b 64 62 32 5d 20 6f  ed [db], [db2] o
f6f0: 72 20 5b 64 62 33 5d 2e 20 54 68 65 6e 20 75 73  r [db3]. Then us
f700: 65 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  e sqlite3_config
f710: 0a 23 20 74 6f 20 63 6f 6e 66 69 67 75 72 65 20  .# to configure 
f720: 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  the size of the 
f730: 50 41 47 45 43 41 43 48 45 20 61 6c 6c 6f 63 61  PAGECACHE alloca
f740: 74 69 6f 6e 20 74 6f 20 74 68 65 20 73 69 7a 65  tion to the size
f750: 20 73 61 76 65 64 20 69 6e 0a 23 20 74 68 65 20   saved in.# the 
f760: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20  global variable 
f770: 62 79 20 61 6e 20 65 61 72 6c 69 65 72 20 63 61  by an earlier ca
f780: 6c 6c 20 74 6f 20 5b 74 65 73 74 5f 73 65 74 5f  ll to [test_set_
f790: 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68 65  config_pagecache
f7a0: 5d 2e 0a 23 0a 23 20 42 65 66 6f 72 65 20 72 65  ]..#.# Before re
f7b0: 74 75 72 6e 69 6e 67 2c 20 72 65 6f 70 65 6e 20  turning, reopen 
f7c0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64 62 5d 20  connection [db] 
f7d0: 6f 6e 20 66 69 6c 65 20 74 65 73 74 2e 64 62 2e  on file test.db.
f7e0: 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 72 65 73  .#.proc test_res
f7f0: 74 6f 72 65 5f 63 6f 6e 66 69 67 5f 70 61 67 65  tore_config_page
f800: 63 61 63 68 65 20 7b 7d 20 7b 0a 20 20 63 61 74  cache {} {.  cat
f810: 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20  ch {db close}.  
f820: 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65  catch {db2 close
f830: 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20 63  }.  catch {db3 c
f840: 6c 6f 73 65 7d 0a 0a 20 20 73 71 6c 69 74 65 33  lose}..  sqlite3
f850: 5f 73 68 75 74 64 6f 77 6e 0a 20 20 65 76 61 6c  _shutdown.  eval
f860: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 5f   sqlite3_config_
f870: 70 61 67 65 63 61 63 68 65 20 24 3a 3a 6f 6c 64  pagecache $::old
f880: 5f 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69  _pagecache_confi
f890: 67 0a 20 20 75 6e 73 65 74 20 3a 3a 6f 6c 64 5f  g.  unset ::old_
f8a0: 70 61 67 65 63 61 63 68 65 5f 63 6f 6e 66 69 67  pagecache_config
f8b0: 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74   .  sqlite3_init
f8c0: 69 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73  ialize.  autoins
f8d0: 74 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69  tall_test_functi
f8e0: 6f 6e 73 0a 20 20 73 71 6c 69 74 65 33 20 64 62  ons.  sqlite3 db
f8f0: 20 74 65 73 74 2e 64 62 0a 7d 0a 0a 70 72 6f 63   test.db.}..proc
f900: 20 74 65 73 74 5f 66 69 6e 64 5f 62 69 6e 61 72   test_find_binar
f910: 79 20 7b 6e 6d 7d 20 7b 0a 20 20 69 66 20 7b 24  y {nm} {.  if {$
f920: 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70  ::tcl_platform(p
f930: 6c 61 74 66 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f  latform)=="windo
f940: 77 73 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 72  ws"} {.    set r
f950: 65 74 20 22 24 6e 6d 2e 65 78 65 22 0a 20 20 7d  et "$nm.exe".  }
f960: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
f970: 72 65 74 20 24 6e 6d 0a 20 20 7d 0a 20 20 73 65  ret $nm.  }.  se
f980: 74 20 72 65 74 20 5b 66 69 6c 65 20 6e 6f 72 6d  t ret [file norm
f990: 61 6c 69 7a 65 20 5b 66 69 6c 65 20 6a 6f 69 6e  alize [file join
f9a0: 20 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 54   $::cmdlinearg(T
f9b0: 45 53 54 46 49 58 54 55 52 45 5f 48 4f 4d 45 29  ESTFIXTURE_HOME)
f9c0: 20 24 72 65 74 5d 5d 0a 20 20 69 66 20 7b 21 5b   $ret]].  if {![
f9d0: 66 69 6c 65 20 65 78 65 63 75 74 61 62 6c 65 20  file executable 
f9e0: 24 72 65 74 5d 7d 20 7b 0a 20 20 20 20 66 69 6e  $ret]} {.    fin
f9f0: 69 73 68 5f 74 65 73 74 0a 20 20 20 20 72 65 74  ish_test.    ret
fa00: 75 72 6e 20 22 22 0a 20 20 7d 0a 20 20 72 65 74  urn "".  }.  ret
fa10: 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23 20 46 69  urn $ret.}..# Fi
fa20: 6e 64 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  nd the name of t
fa30: 68 65 20 27 73 68 65 6c 6c 27 20 65 78 65 63 75  he 'shell' execu
fa40: 74 61 62 6c 65 20 28 65 2e 67 2e 20 22 73 71 6c  table (e.g. "sql
fa50: 69 74 65 33 2e 65 78 65 22 29 20 74 6f 20 75 73  ite3.exe") to us
fa60: 65 20 66 6f 72 0a 23 20 74 68 65 20 74 65 73 74  e for.# the test
fa70: 73 20 69 6e 20 73 68 65 6c 6c 5b 31 2d 35 5d 2e  s in shell[1-5].
fa80: 74 65 73 74 2e 20 49 66 20 6e 6f 20 73 75 63 68  test. If no such
fa90: 20 65 78 65 63 75 74 61 62 6c 65 20 63 61 6e 20   executable can 
faa0: 62 65 20 66 6f 75 6e 64 2c 20 69 6e 76 6f 6b 65  be found, invoke
fab0: 0a 23 20 5b 66 69 6e 69 73 68 5f 74 65 73 74 20  .# [finish_test 
fac0: 3b 20 72 65 74 75 72 6e 5d 20 69 6e 20 74 68 65  ; return] in the
fad0: 20 63 61 6c 6c 65 72 73 20 63 6f 6e 74 65 78 74   callers context
fae0: 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 66 69  ..#.proc test_fi
faf0: 6e 64 5f 63 6c 69 20 7b 7d 20 7b 0a 20 20 73 65  nd_cli {} {.  se
fb00: 74 20 70 72 6f 67 20 5b 74 65 73 74 5f 66 69 6e  t prog [test_fin
fb10: 64 5f 62 69 6e 61 72 79 20 73 71 6c 69 74 65 33  d_binary sqlite3
fb20: 5d 0a 20 20 69 66 20 7b 24 70 72 6f 67 3d 3d 22  ].  if {$prog=="
fb30: 22 7d 20 7b 20 72 65 74 75 72 6e 20 2d 63 6f 64  "} { return -cod
fb40: 65 20 72 65 74 75 72 6e 20 7d 0a 20 20 72 65 74  e return }.  ret
fb50: 75 72 6e 20 24 70 72 6f 67 0a 7d 0a 0a 23 20 46  urn $prog.}..# F
fb60: 69 6e 64 20 74 68 65 20 6e 61 6d 65 20 6f 66 20  ind the name of 
fb70: 74 68 65 20 27 73 71 6c 64 69 66 66 27 20 65 78  the 'sqldiff' ex
fb80: 65 63 75 74 61 62 6c 65 20 28 65 2e 67 2e 20 22  ecutable (e.g. "
fb90: 73 71 6c 69 74 65 33 2e 65 78 65 22 29 20 74 6f  sqlite3.exe") to
fba0: 20 75 73 65 20 66 6f 72 0a 23 20 74 68 65 20 74   use for.# the t
fbb0: 65 73 74 73 20 69 6e 20 73 71 6c 64 69 66 66 20  ests in sqldiff 
fbc0: 74 65 73 74 73 2e 20 49 66 20 6e 6f 20 73 75 63  tests. If no suc
fbd0: 68 20 65 78 65 63 75 74 61 62 6c 65 20 63 61 6e  h executable can
fbe0: 20 62 65 20 66 6f 75 6e 64 2c 20 69 6e 76 6f 6b   be found, invok
fbf0: 65 0a 23 20 5b 66 69 6e 69 73 68 5f 74 65 73 74  e.# [finish_test
fc00: 20 3b 20 72 65 74 75 72 6e 5d 20 69 6e 20 74 68   ; return] in th
fc10: 65 20 63 61 6c 6c 65 72 73 20 63 6f 6e 74 65 78  e callers contex
fc20: 74 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 5f 66  t..#.proc test_f
fc30: 69 6e 64 5f 73 71 6c 64 69 66 66 20 7b 7d 20 7b  ind_sqldiff {} {
fc40: 0a 20 20 73 65 74 20 70 72 6f 67 20 5b 74 65 73  .  set prog [tes
fc50: 74 5f 66 69 6e 64 5f 62 69 6e 61 72 79 20 73 71  t_find_binary sq
fc60: 6c 64 69 66 66 5d 0a 20 20 69 66 20 7b 24 70 72  ldiff].  if {$pr
fc70: 6f 67 3d 3d 22 22 7d 20 7b 20 72 65 74 75 72 6e  og==""} { return
fc80: 20 2d 63 6f 64 65 20 72 65 74 75 72 6e 20 7d 0a   -code return }.
fc90: 20 20 72 65 74 75 72 6e 20 24 70 72 6f 67 0a 7d    return $prog.}
fca0: 0a 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62 72  ...# If the libr
fcb0: 61 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64 20  ary is compiled 
fcc0: 77 69 74 68 20 74 68 65 20 53 51 4c 49 54 45 5f  with the SQLITE_
fcd0: 44 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43 55  DEFAULT_AUTOVACU
fce0: 55 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20 74  UM macro set.# t
fcf0: 6f 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e  o non-zero, then
fd00: 20 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c 20   set the global 
fd10: 76 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56 41  variable $AUTOVA
fd20: 43 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41  CUUM to 1..set A
fd30: 55 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69 74  UTOVACUUM $sqlit
fd40: 65 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75 6c  e_options(defaul
fd50: 74 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a 23  t_autovacuum)..#
fd60: 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 46   Make sure the F
fd70: 54 53 20 65 6e 68 61 6e 63 65 64 20 71 75 65 72  TS enhanced quer
fd80: 79 20 73 79 6e 74 61 78 20 69 73 20 64 69 73 61  y syntax is disa
fd90: 62 6c 65 64 2e 0a 73 65 74 20 73 71 6c 69 74 65  bled..set sqlite
fda0: 5f 66 74 73 33 5f 65 6e 61 62 6c 65 5f 70 61 72  _fts3_enable_par
fdb0: 65 6e 74 68 65 73 65 73 20 30 0a 0a 23 20 44 75  entheses 0..# Du
fdc0: 72 69 6e 67 20 74 65 73 74 69 6e 67 2c 20 61 73  ring testing, as
fdd0: 73 75 6d 65 20 74 68 61 74 20 61 6c 6c 20 64 61  sume that all da
fde0: 74 61 62 61 73 65 20 66 69 6c 65 73 20 61 72 65  tabase files are
fdf0: 20 77 65 6c 6c 2d 66 6f 72 6d 65 64 2e 20 20 54   well-formed.  T
fe00: 68 65 0a 23 20 66 65 77 20 74 65 73 74 20 63 61  he.# few test ca
fe10: 73 65 73 20 74 68 61 74 20 64 65 6c 69 62 65 72  ses that deliber
fe20: 61 74 65 6c 79 20 63 6f 72 72 75 70 74 20 64 61  ately corrupt da
fe30: 74 61 62 61 73 65 20 66 69 6c 65 73 20 73 68 6f  tabase files sho
fe40: 75 6c 64 20 72 65 73 63 69 6e 64 20 0a 23 20 74  uld rescind .# t
fe50: 68 69 73 20 73 65 74 74 69 6e 67 20 62 79 20 69  his setting by i
fe60: 6e 76 6f 6b 69 6e 67 20 22 64 61 74 61 62 61 73  nvoking "databas
fe70: 65 5f 63 61 6e 5f 62 65 5f 63 6f 72 72 75 70 74  e_can_be_corrupt
fe80: 22 0a 23 0a 64 61 74 61 62 61 73 65 5f 6e 65 76  ".#.database_nev
fe90: 65 72 5f 63 6f 72 72 75 70 74 0a 0a 73 6f 75 72  er_corrupt..sour
fea0: 63 65 20 24 74 65 73 74 64 69 72 2f 74 68 72 65  ce $testdir/thre
feb0: 61 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f  ad_common.tcl.so
fec0: 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d 61  urce $testdir/ma
fed0: 6c 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a  lloc_common.tcl.