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

Artifact a2c3874cb3768d4369940e7235871f8a85a75580:


0000: 23 20 32 30 30 31 20 53 65 70 74 65 6d 62 65 72  # 2001 September
0010: 20 31 35 0a 23 0a 23 20 54 68 65 20 61 75 74 68   15.#.# The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 23 20 61 20 6c 65 67  place of.# a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23  is a blessing:.#
0080: 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 64 6f  .#    May you do
0090: 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76   good and not ev
00a0: 69 6c 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75  il..#    May you
00b0: 20 66 69 6e 64 20 66 6f 72 67 69 76 65 6e 65 73   find forgivenes
00c0: 73 20 66 6f 72 20 79 6f 75 72 73 65 6c 66 20 61  s for yourself a
00d0: 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 68 65 72  nd forgive other
00e0: 73 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20  s..#    May you 
00f0: 73 68 61 72 65 20 66 72 65 65 6c 79 2c 20 6e 65  share freely, ne
0100: 76 65 72 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20  ver taking more 
0110: 74 68 61 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23  than you give..#
0120: 0a 23 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .#**************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73  *********.# This
0170: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0180: 20 73 6f 6d 65 20 63 6f 6d 6d 6f 6e 20 54 43 4c   some common TCL
0190: 20 72 6f 75 74 69 6e 65 73 20 75 73 65 64 20 66   routines used f
01a0: 6f 72 20 72 65 67 72 65 73 73 69 6f 6e 0a 23 20  or regression.# 
01b0: 74 65 73 74 69 6e 67 20 74 68 65 20 53 51 4c 69  testing the SQLi
01c0: 74 65 20 6c 69 62 72 61 72 79 0a 23 0a 23 20 24  te library.#.# $
01d0: 49 64 3a 20 74 65 73 74 65 72 2e 74 63 6c 2c 76  Id: tester.tcl,v
01e0: 20 31 2e 31 34 33 20 32 30 30 39 2f 30 34 2f 30   1.143 2009/04/0
01f0: 39 20 30 31 3a 32 33 3a 34 39 20 64 72 68 20 45  9 01:23:49 drh E
0200: 78 70 20 24 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  xp $..#---------
0210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0240: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0250: 0a 23 20 54 68 65 20 63 6f 6d 6d 61 6e 64 73 20  .# The commands 
0260: 70 72 6f 76 69 64 65 64 20 62 79 20 74 68 65 20  provided by the 
0270: 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c  code in this fil
0280: 65 20 74 6f 20 68 65 6c 70 20 77 69 74 68 20 63  e to help with c
0290: 72 65 61 74 69 6e 67 20 0a 23 20 74 65 73 74 20  reating .# test 
02a0: 63 61 73 65 73 20 61 72 65 20 61 73 20 66 6f 6c  cases are as fol
02b0: 6c 6f 77 73 3a 0a 23 0a 23 20 43 6f 6d 6d 61 6e  lows:.#.# Comman
02c0: 64 73 20 74 6f 20 6d 61 6e 69 70 75 6c 61 74 65  ds to manipulate
02d0: 20 74 68 65 20 64 62 20 61 6e 64 20 74 68 65 20   the db and the 
02e0: 66 69 6c 65 2d 73 79 73 74 65 6d 20 61 74 20 61  file-system at a
02f0: 20 68 69 67 68 20 6c 65 76 65 6c 3a 0a 23 0a 23   high level:.#.#
0300: 20 20 20 20 20 20 63 6f 70 79 5f 66 69 6c 65 20        copy_file 
0310: 20 20 20 20 20 20 20 20 20 20 20 20 20 46 52 4f               FRO
0320: 4d 20 54 4f 0a 23 20 20 20 20 20 20 64 65 6c 65  M TO.#      dele
0330: 74 65 5f 66 69 6c 65 20 20 20 20 20 20 20 20 20  te_file         
0340: 20 20 20 46 49 4c 45 4e 41 4d 45 0a 23 20 20 20     FILENAME.#   
0350: 20 20 20 64 72 6f 70 5f 61 6c 6c 5f 74 61 62 6c     drop_all_tabl
0360: 65 73 20 20 20 20 20 20 20 20 3f 44 42 3f 0a 23  es        ?DB?.#
0370: 20 20 20 20 20 20 66 6f 72 63 65 63 6f 70 79 20        forcecopy 
0380: 20 20 20 20 20 20 20 20 20 20 20 20 20 46 52 4f               FRO
0390: 4d 20 54 4f 0a 23 20 20 20 20 20 20 66 6f 72 63  M TO.#      forc
03a0: 65 64 65 6c 65 74 65 20 20 20 20 20 20 20 20 20  edelete         
03b0: 20 20 20 46 49 4c 45 4e 41 4d 45 0a 23 0a 23 20     FILENAME.#.# 
03c0: 54 65 73 74 20 74 68 65 20 63 61 70 61 62 69 6c  Test the capabil
03d0: 69 74 79 20 6f 66 20 74 68 65 20 53 51 4c 69 74  ity of the SQLit
03e0: 65 20 76 65 72 73 69 6f 6e 20 62 75 69 6c 74 20  e version built 
03f0: 69 6e 74 6f 20 74 68 65 20 69 6e 74 65 72 70 72  into the interpr
0400: 65 74 65 72 20 74 6f 0a 23 20 64 65 74 65 72 6d  eter to.# determ
0410: 69 6e 65 20 69 66 20 61 20 73 70 65 63 69 66 69  ine if a specifi
0420: 63 20 74 65 73 74 20 63 61 6e 20 62 65 20 72 75  c test can be ru
0430: 6e 3a 0a 23 0a 23 20 20 20 20 20 20 69 66 63 61  n:.#.#      ifca
0440: 70 61 62 6c 65 20 20 20 20 20 20 20 20 20 20 20  pable           
0450: 20 20 20 45 58 50 52 0a 23 0a 23 20 43 61 6c 75     EXPR.#.# Calu
0460: 6c 61 74 65 20 63 68 65 63 6b 73 75 6d 73 20 62  late checksums b
0470: 61 73 65 64 20 6f 6e 20 64 61 74 61 62 61 73 65  ased on database
0480: 20 63 6f 6e 74 65 6e 74 73 3a 0a 23 0a 23 20 20   contents:.#.#  
0490: 20 20 20 20 64 62 63 6b 73 75 6d 20 20 20 20 20      dbcksum     
04a0: 20 20 20 20 20 20 20 20 20 20 20 44 42 20 44 42             DB DB
04b0: 4e 41 4d 45 0a 23 20 20 20 20 20 20 61 6c 6c 63  NAME.#      allc
04c0: 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20 20  ksum            
04d0: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 63     ?DB?.#      c
04e0: 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20 20  ksum            
04f0: 20 20 20 20 20 20 3f 44 42 3f 0a 23 0a 23 20 43        ?DB?.#.# C
0500: 6f 6d 6d 61 6e 64 73 20 74 6f 20 65 78 65 63 75  ommands to execu
0510: 74 65 2f 65 78 70 6c 61 69 6e 20 53 51 4c 20 73  te/explain SQL s
0520: 74 61 74 65 6d 65 6e 74 73 3a 0a 23 0a 23 20 20  tatements:.#.#  
0530: 20 20 20 20 73 74 65 70 73 71 6c 20 20 20 20 20      stepsql     
0540: 20 20 20 20 20 20 20 20 20 20 20 44 42 20 53 51             DB SQ
0550: 4c 0a 23 20 20 20 20 20 20 65 78 65 63 73 71 6c  L.#      execsql
0560: 32 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2               
0570: 53 51 4c 0a 23 20 20 20 20 20 20 65 78 70 6c 61  SQL.#      expla
0580: 69 6e 5f 6e 6f 5f 74 72 61 63 65 20 20 20 20 20  in_no_trace     
0590: 20 20 53 51 4c 0a 23 20 20 20 20 20 20 65 78 70    SQL.#      exp
05a0: 6c 61 69 6e 20 20 20 20 20 20 20 20 20 20 20 20  lain            
05b0: 20 20 20 20 53 51 4c 20 3f 44 42 3f 0a 23 20 20      SQL ?DB?.#  
05c0: 20 20 20 20 63 61 74 63 68 73 71 6c 20 20 20 20      catchsql    
05d0: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 20 3f             SQL ?
05e0: 44 42 3f 0a 23 20 20 20 20 20 20 65 78 65 63 73  DB?.#      execs
05f0: 71 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ql              
0600: 20 20 53 51 4c 20 3f 44 42 3f 0a 23 0a 23 20 43    SQL ?DB?.#.# C
0610: 6f 6d 6d 61 6e 64 73 20 74 6f 20 72 75 6e 20 74  ommands to run t
0620: 65 73 74 20 63 61 73 65 73 3a 0a 23 0a 23 20 20  est cases:.#.#  
0630: 20 20 20 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73      do_ioerr_tes
0640: 74 20 20 20 20 20 20 20 20 20 20 54 45 53 54 4e  t          TESTN
0650: 41 4d 45 20 41 52 47 53 2e 2e 2e 0a 23 20 20 20  AME ARGS....#   
0660: 20 20 20 63 72 61 73 68 73 71 6c 20 20 20 20 20     crashsql     
0670: 20 20 20 20 20 20 20 20 20 20 41 52 47 53 2e 2e            ARGS..
0680: 2e 0a 23 20 20 20 20 20 20 69 6e 74 65 67 72 69  ..#      integri
0690: 74 79 5f 63 68 65 63 6b 20 20 20 20 20 20 20 20  ty_check        
06a0: 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f 0a 23 20  TESTNAME ?DB?.# 
06b0: 20 20 20 20 20 64 6f 5f 74 65 73 74 20 20 20 20       do_test    
06c0: 20 20 20 20 20 20 20 20 20 20 20 20 54 45 53 54              TEST
06d0: 4e 41 4d 45 20 53 43 52 49 50 54 20 45 58 50 45  NAME SCRIPT EXPE
06e0: 43 54 45 44 0a 23 20 20 20 20 20 20 64 6f 5f 65  CTED.#      do_e
06f0: 78 65 63 73 71 6c 5f 74 65 73 74 20 20 20 20 20  xecsql_test     
0700: 20 20 20 54 45 53 54 4e 41 4d 45 20 53 51 4c 20     TESTNAME SQL 
0710: 45 58 50 45 43 54 45 44 0a 23 20 20 20 20 20 20  EXPECTED.#      
0720: 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74  do_catchsql_test
0730: 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20         TESTNAME 
0740: 53 51 4c 20 45 58 50 45 43 54 45 44 0a 23 0a 23  SQL EXPECTED.#.#
0750: 20 43 6f 6d 6d 61 6e 64 73 20 70 72 6f 76 69 64   Commands provid
0760: 69 6e 67 20 61 20 6c 6f 77 65 72 20 6c 65 76 65  ing a lower leve
0770: 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 74  l interface to t
0780: 68 65 20 67 6c 6f 62 61 6c 20 74 65 73 74 20 63  he global test c
0790: 6f 75 6e 74 65 72 73 3a 0a 23 0a 23 20 20 20 20  ounters:.#.#    
07a0: 20 20 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74    set_test_count
07b0: 65 72 20 20 20 20 20 20 20 43 4f 55 4e 54 45 52  er       COUNTER
07c0: 20 3f 56 41 4c 55 45 3f 0a 23 20 20 20 20 20 20   ?VALUE?.#      
07d0: 6f 6d 69 74 5f 74 65 73 74 20 20 20 20 20 20 20  omit_test       
07e0: 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20         TESTNAME 
07f0: 52 45 41 53 4f 4e 20 3f 41 50 50 45 4e 44 3f 0a  REASON ?APPEND?.
0800: 23 20 20 20 20 20 20 66 61 69 6c 5f 74 65 73 74  #      fail_test
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 45                TE
0820: 53 54 4e 41 4d 45 0a 23 20 20 20 20 20 20 69 6e  STNAME.#      in
0830: 63 72 5f 6e 74 65 73 74 0a 23 0a 23 20 43 6f 6d  cr_ntest.#.# Com
0840: 6d 61 6e 64 20 72 75 6e 20 61 74 20 74 68 65 20  mand run at the 
0850: 65 6e 64 20 6f 66 20 65 61 63 68 20 74 65 73 74  end of each test
0860: 20 66 69 6c 65 3a 0a 23 0a 23 20 20 20 20 20 20   file:.#.#      
0870: 66 69 6e 69 73 68 5f 74 65 73 74 0a 23 0a 23 20  finish_test.#.# 
0880: 43 6f 6d 6d 61 6e 64 73 20 74 6f 20 68 65 6c 70  Commands to help
0890: 20 63 72 65 61 74 65 20 74 65 73 74 20 66 69 6c   create test fil
08a0: 65 73 20 74 68 61 74 20 72 75 6e 20 77 69 74 68  es that run with
08b0: 20 74 68 65 20 22 57 41 4c 22 20 61 6e 64 20 6f   the "WAL" and o
08c0: 74 68 65 72 0a 23 20 70 65 72 6d 75 74 61 74 69  ther.# permutati
08d0: 6f 6e 73 20 28 73 65 65 20 66 69 6c 65 20 70 65  ons (see file pe
08e0: 72 6d 75 74 61 74 69 6f 6e 73 2e 74 65 73 74 29  rmutations.test)
08f0: 3a 0a 23 0a 23 20 20 20 20 20 20 77 61 6c 5f 69  :.#.#      wal_i
0900: 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23 20 20 20 20  s_wal_mode.#    
0910: 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e 61    wal_set_journa
0920: 6c 5f 6d 6f 64 65 20 20 20 3f 44 42 3f 0a 23 20  l_mode   ?DB?.# 
0930: 20 20 20 20 20 77 61 6c 5f 63 68 65 63 6b 5f 6a       wal_check_j
0940: 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 54 45 53 54  ournal_mode TEST
0950: 4e 41 4d 45 3f 44 42 3f 0a 23 20 20 20 20 20 20  NAME?DB?.#      
0960: 70 65 72 6d 75 74 61 74 69 6f 6e 0a 23 20 20 20  permutation.#   
0970: 20 20 20 70 72 65 73 71 6c 0a 23 0a 0a 23 20 53     presql.#..# S
0980: 65 74 20 74 68 65 20 70 72 65 63 69 73 69 6f 6e  et the precision
0990: 20 6f 66 20 46 50 20 61 72 69 74 68 6d 61 74 69   of FP arithmati
09a0: 63 20 75 73 65 64 20 62 79 20 74 68 65 20 69 6e  c used by the in
09b0: 74 65 72 70 72 65 74 65 72 2e 20 41 6e 64 20 0a  terpreter. And .
09c0: 23 20 63 6f 6e 66 69 67 75 72 65 20 53 51 4c 69  # configure SQLi
09d0: 74 65 20 74 6f 20 74 61 6b 65 20 64 61 74 61 62  te to take datab
09e0: 61 73 65 20 66 69 6c 65 20 6c 6f 63 6b 73 20 6f  ase file locks o
09f0: 6e 20 74 68 65 20 70 61 67 65 20 74 68 61 74 20  n the page that 
0a00: 62 65 67 69 6e 73 0a 23 20 36 34 4b 42 20 69 6e  begins.# 64KB in
0a10: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
0a20: 66 69 6c 65 20 69 6e 73 74 65 61 64 20 6f 66 20  file instead of 
0a30: 74 68 65 20 6f 6e 65 20 31 47 42 20 69 6e 2e 20  the one 1GB in. 
0a40: 54 68 69 73 20 6d 65 61 6e 73 0a 23 20 74 68 65  This means.# the
0a50: 20 63 6f 64 65 20 74 68 61 74 20 68 61 6e 64 6c   code that handl
0a60: 65 73 20 74 68 61 74 20 73 70 65 63 69 61 6c 20  es that special 
0a70: 63 61 73 65 20 63 61 6e 20 62 65 20 74 65 73 74  case can be test
0a80: 65 64 20 77 69 74 68 6f 75 74 20 63 72 65 61 74  ed without creat
0a90: 69 6e 67 0a 23 20 76 65 72 79 20 6c 61 72 67 65  ing.# very large
0aa0: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 2e   database files.
0ab0: 0a 23 0a 73 65 74 20 74 63 6c 5f 70 72 65 63 69  .#.set tcl_preci
0ac0: 73 69 6f 6e 20 31 35 0a 73 71 6c 69 74 65 33 5f  sion 15.sqlite3_
0ad0: 74 65 73 74 5f 63 6f 6e 74 72 6f 6c 5f 70 65 6e  test_control_pen
0ae0: 64 69 6e 67 5f 62 79 74 65 20 30 78 30 30 31 30  ding_byte 0x0010
0af0: 30 30 30 0a 0a 0a 23 20 49 66 20 74 68 65 20 70  000...# If the p
0b00: 61 67 65 72 20 63 6f 64 65 63 20 69 73 20 61 76  ager codec is av
0b10: 61 69 6c 61 62 6c 65 2c 20 63 72 65 61 74 65 20  ailable, create 
0b20: 61 20 77 72 61 70 70 65 72 20 66 6f 72 20 74 68  a wrapper for th
0b30: 65 20 5b 73 71 6c 69 74 65 33 5d 20 0a 23 20 63  e [sqlite3] .# c
0b40: 6f 6d 6d 61 6e 64 20 74 68 61 74 20 61 70 70 65  ommand that appe
0b50: 6e 64 73 20 22 2d 6b 65 79 20 7b 78 79 7a 7a 79  nds "-key {xyzzy
0b60: 7d 22 20 74 6f 20 74 68 65 20 63 6f 6d 6d 61 6e  }" to the comman
0b70: 64 20 6c 69 6e 65 2e 20 69 2e 65 2e 20 74 68 69  d line. i.e. thi
0b80: 73 3a 0a 23 0a 23 20 20 20 20 20 73 71 6c 69 74  s:.#.#     sqlit
0b90: 65 33 20 64 62 20 74 65 73 74 2e 64 62 0a 23 0a  e3 db test.db.#.
0ba0: 23 20 62 65 63 6f 6d 65 73 0a 23 0a 23 20 20 20  # becomes.#.#   
0bb0: 20 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73    sqlite3 db tes
0bc0: 74 2e 64 62 20 2d 6b 65 79 20 7b 78 79 7a 7a 79  t.db -key {xyzzy
0bd0: 7d 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f 20 63 6f  }.#.if {[info co
0be0: 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f 6f 72 69  mmand sqlite_ori
0bf0: 67 5d 3d 3d 22 22 7d 20 7b 0a 20 20 72 65 6e 61  g]==""} {.  rena
0c00: 6d 65 20 73 71 6c 69 74 65 33 20 73 71 6c 69 74  me sqlite3 sqlit
0c10: 65 5f 6f 72 69 67 0a 20 20 70 72 6f 63 20 73 71  e_orig.  proc sq
0c20: 6c 69 74 65 33 20 7b 61 72 67 73 7d 20 7b 0a 20  lite3 {args} {. 
0c30: 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20     if {[llength 
0c40: 24 61 72 67 73 5d 3e 3d 32 20 26 26 20 5b 73 74  $args]>=2 && [st
0c50: 72 69 6e 67 20 69 6e 64 65 78 20 5b 6c 69 6e 64  ring index [lind
0c60: 65 78 20 24 61 72 67 73 20 30 5d 20 30 5d 21 3d  ex $args 0] 0]!=
0c70: 22 2d 22 7d 20 7b 0a 20 20 20 20 20 20 23 20 54  "-"} {.      # T
0c80: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 6f  his command is o
0c90: 70 65 6e 69 6e 67 20 61 20 6e 65 77 20 64 61 74  pening a new dat
0ca0: 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  abase connection
0cb0: 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20  ..      #.      
0cc0: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
0cd0: 20 3a 3a 47 28 70 65 72 6d 3a 73 71 6c 69 74 65   ::G(perm:sqlite
0ce0: 33 5f 61 72 67 73 29 5d 7d 20 7b 0a 20 20 20 20  3_args)]} {.    
0cf0: 20 20 20 20 73 65 74 20 61 72 67 73 20 5b 63 6f      set args [co
0d00: 6e 63 61 74 20 24 61 72 67 73 20 24 3a 3a 47 28  ncat $args $::G(
0d10: 70 65 72 6d 3a 73 71 6c 69 74 65 33 5f 61 72 67  perm:sqlite3_arg
0d20: 73 29 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  s)].      }.    
0d30: 20 20 69 66 20 7b 5b 73 71 6c 69 74 65 5f 6f 72    if {[sqlite_or
0d40: 69 67 20 2d 68 61 73 2d 63 6f 64 65 63 5d 20 26  ig -has-codec] &
0d50: 26 20 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  & ![info exists 
0d60: 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f 63 6f 64  ::do_not_use_cod
0d70: 65 63 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 6c  ec]} {.        l
0d80: 61 70 70 65 6e 64 20 61 72 67 73 20 2d 6b 65 79  append args -key
0d90: 20 7b 78 79 7a 7a 79 7d 0a 20 20 20 20 20 20 7d   {xyzzy}.      }
0da0: 0a 0a 20 20 20 20 20 20 73 65 74 20 72 65 73 20  ..      set res 
0db0: 5b 75 70 6c 65 76 65 6c 20 31 20 73 71 6c 69 74  [uplevel 1 sqlit
0dc0: 65 5f 6f 72 69 67 20 24 61 72 67 73 5d 0a 20 20  e_orig $args].  
0dd0: 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78      if {[info ex
0de0: 69 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a 70 72  ists ::G(perm:pr
0df0: 65 73 71 6c 29 5d 7d 20 7b 0a 20 20 20 20 20 20  esql)]} {.      
0e00: 20 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20    [lindex $args 
0e10: 30 5d 20 65 76 61 6c 20 24 3a 3a 47 28 70 65 72  0] eval $::G(per
0e20: 6d 3a 70 72 65 73 71 6c 29 0a 20 20 20 20 20 20  m:presql).      
0e30: 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66  }.      if {[inf
0e40: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72  o exists ::G(per
0e50: 6d 3a 64 62 63 6f 6e 66 69 67 29 5d 7d 20 7b 0a  m:dbconfig)]} {.
0e60: 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a 64 62          set ::db
0e70: 68 61 6e 64 6c 65 20 5b 6c 69 6e 64 65 78 20 24  handle [lindex $
0e80: 61 72 67 73 20 30 5d 0a 20 20 20 20 20 20 20 20  args 0].        
0e90: 75 70 6c 65 76 65 6c 20 23 30 20 24 3a 3a 47 28  uplevel #0 $::G(
0ea0: 70 65 72 6d 3a 64 62 63 6f 6e 66 69 67 29 0a 20  perm:dbconfig). 
0eb0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 65 74       }.      set
0ec0: 20 72 65 73 0a 20 20 20 20 7d 20 65 6c 73 65 20   res.    } else 
0ed0: 7b 0a 20 20 20 20 20 20 23 20 54 68 69 73 20 63  {.      # This c
0ee0: 6f 6d 6d 61 6e 64 20 69 73 20 6e 6f 74 20 6f 70  ommand is not op
0ef0: 65 6e 69 6e 67 20 61 20 6e 65 77 20 64 61 74 61  ening a new data
0f00: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e  base connection.
0f10: 20 50 61 73 73 20 74 68 65 20 0a 20 20 20 20 20   Pass the .     
0f20: 20 23 20 61 72 67 75 6d 65 6e 74 73 20 74 68 72   # arguments thr
0f30: 6f 75 67 68 20 74 6f 20 74 68 65 20 43 20 69 6d  ough to the C im
0f40: 70 6c 65 6d 65 6e 61 74 69 6f 6e 20 61 73 20 74  plemenation as t
0f50: 68 65 20 61 72 65 2e 0a 20 20 20 20 20 20 23 0a  he are..      #.
0f60: 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 31 20        uplevel 1 
0f70: 73 71 6c 69 74 65 5f 6f 72 69 67 20 24 61 72 67  sqlite_orig $arg
0f80: 73 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 70  s.    }.  }.}..p
0f90: 72 6f 63 20 67 65 74 46 69 6c 65 52 65 74 72 69  roc getFileRetri
0fa0: 65 73 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 21 5b  es {} {.  if {![
0fb0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
0fc0: 66 69 6c 65 2d 72 65 74 72 69 65 73 29 5d 7d 20  file-retries)]} 
0fd0: 7b 0a 20 20 20 20 23 0a 20 20 20 20 23 20 4e 4f  {.    #.    # NO
0fe0: 54 45 3a 20 52 65 74 75 72 6e 20 74 68 65 20 64  TE: Return the d
0ff0: 65 66 61 75 6c 74 20 6e 75 6d 62 65 72 20 6f 66  efault number of
1000: 20 72 65 74 72 69 65 73 20 66 6f 72 20 5b 66 69   retries for [fi
1010: 6c 65 5d 20 6f 70 65 72 61 74 69 6f 6e 73 2e 20  le] operations. 
1020: 20 41 0a 20 20 20 20 23 20 20 20 20 20 20 20 76   A.    #       v
1030: 61 6c 75 65 20 6f 66 20 7a 65 72 6f 20 6f 72 20  alue of zero or 
1040: 6c 65 73 73 20 68 65 72 65 20 6d 65 61 6e 73 20  less here means 
1050: 22 64 69 73 61 62 6c 65 64 22 2e 0a 20 20 20 20  "disabled"..    
1060: 23 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 65 78  #.    return [ex
1070: 70 72 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  pr {$::tcl_platf
1080: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 20 65 71  orm(platform) eq
1090: 20 22 77 69 6e 64 6f 77 73 22 20 3f 20 31 30 20   "windows" ? 10 
10a0: 3a 20 30 7d 5d 0a 20 20 7d 0a 20 20 72 65 74 75  : 0}].  }.  retu
10b0: 72 6e 20 24 3a 3a 47 28 66 69 6c 65 2d 72 65 74  rn $::G(file-ret
10c0: 72 69 65 73 29 0a 7d 0a 0a 70 72 6f 63 20 67 65  ries).}..proc ge
10d0: 74 46 69 6c 65 52 65 74 72 79 44 65 6c 61 79 20  tFileRetryDelay 
10e0: 7b 7d 20 7b 0a 20 20 69 66 20 7b 21 5b 69 6e 66  {} {.  if {![inf
10f0: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 66 69 6c  o exists ::G(fil
1100: 65 2d 72 65 74 72 79 2d 64 65 6c 61 79 29 5d 7d  e-retry-delay)]}
1110: 20 7b 0a 20 20 20 20 23 0a 20 20 20 20 23 20 4e   {.    #.    # N
1120: 4f 54 45 3a 20 52 65 74 75 72 6e 20 74 68 65 20  OTE: Return the 
1130: 64 65 66 61 75 6c 74 20 6e 75 6d 62 65 72 20 6f  default number o
1140: 66 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73 20 74  f milliseconds t
1150: 6f 20 77 61 69 74 20 77 68 65 6e 20 72 65 74 72  o wait when retr
1160: 79 69 6e 67 0a 20 20 20 20 23 20 20 20 20 20 20  ying.    #      
1170: 20 66 61 69 6c 65 64 20 5b 66 69 6c 65 5d 20 6f   failed [file] o
1180: 70 65 72 61 74 69 6f 6e 73 2e 20 20 41 20 76 61  perations.  A va
1190: 6c 75 65 20 6f 66 20 7a 65 72 6f 20 6f 72 20 6c  lue of zero or l
11a0: 65 73 73 20 6d 65 61 6e 73 20 22 64 6f 20 6e 6f  ess means "do no
11b0: 74 0a 20 20 20 20 23 20 20 20 20 20 20 20 77 61  t.    #       wa
11c0: 69 74 22 2e 0a 20 20 20 20 23 0a 20 20 20 20 72  it"..    #.    r
11d0: 65 74 75 72 6e 20 31 30 30 3b 20 23 20 54 4f 44  eturn 100; # TOD
11e0: 4f 3a 20 47 6f 6f 64 20 64 65 66 61 75 6c 74 3f  O: Good default?
11f0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 3a  .  }.  return $:
1200: 3a 47 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65  :G(file-retry-de
1210: 6c 61 79 29 0a 7d 0a 0a 23 20 43 6f 70 79 20 66  lay).}..# Copy f
1220: 69 6c 65 20 24 66 72 6f 6d 20 69 6e 74 6f 20 24  ile $from into $
1230: 74 6f 2e 20 54 68 69 73 20 69 73 20 75 73 65 64  to. This is used
1240: 20 62 65 63 61 75 73 65 20 73 6f 6d 65 20 76 65   because some ve
1250: 72 73 69 6f 6e 73 20 6f 66 0a 23 20 54 43 4c 20  rsions of.# TCL 
1260: 66 6f 72 20 77 69 6e 64 6f 77 73 20 28 6e 6f 74  for windows (not
1270: 61 62 6c 79 20 74 68 65 20 38 2e 34 2e 31 20 62  ably the 8.4.1 b
1280: 69 6e 61 72 79 20 70 61 63 6b 61 67 65 20 73 68  inary package sh
1290: 69 70 70 65 64 20 77 69 74 68 20 74 68 65 0a 23  ipped with the.#
12a0: 20 63 75 72 72 65 6e 74 20 6d 69 6e 67 77 20 72   current mingw r
12b0: 65 6c 65 61 73 65 29 20 68 61 76 65 20 61 20 62  elease) have a b
12c0: 72 6f 6b 65 6e 20 22 66 69 6c 65 20 63 6f 70 79  roken "file copy
12d0: 22 20 63 6f 6d 6d 61 6e 64 2e 0a 23 0a 70 72 6f  " command..#.pro
12e0: 63 20 63 6f 70 79 5f 66 69 6c 65 20 7b 66 72 6f  c copy_file {fro
12f0: 6d 20 74 6f 7d 20 7b 0a 20 20 64 6f 5f 63 6f 70  m to} {.  do_cop
1300: 79 5f 66 69 6c 65 20 66 61 6c 73 65 20 24 66 72  y_file false $fr
1310: 6f 6d 20 24 74 6f 0a 7d 0a 0a 70 72 6f 63 20 66  om $to.}..proc f
1320: 6f 72 63 65 63 6f 70 79 20 7b 66 72 6f 6d 20 74  orcecopy {from t
1330: 6f 7d 20 7b 0a 20 20 64 6f 5f 63 6f 70 79 5f 66  o} {.  do_copy_f
1340: 69 6c 65 20 74 72 75 65 20 24 66 72 6f 6d 20 24  ile true $from $
1350: 74 6f 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 63 6f  to.}..proc do_co
1360: 70 79 5f 66 69 6c 65 20 7b 66 6f 72 63 65 20 66  py_file {force f
1370: 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 73 65 74 20  rom to} {.  set 
1380: 6e 52 65 74 72 79 20 5b 67 65 74 46 69 6c 65 52  nRetry [getFileR
1390: 65 74 72 69 65 73 5d 20 20 20 20 20 3b 23 20 4d  etries]     ;# M
13a0: 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66  aximum number of
13b0: 20 72 65 74 72 69 65 73 2e 0a 20 20 73 65 74 20   retries..  set 
13c0: 6e 44 65 6c 61 79 20 5b 67 65 74 46 69 6c 65 52  nDelay [getFileR
13d0: 65 74 72 79 44 65 6c 61 79 5d 20 20 3b 23 20 44  etryDelay]  ;# D
13e0: 65 6c 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72  elay in ms befor
13f0: 65 20 72 65 74 72 79 69 6e 67 2e 0a 0a 20 20 23  e retrying...  #
1400: 20 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d   On windows, som
1410: 65 74 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 66  etimes even a [f
1420: 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 5d  ile copy -force]
1430: 20 63 61 6e 20 66 61 69 6c 2e 20 54 68 65 20 63   can fail. The c
1440: 61 75 73 65 20 69 73 0a 20 20 23 20 75 73 75 61  ause is.  # usua
1450: 6c 6c 79 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22  lly "tag-alongs"
1460: 20 2d 20 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65   - programs like
1470: 20 61 6e 74 69 2d 76 69 72 75 73 20 73 6f 66 74   anti-virus soft
1480: 77 61 72 65 2c 20 61 75 74 6f 6d 61 74 69 63 20  ware, automatic 
1490: 62 61 63 6b 75 70 0a 20 20 23 20 74 6f 6f 6c 73  backup.  # tools
14a0: 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65 78 70   and various exp
14b0: 6c 6f 72 65 72 20 65 78 74 65 6e 73 69 6f 6e 73  lorer extensions
14c0: 20 74 68 61 74 20 6b 65 65 70 20 61 20 66 69 6c   that keep a fil
14d0: 65 20 6f 70 65 6e 20 61 20 6c 69 74 74 6c 65 20  e open a little 
14e0: 6c 6f 6e 67 65 72 0a 20 20 23 20 74 68 61 6e 20  longer.  # than 
14f0: 77 65 20 65 78 70 65 63 74 2c 20 63 61 75 73 69  we expect, causi
1500: 6e 67 20 74 68 65 20 64 65 6c 65 74 65 20 74 6f  ng the delete to
1510: 20 66 61 69 6c 2e 0a 20 20 23 0a 20 20 23 20 54   fail..  #.  # T
1520: 68 65 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74  he solution is t
1530: 6f 20 77 61 69 74 20 61 20 73 68 6f 72 74 20 61  o wait a short a
1540: 6d 6f 75 6e 74 20 6f 66 20 74 69 6d 65 20 62 65  mount of time be
1550: 66 6f 72 65 20 72 65 74 72 79 69 6e 67 20 74 68  fore retrying th
1560: 65 20 63 6f 70 79 2e 0a 20 20 23 0a 20 20 69 66  e copy..  #.  if
1570: 20 7b 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b   {$nRetry > 0} {
1580: 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20  .    for {set i 
1590: 30 7d 20 7b 24 69 3c 24 6e 52 65 74 72 79 7d 20  0} {$i<$nRetry} 
15a0: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
15b0: 20 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b   set rc [catch {
15c0: 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 66 6f  .        if {$fo
15d0: 72 63 65 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  rce} {.         
15e0: 20 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63   file copy -forc
15f0: 65 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20  e $from $to.    
1600: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
1610: 20 20 20 20 20 20 20 66 69 6c 65 20 63 6f 70 79         file copy
1620: 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20 20   $from $to.     
1630: 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 6d 73 67     }.      } msg
1640: 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 72 63 3d  ].      if {$rc=
1650: 3d 30 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20  =0} break.      
1660: 69 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20 30 7d  if {$nDelay > 0}
1670: 20 7b 20 61 66 74 65 72 20 24 6e 44 65 6c 61 79   { after $nDelay
1680: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20   }.    }.    if 
1690: 7b 24 72 63 7d 20 7b 20 65 72 72 6f 72 20 24 6d  {$rc} { error $m
16a0: 73 67 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  sg }.  } else {.
16b0: 20 20 20 20 69 66 20 7b 24 66 6f 72 63 65 7d 20      if {$force} 
16c0: 7b 0a 20 20 20 20 20 20 66 69 6c 65 20 63 6f 70  {.      file cop
16d0: 79 20 2d 66 6f 72 63 65 20 24 66 72 6f 6d 20 24  y -force $from $
16e0: 74 6f 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  to.    } else {.
16f0: 20 20 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20        file copy 
1700: 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20 7d 0a  $from $to.    }.
1710: 20 20 7d 0a 7d 0a 0a 23 20 44 65 6c 65 74 65 20    }.}..# Delete 
1720: 61 20 66 69 6c 65 20 6f 72 20 64 69 72 65 63 74  a file or direct
1730: 6f 72 79 0a 23 0a 70 72 6f 63 20 64 65 6c 65 74  ory.#.proc delet
1740: 65 5f 66 69 6c 65 20 7b 61 72 67 73 7d 20 7b 0a  e_file {args} {.
1750: 20 20 64 6f 5f 64 65 6c 65 74 65 5f 66 69 6c 65    do_delete_file
1760: 20 66 61 6c 73 65 20 7b 2a 7d 24 61 72 67 73 0a   false {*}$args.
1770: 7d 0a 0a 70 72 6f 63 20 66 6f 72 63 65 64 65 6c  }..proc forcedel
1780: 65 74 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 64  ete {args} {.  d
1790: 6f 5f 64 65 6c 65 74 65 5f 66 69 6c 65 20 74 72  o_delete_file tr
17a0: 75 65 20 7b 2a 7d 24 61 72 67 73 0a 7d 0a 0a 70  ue {*}$args.}..p
17b0: 72 6f 63 20 64 6f 5f 64 65 6c 65 74 65 5f 66 69  roc do_delete_fi
17c0: 6c 65 20 7b 66 6f 72 63 65 20 61 72 67 73 7d 20  le {force args} 
17d0: 7b 0a 20 20 73 65 74 20 6e 52 65 74 72 79 20 5b  {.  set nRetry [
17e0: 67 65 74 46 69 6c 65 52 65 74 72 69 65 73 5d 20  getFileRetries] 
17f0: 20 20 20 20 3b 23 20 4d 61 78 69 6d 75 6d 20 6e      ;# Maximum n
1800: 75 6d 62 65 72 20 6f 66 20 72 65 74 72 69 65 73  umber of retries
1810: 2e 0a 20 20 73 65 74 20 6e 44 65 6c 61 79 20 5b  ..  set nDelay [
1820: 67 65 74 46 69 6c 65 52 65 74 72 79 44 65 6c 61  getFileRetryDela
1830: 79 5d 20 20 3b 23 20 44 65 6c 61 79 20 69 6e 20  y]  ;# Delay in 
1840: 6d 73 20 62 65 66 6f 72 65 20 72 65 74 72 79 69  ms before retryi
1850: 6e 67 2e 0a 0a 20 20 66 6f 72 65 61 63 68 20 66  ng...  foreach f
1860: 69 6c 65 6e 61 6d 65 20 24 61 72 67 73 20 7b 0a  ilename $args {.
1870: 20 20 20 20 23 20 4f 6e 20 77 69 6e 64 6f 77 73      # On windows
1880: 2c 20 73 6f 6d 65 74 69 6d 65 73 20 65 76 65 6e  , sometimes even
1890: 20 61 20 5b 66 69 6c 65 20 64 65 6c 65 74 65 20   a [file delete 
18a0: 2d 66 6f 72 63 65 5d 20 63 61 6e 20 66 61 69 6c  -force] can fail
18b0: 20 6a 75 73 74 20 61 66 74 65 72 0a 20 20 20 20   just after.    
18c0: 23 20 61 20 66 69 6c 65 20 69 73 20 63 6c 6f 73  # a file is clos
18d0: 65 64 2e 20 54 68 65 20 63 61 75 73 65 20 69 73  ed. The cause is
18e0: 20 75 73 75 61 6c 6c 79 20 22 74 61 67 2d 61 6c   usually "tag-al
18f0: 6f 6e 67 73 22 20 2d 20 70 72 6f 67 72 61 6d 73  ongs" - programs
1900: 20 6c 69 6b 65 0a 20 20 20 20 23 20 61 6e 74 69   like.    # anti
1910: 2d 76 69 72 75 73 20 73 6f 66 74 77 61 72 65 2c  -virus software,
1920: 20 61 75 74 6f 6d 61 74 69 63 20 62 61 63 6b 75   automatic backu
1930: 70 20 74 6f 6f 6c 73 20 61 6e 64 20 76 61 72 69  p tools and vari
1940: 6f 75 73 20 65 78 70 6c 6f 72 65 72 0a 20 20 20  ous explorer.   
1950: 20 23 20 65 78 74 65 6e 73 69 6f 6e 73 20 74 68   # extensions th
1960: 61 74 20 6b 65 65 70 20 61 20 66 69 6c 65 20 6f  at keep a file o
1970: 70 65 6e 20 61 20 6c 69 74 74 6c 65 20 6c 6f 6e  pen a little lon
1980: 67 65 72 20 74 68 61 6e 20 77 65 20 65 78 70 65  ger than we expe
1990: 63 74 2c 20 63 61 75 73 69 6e 67 0a 20 20 20 20  ct, causing.    
19a0: 23 20 74 68 65 20 64 65 6c 65 74 65 20 74 6f 20  # the delete to 
19b0: 66 61 69 6c 2e 0a 20 20 20 20 23 0a 20 20 20 20  fail..    #.    
19c0: 23 20 54 68 65 20 73 6f 6c 75 74 69 6f 6e 20 69  # The solution i
19d0: 73 20 74 6f 20 77 61 69 74 20 61 20 73 68 6f 72  s to wait a shor
19e0: 74 20 61 6d 6f 75 6e 74 20 6f 66 20 74 69 6d 65  t amount of time
19f0: 20 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e 67   before retrying
1a00: 20 74 68 65 0a 20 20 20 20 23 20 64 65 6c 65 74   the.    # delet
1a10: 65 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20  e..    #.    if 
1a20: 7b 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b 0a  {$nRetry > 0} {.
1a30: 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69        for {set i
1a40: 20 30 7d 20 7b 24 69 3c 24 6e 52 65 74 72 79 7d   0} {$i<$nRetry}
1a50: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
1a60: 20 20 20 20 73 65 74 20 72 63 20 5b 63 61 74 63      set rc [catc
1a70: 68 20 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66  h {.          if
1a80: 20 7b 24 66 6f 72 63 65 7d 20 7b 0a 20 20 20 20   {$force} {.    
1a90: 20 20 20 20 20 20 20 20 66 69 6c 65 20 64 65 6c          file del
1aa0: 65 74 65 20 2d 66 6f 72 63 65 20 24 66 69 6c 65  ete -force $file
1ab0: 6e 61 6d 65 0a 20 20 20 20 20 20 20 20 20 20 7d  name.          }
1ac0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
1ad0: 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20      file delete 
1ae0: 24 66 69 6c 65 6e 61 6d 65 0a 20 20 20 20 20 20  $filename.      
1af0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 20      }.        } 
1b00: 6d 73 67 5d 0a 20 20 20 20 20 20 20 20 69 66 20  msg].        if 
1b10: 7b 24 72 63 3d 3d 30 7d 20 62 72 65 61 6b 0a 20  {$rc==0} break. 
1b20: 20 20 20 20 20 20 20 69 66 20 7b 24 6e 44 65 6c         if {$nDel
1b30: 61 79 20 3e 20 30 7d 20 7b 20 61 66 74 65 72 20  ay > 0} { after 
1b40: 24 6e 44 65 6c 61 79 20 7d 0a 20 20 20 20 20 20  $nDelay }.      
1b50: 7d 0a 20 20 20 20 20 20 69 66 20 7b 24 72 63 7d  }.      if {$rc}
1b60: 20 7b 20 65 72 72 6f 72 20 24 6d 73 67 20 7d 0a   { error $msg }.
1b70: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
1b80: 20 20 20 69 66 20 7b 24 66 6f 72 63 65 7d 20 7b     if {$force} {
1b90: 0a 20 20 20 20 20 20 20 20 66 69 6c 65 20 64 65  .        file de
1ba0: 6c 65 74 65 20 2d 66 6f 72 63 65 20 24 66 69 6c  lete -force $fil
1bb0: 65 6e 61 6d 65 0a 20 20 20 20 20 20 7d 20 65 6c  ename.      } el
1bc0: 73 65 20 7b 0a 20 20 20 20 20 20 20 20 66 69 6c  se {.        fil
1bd0: 65 20 64 65 6c 65 74 65 20 24 66 69 6c 65 6e 61  e delete $filena
1be0: 6d 65 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  me.      }.    }
1bf0: 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78 65  .  }.}..proc exe
1c00: 63 70 72 65 73 71 6c 20 7b 68 61 6e 64 6c 65 20  cpresql {handle 
1c10: 61 72 67 73 7d 20 7b 0a 20 20 74 72 61 63 65 20  args} {.  trace 
1c20: 72 65 6d 6f 76 65 20 65 78 65 63 75 74 69 6f 6e  remove execution
1c30: 20 24 68 61 6e 64 6c 65 20 65 6e 74 65 72 20 5b   $handle enter [
1c40: 6c 69 73 74 20 65 78 65 63 70 72 65 73 71 6c 20  list execpresql 
1c50: 24 68 61 6e 64 6c 65 5d 0a 20 20 69 66 20 7b 5b  $handle].  if {[
1c60: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
1c70: 70 65 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20 7b  perm:presql)]} {
1c80: 0a 20 20 20 20 24 68 61 6e 64 6c 65 20 65 76 61  .    $handle eva
1c90: 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73  l $::G(perm:pres
1ca0: 71 6c 29 0a 20 20 7d 0a 7d 0a 0a 23 20 54 68 69  ql).  }.}..# Thi
1cb0: 73 20 63 6f 6d 6d 61 6e 64 20 73 68 6f 75 6c 64  s command should
1cc0: 20 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72   be called after
1cd0: 20 6c 6f 61 64 69 6e 67 20 74 65 73 74 65 72 2e   loading tester.
1ce0: 74 63 6c 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a  tcl from within.
1cf0: 23 20 61 6c 6c 20 74 65 73 74 20 73 63 72 69 70  # all test scrip
1d00: 74 73 20 74 68 61 74 20 61 72 65 20 69 6e 63 6f  ts that are inco
1d10: 6d 70 61 74 69 62 6c 65 20 77 69 74 68 20 65 6e  mpatible with en
1d20: 63 72 79 70 74 69 6f 6e 20 63 6f 64 65 63 73 2e  cryption codecs.
1d30: 0a 23 0a 70 72 6f 63 20 64 6f 5f 6e 6f 74 5f 75  .#.proc do_not_u
1d40: 73 65 5f 63 6f 64 65 63 20 7b 7d 20 7b 0a 20 20  se_codec {} {.  
1d50: 73 65 74 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65  set ::do_not_use
1d60: 5f 63 6f 64 65 63 20 31 0a 20 20 72 65 73 65 74  _codec 1.  reset
1d70: 5f 64 62 0a 7d 0a 0a 23 20 54 68 65 20 66 6f 6c  _db.}..# The fol
1d80: 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 6f 6e 6c  lowing block onl
1d90: 79 20 72 75 6e 73 20 74 68 65 20 66 69 72 73 74  y runs the first
1da0: 20 74 69 6d 65 20 74 68 69 73 20 66 69 6c 65 20   time this file 
1db0: 69 73 20 73 6f 75 72 63 65 64 2e 20 49 74 0a 23  is sourced. It.#
1dc0: 20 64 6f 65 73 20 6e 6f 74 20 72 75 6e 20 69 6e   does not run in
1dd0: 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74   slave interpret
1de0: 65 72 73 20 28 73 69 6e 63 65 20 74 68 65 20 3a  ers (since the :
1df0: 3a 63 6d 64 6c 69 6e 65 61 72 67 20 61 72 72 61  :cmdlinearg arra
1e00: 79 20 69 73 0a 23 20 70 6f 70 75 6c 61 74 65 64  y is.# populated
1e10: 20 62 65 66 6f 72 65 20 74 68 65 20 74 65 73 74   before the test
1e20: 20 73 63 72 69 70 74 20 69 73 20 72 75 6e 20 69   script is run i
1e30: 6e 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65  n slave interpre
1e40: 74 65 72 73 29 2e 0a 23 0a 69 66 20 7b 5b 69 6e  ters)..#.if {[in
1e50: 66 6f 20 65 78 69 73 74 73 20 63 6d 64 6c 69 6e  fo exists cmdlin
1e60: 65 61 72 67 5d 3d 3d 30 7d 20 7b 0a 0a 20 20 23  earg]==0} {..  #
1e70: 20 50 61 72 73 65 20 61 6e 79 20 6f 70 74 69 6f   Parse any optio
1e80: 6e 73 20 73 70 65 63 69 66 69 65 64 20 69 6e 20  ns specified in 
1e90: 74 68 65 20 24 61 72 67 76 20 61 72 72 61 79 2e  the $argv array.
1ea0: 20 54 68 69 73 20 73 63 72 69 70 74 20 61 63 63   This script acc
1eb0: 65 70 74 73 20 74 68 65 20 0a 20 20 23 20 66 6f  epts the .  # fo
1ec0: 6c 6c 6f 77 69 6e 67 20 6f 70 74 69 6f 6e 73 3a  llowing options:
1ed0: 20 0a 20 20 23 0a 20 20 23 20 20 20 2d 2d 70 61   .  #.  #   --pa
1ee0: 75 73 65 0a 20 20 23 20 20 20 2d 2d 73 6f 66 74  use.  #   --soft
1ef0: 2d 68 65 61 70 2d 6c 69 6d 69 74 3d 4e 4e 0a 20  -heap-limit=NN. 
1f00: 20 23 20 20 20 2d 2d 6d 61 78 65 72 72 6f 72 3d   #   --maxerror=
1f10: 4e 4e 0a 20 20 23 20 20 20 2d 2d 6d 61 6c 6c 6f  NN.  #   --mallo
1f20: 63 74 72 61 63 65 3d 4e 0a 20 20 23 20 20 20 2d  ctrace=N.  #   -
1f30: 2d 62 61 63 6b 74 72 61 63 65 3d 4e 0a 20 20 23  -backtrace=N.  #
1f40: 20 20 20 2d 2d 62 69 6e 61 72 79 6c 6f 67 3d 4e     --binarylog=N
1f50: 0a 20 20 23 20 20 20 2d 2d 73 6f 61 6b 3d 4e 0a  .  #   --soak=N.
1f60: 20 20 23 20 20 20 2d 2d 66 69 6c 65 2d 72 65 74    #   --file-ret
1f70: 72 69 65 73 3d 4e 0a 20 20 23 20 20 20 2d 2d 66  ries=N.  #   --f
1f80: 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79 3d  ile-retry-delay=
1f90: 4e 0a 20 20 23 20 20 20 2d 2d 73 74 61 72 74 3d  N.  #   --start=
1fa0: 5b 24 70 65 72 6d 75 74 61 74 69 6f 6e 3a 5d 24  [$permutation:]$
1fb0: 74 65 73 74 66 69 6c 65 0a 20 20 23 20 20 20 2d  testfile.  #   -
1fc0: 2d 6d 61 74 63 68 3d 24 70 61 74 74 65 72 6e 0a  -match=$pattern.
1fd0: 20 20 23 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e    #.  set cmdlin
1fe0: 65 61 72 67 28 73 6f 66 74 2d 68 65 61 70 2d 6c  earg(soft-heap-l
1ff0: 69 6d 69 74 29 20 20 20 20 30 0a 20 20 73 65 74  imit)    0.  set
2000: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 78 65   cmdlinearg(maxe
2010: 72 72 6f 72 29 20 20 20 20 20 20 20 20 31 30 30  rror)        100
2020: 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61  0.  set cmdlinea
2030: 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 20  rg(malloctrace) 
2040: 20 20 20 20 20 20 20 30 0a 20 20 73 65 74 20 63         0.  set c
2050: 6d 64 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72  mdlinearg(backtr
2060: 61 63 65 29 20 20 20 20 20 20 20 20 20 31 30 0a  ace)         10.
2070: 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67    set cmdlinearg
2080: 28 62 69 6e 61 72 79 6c 6f 67 29 20 20 20 20 20  (binarylog)     
2090: 20 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64       0.  set cmd
20a0: 6c 69 6e 65 61 72 67 28 73 6f 61 6b 29 20 20 20  linearg(soak)   
20b0: 20 20 20 20 20 20 20 20 20 20 20 20 30 0a 20 20              0.  
20c0: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 66  set cmdlinearg(f
20d0: 69 6c 65 2d 72 65 74 72 69 65 73 29 20 20 20 20  ile-retries)    
20e0: 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69     0.  set cmdli
20f0: 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72 79  nearg(file-retry
2100: 2d 64 65 6c 61 79 29 20 20 20 30 0a 20 20 73 65  -delay)   0.  se
2110: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 74 61  t cmdlinearg(sta
2120: 72 74 29 20 20 20 20 20 20 20 20 20 20 20 20 20  rt)             
2130: 22 22 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65  "".  set cmdline
2140: 61 72 67 28 6d 61 74 63 68 29 20 20 20 20 20 20  arg(match)      
2150: 20 20 20 20 20 20 20 22 22 0a 0a 20 20 73 65 74         ""..  set
2160: 20 6c 65 66 74 6f 76 65 72 20 5b 6c 69 73 74 5d   leftover [list]
2170: 0a 20 20 66 6f 72 65 61 63 68 20 61 20 24 61 72  .  foreach a $ar
2180: 67 76 20 7b 0a 20 20 20 20 73 77 69 74 63 68 20  gv {.    switch 
2190: 2d 72 65 67 65 78 70 20 2d 2d 20 24 61 20 7b 0a  -regexp -- $a {.
21a0: 20 20 20 20 20 20 7b 5e 2d 2b 70 61 75 73 65 24        {^-+pause$
21b0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20 57 61  } {.        # Wa
21c0: 69 74 20 66 6f 72 20 75 73 65 72 20 69 6e 70 75  it for user inpu
21d0: 74 20 62 65 66 6f 72 65 20 63 6f 6e 74 69 6e 75  t before continu
21e0: 69 6e 67 2e 20 54 68 69 73 20 69 73 20 74 6f 20  ing. This is to 
21f0: 67 69 76 65 20 74 68 65 20 75 73 65 72 20 61 6e  give the user an
2200: 20 0a 20 20 20 20 20 20 20 20 23 20 6f 70 70 6f   .        # oppo
2210: 72 74 75 6e 69 74 79 20 74 6f 20 63 6f 6e 6e 65  rtunity to conne
2220: 63 74 20 70 72 6f 66 69 6c 69 6e 67 20 74 6f 6f  ct profiling too
2230: 6c 73 20 74 6f 20 74 68 65 20 70 72 6f 63 65 73  ls to the proces
2240: 73 2e 0a 20 20 20 20 20 20 20 20 70 75 74 73 20  s..        puts 
2250: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 50 72 65 73  -nonewline "Pres
2260: 73 20 52 45 54 55 52 4e 20 74 6f 20 62 65 67 69  s RETURN to begi
2270: 6e 2e 2e 2e 22 0a 20 20 20 20 20 20 20 20 66 6c  n...".        fl
2280: 75 73 68 20 73 74 64 6f 75 74 0a 20 20 20 20 20  ush stdout.     
2290: 20 20 20 67 65 74 73 20 73 74 64 69 6e 0a 20 20     gets stdin.  
22a0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b      }.      {^-+
22b0: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d  soft-heap-limit=
22c0: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
22d0: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
22e0: 64 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65  dlinearg(soft-he
22f0: 61 70 2d 6c 69 6d 69 74 29 7d 20 5b 73 70 6c 69  ap-limit)} [spli
2300: 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20  t $a =] break.  
2310: 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b      }.      {^-+
2320: 6d 61 78 65 72 72 6f 72 3d 2e 2b 24 7d 20 7b 0a  maxerror=.+$} {.
2330: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
2340: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
2350: 67 28 6d 61 78 65 72 72 6f 72 29 7d 20 5b 73 70  g(maxerror)} [sp
2360: 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a  lit $a =] break.
2370: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
2380: 2d 2b 6d 61 6c 6c 6f 63 74 72 61 63 65 3d 2e 2b  -+malloctrace=.+
2390: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
23a0: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
23b0: 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61  inearg(malloctra
23c0: 63 65 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ce)} [split $a =
23d0: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
23e0: 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28  if {$cmdlinearg(
23f0: 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a  malloctrace)} {.
2400: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
2410: 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73  3_memdebug_log s
2420: 74 61 72 74 0a 20 20 20 20 20 20 20 20 7d 0a 20  tart.        }. 
2430: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d       }.      {^-
2440: 2b 62 61 63 6b 74 72 61 63 65 3d 2e 2b 24 7d 20  +backtrace=.+$} 
2450: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
2460: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
2470: 61 72 67 28 62 61 63 6b 74 72 61 63 65 29 7d 20  arg(backtrace)} 
2480: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
2490: 61 6b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  ak.        sqlit
24a0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63 6b  e3_memdebug_back
24b0: 74 72 61 63 65 20 24 76 61 6c 75 65 0a 20 20 20  trace $value.   
24c0: 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d 2b 62     }.      {^-+b
24d0: 69 6e 61 72 79 6c 6f 67 3d 2e 2b 24 7d 20 7b 0a  inarylog=.+$} {.
24e0: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
24f0: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
2500: 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 5b 73  g(binarylog)} [s
2510: 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b  plit $a =] break
2520: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
2530: 5e 2d 2b 73 6f 61 6b 3d 2e 2b 24 7d 20 7b 0a 20  ^-+soak=.+$} {. 
2540: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
2550: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
2560: 28 73 6f 61 6b 29 7d 20 5b 73 70 6c 69 74 20 24  (soak)} [split $
2570: 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20  a =] break.     
2580: 20 20 20 73 65 74 20 3a 3a 47 28 69 73 73 6f 61     set ::G(issoa
2590: 6b 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73  k) $cmdlinearg(s
25a0: 6f 61 6b 29 0a 20 20 20 20 20 20 7d 0a 20 20 20  oak).      }.   
25b0: 20 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74 72     {^-+file-retr
25c0: 69 65 73 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20  ies=.+$} {.     
25d0: 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d     foreach {dumm
25e0: 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c  y cmdlinearg(fil
25f0: 65 2d 72 65 74 72 69 65 73 29 7d 20 5b 73 70 6c  e-retries)} [spl
2600: 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20  it $a =] break. 
2610: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 66         set ::G(f
2620: 69 6c 65 2d 72 65 74 72 69 65 73 29 20 24 63 6d  ile-retries) $cm
2630: 64 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65  dlinearg(file-re
2640: 74 72 69 65 73 29 0a 20 20 20 20 20 20 7d 0a 20  tries).      }. 
2650: 20 20 20 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65       {^-+file-re
2660: 74 72 79 2d 64 65 6c 61 79 3d 2e 2b 24 7d 20 7b  try-delay=.+$} {
2670: 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68  .        foreach
2680: 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61   {dummy cmdlinea
2690: 72 67 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65  rg(file-retry-de
26a0: 6c 61 79 29 7d 20 5b 73 70 6c 69 74 20 24 61 20  lay)} [split $a 
26b0: 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20  =] break.       
26c0: 20 73 65 74 20 3a 3a 47 28 66 69 6c 65 2d 72 65   set ::G(file-re
26d0: 74 72 79 2d 64 65 6c 61 79 29 20 24 63 6d 64 6c  try-delay) $cmdl
26e0: 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72  inearg(file-retr
26f0: 79 2d 64 65 6c 61 79 29 0a 20 20 20 20 20 20 7d  y-delay).      }
2700: 0a 20 20 20 20 20 20 7b 5e 2d 2b 73 74 61 72 74  .      {^-+start
2710: 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20  =.+$} {.        
2720: 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63  foreach {dummy c
2730: 6d 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29  mdlinearg(start)
2740: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
2750: 72 65 61 6b 0a 0a 20 20 20 20 20 20 20 20 73 65  reak..        se
2760: 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65  t ::G(start:file
2770: 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 74  ) $cmdlinearg(st
2780: 61 72 74 29 0a 20 20 20 20 20 20 20 20 69 66 20  art).        if 
2790: 7b 5b 72 65 67 65 78 70 20 7b 28 2e 2a 29 3a 28  {[regexp {(.*):(
27a0: 2e 2a 29 7d 20 24 63 6d 64 6c 69 6e 65 61 72 67  .*)} $cmdlinearg
27b0: 28 73 74 61 72 74 29 20 2d 3e 20 73 2e 70 65 72  (start) -> s.per
27c0: 6d 20 73 2e 66 69 6c 65 5d 7d 20 7b 0a 20 20 20  m s.file]} {.   
27d0: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73         set ::G(s
27e0: 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e  tart:permutation
27f0: 29 20 24 7b 73 2e 70 65 72 6d 7d 0a 20 20 20 20  ) ${s.perm}.    
2800: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74        set ::G(st
2810: 61 72 74 3a 66 69 6c 65 29 20 20 20 20 20 20 20  art:file)       
2820: 20 24 7b 73 2e 66 69 6c 65 7d 0a 20 20 20 20 20   ${s.file}.     
2830: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 20     }.        if 
2840: 7b 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65  {$::G(start:file
2850: 29 20 3d 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20  ) == ""} {unset 
2860: 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 7d  ::G(start:file)}
2870: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
2880: 5e 2d 2b 6d 61 74 63 68 3d 2e 2b 24 7d 20 7b 0a  ^-+match=.+$} {.
2890: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
28a0: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
28b0: 67 28 6d 61 74 63 68 29 7d 20 5b 73 70 6c 69 74  g(match)} [split
28c0: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 0a 20 20   $a =] break..  
28d0: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 6d 61        set ::G(ma
28e0: 74 63 68 29 20 24 63 6d 64 6c 69 6e 65 61 72 67  tch) $cmdlinearg
28f0: 28 6d 61 74 63 68 29 0a 20 20 20 20 20 20 20 20  (match).        
2900: 69 66 20 7b 24 3a 3a 47 28 6d 61 74 63 68 29 20  if {$::G(match) 
2910: 3d 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a 3a  == ""} {unset ::
2920: 47 28 6d 61 74 63 68 29 7d 0a 20 20 20 20 20 20  G(match)}.      
2930: 7d 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 20  }.      default 
2940: 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e  {.        lappen
2950: 64 20 6c 65 66 74 6f 76 65 72 20 24 61 0a 20 20  d leftover $a.  
2960: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
2970: 20 20 73 65 74 20 61 72 67 76 20 24 6c 65 66 74    set argv $left
2980: 6f 76 65 72 0a 0a 20 20 23 20 49 6e 73 74 61 6c  over..  # Instal
2990: 6c 20 74 68 65 20 6d 61 6c 6c 6f 63 20 6c 61 79  l the malloc lay
29a0: 65 72 20 75 73 65 64 20 74 6f 20 69 6e 6a 65 63  er used to injec
29b0: 74 20 4f 4f 4d 20 65 72 72 6f 72 73 2e 20 41 6e  t OOM errors. An
29c0: 64 20 74 68 65 20 27 61 75 74 6f 6d 61 74 69 63  d the 'automatic
29d0: 27 0a 20 20 23 20 65 78 74 65 6e 73 69 6f 6e 73  '.  # extensions
29e0: 2e 20 54 68 69 73 20 6f 6e 6c 79 20 6e 65 65 64  . This only need
29f0: 73 20 74 6f 20 62 65 20 64 6f 6e 65 20 6f 6e 63  s to be done onc
2a00: 65 20 66 6f 72 20 74 68 65 20 70 72 6f 63 65 73  e for the proces
2a10: 73 2e 0a 20 20 23 0a 20 20 73 71 6c 69 74 65 33  s..  #.  sqlite3
2a20: 5f 73 68 75 74 64 6f 77 6e 20 0a 20 20 69 6e 73  _shutdown .  ins
2a30: 74 61 6c 6c 5f 6d 61 6c 6c 6f 63 5f 66 61 75 6c  tall_malloc_faul
2a40: 74 73 69 6d 20 31 20 0a 20 20 73 71 6c 69 74 65  tsim 1 .  sqlite
2a50: 33 5f 69 6e 69 74 69 61 6c 69 7a 65 0a 20 20 61  3_initialize.  a
2a60: 75 74 6f 69 6e 73 74 61 6c 6c 5f 74 65 73 74 5f  utoinstall_test_
2a70: 66 75 6e 63 74 69 6f 6e 73 0a 0a 20 20 23 20 49  functions..  # I
2a80: 66 20 74 68 65 20 2d 2d 62 69 6e 61 72 79 6c 6f  f the --binarylo
2a90: 67 20 6f 70 74 69 6f 6e 20 77 61 73 20 73 70 65  g option was spe
2aa0: 63 69 66 69 65 64 2c 20 63 72 65 61 74 65 20 74  cified, create t
2ab0: 68 65 20 6c 6f 67 67 69 6e 67 20 56 46 53 2e 20  he logging VFS. 
2ac0: 54 68 69 73 0a 20 20 23 20 63 61 6c 6c 20 69 6e  This.  # call in
2ad0: 73 74 61 6c 6c 73 20 74 68 65 20 6e 65 77 20 56  stalls the new V
2ae0: 46 53 20 61 73 20 74 68 65 20 64 65 66 61 75 6c  FS as the defaul
2af0: 74 20 66 6f 72 20 61 6c 6c 20 53 51 4c 69 74 65  t for all SQLite
2b00: 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 2e 0a 20 20   connections..  
2b10: 23 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65  #.  if {$cmdline
2b20: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20  arg(binarylog)} 
2b30: 7b 0a 20 20 20 20 76 66 73 6c 6f 67 20 6e 65 77  {.    vfslog new
2b40: 20 62 69 6e 61 72 79 6c 6f 67 20 7b 7d 20 76 66   binarylog {} vf
2b50: 73 6c 6f 67 2e 62 69 6e 0a 20 20 7d 0a 0a 20 20  slog.bin.  }..  
2b60: 23 20 53 65 74 20 74 68 65 20 62 61 63 6b 74 72  # Set the backtr
2b70: 61 63 65 20 64 65 70 74 68 2c 20 69 66 20 6d 61  ace depth, if ma
2b80: 6c 6c 6f 63 20 74 72 61 63 69 6e 67 20 69 73 20  lloc tracing is 
2b90: 65 6e 61 62 6c 65 64 2e 0a 20 20 23 0a 20 20 69  enabled..  #.  i
2ba0: 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 6d  f {$cmdlinearg(m
2bb0: 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20  alloctrace)} {. 
2bc0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
2bd0: 62 75 67 5f 62 61 63 6b 74 72 61 63 65 20 24 63  bug_backtrace $c
2be0: 6d 64 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72  mdlinearg(backtr
2bf0: 61 63 65 29 0a 20 20 7d 0a 7d 0a 0a 23 20 55 70  ace).  }.}..# Up
2c00: 64 61 74 65 20 74 68 65 20 73 6f 66 74 2d 68 65  date the soft-he
2c10: 61 70 2d 6c 69 6d 69 74 20 65 61 63 68 20 74 69  ap-limit each ti
2c20: 6d 65 20 74 68 69 73 20 73 63 72 69 70 74 20 69  me this script i
2c30: 73 20 72 75 6e 2e 20 49 6e 20 74 68 61 74 0a 23  s run. In that.#
2c40: 20 77 61 79 20 69 66 20 61 6e 20 69 6e 64 69 76   way if an indiv
2c50: 69 64 75 61 6c 20 74 65 73 74 20 66 69 6c 65 20  idual test file 
2c60: 63 68 61 6e 67 65 73 20 74 68 65 20 73 6f 66 74  changes the soft
2c70: 2d 68 65 61 70 2d 6c 69 6d 69 74 2c 20 69 74 0a  -heap-limit, it.
2c80: 23 20 77 69 6c 6c 20 62 65 20 72 65 73 65 74 20  # will be reset 
2c90: 61 74 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  at the start of 
2ca0: 74 68 65 20 6e 65 78 74 20 74 65 73 74 20 66 69  the next test fi
2cb0: 6c 65 2e 0a 23 0a 73 71 6c 69 74 65 33 5f 73 6f  le..#.sqlite3_so
2cc0: 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20 24 63  ft_heap_limit $c
2cd0: 6d 64 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d 68  mdlinearg(soft-h
2ce0: 65 61 70 2d 6c 69 6d 69 74 29 0a 0a 70 72 6f 63  eap-limit)..proc
2cf0: 20 66 6f 72 63 65 64 5f 70 72 6f 78 79 5f 6c 6f   forced_proxy_lo
2d00: 63 6b 69 6e 67 20 7b 7d 20 7b 0a 20 20 69 66 20  cking {} {.  if 
2d10: 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e  $::sqlite_option
2d20: 73 28 6c 6f 63 6b 5f 70 72 6f 78 79 5f 70 72 61  s(lock_proxy_pra
2d30: 67 6d 61 73 29 26 26 24 3a 3a 73 71 6c 69 74 65  gmas)&&$::sqlite
2d40: 5f 6f 70 74 69 6f 6e 73 28 70 72 65 66 65 72 5f  _options(prefer_
2d50: 70 72 6f 78 79 5f 6c 6f 63 6b 69 6e 67 29 20 7b  proxy_locking) {
2d60: 0a 20 20 20 20 73 65 74 20 66 6f 72 63 65 5f 70  .    set force_p
2d70: 72 6f 78 79 5f 76 61 6c 75 65 20 30 0a 20 20 20  roxy_value 0.   
2d80: 20 73 65 74 20 66 6f 72 63 65 5f 6b 65 79 20 22   set force_key "
2d90: 53 51 4c 49 54 45 5f 46 4f 52 43 45 5f 50 52 4f  SQLITE_FORCE_PRO
2da0: 58 59 5f 4c 4f 43 4b 49 4e 47 3d 22 0a 20 20 20  XY_LOCKING=".   
2db0: 20 66 6f 72 65 61 63 68 20 7b 65 6e 76 5f 70 61   foreach {env_pa
2dc0: 69 72 7d 20 5b 65 78 65 63 20 65 6e 76 5d 20 7b  ir} [exec env] {
2dd0: 20 0a 20 20 20 20 20 20 69 66 20 7b 20 5b 73 74   .      if { [st
2de0: 72 69 6e 67 20 66 69 72 73 74 20 24 66 6f 72 63  ring first $forc
2df0: 65 5f 6b 65 79 20 24 65 6e 76 5f 70 61 69 72 5d  e_key $env_pair]
2e00: 20 3d 3d 20 30 7d 20 7b 0a 20 20 20 20 20 20 20   == 0} {.       
2e10: 20 73 65 74 20 66 6f 72 63 65 5f 70 72 6f 78 79   set force_proxy
2e20: 5f 76 61 6c 75 65 20 5b 73 74 72 69 6e 67 20 72  _value [string r
2e30: 61 6e 67 65 20 24 65 6e 76 5f 70 61 69 72 20 5b  ange $env_pair [
2e40: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 66  string length $f
2e50: 6f 72 63 65 5f 6b 65 79 5d 20 65 6e 64 5d 0a 20  orce_key] end]. 
2e60: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
2e70: 20 69 66 20 7b 20 22 24 66 6f 72 63 65 5f 70 72   if { "$force_pr
2e80: 6f 78 79 5f 76 61 6c 75 65 20 22 20 3d 3d 20 22  oxy_value " == "
2e90: 31 20 22 20 7d 20 7b 0a 20 20 20 20 20 20 72 65  1 " } {.      re
2ea0: 74 75 72 6e 20 31 0a 20 20 20 20 7d 20 0a 20 20  turn 1.    } .  
2eb0: 7d 0a 20 20 72 65 74 75 72 6e 20 30 0a 7d 0a 0a  }.  return 0.}..
2ec0: 0a 23 20 43 72 65 61 74 65 20 61 20 74 65 73 74  .# Create a test
2ed0: 20 64 61 74 61 62 61 73 65 0a 23 0a 70 72 6f 63   database.#.proc
2ee0: 20 72 65 73 65 74 5f 64 62 20 7b 7d 20 7b 0a 20   reset_db {} {. 
2ef0: 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65   catch {db close
2f00: 7d 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20  }.  forcedelete 
2f10: 74 65 73 74 2e 64 62 0a 20 20 66 6f 72 63 65 64  test.db.  forced
2f20: 65 6c 65 74 65 20 74 65 73 74 2e 64 62 2d 6a 6f  elete test.db-jo
2f30: 75 72 6e 61 6c 0a 20 20 66 6f 72 63 65 64 65 6c  urnal.  forcedel
2f40: 65 74 65 20 74 65 73 74 2e 64 62 2d 77 61 6c 0a  ete test.db-wal.
2f50: 20 20 69 66 20 7b 5b 66 6f 72 63 65 64 5f 70 72    if {[forced_pr
2f60: 6f 78 79 5f 6c 6f 63 6b 69 6e 67 5d 7d 20 7b 0a  oxy_locking]} {.
2f70: 20 20 20 20 73 71 6c 69 74 65 33 20 64 62 20 2e      sqlite3 db .
2f80: 2f 74 65 73 74 2e 64 62 0a 20 20 20 20 73 65 74  /test.db.    set
2f90: 20 6c 6f 63 6b 5f 70 72 6f 78 79 5f 70 61 74 68   lock_proxy_path
2fa0: 20 5b 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d   [db eval "PRAGM
2fb0: 41 20 6c 6f 63 6b 5f 70 72 6f 78 79 5f 66 69 6c  A lock_proxy_fil
2fc0: 65 3b 22 5d 20 0a 20 20 20 20 63 61 74 63 68 20  e;"] .    catch 
2fd0: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 23  {db close}.    #
2fe0: 20 70 75 74 73 20 22 64 65 6c 65 74 69 6e 67 20   puts "deleting 
2ff0: 24 6c 6f 63 6b 5f 70 72 6f 78 79 5f 70 61 74 68  $lock_proxy_path
3000: 22 0a 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74  ".    file delet
3010: 65 20 2d 66 6f 72 63 65 20 24 6c 6f 63 6b 5f 70  e -force $lock_p
3020: 72 6f 78 79 5f 70 61 74 68 20 20 20 20 0a 20 20  roxy_path    .  
3030: 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66    file delete -f
3040: 6f 72 63 65 20 74 65 73 74 2e 64 62 0a 20 20 7d  orce test.db.  }
3050: 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20 2e 2f  .  sqlite3 db ./
3060: 74 65 73 74 2e 64 62 0a 20 20 73 65 74 20 3a 3a  test.db.  set ::
3070: 44 42 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 6e  DB [sqlite3_conn
3080: 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64  ection_pointer d
3090: 62 5d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65  b].  if {[info e
30a0: 78 69 73 74 73 20 3a 3a 53 45 54 55 50 5f 53 51  xists ::SETUP_SQ
30b0: 4c 5d 7d 20 7b 0a 20 20 20 20 64 62 20 65 76 61  L]} {.    db eva
30c0: 6c 20 24 3a 3a 53 45 54 55 50 5f 53 51 4c 0a 20  l $::SETUP_SQL. 
30d0: 20 7d 0a 7d 0a 72 65 73 65 74 5f 64 62 0a 0a 23   }.}.reset_db..#
30e0: 20 41 62 6f 72 74 20 65 61 72 6c 79 20 69 66 20   Abort early if 
30f0: 74 68 69 73 20 73 63 72 69 70 74 20 68 61 73 20  this script has 
3100: 62 65 65 6e 20 72 75 6e 20 62 65 66 6f 72 65 2e  been run before.
3110: 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69  .#.if {[info exi
3120: 73 74 73 20 54 43 28 63 6f 75 6e 74 29 5d 7d 20  sts TC(count)]} 
3130: 72 65 74 75 72 6e 0a 0a 23 20 4d 61 6b 65 20 73  return..# Make s
3140: 75 72 65 20 6d 65 6d 6f 72 79 20 73 74 61 74 69  ure memory stati
3150: 73 74 69 63 73 20 61 72 65 20 65 6e 61 62 6c 65  stics are enable
3160: 64 2e 0a 23 0a 73 71 6c 69 74 65 33 5f 63 6f 6e  d..#.sqlite3_con
3170: 66 69 67 5f 6d 65 6d 73 74 61 74 75 73 20 31 0a  fig_memstatus 1.
3180: 0a 23 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68  .# Initialize th
3190: 65 20 74 65 73 74 20 63 6f 75 6e 74 65 72 73 20  e test counters 
31a0: 61 6e 64 20 73 65 74 20 75 70 20 63 6f 6d 6d 61  and set up comma
31b0: 6e 64 73 20 74 6f 20 61 63 63 65 73 73 20 74 68  nds to access th
31c0: 65 6d 2e 0a 23 20 4f 72 2c 20 69 66 20 74 68 69  em..# Or, if thi
31d0: 73 20 69 73 20 61 20 73 6c 61 76 65 20 69 6e 74  s is a slave int
31e0: 65 72 70 72 65 74 65 72 2c 20 73 65 74 20 75 70  erpreter, set up
31f0: 20 61 6c 69 61 73 65 73 20 74 6f 20 77 72 69 74   aliases to writ
3200: 65 20 74 68 65 0a 23 20 63 6f 75 6e 74 65 72 73  e the.# counters
3210: 20 69 6e 20 74 68 65 20 70 61 72 65 6e 74 20 69   in the parent i
3220: 6e 74 65 72 70 72 65 74 65 72 2e 0a 23 0a 69 66  nterpreter..#.if
3230: 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69 73 74   {0==[info exist
3240: 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 0a 20 20  s ::SLAVE]} {.  
3250: 73 65 74 20 54 43 28 65 72 72 6f 72 73 29 20 20  set TC(errors)  
3260: 20 20 30 0a 20 20 73 65 74 20 54 43 28 63 6f 75    0.  set TC(cou
3270: 6e 74 29 20 20 20 20 20 30 0a 20 20 73 65 74 20  nt)     0.  set 
3280: 54 43 28 66 61 69 6c 5f 6c 69 73 74 29 20 5b 6c  TC(fail_list) [l
3290: 69 73 74 5d 0a 20 20 73 65 74 20 54 43 28 6f 6d  ist].  set TC(om
32a0: 69 74 5f 6c 69 73 74 29 20 5b 6c 69 73 74 5d 0a  it_list) [list].
32b0: 0a 20 20 70 72 6f 63 20 73 65 74 5f 74 65 73 74  .  proc set_test
32c0: 5f 63 6f 75 6e 74 65 72 20 7b 63 6f 75 6e 74 65  _counter {counte
32d0: 72 20 61 72 67 73 7d 20 7b 0a 20 20 20 20 69 66  r args} {.    if
32e0: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73   {[llength $args
32f0: 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a  ]} {.      set :
3300: 3a 54 43 28 24 63 6f 75 6e 74 65 72 29 20 5b 6c  :TC($counter) [l
3310: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 0a 20  index $args 0]. 
3320: 20 20 20 7d 0a 20 20 20 20 73 65 74 20 3a 3a 54     }.    set ::T
3330: 43 28 24 63 6f 75 6e 74 65 72 29 0a 20 20 7d 0a  C($counter).  }.
3340: 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74 68 65 20  }..# Record the 
3350: 66 61 63 74 20 74 68 61 74 20 61 20 73 65 71 75  fact that a sequ
3360: 65 6e 63 65 20 6f 66 20 74 65 73 74 73 20 77 65  ence of tests we
3370: 72 65 20 6f 6d 69 74 74 65 64 2e 0a 23 0a 70 72  re omitted..#.pr
3380: 6f 63 20 6f 6d 69 74 5f 74 65 73 74 20 7b 6e 61  oc omit_test {na
3390: 6d 65 20 72 65 61 73 6f 6e 20 7b 61 70 70 65 6e  me reason {appen
33a0: 64 20 31 7d 7d 20 7b 0a 20 20 73 65 74 20 6f 6d  d 1}} {.  set om
33b0: 69 74 4c 69 73 74 20 5b 73 65 74 5f 74 65 73 74  itList [set_test
33c0: 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69  _counter omit_li
33d0: 73 74 5d 0a 20 20 69 66 20 7b 24 61 70 70 65 6e  st].  if {$appen
33e0: 64 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64  d} {.    lappend
33f0: 20 6f 6d 69 74 4c 69 73 74 20 5b 6c 69 73 74 20   omitList [list 
3400: 24 6e 61 6d 65 20 24 72 65 61 73 6f 6e 5d 0a 20  $name $reason]. 
3410: 20 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f 63 6f   }.  set_test_co
3420: 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74 20  unter omit_list 
3430: 24 6f 6d 69 74 4c 69 73 74 0a 7d 0a 0a 23 20 52  $omitList.}..# R
3440: 65 63 6f 72 64 20 74 68 65 20 66 61 63 74 20 74  ecord the fact t
3450: 68 61 74 20 61 20 74 65 73 74 20 66 61 69 6c 65  hat a test faile
3460: 64 2e 0a 23 0a 70 72 6f 63 20 66 61 69 6c 5f 74  d..#.proc fail_t
3470: 65 73 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 73  est {name} {.  s
3480: 65 74 20 66 20 5b 73 65 74 5f 74 65 73 74 5f 63  et f [set_test_c
3490: 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73 74  ounter fail_list
34a0: 5d 0a 20 20 6c 61 70 70 65 6e 64 20 66 20 24 6e  ].  lappend f $n
34b0: 61 6d 65 0a 20 20 73 65 74 5f 74 65 73 74 5f 63  ame.  set_test_c
34c0: 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73 74  ounter fail_list
34d0: 20 24 66 0a 20 20 73 65 74 5f 74 65 73 74 5f 63   $f.  set_test_c
34e0: 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 20 5b 65  ounter errors [e
34f0: 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  xpr [set_test_co
3500: 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 20 2b 20  unter errors] + 
3510: 31 5d 0a 0a 20 20 73 65 74 20 6e 46 61 69 6c 20  1]..  set nFail 
3520: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
3530: 72 20 65 72 72 6f 72 73 5d 0a 20 20 69 66 20 7b  r errors].  if {
3540: 24 6e 46 61 69 6c 3e 3d 24 3a 3a 63 6d 64 6c 69  $nFail>=$::cmdli
3550: 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29 7d  nearg(maxerror)}
3560: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 2a 2a 2a   {.    puts "***
3570: 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e 22 0a 20   Giving up...". 
3580: 20 20 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74     finalize_test
3590: 69 6e 67 0a 20 20 7d 0a 7d 0a 0a 23 20 49 6e 63  ing.  }.}..# Inc
35a0: 72 65 6d 65 6e 74 20 74 68 65 20 6e 75 6d 62 65  rement the numbe
35b0: 72 20 6f 66 20 74 65 73 74 73 20 72 75 6e 0a 23  r of tests run.#
35c0: 0a 70 72 6f 63 20 69 6e 63 72 5f 6e 74 65 73 74  .proc incr_ntest
35d0: 20 7b 7d 20 7b 0a 20 20 73 65 74 5f 74 65 73 74   {} {.  set_test
35e0: 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74 20 5b  _counter count [
35f0: 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f 63  expr [set_test_c
3600: 6f 75 6e 74 65 72 20 63 6f 75 6e 74 5d 20 2b 20  ounter count] + 
3610: 31 5d 0a 7d 0a 0a 0a 23 20 49 6e 76 6f 6b 65 20  1].}...# Invoke 
3620: 74 68 65 20 64 6f 5f 74 65 73 74 20 70 72 6f 63  the do_test proc
3630: 65 64 75 72 65 20 74 6f 20 72 75 6e 20 61 20 73  edure to run a s
3640: 69 6e 67 6c 65 20 74 65 73 74 20 0a 23 0a 70 72  ingle test .#.pr
3650: 6f 63 20 64 6f 5f 74 65 73 74 20 7b 6e 61 6d 65  oc do_test {name
3660: 20 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b   cmd expected} {
3670: 0a 0a 20 20 67 6c 6f 62 61 6c 20 61 72 67 76 20  ..  global argv 
3680: 63 6d 64 6c 69 6e 65 61 72 67 0a 0a 20 20 66 69  cmdlinearg..  fi
3690: 78 5f 74 65 73 74 6e 61 6d 65 20 6e 61 6d 65 0a  x_testname name.
36a0: 0a 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65  .  sqlite3_memde
36b0: 62 75 67 5f 73 65 74 74 69 74 6c 65 20 24 6e 61  bug_settitle $na
36c0: 6d 65 0a 0a 23 20 20 69 66 20 7b 5b 6c 6c 65 6e  me..#  if {[llen
36d0: 67 74 68 20 24 61 72 67 76 5d 3d 3d 30 7d 20 7b  gth $argv]==0} {
36e0: 20 0a 23 20 20 20 20 73 65 74 20 67 6f 20 31 0a   .#    set go 1.
36f0: 23 20 20 7d 20 65 6c 73 65 20 7b 0a 23 20 20 20  #  } else {.#   
3700: 20 73 65 74 20 67 6f 20 30 0a 23 20 20 20 20 66   set go 0.#    f
3710: 6f 72 65 61 63 68 20 70 61 74 74 65 72 6e 20 24  oreach pattern $
3720: 61 72 67 76 20 7b 0a 23 20 20 20 20 20 20 69 66  argv {.#      if
3730: 20 7b 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20   {[string match 
3740: 24 70 61 74 74 65 72 6e 20 24 6e 61 6d 65 5d 7d  $pattern $name]}
3750: 20 7b 0a 23 20 20 20 20 20 20 20 20 73 65 74 20   {.#        set 
3760: 67 6f 20 31 0a 23 20 20 20 20 20 20 20 20 62 72  go 1.#        br
3770: 65 61 6b 0a 23 20 20 20 20 20 20 7d 0a 23 20 20  eak.#      }.#  
3780: 20 20 7d 0a 23 20 20 7d 0a 0a 20 20 69 66 20 7b    }.#  }..  if {
3790: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47  [info exists ::G
37a0: 28 70 65 72 6d 3a 70 72 65 66 69 78 29 5d 7d 20  (perm:prefix)]} 
37b0: 7b 0a 20 20 20 20 73 65 74 20 6e 61 6d 65 20 22  {.    set name "
37c0: 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 66 69 78  $::G(perm:prefix
37d0: 29 24 6e 61 6d 65 22 0a 20 20 7d 0a 0a 20 20 69  )$name".  }..  i
37e0: 6e 63 72 5f 6e 74 65 73 74 0a 20 20 70 75 74 73  ncr_ntest.  puts
37f0: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d   -nonewline $nam
3800: 65 2e 2e 2e 0a 20 20 66 6c 75 73 68 20 73 74 64  e....  flush std
3810: 6f 75 74 0a 0a 20 20 69 66 20 7b 21 5b 69 6e 66  out..  if {![inf
3820: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6d 61 74  o exists ::G(mat
3830: 63 68 29 5d 20 7c 7c 20 5b 73 74 72 69 6e 67 20  ch)] || [string 
3840: 6d 61 74 63 68 20 24 3a 3a 47 28 6d 61 74 63 68  match $::G(match
3850: 29 20 24 6e 61 6d 65 5d 7d 20 7b 0a 20 20 20 20  ) $name]} {.    
3860: 69 66 20 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65  if {[catch {uple
3870: 76 65 6c 20 23 30 20 22 24 63 6d 64 3b 5c 6e 22  vel #0 "$cmd;\n"
3880: 7d 20 72 65 73 75 6c 74 5d 7d 20 7b 0a 20 20 20  } result]} {.   
3890: 20 20 20 70 75 74 73 20 22 5c 6e 45 72 72 6f 72     puts "\nError
38a0: 3a 20 24 72 65 73 75 6c 74 22 0a 20 20 20 20 20  : $result".     
38b0: 20 66 61 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65   fail_test $name
38c0: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b  .    } elseif {[
38d0: 73 74 72 69 6e 67 20 63 6f 6d 70 61 72 65 20 24  string compare $
38e0: 72 65 73 75 6c 74 20 24 65 78 70 65 63 74 65 64  result $expected
38f0: 5d 7d 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20  ]} {.      puts 
3900: 22 5c 6e 45 78 70 65 63 74 65 64 3a 20 5c 5b 24  "\nExpected: \[$
3910: 65 78 70 65 63 74 65 64 5c 5d 5c 6e 20 20 20 20  expected\]\n    
3920: 20 47 6f 74 3a 20 5c 5b 24 72 65 73 75 6c 74 5c   Got: \[$result\
3930: 5d 22 0a 20 20 20 20 20 20 66 61 69 6c 5f 74 65  ]".      fail_te
3940: 73 74 20 24 6e 61 6d 65 0a 20 20 20 20 7d 20 65  st $name.    } e
3950: 6c 73 65 20 7b 0a 20 20 20 20 20 20 70 75 74 73  lse {.      puts
3960: 20 22 20 4f 6b 22 0a 20 20 20 20 7d 0a 20 20 7d   " Ok".    }.  }
3970: 20 65 6c 73 65 20 7b 0a 20 20 20 20 70 75 74 73   else {.    puts
3980: 20 22 20 4f 6d 69 74 74 65 64 22 0a 20 20 20 20   " Omitted".    
3990: 6f 6d 69 74 5f 74 65 73 74 20 24 6e 61 6d 65 20  omit_test $name 
39a0: 22 70 61 74 74 65 72 6e 20 6d 69 73 6d 61 74 63  "pattern mismatc
39b0: 68 22 20 30 0a 20 20 7d 0a 20 20 66 6c 75 73 68  h" 0.  }.  flush
39c0: 20 73 74 64 6f 75 74 0a 7d 0a 0a 70 72 6f 63 20   stdout.}..proc 
39d0: 66 69 6c 65 70 61 74 68 5f 6e 6f 72 6d 61 6c 69  filepath_normali
39e0: 7a 65 20 7b 70 7d 20 7b 0a 20 20 23 20 74 65 73  ze {p} {.  # tes
39f0: 74 20 63 61 73 65 73 20 73 68 6f 75 6c 64 20 62  t cases should b
3a00: 65 20 77 72 69 74 74 65 6e 20 74 6f 20 61 73 73  e written to ass
3a10: 75 6d 65 20 22 75 6e 69 78 22 2d 6c 69 6b 65 20  ume "unix"-like 
3a20: 66 69 6c 65 20 70 61 74 68 73 0a 20 20 69 66 20  file paths.  if 
3a30: 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d  {$::tcl_platform
3a40: 28 70 6c 61 74 66 6f 72 6d 29 21 3d 22 75 6e 69  (platform)!="uni
3a50: 78 22 7d 20 7b 0a 20 20 20 20 23 20 6c 72 65 76  x"} {.    # lrev
3a60: 65 72 73 65 2a 32 20 61 73 20 61 20 68 61 63 6b  erse*2 as a hack
3a70: 20 74 6f 20 72 65 6d 6f 76 65 20 61 6e 79 20 75   to remove any u
3a80: 6e 6e 65 65 64 65 64 20 7b 7d 20 61 66 74 65 72  nneeded {} after
3a90: 20 74 68 65 20 73 74 72 69 6e 67 20 6d 61 70 0a   the string map.
3aa0: 20 20 20 20 6c 72 65 76 65 72 73 65 20 5b 6c 72      lreverse [lr
3ab0: 65 76 65 72 73 65 20 5b 73 74 72 69 6e 67 20 6d  everse [string m
3ac0: 61 70 20 7b 5c 5c 20 2f 7d 20 5b 72 65 67 73 75  ap {\\ /} [regsu
3ad0: 62 20 2d 6e 6f 63 61 73 65 20 2d 61 6c 6c 20 7b  b -nocase -all {
3ae0: 5b 61 2d 7a 5d 3a 5b 2f 5c 5c 5d 2b 7d 20 24 70  [a-z]:[/\\]+} $p
3af0: 20 7b 2f 7d 5d 5d 5d 0a 20 20 7d 20 7b 0a 20 20   {/}]]].  } {.  
3b00: 20 20 73 65 74 20 70 0a 20 20 7d 0a 7d 0a 70 72    set p.  }.}.pr
3b10: 6f 63 20 64 6f 5f 66 69 6c 65 70 61 74 68 5f 74  oc do_filepath_t
3b20: 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78  est {name cmd ex
3b30: 70 65 63 74 65 64 7d 20 7b 0a 20 20 75 70 6c 65  pected} {.  uple
3b40: 76 65 6c 20 5b 6c 69 73 74 20 64 6f 5f 74 65 73  vel [list do_tes
3b50: 74 20 24 6e 61 6d 65 20 5b 0a 20 20 20 20 73 75  t $name [.    su
3b60: 62 73 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64 73 20  bst -nocommands 
3b70: 7b 20 66 69 6c 65 70 61 74 68 5f 6e 6f 72 6d 61  { filepath_norma
3b80: 6c 69 7a 65 20 5b 20 24 63 6d 64 20 5d 20 7d 0a  lize [ $cmd ] }.
3b90: 20 20 5d 20 5b 66 69 6c 65 70 61 74 68 5f 6e 6f    ] [filepath_no
3ba0: 72 6d 61 6c 69 7a 65 20 24 65 78 70 65 63 74 65  rmalize $expecte
3bb0: 64 5d 5d 0a 7d 0a 0a 70 72 6f 63 20 72 65 61 6c  d]].}..proc real
3bc0: 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20 7b 72  num_normalize {r
3bd0: 7d 20 7b 0a 20 20 23 20 64 69 66 66 65 72 65 6e  } {.  # differen
3be0: 74 20 54 43 4c 20 76 65 72 73 69 6f 6e 73 20 64  t TCL versions d
3bf0: 69 73 70 6c 61 79 20 66 6c 6f 61 74 69 6e 67 20  isplay floating 
3c00: 70 6f 69 6e 74 20 76 61 6c 75 65 73 20 64 69 66  point values dif
3c10: 66 65 72 65 6e 74 6c 79 2e 0a 20 20 73 74 72 69  ferently..  stri
3c20: 6e 67 20 6d 61 70 20 7b 31 2e 23 49 4e 46 20 69  ng map {1.#INF i
3c30: 6e 66 20 49 6e 66 20 69 6e 66 20 2e 30 65 20 65  nf Inf inf .0e e
3c40: 7d 20 5b 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b  } [regsub -all {
3c50: 28 65 5b 2b 2d 5d 29 30 2b 7d 20 24 72 20 7b 5c  (e[+-])0+} $r {\
3c60: 31 7d 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 72 65  1}].}.proc do_re
3c70: 61 6c 6e 75 6d 5f 74 65 73 74 20 7b 6e 61 6d 65  alnum_test {name
3c80: 20 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b   cmd expected} {
3c90: 0a 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74  .  uplevel [list
3ca0: 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b   do_test $name [
3cb0: 0a 20 20 20 20 73 75 62 73 74 20 2d 6e 6f 63 6f  .    subst -noco
3cc0: 6d 6d 61 6e 64 73 20 7b 20 72 65 61 6c 6e 75 6d  mmands { realnum
3cd0: 5f 6e 6f 72 6d 61 6c 69 7a 65 20 5b 20 24 63 6d  _normalize [ $cm
3ce0: 64 20 5d 20 7d 0a 20 20 5d 20 5b 72 65 61 6c 6e  d ] }.  ] [realn
3cf0: 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20 24 65 78  um_normalize $ex
3d00: 70 65 63 74 65 64 5d 5d 0a 7d 0a 0a 70 72 6f 63  pected]].}..proc
3d10: 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 7b 76   fix_testname {v
3d20: 61 72 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61  arname} {.  upva
3d30: 72 20 24 76 61 72 6e 61 6d 65 20 74 65 73 74 6e  r $varname testn
3d40: 61 6d 65 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20  ame.  if {[info 
3d50: 65 78 69 73 74 73 20 3a 3a 74 65 73 74 70 72 65  exists ::testpre
3d60: 66 69 78 5d 20 0a 20 20 20 26 26 20 5b 73 74 72  fix] .   && [str
3d70: 69 6e 67 20 69 73 20 64 69 67 69 74 20 5b 73 74  ing is digit [st
3d80: 72 69 6e 67 20 72 61 6e 67 65 20 24 74 65 73 74  ring range $test
3d90: 6e 61 6d 65 20 30 20 30 5d 5d 0a 20 20 7d 20 7b  name 0 0]].  } {
3da0: 0a 20 20 20 20 73 65 74 20 74 65 73 74 6e 61 6d  .    set testnam
3db0: 65 20 22 24 7b 3a 3a 74 65 73 74 70 72 65 66 69  e "${::testprefi
3dc0: 78 7d 2d 24 74 65 73 74 6e 61 6d 65 22 0a 20 20  x}-$testname".  
3dd0: 7d 0a 7d 0a 20 20 20 20 0a 70 72 6f 63 20 64 6f  }.}.    .proc do
3de0: 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 7b 74  _execsql_test {t
3df0: 65 73 74 6e 61 6d 65 20 73 71 6c 20 7b 72 65 73  estname sql {res
3e00: 75 6c 74 20 7b 7d 7d 7d 20 7b 0a 20 20 66 69 78  ult {}}} {.  fix
3e10: 5f 74 65 73 74 6e 61 6d 65 20 74 65 73 74 6e 61  _testname testna
3e20: 6d 65 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f  me.  uplevel do_
3e30: 74 65 73 74 20 5b 6c 69 73 74 20 24 74 65 73 74  test [list $test
3e40: 6e 61 6d 65 5d 20 5b 6c 69 73 74 20 22 65 78 65  name] [list "exe
3e50: 63 73 71 6c 20 7b 24 73 71 6c 7d 22 5d 20 5b 6c  csql {$sql}"] [l
3e60: 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65  ist [list {*}$re
3e70: 73 75 6c 74 5d 5d 0a 7d 0a 70 72 6f 63 20 64 6f  sult]].}.proc do
3e80: 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74 20 7b  _catchsql_test {
3e90: 74 65 73 74 6e 61 6d 65 20 73 71 6c 20 72 65 73  testname sql res
3ea0: 75 6c 74 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73  ult} {.  fix_tes
3eb0: 74 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20  tname testname. 
3ec0: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74   uplevel do_test
3ed0: 20 5b 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65   [list $testname
3ee0: 5d 20 5b 6c 69 73 74 20 22 63 61 74 63 68 73 71  ] [list "catchsq
3ef0: 6c 20 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69 73 74  l {$sql}"] [list
3f00: 20 24 72 65 73 75 6c 74 5d 0a 7d 0a 70 72 6f 63   $result].}.proc
3f10: 20 64 6f 5f 65 71 70 5f 74 65 73 74 20 7b 6e 61   do_eqp_test {na
3f20: 6d 65 20 73 71 6c 20 72 65 73 7d 20 7b 0a 20 20  me sql res} {.  
3f30: 75 70 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63 73  uplevel do_execs
3f40: 71 6c 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 6c  ql_test $name [l
3f50: 69 73 74 20 22 45 58 50 4c 41 49 4e 20 51 55 45  ist "EXPLAIN QUE
3f60: 52 59 20 50 4c 41 4e 20 24 73 71 6c 22 5d 20 5b  RY PLAN $sql"] [
3f70: 6c 69 73 74 20 24 72 65 73 5d 0a 7d 0a 0a 23 2d  list $res].}..#-
3f80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3fa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3fb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3fc0: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 20 20 55 73 61  --------.#   Usa
3fd0: 67 65 3a 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65  ge: do_select_te
3fe0: 73 74 73 20 50 52 45 46 49 58 20 3f 53 57 49 54  sts PREFIX ?SWIT
3ff0: 43 48 45 53 3f 20 54 45 53 54 4c 49 53 54 0a 23  CHES? TESTLIST.#
4000: 0a 23 20 57 68 65 72 65 20 73 77 69 74 63 68 65  .# Where switche
4010: 73 20 61 72 65 3a 0a 23 0a 23 20 20 20 2d 65 72  s are:.#.#   -er
4020: 72 6f 72 66 6f 72 6d 61 74 20 46 4d 54 53 54 52  rorformat FMTSTR
4030: 49 4e 47 0a 23 20 20 20 2d 63 6f 75 6e 74 0a 23  ING.#   -count.#
4040: 20 20 20 2d 71 75 65 72 79 20 53 51 4c 0a 23 20     -query SQL.# 
4050: 20 20 2d 74 63 6c 71 75 65 72 79 20 54 43 4c 0a    -tclquery TCL.
4060: 23 20 20 20 2d 72 65 70 61 69 72 20 54 43 4c 0a  #   -repair TCL.
4070: 23 0a 70 72 6f 63 20 64 6f 5f 73 65 6c 65 63 74  #.proc do_select
4080: 5f 74 65 73 74 73 20 7b 70 72 65 66 69 78 20 61  _tests {prefix a
4090: 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 74 65  rgs} {..  set te
40a0: 73 74 6c 69 73 74 20 5b 6c 69 6e 64 65 78 20 24  stlist [lindex $
40b0: 61 72 67 73 20 65 6e 64 5d 0a 20 20 73 65 74 20  args end].  set 
40c0: 73 77 69 74 63 68 65 73 20 5b 6c 72 61 6e 67 65  switches [lrange
40d0: 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 0a   $args 0 end-1].
40e0: 0a 20 20 73 65 74 20 65 72 72 66 6d 74 20 22 22  .  set errfmt ""
40f0: 0a 20 20 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79  .  set countonly
4100: 20 30 0a 20 20 73 65 74 20 74 63 6c 71 75 65 72   0.  set tclquer
4110: 79 20 22 22 0a 20 20 73 65 74 20 72 65 70 61 69  y "".  set repai
4120: 72 20 22 22 0a 0a 20 20 66 6f 72 20 7b 73 65 74  r ""..  for {set
4130: 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b 6c 6c 65   i 0} {$i < [lle
4140: 6e 67 74 68 20 24 73 77 69 74 63 68 65 73 5d 7d  ngth $switches]}
4150: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
4160: 73 65 74 20 73 20 5b 6c 69 6e 64 65 78 20 24 73  set s [lindex $s
4170: 77 69 74 63 68 65 73 20 24 69 5d 0a 20 20 20 20  witches $i].    
4180: 73 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65  set n [string le
4190: 6e 67 74 68 20 24 73 5d 0a 20 20 20 20 69 66 20  ngth $s].    if 
41a0: 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e  {$n>=2 && [strin
41b0: 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20  g equal -length 
41c0: 24 6e 20 24 73 20 22 2d 71 75 65 72 79 22 5d 7d  $n $s "-query"]}
41d0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 74 63 6c   {.      set tcl
41e0: 71 75 65 72 79 20 5b 6c 69 73 74 20 65 78 65 63  query [list exec
41f0: 73 71 6c 20 5b 6c 69 6e 64 65 78 20 24 73 77 69  sql [lindex $swi
4200: 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 5d  tches [incr i]]]
4210: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
4220: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
4230: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
4240: 20 24 73 20 22 2d 74 63 6c 71 75 65 72 79 22 5d   $s "-tclquery"]
4250: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 74 63  } {.      set tc
4260: 6c 71 75 65 72 79 20 5b 6c 69 6e 64 65 78 20 24  lquery [lindex $
4270: 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69  switches [incr i
4280: 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20  ]].    } elseif 
4290: 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e  {$n>=2 && [strin
42a0: 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20  g equal -length 
42b0: 24 6e 20 24 73 20 22 2d 65 72 72 6f 72 66 6f 72  $n $s "-errorfor
42c0: 6d 61 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73  mat"]} {.      s
42d0: 65 74 20 65 72 72 66 6d 74 20 5b 6c 69 6e 64 65  et errfmt [linde
42e0: 78 20 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63  x $switches [inc
42f0: 72 20 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65  r i]].    } else
4300: 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74  if {$n>=2 && [st
4310: 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67  ring equal -leng
4320: 74 68 20 24 6e 20 24 73 20 22 2d 72 65 70 61 69  th $n $s "-repai
4330: 72 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  r"]} {.      set
4340: 20 72 65 70 61 69 72 20 5b 6c 69 6e 64 65 78 20   repair [lindex 
4350: 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20  $switches [incr 
4360: 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66  i]].    } elseif
4370: 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69   {$n>=2 && [stri
4380: 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68  ng equal -length
4390: 20 24 6e 20 24 73 20 22 2d 63 6f 75 6e 74 22 5d   $n $s "-count"]
43a0: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 63 6f  } {.      set co
43b0: 75 6e 74 6f 6e 6c 79 20 31 0a 20 20 20 20 7d 20  untonly 1.    } 
43c0: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 65 72 72  else {.      err
43d0: 6f 72 20 22 75 6e 6b 6e 6f 77 6e 20 73 77 69 74  or "unknown swit
43e0: 63 68 3a 20 24 73 22 0a 20 20 20 20 7d 0a 20 20  ch: $s".    }.  
43f0: 7d 0a 0a 20 20 69 66 20 7b 24 63 6f 75 6e 74 6f  }..  if {$counto
4400: 6e 6c 79 20 26 26 20 24 65 72 72 66 6d 74 21 3d  nly && $errfmt!=
4410: 22 22 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20  ""} {.    error 
4420: 22 43 61 6e 6e 6f 74 20 75 73 65 20 2d 63 6f 75  "Cannot use -cou
4430: 6e 74 20 61 6e 64 20 2d 65 72 72 6f 72 66 6f 72  nt and -errorfor
4440: 6d 61 74 20 74 6f 67 65 74 68 65 72 22 0a 20 20  mat together".  
4450: 7d 0a 20 20 73 65 74 20 6e 54 65 73 74 6c 69 73  }.  set nTestlis
4460: 74 20 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73 74  t [llength $test
4470: 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24 6e 54 65  list].  if {$nTe
4480: 73 74 6c 69 73 74 25 33 20 7c 7c 20 24 6e 54 65  stlist%3 || $nTe
4490: 73 74 6c 69 73 74 3d 3d 30 20 7d 20 7b 0a 20 20  stlist==0 } {.  
44a0: 20 20 65 72 72 6f 72 20 22 53 45 4c 45 43 54 20    error "SELECT 
44b0: 74 65 73 74 20 6c 69 73 74 20 63 6f 6e 74 61 69  test list contai
44c0: 6e 73 20 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73  ns [llength $tes
44d0: 74 6c 69 73 74 5d 20 65 6c 65 6d 65 6e 74 73 22  tlist] elements"
44e0: 0a 20 20 7d 0a 0a 20 20 65 76 61 6c 20 24 72 65  .  }..  eval $re
44f0: 70 61 69 72 0a 20 20 66 6f 72 65 61 63 68 20 7b  pair.  foreach {
4500: 74 6e 20 73 71 6c 20 72 65 73 7d 20 24 74 65 73  tn sql res} $tes
4510: 74 6c 69 73 74 20 7b 0a 20 20 20 20 69 66 20 7b  tlist {.    if {
4520: 24 74 63 6c 71 75 65 72 79 20 21 3d 20 22 22 7d  $tclquery != ""}
4530: 20 7b 0a 20 20 20 20 20 20 65 78 65 63 73 71 6c   {.      execsql
4540: 20 24 73 71 6c 0a 20 20 20 20 20 20 75 70 6c 65   $sql.      uple
4550: 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 7b 70 72  vel do_test ${pr
4560: 65 66 69 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20  efix}.$tn [list 
4570: 24 74 63 6c 71 75 65 72 79 5d 20 5b 6c 69 73 74  $tclquery] [list
4580: 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d   [list {*}$res]]
4590: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
45a0: 63 6f 75 6e 74 6f 6e 6c 79 7d 20 7b 0a 20 20 20  countonly} {.   
45b0: 20 20 20 73 65 74 20 6e 52 6f 77 20 30 0a 20 20     set nRow 0.  
45c0: 20 20 20 20 64 62 20 65 76 61 6c 20 24 73 71 6c      db eval $sql
45d0: 20 7b 69 6e 63 72 20 6e 52 6f 77 7d 0a 20 20 20   {incr nRow}.   
45e0: 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65     uplevel do_te
45f0: 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e  st ${prefix}.$tn
4600: 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 73 65 74   [list [list set
4610: 20 7b 7d 20 24 6e 52 6f 77 5d 5d 20 5b 6c 69 73   {} $nRow]] [lis
4620: 74 20 24 72 65 73 5d 0a 20 20 20 20 7d 20 65 6c  t $res].    } el
4630: 73 65 69 66 20 7b 24 65 72 72 66 6d 74 3d 3d 22  seif {$errfmt=="
4640: 22 7d 20 7b 0a 20 20 20 20 20 20 75 70 6c 65 76  "} {.      uplev
4650: 65 6c 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65  el do_execsql_te
4660: 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 7b 74  st ${prefix}.${t
4670: 6e 7d 20 5b 6c 69 73 74 20 24 73 71 6c 5d 20 5b  n} [list $sql] [
4680: 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72  list [list {*}$r
4690: 65 73 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20  es]].    } else 
46a0: 7b 0a 20 20 20 20 20 20 73 65 74 20 72 65 73 20  {.      set res 
46b0: 5b 6c 69 73 74 20 31 20 5b 73 74 72 69 6e 67 20  [list 1 [string 
46c0: 74 72 69 6d 20 5b 66 6f 72 6d 61 74 20 24 65 72  trim [format $er
46d0: 72 66 6d 74 20 7b 2a 7d 24 72 65 73 5d 5d 5d 0a  rfmt {*}$res]]].
46e0: 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f        uplevel do
46f0: 5f 63 61 74 63 68 73 71 6c 5f 74 65 73 74 20 24  _catchsql_test $
4700: 7b 70 72 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b  {prefix}.${tn} [
4710: 6c 69 73 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74  list $sql] [list
4720: 20 24 72 65 73 5d 0a 20 20 20 20 7d 0a 20 20 20   $res].    }.   
4730: 20 65 76 61 6c 20 24 72 65 70 61 69 72 0a 20 20   eval $repair.  
4740: 7d 0a 0a 7d 0a 0a 70 72 6f 63 20 64 65 6c 65 74  }..}..proc delet
4750: 65 5f 61 6c 6c 5f 64 61 74 61 20 7b 7d 20 7b 0a  e_all_data {} {.
4760: 20 20 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43    db eval {SELEC
4770: 54 20 74 62 6c 5f 6e 61 6d 65 20 41 53 20 74 20  T tbl_name AS t 
4780: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
4790: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
47a0: 27 74 61 62 6c 65 27 7d 20 7b 0a 20 20 20 20 64  'table'} {.    d
47b0: 62 20 65 76 61 6c 20 22 44 45 4c 45 54 45 20 46  b eval "DELETE F
47c0: 52 4f 4d 20 27 5b 73 74 72 69 6e 67 20 6d 61 70  ROM '[string map
47d0: 20 7b 27 20 27 27 7d 20 24 74 5d 27 22 0a 20 20   {' ''} $t]'".  
47e0: 7d 0a 7d 0a 0a 23 20 52 75 6e 20 61 6e 20 53 51  }.}..# Run an SQ
47f0: 4c 20 73 63 72 69 70 74 2e 20 20 0a 23 20 52 65  L script.  .# Re
4800: 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20  turn the number 
4810: 6f 66 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20  of microseconds 
4820: 70 65 72 20 73 74 61 74 65 6d 65 6e 74 2e 0a 23  per statement..#
4830: 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61  .proc speed_tria
4840: 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20  l {name numstmt 
4850: 75 6e 69 74 73 20 73 71 6c 7d 20 7b 0a 20 20 70  units sql} {.  p
4860: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b  uts -nonewline [
4870: 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73  format {%-21.21s
4880: 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66   } $name...].  f
4890: 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65  lush stdout.  se
48a0: 74 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 73  t speed [time {s
48b0: 71 6c 69 74 65 33 5f 65 78 65 63 5f 6e 72 20 64  qlite3_exec_nr d
48c0: 62 20 24 73 71 6c 7d 5d 0a 20 20 73 65 74 20 74  b $sql}].  set t
48d0: 6d 20 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64  m [lindex $speed
48e0: 20 30 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d 3d   0].  if {$tm ==
48f0: 20 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 61   0} {.    set ra
4900: 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 73 20  te [format %20s 
4910: 22 6d 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73 65  "many"].  } else
4920: 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65 20   {.    set rate 
4930: 5b 66 6f 72 6d 61 74 20 25 32 30 2e 35 66 20 5b  [format %20.5f [
4940: 65 78 70 72 20 7b 31 30 30 30 30 30 30 2e 30 2a  expr {1000000.0*
4950: 24 6e 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a  $numstmt/$tm}]].
4960: 20 20 7d 0a 20 20 73 65 74 20 75 32 20 24 75 6e    }.  set u2 $un
4970: 69 74 73 2f 73 0a 20 20 70 75 74 73 20 5b 66 6f  its/s.  puts [fo
4980: 72 6d 61 74 20 7b 25 31 32 64 20 75 53 20 25 73  rmat {%12d uS %s
4990: 20 25 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24   %s} $tm $rate $
49a0: 75 32 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74  u2].  global tot
49b0: 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f  al_time.  set to
49c0: 74 61 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b  tal_time [expr {
49d0: 24 74 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d  $total_time+$tm}
49e0: 5d 0a 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73 70  ].  lappend ::sp
49f0: 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20  eed_trial_times 
4a00: 24 6e 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f 63  $name $tm.}.proc
4a10: 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 63 6c   speed_trial_tcl
4a20: 20 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75   {name numstmt u
4a30: 6e 69 74 73 20 73 63 72 69 70 74 7d 20 7b 0a 20  nits script} {. 
4a40: 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65   puts -nonewline
4a50: 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32   [format {%-21.2
4a60: 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20  1s } $name...]. 
4a70: 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20   flush stdout.  
4a80: 73 65 74 20 73 70 65 65 64 20 5b 74 69 6d 65 20  set speed [time 
4a90: 7b 65 76 61 6c 20 24 73 63 72 69 70 74 7d 5d 0a  {eval $script}].
4aa0: 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78    set tm [lindex
4ab0: 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69 66 20   $speed 0].  if 
4ac0: 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20  {$tm == 0} {.   
4ad0: 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61   set rate [forma
4ae0: 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20  t %20s "many"]. 
4af0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
4b00: 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25  t rate [format %
4b10: 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31 30 30  20.5f [expr {100
4b20: 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f  0000.0*$numstmt/
4b30: 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74  $tm}]].  }.  set
4b40: 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20 70   u2 $units/s.  p
4b50: 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32  uts [format {%12
4b60: 64 20 75 53 20 25 73 20 25 73 7d 20 24 74 6d 20  d uS %s %s} $tm 
4b70: 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f  $rate $u2].  glo
4b80: 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20  bal total_time. 
4b90: 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20   set total_time 
4ba0: 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69  [expr {$total_ti
4bb0: 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70 70 65  me+$tm}].  lappe
4bc0: 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c  nd ::speed_trial
4bd0: 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20 24 74 6d  _times $name $tm
4be0: 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72  .}.proc speed_tr
4bf0: 69 61 6c 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20  ial_init {name} 
4c00: 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  {.  global total
4c10: 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61  _time.  set tota
4c20: 6c 5f 74 69 6d 65 20 30 0a 20 20 73 65 74 20 3a  l_time 0.  set :
4c30: 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d  :speed_trial_tim
4c40: 65 73 20 5b 6c 69 73 74 5d 0a 20 20 73 71 6c 69  es [list].  sqli
4c50: 74 65 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f  te3 versdb :memo
4c60: 72 79 3a 0a 20 20 73 65 74 20 76 65 72 73 20 5b  ry:.  set vers [
4c70: 76 65 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45  versdb one {SELE
4c80: 43 54 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65  CT sqlite_source
4c90: 5f 69 64 28 29 7d 5d 0a 20 20 76 65 72 73 64 62  _id()}].  versdb
4ca0: 20 63 6c 6f 73 65 0a 20 20 70 75 74 73 20 22 53   close.  puts "S
4cb0: 51 4c 69 74 65 20 24 76 65 72 73 22 0a 7d 0a 70  QLite $vers".}.p
4cc0: 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 5f  roc speed_trial_
4cd0: 73 75 6d 6d 61 72 79 20 7b 6e 61 6d 65 7d 20 7b  summary {name} {
4ce0: 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f  .  global total_
4cf0: 74 69 6d 65 0a 20 20 70 75 74 73 20 5b 66 6f 72  time.  puts [for
4d00: 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 25 31  mat {%-21.21s %1
4d10: 32 64 20 75 53 20 54 4f 54 41 4c 7d 20 24 6e 61  2d uS TOTAL} $na
4d20: 6d 65 20 24 74 6f 74 61 6c 5f 74 69 6d 65 5d 0a  me $total_time].
4d30: 0a 20 20 69 66 20 7b 20 30 20 7d 20 7b 0a 20 20  .  if { 0 } {.  
4d40: 20 20 73 71 6c 69 74 65 33 20 76 65 72 73 64 62    sqlite3 versdb
4d50: 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 20 20 73 65   :memory:.    se
4d60: 74 20 76 65 72 73 20 5b 6c 69 6e 64 65 78 20 5b  t vers [lindex [
4d70: 76 65 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45  versdb one {SELE
4d80: 43 54 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65  CT sqlite_source
4d90: 5f 69 64 28 29 7d 5d 20 30 5d 0a 20 20 20 20 76  _id()}] 0].    v
4da0: 65 72 73 64 62 20 63 6c 6f 73 65 0a 20 20 20 20  ersdb close.    
4db0: 70 75 74 73 20 22 43 52 45 41 54 45 20 54 41 42  puts "CREATE TAB
4dc0: 4c 45 20 49 46 20 4e 4f 54 20 45 58 49 53 54 53  LE IF NOT EXISTS
4dd0: 20 74 69 6d 65 28 76 65 72 73 69 6f 6e 2c 20 73   time(version, s
4de0: 63 72 69 70 74 2c 20 74 65 73 74 2c 20 75 73 29  cript, test, us)
4df0: 3b 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b  ;".    foreach {
4e00: 74 65 73 74 20 75 73 7d 20 24 3a 3a 73 70 65 65  test us} $::spee
4e10: 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 7b 0a  d_trial_times {.
4e20: 20 20 20 20 20 20 70 75 74 73 20 22 49 4e 53 45        puts "INSE
4e30: 52 54 20 49 4e 54 4f 20 74 69 6d 65 20 56 41 4c  RT INTO time VAL
4e40: 55 45 53 28 27 24 76 65 72 73 27 2c 20 27 24 6e  UES('$vers', '$n
4e50: 61 6d 65 27 2c 20 27 24 74 65 73 74 27 2c 20 24  ame', '$test', $
4e60: 75 73 29 3b 22 0a 20 20 20 20 7d 0a 20 20 7d 0a  us);".    }.  }.
4e70: 7d 0a 0a 23 20 52 75 6e 20 74 68 69 73 20 72 6f  }..# Run this ro
4e80: 75 74 69 6e 65 20 6c 61 73 74 0a 23 0a 70 72 6f  utine last.#.pro
4e90: 63 20 66 69 6e 69 73 68 5f 74 65 73 74 20 7b 7d  c finish_test {}
4ea0: 20 7b 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63   {.  catch {db c
4eb0: 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64  lose}.  catch {d
4ec0: 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  b2 close}.  catc
4ed0: 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 20 20  h {db3 close}.  
4ee0: 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69  if {0==[info exi
4ef0: 73 74 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 20  sts ::SLAVE]} { 
4f00: 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67  finalize_testing
4f10: 20 7d 0a 7d 0a 70 72 6f 63 20 66 69 6e 61 6c 69   }.}.proc finali
4f20: 7a 65 5f 74 65 73 74 69 6e 67 20 7b 7d 20 7b 0a  ze_testing {} {.
4f30: 20 20 67 6c 6f 62 61 6c 20 73 71 6c 69 74 65 5f    global sqlite_
4f40: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a  open_file_count.
4f50: 0a 20 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20  .  set omitList 
4f60: 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65  [set_test_counte
4f70: 72 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 0a 20 20  r omit_list]..  
4f80: 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d  catch {db close}
4f90: 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c  .  catch {db2 cl
4fa0: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
4fb0: 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 76 66 73 5f  3 close}..  vfs_
4fc0: 75 6e 6c 69 6e 6b 5f 74 65 73 74 0a 20 20 73 71  unlink_test.  sq
4fd0: 6c 69 74 65 33 20 64 62 20 7b 7d 0a 20 20 23 20  lite3 db {}.  # 
4fe0: 73 71 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74 73  sqlite3_clear_ts
4ff0: 64 5f 6d 65 6d 64 65 62 75 67 0a 20 20 64 62 20  d_memdebug.  db 
5000: 63 6c 6f 73 65 0a 20 20 73 71 6c 69 74 65 33 5f  close.  sqlite3_
5010: 72 65 73 65 74 5f 61 75 74 6f 5f 65 78 74 65 6e  reset_auto_exten
5020: 73 69 6f 6e 0a 0a 20 20 73 71 6c 69 74 65 33 5f  sion..  sqlite3_
5030: 73 6f 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20  soft_heap_limit 
5040: 30 0a 20 20 73 65 74 20 6e 54 65 73 74 20 5b 69  0.  set nTest [i
5050: 6e 63 72 5f 6e 74 65 73 74 5d 0a 20 20 73 65 74  ncr_ntest].  set
5060: 20 6e 45 72 72 20 5b 73 65 74 5f 74 65 73 74 5f   nErr [set_test_
5070: 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a  counter errors].
5080: 0a 20 20 70 75 74 73 20 22 24 6e 45 72 72 20 65  .  puts "$nErr e
5090: 72 72 6f 72 73 20 6f 75 74 20 6f 66 20 24 6e 54  rrors out of $nT
50a0: 65 73 74 20 74 65 73 74 73 22 0a 20 20 69 66 20  est tests".  if 
50b0: 7b 24 6e 45 72 72 3e 30 7d 20 7b 0a 20 20 20 20  {$nErr>0} {.    
50c0: 70 75 74 73 20 22 46 61 69 6c 75 72 65 73 20 6f  puts "Failures o
50d0: 6e 20 74 68 65 73 65 20 74 65 73 74 73 3a 20 5b  n these tests: [
50e0: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
50f0: 20 66 61 69 6c 5f 6c 69 73 74 5d 22 0a 20 20 7d   fail_list]".  }
5100: 0a 20 20 72 75 6e 5f 74 68 72 65 61 64 5f 74 65  .  run_thread_te
5110: 73 74 73 20 31 0a 20 20 69 66 20 7b 5b 6c 6c 65  sts 1.  if {[lle
5120: 6e 67 74 68 20 24 6f 6d 69 74 4c 69 73 74 5d 3e  ngth $omitList]>
5130: 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 4f  0} {.    puts "O
5140: 6d 69 74 74 65 64 20 74 65 73 74 20 63 61 73 65  mitted test case
5150: 73 3a 22 0a 20 20 20 20 73 65 74 20 70 72 65 63  s:".    set prec
5160: 20 7b 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20   {}.    foreach 
5170: 7b 72 65 63 7d 20 5b 6c 73 6f 72 74 20 24 6f 6d  {rec} [lsort $om
5180: 69 74 4c 69 73 74 5d 20 7b 0a 20 20 20 20 20 20  itList] {.      
5190: 69 66 20 7b 24 72 65 63 3d 3d 24 70 72 65 63 7d  if {$rec==$prec}
51a0: 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20   continue.      
51b0: 73 65 74 20 70 72 65 63 20 24 72 65 63 0a 20 20  set prec $rec.  
51c0: 20 20 20 20 70 75 74 73 20 5b 66 6f 72 6d 61 74      puts [format
51d0: 20 7b 20 20 25 2d 31 32 73 20 25 73 7d 20 5b 6c   {  %-12s %s} [l
51e0: 69 6e 64 65 78 20 24 72 65 63 20 30 5d 20 5b 6c  index $rec 0] [l
51f0: 69 6e 64 65 78 20 24 72 65 63 20 31 5d 5d 0a 20  index $rec 1]]. 
5200: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24     }.  }.  if {$
5210: 6e 45 72 72 3e 30 20 26 26 20 21 5b 77 6f 72 6b  nErr>0 && ![work
5220: 69 6e 67 5f 36 34 62 69 74 5f 69 6e 74 5d 7d 20  ing_64bit_int]} 
5230: 7b 0a 20 20 20 20 70 75 74 73 20 22 2a 2a 2a 2a  {.    puts "****
5240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5250: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5260: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5270: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a  **************".
5280: 20 20 20 20 70 75 74 73 20 22 4e 2e 42 2e 3a 20      puts "N.B.: 
5290: 20 54 68 65 20 76 65 72 73 69 6f 6e 20 6f 66 20   The version of 
52a0: 54 43 4c 20 74 68 61 74 20 79 6f 75 20 75 73 65  TCL that you use
52b0: 64 20 74 6f 20 62 75 69 6c 64 20 74 68 69 73 20  d to build this 
52c0: 74 65 73 74 20 68 61 72 6e 65 73 73 22 0a 20 20  test harness".  
52d0: 20 20 70 75 74 73 20 22 69 73 20 64 65 66 65 63    puts "is defec
52e0: 74 69 76 65 20 69 6e 20 74 68 61 74 20 69 74 20  tive in that it 
52f0: 64 6f 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74  does not support
5300: 20 36 34 2d 62 69 74 20 69 6e 74 65 67 65 72 73   64-bit integers
5310: 2e 20 20 53 6f 6d 65 20 6f 72 22 0a 20 20 20 20  .  Some or".    
5320: 70 75 74 73 20 22 61 6c 6c 20 6f 66 20 74 68 65  puts "all of the
5330: 20 74 65 73 74 20 66 61 69 6c 75 72 65 73 20 61   test failures a
5340: 62 6f 76 65 20 6d 69 67 68 74 20 62 65 20 61 20  bove might be a 
5350: 72 65 73 75 6c 74 20 66 72 6f 6d 20 74 68 69 73  result from this
5360: 20 64 65 66 65 63 74 22 0a 20 20 20 20 70 75 74   defect".    put
5370: 73 20 22 69 6e 20 79 6f 75 72 20 54 43 4c 20 62  s "in your TCL b
5380: 75 69 6c 64 2e 22 0a 20 20 20 20 70 75 74 73 20  uild.".    puts 
5390: 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  "***************
53a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
53b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
53c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
53d0: 2a 2a 2a 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24  ***".  }.  if {$
53e0: 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e  ::cmdlinearg(bin
53f0: 61 72 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76  arylog)} {.    v
5400: 66 73 6c 6f 67 20 66 69 6e 61 6c 69 7a 65 20 62  fslog finalize b
5410: 69 6e 61 72 79 6c 6f 67 0a 20 20 7d 0a 20 20 69  inarylog.  }.  i
5420: 66 20 7b 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f  f {$sqlite_open_
5430: 66 69 6c 65 5f 63 6f 75 6e 74 7d 20 7b 0a 20 20  file_count} {.  
5440: 20 20 70 75 74 73 20 22 24 73 71 6c 69 74 65 5f    puts "$sqlite_
5450: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20  open_file_count 
5460: 66 69 6c 65 73 20 77 65 72 65 20 6c 65 66 74 20  files were left 
5470: 6f 70 65 6e 22 0a 20 20 20 20 69 6e 63 72 20 6e  open".    incr n
5480: 45 72 72 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 6c  Err.  }.  if {[l
5490: 69 6e 64 65 78 20 5b 73 71 6c 69 74 65 33 5f 73  index [sqlite3_s
54a0: 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41  tatus SQLITE_STA
54b0: 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54  TUS_MALLOC_COUNT
54c0: 20 30 5d 20 31 5d 3e 30 20 7c 7c 0a 20 20 20 20   0] 1]>0 ||.    
54d0: 20 20 20 20 20 20 20 20 20 20 5b 73 71 6c 69 74            [sqlit
54e0: 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e  e3_memory_used]>
54f0: 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 55  0} {.    puts "U
5500: 6e 66 72 65 65 64 20 6d 65 6d 6f 72 79 3a 20 5b  nfreed memory: [
5510: 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75  sqlite3_memory_u
5520: 73 65 64 5d 20 62 79 74 65 73 20 69 6e 5c 0a 20  sed] bytes in\. 
5530: 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20          [lindex 
5540: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
5550: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41  SQLITE_STATUS_MA
5560: 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d  LLOC_COUNT 0] 1]
5570: 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 22 0a 20 20   allocations".  
5580: 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 20 20    incr nErr.    
5590: 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64 65 62  ifcapable memdeb
55a0: 75 67 7c 7c 6d 65 6d 35 7c 7c 28 6d 65 6d 33 26  ug||mem5||(mem3&
55b0: 26 64 65 62 75 67 29 20 7b 0a 20 20 20 20 20 20  &debug) {.      
55c0: 70 75 74 73 20 22 57 72 69 74 69 6e 67 20 75 6e  puts "Writing un
55d0: 66 72 65 65 64 20 6d 65 6d 6f 72 79 20 6c 6f 67  freed memory log
55e0: 20 74 6f 20 5c 22 2e 2f 6d 65 6d 6c 65 61 6b 2e   to \"./memleak.
55f0: 74 78 74 5c 22 22 0a 20 20 20 20 20 20 73 71 6c  txt\"".      sql
5600: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75  ite3_memdebug_du
5610: 6d 70 20 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74  mp ./memleak.txt
5620: 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20  .    }.  } else 
5630: 7b 0a 20 20 20 20 70 75 74 73 20 22 41 6c 6c 20  {.    puts "All 
5640: 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f  memory allocatio
5650: 6e 73 20 66 72 65 65 64 20 2d 20 6e 6f 20 6c 65  ns freed - no le
5660: 61 6b 73 22 0a 20 20 20 20 69 66 63 61 70 61 62  aks".    ifcapab
5670: 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d  le memdebug||mem
5680: 35 20 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  5 {.      sqlite
5690: 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70 20  3_memdebug_dump 
56a0: 2e 2f 6d 65 6d 75 73 61 67 65 2e 74 78 74 0a 20  ./memusage.txt. 
56b0: 20 20 20 7d 0a 20 20 7d 0a 20 20 73 68 6f 77 5f     }.  }.  show_
56c0: 6d 65 6d 73 74 61 74 73 0a 20 20 70 75 74 73 20  memstats.  puts 
56d0: 22 4d 61 78 69 6d 75 6d 20 6d 65 6d 6f 72 79 20  "Maximum memory 
56e0: 75 73 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f  usage: [sqlite3_
56f0: 6d 65 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72  memory_highwater
5700: 20 31 5d 20 62 79 74 65 73 22 0a 20 20 70 75 74   1] bytes".  put
5710: 73 20 22 43 75 72 72 65 6e 74 20 6d 65 6d 6f 72  s "Current memor
5720: 79 20 75 73 61 67 65 3a 20 5b 73 71 6c 69 74 65  y usage: [sqlite
5730: 33 5f 6d 65 6d 6f 72 79 5f 68 69 67 68 77 61 74  3_memory_highwat
5740: 65 72 5d 20 62 79 74 65 73 22 0a 20 20 69 66 20  er] bytes".  if 
5750: 7b 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20  {[info commands 
5760: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
5770: 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20 6e  _malloc_count] n
5780: 65 20 22 22 7d 20 7b 0a 20 20 20 20 70 75 74 73  e ""} {.    puts
5790: 20 22 4e 75 6d 62 65 72 20 6f 66 20 6d 61 6c 6c   "Number of mall
57a0: 6f 63 28 29 20 20 3a 20 5b 73 71 6c 69 74 65 33  oc()  : [sqlite3
57b0: 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63  _memdebug_malloc
57c0: 5f 63 6f 75 6e 74 5d 20 63 61 6c 6c 73 22 0a 20  _count] calls". 
57d0: 20 7d 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c   }.  if {$::cmdl
57e0: 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61  inearg(malloctra
57f0: 63 65 29 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  ce)} {.    puts 
5800: 22 57 72 69 74 69 6e 67 20 6d 61 6c 6c 6f 63 73  "Writing mallocs
5810: 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20 20 6d 65 6d  .sql...".    mem
5820: 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 0a 20 20  debug_log_sql.  
5830: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
5840: 75 67 5f 6c 6f 67 20 73 74 6f 70 0a 20 20 20 20  ug_log stop.    
5850: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
5860: 5f 6c 6f 67 20 63 6c 65 61 72 0a 0a 20 20 20 20  _log clear..    
5870: 69 66 20 7b 5b 73 71 6c 69 74 65 33 5f 6d 65 6d  if {[sqlite3_mem
5880: 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20  ory_used]>0} {. 
5890: 20 20 20 20 20 70 75 74 73 20 22 57 72 69 74 69       puts "Writi
58a0: 6e 67 20 6c 65 61 6b 73 2e 73 71 6c 2e 2e 2e 22  ng leaks.sql..."
58b0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
58c0: 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 79 6e 63  emdebug_log sync
58d0: 0a 20 20 20 20 20 20 6d 65 6d 64 65 62 75 67 5f  .      memdebug_
58e0: 6c 6f 67 5f 73 71 6c 20 6c 65 61 6b 73 2e 73 71  log_sql leaks.sq
58f0: 6c 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 63 61  l.    }.  }.  ca
5900: 74 63 68 20 7b 0a 20 20 20 20 66 6f 72 65 61 63  tch {.    foreac
5910: 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
5920: 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d 2a 2d  plain test.db-*-
5930: 6a 6f 75 72 6e 61 6c 5d 20 7b 0a 20 20 20 20 20  journal] {.     
5940: 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 0a   forcedelete $f.
5950: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 63 61 74 63      }.  }.  catc
5960: 68 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20  h {.    foreach 
5970: 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
5980: 61 69 6e 20 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d  ain test.db-mj*]
5990: 20 7b 0a 20 20 20 20 20 20 66 6f 72 63 65 64 65   {.      forcede
59a0: 6c 65 74 65 20 24 66 0a 20 20 20 20 7d 0a 20 20  lete $f.    }.  
59b0: 7d 0a 20 20 65 78 69 74 20 5b 65 78 70 72 20 7b  }.  exit [expr {
59c0: 24 6e 45 72 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 44  $nErr>0}].}..# D
59d0: 69 73 70 6c 61 79 20 6d 65 6d 6f 72 79 20 73 74  isplay memory st
59e0: 61 74 69 73 74 69 63 73 20 66 6f 72 20 61 6e 61  atistics for ana
59f0: 6c 79 73 69 73 20 61 6e 64 20 64 65 62 75 67 67  lysis and debugg
5a00: 69 6e 67 20 70 75 72 70 6f 73 65 73 2e 0a 23 0a  ing purposes..#.
5a10: 70 72 6f 63 20 73 68 6f 77 5f 6d 65 6d 73 74 61  proc show_memsta
5a20: 74 73 20 7b 7d 20 7b 0a 20 20 73 65 74 20 78 20  ts {} {.  set x 
5a30: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
5a40: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 45  SQLITE_STATUS_ME
5a50: 4d 4f 52 59 5f 55 53 45 44 20 30 5d 0a 20 20 73  MORY_USED 0].  s
5a60: 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74  et y [sqlite3_st
5a70: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
5a80: 55 53 5f 4d 41 4c 4c 4f 43 5f 53 49 5a 45 20 30  US_MALLOC_SIZE 0
5a90: 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72  ].  set val [for
5aa0: 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d  mat {now %10d  m
5ab0: 61 78 20 25 31 30 64 20 20 6d 61 78 2d 73 69 7a  ax %10d  max-siz
5ac0: 65 20 25 31 30 64 7d 20 5c 0a 20 20 20 20 20 20  e %10d} \.      
5ad0: 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20          [lindex 
5ae0: 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78  $x 1] [lindex $x
5af0: 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20 32   2] [lindex $y 2
5b00: 5d 5d 0a 20 20 70 75 74 73 20 22 4d 65 6d 6f 72  ]].  puts "Memor
5b10: 79 20 75 73 65 64 3a 20 20 20 20 20 20 20 20 20  y used:         
5b20: 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b   $val".  set x [
5b30: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
5b40: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c  QLITE_STATUS_MAL
5b50: 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d 0a 20 20 73  LOC_COUNT 0].  s
5b60: 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b  et val [format {
5b70: 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31  now %10d  max %1
5b80: 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31  0d} [lindex $x 1
5b90: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d  ] [lindex $x 2]]
5ba0: 0a 20 20 70 75 74 73 20 22 41 6c 6c 6f 63 61 74  .  puts "Allocat
5bb0: 69 6f 6e 20 63 6f 75 6e 74 3a 20 20 20 20 20 24  ion count:     $
5bc0: 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71  val".  set x [sq
5bd0: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
5be0: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
5bf0: 41 43 48 45 5f 55 53 45 44 20 30 5d 0a 20 20 73  ACHE_USED 0].  s
5c00: 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74  et y [sqlite3_st
5c10: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
5c20: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a  US_PAGECACHE_SIZ
5c30: 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b  E 0].  set val [
5c40: 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64  format {now %10d
5c50: 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d    max %10d  max-
5c60: 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20  size %10d} \.   
5c70: 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64             [lind
5c80: 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78  ex $x 1] [lindex
5c90: 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24   $x 2] [lindex $
5ca0: 79 20 32 5d 5d 0a 20 20 70 75 74 73 20 22 50 61  y 2]].  puts "Pa
5cb0: 67 65 2d 63 61 63 68 65 20 75 73 65 64 3a 20 20  ge-cache used:  
5cc0: 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20      $val".  set 
5cd0: 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75  x [sqlite3_statu
5ce0: 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  s SQLITE_STATUS_
5cf0: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
5d00: 4f 57 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20  OW 0].  set val 
5d10: 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30  [format {now %10
5d20: 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69  d  max %10d} [li
5d30: 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64  ndex $x 1] [lind
5d40: 65 78 20 24 78 20 32 5d 5d 0a 20 20 70 75 74 73  ex $x 2]].  puts
5d50: 20 22 50 61 67 65 2d 63 61 63 68 65 20 6f 76 65   "Page-cache ove
5d60: 72 66 6c 6f 77 3a 20 20 24 76 61 6c 22 0a 20 20  rflow:  $val".  
5d70: 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73  set x [sqlite3_s
5d80: 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41  tatus SQLITE_STA
5d90: 54 55 53 5f 53 43 52 41 54 43 48 5f 55 53 45 44  TUS_SCRATCH_USED
5da0: 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66   0].  set val [f
5db0: 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20  ormat {now %10d 
5dc0: 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e 64   max %10d} [lind
5dd0: 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78  ex $x 1] [lindex
5de0: 20 24 78 20 32 5d 5d 0a 20 20 70 75 74 73 20 22   $x 2]].  puts "
5df0: 53 63 72 61 74 63 68 20 6d 65 6d 6f 72 79 20 75  Scratch memory u
5e00: 73 65 64 3a 20 20 24 76 61 6c 22 0a 20 20 73 65  sed:  $val".  se
5e10: 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  t x [sqlite3_sta
5e20: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
5e30: 53 5f 53 43 52 41 54 43 48 5f 4f 56 45 52 46 4c  S_SCRATCH_OVERFL
5e40: 4f 57 20 30 5d 0a 20 20 73 65 74 20 79 20 5b 73  OW 0].  set y [s
5e50: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
5e60: 4c 49 54 45 5f 53 54 41 54 55 53 5f 53 43 52 41  LITE_STATUS_SCRA
5e70: 54 43 48 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65  TCH_SIZE 0].  se
5e80: 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e  t val [format {n
5e90: 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31 30  ow %10d  max %10
5ea0: 64 20 20 6d 61 78 2d 73 69 7a 65 20 25 31 30 64  d  max-size %10d
5eb0: 7d 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  } \.            
5ec0: 20 20 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d     [lindex $x 1]
5ed0: 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 20 5b   [lindex $x 2] [
5ee0: 6c 69 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20 20  lindex $y 2]].  
5ef0: 70 75 74 73 20 22 53 63 72 61 74 63 68 20 6f 76  puts "Scratch ov
5f00: 65 72 66 6c 6f 77 3a 20 20 20 20 20 24 76 61 6c  erflow:     $val
5f10: 22 0a 20 20 69 66 63 61 70 61 62 6c 65 20 79 79  ".  ifcapable yy
5f20: 74 72 61 63 6b 6d 61 78 73 74 61 63 6b 64 65 70  trackmaxstackdep
5f30: 74 68 20 7b 0a 20 20 20 20 73 65 74 20 78 20 5b  th {.    set x [
5f40: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
5f50: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 52  QLITE_STATUS_PAR
5f60: 53 45 52 5f 53 54 41 43 4b 20 30 5d 0a 20 20 20  SER_STACK 0].   
5f70: 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74   set val [format
5f80: 20 7b 20 20 20 20 20 20 20 20 20 20 20 20 20 20   {              
5f90: 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e 64   max %10d} [lind
5fa0: 65 78 20 24 78 20 32 5d 5d 0a 20 20 20 20 70 75  ex $x 2]].    pu
5fb0: 74 73 20 22 50 61 72 73 65 72 20 73 74 61 63 6b  ts "Parser stack
5fc0: 20 64 65 70 74 68 3a 20 20 20 20 24 76 61 6c 22   depth:    $val"
5fd0: 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20 70 72 6f 63  .  }.}..# A proc
5fe0: 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74 65  edure to execute
5ff0: 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65 63   SQL.#.proc exec
6000: 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d  sql {sql {db db}
6010: 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51  } {.  # puts "SQ
6020: 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c 65  L = $sql".  uple
6030: 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76  vel [list $db ev
6040: 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20 45 78  al $sql].}..# Ex
6050: 65 63 75 74 65 20 53 51 4c 20 61 6e 64 20 63 61  ecute SQL and ca
6060: 74 63 68 20 65 78 63 65 70 74 69 6f 6e 73 2e 0a  tch exceptions..
6070: 23 0a 70 72 6f 63 20 63 61 74 63 68 73 71 6c 20  #.proc catchsql 
6080: 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a  {sql {db db}} {.
6090: 20 20 23 20 70 75 74 73 20 22 53 51 4c 20 3d 20    # puts "SQL = 
60a0: 24 73 71 6c 22 0a 20 20 73 65 74 20 72 20 5b 63  $sql".  set r [c
60b0: 61 74 63 68 20 5b 6c 69 73 74 20 75 70 6c 65 76  atch [list uplev
60c0: 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61  el [list $db eva
60d0: 6c 20 24 73 71 6c 5d 5d 20 6d 73 67 5d 0a 20 20  l $sql]] msg].  
60e0: 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a 20  lappend r $msg. 
60f0: 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20   return $r.}..# 
6100: 44 6f 20 61 6e 20 56 44 42 45 20 63 6f 64 65 20  Do an VDBE code 
6110: 64 75 6d 70 20 6f 6e 20 74 68 65 20 53 51 4c 20  dump on the SQL 
6120: 67 69 76 65 6e 0a 23 0a 70 72 6f 63 20 65 78 70  given.#.proc exp
6130: 6c 61 69 6e 20 7b 73 71 6c 20 7b 64 62 20 64 62  lain {sql {db db
6140: 7d 7d 20 7b 0a 20 20 70 75 74 73 20 22 22 0a 20  }} {.  puts "". 
6150: 20 70 75 74 73 20 22 61 64 64 72 20 20 6f 70 63   puts "addr  opc
6160: 6f 64 65 20 20 20 20 20 20 20 20 70 31 20 20 20  ode        p1   
6170: 20 20 20 70 32 20 20 20 20 20 20 70 33 20 20 20     p2      p3   
6180: 20 20 20 70 34 20 20 20 20 20 20 20 20 20 20 20     p4           
6190: 20 20 20 20 70 35 20 20 23 22 0a 20 20 70 75 74      p5  #".  put
61a0: 73 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d  s "----  -------
61b0: 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d  -----  ------  -
61c0: 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d  -----  ------  -
61d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20  --------------  
61e0: 2d 2d 20 20 2d 22 0a 20 20 24 64 62 20 65 76 61  --  -".  $db eva
61f0: 6c 20 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22  l "explain $sql"
6200: 20 7b 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 5b   {} {.    puts [
6210: 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25 2d  format {%-4d  %-
6220: 31 32 2e 31 32 73 20 20 25 2d 36 64 20 20 25 2d  12.12s  %-6d  %-
6230: 36 64 20 20 25 2d 36 64 20 20 25 20 2d 31 37 73  6d  %-6d  % -17s
6240: 20 25 73 20 20 25 73 7d 20 5c 0a 20 20 20 20 20   %s  %s} \.     
6250: 20 24 61 64 64 72 20 24 6f 70 63 6f 64 65 20 24   $addr $opcode $
6260: 70 31 20 24 70 32 20 24 70 33 20 24 70 34 20 24  p1 $p2 $p3 $p4 $
6270: 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20 20  p5 $comment.    
6280: 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 53 68 6f 77 20  ].  }.}..# Show 
6290: 74 68 65 20 56 44 42 45 20 70 72 6f 67 72 61 6d  the VDBE program
62a0: 20 66 6f 72 20 61 6e 20 53 51 4c 20 73 74 61 74   for an SQL stat
62b0: 65 6d 65 6e 74 20 62 75 74 20 6f 6d 69 74 20 74  ement but omit t
62c0: 68 65 20 54 72 61 63 65 0a 23 20 6f 70 63 6f 64  he Trace.# opcod
62d0: 65 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69  e at the beginni
62e0: 6e 67 2e 20 20 54 68 69 73 20 70 72 6f 63 65 64  ng.  This proced
62f0: 75 72 65 20 63 61 6e 20 62 65 20 75 73 65 64 20  ure can be used 
6300: 74 6f 20 70 72 6f 76 65 0a 23 20 74 68 61 74 20  to prove.# that 
6310: 64 69 66 66 65 72 65 6e 74 20 53 51 4c 20 73 74  different SQL st
6320: 61 74 65 6d 65 6e 74 73 20 67 65 6e 65 72 61 74  atements generat
6330: 65 20 65 78 61 63 74 6c 79 20 74 68 65 20 73 61  e exactly the sa
6340: 6d 65 20 56 44 42 45 20 63 6f 64 65 2e 0a 23 0a  me VDBE code..#.
6350: 70 72 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f 5f  proc explain_no_
6360: 74 72 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20 20  trace {sql} {.  
6370: 73 65 74 20 74 72 20 5b 64 62 20 65 76 61 6c 20  set tr [db eval 
6380: 22 45 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d 0a  "EXPLAIN $sql"].
6390: 20 20 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67 65    return [lrange
63a0: 20 24 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a 23   $tr 7 end].}..#
63b0: 20 41 6e 6f 74 68 65 72 20 70 72 6f 63 65 64 75   Another procedu
63c0: 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53 51  re to execute SQ
63d0: 4c 2e 20 20 54 68 69 73 20 6f 6e 65 20 69 6e 63  L.  This one inc
63e0: 6c 75 64 65 73 20 74 68 65 20 66 69 65 6c 64 0a  ludes the field.
63f0: 23 20 6e 61 6d 65 73 20 69 6e 20 74 68 65 20 72  # names in the r
6400: 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23 0a  eturned list..#.
6410: 70 72 6f 63 20 65 78 65 63 73 71 6c 32 20 7b 73  proc execsql2 {s
6420: 71 6c 7d 20 7b 0a 20 20 73 65 74 20 72 65 73 75  ql} {.  set resu
6430: 6c 74 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c 20  lt {}.  db eval 
6440: 24 73 71 6c 20 64 61 74 61 20 7b 0a 20 20 20 20  $sql data {.    
6450: 66 6f 72 65 61 63 68 20 66 20 24 64 61 74 61 28  foreach f $data(
6460: 2a 29 20 7b 0a 20 20 20 20 20 20 6c 61 70 70 65  *) {.      lappe
6470: 6e 64 20 72 65 73 75 6c 74 20 24 66 20 24 64 61  nd result $f $da
6480: 74 61 28 24 66 29 0a 20 20 20 20 7d 0a 20 20 7d  ta($f).    }.  }
6490: 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73 75 6c  .  return $resul
64a0: 74 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65 20 6e  t.}..# Use the n
64b0: 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49 20  on-callback API 
64c0: 74 6f 20 65 78 65 63 75 74 65 20 6d 75 6c 74 69  to execute multi
64d0: 70 6c 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e  ple SQL statemen
64e0: 74 73 0a 23 0a 70 72 6f 63 20 73 74 65 70 73 71  ts.#.proc stepsq
64f0: 6c 20 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b 0a  l {dbptr sql} {.
6500: 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69 6e    set sql [strin
6510: 67 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20 73  g trim $sql].  s
6520: 65 74 20 72 20 30 0a 20 20 77 68 69 6c 65 20 7b  et r 0.  while {
6530: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
6540: 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69 66  sql]>0} {.    if
6550: 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65   {[catch {sqlite
6560: 33 5f 70 72 65 70 61 72 65 20 24 64 62 70 74 72  3_prepare $dbptr
6570: 20 24 73 71 6c 20 2d 31 20 73 71 6c 74 61 69 6c   $sql -1 sqltail
6580: 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20 72  } vm]} {.      r
6590: 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24 76  eturn [list 1 $v
65a0: 6d 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74  m].    }.    set
65b0: 20 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72 69   sql [string tri
65c0: 6d 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20 20  m $sqltail].#   
65d0: 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65 5f   while {[sqlite_
65e0: 73 74 65 70 20 24 76 6d 20 4e 20 56 41 4c 20 43  step $vm N VAL C
65f0: 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57  OL]=="SQLITE_ROW
6600: 22 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f 72 65  "} {.#      fore
6610: 61 63 68 20 76 20 24 56 41 4c 20 7b 6c 61 70 70  ach v $VAL {lapp
6620: 65 6e 64 20 72 20 24 76 7d 0a 23 20 20 20 20 7d  end r $v}.#    }
6630: 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c  .    while {[sql
6640: 69 74 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d 3d  ite3_step $vm]==
6650: 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a  "SQLITE_ROW"} {.
6660: 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69        for {set i
6670: 20 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65 33   0} {$i<[sqlite3
6680: 5f 64 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d 5d  _data_count $vm]
6690: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
66a0: 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72 20 5b       lappend r [
66b0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
66c0: 65 78 74 20 24 76 6d 20 24 69 5d 0a 20 20 20 20  ext $vm $i].    
66d0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
66e0: 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65   {[catch {sqlite
66f0: 33 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d 20  3_finalize $vm} 
6700: 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20 20  errmsg]} {.     
6710: 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20   return [list 1 
6720: 24 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a 20  $errmsg].    }. 
6730: 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d   }.  return $r.}
6740: 0a 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67 72  ..# Do an integr
6750: 69 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68 65  ity check of the
6760: 20 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65   entire database
6770: 0a 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69 74  .#.proc integrit
6780: 79 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20 7b 64  y_check {name {d
6790: 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70  b db}} {.  ifcap
67a0: 61 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63 6b  able integrityck
67b0: 20 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24   {.    do_test $
67c0: 6e 61 6d 65 20 5b 6c 69 73 74 20 65 78 65 63 73  name [list execs
67d0: 71 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67  ql {PRAGMA integ
67e0: 72 69 74 79 5f 63 68 65 63 6b 7d 20 24 64 62 5d  rity_check} $db]
67f0: 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 0a 23 20   {ok}.  }.}...# 
6800: 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74  Return true if t
6810: 68 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  he SQL statement
6820: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
6830: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 75  econd argument u
6840: 73 65 73 20 61 0a 23 20 73 74 61 74 65 6d 65 6e  ses a.# statemen
6850: 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 23  t transaction..#
6860: 0a 70 72 6f 63 20 73 71 6c 5f 75 73 65 73 5f 73  .proc sql_uses_s
6870: 74 6d 74 20 7b 64 62 20 73 71 6c 7d 20 7b 0a 20  tmt {db sql} {. 
6880: 20 73 65 74 20 73 74 6d 74 20 5b 73 71 6c 69 74   set stmt [sqlit
6890: 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 20 24  e3_prepare $db $
68a0: 73 71 6c 20 2d 31 20 64 75 6d 6d 79 5d 0a 20 20  sql -1 dummy].  
68b0: 73 65 74 20 75 73 65 73 20 5b 75 73 65 73 5f 73  set uses [uses_s
68c0: 74 6d 74 5f 6a 6f 75 72 6e 61 6c 20 24 73 74 6d  tmt_journal $stm
68d0: 74 5d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e  t].  sqlite3_fin
68e0: 61 6c 69 7a 65 20 24 73 74 6d 74 0a 20 20 72 65  alize $stmt.  re
68f0: 74 75 72 6e 20 24 75 73 65 73 0a 7d 0a 0a 70 72  turn $uses.}..pr
6900: 6f 63 20 66 69 78 5f 69 66 63 61 70 61 62 6c 65  oc fix_ifcapable
6910: 5f 65 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a 20  _expr {expr} {. 
6920: 20 73 65 74 20 72 65 74 20 22 22 0a 20 20 73 65   set ret "".  se
6930: 74 20 73 74 61 74 65 20 30 0a 20 20 66 6f 72 20  t state 0.  for 
6940: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20  {set i 0} {$i < 
6950: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
6960: 65 78 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  expr]} {incr i} 
6970: 7b 0a 20 20 20 20 73 65 74 20 63 68 61 72 20 5b  {.    set char [
6980: 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78  string range $ex
6990: 70 72 20 24 69 20 24 69 5d 0a 20 20 20 20 73 65  pr $i $i].    se
69a0: 74 20 6e 65 77 73 74 61 74 65 20 5b 65 78 70 72  t newstate [expr
69b0: 20 7b 5b 73 74 72 69 6e 67 20 69 73 20 61 6c 6e   {[string is aln
69c0: 75 6d 20 24 63 68 61 72 5d 20 7c 7c 20 24 63 68  um $char] || $ch
69d0: 61 72 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20 20  ar eq "_"}].    
69e0: 69 66 20 7b 24 6e 65 77 73 74 61 74 65 20 26 26  if {$newstate &&
69f0: 20 21 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20   !$state} {.    
6a00: 20 20 61 70 70 65 6e 64 20 72 65 74 20 7b 24 3a    append ret {$:
6a10: 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28  :sqlite_options(
6a20: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b  }.    }.    if {
6a30: 21 24 6e 65 77 73 74 61 74 65 20 26 26 20 24 73  !$newstate && $s
6a40: 74 61 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70  tate} {.      ap
6a50: 70 65 6e 64 20 72 65 74 20 29 0a 20 20 20 20 7d  pend ret ).    }
6a60: 0a 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20  .    append ret 
6a70: 24 63 68 61 72 0a 20 20 20 20 73 65 74 20 73 74  $char.    set st
6a80: 61 74 65 20 24 6e 65 77 73 74 61 74 65 0a 20 20  ate $newstate.  
6a90: 7d 0a 20 20 69 66 20 7b 24 73 74 61 74 65 7d 20  }.  if {$state} 
6aa0: 7b 61 70 70 65 6e 64 20 72 65 74 20 29 7d 0a 20  {append ret )}. 
6ab0: 20 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a   return $ret.}..
6ac0: 23 20 45 76 61 6c 75 61 74 65 20 61 20 62 6f 6f  # Evaluate a boo
6ad0: 6c 65 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20  lean expression 
6ae0: 6f 66 20 63 61 70 61 62 69 6c 69 74 69 65 73 2e  of capabilities.
6af0: 20 20 49 66 20 74 72 75 65 2c 20 65 78 65 63 75    If true, execu
6b00: 74 65 20 74 68 65 0a 23 20 63 6f 64 65 2e 20 20  te the.# code.  
6b10: 4f 6d 69 74 20 74 68 65 20 63 6f 64 65 20 69 66  Omit the code if
6b20: 20 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69   false..#.proc i
6b30: 66 63 61 70 61 62 6c 65 20 7b 65 78 70 72 20 63  fcapable {expr c
6b40: 6f 64 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65  ode {else ""} {e
6b50: 6c 73 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20  lsecode ""}} {. 
6b60: 20 23 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b   #regsub -all {[
6b70: 61 2d 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72  a-z_0-9]+} $expr
6b80: 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69   {$::sqlite_opti
6b90: 6f 6e 73 28 26 29 7d 20 65 32 0a 20 20 73 65 74  ons(&)} e2.  set
6ba0: 20 65 32 20 5b 66 69 78 5f 69 66 63 61 70 61 62   e2 [fix_ifcapab
6bb0: 6c 65 5f 65 78 70 72 20 24 65 78 70 72 5d 0a 20  le_expr $expr]. 
6bc0: 20 69 66 20 28 24 65 32 29 20 7b 0a 20 20 20 20   if ($e2) {.    
6bd0: 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70  set c [catch {up
6be0: 6c 65 76 65 6c 20 31 20 24 63 6f 64 65 7d 20 72  level 1 $code} r
6bf0: 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  ].  } else {.   
6c00: 20 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75   set c [catch {u
6c10: 70 6c 65 76 65 6c 20 31 20 24 65 6c 73 65 63 6f  plevel 1 $elseco
6c20: 64 65 7d 20 72 5d 0a 20 20 7d 0a 20 20 72 65 74  de} r].  }.  ret
6c30: 75 72 6e 20 2d 63 6f 64 65 20 24 63 20 24 72 0a  urn -code $c $r.
6c40: 7d 0a 0a 23 20 54 68 69 73 20 70 72 6f 63 20 65  }..# This proc e
6c50: 78 65 63 73 20 61 20 73 65 70 65 72 61 74 65 20  xecs a seperate 
6c60: 70 72 6f 63 65 73 73 20 74 68 61 74 20 63 72 61  process that cra
6c70: 73 68 65 73 20 6d 69 64 77 61 79 20 74 68 72 6f  shes midway thro
6c80: 75 67 68 20 65 78 65 63 75 74 69 6e 67 0a 23 20  ugh executing.# 
6c90: 74 68 65 20 53 51 4c 20 73 63 72 69 70 74 20 24  the SQL script $
6ca0: 73 71 6c 20 6f 6e 20 64 61 74 61 62 61 73 65 20  sql on database 
6cb0: 74 65 73 74 2e 64 62 2e 0a 23 0a 23 20 54 68 65  test.db..#.# The
6cc0: 20 63 72 61 73 68 20 6f 63 63 75 72 73 20 64 75   crash occurs du
6cd0: 72 69 6e 67 20 61 20 73 79 6e 63 28 29 20 6f 66  ring a sync() of
6ce0: 20 66 69 6c 65 20 24 63 72 61 73 68 66 69 6c 65   file $crashfile
6cf0: 2e 20 57 68 65 6e 20 74 68 65 20 63 72 61 73 68  . When the crash
6d00: 0a 23 20 6f 63 63 75 72 73 20 61 20 72 61 6e 64  .# occurs a rand
6d10: 6f 6d 20 73 75 62 73 65 74 20 6f 66 20 61 6c 6c  om subset of all
6d20: 20 75 6e 73 79 6e 63 65 64 20 77 72 69 74 65 73   unsynced writes
6d30: 20 6d 61 64 65 20 62 79 20 74 68 65 20 70 72 6f   made by the pro
6d40: 63 65 73 73 20 61 72 65 0a 23 20 77 72 69 74 74  cess are.# writt
6d50: 65 6e 20 69 6e 74 6f 20 74 68 65 20 66 69 6c 65  en into the file
6d60: 73 20 6f 6e 20 64 69 73 6b 2e 20 41 72 67 75 6d  s on disk. Argum
6d70: 65 6e 74 20 24 63 72 61 73 68 64 65 6c 61 79 20  ent $crashdelay 
6d80: 69 6e 64 69 63 61 74 65 73 20 74 68 65 0a 23 20  indicates the.# 
6d90: 6e 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 20 73  number of file s
6da0: 79 6e 63 73 20 74 6f 20 77 61 69 74 20 62 65 66  yncs to wait bef
6db0: 6f 72 65 20 63 72 61 73 68 69 6e 67 2e 0a 23 0a  ore crashing..#.
6dc0: 23 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c  # The return val
6dd0: 75 65 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20  ue is a list of 
6de0: 74 77 6f 20 65 6c 65 6d 65 6e 74 73 2e 20 54 68  two elements. Th
6df0: 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20  e first element 
6e00: 69 73 20 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20  is a.# boolean, 
6e10: 69 6e 64 69 63 61 74 69 6e 67 20 77 68 65 74 68  indicating wheth
6e20: 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 70 72  er or not the pr
6e30: 6f 63 65 73 73 20 61 63 74 75 61 6c 6c 79 20 63  ocess actually c
6e40: 72 61 73 68 65 64 20 6f 72 0a 23 20 72 65 70 6f  rashed or.# repo
6e50: 72 74 65 64 20 73 6f 6d 65 20 6f 74 68 65 72 20  rted some other 
6e60: 65 72 72 6f 72 2e 20 54 68 65 20 73 65 63 6f 6e  error. The secon
6e70: 64 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65  d element in the
6e80: 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74 20 69   returned list i
6e90: 73 20 74 68 65 0a 23 20 65 72 72 6f 72 20 6d 65  s the.# error me
6ea0: 73 73 61 67 65 2e 20 54 68 69 73 20 69 73 20 22  ssage. This is "
6eb0: 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78  child process ex
6ec0: 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22  ited abnormally"
6ed0: 20 69 66 20 74 68 65 20 63 72 61 73 68 0a 23 20   if the crash.# 
6ee0: 6f 63 63 75 72 65 64 2e 0a 23 0a 23 20 20 20 63  occured..#.#   c
6ef0: 72 61 73 68 73 71 6c 20 2d 64 65 6c 61 79 20 43  rashsql -delay C
6f00: 52 41 53 48 44 45 4c 41 59 20 2d 66 69 6c 65 20  RASHDELAY -file 
6f10: 43 52 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f 63  CRASHFILE ?-bloc
6f20: 6b 73 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45 3f  ksize BLOCKSIZE?
6f30: 20 24 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72 61   $sql.#.proc cra
6f40: 73 68 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a 0a  shsql {args} {..
6f50: 20 20 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20    set blocksize 
6f60: 22 22 0a 20 20 73 65 74 20 63 72 61 73 68 64 65  "".  set crashde
6f70: 6c 61 79 20 31 0a 20 20 73 65 74 20 70 72 6e 67  lay 1.  set prng
6f80: 73 65 65 64 20 30 0a 20 20 73 65 74 20 74 63 6c  seed 0.  set tcl
6f90: 62 6f 64 79 20 7b 7d 0a 20 20 73 65 74 20 63 72  body {}.  set cr
6fa0: 61 73 68 66 69 6c 65 20 22 22 0a 20 20 73 65 74  ashfile "".  set
6fb0: 20 64 63 20 22 22 0a 20 20 73 65 74 20 73 71 6c   dc "".  set sql
6fc0: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65   [lindex $args e
6fd0: 6e 64 5d 0a 20 20 0a 20 20 66 6f 72 20 7b 73 65  nd].  .  for {se
6fe0: 74 20 69 69 20 30 7d 20 7b 24 69 69 20 3c 20 5b  t ii 0} {$ii < [
6ff0: 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 2d 31  llength $args]-1
7000: 7d 20 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b 0a  } {incr ii 2} {.
7010: 20 20 20 20 73 65 74 20 7a 20 5b 6c 69 6e 64 65      set z [linde
7020: 78 20 24 61 72 67 73 20 24 69 69 5d 0a 20 20 20  x $args $ii].   
7030: 20 73 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c   set n [string l
7040: 65 6e 67 74 68 20 24 7a 5d 0a 20 20 20 20 73 65  ength $z].    se
7050: 74 20 7a 32 20 5b 6c 69 6e 64 65 78 20 24 61 72  t z2 [lindex $ar
7060: 67 73 20 5b 65 78 70 72 20 24 69 69 2b 31 5d 5d  gs [expr $ii+1]]
7070: 0a 0a 20 20 20 20 69 66 20 20 20 20 20 7b 24 6e  ..    if     {$n
7080: 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69  >1 && [string fi
7090: 72 73 74 20 24 7a 20 2d 64 65 6c 61 79 5d 3d 3d  rst $z -delay]==
70a0: 30 7d 20 20 20 20 20 7b 73 65 74 20 63 72 61 73  0}     {set cras
70b0: 68 64 65 6c 61 79 20 24 7a 32 7d 20 5c 0a 20 20  hdelay $z2} \.  
70c0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
70d0: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
70e0: 24 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20 20  $z -seed]==0}   
70f0: 20 20 20 7b 73 65 74 20 70 72 6e 67 73 65 65 64     {set prngseed
7100: 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65   $z2} \.    else
7110: 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72  if {$n>1 && [str
7120: 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66 69  ing first $z -fi
7130: 6c 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65  le]==0}      {se
7140: 74 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32 7d  t crashfile $z2}
7150: 20 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b    \.    elseif {
7160: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
7170: 66 69 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f 64  first $z -tclbod
7180: 79 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74 63  y]==0}   {set tc
7190: 6c 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20 20  lbody $z2}  \.  
71a0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
71b0: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
71c0: 24 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d  $z -blocksize]==
71d0: 30 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a  0} {set blocksiz
71e0: 65 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a 20  e "-s $z2" } \. 
71f0: 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20     elseif {$n>1 
7200: 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74  && [string first
7210: 20 24 7a 20 2d 63 68 61 72 61 63 74 65 72 69 73   $z -characteris
7220: 74 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64  tics]==0} {set d
7230: 63 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 20 5c  c "-c {$z2}" } \
7240: 0a 20 20 20 20 65 6c 73 65 20 20 20 7b 20 65 72  .    else   { er
7250: 72 6f 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a 65  ror "Unrecognize
7260: 64 20 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a  d option: $z" }.
7270: 20 20 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61 73    }..  if {$cras
7280: 68 66 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a 20  hfile eq ""} {. 
7290: 20 20 20 65 72 72 6f 72 20 22 43 6f 6d 70 75 6c     error "Compul
72a0: 73 6f 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69 6c  sory option -fil
72b0: 65 20 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a 0a  e missing".  }..
72c0: 20 20 23 20 24 63 72 61 73 68 66 69 6c 65 20 67    # $crashfile g
72d0: 65 74 73 20 63 6f 6d 70 61 72 65 64 20 74 6f 20  ets compared to 
72e0: 74 68 65 20 6e 61 74 69 76 65 20 66 69 6c 65 6e  the native filen
72f0: 61 6d 65 20 69 6e 20 0a 20 20 23 20 63 66 53 79  ame in .  # cfSy
7300: 6e 63 28 29 2c 20 77 68 69 63 68 20 63 61 6e 20  nc(), which can 
7310: 62 65 20 64 69 66 66 65 72 65 6e 74 20 74 68 65  be different the
7320: 6e 20 77 68 61 74 20 54 43 4c 20 75 73 65 73 20  n what TCL uses 
7330: 62 79 0a 20 20 23 20 64 65 66 61 75 6c 74 2c 20  by.  # default, 
7340: 73 6f 20 68 65 72 65 20 77 65 20 66 6f 72 63 65  so here we force
7350: 20 69 74 20 74 6f 20 74 68 65 20 22 6e 61 74 69   it to the "nati
7360: 76 65 6e 61 6d 65 22 20 66 6f 72 6d 61 74 2e 0a  vename" format..
7370: 20 20 73 65 74 20 63 66 69 6c 65 20 5b 73 74 72    set cfile [str
7380: 69 6e 67 20 6d 61 70 20 7b 5c 5c 20 5c 5c 5c 5c  ing map {\\ \\\\
7390: 7d 20 5b 66 69 6c 65 20 6e 61 74 69 76 65 6e 61  } [file nativena
73a0: 6d 65 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b 70  me [file join [p
73b0: 77 64 5d 20 24 63 72 61 73 68 66 69 6c 65 5d 5d  wd] $crashfile]]
73c0: 5d 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e  ]..  set f [open
73d0: 20 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20   crash.tcl w].  
73e0: 70 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33  puts $f "sqlite3
73f0: 5f 63 72 61 73 68 5f 65 6e 61 62 6c 65 20 31 22  _crash_enable 1"
7400: 0a 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69  .  puts $f "sqli
7410: 74 65 33 5f 63 72 61 73 68 70 61 72 61 6d 73 20  te3_crashparams 
7420: 24 62 6c 6f 63 6b 73 69 7a 65 20 24 64 63 20 24  $blocksize $dc $
7430: 63 72 61 73 68 64 65 6c 61 79 20 24 63 66 69 6c  crashdelay $cfil
7440: 65 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 71  e".  puts $f "sq
7450: 6c 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72  lite3_test_contr
7460: 6f 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20  ol_pending_byte 
7470: 24 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e  $::sqlite_pendin
7480: 67 5f 62 79 74 65 22 0a 20 20 70 75 74 73 20 24  g_byte".  puts $
7490: 66 20 22 73 71 6c 69 74 65 33 20 64 62 20 74 65  f "sqlite3 db te
74a0: 73 74 2e 64 62 20 2d 76 66 73 20 63 72 61 73 68  st.db -vfs crash
74b0: 22 0a 0a 20 20 23 20 54 68 69 73 20 62 6c 6f 63  "..  # This bloc
74c0: 6b 20 73 65 74 73 20 74 68 65 20 63 61 63 68 65  k sets the cache
74d0: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 6d 61 69   size of the mai
74e0: 6e 20 64 61 74 61 62 61 73 65 20 74 6f 20 31 30  n database to 10
74f0: 0a 20 20 23 20 70 61 67 65 73 2e 20 54 68 69 73  .  # pages. This
7500: 20 69 73 20 64 6f 6e 65 20 69 6e 20 63 61 73 65   is done in case
7510: 20 74 68 65 20 62 75 69 6c 64 20 69 73 20 63 6f   the build is co
7520: 6e 66 69 67 75 72 65 64 20 74 6f 20 6f 6d 69 74  nfigured to omit
7530: 0a 20 20 23 20 22 50 52 41 47 4d 41 20 63 61 63  .  # "PRAGMA cac
7540: 68 65 5f 73 69 7a 65 22 2e 0a 20 20 70 75 74 73  he_size"..  puts
7550: 20 24 66 20 7b 64 62 20 65 76 61 6c 20 7b 53 45   $f {db eval {SE
7560: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69  LECT * FROM sqli
7570: 74 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a 20 20 70  te_master;}}.  p
7580: 75 74 73 20 24 66 20 7b 73 65 74 20 62 74 20 5b  uts $f {set bt [
7590: 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62  btree_from_db db
75a0: 5d 7d 0a 20 20 70 75 74 73 20 24 66 20 7b 62 74  ]}.  puts $f {bt
75b0: 72 65 65 5f 73 65 74 5f 63 61 63 68 65 5f 73 69  ree_set_cache_si
75c0: 7a 65 20 24 62 74 20 31 30 7d 0a 20 20 69 66 20  ze $bt 10}.  if 
75d0: 7b 24 70 72 6e 67 73 65 65 64 7d 20 7b 0a 20 20  {$prngseed} {.  
75e0: 20 20 73 65 74 20 73 65 65 64 20 5b 65 78 70 72    set seed [expr
75f0: 20 7b 24 70 72 6e 67 73 65 65 64 25 31 30 30 30   {$prngseed%1000
7600: 37 2b 31 7d 5d 0a 20 20 20 20 23 20 70 75 74 73  7+1}].    # puts
7610: 20 73 65 65 64 3d 24 73 65 65 64 0a 20 20 20 20   seed=$seed.    
7620: 70 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c  puts $f "db eval
7630: 20 7b 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62   {SELECT randomb
7640: 6c 6f 62 28 24 73 65 65 64 29 7d 22 0a 20 20 7d  lob($seed)}".  }
7650: 0a 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20  ..  if {[string 
7660: 6c 65 6e 67 74 68 20 24 74 63 6c 62 6f 64 79 5d  length $tclbody]
7670: 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24  >0} {.    puts $
7680: 66 20 24 74 63 6c 62 6f 64 79 0a 20 20 7d 0a 20  f $tclbody.  }. 
7690: 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e   if {[string len
76a0: 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20  gth $sql]>0} {. 
76b0: 20 20 20 70 75 74 73 20 24 66 20 22 64 62 20 65     puts $f "db e
76c0: 76 61 6c 20 7b 22 0a 20 20 20 20 70 75 74 73 20  val {".    puts 
76d0: 24 66 20 20 20 22 24 73 71 6c 22 0a 20 20 20 20  $f   "$sql".    
76e0: 70 75 74 73 20 24 66 20 22 7d 22 0a 20 20 7d 0a  puts $f "}".  }.
76f0: 20 20 63 6c 6f 73 65 20 24 66 0a 20 20 73 65 74    close $f.  set
7700: 20 72 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20   r [catch {.    
7710: 65 78 65 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f  exec [info nameo
7720: 66 65 78 65 63 5d 20 63 72 61 73 68 2e 74 63 6c  fexec] crash.tcl
7730: 20 3e 40 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73   >@stdout.  } ms
7740: 67 5d 0a 20 20 0a 20 20 23 20 57 69 6e 64 6f 77  g].  .  # Window
7750: 73 2f 41 63 74 69 76 65 53 74 61 74 65 20 54 43  s/ActiveState TC
7760: 4c 20 72 65 74 75 72 6e 73 20 61 20 73 6c 69 67  L returns a slig
7770: 68 74 6c 79 20 64 69 66 66 65 72 65 6e 74 0a 20  htly different. 
7780: 20 23 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65   # error message
7790: 2e 20 20 57 65 20 6d 61 70 20 74 68 61 74 20 74  .  We map that t
77a0: 6f 20 74 68 65 20 65 78 70 65 63 74 65 64 20 6d  o the expected m
77b0: 65 73 73 61 67 65 0a 20 20 23 20 73 6f 20 74 68  essage.  # so th
77c0: 61 74 20 77 65 20 64 6f 6e 27 74 20 68 61 76 65  at we don't have
77d0: 20 74 6f 20 63 68 61 6e 67 65 20 61 6c 6c 20 6f   to change all o
77e0: 66 20 74 68 65 20 74 65 73 74 0a 20 20 23 20 63  f the test.  # c
77f0: 61 73 65 73 2e 0a 20 20 69 66 20 7b 24 3a 3a 74  ases..  if {$::t
7800: 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74  cl_platform(plat
7810: 66 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22  form)=="windows"
7820: 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24 6d 73 67  } {.    if {$msg
7830: 3d 3d 22 63 68 69 6c 64 20 6b 69 6c 6c 65 64 3a  =="child killed:
7840: 20 75 6e 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c 22   unknown signal"
7850: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 73  } {.      set ms
7860: 67 20 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73  g "child process
7870: 20 65 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c   exited abnormal
7880: 6c 79 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ly".    }.  }.  
7890: 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73  .  lappend r $ms
78a0: 67 0a 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64 6f  g.}..# Usage: do
78b0: 5f 69 6f 65 72 72 5f 74 65 73 74 20 3c 74 65 73  _ioerr_test <tes
78c0: 74 20 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69 6f  t number> <optio
78d0: 6e 73 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73 20  ns...>.#.# This 
78e0: 70 72 6f 63 20 69 73 20 75 73 65 64 20 74 6f 20  proc is used to 
78f0: 69 6d 70 6c 65 6d 65 6e 74 20 74 65 73 74 20 63  implement test c
7900: 61 73 65 73 20 74 68 61 74 20 63 68 65 63 6b 20  ases that check 
7910: 74 68 61 74 20 49 4f 20 65 72 72 6f 72 73 0a 23  that IO errors.#
7920: 20 61 72 65 20 63 6f 72 72 65 63 74 6c 79 20 68   are correctly h
7930: 61 6e 64 6c 65 64 2e 20 54 68 65 20 66 69 72 73  andled. The firs
7940: 74 20 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65 73  t argument, <tes
7950: 74 20 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61 6e  t number>, is an
7960: 20 69 6e 74 65 67 65 72 20 0a 23 20 75 73 65 64   integer .# used
7970: 20 74 6f 20 6e 61 6d 65 20 74 68 65 20 74 65 73   to name the tes
7980: 74 73 20 65 78 65 63 75 74 65 64 20 62 79 20 74  ts executed by t
7990: 68 69 73 20 70 72 6f 63 2e 20 4f 70 74 69 6f 6e  his proc. Option
79a0: 73 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73  s are as follows
79b0: 3a 0a 23 0a 23 20 20 20 20 20 2d 74 63 6c 70 72  :.#.#     -tclpr
79c0: 65 70 20 20 20 20 20 20 20 20 20 20 54 43 4c 20  ep          TCL 
79d0: 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74 6f  script to run to
79e0: 20 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a 23   prepare test..#
79f0: 20 20 20 20 20 2d 73 71 6c 70 72 65 70 20 20 20       -sqlprep   
7a00: 20 20 20 20 20 20 20 53 51 4c 20 73 63 72 69 70         SQL scrip
7a10: 74 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70  t to run to prep
7a20: 61 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20  are test..#     
7a30: 2d 74 63 6c 62 6f 64 79 20 20 20 20 20 20 20 20  -tclbody        
7a40: 20 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20    TCL script to 
7a50: 72 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f  run with IO erro
7a60: 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20  r simulation..# 
7a70: 20 20 20 20 2d 73 71 6c 62 6f 64 79 20 20 20 20      -sqlbody    
7a80: 20 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74        TCL script
7a90: 20 74 6f 20 72 75 6e 20 77 69 74 68 20 49 4f 20   to run with IO 
7aa0: 65 72 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e  error simulation
7ab0: 2e 0a 23 20 20 20 20 20 2d 65 78 63 6c 75 64 65  ..#     -exclude
7ac0: 20 20 20 20 20 20 20 20 20 20 4c 69 73 74 20 6f            List o
7ad0: 66 20 27 4e 27 20 76 61 6c 75 65 73 20 6e 6f 74  f 'N' values not
7ae0: 20 74 6f 20 74 65 73 74 2e 0a 23 20 20 20 20 20   to test..#     
7af0: 2d 65 72 63 20 20 20 20 20 20 20 20 20 20 20 20  -erc            
7b00: 20 20 55 73 65 20 65 78 74 65 6e 64 65 64 20 72    Use extended r
7b10: 65 73 75 6c 74 20 63 6f 64 65 73 0a 23 20 20 20  esult codes.#   
7b20: 20 20 2d 70 65 72 73 69 73 74 20 20 20 20 20 20    -persist      
7b30: 20 20 20 20 4d 61 6b 65 20 73 69 6d 75 6c 61 74      Make simulat
7b40: 65 64 20 49 2f 4f 20 65 72 72 6f 72 73 20 70 65  ed I/O errors pe
7b50: 72 73 69 73 74 65 6e 74 0a 23 20 20 20 20 20 2d  rsistent.#     -
7b60: 73 74 61 72 74 20 20 20 20 20 20 20 20 20 20 20  start           
7b70: 20 56 61 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f   Value of 'N' to
7b80: 20 62 65 67 69 6e 20 77 69 74 68 20 28 64 65 66   begin with (def
7b90: 61 75 6c 74 20 31 29 0a 23 0a 23 20 20 20 20 20  ault 1).#.#     
7ba0: 2d 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20  -cksum          
7bb0: 20 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72    Boolean. If tr
7bc0: 75 65 2c 20 74 65 73 74 20 74 68 61 74 20 74 68  ue, test that th
7bd0: 65 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 0a  e database does.
7be0: 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  #               
7bf0: 20 20 20 20 20 20 20 20 6e 6f 74 20 63 68 61 6e          not chan
7c00: 67 65 20 64 75 72 69 6e 67 20 74 68 65 20 65 78  ge during the ex
7c10: 65 63 75 74 69 6f 6e 20 6f 66 20 74 68 65 20 74  ecution of the t
7c20: 65 73 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63  est case..#.proc
7c30: 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b   do_ioerr_test {
7c40: 74 65 73 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b  testname args} {
7c50: 0a 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f  ..  set ::ioerro
7c60: 70 74 73 28 2d 73 74 61 72 74 29 20 31 0a 20 20  pts(-start) 1.  
7c70: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  set ::ioerropts(
7c80: 2d 63 6b 73 75 6d 29 20 30 0a 20 20 73 65 74 20  -cksum) 0.  set 
7c90: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63  ::ioerropts(-erc
7ca0: 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  ) 0.  set ::ioer
7cb0: 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20 31 30  ropts(-count) 10
7cc0: 30 30 30 30 30 30 30 0a 20 20 73 65 74 20 3a 3a  0000000.  set ::
7cd0: 69 6f 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69  ioerropts(-persi
7ce0: 73 74 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f  st) 1.  set ::io
7cf0: 65 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f  erropts(-ckrefco
7d00: 75 6e 74 29 20 30 0a 20 20 73 65 74 20 3a 3a 69  unt) 0.  set ::i
7d10: 6f 65 72 72 6f 70 74 73 28 2d 72 65 73 74 6f 72  oerropts(-restor
7d20: 65 70 72 6e 67 29 20 31 0a 20 20 61 72 72 61 79  eprng) 1.  array
7d30: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
7d40: 20 24 61 72 67 73 0a 0a 20 20 23 20 54 45 4d 50   $args..  # TEMP
7d50: 4f 52 41 52 59 3a 20 46 6f 72 20 33 2e 35 2e 39  ORARY: For 3.5.9
7d60: 2c 20 64 69 73 61 62 6c 65 20 74 65 73 74 69 6e  , disable testin
7d70: 67 20 6f 66 20 65 78 74 65 6e 64 65 64 20 72 65  g of extended re
7d80: 73 75 6c 74 20 63 6f 64 65 73 2e 20 54 68 65 72  sult codes. Ther
7d90: 65 20 61 72 65 0a 20 20 23 20 61 20 63 6f 75 70  e are.  # a coup
7da0: 6c 65 20 6f 66 20 6f 62 73 63 75 72 65 20 49 4f  le of obscure IO
7db0: 20 65 72 72 6f 72 73 20 74 68 61 74 20 64 6f 20   errors that do 
7dc0: 6e 6f 74 20 72 65 74 75 72 6e 20 74 68 65 6d 2e  not return them.
7dd0: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
7de0: 74 73 28 2d 65 72 63 29 20 30 0a 0a 20 20 73 65  ts(-erc) 0..  se
7df0: 74 20 3a 3a 67 6f 20 31 0a 20 20 23 72 65 73 65  t ::go 1.  #rese
7e00: 74 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 73  t_prng_state.  s
7e10: 61 76 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20  ave_prng_state. 
7e20: 20 66 6f 72 20 7b 73 65 74 20 6e 20 24 3a 3a 69   for {set n $::i
7e30: 6f 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74 29  oerropts(-start)
7e40: 7d 20 7b 24 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20  } {$::go} {incr 
7e50: 6e 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 54  n} {.    set ::T
7e60: 4e 20 24 6e 0a 20 20 20 20 69 6e 63 72 20 3a 3a  N $n.    incr ::
7e70: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74  ioerropts(-count
7e80: 29 20 2d 31 0a 20 20 20 20 69 66 20 7b 24 3a 3a  ) -1.    if {$::
7e90: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74  ioerropts(-count
7ea0: 29 3c 30 7d 20 62 72 65 61 6b 0a 20 0a 20 20 20  )<0} break. .   
7eb0: 20 23 20 53 6b 69 70 20 74 68 69 73 20 49 4f 20   # Skip this IO 
7ec0: 65 72 72 6f 72 20 69 66 20 69 74 20 77 61 73 20  error if it was 
7ed0: 73 70 65 63 69 66 69 65 64 20 77 69 74 68 20 74  specified with t
7ee0: 68 65 20 22 2d 65 78 63 6c 75 64 65 22 20 6f 70  he "-exclude" op
7ef0: 74 69 6f 6e 2e 0a 20 20 20 20 69 66 20 7b 5b 69  tion..    if {[i
7f00: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65  nfo exists ::ioe
7f10: 72 72 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29  rropts(-exclude)
7f20: 5d 7d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b  ]} {.      if {[
7f30: 6c 73 65 61 72 63 68 20 24 3a 3a 69 6f 65 72 72  lsearch $::ioerr
7f40: 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29 20 24  opts(-exclude) $
7f50: 6e 5d 21 3d 2d 31 7d 20 63 6f 6e 74 69 6e 75 65  n]!=-1} continue
7f60: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24  .    }.    if {$
7f70: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 72 65 73  ::ioerropts(-res
7f80: 74 6f 72 65 70 72 6e 67 29 7d 20 7b 0a 20 20 20  toreprng)} {.   
7f90: 20 20 20 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f     restore_prng_
7fa0: 73 74 61 74 65 0a 20 20 20 20 7d 0a 0a 20 20 20  state.    }..   
7fb0: 20 23 20 44 65 6c 65 74 65 20 74 68 65 20 66 69   # Delete the fi
7fc0: 6c 65 73 20 74 65 73 74 2e 64 62 20 61 6e 64 20  les test.db and 
7fd0: 74 65 73 74 32 2e 64 62 2c 20 74 68 65 6e 20 65  test2.db, then e
7fe0: 78 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 61  xecute the TCL a
7ff0: 6e 64 20 0a 20 20 20 20 23 20 53 51 4c 20 28 69  nd .    # SQL (i
8000: 6e 20 74 68 61 74 20 6f 72 64 65 72 29 20 74 6f  n that order) to
8010: 20 70 72 65 70 61 72 65 20 66 6f 72 20 74 68 65   prepare for the
8020: 20 74 65 73 74 20 63 61 73 65 2e 0a 20 20 20 20   test case..    
8030: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
8040: 65 2e 24 6e 2e 31 20 7b 0a 20 20 20 20 20 20 73  e.$n.1 {.      s
8050: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  et ::sqlite_io_e
8060: 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20  rror_pending 0. 
8070: 20 20 20 20 20 63 61 74 63 68 20 7b 64 62 20 63       catch {db c
8080: 6c 6f 73 65 7d 0a 20 20 20 20 20 20 63 61 74 63  lose}.      catc
8090: 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20  h {db2 close}.  
80a0: 20 20 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65      catch {force
80b0: 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62 7d 0a  delete test.db}.
80c0: 20 20 20 20 20 20 63 61 74 63 68 20 7b 66 6f 72        catch {for
80d0: 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62  cedelete test.db
80e0: 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 20 20 20 20  -journal}.      
80f0: 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65  catch {forcedele
8100: 74 65 20 74 65 73 74 32 2e 64 62 7d 0a 20 20 20  te test2.db}.   
8110: 20 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64     catch {forced
8120: 65 6c 65 74 65 20 74 65 73 74 32 2e 64 62 2d 6a  elete test2.db-j
8130: 6f 75 72 6e 61 6c 7d 0a 20 20 20 20 20 20 73 65  ournal}.      se
8140: 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 20  t ::DB [sqlite3 
8150: 64 62 20 74 65 73 74 2e 64 62 3b 20 73 71 6c 69  db test.db; sqli
8160: 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70  te3_connection_p
8170: 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 20 20 20  ointer db].     
8180: 20 73 71 6c 69 74 65 33 5f 65 78 74 65 6e 64 65   sqlite3_extende
8190: 64 5f 72 65 73 75 6c 74 5f 63 6f 64 65 73 20 24  d_result_codes $
81a0: 3a 3a 44 42 20 24 3a 3a 69 6f 65 72 72 6f 70 74  ::DB $::ioerropt
81b0: 73 28 2d 65 72 63 29 0a 20 20 20 20 20 20 69 66  s(-erc).      if
81c0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
81d0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 70  :ioerropts(-tclp
81e0: 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20  rep)]} {.       
81f0: 20 65 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 70   eval $::ioerrop
8200: 74 73 28 2d 74 63 6c 70 72 65 70 29 0a 20 20 20  ts(-tclprep).   
8210: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b     }.      if {[
8220: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f  info exists ::io
8230: 65 72 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70  erropts(-sqlprep
8240: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 65 78  )]} {.        ex
8250: 65 63 73 71 6c 20 24 3a 3a 69 6f 65 72 72 6f 70  ecsql $::ioerrop
8260: 74 73 28 2d 73 71 6c 70 72 65 70 29 0a 20 20 20  ts(-sqlprep).   
8270: 20 20 20 7d 0a 20 20 20 20 20 20 65 78 70 72 20     }.      expr 
8280: 30 0a 20 20 20 20 7d 20 7b 30 7d 0a 0a 20 20 20  0.    } {0}..   
8290: 20 23 20 52 65 61 64 20 74 68 65 20 27 63 68 65   # Read the 'che
82a0: 63 6b 73 75 6d 27 20 6f 66 20 74 68 65 20 64 61  cksum' of the da
82b0: 74 61 62 61 73 65 2e 0a 20 20 20 20 69 66 20 7b  tabase..    if {
82c0: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b  $::ioerropts(-ck
82d0: 73 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20 73 65  sum)} {.      se
82e0: 74 20 63 68 65 63 6b 73 75 6d 20 5b 63 6b 73 75  t checksum [cksu
82f0: 6d 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20  m].    }..    # 
8300: 53 65 74 20 74 68 65 20 4e 74 68 20 49 4f 20 65  Set the Nth IO e
8310: 72 72 6f 72 20 74 6f 20 66 61 69 6c 2e 0a 20 20  rror to fail..  
8320: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
8330: 61 6d 65 2e 24 6e 2e 32 20 5b 73 75 62 73 74 20  ame.$n.2 [subst 
8340: 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  {.      set ::sq
8350: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65  lite_io_error_pe
8360: 72 73 69 73 74 20 24 3a 3a 69 6f 65 72 72 6f 70  rsist $::ioerrop
8370: 74 73 28 2d 70 65 72 73 69 73 74 29 0a 20 20 20  ts(-persist).   
8380: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
8390: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
83a0: 20 24 6e 0a 20 20 20 20 7d 5d 20 24 6e 0a 20 20   $n.    }] $n.  
83b0: 0a 20 20 20 20 23 20 43 72 65 61 74 65 20 61 20  .    # Create a 
83c0: 73 69 6e 67 6c 65 20 54 43 4c 20 73 63 72 69 70  single TCL scrip
83d0: 74 20 66 72 6f 6d 20 74 68 65 20 54 43 4c 20 61  t from the TCL a
83e0: 6e 64 20 53 51 4c 20 73 70 65 63 69 66 69 65 64  nd SQL specified
83f0: 0a 20 20 20 20 23 20 61 73 20 74 68 65 20 62 6f  .    # as the bo
8400: 64 79 20 6f 66 20 74 68 65 20 74 65 73 74 2e 0a  dy of the test..
8410: 20 20 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f      set ::ioerro
8420: 72 62 6f 64 79 20 7b 7d 0a 20 20 20 20 69 66 20  rbody {}.    if 
8430: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
8440: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f  ioerropts(-tclbo
8450: 64 79 29 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70  dy)]} {.      ap
8460: 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f  pend ::ioerrorbo
8470: 64 79 20 22 24 3a 3a 69 6f 65 72 72 6f 70 74 73  dy "$::ioerropts
8480: 28 2d 74 63 6c 62 6f 64 79 29 5c 6e 22 0a 20 20  (-tclbody)\n".  
8490: 20 20 7d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66    }.    if {[inf
84a0: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
84b0: 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79 29 5d 7d  opts(-sqlbody)]}
84c0: 20 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20   {.      append 
84d0: 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 64  ::ioerrorbody "d
84e0: 62 20 65 76 61 6c 20 7b 24 3a 3a 69 6f 65 72 72  b eval {$::ioerr
84f0: 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79 29 7d 22  opts(-sqlbody)}"
8500: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 45 78  .    }..    # Ex
8510: 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 53 63  ecute the TCL Sc
8520: 72 69 70 74 20 63 72 65 61 74 65 64 20 69 6e 20  ript created in 
8530: 74 68 65 20 61 62 6f 76 65 20 62 6c 6f 63 6b 2e  the above block.
8540: 20 49 66 0a 20 20 20 20 23 20 74 68 65 72 65 20   If.    # there 
8550: 61 72 65 20 61 74 20 6c 65 61 73 74 20 4e 20 49  are at least N I
8560: 4f 20 6f 70 65 72 61 74 69 6f 6e 73 20 70 65 72  O operations per
8570: 66 6f 72 6d 65 64 20 62 79 20 53 51 4c 69 74 65  formed by SQLite
8580: 20 61 73 0a 20 20 20 20 23 20 61 20 72 65 73 75   as.    # a resu
8590: 6c 74 20 6f 66 20 74 68 65 20 73 63 72 69 70 74  lt of the script
85a0: 2c 20 74 68 65 20 4e 74 68 20 77 69 6c 6c 20 66  , the Nth will f
85b0: 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74  ail..    do_test
85c0: 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 33 20   $testname.$n.3 
85d0: 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  {.      set ::sq
85e0: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69  lite_io_error_hi
85f0: 74 20 30 0a 20 20 20 20 20 20 73 65 74 20 3a 3a  t 0.      set ::
8600: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
8610: 68 61 72 64 68 69 74 20 30 0a 20 20 20 20 20 20  hardhit 0.      
8620: 73 65 74 20 72 20 5b 63 61 74 63 68 20 24 3a 3a  set r [catch $::
8630: 69 6f 65 72 72 6f 72 62 6f 64 79 20 6d 73 67 5d  ioerrorbody msg]
8640: 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 65 72 72  .      set ::err
8650: 73 65 65 6e 20 24 72 0a 20 20 20 20 20 20 73 65  seen $r.      se
8660: 74 20 72 63 20 5b 73 71 6c 69 74 65 33 5f 65 72  t rc [sqlite3_er
8670: 72 63 6f 64 65 20 24 3a 3a 44 42 5d 0a 20 20 20  rcode $::DB].   
8680: 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f     if {$::ioerro
8690: 70 74 73 28 2d 65 72 63 29 7d 20 7b 0a 20 20 20  pts(-erc)} {.   
86a0: 20 20 20 20 20 23 20 49 66 20 77 65 20 61 72 65       # If we are
86b0: 20 69 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73   in extended res
86c0: 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20 6d  ult code mode, m
86d0: 61 6b 65 20 73 75 72 65 20 61 6c 6c 20 6f 66 20  ake sure all of 
86e0: 74 68 65 0a 20 20 20 20 20 20 20 20 23 20 49 4f  the.        # IO
86f0: 45 52 52 73 20 77 65 20 67 65 74 20 62 61 63 6b  ERRs we get back
8700: 20 72 65 61 6c 6c 79 20 64 6f 20 68 61 76 65 20   really do have 
8710: 74 68 65 69 72 20 65 78 74 65 6e 64 65 64 20 63  their extended c
8720: 6f 64 65 20 76 61 6c 75 65 73 2e 0a 20 20 20 20  ode values..    
8730: 20 20 20 20 23 20 49 66 20 61 6e 20 65 78 74 65      # If an exte
8740: 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65  nded result code
8750: 20 69 73 20 72 65 74 75 72 6e 65 64 2c 20 74 68   is returned, th
8760: 65 20 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64  e sqlite3_errcod
8770: 65 0a 20 20 20 20 20 20 20 20 23 20 54 43 4c 63  e.        # TCLc
8780: 6f 6d 6d 61 6e 64 20 77 69 6c 6c 20 72 65 74 75  ommand will retu
8790: 72 6e 20 61 20 73 74 72 69 6e 67 20 6f 66 20 74  rn a string of t
87a0: 68 65 20 66 6f 72 6d 3a 20 20 53 51 4c 49 54 45  he form:  SQLITE
87b0: 5f 49 4f 45 52 52 2b 6e 6e 6e 6e 0a 20 20 20 20  _IOERR+nnnn.    
87c0: 20 20 20 20 23 20 77 68 65 72 65 20 6e 6e 6e 6e      # where nnnn
87d0: 20 69 73 20 61 20 6e 75 6d 62 65 72 0a 20 20 20   is a number.   
87e0: 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70       if {[regexp
87f0: 20 7b 5e 53 51 4c 49 54 45 5f 49 4f 45 52 52 7d   {^SQLITE_IOERR}
8800: 20 24 72 63 5d 20 26 26 20 21 5b 72 65 67 65 78   $rc] && ![regex
8810: 70 20 7b 49 4f 45 52 52 5c 2b 5c 64 7d 20 24 72  p {IOERR\+\d} $r
8820: 63 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20  c]} {.          
8830: 72 65 74 75 72 6e 20 24 72 63 0a 20 20 20 20 20  return $rc.     
8840: 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73     }.      } els
8850: 65 20 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66  e {.        # If
8860: 20 77 65 20 61 72 65 20 6e 6f 74 20 69 6e 20 65   we are not in e
8870: 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63  xtended result c
8880: 6f 64 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73  ode mode, make s
8890: 75 72 65 20 6e 6f 0a 20 20 20 20 20 20 20 20 23  ure no.        #
88a0: 20 65 78 74 65 6e 64 65 64 20 65 72 72 6f 72 20   extended error 
88b0: 63 6f 64 65 73 20 61 72 65 20 72 65 74 75 72 6e  codes are return
88c0: 65 64 2e 0a 20 20 20 20 20 20 20 20 69 66 20 7b  ed..        if {
88d0: 5b 72 65 67 65 78 70 20 7b 5c 2b 5c 64 7d 20 24  [regexp {\+\d} $
88e0: 72 63 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  rc]} {.         
88f0: 20 72 65 74 75 72 6e 20 24 72 63 0a 20 20 20 20   return $rc.    
8900: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
8910: 20 20 20 20 23 20 54 68 65 20 74 65 73 74 20 72      # The test r
8920: 65 70 65 61 74 73 20 61 73 20 6c 6f 6e 67 20 61  epeats as long a
8930: 73 20 24 3a 3a 67 6f 20 69 73 20 6e 6f 6e 2d 7a  s $::go is non-z
8940: 65 72 6f 2e 20 20 24 3a 3a 67 6f 20 73 74 61 72  ero.  $::go star
8950: 74 73 20 6f 75 74 0a 20 20 20 20 20 20 23 20 61  ts out.      # a
8960: 73 20 31 2e 20 20 57 68 65 6e 20 61 20 74 65 73  s 1.  When a tes
8970: 74 20 72 75 6e 73 20 74 6f 20 63 6f 6d 70 6c 65  t runs to comple
8980: 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 68 69 74  tion without hit
8990: 74 69 6e 67 20 61 6e 20 49 2f 4f 0a 20 20 20 20  ting an I/O.    
89a0: 20 20 23 20 65 72 72 6f 72 2c 20 74 68 61 74 20    # error, that 
89b0: 6d 65 61 6e 73 20 74 68 65 72 65 20 69 73 20 6e  means there is n
89c0: 6f 20 70 6f 69 6e 74 20 69 6e 20 63 6f 6e 74 69  o point in conti
89d0: 6e 75 69 6e 67 20 77 69 74 68 20 74 68 69 73 20  nuing with this 
89e0: 74 65 73 74 0a 20 20 20 20 20 20 23 20 63 61 73  test.      # cas
89f0: 65 20 73 6f 20 73 65 74 20 24 3a 3a 67 6f 20 74  e so set $::go t
8a00: 6f 20 7a 65 72 6f 2e 0a 20 20 20 20 20 20 23 0a  o zero..      #.
8a10: 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 73 71 6c        if {$::sql
8a20: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
8a30: 64 69 6e 67 3e 30 7d 20 7b 0a 20 20 20 20 20 20  ding>0} {.      
8a40: 20 20 73 65 74 20 3a 3a 67 6f 20 30 0a 20 20 20    set ::go 0.   
8a50: 20 20 20 20 20 73 65 74 20 71 20 30 0a 20 20 20       set q 0.   
8a60: 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74       set ::sqlit
8a70: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
8a80: 6e 67 20 30 0a 20 20 20 20 20 20 7d 20 65 6c 73  ng 0.      } els
8a90: 65 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  e {.        set 
8aa0: 71 20 31 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  q 1.      }..   
8ab0: 20 20 20 73 65 74 20 73 20 5b 65 78 70 72 20 24     set s [expr $
8ac0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
8ad0: 72 5f 68 69 74 3d 3d 30 5d 0a 20 20 20 20 20 20  r_hit==0].      
8ae0: 69 66 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f  if {$::sqlite_io
8af0: 5f 65 72 72 6f 72 5f 68 69 74 3e 24 3a 3a 73 71  _error_hit>$::sq
8b00: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61  lite_io_error_ha
8b10: 72 64 68 69 74 20 26 26 20 24 72 3d 3d 30 7d 20  rdhit && $r==0} 
8b20: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 72 20  {.        set r 
8b30: 31 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  1.      }.      
8b40: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
8b50: 65 72 72 6f 72 5f 68 69 74 20 30 0a 0a 20 20 20  error_hit 0..   
8b60: 20 20 20 23 20 4f 6e 65 20 6f 66 20 74 77 6f 20     # One of two 
8b70: 74 68 69 6e 67 73 20 6d 75 73 74 20 68 61 76 65  things must have
8b80: 20 68 61 70 70 65 6e 65 64 2e 20 65 69 74 68 65   happened. eithe
8b90: 72 0a 20 20 20 20 20 20 23 20 20 20 31 2e 20 20  r.      #   1.  
8ba0: 57 65 20 6e 65 76 65 72 20 68 69 74 20 74 68 65  We never hit the
8bb0: 20 49 4f 20 65 72 72 6f 72 20 61 6e 64 20 74 68   IO error and th
8bc0: 65 20 53 51 4c 20 72 65 74 75 72 6e 65 64 20 4f  e SQL returned O
8bd0: 4b 0a 20 20 20 20 20 20 23 20 20 20 32 2e 20 20  K.      #   2.  
8be0: 41 6e 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20  An IO error was 
8bf0: 68 69 74 20 61 6e 64 20 74 68 65 20 53 51 4c 20  hit and the SQL 
8c00: 66 61 69 6c 65 64 0a 20 20 20 20 20 20 23 0a 20  failed.      #. 
8c10: 20 20 20 20 20 23 70 75 74 73 20 22 73 3d 24 73       #puts "s=$s
8c20: 20 72 3d 24 72 20 71 3d 24 71 22 0a 20 20 20 20   r=$r q=$q".    
8c30: 20 20 65 78 70 72 20 7b 20 28 24 73 20 26 26 20    expr { ($s && 
8c40: 21 24 72 20 26 26 20 21 24 71 29 20 7c 7c 20 28  !$r && !$q) || (
8c50: 21 24 73 20 26 26 20 24 72 20 26 26 20 24 71 29  !$s && $r && $q)
8c60: 20 7d 0a 20 20 20 20 7d 20 7b 31 7d 0a 0a 20 20   }.    } {1}..  
8c70: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
8c80: 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 20 20  o_error_hit 0.  
8c90: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
8ca0: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
8cb0: 30 0a 0a 20 20 20 20 23 20 43 68 65 63 6b 20 74  0..    # Check t
8cc0: 68 61 74 20 6e 6f 20 70 61 67 65 20 72 65 66 65  hat no page refe
8cd0: 72 65 6e 63 65 73 20 77 65 72 65 20 6c 65 61 6b  rences were leak
8ce0: 65 64 2e 20 54 68 65 72 65 20 73 68 6f 75 6c 64  ed. There should
8cf0: 20 62 65 20 0a 20 20 20 20 23 20 61 20 73 69 6e   be .    # a sin
8d00: 67 6c 65 20 72 65 66 65 72 65 6e 63 65 20 69 66  gle reference if
8d10: 20 74 68 65 72 65 20 69 73 20 73 74 69 6c 6c 20   there is still 
8d20: 61 6e 20 61 63 74 69 76 65 20 74 72 61 6e 73 61  an active transa
8d30: 63 74 69 6f 6e 2c 20 0a 20 20 20 20 23 20 6f 72  ction, .    # or
8d40: 20 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65 2e   zero otherwise.
8d50: 0a 20 20 20 20 23 0a 20 20 20 20 23 20 55 50 44  .    #.    # UPD
8d60: 41 54 45 3a 20 49 66 20 74 68 65 20 49 4f 20 65  ATE: If the IO e
8d70: 72 72 6f 72 20 6f 63 63 75 72 73 20 61 66 74 65  rror occurs afte
8d80: 72 20 61 20 27 42 45 47 49 4e 27 20 62 75 74 20  r a 'BEGIN' but 
8d90: 62 65 66 6f 72 65 20 61 6e 79 0a 20 20 20 20 23  before any.    #
8da0: 20 6c 6f 63 6b 73 20 61 72 65 20 65 73 74 61 62   locks are estab
8db0: 6c 69 73 68 65 64 20 6f 6e 20 64 61 74 61 62 61  lished on databa
8dc0: 73 65 20 66 69 6c 65 73 20 28 69 2e 65 2e 20 69  se files (i.e. i
8dd0: 66 20 74 68 65 20 65 72 72 6f 72 20 0a 20 20 20  f the error .   
8de0: 20 23 20 6f 63 63 75 72 73 20 77 68 69 6c 65 20   # occurs while 
8df0: 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 64 65  attempting to de
8e00: 74 65 63 74 20 61 20 68 6f 74 2d 6a 6f 75 72 6e  tect a hot-journ
8e10: 61 6c 20 66 69 6c 65 29 2c 20 74 68 65 6e 0a 20  al file), then. 
8e20: 20 20 20 23 20 74 68 65 72 65 20 6d 61 79 20 30     # there may 0
8e30: 20 70 61 67 65 20 72 65 66 65 72 65 6e 63 65 73   page references
8e40: 20 61 6e 64 20 61 6e 20 61 63 74 69 76 65 20 74   and an active t
8e50: 72 61 6e 73 61 63 74 69 6f 6e 20 61 63 63 6f 72  ransaction accor
8e60: 64 69 6e 67 0a 20 20 20 20 23 20 74 6f 20 5b 73  ding.    # to [s
8e70: 71 6c 69 74 65 33 5f 67 65 74 5f 61 75 74 6f 63  qlite3_get_autoc
8e80: 6f 6d 6d 69 74 5d 2e 0a 20 20 20 20 23 0a 20 20  ommit]..    #.  
8e90: 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20 24    if {$::go && $
8ea0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
8eb0: 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 3a 3a  r_hardhit && $::
8ec0: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72 65 66  ioerropts(-ckref
8ed0: 63 6f 75 6e 74 29 7d 20 7b 0a 20 20 20 20 20 20  count)} {.      
8ee0: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
8ef0: 65 2e 24 6e 2e 34 20 7b 0a 20 20 20 20 20 20 20  e.$n.4 {.       
8f00: 20 73 65 74 20 62 74 20 5b 62 74 72 65 65 5f 66   set bt [btree_f
8f10: 72 6f 6d 5f 64 62 20 64 62 5d 0a 20 20 20 20 20  rom_db db].     
8f20: 20 20 20 64 62 5f 65 6e 74 65 72 20 64 62 0a 20     db_enter db. 
8f30: 20 20 20 20 20 20 20 61 72 72 61 79 20 73 65 74         array set
8f40: 20 73 74 61 74 73 20 5b 62 74 72 65 65 5f 70 61   stats [btree_pa
8f50: 67 65 72 5f 73 74 61 74 73 20 24 62 74 5d 0a 20  ger_stats $bt]. 
8f60: 20 20 20 20 20 20 20 64 62 5f 6c 65 61 76 65 20         db_leave 
8f70: 64 62 0a 20 20 20 20 20 20 20 20 73 65 74 20 6e  db.        set n
8f80: 52 65 66 20 24 73 74 61 74 73 28 72 65 66 29 0a  Ref $stats(ref).
8f90: 20 20 20 20 20 20 20 20 65 78 70 72 20 7b 24 6e          expr {$n
8fa0: 52 65 66 20 3d 3d 20 30 20 7c 7c 20 28 5b 73 71  Ref == 0 || ([sq
8fb0: 6c 69 74 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f  lite3_get_autoco
8fc0: 6d 6d 69 74 20 64 62 5d 3d 3d 30 20 26 26 20 24  mmit db]==0 && $
8fd0: 6e 52 65 66 20 3d 3d 20 31 29 7d 0a 20 20 20 20  nRef == 1)}.    
8fe0: 20 20 7d 20 7b 31 7d 0a 20 20 20 20 7d 0a 0a 20    } {1}.    }.. 
8ff0: 20 20 20 23 20 49 66 20 74 68 65 72 65 20 69 73     # If there is
9000: 20 61 6e 20 6f 70 65 6e 20 64 61 74 61 62 61 73   an open databas
9010: 65 20 68 61 6e 64 6c 65 20 61 6e 64 20 6e 6f 20  e handle and no 
9020: 6f 70 65 6e 20 74 72 61 6e 73 61 63 74 69 6f 6e  open transaction
9030: 2c 20 0a 20 20 20 20 23 20 61 6e 64 20 74 68 65  , .    # and the
9040: 20 70 61 67 65 72 20 69 73 20 6e 6f 74 20 72 75   pager is not ru
9050: 6e 6e 69 6e 67 20 69 6e 20 65 78 63 6c 75 73 69  nning in exclusi
9060: 76 65 2d 6c 6f 63 6b 69 6e 67 20 6d 6f 64 65 2c  ve-locking mode,
9070: 0a 20 20 20 20 23 20 63 68 65 63 6b 20 74 68 61  .    # check tha
9080: 74 20 74 68 65 20 70 61 67 65 72 20 69 73 20 69  t the pager is i
9090: 6e 20 22 75 6e 6c 6f 63 6b 65 64 22 20 73 74 61  n "unlocked" sta
90a0: 74 65 2e 20 54 68 65 6f 72 65 74 69 63 61 6c 6c  te. Theoreticall
90b0: 79 2c 0a 20 20 20 20 23 20 69 66 20 61 20 63 61  y,.    # if a ca
90c0: 6c 6c 20 74 6f 20 78 55 6e 6c 6f 63 6b 28 29 20  ll to xUnlock() 
90d0: 66 61 69 6c 65 64 20 64 75 65 20 74 6f 20 61 6e  failed due to an
90e0: 20 49 4f 20 65 72 72 6f 72 20 74 68 65 20 75 6e   IO error the un
90f0: 64 65 72 6c 79 69 6e 67 0a 20 20 20 20 23 20 66  derlying.    # f
9100: 69 6c 65 20 6d 61 79 20 73 74 69 6c 6c 20 62 65  ile may still be
9110: 20 6c 6f 63 6b 65 64 2e 0a 20 20 20 20 23 0a 20   locked..    #. 
9120: 20 20 20 69 66 63 61 70 61 62 6c 65 20 70 72 61     ifcapable pra
9130: 67 6d 61 20 7b 0a 20 20 20 20 20 20 69 66 20 7b  gma {.      if {
9140: 20 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20   [info commands 
9150: 64 62 5d 20 6e 65 20 22 22 0a 20 20 20 20 20 20  db] ne "".      
9160: 20 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74    && $::ioerropt
9170: 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29 0a 20  s(-ckrefcount). 
9180: 20 20 20 20 20 20 20 26 26 20 5b 64 62 20 6f 6e         && [db on
9190: 65 20 7b 70 72 61 67 6d 61 20 6c 6f 63 6b 69 6e  e {pragma lockin
91a0: 67 5f 6d 6f 64 65 7d 5d 20 65 71 20 22 6e 6f 72  g_mode}] eq "nor
91b0: 6d 61 6c 22 0a 20 20 20 20 20 20 20 20 26 26 20  mal".        && 
91c0: 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f 61 75 74  [sqlite3_get_aut
91d0: 6f 63 6f 6d 6d 69 74 20 64 62 5d 0a 20 20 20 20  ocommit db].    
91e0: 20 20 7d 20 7b 0a 20 20 20 20 20 20 20 20 64 6f    } {.        do
91f0: 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e  _test $testname.
9200: 24 6e 2e 35 20 7b 0a 20 20 20 20 20 20 20 20 20  $n.5 {.         
9210: 20 73 65 74 20 62 74 20 5b 62 74 72 65 65 5f 66   set bt [btree_f
9220: 72 6f 6d 5f 64 62 20 64 62 5d 0a 20 20 20 20 20  rom_db db].     
9230: 20 20 20 20 20 64 62 5f 65 6e 74 65 72 20 64 62       db_enter db
9240: 0a 20 20 20 20 20 20 20 20 20 20 61 72 72 61 79  .          array
9250: 20 73 65 74 20 73 74 61 74 73 20 5b 62 74 72 65   set stats [btre
9260: 65 5f 70 61 67 65 72 5f 73 74 61 74 73 20 24 62  e_pager_stats $b
9270: 74 5d 0a 20 20 20 20 20 20 20 20 20 20 64 62 5f  t].          db_
9280: 6c 65 61 76 65 20 64 62 0a 20 20 20 20 20 20 20  leave db.       
9290: 20 20 20 73 65 74 20 73 74 61 74 73 28 73 74 61     set stats(sta
92a0: 74 65 29 0a 20 20 20 20 20 20 20 20 7d 20 30 0a  te).        } 0.
92b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
92c0: 20 20 20 23 20 49 66 20 61 6e 20 49 4f 20 65 72     # If an IO er
92d0: 72 6f 72 20 6f 63 63 75 72 65 64 2c 20 74 68 65  ror occured, the
92e0: 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f  n the checksum o
92f0: 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20 73  f the database s
9300: 68 6f 75 6c 64 0a 20 20 20 20 23 20 62 65 20 74  hould.    # be t
9310: 68 65 20 73 61 6d 65 20 61 73 20 62 65 66 6f 72  he same as befor
9320: 65 20 74 68 65 20 73 63 72 69 70 74 20 74 68 61  e the script tha
9330: 74 20 63 61 75 73 65 64 20 74 68 65 20 49 4f 20  t caused the IO 
9340: 65 72 72 6f 72 20 77 61 73 20 72 75 6e 2e 0a 20  error was run.. 
9350: 20 20 20 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a     #.    if {$::
9360: 67 6f 20 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f  go && $::sqlite_
9370: 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74  io_error_hardhit
9380: 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73   && $::ioerropts
9390: 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20  (-cksum)} {.    
93a0: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
93b0: 61 6d 65 2e 24 6e 2e 36 20 7b 0a 20 20 20 20 20  ame.$n.6 {.     
93c0: 20 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f     catch {db clo
93d0: 73 65 7d 0a 20 20 20 20 20 20 20 20 63 61 74 63  se}.        catc
93e0: 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20  h {db2 close}.  
93f0: 20 20 20 20 20 20 73 65 74 20 3a 3a 44 42 20 5b        set ::DB [
9400: 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e  sqlite3 db test.
9410: 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e  db; sqlite3_conn
9420: 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64  ection_pointer d
9430: 62 5d 0a 20 20 20 20 20 20 20 20 63 6b 73 75 6d  b].        cksum
9440: 0a 20 20 20 20 20 20 7d 20 24 63 68 65 63 6b 73  .      } $checks
9450: 75 6d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 65  um.    }..    se
9460: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
9470: 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a 20 20  ror_hardhit 0.  
9480: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
9490: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
94a0: 30 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  0.    if {[info 
94b0: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
94c0: 74 73 28 2d 63 6c 65 61 6e 75 70 29 5d 7d 20 7b  ts(-cleanup)]} {
94d0: 0a 20 20 20 20 20 20 63 61 74 63 68 20 24 3a 3a  .      catch $::
94e0: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e  ioerropts(-clean
94f0: 75 70 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  up).    }.  }.  
9500: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
9510: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a  error_pending 0.
9520: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
9530: 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20  o_error_persist 
9540: 30 0a 20 20 75 6e 73 65 74 20 3a 3a 69 6f 65 72  0.  unset ::ioer
9550: 72 6f 70 74 73 0a 7d 0a 0a 23 20 52 65 74 75 72  ropts.}..# Retur
9560: 6e 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73  n a checksum bas
9570: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e  ed on the conten
9580: 74 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 64  ts of the main d
9590: 61 74 61 62 61 73 65 20 61 73 73 6f 63 69 61 74  atabase associat
95a0: 65 64 0a 23 20 77 69 74 68 20 63 6f 6e 6e 65 63  ed.# with connec
95b0: 74 69 6f 6e 20 24 64 62 0a 23 0a 70 72 6f 63 20  tion $db.#.proc 
95c0: 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20  cksum {{db db}} 
95d0: 7b 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64 62  {.  set txt [$db
95e0: 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45   eval {.      SE
95f0: 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79 70 65 2c  LECT name, type,
9600: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
9610: 5f 6d 61 73 74 65 72 20 6f 72 64 65 72 20 62 79  _master order by
9620: 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e 0a 20 20 66   name.  }]\n.  f
9630: 6f 72 65 61 63 68 20 74 62 6c 20 5b 24 64 62 20  oreach tbl [$db 
9640: 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c  eval {.      SEL
9650: 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71  ECT name FROM sq
9660: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
9670: 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27 20 6f  E type='table' o
9680: 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d  rder by name.  }
9690: 5d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74  ] {.    append t
96a0: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45  xt [$db eval "SE
96b0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c  LECT * FROM $tbl
96c0: 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66 6f 72 65 61  "]\n.  }.  forea
96d0: 63 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c 74  ch prag {default
96e0: 5f 73 79 6e 63 68 72 6f 6e 6f 75 73 20 64 65 66  _synchronous def
96f0: 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d  ault_cache_size}
9700: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78   {.    append tx
9710: 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76 61  t $prag-[$db eva
9720: 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61 67 22  l "PRAGMA $prag"
9730: 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65 74 20 63 6b  ]\n.  }.  set ck
9740: 73 75 6d 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  sum [string leng
9750: 74 68 20 24 74 78 74 5d 2d 5b 6d 64 35 20 24 74  th $txt]-[md5 $t
9760: 78 74 5d 0a 20 20 23 20 70 75 74 73 20 24 63 6b  xt].  # puts $ck
9770: 73 75 6d 2d 5b 66 69 6c 65 20 73 69 7a 65 20 74  sum-[file size t
9780: 65 73 74 2e 64 62 5d 0a 20 20 72 65 74 75 72 6e  est.db].  return
9790: 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23 20 47 65 6e   $cksum.}..# Gen
97a0: 65 72 61 74 65 20 61 20 63 68 65 63 6b 73 75 6d  erate a checksum
97b0: 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f   based on the co
97c0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 6d 61  ntents of the ma
97d0: 69 6e 20 61 6e 64 20 74 65 6d 70 20 74 61 62 6c  in and temp tabl
97e0: 65 73 0a 23 20 64 61 74 61 62 61 73 65 20 24 64  es.# database $d
97f0: 62 2e 20 49 66 20 74 68 65 20 63 68 65 63 6b 73  b. If the checks
9800: 75 6d 20 6f 66 20 74 77 6f 20 64 61 74 61 62 61  um of two databa
9810: 73 65 73 20 69 73 20 74 68 65 20 73 61 6d 65 2c  ses is the same,
9820: 20 61 6e 64 20 74 68 65 0a 23 20 69 6e 74 65 67   and the.# integ
9830: 72 69 74 79 2d 63 68 65 63 6b 20 70 61 73 73 65  rity-check passe
9840: 73 20 66 6f 72 20 62 6f 74 68 2c 20 74 68 65 20  s for both, the 
9850: 74 77 6f 20 64 61 74 61 62 61 73 65 73 20 61 72  two databases ar
9860: 65 20 69 64 65 6e 74 69 63 61 6c 2e 0a 23 0a 70  e identical..#.p
9870: 72 6f 63 20 61 6c 6c 63 6b 73 75 6d 20 7b 7b 64  roc allcksum {{d
9880: 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 72  b db}} {.  set r
9890: 65 74 20 5b 6c 69 73 74 5d 0a 20 20 69 66 63 61  et [list].  ifca
98a0: 70 61 62 6c 65 20 74 65 6d 70 64 62 20 7b 0a 20  pable tempdb {. 
98b0: 20 20 20 73 65 74 20 73 71 6c 20 7b 0a 20 20 20     set sql {.   
98c0: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
98d0: 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ROM sqlite_maste
98e0: 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27  r WHERE type = '
98f0: 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20  table' UNION.   
9900: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
9910: 52 4f 4d 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f  ROM sqlite_temp_
9920: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
9930: 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f  e = 'table' UNIO
9940: 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27  N.      SELECT '
9950: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20 55  sqlite_master' U
9960: 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43  NION.      SELEC
9970: 54 20 27 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d  T 'sqlite_temp_m
9980: 61 73 74 65 72 27 20 4f 52 44 45 52 20 42 59 20  aster' ORDER BY 
9990: 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  1.    }.  } else
99a0: 20 7b 0a 20 20 20 20 73 65 74 20 73 71 6c 20 7b   {.    set sql {
99b0: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
99c0: 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  me FROM sqlite_m
99d0: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
99e0: 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e   = 'table' UNION
99f0: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27 73  .      SELECT 's
9a00: 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20 4f 52  qlite_master' OR
9a10: 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d 0a 20  DER BY 1.    }. 
9a20: 20 7d 0a 20 20 73 65 74 20 74 62 6c 6c 69 73 74   }.  set tbllist
9a30: 20 5b 24 64 62 20 65 76 61 6c 20 24 73 71 6c 5d   [$db eval $sql]
9a40: 0a 20 20 73 65 74 20 74 78 74 20 7b 7d 0a 20 20  .  set txt {}.  
9a50: 66 6f 72 65 61 63 68 20 74 62 6c 20 24 74 62 6c  foreach tbl $tbl
9a60: 6c 69 73 74 20 7b 0a 20 20 20 20 61 70 70 65 6e  list {.    appen
9a70: 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20  d txt [$db eval 
9a80: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24  "SELECT * FROM $
9a90: 74 62 6c 22 5d 0a 20 20 7d 0a 20 20 66 6f 72 65  tbl"].  }.  fore
9aa0: 61 63 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c  ach prag {defaul
9ab0: 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d 20 7b 0a  t_cache_size} {.
9ac0: 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 24      append txt $
9ad0: 70 72 61 67 2d 5b 24 64 62 20 65 76 61 6c 20 22  prag-[$db eval "
9ae0: 50 52 41 47 4d 41 20 24 70 72 61 67 22 5d 5c 6e  PRAGMA $prag"]\n
9af0: 0a 20 20 7d 0a 20 20 23 20 70 75 74 73 20 74 78  .  }.  # puts tx
9b00: 74 3d 24 74 78 74 0a 20 20 72 65 74 75 72 6e 20  t=$txt.  return 
9b10: 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 23 20  [md5 $txt].}..# 
9b20: 47 65 6e 65 72 61 74 65 20 61 20 63 68 65 63 6b  Generate a check
9b30: 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65  sum based on the
9b40: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 20 73   contents of a s
9b50: 69 6e 67 6c 65 20 64 61 74 61 62 61 73 65 20 77  ingle database w
9b60: 69 74 68 0a 23 20 61 20 64 61 74 61 62 61 73 65  ith.# a database
9b70: 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20 20 54 68   connection.  Th
9b80: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 64 61  e name of the da
9b90: 74 61 62 61 73 65 20 69 73 20 24 64 62 6e 61 6d  tabase is $dbnam
9ba0: 65 2e 20 20 0a 23 20 45 78 61 6d 70 6c 65 73 20  e.  .# Examples 
9bb0: 6f 66 20 24 64 62 6e 61 6d 65 20 61 72 65 20 22  of $dbname are "
9bc0: 74 65 6d 70 22 20 6f 72 20 22 6d 61 69 6e 22 2e  temp" or "main".
9bd0: 0a 23 0a 70 72 6f 63 20 64 62 63 6b 73 75 6d 20  .#.proc dbcksum 
9be0: 7b 64 62 20 64 62 6e 61 6d 65 7d 20 7b 0a 20 20  {db dbname} {.  
9bf0: 69 66 20 7b 24 64 62 6e 61 6d 65 3d 3d 22 74 65  if {$dbname=="te
9c00: 6d 70 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 6d  mp"} {.    set m
9c10: 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74 65 6d  aster sqlite_tem
9c20: 70 5f 6d 61 73 74 65 72 0a 20 20 7d 20 65 6c 73  p_master.  } els
9c30: 65 20 7b 0a 20 20 20 20 73 65 74 20 6d 61 73 74  e {.    set mast
9c40: 65 72 20 24 64 62 6e 61 6d 65 2e 73 71 6c 69 74  er $dbname.sqlit
9c50: 65 5f 6d 61 73 74 65 72 0a 20 20 7d 0a 20 20 73  e_master.  }.  s
9c60: 65 74 20 61 6c 6c 74 61 62 20 5b 24 64 62 20 65  et alltab [$db e
9c70: 76 61 6c 20 22 53 45 4c 45 43 54 20 6e 61 6d 65  val "SELECT name
9c80: 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 20 57 48   FROM $master WH
9c90: 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27  ERE type='table'
9ca0: 22 5d 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64  "].  set txt [$d
9cb0: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a  b eval "SELECT *
9cc0: 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 22 5d 5c   FROM $master"]\
9cd0: 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 61 62 20  n.  foreach tab 
9ce0: 24 61 6c 6c 74 61 62 20 7b 0a 20 20 20 20 61 70  $alltab {.    ap
9cf0: 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76  pend txt [$db ev
9d00: 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  al "SELECT * FRO
9d10: 4d 20 24 64 62 6e 61 6d 65 2e 24 74 61 62 22 5d  M $dbname.$tab"]
9d20: 5c 6e 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  \n.  }.  return 
9d30: 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 70 72  [md5 $txt].}..pr
9d40: 6f 63 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f  oc memdebug_log_
9d50: 73 71 6c 20 7b 7b 66 69 6c 65 6e 61 6d 65 20 6d  sql {{filename m
9d60: 61 6c 6c 6f 63 73 2e 73 71 6c 7d 7d 20 7b 0a 0a  allocs.sql}} {..
9d70: 20 20 73 65 74 20 64 61 74 61 20 5b 73 71 6c 69    set data [sqli
9d80: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67  te3_memdebug_log
9d90: 20 64 75 6d 70 5d 0a 20 20 73 65 74 20 6e 46 72   dump].  set nFr
9da0: 61 6d 65 20 5b 65 78 70 72 20 5b 6c 6c 65 6e 67  ame [expr [lleng
9db0: 74 68 20 5b 6c 69 6e 64 65 78 20 24 64 61 74 61  th [lindex $data
9dc0: 20 30 5d 5d 2d 32 5d 0a 20 20 69 66 20 7b 24 6e   0]]-2].  if {$n
9dd0: 46 72 61 6d 65 20 3c 20 30 7d 20 7b 20 72 65 74  Frame < 0} { ret
9de0: 75 72 6e 20 22 22 20 7d 0a 0a 20 20 73 65 74 20  urn "" }..  set 
9df0: 64 61 74 61 62 61 73 65 20 74 65 6d 70 0a 0a 20  database temp.. 
9e00: 20 73 65 74 20 74 62 6c 20 22 43 52 45 41 54 45   set tbl "CREATE
9e10: 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73   TABLE ${databas
9e20: 65 7d 2e 6d 61 6c 6c 6f 63 28 7a 54 65 73 74 2c  e}.malloc(zTest,
9e30: 20 6e 43 61 6c 6c 2c 20 6e 42 79 74 65 2c 20 6c   nCall, nByte, l
9e40: 53 74 61 63 6b 29 3b 22 0a 0a 20 20 73 65 74 20  Stack);"..  set 
9e50: 73 71 6c 20 22 22 0a 20 20 66 6f 72 65 61 63 68  sql "".  foreach
9e60: 20 65 20 24 64 61 74 61 20 7b 0a 20 20 20 20 73   e $data {.    s
9e70: 65 74 20 6e 43 61 6c 6c 20 5b 6c 69 6e 64 65 78  et nCall [lindex
9e80: 20 24 65 20 30 5d 0a 20 20 20 20 73 65 74 20 6e   $e 0].    set n
9e90: 42 79 74 65 20 5b 6c 69 6e 64 65 78 20 24 65 20  Byte [lindex $e 
9ea0: 31 5d 0a 20 20 20 20 73 65 74 20 6c 53 74 61 63  1].    set lStac
9eb0: 6b 20 5b 6c 72 61 6e 67 65 20 24 65 20 32 20 65  k [lrange $e 2 e
9ec0: 6e 64 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73  nd].    append s
9ed0: 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20  ql "INSERT INTO 
9ee0: 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c 6c  ${database}.mall
9ef0: 6f 63 20 56 41 4c 55 45 53 22 0a 20 20 20 20 61  oc VALUES".    a
9f00: 70 70 65 6e 64 20 73 71 6c 20 22 28 27 74 65 73  ppend sql "('tes
9f10: 74 27 2c 20 24 6e 43 61 6c 6c 2c 20 24 6e 42 79  t', $nCall, $nBy
9f20: 74 65 2c 20 27 24 6c 53 74 61 63 6b 27 29 3b 5c  te, '$lStack');\
9f30: 6e 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66  n".    foreach f
9f40: 20 24 6c 53 74 61 63 6b 20 7b 0a 20 20 20 20 20   $lStack {.     
9f50: 20 73 65 74 20 66 72 61 6d 65 73 28 24 66 29 20   set frames($f) 
9f60: 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73  1.    }.  }..  s
9f70: 65 74 20 74 62 6c 32 20 22 43 52 45 41 54 45 20  et tbl2 "CREATE 
9f80: 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65  TABLE ${database
9f90: 7d 2e 66 72 61 6d 65 28 66 72 61 6d 65 20 49 4e  }.frame(frame IN
9fa0: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45  TEGER PRIMARY KE
9fb0: 59 2c 20 6c 69 6e 65 29 3b 5c 6e 22 0a 20 20 73  Y, line);\n".  s
9fc0: 65 74 20 74 62 6c 33 20 22 43 52 45 41 54 45 20  et tbl3 "CREATE 
9fd0: 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65  TABLE ${database
9fe0: 7d 2e 66 69 6c 65 28 6e 61 6d 65 20 50 52 49 4d  }.file(name PRIM
9ff0: 41 52 59 20 4b 45 59 2c 20 63 6f 6e 74 65 6e 74  ARY KEY, content
a000: 29 3b 5c 6e 22 0a 0a 20 20 66 6f 72 65 61 63 68  );\n"..  foreach
a010: 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20   f [array names 
a020: 66 72 61 6d 65 73 5d 20 7b 0a 20 20 20 20 73 65  frames] {.    se
a030: 74 20 61 64 64 72 20 5b 66 6f 72 6d 61 74 20 25  t addr [format %
a040: 78 20 24 66 5d 0a 20 20 20 20 73 65 74 20 63 6d  x $f].    set cm
a050: 64 20 22 61 64 64 72 32 6c 69 6e 65 20 2d 65 20  d "addr2line -e 
a060: 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63  [info nameofexec
a070: 5d 20 24 61 64 64 72 22 0a 20 20 20 20 73 65 74  ] $addr".    set
a080: 20 6c 69 6e 65 20 5b 65 76 61 6c 20 65 78 65 63   line [eval exec
a090: 20 24 63 6d 64 5d 0a 20 20 20 20 61 70 70 65 6e   $cmd].    appen
a0a0: 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e  d sql "INSERT IN
a0b0: 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66  TO ${database}.f
a0c0: 72 61 6d 65 20 56 41 4c 55 45 53 28 24 66 2c 20  rame VALUES($f, 
a0d0: 27 24 6c 69 6e 65 27 29 3b 5c 6e 22 0a 0a 20 20  '$line');\n"..  
a0e0: 20 20 73 65 74 20 66 69 6c 65 20 5b 6c 69 6e 64    set file [lind
a0f0: 65 78 20 5b 73 70 6c 69 74 20 24 6c 69 6e 65 20  ex [split $line 
a100: 3a 5d 20 30 5d 0a 20 20 20 20 73 65 74 20 66 69  :] 0].    set fi
a110: 6c 65 73 28 24 66 69 6c 65 29 20 31 0a 20 20 7d  les($file) 1.  }
a120: 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 61  ..  foreach f [a
a130: 72 72 61 79 20 6e 61 6d 65 73 20 66 69 6c 65 73  rray names files
a140: 5d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6e 74  ] {.    set cont
a150: 65 6e 74 73 20 22 22 0a 20 20 20 20 63 61 74 63  ents "".    catc
a160: 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66 64  h {.      set fd
a170: 20 5b 6f 70 65 6e 20 24 66 5d 0a 20 20 20 20 20   [open $f].     
a180: 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 5b 72   set contents [r
a190: 65 61 64 20 24 66 64 5d 0a 20 20 20 20 20 20 63  ead $fd].      c
a1a0: 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 7d 0a 20  lose $fd.    }. 
a1b0: 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20     set contents 
a1c0: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27  [string map {' '
a1d0: 27 7d 20 24 63 6f 6e 74 65 6e 74 73 5d 0a 20 20  '} $contents].  
a1e0: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e    append sql "IN
a1f0: 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61  SERT INTO ${data
a200: 62 61 73 65 7d 2e 66 69 6c 65 20 56 41 4c 55 45  base}.file VALUE
a210: 53 28 27 24 66 27 2c 20 27 24 63 6f 6e 74 65 6e  S('$f', '$conten
a220: 74 73 27 29 3b 5c 6e 22 0a 20 20 7d 0a 0a 20 20  ts');\n".  }..  
a230: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66 69  set fd [open $fi
a240: 6c 65 6e 61 6d 65 20 77 5d 0a 20 20 70 75 74 73  lename w].  puts
a250: 20 24 66 64 20 22 42 45 47 49 4e 3b 20 24 7b 74   $fd "BEGIN; ${t
a260: 62 6c 7d 24 7b 74 62 6c 32 7d 24 7b 74 62 6c 33  bl}${tbl2}${tbl3
a270: 7d 24 7b 73 71 6c 7d 20 3b 20 43 4f 4d 4d 49 54  }${sql} ; COMMIT
a280: 3b 22 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 7d  ;".  close $fd.}
a290: 0a 0a 23 20 44 72 6f 70 20 61 6c 6c 20 74 61 62  ..# Drop all tab
a2a0: 6c 65 73 20 69 6e 20 64 61 74 61 62 61 73 65 20  les in database 
a2b0: 5b 64 62 5d 0a 70 72 6f 63 20 64 72 6f 70 5f 61  [db].proc drop_a
a2c0: 6c 6c 5f 74 61 62 6c 65 73 20 7b 7b 64 62 20 64  ll_tables {{db d
a2d0: 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61 62 6c  b}} {.  ifcapabl
a2e0: 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65 69  e trigger&&forei
a2f0: 67 6e 6b 65 79 20 7b 0a 20 20 20 20 73 65 74 20  gnkey {.    set 
a300: 70 6b 20 5b 24 64 62 20 6f 6e 65 20 22 50 52 41  pk [$db one "PRA
a310: 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73  GMA foreign_keys
a320: 22 5d 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20  "].    $db eval 
a330: 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f  "PRAGMA foreign_
a340: 6b 65 79 73 20 3d 20 4f 46 46 22 0a 20 20 7d 0a  keys = OFF".  }.
a350: 20 20 66 6f 72 65 61 63 68 20 7b 69 64 78 20 6e    foreach {idx n
a360: 61 6d 65 20 66 69 6c 65 7d 20 5b 64 62 20 65 76  ame file} [db ev
a370: 61 6c 20 7b 50 52 41 47 4d 41 20 64 61 74 61 62  al {PRAGMA datab
a380: 61 73 65 5f 6c 69 73 74 7d 5d 20 7b 0a 20 20 20  ase_list}] {.   
a390: 20 69 66 20 7b 24 69 64 78 3d 3d 31 7d 20 7b 0a   if {$idx==1} {.
a3a0: 20 20 20 20 20 20 73 65 74 20 6d 61 73 74 65 72        set master
a3b0: 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73   sqlite_temp_mas
a3c0: 74 65 72 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  ter.    } else {
a3d0: 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74 65  .      set maste
a3e0: 72 20 24 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d  r $name.sqlite_m
a3f0: 61 73 74 65 72 0a 20 20 20 20 7d 0a 20 20 20 20  aster.    }.    
a400: 66 6f 72 65 61 63 68 20 7b 74 20 74 79 70 65 7d  foreach {t type}
a410: 20 5b 24 64 62 20 65 76 61 6c 20 22 0a 20 20 20   [$db eval ".   
a420: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20     SELECT name, 
a430: 74 79 70 65 20 46 52 4f 4d 20 24 6d 61 73 74 65  type FROM $maste
a440: 72 0a 20 20 20 20 20 20 57 48 45 52 45 20 74 79  r.      WHERE ty
a450: 70 65 20 49 4e 28 27 74 61 62 6c 65 27 2c 20 27  pe IN('table', '
a460: 76 69 65 77 27 29 20 41 4e 44 20 6e 61 6d 65 20  view') AND name 
a470: 4e 4f 54 20 4c 49 4b 45 20 27 73 71 6c 69 74 65  NOT LIKE 'sqlite
a480: 58 5f 25 27 20 45 53 43 41 50 45 20 27 58 27 0a  X_%' ESCAPE 'X'.
a490: 20 20 20 20 22 5d 20 7b 0a 20 20 20 20 20 20 24      "] {.      $
a4a0: 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20 24 74  db eval "DROP $t
a4b0: 79 70 65 20 5c 22 24 74 5c 22 22 0a 20 20 20 20  ype \"$t\"".    
a4c0: 7d 0a 20 20 7d 0a 20 20 69 66 63 61 70 61 62 6c  }.  }.  ifcapabl
a4d0: 65 20 74 72 69 67 67 65 72 26 26 66 6f 72 65 69  e trigger&&forei
a4e0: 67 6e 6b 65 79 20 7b 0a 20 20 20 20 24 64 62 20  gnkey {.    $db 
a4f0: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66 6f 72  eval "PRAGMA for
a500: 65 69 67 6e 5f 6b 65 79 73 20 3d 20 24 70 6b 22  eign_keys = $pk"
a510: 0a 20 20 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  .  }.}..#-------
a520: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a530: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a540: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a550: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
a560: 2d 2d 0a 23 20 49 66 20 61 20 74 65 73 74 20 73  --.# If a test s
a570: 63 72 69 70 74 20 69 73 20 65 78 65 63 75 74 65  cript is execute
a580: 64 20 77 69 74 68 20 67 6c 6f 62 61 6c 20 76 61  d with global va
a590: 72 69 61 62 6c 65 20 24 3a 3a 47 28 70 65 72 6d  riable $::G(perm
a5a0: 3a 6e 61 6d 65 29 20 73 65 74 20 74 6f 0a 23 20  :name) set to.# 
a5b0: 22 77 61 6c 22 2c 20 74 68 65 6e 20 74 68 65 20  "wal", then the 
a5c0: 74 65 73 74 73 20 61 72 65 20 72 75 6e 20 69 6e  tests are run in
a5d0: 20 57 41 4c 20 6d 6f 64 65 2e 20 4f 74 68 65 72   WAL mode. Other
a5e0: 77 69 73 65 2c 20 74 68 65 79 20 73 68 6f 75 6c  wise, they shoul
a5f0: 64 20 62 65 20 72 75 6e 20 0a 23 20 69 6e 20 72  d be run .# in r
a600: 6f 6c 6c 62 61 63 6b 20 6d 6f 64 65 2e 20 54 68  ollback mode. Th
a610: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 54 63 6c 20  e following Tcl 
a620: 70 72 6f 63 73 20 61 72 65 20 75 73 65 64 20 74  procs are used t
a630: 6f 20 6d 61 6b 65 20 74 68 69 73 20 6c 65 73 73  o make this less
a640: 20 0a 23 20 69 6e 74 72 75 73 69 76 65 3a 0a 23   .# intrusive:.#
a650: 0a 23 20 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75  .#   wal_set_jou
a660: 72 6e 61 6c 5f 6d 6f 64 65 20 3f 44 42 3f 0a 23  rnal_mode ?DB?.#
a670: 0a 23 20 20 20 20 20 49 66 20 72 75 6e 6e 69 6e  .#     If runnin
a680: 67 20 61 20 57 41 4c 20 74 65 73 74 2c 20 65 78  g a WAL test, ex
a690: 65 63 75 74 65 20 22 50 52 41 47 4d 41 20 6a 6f  ecute "PRAGMA jo
a6a0: 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 77 61 6c  urnal_mode = wal
a6b0: 22 20 75 73 69 6e 67 0a 23 20 20 20 20 20 63 6f  " using.#     co
a6c0: 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20  nnection handle 
a6d0: 44 42 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74  DB. Otherwise, t
a6e0: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61  his command is a
a6f0: 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61   no-op..#.#   wa
a700: 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f  l_check_journal_
a710: 6d 6f 64 65 20 54 45 53 54 4e 41 4d 45 20 3f 44  mode TESTNAME ?D
a720: 42 3f 0a 23 0a 23 20 20 20 20 20 49 66 20 72 75  B?.#.#     If ru
a730: 6e 6e 69 6e 67 20 61 20 57 41 4c 20 74 65 73 74  nning a WAL test
a740: 2c 20 65 78 65 63 75 74 65 20 61 20 74 65 73 74  , execute a test
a750: 73 20 63 61 73 65 20 74 68 61 74 20 66 61 69 6c  s case that fail
a760: 73 20 69 66 20 74 68 65 20 6d 61 69 6e 0a 23 20  s if the main.# 
a770: 20 20 20 20 64 61 74 61 62 61 73 65 20 66 6f 72      database for
a780: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64   connection hand
a790: 6c 65 20 44 42 20 69 73 20 6e 6f 74 20 63 75 72  le DB is not cur
a7a0: 72 65 6e 74 6c 79 20 61 20 57 41 4c 20 64 61 74  rently a WAL dat
a7b0: 61 62 61 73 65 2e 0a 23 20 20 20 20 20 4f 74 68  abase..#     Oth
a7c0: 65 72 77 69 73 65 20 28 69 66 20 6e 6f 74 20 72  erwise (if not r
a7d0: 75 6e 6e 69 6e 67 20 61 20 57 41 4c 20 70 65 72  unning a WAL per
a7e0: 6d 75 74 61 74 69 6f 6e 29 20 74 68 69 73 20 69  mutation) this i
a7f0: 73 20 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20  s a no-op..#.#  
a800: 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65   wal_is_wal_mode
a810: 0a 23 20 20 20 0a 23 20 20 20 20 20 52 65 74 75  .#   .#     Retu
a820: 72 6e 73 20 74 72 75 65 20 69 66 20 74 68 69 73  rns true if this
a830: 20 74 65 73 74 20 73 68 6f 75 6c 64 20 62 65 20   test should be 
a840: 72 75 6e 20 69 6e 20 57 41 4c 20 6d 6f 64 65 2e  run in WAL mode.
a850: 20 46 61 6c 73 65 20 6f 74 68 65 72 77 69 73 65   False otherwise
a860: 2e 0a 23 20 0a 70 72 6f 63 20 77 61 6c 5f 69 73  ..# .proc wal_is
a870: 5f 77 61 6c 5f 6d 6f 64 65 20 7b 7d 20 7b 0a 20  _wal_mode {} {. 
a880: 20 65 78 70 72 20 7b 5b 70 65 72 6d 75 74 61 74   expr {[permutat
a890: 69 6f 6e 5d 20 65 71 20 22 77 61 6c 22 7d 0a 7d  ion] eq "wal"}.}
a8a0: 0a 70 72 6f 63 20 77 61 6c 5f 73 65 74 5f 6a 6f  .proc wal_set_jo
a8b0: 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b 7b 64 62 20  urnal_mode {{db 
a8c0: 64 62 7d 7d 20 7b 0a 20 20 69 66 20 7b 20 5b 77  db}} {.  if { [w
a8d0: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d 20  al_is_wal_mode] 
a8e0: 7d 20 7b 0a 20 20 20 20 24 64 62 20 65 76 61 6c  } {.    $db eval
a8f0: 20 22 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c   "PRAGMA journal
a900: 5f 6d 6f 64 65 20 3d 20 57 41 4c 22 0a 20 20 7d  _mode = WAL".  }
a910: 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f 63 68 65 63  .}.proc wal_chec
a920: 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b  k_journal_mode {
a930: 74 65 73 74 6e 61 6d 65 20 7b 64 62 20 64 62 7d  testname {db db}
a940: 7d 20 7b 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f  } {.  if { [wal_
a950: 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b  is_wal_mode] } {
a960: 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20 7b 20  .    $db eval { 
a970: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73 71  SELECT * FROM sq
a980: 6c 69 74 65 5f 6d 61 73 74 65 72 20 7d 0a 20 20  lite_master }.  
a990: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
a9a0: 61 6d 65 20 5b 6c 69 73 74 20 24 64 62 20 65 76  ame [list $db ev
a9b0: 61 6c 20 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e  al "PRAGMA main.
a9c0: 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 22 5d 20 7b  journal_mode"] {
a9d0: 77 61 6c 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63  wal}.  }.}..proc
a9e0: 20 70 65 72 6d 75 74 61 74 69 6f 6e 20 7b 7d 20   permutation {} 
a9f0: 7b 0a 20 20 73 65 74 20 70 65 72 6d 20 22 22 0a  {.  set perm "".
aa00: 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 65 72    catch {set per
aa10: 6d 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65  m $::G(perm:name
aa20: 29 7d 0a 20 20 73 65 74 20 70 65 72 6d 0a 7d 0a  )}.  set perm.}.
aa30: 70 72 6f 63 20 70 72 65 73 71 6c 20 7b 7d 20 7b  proc presql {} {
aa40: 0a 20 20 73 65 74 20 70 72 65 73 71 6c 20 22 22  .  set presql ""
aa50: 0a 20 20 63 61 74 63 68 20 7b 73 65 74 20 70 72  .  catch {set pr
aa60: 65 73 71 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70  esql $::G(perm:p
aa70: 72 65 73 71 6c 29 7d 0a 20 20 73 65 74 20 70 72  resql)}.  set pr
aa80: 65 73 71 6c 0a 7d 0a 0a 70 72 6f 63 20 77 61 6c  esql.}..proc wal
aa90: 5f 69 73 5f 6f 6b 20 7b 7d 20 7b 0a 20 20 69 66  _is_ok {} {.  if
aaa0: 20 7b 20 5b 66 6f 72 63 65 64 5f 70 72 6f 78 79   { [forced_proxy
aab0: 5f 6c 6f 63 6b 69 6e 67 5d 20 7d 20 7b 0a 20 20  _locking] } {.  
aac0: 20 20 72 65 74 75 72 6e 20 31 0a 20 20 7d 0a 20    return 1.  }. 
aad0: 20 69 66 20 7b 20 21 5b 70 61 74 68 5f 69 73 5f   if { ![path_is_
aae0: 6c 6f 63 61 6c 20 22 2e 22 5d 20 7d 20 7b 0a 20  local "."] } {. 
aaf0: 20 20 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a     return 0.  }.
ab00: 20 20 69 66 20 7b 20 5b 70 61 74 68 5f 69 73 5f    if { [path_is_
ab10: 64 6f 73 20 22 2e 22 5d 20 7d 20 7b 0a 20 20 20  dos "."] } {.   
ab20: 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a 20 20   return 0.  }.  
ab30: 72 65 74 75 72 6e 20 31 0a 7d 0a 0a 23 2d 2d 2d  return 1.}..#---
ab40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ab50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ab60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ab70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ab80: 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72 6f 63 20 73 6c  ------.#.proc sl
ab90: 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70 74 20  ave_test_script 
aba0: 7b 73 63 72 69 70 74 7d 20 7b 0a 0a 20 20 23 20  {script} {..  # 
abb0: 43 72 65 61 74 65 20 74 68 65 20 69 6e 74 65 72  Create the inter
abc0: 70 72 65 74 65 72 20 75 73 65 64 20 74 6f 20 72  preter used to r
abd0: 75 6e 20 74 68 65 20 74 65 73 74 20 73 63 72 69  un the test scri
abe0: 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 63 72 65  pt..  interp cre
abf0: 61 74 65 20 74 69 6e 74 65 72 70 0a 0a 20 20 23  ate tinterp..  #
ac00: 20 50 6f 70 75 6c 61 74 65 20 73 6f 6d 65 20 67   Populate some g
ac10: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
ac20: 74 68 61 74 20 74 65 73 74 65 72 2e 74 63 6c 20  that tester.tcl 
ac30: 65 78 70 65 63 74 73 20 74 6f 20 73 65 65 2e 0a  expects to see..
ac40: 20 20 66 6f 72 65 61 63 68 20 7b 76 61 72 20 76    foreach {var v
ac50: 61 6c 75 65 7d 20 5b 6c 69 73 74 20 20 20 20 20  alue} [list     
ac60: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 3a           \.    :
ac70: 3a 61 72 67 76 30 20 24 3a 3a 61 72 67 76 30 20  :argv0 $::argv0 
ac80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ac90: 20 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72 67 76      \.    ::argv
aca0: 20 20 7b 7d 20 20 20 20 20 20 20 20 20 20 20 20    {}            
acb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
acc0: 0a 20 20 20 20 3a 3a 53 4c 41 56 45 20 31 20 20  .    ::SLAVE 1  
acd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ace0: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 5d 20            \.  ] 
acf0: 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 65 76 61  {.    interp eva
ad00: 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73 74 20  l tinterp [list 
ad10: 73 65 74 20 24 76 61 72 20 24 76 61 6c 75 65 5d  set $var $value]
ad20: 0a 20 20 7d 0a 0a 20 20 23 20 54 68 65 20 61 6c  .  }..  # The al
ad30: 69 61 73 20 75 73 65 64 20 74 6f 20 61 63 63 65  ias used to acce
ad40: 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20 74 65  ss the global te
ad50: 73 74 20 63 6f 75 6e 74 65 72 73 2e 0a 20 20 74  st counters..  t
ad60: 69 6e 74 65 72 70 20 61 6c 69 61 73 20 73 65 74  interp alias set
ad70: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 73 65  _test_counter se
ad80: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 0a 0a  t_test_counter..
ad90: 20 20 23 20 53 65 74 20 75 70 20 74 68 65 20 3a    # Set up the :
ada0: 3a 63 6d 64 6c 69 6e 65 61 72 67 20 61 72 72 61  :cmdlinearg arra
adb0: 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65 2e 0a  y in the slave..
adc0: 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69    interp eval ti
add0: 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72 72 61  nterp [list arra
ade0: 79 20 73 65 74 20 3a 3a 63 6d 64 6c 69 6e 65 61  y set ::cmdlinea
adf0: 72 67 20 5b 61 72 72 61 79 20 67 65 74 20 3a 3a  rg [array get ::
ae00: 63 6d 64 6c 69 6e 65 61 72 67 5d 5d 0a 0a 20 20  cmdlinearg]]..  
ae10: 23 20 53 65 74 20 75 70 20 74 68 65 20 3a 3a 47  # Set up the ::G
ae20: 20 61 72 72 61 79 20 69 6e 20 74 68 65 20 73 6c   array in the sl
ae30: 61 76 65 2e 0a 20 20 69 6e 74 65 72 70 20 65 76  ave..  interp ev
ae40: 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73 74  al tinterp [list
ae50: 20 61 72 72 61 79 20 73 65 74 20 3a 3a 47 20 5b   array set ::G [
ae60: 61 72 72 61 79 20 67 65 74 20 3a 3a 47 5d 5d 0a  array get ::G]].
ae70: 0a 20 20 23 20 4c 6f 61 64 20 74 68 65 20 76 61  .  # Load the va
ae80: 72 69 6f 75 73 20 74 65 73 74 20 69 6e 74 65 72  rious test inter
ae90: 66 61 63 65 73 20 69 6d 70 6c 65 6d 65 6e 74 65  faces implemente
aea0: 64 20 69 6e 20 43 2e 0a 20 20 6c 6f 61 64 5f 74  d in C..  load_t
aeb0: 65 73 74 66 69 78 74 75 72 65 5f 65 78 74 65 6e  estfixture_exten
aec0: 73 69 6f 6e 73 20 74 69 6e 74 65 72 70 0a 0a 20  sions tinterp.. 
aed0: 20 23 20 52 75 6e 20 74 68 65 20 74 65 73 74 20   # Run the test 
aee0: 73 63 72 69 70 74 2e 0a 20 20 69 6e 74 65 72 70  script..  interp
aef0: 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20 24 73   eval tinterp $s
af00: 63 72 69 70 74 0a 0a 20 20 23 20 43 68 65 63 6b  cript..  # Check
af10: 20 69 66 20 74 68 65 20 69 6e 74 65 72 70 72 65   if the interpre
af20: 74 65 72 20 63 61 6c 6c 20 5b 72 75 6e 5f 74 68  ter call [run_th
af30: 72 65 61 64 5f 74 65 73 74 73 5d 0a 20 20 69 66  read_tests].  if
af40: 20 7b 20 5b 69 6e 74 65 72 70 20 65 76 61 6c 20   { [interp eval 
af50: 74 69 6e 74 65 72 70 20 7b 69 6e 66 6f 20 65 78  tinterp {info ex
af60: 69 73 74 73 20 3a 3a 72 75 6e 5f 74 68 72 65 61  ists ::run_threa
af70: 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 7d 5d  d_tests_called}]
af80: 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 72   } {.    set ::r
af90: 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f  un_thread_tests_
afa0: 63 61 6c 6c 65 64 20 31 0a 20 20 7d 0a 0a 20 20  called 1.  }..  
afb0: 23 20 44 65 6c 65 74 65 20 74 68 65 20 69 6e 74  # Delete the int
afc0: 65 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f  erpreter used to
afd0: 20 72 75 6e 20 74 68 65 20 74 65 73 74 20 73 63   run the test sc
afe0: 72 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 64  ript..  interp d
aff0: 65 6c 65 74 65 20 74 69 6e 74 65 72 70 0a 7d 0a  elete tinterp.}.
b000: 0a 70 72 6f 63 20 73 6c 61 76 65 5f 74 65 73 74  .proc slave_test
b010: 5f 66 69 6c 65 20 7b 7a 46 69 6c 65 7d 20 7b 0a  _file {zFile} {.
b020: 20 20 73 65 74 20 74 61 69 6c 20 5b 66 69 6c 65    set tail [file
b030: 20 74 61 69 6c 20 24 7a 46 69 6c 65 5d 0a 0a 20   tail $zFile].. 
b040: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
b050: 73 20 3a 3a 47 28 73 74 61 72 74 3a 70 65 72 6d  s ::G(start:perm
b060: 75 74 61 74 69 6f 6e 29 5d 7d 20 7b 0a 20 20 20  utation)]} {.   
b070: 20 69 66 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f   if {[permutatio
b080: 6e 5d 20 21 3d 20 24 3a 3a 47 28 73 74 61 72 74  n] != $::G(start
b090: 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 7d 20 72  :permutation)} r
b0a0: 65 74 75 72 6e 0a 20 20 20 20 75 6e 73 65 74 20  eturn.    unset 
b0b0: 3a 3a 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74  ::G(start:permut
b0c0: 61 74 69 6f 6e 29 0a 20 20 7d 0a 20 20 69 66 20  ation).  }.  if 
b0d0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
b0e0: 47 28 73 74 61 72 74 3a 66 69 6c 65 29 5d 7d 20  G(start:file)]} 
b0f0: 7b 0a 20 20 20 20 69 66 20 7b 24 74 61 69 6c 20  {.    if {$tail 
b100: 21 3d 20 24 3a 3a 47 28 73 74 61 72 74 3a 66 69  != $::G(start:fi
b110: 6c 65 29 20 26 26 20 24 74 61 69 6c 21 3d 22 24  le) && $tail!="$
b120: 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 2e  ::G(start:file).
b130: 74 65 73 74 22 7d 20 72 65 74 75 72 6e 0a 20 20  test"} return.  
b140: 20 20 75 6e 73 65 74 20 3a 3a 47 28 73 74 61 72    unset ::G(star
b150: 74 3a 66 69 6c 65 29 0a 20 20 7d 0a 0a 20 20 23  t:file).  }..  #
b160: 20 52 65 6d 65 6d 62 65 72 20 74 68 65 20 76 61   Remember the va
b170: 6c 75 65 20 6f 66 20 74 68 65 20 73 68 61 72 65  lue of the share
b180: 64 2d 63 61 63 68 65 20 73 65 74 74 69 6e 67 2e  d-cache setting.
b190: 20 53 6f 20 74 68 61 74 20 69 74 20 69 73 20 70   So that it is p
b1a0: 6f 73 73 69 62 6c 65 0a 20 20 23 20 74 6f 20 63  ossible.  # to c
b1b0: 68 65 63 6b 20 61 66 74 65 72 77 61 72 64 73 20  heck afterwards 
b1c0: 74 68 61 74 20 69 74 20 77 61 73 20 6e 6f 74 20  that it was not 
b1d0: 6d 6f 64 69 66 69 65 64 20 62 79 20 74 68 65 20  modified by the 
b1e0: 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20 23  test script..  #
b1f0: 0a 20 20 69 66 63 61 70 61 62 6c 65 20 73 68 61  .  ifcapable sha
b200: 72 65 64 5f 63 61 63 68 65 20 7b 20 73 65 74 20  red_cache { set 
b210: 73 63 73 20 5b 73 71 6c 69 74 65 33 5f 65 6e 61  scs [sqlite3_ena
b220: 62 6c 65 5f 73 68 61 72 65 64 5f 63 61 63 68 65  ble_shared_cache
b230: 5d 20 7d 0a 0a 20 20 23 20 52 75 6e 20 74 68 65  ] }..  # Run the
b240: 20 74 65 73 74 20 73 63 72 69 70 74 20 69 6e 20   test script in 
b250: 61 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65  a slave interpre
b260: 74 65 72 2e 0a 20 20 23 0a 20 20 75 6e 73 65 74  ter..  #.  unset
b270: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 3a 3a 72   -nocomplain ::r
b280: 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f  un_thread_tests_
b290: 63 61 6c 6c 65 64 0a 20 20 72 65 73 65 74 5f 70  called.  reset_p
b2a0: 72 6e 67 5f 73 74 61 74 65 0a 20 20 73 65 74 20  rng_state.  set 
b2b0: 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  ::sqlite_open_fi
b2c0: 6c 65 5f 63 6f 75 6e 74 20 30 0a 20 20 73 65 74  le_count 0.  set
b2d0: 20 74 69 6d 65 20 5b 74 69 6d 65 20 7b 20 73 6c   time [time { sl
b2e0: 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70 74 20  ave_test_script 
b2f0: 5b 6c 69 73 74 20 73 6f 75 72 63 65 20 24 7a 46  [list source $zF
b300: 69 6c 65 5d 20 7d 5d 0a 20 20 73 65 74 20 6d 73  ile] }].  set ms
b310: 20 5b 65 78 70 72 20 5b 6c 69 6e 64 65 78 20 24   [expr [lindex $
b320: 74 69 6d 65 20 30 5d 20 2f 20 31 30 30 30 5d 0a  time 0] / 1000].
b330: 0a 20 20 23 20 54 65 73 74 20 74 68 61 74 20 61  .  # Test that a
b340: 6c 6c 20 66 69 6c 65 73 20 6f 70 65 6e 65 64 20  ll files opened 
b350: 62 79 20 74 68 65 20 74 65 73 74 20 73 63 72 69  by the test scri
b360: 70 74 20 77 65 72 65 20 63 6c 6f 73 65 64 2e 20  pt were closed. 
b370: 4f 6d 69 74 20 74 68 69 73 0a 20 20 23 20 69 66  Omit this.  # if
b380: 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74   the test script
b390: 20 68 61 73 20 22 74 68 72 65 61 64 22 20 69 6e   has "thread" in
b3a0: 20 69 74 73 20 6e 61 6d 65 2e 20 54 68 65 20 6f   its name. The o
b3b0: 70 65 6e 20 66 69 6c 65 20 63 6f 75 6e 74 65 72  pen file counter
b3c0: 0a 20 20 23 20 69 73 20 6e 6f 74 20 74 68 72 65  .  # is not thre
b3d0: 61 64 2d 73 61 66 65 2e 0a 20 20 23 0a 20 20 69  ad-safe..  #.  i
b3e0: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
b3f0: 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73  ::run_thread_tes
b400: 74 73 5f 63 61 6c 6c 65 64 5d 3d 3d 30 7d 20 7b  ts_called]==0} {
b410: 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 7b 74  .    do_test ${t
b420: 61 69 6c 7d 2d 63 6c 6f 73 65 61 6c 6c 66 69 6c  ail}-closeallfil
b430: 65 73 20 7b 20 65 78 70 72 20 7b 24 3a 3a 73 71  es { expr {$::sq
b440: 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63  lite_open_file_c
b450: 6f 75 6e 74 3e 30 7d 20 7d 20 7b 30 7d 0a 20 20  ount>0} } {0}.  
b460: 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65  }.  set ::sqlite
b470: 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74  _open_file_count
b480: 20 30 0a 0a 20 20 23 20 54 65 73 74 20 74 68 61   0..  # Test tha
b490: 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 22 73 68  t the global "sh
b4a0: 61 72 65 64 2d 63 61 63 68 65 22 20 73 65 74 74  ared-cache" sett
b4b0: 69 6e 67 20 77 61 73 20 6e 6f 74 20 61 6c 74 65  ing was not alte
b4c0: 72 65 64 20 62 79 20 0a 20 20 23 20 74 68 65 20  red by .  # the 
b4d0: 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20 23  test script..  #
b4e0: 0a 20 20 69 66 63 61 70 61 62 6c 65 20 73 68 61  .  ifcapable sha
b4f0: 72 65 64 5f 63 61 63 68 65 20 7b 20 0a 20 20 20  red_cache { .   
b500: 20 73 65 74 20 72 65 73 20 5b 65 78 70 72 20 7b   set res [expr {
b510: 5b 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f  [sqlite3_enable_
b520: 73 68 61 72 65 64 5f 63 61 63 68 65 5d 20 3d 3d  shared_cache] ==
b530: 20 24 73 63 73 7d 5d 0a 20 20 20 20 64 6f 5f 74   $scs}].    do_t
b540: 65 73 74 20 24 7b 74 61 69 6c 7d 2d 73 68 61 72  est ${tail}-shar
b550: 65 64 63 61 63 68 65 73 65 74 74 69 6e 67 20 5b  edcachesetting [
b560: 6c 69 73 74 20 73 65 74 20 7b 7d 20 24 72 65 73  list set {} $res
b570: 5d 20 31 0a 20 20 7d 0a 0a 20 20 23 20 41 64 64  ] 1.  }..  # Add
b580: 20 73 6f 6d 65 20 69 6e 66 6f 20 74 6f 20 74 68   some info to th
b590: 65 20 6f 75 74 70 75 74 2e 0a 20 20 23 0a 20 20  e output..  #.  
b5a0: 70 75 74 73 20 22 54 69 6d 65 3a 20 24 74 61 69  puts "Time: $tai
b5b0: 6c 20 24 6d 73 20 6d 73 22 0a 20 20 73 68 6f 77  l $ms ms".  show
b5c0: 5f 6d 65 6d 73 74 61 74 73 0a 7d 0a 0a 23 20 4f  _memstats.}..# O
b5d0: 70 65 6e 20 61 20 6e 65 77 20 63 6f 6e 6e 65 63  pen a new connec
b5e0: 74 69 6f 6e 20 6f 6e 20 64 61 74 61 62 61 73 65  tion on database
b5f0: 20 74 65 73 74 2e 64 62 20 61 6e 64 20 65 78 65   test.db and exe
b600: 63 75 74 65 20 74 68 65 20 53 51 4c 20 73 63 72  cute the SQL scr
b610: 69 70 74 0a 23 20 73 75 70 70 6c 69 65 64 20 61  ipt.# supplied a
b620: 73 20 61 6e 20 61 72 67 75 6d 65 6e 74 2e 20 42  s an argument. B
b630: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c  efore returning,
b640: 20 63 6c 6f 73 65 20 74 68 65 20 6e 65 77 20 63   close the new c
b650: 6f 6e 65 63 74 69 6f 6e 20 61 6e 64 0a 23 20 72  onection and.# r
b660: 65 73 74 6f 72 65 20 74 68 65 20 34 20 62 79 74  estore the 4 byt
b670: 65 20 66 69 65 6c 64 73 20 73 74 61 72 74 69 6e  e fields startin
b680: 67 20 61 74 20 68 65 61 64 65 72 20 6f 66 66 73  g at header offs
b690: 65 74 73 20 32 38 2c 20 39 32 20 61 6e 64 20 39  ets 28, 92 and 9
b6a0: 36 0a 23 20 74 6f 20 74 68 65 20 76 61 6c 75 65  6.# to the value
b6b0: 73 20 74 68 65 79 20 68 65 6c 64 20 62 65 66 6f  s they held befo
b6c0: 72 65 20 74 68 65 20 53 51 4c 20 77 61 73 20 65  re the SQL was e
b6d0: 78 65 63 75 74 65 64 2e 20 54 68 69 73 20 73 69  xecuted. This si
b6e0: 6d 75 6c 61 74 65 73 0a 23 20 61 20 77 72 69 74  mulates.# a writ
b6f0: 65 20 62 79 20 61 20 70 72 65 2d 33 2e 37 2e 30  e by a pre-3.7.0
b700: 20 63 6c 69 65 6e 74 2e 0a 23 0a 70 72 6f 63 20   client..#.proc 
b710: 73 71 6c 33 36 32 33 31 20 7b 73 71 6c 7d 20 7b  sql36231 {sql} {
b720: 0a 20 20 73 65 74 20 42 20 5b 68 65 78 69 6f 5f  .  set B [hexio_
b730: 72 65 61 64 20 74 65 73 74 2e 64 62 20 39 32 20  read test.db 92 
b740: 38 5d 0a 20 20 73 65 74 20 41 20 5b 68 65 78 69  8].  set A [hexi
b750: 6f 5f 72 65 61 64 20 74 65 73 74 2e 64 62 20 32  o_read test.db 2
b760: 38 20 34 5d 0a 20 20 73 71 6c 69 74 65 33 20 64  8 4].  sqlite3 d
b770: 62 33 36 32 33 31 20 74 65 73 74 2e 64 62 0a 20  b36231 test.db. 
b780: 20 63 61 74 63 68 20 7b 20 64 62 33 36 32 33 31   catch { db36231
b790: 20 66 75 6e 63 20 61 5f 73 74 72 69 6e 67 20 61   func a_string a
b7a0: 5f 73 74 72 69 6e 67 20 7d 0a 20 20 65 78 65 63  _string }.  exec
b7b0: 73 71 6c 20 24 73 71 6c 20 64 62 33 36 32 33 31  sql $sql db36231
b7c0: 0a 20 20 64 62 33 36 32 33 31 20 63 6c 6f 73 65  .  db36231 close
b7d0: 0a 20 20 68 65 78 69 6f 5f 77 72 69 74 65 20 74  .  hexio_write t
b7e0: 65 73 74 2e 64 62 20 32 38 20 24 41 0a 20 20 68  est.db 28 $A.  h
b7f0: 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73 74 2e  exio_write test.
b800: 64 62 20 39 32 20 24 42 0a 20 20 72 65 74 75 72  db 92 $B.  retur
b810: 6e 20 22 22 0a 7d 0a 0a 70 72 6f 63 20 64 62 5f  n "".}..proc db_
b820: 73 61 76 65 20 7b 7d 20 7b 0a 20 20 66 6f 72 65  save {} {.  fore
b830: 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ach f [glob -noc
b840: 6f 6d 70 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e  omplain sv_test.
b850: 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c 65  db*] { forcedele
b860: 74 65 20 24 66 20 7d 0a 20 20 66 6f 72 65 61 63  te $f }.  foreac
b870: 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
b880: 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20  plain test.db*] 
b890: 7b 0a 20 20 20 20 73 65 74 20 66 32 20 22 73 76  {.    set f2 "sv
b8a0: 5f 24 66 22 0a 20 20 20 20 66 6f 72 63 65 63 6f  _$f".    forceco
b8b0: 70 79 20 24 66 20 24 66 32 0a 20 20 7d 0a 7d 0a  py $f $f2.  }.}.
b8c0: 70 72 6f 63 20 64 62 5f 73 61 76 65 5f 61 6e 64  proc db_save_and
b8d0: 5f 63 6c 6f 73 65 20 7b 7d 20 7b 0a 20 20 64 62  _close {} {.  db
b8e0: 5f 73 61 76 65 0a 20 20 63 61 74 63 68 20 7b 20  _save.  catch { 
b8f0: 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20 72 65 74  db close }.  ret
b900: 75 72 6e 20 22 22 0a 7d 0a 70 72 6f 63 20 64 62  urn "".}.proc db
b910: 5f 72 65 73 74 6f 72 65 20 7b 7d 20 7b 0a 20 20  _restore {} {.  
b920: 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20  foreach f [glob 
b930: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74  -nocomplain test
b940: 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65 6c  .db*] { forcedel
b950: 65 74 65 20 24 66 20 7d 0a 20 20 66 6f 72 65 61  ete $f }.  forea
b960: 63 68 20 66 32 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ch f2 [glob -noc
b970: 6f 6d 70 6c 61 69 6e 20 73 76 5f 74 65 73 74 2e  omplain sv_test.
b980: 64 62 2a 5d 20 7b 0a 20 20 20 20 73 65 74 20 66  db*] {.    set f
b990: 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24   [string range $
b9a0: 66 32 20 33 20 65 6e 64 5d 0a 20 20 20 20 66 6f  f2 3 end].    fo
b9b0: 72 63 65 63 6f 70 79 20 24 66 32 20 24 66 0a 20  rcecopy $f2 $f. 
b9c0: 20 7d 0a 7d 0a 70 72 6f 63 20 64 62 5f 72 65 73   }.}.proc db_res
b9d0: 74 6f 72 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20  tore_and_reopen 
b9e0: 7b 7b 64 62 66 69 6c 65 20 74 65 73 74 2e 64 62  {{dbfile test.db
b9f0: 7d 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64  }} {.  catch { d
ba00: 62 20 63 6c 6f 73 65 20 7d 0a 20 20 64 62 5f 72  b close }.  db_r
ba10: 65 73 74 6f 72 65 0a 20 20 73 71 6c 69 74 65 33  estore.  sqlite3
ba20: 20 64 62 20 24 64 62 66 69 6c 65 0a 7d 0a 70 72   db $dbfile.}.pr
ba30: 6f 63 20 64 62 5f 64 65 6c 65 74 65 5f 61 6e 64  oc db_delete_and
ba40: 5f 72 65 6f 70 65 6e 20 7b 7b 66 69 6c 65 20 74  _reopen {{file t
ba50: 65 73 74 2e 64 62 7d 7d 20 7b 0a 20 20 63 61 74  est.db}} {.  cat
ba60: 63 68 20 7b 20 64 62 20 63 6c 6f 73 65 20 7d 0a  ch { db close }.
ba70: 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f    foreach f [glo
ba80: 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65  b -nocomplain te
ba90: 73 74 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64  st.db*] { forced
baa0: 65 6c 65 74 65 20 24 66 20 7d 0a 20 20 73 71 6c  elete $f }.  sql
bab0: 69 74 65 33 20 64 62 20 24 66 69 6c 65 0a 7d 0a  ite3 db $file.}.
bac0: 0a 23 20 49 66 20 74 68 65 20 6c 69 62 72 61 72  .# If the librar
bad0: 79 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77 69  y is compiled wi
bae0: 74 68 20 74 68 65 20 53 51 4c 49 54 45 5f 44 45  th the SQLITE_DE
baf0: 46 41 55 4c 54 5f 41 55 54 4f 56 41 43 55 55 4d  FAULT_AUTOVACUUM
bb00: 20 6d 61 63 72 6f 20 73 65 74 0a 23 20 74 6f 20   macro set.# to 
bb10: 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 73  non-zero, then s
bb20: 65 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61  et the global va
bb30: 72 69 61 62 6c 65 20 24 41 55 54 4f 56 41 43 55  riable $AUTOVACU
bb40: 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41 55 54  UM to 1..set AUT
bb50: 4f 56 41 43 55 55 4d 20 24 73 71 6c 69 74 65 5f  OVACUUM $sqlite_
bb60: 6f 70 74 69 6f 6e 73 28 64 65 66 61 75 6c 74 5f  options(default_
bb70: 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a 73 6f 75  autovacuum)..sou
bb80: 72 63 65 20 24 74 65 73 74 64 69 72 2f 74 68 72  rce $testdir/thr
bb90: 65 61 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73  ead_common.tcl.s
bba0: 6f 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d  ource $testdir/m
bbb0: 61 6c 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c  alloc_common.tcl
bbc0: 0a                                               .