/ Hex Artifact Content
Login

Artifact 76222602e59047c6ef119473c7a2ea7c6ee73d09:


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 72 6f 70  M TO.#      drop
0330: 5f 61 6c 6c 5f 74 61 62 6c 65 20 20 20 20 20 20  _all_table      
0340: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 66     ?DB?.#      f
0350: 6f 72 63 65 64 65 6c 65 74 65 20 20 20 20 20 20  orcedelete      
0360: 20 20 20 20 20 20 46 49 4c 45 4e 41 4d 45 0a 23        FILENAME.#
0370: 0a 23 20 54 65 73 74 20 74 68 65 20 63 61 70 61  .# Test the capa
0380: 62 69 6c 69 74 79 20 6f 66 20 74 68 65 20 53 51  bility of the SQ
0390: 4c 69 74 65 20 76 65 72 73 69 6f 6e 20 62 75 69  Lite version bui
03a0: 6c 74 20 69 6e 74 6f 20 74 68 65 20 69 6e 74 65  lt into the inte
03b0: 72 70 72 65 74 65 72 20 74 6f 0a 23 20 64 65 74  rpreter to.# det
03c0: 65 72 6d 69 6e 65 20 69 66 20 61 20 73 70 65 63  ermine if a spec
03d0: 69 66 69 63 20 74 65 73 74 20 63 61 6e 20 62 65  ific test can be
03e0: 20 72 75 6e 3a 0a 23 0a 23 20 20 20 20 20 20 69   run:.#.#      i
03f0: 66 63 61 70 61 62 6c 65 20 20 20 20 20 20 20 20  fcapable        
0400: 20 20 20 20 20 20 45 58 50 52 0a 23 0a 23 20 43        EXPR.#.# C
0410: 61 6c 75 6c 61 74 65 20 63 68 65 63 6b 73 75 6d  alulate checksum
0420: 73 20 62 61 73 65 64 20 6f 6e 20 64 61 74 61 62  s based on datab
0430: 61 73 65 20 63 6f 6e 74 65 6e 74 73 3a 0a 23 0a  ase contents:.#.
0440: 23 20 20 20 20 20 20 64 62 63 6b 73 75 6d 20 20  #      dbcksum  
0450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 44 42                DB
0460: 20 44 42 4e 41 4d 45 0a 23 20 20 20 20 20 20 61   DBNAME.#      a
0470: 6c 6c 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20  llcksum         
0480: 20 20 20 20 20 20 3f 44 42 3f 0a 23 20 20 20 20        ?DB?.#    
0490: 20 20 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20    cksum         
04a0: 20 20 20 20 20 20 20 20 20 3f 44 42 3f 0a 23 0a           ?DB?.#.
04b0: 23 20 43 6f 6d 6d 61 6e 64 73 20 74 6f 20 65 78  # Commands to ex
04c0: 65 63 75 74 65 2f 65 78 70 6c 61 69 6e 20 53 51  ecute/explain SQ
04d0: 4c 20 73 74 61 74 65 6d 65 6e 74 73 3a 0a 23 0a  L statements:.#.
04e0: 23 20 20 20 20 20 20 73 74 65 70 73 71 6c 20 20  #      stepsql  
04f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 44 42                DB
0500: 20 53 51 4c 0a 23 20 20 20 20 20 20 65 78 65 63   SQL.#      exec
0510: 73 71 6c 32 20 20 20 20 20 20 20 20 20 20 20 20  sql2            
0520: 20 20 20 53 51 4c 0a 23 20 20 20 20 20 20 65 78     SQL.#      ex
0530: 70 6c 61 69 6e 5f 6e 6f 5f 74 72 61 63 65 20 20  plain_no_trace  
0540: 20 20 20 20 20 53 51 4c 0a 23 20 20 20 20 20 20       SQL.#      
0550: 65 78 70 6c 61 69 6e 20 20 20 20 20 20 20 20 20  explain         
0560: 20 20 20 20 20 20 20 53 51 4c 20 3f 44 42 3f 0a         SQL ?DB?.
0570: 23 20 20 20 20 20 20 63 61 74 63 68 73 71 6c 20  #      catchsql 
0580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
0590: 4c 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 65 78  L ?DB?.#      ex
05a0: 65 63 73 71 6c 20 20 20 20 20 20 20 20 20 20 20  ecsql           
05b0: 20 20 20 20 20 53 51 4c 20 3f 44 42 3f 0a 23 0a       SQL ?DB?.#.
05c0: 23 20 43 6f 6d 6d 61 6e 64 73 20 74 6f 20 72 75  # Commands to ru
05d0: 6e 20 74 65 73 74 20 63 61 73 65 73 3a 0a 23 0a  n test cases:.#.
05e0: 23 20 20 20 20 20 20 64 6f 5f 69 6f 65 72 72 5f  #      do_ioerr_
05f0: 74 65 73 74 20 20 20 20 20 20 20 20 20 20 54 45  test          TE
0600: 53 54 4e 41 4d 45 20 41 52 47 53 2e 2e 2e 0a 23  STNAME ARGS....#
0610: 20 20 20 20 20 20 63 72 61 73 68 73 71 6c 20 20        crashsql  
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 41 52 47               ARG
0630: 53 2e 2e 2e 0a 23 20 20 20 20 20 20 69 6e 74 65  S....#      inte
0640: 67 72 69 74 79 5f 63 68 65 63 6b 20 20 20 20 20  grity_check     
0650: 20 20 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f     TESTNAME ?DB?
0660: 0a 23 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20  .#      do_test 
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
0680: 45 53 54 4e 41 4d 45 20 53 43 52 49 50 54 20 45  ESTNAME SCRIPT E
0690: 58 50 45 43 54 45 44 0a 23 20 20 20 20 20 20 64  XPECTED.#      d
06a0: 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 20  o_execsql_test  
06b0: 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20 53        TESTNAME S
06c0: 51 4c 20 45 58 50 45 43 54 45 44 0a 23 20 20 20  QL EXPECTED.#   
06d0: 20 20 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74     do_catchsql_t
06e0: 65 73 74 20 20 20 20 20 20 20 54 45 53 54 4e 41  est       TESTNA
06f0: 4d 45 20 53 51 4c 20 45 58 50 45 43 54 45 44 0a  ME SQL EXPECTED.
0700: 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20 70 72 6f  #.# Commands pro
0710: 76 69 64 69 6e 67 20 61 20 6c 6f 77 65 72 20 6c  viding a lower l
0720: 65 76 65 6c 20 69 6e 74 65 72 66 61 63 65 20 74  evel interface t
0730: 6f 20 74 68 65 20 67 6c 6f 62 61 6c 20 74 65 73  o the global tes
0740: 74 20 63 6f 75 6e 74 65 72 73 3a 0a 23 0a 23 20  t counters:.#.# 
0750: 20 20 20 20 20 73 65 74 5f 74 65 73 74 5f 63 6f       set_test_co
0760: 75 6e 74 65 72 20 20 20 20 20 20 20 43 4f 55 4e  unter       COUN
0770: 54 45 52 20 3f 56 41 4c 55 45 3f 0a 23 20 20 20  TER ?VALUE?.#   
0780: 20 20 20 6f 6d 69 74 5f 74 65 73 74 20 20 20 20     omit_test    
0790: 20 20 20 20 20 20 20 20 20 20 54 45 53 54 4e 41            TESTNA
07a0: 4d 45 20 52 45 41 53 4f 4e 0a 23 20 20 20 20 20  ME REASON.#     
07b0: 20 66 61 69 6c 5f 74 65 73 74 20 20 20 20 20 20   fail_test      
07c0: 20 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45          TESTNAME
07d0: 0a 23 20 20 20 20 20 20 69 6e 63 72 5f 6e 74 65  .#      incr_nte
07e0: 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 72  st.#.# Command r
07f0: 75 6e 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66  un at the end of
0800: 20 65 61 63 68 20 74 65 73 74 20 66 69 6c 65 3a   each test file:
0810: 0a 23 0a 23 20 20 20 20 20 20 66 69 6e 69 73 68  .#.#      finish
0820: 5f 74 65 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e  _test.#.# Comman
0830: 64 73 20 74 6f 20 68 65 6c 70 20 63 72 65 61 74  ds to help creat
0840: 65 20 74 65 73 74 20 66 69 6c 65 73 20 74 68 61  e test files tha
0850: 74 20 72 75 6e 20 77 69 74 68 20 74 68 65 20 22  t run with the "
0860: 57 41 4c 22 20 61 6e 64 20 6f 74 68 65 72 0a 23  WAL" and other.#
0870: 20 70 65 72 6d 75 74 61 74 69 6f 6e 73 20 28 73   permutations (s
0880: 65 65 20 66 69 6c 65 20 70 65 72 6d 75 74 61 74  ee file permutat
0890: 69 6f 6e 73 2e 74 65 73 74 29 3a 0a 23 0a 23 20  ions.test):.#.# 
08a0: 20 20 20 20 20 77 61 6c 5f 69 73 5f 77 61 6c 5f       wal_is_wal_
08b0: 6d 6f 64 65 0a 23 20 20 20 20 20 20 77 61 6c 5f  mode.#      wal_
08c0: 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65  set_journal_mode
08d0: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 77     ?DB?.#      w
08e0: 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c  al_check_journal
08f0: 5f 6d 6f 64 65 20 54 45 53 54 4e 41 4d 45 3f 44  _mode TESTNAME?D
0900: 42 3f 0a 23 20 20 20 20 20 20 70 65 72 6d 75 74  B?.#      permut
0910: 61 74 69 6f 6e 0a 23 20 20 20 20 20 20 70 72 65  ation.#      pre
0920: 73 71 6c 0a 23 0a 0a 23 20 53 65 74 20 74 68 65  sql.#..# Set the
0930: 20 70 72 65 63 69 73 69 6f 6e 20 6f 66 20 46 50   precision of FP
0940: 20 61 72 69 74 68 6d 61 74 69 63 20 75 73 65 64   arithmatic used
0950: 20 62 79 20 74 68 65 20 69 6e 74 65 72 70 72 65   by the interpre
0960: 74 65 72 2e 20 41 6e 64 20 0a 23 20 63 6f 6e 66  ter. And .# conf
0970: 69 67 75 72 65 20 53 51 4c 69 74 65 20 74 6f 20  igure SQLite to 
0980: 74 61 6b 65 20 64 61 74 61 62 61 73 65 20 66 69  take database fi
0990: 6c 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20  le locks on the 
09a0: 70 61 67 65 20 74 68 61 74 20 62 65 67 69 6e 73  page that begins
09b0: 0a 23 20 36 34 4b 42 20 69 6e 74 6f 20 74 68 65  .# 64KB into the
09c0: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 69   database file i
09d0: 6e 73 74 65 61 64 20 6f 66 20 74 68 65 20 6f 6e  nstead of the on
09e0: 65 20 31 47 42 20 69 6e 2e 20 54 68 69 73 20 6d  e 1GB in. This m
09f0: 65 61 6e 73 0a 23 20 74 68 65 20 63 6f 64 65 20  eans.# the code 
0a00: 74 68 61 74 20 68 61 6e 64 6c 65 73 20 74 68 61  that handles tha
0a10: 74 20 73 70 65 63 69 61 6c 20 63 61 73 65 20 63  t special case c
0a20: 61 6e 20 62 65 20 74 65 73 74 65 64 20 77 69 74  an be tested wit
0a30: 68 6f 75 74 20 63 72 65 61 74 69 6e 67 0a 23 20  hout creating.# 
0a40: 76 65 72 79 20 6c 61 72 67 65 20 64 61 74 61 62  very large datab
0a50: 61 73 65 20 66 69 6c 65 73 2e 0a 23 0a 73 65 74  ase files..#.set
0a60: 20 74 63 6c 5f 70 72 65 63 69 73 69 6f 6e 20 31   tcl_precision 1
0a70: 35 0a 73 71 6c 69 74 65 33 5f 74 65 73 74 5f 63  5.sqlite3_test_c
0a80: 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69 6e 67 5f 62  ontrol_pending_b
0a90: 79 74 65 20 30 78 30 30 31 30 30 30 30 0a 0a 0a  yte 0x0010000...
0aa0: 23 20 49 66 20 74 68 65 20 70 61 67 65 72 20 63  # If the pager c
0ab0: 6f 64 65 63 20 69 73 20 61 76 61 69 6c 61 62 6c  odec is availabl
0ac0: 65 2c 20 63 72 65 61 74 65 20 61 20 77 72 61 70  e, create a wrap
0ad0: 70 65 72 20 66 6f 72 20 74 68 65 20 5b 73 71 6c  per for the [sql
0ae0: 69 74 65 33 5d 20 0a 23 20 63 6f 6d 6d 61 6e 64  ite3] .# command
0af0: 20 74 68 61 74 20 61 70 70 65 6e 64 73 20 22 2d   that appends "-
0b00: 6b 65 79 20 7b 78 79 7a 7a 79 7d 22 20 74 6f 20  key {xyzzy}" to 
0b10: 74 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65  the command line
0b20: 2e 20 69 2e 65 2e 20 74 68 69 73 3a 0a 23 0a 23  . i.e. this:.#.#
0b30: 20 20 20 20 20 73 71 6c 69 74 65 33 20 64 62 20       sqlite3 db 
0b40: 74 65 73 74 2e 64 62 0a 23 0a 23 20 62 65 63 6f  test.db.#.# beco
0b50: 6d 65 73 0a 23 0a 23 20 20 20 20 20 73 71 6c 69  mes.#.#     sqli
0b60: 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 20 2d  te3 db test.db -
0b70: 6b 65 79 20 7b 78 79 7a 7a 79 7d 0a 23 0a 69 66  key {xyzzy}.#.if
0b80: 20 7b 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 20   {[info command 
0b90: 73 71 6c 69 74 65 5f 6f 72 69 67 5d 3d 3d 22 22  sqlite_orig]==""
0ba0: 7d 20 7b 0a 20 20 72 65 6e 61 6d 65 20 73 71 6c  } {.  rename sql
0bb0: 69 74 65 33 20 73 71 6c 69 74 65 5f 6f 72 69 67  ite3 sqlite_orig
0bc0: 0a 20 20 70 72 6f 63 20 73 71 6c 69 74 65 33 20  .  proc sqlite3 
0bd0: 7b 61 72 67 73 7d 20 7b 0a 20 20 20 20 69 66 20  {args} {.    if 
0be0: 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d  {[llength $args]
0bf0: 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 69  >=2 && [string i
0c00: 6e 64 65 78 20 5b 6c 69 6e 64 65 78 20 24 61 72  ndex [lindex $ar
0c10: 67 73 20 30 5d 20 30 5d 21 3d 22 2d 22 7d 20 7b  gs 0] 0]!="-"} {
0c20: 0a 20 20 20 20 20 20 23 20 54 68 69 73 20 63 6f  .      # This co
0c30: 6d 6d 61 6e 64 20 69 73 20 6f 70 65 6e 69 6e 67  mmand is opening
0c40: 20 61 20 6e 65 77 20 64 61 74 61 62 61 73 65 20   a new database 
0c50: 63 6f 6e 6e 65 63 74 69 6f 6e 2e 0a 20 20 20 20  connection..    
0c60: 20 20 23 0a 20 20 20 20 20 20 69 66 20 7b 5b 69    #.      if {[i
0c70: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70  nfo exists ::G(p
0c80: 65 72 6d 3a 73 71 6c 69 74 65 33 5f 61 72 67 73  erm:sqlite3_args
0c90: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  )]} {.        se
0ca0: 74 20 61 72 67 73 20 5b 63 6f 6e 63 61 74 20 24  t args [concat $
0cb0: 61 72 67 73 20 24 3a 3a 47 28 70 65 72 6d 3a 73  args $::G(perm:s
0cc0: 71 6c 69 74 65 33 5f 61 72 67 73 29 5d 0a 20 20  qlite3_args)].  
0cd0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 20 7b      }.      if {
0ce0: 5b 73 71 6c 69 74 65 5f 6f 72 69 67 20 2d 68 61  [sqlite_orig -ha
0cf0: 73 2d 63 6f 64 65 63 5d 20 26 26 20 21 5b 69 6e  s-codec] && ![in
0d00: 66 6f 20 65 78 69 73 74 73 20 3a 3a 64 6f 5f 6e  fo exists ::do_n
0d10: 6f 74 5f 75 73 65 5f 63 6f 64 65 63 5d 7d 20 7b  ot_use_codec]} {
0d20: 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64  .        lappend
0d30: 20 61 72 67 73 20 2d 6b 65 79 20 7b 78 79 7a 7a   args -key {xyzz
0d40: 79 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  y}.      }..    
0d50: 20 20 73 65 74 20 72 65 73 20 5b 75 70 6c 65 76    set res [uplev
0d60: 65 6c 20 31 20 73 71 6c 69 74 65 5f 6f 72 69 67  el 1 sqlite_orig
0d70: 20 24 61 72 67 73 5d 0a 20 20 20 20 20 20 69 66   $args].      if
0d80: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
0d90: 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c 29 5d  :G(perm:presql)]
0da0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 5b 6c 69 6e  } {.        [lin
0db0: 64 65 78 20 24 61 72 67 73 20 30 5d 20 65 76 61  dex $args 0] eva
0dc0: 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73  l $::G(perm:pres
0dd0: 71 6c 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ql).      }.    
0de0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
0df0: 74 73 20 3a 3a 47 28 70 65 72 6d 3a 64 62 63 6f  ts ::G(perm:dbco
0e00: 6e 66 69 67 29 5d 7d 20 7b 0a 20 20 20 20 20 20  nfig)]} {.      
0e10: 20 20 73 65 74 20 3a 3a 64 62 68 61 6e 64 6c 65    set ::dbhandle
0e20: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30   [lindex $args 0
0e30: 5d 0a 20 20 20 20 20 20 20 20 75 70 6c 65 76 65  ].        upleve
0e40: 6c 20 23 30 20 24 3a 3a 47 28 70 65 72 6d 3a 64  l #0 $::G(perm:d
0e50: 62 63 6f 6e 66 69 67 29 0a 20 20 20 20 20 20 7d  bconfig).      }
0e60: 0a 20 20 20 20 20 20 73 65 74 20 72 65 73 0a 20  .      set res. 
0e70: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
0e80: 20 20 23 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64    # This command
0e90: 20 69 73 20 6e 6f 74 20 6f 70 65 6e 69 6e 67 20   is not opening 
0ea0: 61 20 6e 65 77 20 64 61 74 61 62 61 73 65 20 63  a new database c
0eb0: 6f 6e 6e 65 63 74 69 6f 6e 2e 20 50 61 73 73 20  onnection. Pass 
0ec0: 74 68 65 20 0a 20 20 20 20 20 20 23 20 61 72 67  the .      # arg
0ed0: 75 6d 65 6e 74 73 20 74 68 72 6f 75 67 68 20 74  uments through t
0ee0: 6f 20 74 68 65 20 43 20 69 6d 70 6c 65 6d 65 6e  o the C implemen
0ef0: 61 74 69 6f 6e 20 61 73 20 74 68 65 20 61 72 65  ation as the are
0f00: 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20  ..      #.      
0f10: 75 70 6c 65 76 65 6c 20 31 20 73 71 6c 69 74 65  uplevel 1 sqlite
0f20: 5f 6f 72 69 67 20 24 61 72 67 73 0a 20 20 20 20  _orig $args.    
0f30: 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78  }.  }.}..proc ex
0f40: 65 63 70 72 65 73 71 6c 20 7b 68 61 6e 64 6c 65  ecpresql {handle
0f50: 20 61 72 67 73 7d 20 7b 0a 20 20 74 72 61 63 65   args} {.  trace
0f60: 20 72 65 6d 6f 76 65 20 65 78 65 63 75 74 69 6f   remove executio
0f70: 6e 20 24 68 61 6e 64 6c 65 20 65 6e 74 65 72 20  n $handle enter 
0f80: 5b 6c 69 73 74 20 65 78 65 63 70 72 65 73 71 6c  [list execpresql
0f90: 20 24 68 61 6e 64 6c 65 5d 0a 20 20 69 66 20 7b   $handle].  if {
0fa0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47  [info exists ::G
0fb0: 28 70 65 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20  (perm:presql)]} 
0fc0: 7b 0a 20 20 20 20 24 68 61 6e 64 6c 65 20 65 76  {.    $handle ev
0fd0: 61 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65  al $::G(perm:pre
0fe0: 73 71 6c 29 0a 20 20 7d 0a 7d 0a 0a 23 20 54 68  sql).  }.}..# Th
0ff0: 69 73 20 63 6f 6d 6d 61 6e 64 20 73 68 6f 75 6c  is command shoul
1000: 64 20 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65  d be called afte
1010: 72 20 6c 6f 61 64 69 6e 67 20 74 65 73 74 65 72  r loading tester
1020: 2e 74 63 6c 20 66 72 6f 6d 20 77 69 74 68 69 6e  .tcl from within
1030: 0a 23 20 61 6c 6c 20 74 65 73 74 20 73 63 72 69  .# all test scri
1040: 70 74 73 20 74 68 61 74 20 61 72 65 20 69 6e 63  pts that are inc
1050: 6f 6d 70 61 74 69 62 6c 65 20 77 69 74 68 20 65  ompatible with e
1060: 6e 63 72 79 70 74 69 6f 6e 20 63 6f 64 65 63 73  ncryption codecs
1070: 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 6e 6f 74 5f  ..#.proc do_not_
1080: 75 73 65 5f 63 6f 64 65 63 20 7b 7d 20 7b 0a 20  use_codec {} {. 
1090: 20 73 65 74 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73   set ::do_not_us
10a0: 65 5f 63 6f 64 65 63 20 31 0a 20 20 72 65 73 65  e_codec 1.  rese
10b0: 74 5f 64 62 0a 7d 0a 0a 23 20 54 68 65 20 66 6f  t_db.}..# The fo
10c0: 6c 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 6f 6e  llowing block on
10d0: 6c 79 20 72 75 6e 73 20 74 68 65 20 66 69 72 73  ly runs the firs
10e0: 74 20 74 69 6d 65 20 74 68 69 73 20 66 69 6c 65  t time this file
10f0: 20 69 73 20 73 6f 75 72 63 65 64 2e 20 49 74 0a   is sourced. It.
1100: 23 20 64 6f 65 73 20 6e 6f 74 20 72 75 6e 20 69  # does not run i
1110: 6e 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65  n slave interpre
1120: 74 65 72 73 20 28 73 69 6e 63 65 20 74 68 65 20  ters (since the 
1130: 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 61 72 72  ::cmdlinearg arr
1140: 61 79 20 69 73 0a 23 20 70 6f 70 75 6c 61 74 65  ay is.# populate
1150: 64 20 62 65 66 6f 72 65 20 74 68 65 20 74 65 73  d before the tes
1160: 74 20 73 63 72 69 70 74 20 69 73 20 72 75 6e 20  t script is run 
1170: 69 6e 20 73 6c 61 76 65 20 69 6e 74 65 72 70 72  in slave interpr
1180: 65 74 65 72 73 29 2e 0a 23 0a 69 66 20 7b 5b 69  eters)..#.if {[i
1190: 6e 66 6f 20 65 78 69 73 74 73 20 63 6d 64 6c 69  nfo exists cmdli
11a0: 6e 65 61 72 67 5d 3d 3d 30 7d 20 7b 0a 0a 20 20  nearg]==0} {..  
11b0: 23 20 50 61 72 73 65 20 61 6e 79 20 6f 70 74 69  # Parse any opti
11c0: 6f 6e 73 20 73 70 65 63 69 66 69 65 64 20 69 6e  ons specified in
11d0: 20 74 68 65 20 24 61 72 67 76 20 61 72 72 61 79   the $argv array
11e0: 2e 20 54 68 69 73 20 73 63 72 69 70 74 20 61 63  . This script ac
11f0: 63 65 70 74 73 20 74 68 65 20 0a 20 20 23 20 66  cepts the .  # f
1200: 6f 6c 6c 6f 77 69 6e 67 20 6f 70 74 69 6f 6e 73  ollowing options
1210: 3a 20 0a 20 20 23 0a 20 20 23 20 20 20 2d 2d 70  : .  #.  #   --p
1220: 61 75 73 65 0a 20 20 23 20 20 20 2d 2d 73 6f 66  ause.  #   --sof
1230: 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d 4e 4e 0a  t-heap-limit=NN.
1240: 20 20 23 20 20 20 2d 2d 6d 61 78 65 72 72 6f 72    #   --maxerror
1250: 3d 4e 4e 0a 20 20 23 20 20 20 2d 2d 6d 61 6c 6c  =NN.  #   --mall
1260: 6f 63 74 72 61 63 65 3d 4e 0a 20 20 23 20 20 20  octrace=N.  #   
1270: 2d 2d 62 61 63 6b 74 72 61 63 65 3d 4e 0a 20 20  --backtrace=N.  
1280: 23 20 20 20 2d 2d 62 69 6e 61 72 79 6c 6f 67 3d  #   --binarylog=
1290: 4e 0a 20 20 23 20 20 20 2d 2d 73 6f 61 6b 3d 4e  N.  #   --soak=N
12a0: 0a 20 20 23 20 20 20 2d 2d 73 74 61 72 74 3d 5b  .  #   --start=[
12b0: 24 70 65 72 6d 75 74 61 74 69 6f 6e 3a 5d 24 74  $permutation:]$t
12c0: 65 73 74 66 69 6c 65 0a 20 20 23 0a 20 20 73 65  estfile.  #.  se
12d0: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f 66  t cmdlinearg(sof
12e0: 74 2d 68 65 61 70 2d 6c 69 6d 69 74 29 20 20 20  t-heap-limit)   
12f0: 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65   0.  set cmdline
1300: 61 72 67 28 6d 61 78 65 72 72 6f 72 29 20 20 20  arg(maxerror)   
1310: 20 20 20 20 20 31 30 30 30 0a 20 20 73 65 74 20       1000.  set 
1320: 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c 6c 6f  cmdlinearg(mallo
1330: 63 74 72 61 63 65 29 20 20 20 20 20 20 20 20 30  ctrace)        0
1340: 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72  .  set cmdlinear
1350: 67 28 62 61 63 6b 74 72 61 63 65 29 20 20 20 20  g(backtrace)    
1360: 20 20 20 20 20 31 30 0a 20 20 73 65 74 20 63 6d       10.  set cm
1370: 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c  dlinearg(binaryl
1380: 6f 67 29 20 20 20 20 20 20 20 20 20 20 30 0a 20  og)          0. 
1390: 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28   set cmdlinearg(
13a0: 73 6f 61 6b 29 20 20 20 20 20 20 20 20 20 20 20  soak)           
13b0: 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c      0.  set cmdl
13c0: 69 6e 65 61 72 67 28 73 74 61 72 74 29 20 20 20  inearg(start)   
13d0: 20 20 20 20 20 20 20 20 20 20 22 22 20 0a 0a 20            "" .. 
13e0: 20 73 65 74 20 6c 65 66 74 6f 76 65 72 20 5b 6c   set leftover [l
13f0: 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 61  ist].  foreach a
1400: 20 24 61 72 67 76 20 7b 0a 20 20 20 20 73 77 69   $argv {.    swi
1410: 74 63 68 20 2d 72 65 67 65 78 70 20 2d 2d 20 24  tch -regexp -- $
1420: 61 20 7b 0a 20 20 20 20 20 20 7b 5e 2d 2b 70 61  a {.      {^-+pa
1430: 75 73 65 24 7d 20 7b 0a 20 20 20 20 20 20 20 20  use$} {.        
1440: 23 20 57 61 69 74 20 66 6f 72 20 75 73 65 72 20  # Wait for user 
1450: 69 6e 70 75 74 20 62 65 66 6f 72 65 20 63 6f 6e  input before con
1460: 74 69 6e 75 69 6e 67 2e 20 54 68 69 73 20 69 73  tinuing. This is
1470: 20 74 6f 20 67 69 76 65 20 74 68 65 20 75 73 65   to give the use
1480: 72 20 61 6e 20 0a 20 20 20 20 20 20 20 20 23 20  r an .        # 
1490: 6f 70 70 6f 72 74 75 6e 69 74 79 20 74 6f 20 63  opportunity to c
14a0: 6f 6e 6e 65 63 74 20 70 72 6f 66 69 6c 69 6e 67  onnect profiling
14b0: 20 74 6f 6f 6c 73 20 74 6f 20 74 68 65 20 70 72   tools to the pr
14c0: 6f 63 65 73 73 2e 0a 20 20 20 20 20 20 20 20 70  ocess..        p
14d0: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22  uts -nonewline "
14e0: 50 72 65 73 73 20 52 45 54 55 52 4e 20 74 6f 20  Press RETURN to 
14f0: 62 65 67 69 6e 2e 2e 2e 22 0a 20 20 20 20 20 20  begin...".      
1500: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20    flush stdout. 
1510: 20 20 20 20 20 20 20 67 65 74 73 20 73 74 64 69         gets stdi
1520: 6e 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  n.      }.      
1530: 7b 5e 2d 2b 73 6f 66 74 2d 68 65 61 70 2d 6c 69  {^-+soft-heap-li
1540: 6d 69 74 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20  mit=.+$} {.     
1550: 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d     foreach {dumm
1560: 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f 66  y cmdlinearg(sof
1570: 74 2d 68 65 61 70 2d 6c 69 6d 69 74 29 7d 20 5b  t-heap-limit)} [
1580: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
1590: 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  k.      }.      
15a0: 7b 5e 2d 2b 6d 61 78 65 72 72 6f 72 3d 2e 2b 24  {^-+maxerror=.+$
15b0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
15c0: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
15d0: 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29 7d  nearg(maxerror)}
15e0: 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72   [split $a =] br
15f0: 65 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  eak.      }.    
1600: 20 20 7b 5e 2d 2b 6d 61 6c 6c 6f 63 74 72 61 63    {^-+malloctrac
1610: 65 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20  e=.+$} {.       
1620: 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20   foreach {dummy 
1630: 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c 6c 6f  cmdlinearg(mallo
1640: 63 74 72 61 63 65 29 7d 20 5b 73 70 6c 69 74 20  ctrace)} [split 
1650: 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20  $a =] break.    
1660: 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65      if {$cmdline
1670: 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29  arg(malloctrace)
1680: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71  } {.          sq
1690: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c  lite3_memdebug_l
16a0: 6f 67 20 73 74 61 72 74 0a 20 20 20 20 20 20 20  og start.       
16b0: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
16c0: 20 7b 5e 2d 2b 62 61 63 6b 74 72 61 63 65 3d 2e   {^-+backtrace=.
16d0: 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f  +$} {.        fo
16e0: 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64  reach {dummy cmd
16f0: 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61 63  linearg(backtrac
1700: 65 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d  e)} [split $a =]
1710: 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 73   break.        s
1720: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
1730: 62 61 63 6b 74 72 61 63 65 20 24 76 61 6c 75 65  backtrace $value
1740: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
1750: 5e 2d 2b 62 69 6e 61 72 79 6c 6f 67 3d 2e 2b 24  ^-+binarylog=.+$
1760: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
1770: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
1780: 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29  nearg(binarylog)
1790: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
17a0: 72 65 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20  reak.      }.   
17b0: 20 20 20 7b 5e 2d 2b 73 6f 61 6b 3d 2e 2b 24 7d     {^-+soak=.+$}
17c0: 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61   {.        forea
17d0: 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e  ch {dummy cmdlin
17e0: 65 61 72 67 28 73 6f 61 6b 29 7d 20 5b 73 70 6c  earg(soak)} [spl
17f0: 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20  it $a =] break. 
1800: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 69         set ::G(i
1810: 73 73 6f 61 6b 29 20 24 63 6d 64 6c 69 6e 65 61  ssoak) $cmdlinea
1820: 72 67 28 73 6f 61 6b 29 0a 20 20 20 20 20 20 7d  rg(soak).      }
1830: 0a 20 20 20 20 20 20 7b 5e 2d 2b 73 74 61 72 74  .      {^-+start
1840: 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20  =.+$} {.        
1850: 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63  foreach {dummy c
1860: 6d 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29  mdlinearg(start)
1870: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
1880: 72 65 61 6b 0a 0a 20 20 20 20 20 20 20 20 73 65  reak..        se
1890: 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65  t ::G(start:file
18a0: 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 74  ) $cmdlinearg(st
18b0: 61 72 74 29 0a 20 20 20 20 20 20 20 20 69 66 20  art).        if 
18c0: 7b 5b 72 65 67 65 78 70 20 7b 28 2e 2a 29 3a 28  {[regexp {(.*):(
18d0: 2e 2a 29 7d 20 24 63 6d 64 6c 69 6e 65 61 72 67  .*)} $cmdlinearg
18e0: 28 73 74 61 72 74 29 20 2d 3e 20 73 2e 70 65 72  (start) -> s.per
18f0: 6d 20 73 2e 66 69 6c 65 5d 7d 20 7b 0a 20 20 20  m s.file]} {.   
1900: 20 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73         set ::G(s
1910: 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e  tart:permutation
1920: 29 20 24 7b 73 2e 70 65 72 6d 7d 0a 20 20 20 20  ) ${s.perm}.    
1930: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74        set ::G(st
1940: 61 72 74 3a 66 69 6c 65 29 20 20 20 20 20 20 20  art:file)       
1950: 20 24 7b 73 2e 66 69 6c 65 7d 0a 20 20 20 20 20   ${s.file}.     
1960: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 20     }.        if 
1970: 7b 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65  {$::G(start:file
1980: 29 20 3d 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20  ) == ""} {unset 
1990: 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 7d  ::G(start:file)}
19a0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64  .      }.      d
19b0: 65 66 61 75 6c 74 20 7b 0a 20 20 20 20 20 20 20  efault {.       
19c0: 20 6c 61 70 70 65 6e 64 20 6c 65 66 74 6f 76 65   lappend leftove
19d0: 72 20 24 61 0a 20 20 20 20 20 20 7d 0a 20 20 20  r $a.      }.   
19e0: 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20 61 72 67   }.  }.  set arg
19f0: 76 20 24 6c 65 66 74 6f 76 65 72 0a 0a 20 20 23  v $leftover..  #
1a00: 20 49 6e 73 74 61 6c 6c 20 74 68 65 20 6d 61 6c   Install the mal
1a10: 6c 6f 63 20 6c 61 79 65 72 20 75 73 65 64 20 74  loc layer used t
1a20: 6f 20 69 6e 6a 65 63 74 20 4f 4f 4d 20 65 72 72  o inject OOM err
1a30: 6f 72 73 2e 20 41 6e 64 20 74 68 65 20 27 61 75  ors. And the 'au
1a40: 74 6f 6d 61 74 69 63 27 0a 20 20 23 20 65 78 74  tomatic'.  # ext
1a50: 65 6e 73 69 6f 6e 73 2e 20 54 68 69 73 20 6f 6e  ensions. This on
1a60: 6c 79 20 6e 65 65 64 73 20 74 6f 20 62 65 20 64  ly needs to be d
1a70: 6f 6e 65 20 6f 6e 63 65 20 66 6f 72 20 74 68 65  one once for the
1a80: 20 70 72 6f 63 65 73 73 2e 0a 20 20 23 0a 20 20   process..  #.  
1a90: 73 71 6c 69 74 65 33 5f 73 68 75 74 64 6f 77 6e  sqlite3_shutdown
1aa0: 20 0a 20 20 69 6e 73 74 61 6c 6c 5f 6d 61 6c 6c   .  install_mall
1ab0: 6f 63 5f 66 61 75 6c 74 73 69 6d 20 31 20 0a 20  oc_faultsim 1 . 
1ac0: 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c   sqlite3_initial
1ad0: 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74 61 6c  ize.  autoinstal
1ae0: 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e 73  l_test_functions
1af0: 0a 0a 20 20 23 20 49 66 20 74 68 65 20 2d 2d 62  ..  # If the --b
1b00: 69 6e 61 72 79 6c 6f 67 20 6f 70 74 69 6f 6e 20  inarylog option 
1b10: 77 61 73 20 73 70 65 63 69 66 69 65 64 2c 20 63  was specified, c
1b20: 72 65 61 74 65 20 74 68 65 20 6c 6f 67 67 69 6e  reate the loggin
1b30: 67 20 56 46 53 2e 20 54 68 69 73 0a 20 20 23 20  g VFS. This.  # 
1b40: 63 61 6c 6c 20 69 6e 73 74 61 6c 6c 73 20 74 68  call installs th
1b50: 65 20 6e 65 77 20 56 46 53 20 61 73 20 74 68 65  e new VFS as the
1b60: 20 64 65 66 61 75 6c 74 20 66 6f 72 20 61 6c 6c   default for all
1b70: 20 53 51 4c 69 74 65 20 63 6f 6e 6e 65 63 74 69   SQLite connecti
1b80: 6f 6e 73 2e 0a 20 20 23 0a 20 20 69 66 20 7b 24  ons..  #.  if {$
1b90: 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72  cmdlinearg(binar
1ba0: 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76 66 73  ylog)} {.    vfs
1bb0: 6c 6f 67 20 6e 65 77 20 62 69 6e 61 72 79 6c 6f  log new binarylo
1bc0: 67 20 7b 7d 20 76 66 73 6c 6f 67 2e 62 69 6e 0a  g {} vfslog.bin.
1bd0: 20 20 7d 0a 0a 20 20 23 20 53 65 74 20 74 68 65    }..  # Set the
1be0: 20 62 61 63 6b 74 72 61 63 65 20 64 65 70 74 68   backtrace depth
1bf0: 2c 20 69 66 20 6d 61 6c 6c 6f 63 20 74 72 61 63  , if malloc trac
1c00: 69 6e 67 20 69 73 20 65 6e 61 62 6c 65 64 2e 0a  ing is enabled..
1c10: 20 20 23 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69    #.  if {$cmdli
1c20: 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63  nearg(malloctrac
1c30: 65 29 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65  e)} {.    sqlite
1c40: 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63 6b 74  3_memdebug_backt
1c50: 72 61 63 65 20 24 63 6d 64 6c 69 6e 65 61 72 67  race $cmdlinearg
1c60: 28 62 61 63 6b 74 72 61 63 65 29 0a 20 20 7d 0a  (backtrace).  }.
1c70: 7d 0a 0a 23 20 55 70 64 61 74 65 20 74 68 65 20  }..# Update the 
1c80: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 20  soft-heap-limit 
1c90: 65 61 63 68 20 74 69 6d 65 20 74 68 69 73 20 73  each time this s
1ca0: 63 72 69 70 74 20 69 73 20 72 75 6e 2e 20 49 6e  cript is run. In
1cb0: 20 74 68 61 74 0a 23 20 77 61 79 20 69 66 20 61   that.# way if a
1cc0: 6e 20 69 6e 64 69 76 69 64 75 61 6c 20 74 65 73  n individual tes
1cd0: 74 20 66 69 6c 65 20 63 68 61 6e 67 65 73 20 74  t file changes t
1ce0: 68 65 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d  he soft-heap-lim
1cf0: 69 74 2c 20 69 74 0a 23 20 77 69 6c 6c 20 62 65  it, it.# will be
1d00: 20 72 65 73 65 74 20 61 74 20 74 68 65 20 73 74   reset at the st
1d10: 61 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20  art of the next 
1d20: 74 65 73 74 20 66 69 6c 65 2e 0a 23 0a 73 71 6c  test file..#.sql
1d30: 69 74 65 33 5f 73 6f 66 74 5f 68 65 61 70 5f 6c  ite3_soft_heap_l
1d40: 69 6d 69 74 20 24 63 6d 64 6c 69 6e 65 61 72 67  imit $cmdlinearg
1d50: 28 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74  (soft-heap-limit
1d60: 29 0a 0a 23 20 43 72 65 61 74 65 20 61 20 74 65  )..# Create a te
1d70: 73 74 20 64 61 74 61 62 61 73 65 0a 23 0a 70 72  st database.#.pr
1d80: 6f 63 20 72 65 73 65 74 5f 64 62 20 7b 7d 20 7b  oc reset_db {} {
1d90: 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f  .  catch {db clo
1da0: 73 65 7d 0a 20 20 66 69 6c 65 20 64 65 6c 65 74  se}.  file delet
1db0: 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e 64 62  e -force test.db
1dc0: 0a 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d  .  file delete -
1dd0: 66 6f 72 63 65 20 74 65 73 74 2e 64 62 2d 6a 6f  force test.db-jo
1de0: 75 72 6e 61 6c 0a 20 20 66 69 6c 65 20 64 65 6c  urnal.  file del
1df0: 65 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e  ete -force test.
1e00: 64 62 2d 77 61 6c 0a 20 20 73 71 6c 69 74 65 33  db-wal.  sqlite3
1e10: 20 64 62 20 2e 2f 74 65 73 74 2e 64 62 0a 20 20   db ./test.db.  
1e20: 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65  set ::DB [sqlite
1e30: 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69  3_connection_poi
1e40: 6e 74 65 72 20 64 62 5d 0a 20 20 69 66 20 7b 5b  nter db].  if {[
1e50: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53 45  info exists ::SE
1e60: 54 55 50 5f 53 51 4c 5d 7d 20 7b 0a 20 20 20 20  TUP_SQL]} {.    
1e70: 64 62 20 65 76 61 6c 20 24 3a 3a 53 45 54 55 50  db eval $::SETUP
1e80: 5f 53 51 4c 0a 20 20 7d 0a 7d 0a 72 65 73 65 74  _SQL.  }.}.reset
1e90: 5f 64 62 0a 0a 23 20 41 62 6f 72 74 20 65 61 72  _db..# Abort ear
1ea0: 6c 79 20 69 66 20 74 68 69 73 20 73 63 72 69 70  ly if this scrip
1eb0: 74 20 68 61 73 20 62 65 65 6e 20 72 75 6e 20 62  t has been run b
1ec0: 65 66 6f 72 65 2e 0a 23 0a 69 66 20 7b 5b 69 6e  efore..#.if {[in
1ed0: 66 6f 20 65 78 69 73 74 73 20 54 43 28 63 6f 75  fo exists TC(cou
1ee0: 6e 74 29 5d 7d 20 72 65 74 75 72 6e 0a 0a 23 20  nt)]} return..# 
1ef0: 4d 61 6b 65 20 73 75 72 65 20 6d 65 6d 6f 72 79  Make sure memory
1f00: 20 73 74 61 74 69 73 74 69 63 73 20 61 72 65 20   statistics are 
1f10: 65 6e 61 62 6c 65 64 2e 0a 23 0a 73 71 6c 69 74  enabled..#.sqlit
1f20: 65 33 5f 63 6f 6e 66 69 67 5f 6d 65 6d 73 74 61  e3_config_memsta
1f30: 74 75 73 20 31 0a 0a 23 20 49 6e 69 74 69 61 6c  tus 1..# Initial
1f40: 69 7a 65 20 74 68 65 20 74 65 73 74 20 63 6f 75  ize the test cou
1f50: 6e 74 65 72 73 20 61 6e 64 20 73 65 74 20 75 70  nters and set up
1f60: 20 63 6f 6d 6d 61 6e 64 73 20 74 6f 20 61 63 63   commands to acc
1f70: 65 73 73 20 74 68 65 6d 2e 0a 23 20 4f 72 2c 20  ess them..# Or, 
1f80: 69 66 20 74 68 69 73 20 69 73 20 61 20 73 6c 61  if this is a sla
1f90: 76 65 20 69 6e 74 65 72 70 72 65 74 65 72 2c 20  ve interpreter, 
1fa0: 73 65 74 20 75 70 20 61 6c 69 61 73 65 73 20 74  set up aliases t
1fb0: 6f 20 77 72 69 74 65 20 74 68 65 0a 23 20 63 6f  o write the.# co
1fc0: 75 6e 74 65 72 73 20 69 6e 20 74 68 65 20 70 61  unters in the pa
1fd0: 72 65 6e 74 20 69 6e 74 65 72 70 72 65 74 65 72  rent interpreter
1fe0: 2e 0a 23 0a 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f  ..#.if {0==[info
1ff0: 20 65 78 69 73 74 73 20 3a 3a 53 4c 41 56 45 5d   exists ::SLAVE]
2000: 7d 20 7b 0a 20 20 73 65 74 20 54 43 28 65 72 72  } {.  set TC(err
2010: 6f 72 73 29 20 20 20 20 30 0a 20 20 73 65 74 20  ors)    0.  set 
2020: 54 43 28 63 6f 75 6e 74 29 20 20 20 20 20 30 0a  TC(count)     0.
2030: 20 20 73 65 74 20 54 43 28 66 61 69 6c 5f 6c 69    set TC(fail_li
2040: 73 74 29 20 5b 6c 69 73 74 5d 0a 20 20 73 65 74  st) [list].  set
2050: 20 54 43 28 6f 6d 69 74 5f 6c 69 73 74 29 20 5b   TC(omit_list) [
2060: 6c 69 73 74 5d 0a 0a 20 20 70 72 6f 63 20 73 65  list]..  proc se
2070: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 7b  t_test_counter {
2080: 63 6f 75 6e 74 65 72 20 61 72 67 73 7d 20 7b 0a  counter args} {.
2090: 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68      if {[llength
20a0: 20 24 61 72 67 73 5d 7d 20 7b 0a 20 20 20 20 20   $args]} {.     
20b0: 20 73 65 74 20 3a 3a 54 43 28 24 63 6f 75 6e 74   set ::TC($count
20c0: 65 72 29 20 5b 6c 69 6e 64 65 78 20 24 61 72 67  er) [lindex $arg
20d0: 73 20 30 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73  s 0].    }.    s
20e0: 65 74 20 3a 3a 54 43 28 24 63 6f 75 6e 74 65 72  et ::TC($counter
20f0: 29 0a 20 20 7d 0a 7d 0a 0a 23 20 52 65 63 6f 72  ).  }.}..# Recor
2100: 64 20 74 68 65 20 66 61 63 74 20 74 68 61 74 20  d the fact that 
2110: 61 20 73 65 71 75 65 6e 63 65 20 6f 66 20 74 65  a sequence of te
2120: 73 74 73 20 77 65 72 65 20 6f 6d 69 74 74 65 64  sts were omitted
2130: 2e 0a 23 0a 70 72 6f 63 20 6f 6d 69 74 5f 74 65  ..#.proc omit_te
2140: 73 74 20 7b 6e 61 6d 65 20 72 65 61 73 6f 6e 7d  st {name reason}
2150: 20 7b 0a 20 20 73 65 74 20 6f 6d 69 74 4c 69 73   {.  set omitLis
2160: 74 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  t [set_test_coun
2170: 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 20  ter omit_list]. 
2180: 20 6c 61 70 70 65 6e 64 20 6f 6d 69 74 4c 69 73   lappend omitLis
2190: 74 20 5b 6c 69 73 74 20 24 6e 61 6d 65 20 24 72  t [list $name $r
21a0: 65 61 73 6f 6e 5d 0a 20 20 73 65 74 5f 74 65 73  eason].  set_tes
21b0: 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c  t_counter omit_l
21c0: 69 73 74 20 24 6f 6d 69 74 4c 69 73 74 0a 7d 0a  ist $omitList.}.
21d0: 0a 23 20 52 65 63 6f 72 64 20 74 68 65 20 66 61  .# Record the fa
21e0: 63 74 20 74 68 61 74 20 61 20 74 65 73 74 20 66  ct that a test f
21f0: 61 69 6c 65 64 2e 0a 23 0a 70 72 6f 63 20 66 61  ailed..#.proc fa
2200: 69 6c 5f 74 65 73 74 20 7b 6e 61 6d 65 7d 20 7b  il_test {name} {
2210: 0a 20 20 73 65 74 20 66 20 5b 73 65 74 5f 74 65  .  set f [set_te
2220: 73 74 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f  st_counter fail_
2230: 6c 69 73 74 5d 0a 20 20 6c 61 70 70 65 6e 64 20  list].  lappend 
2240: 66 20 24 6e 61 6d 65 0a 20 20 73 65 74 5f 74 65  f $name.  set_te
2250: 73 74 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f  st_counter fail_
2260: 6c 69 73 74 20 24 66 0a 20 20 73 65 74 5f 74 65  list $f.  set_te
2270: 73 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72  st_counter error
2280: 73 20 5b 65 78 70 72 20 5b 73 65 74 5f 74 65 73  s [expr [set_tes
2290: 74 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73  t_counter errors
22a0: 5d 20 2b 20 31 5d 0a 0a 20 20 73 65 74 20 6e 46  ] + 1]..  set nF
22b0: 61 69 6c 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  ail [set_test_co
22c0: 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a 20 20  unter errors].  
22d0: 69 66 20 7b 24 6e 46 61 69 6c 3e 3d 24 3a 3a 63  if {$nFail>=$::c
22e0: 6d 64 6c 69 6e 65 61 72 67 28 6d 61 78 65 72 72  mdlinearg(maxerr
22f0: 6f 72 29 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  or)} {.    puts 
2300: 22 2a 2a 2a 20 47 69 76 69 6e 67 20 75 70 2e 2e  "*** Giving up..
2310: 2e 22 0a 20 20 20 20 66 69 6e 61 6c 69 7a 65 5f  .".    finalize_
2320: 74 65 73 74 69 6e 67 0a 20 20 7d 0a 7d 0a 0a 23  testing.  }.}..#
2330: 20 49 6e 63 72 65 6d 65 6e 74 20 74 68 65 20 6e   Increment the n
2340: 75 6d 62 65 72 20 6f 66 20 74 65 73 74 73 20 72  umber of tests r
2350: 75 6e 0a 23 0a 70 72 6f 63 20 69 6e 63 72 5f 6e  un.#.proc incr_n
2360: 74 65 73 74 20 7b 7d 20 7b 0a 20 20 73 65 74 5f  test {} {.  set_
2370: 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f 75  test_counter cou
2380: 6e 74 20 5b 65 78 70 72 20 5b 73 65 74 5f 74 65  nt [expr [set_te
2390: 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74  st_counter count
23a0: 5d 20 2b 20 31 5d 0a 7d 0a 0a 0a 23 20 49 6e 76  ] + 1].}...# Inv
23b0: 6f 6b 65 20 74 68 65 20 64 6f 5f 74 65 73 74 20  oke the do_test 
23c0: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 72 75 6e  procedure to run
23d0: 20 61 20 73 69 6e 67 6c 65 20 74 65 73 74 20 0a   a single test .
23e0: 23 0a 70 72 6f 63 20 64 6f 5f 74 65 73 74 20 7b  #.proc do_test {
23f0: 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65  name cmd expecte
2400: 64 7d 20 7b 0a 0a 20 20 67 6c 6f 62 61 6c 20 61  d} {..  global a
2410: 72 67 76 20 63 6d 64 6c 69 6e 65 61 72 67 0a 0a  rgv cmdlinearg..
2420: 20 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 6e    fix_testname n
2430: 61 6d 65 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d  ame..  sqlite3_m
2440: 65 6d 64 65 62 75 67 5f 73 65 74 74 69 74 6c 65  emdebug_settitle
2450: 20 24 6e 61 6d 65 0a 0a 23 20 20 69 66 20 7b 5b   $name..#  if {[
2460: 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 3d 3d  llength $argv]==
2470: 30 7d 20 7b 20 0a 23 20 20 20 20 73 65 74 20 67  0} { .#    set g
2480: 6f 20 31 0a 23 20 20 7d 20 65 6c 73 65 20 7b 0a  o 1.#  } else {.
2490: 23 20 20 20 20 73 65 74 20 67 6f 20 30 0a 23 20  #    set go 0.# 
24a0: 20 20 20 66 6f 72 65 61 63 68 20 70 61 74 74 65     foreach patte
24b0: 72 6e 20 24 61 72 67 76 20 7b 0a 23 20 20 20 20  rn $argv {.#    
24c0: 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6d 61    if {[string ma
24d0: 74 63 68 20 24 70 61 74 74 65 72 6e 20 24 6e 61  tch $pattern $na
24e0: 6d 65 5d 7d 20 7b 0a 23 20 20 20 20 20 20 20 20  me]} {.#        
24f0: 73 65 74 20 67 6f 20 31 0a 23 20 20 20 20 20 20  set go 1.#      
2500: 20 20 62 72 65 61 6b 0a 23 20 20 20 20 20 20 7d    break.#      }
2510: 0a 23 20 20 20 20 7d 0a 23 20 20 7d 0a 0a 20 20  .#    }.#  }..  
2520: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
2530: 20 3a 3a 47 28 70 65 72 6d 3a 70 72 65 66 69 78   ::G(perm:prefix
2540: 29 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 6e 61  )]} {.    set na
2550: 6d 65 20 22 24 3a 3a 47 28 70 65 72 6d 3a 70 72  me "$::G(perm:pr
2560: 65 66 69 78 29 24 6e 61 6d 65 22 0a 20 20 7d 0a  efix)$name".  }.
2570: 0a 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a 20 20  .  incr_ntest.  
2580: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
2590: 24 6e 61 6d 65 2e 2e 2e 0a 20 20 66 6c 75 73 68  $name....  flush
25a0: 20 73 74 64 6f 75 74 0a 20 20 69 66 20 7b 5b 63   stdout.  if {[c
25b0: 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 23 30  atch {uplevel #0
25c0: 20 22 24 63 6d 64 3b 5c 6e 22 7d 20 72 65 73 75   "$cmd;\n"} resu
25d0: 6c 74 5d 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  lt]} {.    puts 
25e0: 22 5c 6e 45 72 72 6f 72 3a 20 24 72 65 73 75 6c  "\nError: $resul
25f0: 74 22 0a 20 20 20 20 66 61 69 6c 5f 74 65 73 74  t".    fail_test
2600: 20 24 6e 61 6d 65 0a 20 20 7d 20 65 6c 73 65 69   $name.  } elsei
2610: 66 20 7b 5b 73 74 72 69 6e 67 20 63 6f 6d 70 61  f {[string compa
2620: 72 65 20 24 72 65 73 75 6c 74 20 24 65 78 70 65  re $result $expe
2630: 63 74 65 64 5d 7d 20 7b 0a 20 20 20 20 70 75 74  cted]} {.    put
2640: 73 20 22 5c 6e 45 78 70 65 63 74 65 64 3a 20 5c  s "\nExpected: \
2650: 5b 24 65 78 70 65 63 74 65 64 5c 5d 5c 6e 20 20  [$expected\]\n  
2660: 20 20 20 47 6f 74 3a 20 5c 5b 24 72 65 73 75 6c     Got: \[$resul
2670: 74 5c 5d 22 0a 20 20 20 20 66 61 69 6c 5f 74 65  t\]".    fail_te
2680: 73 74 20 24 6e 61 6d 65 0a 20 20 7d 20 65 6c 73  st $name.  } els
2690: 65 20 7b 0a 20 20 20 20 70 75 74 73 20 22 20 4f  e {.    puts " O
26a0: 6b 22 0a 20 20 7d 0a 20 20 66 6c 75 73 68 20 73  k".  }.  flush s
26b0: 74 64 6f 75 74 0a 7d 0a 0a 70 72 6f 63 20 72 65  tdout.}..proc re
26c0: 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20  alnum_normalize 
26d0: 7b 72 7d 20 7b 0a 20 20 73 74 72 69 6e 67 20 6d  {r} {.  string m
26e0: 61 70 20 7b 31 2e 23 49 4e 46 20 69 6e 66 7d 20  ap {1.#INF inf} 
26f0: 5b 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 28 65  [regsub -all {(e
2700: 5b 2b 2d 5d 29 30 2b 7d 20 24 72 20 7b 5c 31 7d  [+-])0+} $r {\1}
2710: 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 72 65 61 6c  ].}.proc do_real
2720: 6e 75 6d 5f 74 65 73 74 20 7b 6e 61 6d 65 20 63  num_test {name c
2730: 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b 0a 20  md expected} {. 
2740: 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 64   uplevel [list d
2750: 6f 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 0a 20  o_test $name [. 
2760: 20 20 20 73 75 62 73 74 20 2d 6e 6f 63 6f 6d 6d     subst -nocomm
2770: 61 6e 64 73 20 7b 20 72 65 61 6c 6e 75 6d 5f 6e  ands { realnum_n
2780: 6f 72 6d 61 6c 69 7a 65 20 5b 20 24 63 6d 64 20  ormalize [ $cmd 
2790: 5d 20 7d 0a 20 20 5d 20 5b 72 65 61 6c 6e 75 6d  ] }.  ] [realnum
27a0: 5f 6e 6f 72 6d 61 6c 69 7a 65 20 24 65 78 70 65  _normalize $expe
27b0: 63 74 65 64 5d 5d 0a 7d 0a 0a 70 72 6f 63 20 66  cted]].}..proc f
27c0: 69 78 5f 74 65 73 74 6e 61 6d 65 20 7b 76 61 72  ix_testname {var
27d0: 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61 72 20  name} {.  upvar 
27e0: 24 76 61 72 6e 61 6d 65 20 74 65 73 74 6e 61 6d  $varname testnam
27f0: 65 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  e.  if {[info ex
2800: 69 73 74 73 20 3a 3a 74 65 73 74 70 72 65 66 69  ists ::testprefi
2810: 78 5d 20 0a 20 20 20 26 26 20 5b 73 74 72 69 6e  x] .   && [strin
2820: 67 20 69 73 20 64 69 67 69 74 20 5b 73 74 72 69  g is digit [stri
2830: 6e 67 20 72 61 6e 67 65 20 24 74 65 73 74 6e 61  ng range $testna
2840: 6d 65 20 30 20 30 5d 5d 0a 20 20 7d 20 7b 0a 20  me 0 0]].  } {. 
2850: 20 20 20 73 65 74 20 74 65 73 74 6e 61 6d 65 20     set testname 
2860: 22 24 7b 3a 3a 74 65 73 74 70 72 65 66 69 78 7d  "${::testprefix}
2870: 2d 24 74 65 73 74 6e 61 6d 65 22 0a 20 20 7d 0a  -$testname".  }.
2880: 7d 0a 20 20 20 20 0a 70 72 6f 63 20 64 6f 5f 65  }.    .proc do_e
2890: 78 65 63 73 71 6c 5f 74 65 73 74 20 7b 74 65 73  xecsql_test {tes
28a0: 74 6e 61 6d 65 20 73 71 6c 20 7b 72 65 73 75 6c  tname sql {resul
28b0: 74 20 7b 7d 7d 7d 20 7b 0a 20 20 66 69 78 5f 74  t {}}} {.  fix_t
28c0: 65 73 74 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65  estname testname
28d0: 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65  .  uplevel do_te
28e0: 73 74 20 5b 6c 69 73 74 20 24 74 65 73 74 6e 61  st [list $testna
28f0: 6d 65 5d 20 5b 6c 69 73 74 20 22 65 78 65 63 73  me] [list "execs
2900: 71 6c 20 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69 73  ql {$sql}"] [lis
2910: 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73 75  t [list {*}$resu
2920: 6c 74 5d 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 63  lt]].}.proc do_c
2930: 61 74 63 68 73 71 6c 5f 74 65 73 74 20 7b 74 65  atchsql_test {te
2940: 73 74 6e 61 6d 65 20 73 71 6c 20 72 65 73 75 6c  stname sql resul
2950: 74 7d 20 7b 0a 20 20 66 69 78 5f 74 65 73 74 6e  t} {.  fix_testn
2960: 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a 20 20 75  ame testname.  u
2970: 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 5b  plevel do_test [
2980: 6c 69 73 74 20 24 74 65 73 74 6e 61 6d 65 5d 20  list $testname] 
2990: 5b 6c 69 73 74 20 22 63 61 74 63 68 73 71 6c 20  [list "catchsql 
29a0: 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69 73 74 20 24  {$sql}"] [list $
29b0: 72 65 73 75 6c 74 5d 0a 7d 0a 70 72 6f 63 20 64  result].}.proc d
29c0: 6f 5f 65 71 70 5f 74 65 73 74 20 7b 6e 61 6d 65  o_eqp_test {name
29d0: 20 73 71 6c 20 72 65 73 7d 20 7b 0a 20 20 75 70   sql res} {.  up
29e0: 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63 73 71 6c  level do_execsql
29f0: 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 6c 69 73  _test $name [lis
2a00: 74 20 22 45 58 50 4c 41 49 4e 20 51 55 45 52 59  t "EXPLAIN QUERY
2a10: 20 50 4c 41 4e 20 24 73 71 6c 22 5d 20 5b 6c 69   PLAN $sql"] [li
2a20: 73 74 20 24 72 65 73 5d 0a 7d 0a 0a 23 2d 2d 2d  st $res].}..#---
2a30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a70: 2d 2d 2d 2d 2d 2d 0a 23 20 20 20 55 73 61 67 65  ------.#   Usage
2a80: 3a 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74  : do_select_test
2a90: 73 20 50 52 45 46 49 58 20 3f 53 57 49 54 43 48  s PREFIX ?SWITCH
2aa0: 45 53 3f 20 54 45 53 54 4c 49 53 54 0a 23 0a 23  ES? TESTLIST.#.#
2ab0: 20 57 68 65 72 65 20 73 77 69 74 63 68 65 73 20   Where switches 
2ac0: 61 72 65 3a 0a 23 0a 23 20 20 20 2d 65 72 72 6f  are:.#.#   -erro
2ad0: 72 66 6f 72 6d 61 74 20 46 4d 54 53 54 52 49 4e  rformat FMTSTRIN
2ae0: 47 0a 23 20 20 20 2d 63 6f 75 6e 74 0a 23 20 20  G.#   -count.#  
2af0: 20 2d 71 75 65 72 79 20 53 51 4c 0a 23 20 20 20   -query SQL.#   
2b00: 2d 74 63 6c 71 75 65 72 79 20 54 43 4c 0a 23 20  -tclquery TCL.# 
2b10: 20 20 2d 72 65 70 61 69 72 20 54 43 4c 0a 23 0a    -repair TCL.#.
2b20: 70 72 6f 63 20 64 6f 5f 73 65 6c 65 63 74 5f 74  proc do_select_t
2b30: 65 73 74 73 20 7b 70 72 65 66 69 78 20 61 72 67  ests {prefix arg
2b40: 73 7d 20 7b 0a 0a 20 20 73 65 74 20 74 65 73 74  s} {..  set test
2b50: 6c 69 73 74 20 5b 6c 69 6e 64 65 78 20 24 61 72  list [lindex $ar
2b60: 67 73 20 65 6e 64 5d 0a 20 20 73 65 74 20 73 77  gs end].  set sw
2b70: 69 74 63 68 65 73 20 5b 6c 72 61 6e 67 65 20 24  itches [lrange $
2b80: 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 0a 0a 20  args 0 end-1].. 
2b90: 20 73 65 74 20 65 72 72 66 6d 74 20 22 22 0a 20   set errfmt "". 
2ba0: 20 73 65 74 20 63 6f 75 6e 74 6f 6e 6c 79 20 30   set countonly 0
2bb0: 0a 20 20 73 65 74 20 74 63 6c 71 75 65 72 79 20  .  set tclquery 
2bc0: 22 22 0a 20 20 73 65 74 20 72 65 70 61 69 72 20  "".  set repair 
2bd0: 22 22 0a 0a 20 20 66 6f 72 20 7b 73 65 74 20 69  ""..  for {set i
2be0: 20 30 7d 20 7b 24 69 20 3c 20 5b 6c 6c 65 6e 67   0} {$i < [lleng
2bf0: 74 68 20 24 73 77 69 74 63 68 65 73 5d 7d 20 7b  th $switches]} {
2c00: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 73 65  incr i} {.    se
2c10: 74 20 73 20 5b 6c 69 6e 64 65 78 20 24 73 77 69  t s [lindex $swi
2c20: 74 63 68 65 73 20 24 69 5d 0a 20 20 20 20 73 65  tches $i].    se
2c30: 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  t n [string leng
2c40: 74 68 20 24 73 5d 0a 20 20 20 20 69 66 20 7b 24  th $s].    if {$
2c50: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
2c60: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
2c70: 20 24 73 20 22 2d 71 75 65 72 79 22 5d 7d 20 7b   $s "-query"]} {
2c80: 0a 20 20 20 20 20 20 73 65 74 20 74 63 6c 71 75  .      set tclqu
2c90: 65 72 79 20 5b 6c 69 73 74 20 65 78 65 63 73 71  ery [list execsq
2ca0: 6c 20 5b 6c 69 6e 64 65 78 20 24 73 77 69 74 63  l [lindex $switc
2cb0: 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d 5d 0a 20  hes [incr i]]]. 
2cc0: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6e 3e     } elseif {$n>
2cd0: 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 65 71  =2 && [string eq
2ce0: 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e 20 24  ual -length $n $
2cf0: 73 20 22 2d 74 63 6c 71 75 65 72 79 22 5d 7d 20  s "-tclquery"]} 
2d00: 7b 0a 20 20 20 20 20 20 73 65 74 20 74 63 6c 71  {.      set tclq
2d10: 75 65 72 79 20 5b 6c 69 6e 64 65 78 20 24 73 77  uery [lindex $sw
2d20: 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d 5d  itches [incr i]]
2d30: 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  .    } elseif {$
2d40: 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  n>=2 && [string 
2d50: 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24 6e  equal -length $n
2d60: 20 24 73 20 22 2d 65 72 72 6f 72 66 6f 72 6d 61   $s "-errorforma
2d70: 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  t"]} {.      set
2d80: 20 65 72 72 66 6d 74 20 5b 6c 69 6e 64 65 78 20   errfmt [lindex 
2d90: 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20  $switches [incr 
2da0: 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66  i]].    } elseif
2db0: 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69   {$n>=2 && [stri
2dc0: 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68  ng equal -length
2dd0: 20 24 6e 20 24 73 20 22 2d 72 65 70 61 69 72 22   $n $s "-repair"
2de0: 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 72  ]} {.      set r
2df0: 65 70 61 69 72 20 5b 6c 69 6e 64 65 78 20 24 73  epair [lindex $s
2e00: 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20 69 5d  witches [incr i]
2e10: 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b  ].    } elseif {
2e20: 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67  $n>=2 && [string
2e30: 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 24   equal -length $
2e40: 6e 20 24 73 20 22 2d 63 6f 75 6e 74 22 5d 7d 20  n $s "-count"]} 
2e50: 7b 0a 20 20 20 20 20 20 73 65 74 20 63 6f 75 6e  {.      set coun
2e60: 74 6f 6e 6c 79 20 31 0a 20 20 20 20 7d 20 65 6c  tonly 1.    } el
2e70: 73 65 20 7b 0a 20 20 20 20 20 20 65 72 72 6f 72  se {.      error
2e80: 20 22 75 6e 6b 6e 6f 77 6e 20 73 77 69 74 63 68   "unknown switch
2e90: 3a 20 24 73 22 0a 20 20 20 20 7d 0a 20 20 7d 0a  : $s".    }.  }.
2ea0: 0a 20 20 69 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c  .  if {$countonl
2eb0: 79 20 26 26 20 24 65 72 72 66 6d 74 21 3d 22 22  y && $errfmt!=""
2ec0: 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 43  } {.    error "C
2ed0: 61 6e 6e 6f 74 20 75 73 65 20 2d 63 6f 75 6e 74  annot use -count
2ee0: 20 61 6e 64 20 2d 65 72 72 6f 72 66 6f 72 6d 61   and -errorforma
2ef0: 74 20 74 6f 67 65 74 68 65 72 22 0a 20 20 7d 0a  t together".  }.
2f00: 20 20 73 65 74 20 6e 54 65 73 74 6c 69 73 74 20    set nTestlist 
2f10: 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73 74 6c 69  [llength $testli
2f20: 73 74 5d 0a 20 20 69 66 20 7b 24 6e 54 65 73 74  st].  if {$nTest
2f30: 6c 69 73 74 25 33 20 7c 7c 20 24 6e 54 65 73 74  list%3 || $nTest
2f40: 6c 69 73 74 3d 3d 30 20 7d 20 7b 0a 20 20 20 20  list==0 } {.    
2f50: 65 72 72 6f 72 20 22 53 45 4c 45 43 54 20 74 65  error "SELECT te
2f60: 73 74 20 6c 69 73 74 20 63 6f 6e 74 61 69 6e 73  st list contains
2f70: 20 5b 6c 6c 65 6e 67 74 68 20 24 74 65 73 74 6c   [llength $testl
2f80: 69 73 74 5d 20 65 6c 65 6d 65 6e 74 73 22 0a 20  ist] elements". 
2f90: 20 7d 0a 0a 20 20 65 76 61 6c 20 24 72 65 70 61   }..  eval $repa
2fa0: 69 72 0a 20 20 66 6f 72 65 61 63 68 20 7b 74 6e  ir.  foreach {tn
2fb0: 20 73 71 6c 20 72 65 73 7d 20 24 74 65 73 74 6c   sql res} $testl
2fc0: 69 73 74 20 7b 0a 20 20 20 20 69 66 20 7b 24 74  ist {.    if {$t
2fd0: 63 6c 71 75 65 72 79 20 21 3d 20 22 22 7d 20 7b  clquery != ""} {
2fe0: 0a 20 20 20 20 20 20 65 78 65 63 73 71 6c 20 24  .      execsql $
2ff0: 73 71 6c 0a 20 20 20 20 20 20 75 70 6c 65 76 65  sql.      upleve
3000: 6c 20 64 6f 5f 74 65 73 74 20 24 7b 70 72 65 66  l do_test ${pref
3010: 69 78 7d 2e 24 74 6e 20 5b 6c 69 73 74 20 24 74  ix}.$tn [list $t
3020: 63 6c 71 75 65 72 79 5d 20 5b 6c 69 73 74 20 5b  clquery] [list [
3030: 6c 69 73 74 20 7b 2a 7d 24 72 65 73 5d 5d 0a 20  list {*}$res]]. 
3040: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 63 6f     } elseif {$co
3050: 75 6e 74 6f 6e 6c 79 7d 20 7b 0a 20 20 20 20 20  untonly} {.     
3060: 20 73 65 74 20 6e 52 6f 77 20 30 0a 20 20 20 20   set nRow 0.    
3070: 20 20 64 62 20 65 76 61 6c 20 24 73 71 6c 20 7b    db eval $sql {
3080: 69 6e 63 72 20 6e 52 6f 77 7d 0a 20 20 20 20 20  incr nRow}.     
3090: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74   uplevel do_test
30a0: 20 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e 20 5b   ${prefix}.$tn [
30b0: 6c 69 73 74 20 5b 6c 69 73 74 20 73 65 74 20 7b  list [list set {
30c0: 7d 20 24 6e 52 6f 77 5d 5d 20 5b 6c 69 73 74 20  } $nRow]] [list 
30d0: 24 72 65 73 5d 0a 20 20 20 20 7d 20 65 6c 73 65  $res].    } else
30e0: 69 66 20 7b 24 65 72 72 66 6d 74 3d 3d 22 22 7d  if {$errfmt==""}
30f0: 20 7b 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c   {.      uplevel
3100: 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74   do_execsql_test
3110: 20 24 7b 70 72 65 66 69 78 7d 2e 24 7b 74 6e 7d   ${prefix}.${tn}
3120: 20 5b 6c 69 73 74 20 24 73 71 6c 5d 20 5b 6c 69   [list $sql] [li
3130: 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72 65 73  st [list {*}$res
3140: 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  ]].    } else {.
3150: 20 20 20 20 20 20 73 65 74 20 72 65 73 20 5b 6c        set res [l
3160: 69 73 74 20 31 20 5b 73 74 72 69 6e 67 20 74 72  ist 1 [string tr
3170: 69 6d 20 5b 66 6f 72 6d 61 74 20 24 65 72 72 66  im [format $errf
3180: 6d 74 20 7b 2a 7d 24 72 65 73 5d 5d 5d 0a 20 20  mt {*}$res]]].  
3190: 20 20 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 63      uplevel do_c
31a0: 61 74 63 68 73 71 6c 5f 74 65 73 74 20 24 7b 70  atchsql_test ${p
31b0: 72 65 66 69 78 7d 2e 24 7b 74 6e 7d 20 5b 6c 69  refix}.${tn} [li
31c0: 73 74 20 24 73 71 6c 5d 20 5b 6c 69 73 74 20 24  st $sql] [list $
31d0: 72 65 73 5d 0a 20 20 20 20 7d 0a 20 20 20 20 65  res].    }.    e
31e0: 76 61 6c 20 24 72 65 70 61 69 72 0a 20 20 7d 0a  val $repair.  }.
31f0: 0a 7d 0a 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f  .}..proc delete_
3200: 61 6c 6c 5f 64 61 74 61 20 7b 7d 20 7b 0a 20 20  all_data {} {.  
3210: 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  db eval {SELECT 
3220: 74 62 6c 5f 6e 61 6d 65 20 41 53 20 74 20 46 52  tbl_name AS t FR
3230: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
3240: 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74   WHERE type = 't
3250: 61 62 6c 65 27 7d 20 7b 0a 20 20 20 20 64 62 20  able'} {.    db 
3260: 65 76 61 6c 20 22 44 45 4c 45 54 45 20 46 52 4f  eval "DELETE FRO
3270: 4d 20 27 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b  M '[string map {
3280: 27 20 27 27 7d 20 24 74 5d 27 22 0a 20 20 7d 0a  ' ''} $t]'".  }.
3290: 7d 0a 0a 23 20 52 75 6e 20 61 6e 20 53 51 4c 20  }..# Run an SQL 
32a0: 73 63 72 69 70 74 2e 20 20 0a 23 20 52 65 74 75  script.  .# Retu
32b0: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
32c0: 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20 70 65   microseconds pe
32d0: 72 20 73 74 61 74 65 6d 65 6e 74 2e 0a 23 0a 70  r statement..#.p
32e0: 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 20  roc speed_trial 
32f0: 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e  {name numstmt un
3300: 69 74 73 20 73 71 6c 7d 20 7b 0a 20 20 70 75 74  its sql} {.  put
3310: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f  s -nonewline [fo
3320: 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d  rmat {%-21.21s }
3330: 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75   $name...].  flu
3340: 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74 20  sh stdout.  set 
3350: 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 73 71 6c  speed [time {sql
3360: 69 74 65 33 5f 65 78 65 63 5f 6e 72 20 64 62 20  ite3_exec_nr db 
3370: 24 73 71 6c 7d 5d 0a 20 20 73 65 74 20 74 6d 20  $sql}].  set tm 
3380: 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64 20 30  [lindex $speed 0
3390: 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d 3d 20 30  ].  if {$tm == 0
33a0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65  } {.    set rate
33b0: 20 5b 66 6f 72 6d 61 74 20 25 32 30 73 20 22 6d   [format %20s "m
33c0: 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73 65 20 7b  any"].  } else {
33d0: 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b 66  .    set rate [f
33e0: 6f 72 6d 61 74 20 25 32 30 2e 35 66 20 5b 65 78  ormat %20.5f [ex
33f0: 70 72 20 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e  pr {1000000.0*$n
3400: 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20  umstmt/$tm}]].  
3410: 7d 0a 20 20 73 65 74 20 75 32 20 24 75 6e 69 74  }.  set u2 $unit
3420: 73 2f 73 0a 20 20 70 75 74 73 20 5b 66 6f 72 6d  s/s.  puts [form
3430: 61 74 20 7b 25 31 32 64 20 75 53 20 25 73 20 25  at {%12d uS %s %
3440: 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24 75 32  s} $tm $rate $u2
3450: 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  ].  global total
3460: 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61  _time.  set tota
3470: 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b 24 74  l_time [expr {$t
3480: 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a  otal_time+$tm}].
3490: 20 20 6c 61 70 70 65 6e 64 20 3a 3a 73 70 65 65    lappend ::spee
34a0: 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73 20 24 6e  d_trial_times $n
34b0: 61 6d 65 20 24 74 6d 0a 7d 0a 70 72 6f 63 20 73  ame $tm.}.proc s
34c0: 70 65 65 64 5f 74 72 69 61 6c 5f 74 63 6c 20 7b  peed_trial_tcl {
34d0: 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e 69  name numstmt uni
34e0: 74 73 20 73 63 72 69 70 74 7d 20 7b 0a 20 20 70  ts script} {.  p
34f0: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b  uts -nonewline [
3500: 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73  format {%-21.21s
3510: 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66   } $name...].  f
3520: 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65  lush stdout.  se
3530: 74 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 65  t speed [time {e
3540: 76 61 6c 20 24 73 63 72 69 70 74 7d 5d 0a 20 20  val $script}].  
3550: 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24  set tm [lindex $
3560: 73 70 65 65 64 20 30 5d 0a 20 20 69 66 20 7b 24  speed 0].  if {$
3570: 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20 20 73  tm == 0} {.    s
3580: 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20  et rate [format 
3590: 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20 20 7d  %20s "many"].  }
35a0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
35b0: 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30  rate [format %20
35c0: 2e 35 66 20 5b 65 78 70 72 20 7b 31 30 30 30 30  .5f [expr {10000
35d0: 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f 24 74  00.0*$numstmt/$t
35e0: 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74 20 75  m}]].  }.  set u
35f0: 32 20 24 75 6e 69 74 73 2f 73 0a 20 20 70 75 74  2 $units/s.  put
3600: 73 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32 64 20  s [format {%12d 
3610: 75 53 20 25 73 20 25 73 7d 20 24 74 6d 20 24 72  uS %s %s} $tm $r
3620: 61 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f 62 61  ate $u2].  globa
3630: 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73  l total_time.  s
3640: 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20 5b 65  et total_time [e
3650: 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69 6d 65  xpr {$total_time
3660: 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70 70 65 6e 64  +$tm}].  lappend
3670: 20 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74   ::speed_trial_t
3680: 69 6d 65 73 20 24 6e 61 6d 65 20 24 74 6d 0a 7d  imes $name $tm.}
3690: 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61  .proc speed_tria
36a0: 6c 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20 7b 0a  l_init {name} {.
36b0: 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74    global total_t
36c0: 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f  ime.  set total_
36d0: 74 69 6d 65 20 30 0a 20 20 73 65 74 20 3a 3a 73  time 0.  set ::s
36e0: 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73  peed_trial_times
36f0: 20 5b 6c 69 73 74 5d 0a 20 20 73 71 6c 69 74 65   [list].  sqlite
3700: 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f 72 79  3 versdb :memory
3710: 3a 0a 20 20 73 65 74 20 76 65 72 73 20 5b 76 65  :.  set vers [ve
3720: 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45 43 54  rsdb one {SELECT
3730: 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69   sqlite_source_i
3740: 64 28 29 7d 5d 0a 20 20 76 65 72 73 64 62 20 63  d()}].  versdb c
3750: 6c 6f 73 65 0a 20 20 70 75 74 73 20 22 53 51 4c  lose.  puts "SQL
3760: 69 74 65 20 24 76 65 72 73 22 0a 7d 0a 70 72 6f  ite $vers".}.pro
3770: 63 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 73 75  c speed_trial_su
3780: 6d 6d 61 72 79 20 7b 6e 61 6d 65 7d 20 7b 0a 20  mmary {name} {. 
3790: 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69   global total_ti
37a0: 6d 65 0a 20 20 70 75 74 73 20 5b 66 6f 72 6d 61  me.  puts [forma
37b0: 74 20 7b 25 2d 32 31 2e 32 31 73 20 25 31 32 64  t {%-21.21s %12d
37c0: 20 75 53 20 54 4f 54 41 4c 7d 20 24 6e 61 6d 65   uS TOTAL} $name
37d0: 20 24 74 6f 74 61 6c 5f 74 69 6d 65 5d 0a 0a 20   $total_time].. 
37e0: 20 69 66 20 7b 20 30 20 7d 20 7b 0a 20 20 20 20   if { 0 } {.    
37f0: 73 71 6c 69 74 65 33 20 76 65 72 73 64 62 20 3a  sqlite3 versdb :
3800: 6d 65 6d 6f 72 79 3a 0a 20 20 20 20 73 65 74 20  memory:.    set 
3810: 76 65 72 73 20 5b 6c 69 6e 64 65 78 20 5b 76 65  vers [lindex [ve
3820: 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45 43 54  rsdb one {SELECT
3830: 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69   sqlite_source_i
3840: 64 28 29 7d 5d 20 30 5d 0a 20 20 20 20 76 65 72  d()}] 0].    ver
3850: 73 64 62 20 63 6c 6f 73 65 0a 20 20 20 20 70 75  sdb close.    pu
3860: 74 73 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  ts "CREATE TABLE
3870: 20 49 46 20 4e 4f 54 20 45 58 49 53 54 53 20 74   IF NOT EXISTS t
3880: 69 6d 65 28 76 65 72 73 69 6f 6e 2c 20 73 63 72  ime(version, scr
3890: 69 70 74 2c 20 74 65 73 74 2c 20 75 73 29 3b 22  ipt, test, us);"
38a0: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 65  .    foreach {te
38b0: 73 74 20 75 73 7d 20 24 3a 3a 73 70 65 65 64 5f  st us} $::speed_
38c0: 74 72 69 61 6c 5f 74 69 6d 65 73 20 7b 0a 20 20  trial_times {.  
38d0: 20 20 20 20 70 75 74 73 20 22 49 4e 53 45 52 54      puts "INSERT
38e0: 20 49 4e 54 4f 20 74 69 6d 65 20 56 41 4c 55 45   INTO time VALUE
38f0: 53 28 27 24 76 65 72 73 27 2c 20 27 24 6e 61 6d  S('$vers', '$nam
3900: 65 27 2c 20 27 24 74 65 73 74 27 2c 20 24 75 73  e', '$test', $us
3910: 29 3b 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  );".    }.  }.}.
3920: 0a 23 20 52 75 6e 20 74 68 69 73 20 72 6f 75 74  .# Run this rout
3930: 69 6e 65 20 6c 61 73 74 0a 23 0a 70 72 6f 63 20  ine last.#.proc 
3940: 66 69 6e 69 73 68 5f 74 65 73 74 20 7b 7d 20 7b  finish_test {} {
3950: 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f  .  catch {db clo
3960: 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 32  se}.  catch {db2
3970: 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20   close}.  catch 
3980: 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 20 20 69 66  {db3 close}.  if
3990: 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69 73 74   {0==[info exist
39a0: 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 20 66 69  s ::SLAVE]} { fi
39b0: 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 20 7d  nalize_testing }
39c0: 0a 7d 0a 70 72 6f 63 20 66 69 6e 61 6c 69 7a 65  .}.proc finalize
39d0: 5f 74 65 73 74 69 6e 67 20 7b 7d 20 7b 0a 20 20  _testing {} {.  
39e0: 67 6c 6f 62 61 6c 20 73 71 6c 69 74 65 5f 6f 70  global sqlite_op
39f0: 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a 0a 20  en_file_count.. 
3a00: 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20 5b 73   set omitList [s
3a10: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
3a20: 6f 6d 69 74 5f 6c 69 73 74 5d 0a 0a 20 20 63 61  omit_list]..  ca
3a30: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
3a40: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
3a50: 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20  e}.  catch {db3 
3a60: 63 6c 6f 73 65 7d 0a 0a 20 20 76 66 73 5f 75 6e  close}..  vfs_un
3a70: 6c 69 6e 6b 5f 74 65 73 74 0a 20 20 73 71 6c 69  link_test.  sqli
3a80: 74 65 33 20 64 62 20 7b 7d 0a 20 20 23 20 73 71  te3 db {}.  # sq
3a90: 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74 73 64 5f  lite3_clear_tsd_
3aa0: 6d 65 6d 64 65 62 75 67 0a 20 20 64 62 20 63 6c  memdebug.  db cl
3ab0: 6f 73 65 0a 20 20 73 71 6c 69 74 65 33 5f 72 65  ose.  sqlite3_re
3ac0: 73 65 74 5f 61 75 74 6f 5f 65 78 74 65 6e 73 69  set_auto_extensi
3ad0: 6f 6e 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 6f  on..  sqlite3_so
3ae0: 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20 30 0a  ft_heap_limit 0.
3af0: 20 20 73 65 74 20 6e 54 65 73 74 20 5b 69 6e 63    set nTest [inc
3b00: 72 5f 6e 74 65 73 74 5d 0a 20 20 73 65 74 20 6e  r_ntest].  set n
3b10: 45 72 72 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  Err [set_test_co
3b20: 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a 0a 20  unter errors].. 
3b30: 20 70 75 74 73 20 22 24 6e 45 72 72 20 65 72 72   puts "$nErr err
3b40: 6f 72 73 20 6f 75 74 20 6f 66 20 24 6e 54 65 73  ors out of $nTes
3b50: 74 20 74 65 73 74 73 22 0a 20 20 69 66 20 7b 24  t tests".  if {$
3b60: 6e 45 72 72 3e 30 7d 20 7b 0a 20 20 20 20 70 75  nErr>0} {.    pu
3b70: 74 73 20 22 46 61 69 6c 75 72 65 73 20 6f 6e 20  ts "Failures on 
3b80: 74 68 65 73 65 20 74 65 73 74 73 3a 20 5b 73 65  these tests: [se
3b90: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66  t_test_counter f
3ba0: 61 69 6c 5f 6c 69 73 74 5d 22 0a 20 20 7d 0a 20  ail_list]".  }. 
3bb0: 20 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74   run_thread_test
3bc0: 73 20 31 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  s 1.  if {[lleng
3bd0: 74 68 20 24 6f 6d 69 74 4c 69 73 74 5d 3e 30 7d  th $omitList]>0}
3be0: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 4f 6d 69   {.    puts "Omi
3bf0: 74 74 65 64 20 74 65 73 74 20 63 61 73 65 73 3a  tted test cases:
3c00: 22 0a 20 20 20 20 73 65 74 20 70 72 65 63 20 7b  ".    set prec {
3c10: 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 72  }.    foreach {r
3c20: 65 63 7d 20 5b 6c 73 6f 72 74 20 24 6f 6d 69 74  ec} [lsort $omit
3c30: 4c 69 73 74 5d 20 7b 0a 20 20 20 20 20 20 69 66  List] {.      if
3c40: 20 7b 24 72 65 63 3d 3d 24 70 72 65 63 7d 20 63   {$rec==$prec} c
3c50: 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20 73 65  ontinue.      se
3c60: 74 20 70 72 65 63 20 24 72 65 63 0a 20 20 20 20  t prec $rec.    
3c70: 20 20 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b    puts [format {
3c80: 20 20 25 2d 31 32 73 20 25 73 7d 20 5b 6c 69 6e    %-12s %s} [lin
3c90: 64 65 78 20 24 72 65 63 20 30 5d 20 5b 6c 69 6e  dex $rec 0] [lin
3ca0: 64 65 78 20 24 72 65 63 20 31 5d 5d 0a 20 20 20  dex $rec 1]].   
3cb0: 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 45   }.  }.  if {$nE
3cc0: 72 72 3e 30 20 26 26 20 21 5b 77 6f 72 6b 69 6e  rr>0 && ![workin
3cd0: 67 5f 36 34 62 69 74 5f 69 6e 74 5d 7d 20 7b 0a  g_64bit_int]} {.
3ce0: 20 20 20 20 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a      puts "******
3cf0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20  ************".  
3d30: 20 20 70 75 74 73 20 22 4e 2e 42 2e 3a 20 20 54    puts "N.B.:  T
3d40: 68 65 20 76 65 72 73 69 6f 6e 20 6f 66 20 54 43  he version of TC
3d50: 4c 20 74 68 61 74 20 79 6f 75 20 75 73 65 64 20  L that you used 
3d60: 74 6f 20 62 75 69 6c 64 20 74 68 69 73 20 74 65  to build this te
3d70: 73 74 20 68 61 72 6e 65 73 73 22 0a 20 20 20 20  st harness".    
3d80: 70 75 74 73 20 22 69 73 20 64 65 66 65 63 74 69  puts "is defecti
3d90: 76 65 20 69 6e 20 74 68 61 74 20 69 74 20 64 6f  ve in that it do
3da0: 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 36  es not support 6
3db0: 34 2d 62 69 74 20 69 6e 74 65 67 65 72 73 2e 20  4-bit integers. 
3dc0: 20 53 6f 6d 65 20 6f 72 22 0a 20 20 20 20 70 75   Some or".    pu
3dd0: 74 73 20 22 61 6c 6c 20 6f 66 20 74 68 65 20 74  ts "all of the t
3de0: 65 73 74 20 66 61 69 6c 75 72 65 73 20 61 62 6f  est failures abo
3df0: 76 65 20 6d 69 67 68 74 20 62 65 20 61 20 72 65  ve might be a re
3e00: 73 75 6c 74 20 66 72 6f 6d 20 74 68 69 73 20 64  sult from this d
3e10: 65 66 65 63 74 22 0a 20 20 20 20 70 75 74 73 20  efect".    puts 
3e20: 22 69 6e 20 79 6f 75 72 20 54 43 4c 20 62 75 69  "in your TCL bui
3e30: 6c 64 2e 22 0a 20 20 20 20 70 75 74 73 20 22 2a  ld.".    puts "*
3e40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3e50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3e60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3e70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3e80: 2a 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24 3a 3a  *".  }.  if {$::
3e90: 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72  cmdlinearg(binar
3ea0: 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76 66 73  ylog)} {.    vfs
3eb0: 6c 6f 67 20 66 69 6e 61 6c 69 7a 65 20 62 69 6e  log finalize bin
3ec0: 61 72 79 6c 6f 67 0a 20 20 7d 0a 20 20 69 66 20  arylog.  }.  if 
3ed0: 7b 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  {$sqlite_open_fi
3ee0: 6c 65 5f 63 6f 75 6e 74 7d 20 7b 0a 20 20 20 20  le_count} {.    
3ef0: 70 75 74 73 20 22 24 73 71 6c 69 74 65 5f 6f 70  puts "$sqlite_op
3f00: 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 66 69  en_file_count fi
3f10: 6c 65 73 20 77 65 72 65 20 6c 65 66 74 20 6f 70  les were left op
3f20: 65 6e 22 0a 20 20 20 20 69 6e 63 72 20 6e 45 72  en".    incr nEr
3f30: 72 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 6c 69 6e  r.  }.  if {[lin
3f40: 64 65 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  dex [sqlite3_sta
3f50: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
3f60: 53 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30  S_MALLOC_COUNT 0
3f70: 5d 20 31 5d 3e 30 20 7c 7c 0a 20 20 20 20 20 20  ] 1]>0 ||.      
3f80: 20 20 20 20 20 20 20 20 5b 73 71 6c 69 74 65 33          [sqlite3
3f90: 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e 30 7d  _memory_used]>0}
3fa0: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 55 6e 66   {.    puts "Unf
3fb0: 72 65 65 64 20 6d 65 6d 6f 72 79 3a 20 5b 73 71  reed memory: [sq
3fc0: 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65  lite3_memory_use
3fd0: 64 5d 20 62 79 74 65 73 20 69 6e 5c 0a 20 20 20  d] bytes in\.   
3fe0: 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 5b 73        [lindex [s
3ff0: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
4000: 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c  LITE_STATUS_MALL
4010: 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d 20 61  OC_COUNT 0] 1] a
4020: 6c 6c 6f 63 61 74 69 6f 6e 73 22 0a 20 20 20 20  llocations".    
4030: 69 6e 63 72 20 6e 45 72 72 0a 20 20 20 20 69 66  incr nErr.    if
4040: 63 61 70 61 62 6c 65 20 6d 65 6d 64 65 62 75 67  capable memdebug
4050: 7c 7c 6d 65 6d 35 7c 7c 28 6d 65 6d 33 26 26 64  ||mem5||(mem3&&d
4060: 65 62 75 67 29 20 7b 0a 20 20 20 20 20 20 70 75  ebug) {.      pu
4070: 74 73 20 22 57 72 69 74 69 6e 67 20 75 6e 66 72  ts "Writing unfr
4080: 65 65 64 20 6d 65 6d 6f 72 79 20 6c 6f 67 20 74  eed memory log t
4090: 6f 20 5c 22 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78  o \"./memleak.tx
40a0: 74 5c 22 22 0a 20 20 20 20 20 20 73 71 6c 69 74  t\"".      sqlit
40b0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70  e3_memdebug_dump
40c0: 20 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 0a 20   ./memleak.txt. 
40d0: 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a     }.  } else {.
40e0: 20 20 20 20 70 75 74 73 20 22 41 6c 6c 20 6d 65      puts "All me
40f0: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73  mory allocations
4100: 20 66 72 65 65 64 20 2d 20 6e 6f 20 6c 65 61 6b   freed - no leak
4110: 73 22 0a 20 20 20 20 69 66 63 61 70 61 62 6c 65  s".    ifcapable
4120: 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d 35 20   memdebug||mem5 
4130: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
4140: 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f  memdebug_dump ./
4150: 6d 65 6d 75 73 61 67 65 2e 74 78 74 0a 20 20 20  memusage.txt.   
4160: 20 7d 0a 20 20 7d 0a 20 20 73 68 6f 77 5f 6d 65   }.  }.  show_me
4170: 6d 73 74 61 74 73 0a 20 20 70 75 74 73 20 22 4d  mstats.  puts "M
4180: 61 78 69 6d 75 6d 20 6d 65 6d 6f 72 79 20 75 73  aximum memory us
4190: 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65  age: [sqlite3_me
41a0: 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72 20 31  mory_highwater 1
41b0: 5d 20 62 79 74 65 73 22 0a 20 20 70 75 74 73 20  ] bytes".  puts 
41c0: 22 43 75 72 72 65 6e 74 20 6d 65 6d 6f 72 79 20  "Current memory 
41d0: 75 73 61 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f  usage: [sqlite3_
41e0: 6d 65 6d 6f 72 79 5f 68 69 67 68 77 61 74 65 72  memory_highwater
41f0: 5d 20 62 79 74 65 73 22 0a 20 20 69 66 20 7b 5b  ] bytes".  if {[
4200: 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20 73 71  info commands sq
4210: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6d  lite3_memdebug_m
4220: 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20 6e 65 20  alloc_count] ne 
4230: 22 22 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22  ""} {.    puts "
4240: 4e 75 6d 62 65 72 20 6f 66 20 6d 61 6c 6c 6f 63  Number of malloc
4250: 28 29 20 20 3a 20 5b 73 71 6c 69 74 65 33 5f 6d  ()  : [sqlite3_m
4260: 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63  emdebug_malloc_c
4270: 6f 75 6e 74 5d 20 63 61 6c 6c 73 22 0a 20 20 7d  ount] calls".  }
4280: 0a 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e  .  if {$::cmdlin
4290: 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65  earg(malloctrace
42a0: 29 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 57  )} {.    puts "W
42b0: 72 69 74 69 6e 67 20 6d 61 6c 6c 6f 63 73 2e 73  riting mallocs.s
42c0: 71 6c 2e 2e 2e 22 0a 20 20 20 20 6d 65 6d 64 65  ql...".    memde
42d0: 62 75 67 5f 6c 6f 67 5f 73 71 6c 0a 20 20 20 20  bug_log_sql.    
42e0: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
42f0: 5f 6c 6f 67 20 73 74 6f 70 0a 20 20 20 20 73 71  _log stop.    sq
4300: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c  lite3_memdebug_l
4310: 6f 67 20 63 6c 65 61 72 0a 0a 20 20 20 20 69 66  og clear..    if
4320: 20 7b 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72   {[sqlite3_memor
4330: 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20 20 20  y_used]>0} {.   
4340: 20 20 20 70 75 74 73 20 22 57 72 69 74 69 6e 67     puts "Writing
4350: 20 6c 65 61 6b 73 2e 73 71 6c 2e 2e 2e 22 0a 20   leaks.sql...". 
4360: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d       sqlite3_mem
4370: 64 65 62 75 67 5f 6c 6f 67 20 73 79 6e 63 0a 20  debug_log sync. 
4380: 20 20 20 20 20 6d 65 6d 64 65 62 75 67 5f 6c 6f       memdebug_lo
4390: 67 5f 73 71 6c 20 6c 65 61 6b 73 2e 73 71 6c 0a  g_sql leaks.sql.
43a0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66 6f 72 65      }.  }.  fore
43b0: 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ach f [glob -noc
43c0: 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d  omplain test.db-
43d0: 2a 2d 6a 6f 75 72 6e 61 6c 5d 20 7b 0a 20 20 20  *-journal] {.   
43e0: 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f   file delete -fo
43f0: 72 63 65 20 24 66 0a 20 20 7d 0a 20 20 66 6f 72  rce $f.  }.  for
4400: 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f  each f [glob -no
4410: 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62  complain test.db
4420: 2d 6d 6a 2a 5d 20 7b 0a 20 20 20 20 66 69 6c 65  -mj*] {.    file
4430: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 24   delete -force $
4440: 66 0a 20 20 7d 0a 20 20 65 78 69 74 20 5b 65 78  f.  }.  exit [ex
4450: 70 72 20 7b 24 6e 45 72 72 3e 30 7d 5d 0a 7d 0a  pr {$nErr>0}].}.
4460: 0a 23 20 44 69 73 70 6c 61 79 20 6d 65 6d 6f 72  .# Display memor
4470: 79 20 73 74 61 74 69 73 74 69 63 73 20 66 6f 72  y statistics for
4480: 20 61 6e 61 6c 79 73 69 73 20 61 6e 64 20 64 65   analysis and de
4490: 62 75 67 67 69 6e 67 20 70 75 72 70 6f 73 65 73  bugging purposes
44a0: 2e 0a 23 0a 70 72 6f 63 20 73 68 6f 77 5f 6d 65  ..#.proc show_me
44b0: 6d 73 74 61 74 73 20 7b 7d 20 7b 0a 20 20 73 65  mstats {} {.  se
44c0: 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  t x [sqlite3_sta
44d0: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
44e0: 53 5f 4d 45 4d 4f 52 59 5f 55 53 45 44 20 30 5d  S_MEMORY_USED 0]
44f0: 0a 20 20 73 65 74 20 79 20 5b 73 71 6c 69 74 65  .  set y [sqlite
4500: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
4510: 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 53 49  STATUS_MALLOC_SI
4520: 5a 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20  ZE 0].  set val 
4530: 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30  [format {now %10
4540: 64 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78  d  max %10d  max
4550: 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20  -size %10d} \.  
4560: 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e              [lin
4570: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
4580: 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20  x $x 2] [lindex 
4590: 24 79 20 32 5d 5d 0a 20 20 70 75 74 73 20 22 4d  $y 2]].  puts "M
45a0: 65 6d 6f 72 79 20 75 73 65 64 3a 20 20 20 20 20  emory used:     
45b0: 20 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74       $val".  set
45c0: 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   x [sqlite3_stat
45d0: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
45e0: 5f 4d 41 4c 4c 4f 43 5f 43 4f 55 4e 54 20 30 5d  _MALLOC_COUNT 0]
45f0: 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d  .  set val [form
4600: 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61  at {now %10d  ma
4610: 78 20 25 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20  x %10d} [lindex 
4620: 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78  $x 1] [lindex $x
4630: 20 32 5d 5d 0a 20 20 70 75 74 73 20 22 41 6c 6c   2]].  puts "All
4640: 6f 63 61 74 69 6f 6e 20 63 6f 75 6e 74 3a 20 20  ocation count:  
4650: 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74 20 78     $val".  set x
4660: 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73   [sqlite3_status
4670: 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50   SQLITE_STATUS_P
4680: 41 47 45 43 41 43 48 45 5f 55 53 45 44 20 30 5d  AGECACHE_USED 0]
4690: 0a 20 20 73 65 74 20 79 20 5b 73 71 6c 69 74 65  .  set y [sqlite
46a0: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
46b0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
46c0: 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74 20 76  _SIZE 0].  set v
46d0: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
46e0: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 20 20  %10d  max %10d  
46f0: 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c  max-size %10d} \
4700: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5b  .              [
4710: 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69  lindex $x 1] [li
4720: 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64  ndex $x 2] [lind
4730: 65 78 20 24 79 20 32 5d 5d 0a 20 20 70 75 74 73  ex $y 2]].  puts
4740: 20 22 50 61 67 65 2d 63 61 63 68 65 20 75 73 65   "Page-cache use
4750: 64 3a 20 20 20 20 20 20 24 76 61 6c 22 0a 20 20  d:      $val".  
4760: 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73  set x [sqlite3_s
4770: 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41  tatus SQLITE_STA
4780: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56  TUS_PAGECACHE_OV
4790: 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20  ERFLOW 0].  set 
47a0: 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77  val [format {now
47b0: 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d   %10d  max %10d}
47c0: 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b   [lindex $x 1] [
47d0: 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20  lindex $x 2]].  
47e0: 70 75 74 73 20 22 50 61 67 65 2d 63 61 63 68 65  puts "Page-cache
47f0: 20 6f 76 65 72 66 6c 6f 77 3a 20 20 24 76 61 6c   overflow:  $val
4800: 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74  ".  set x [sqlit
4810: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
4820: 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43 48 5f  _STATUS_SCRATCH_
4830: 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20 76 61  USED 0].  set va
4840: 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25  l [format {now %
4850: 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b  10d  max %10d} [
4860: 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69  lindex $x 1] [li
4870: 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 70 75  ndex $x 2]].  pu
4880: 74 73 20 22 53 63 72 61 74 63 68 20 6d 65 6d 6f  ts "Scratch memo
4890: 72 79 20 75 73 65 64 3a 20 20 24 76 61 6c 22 0a  ry used:  $val".
48a0: 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33    set x [sqlite3
48b0: 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53  _status SQLITE_S
48c0: 54 41 54 55 53 5f 53 43 52 41 54 43 48 5f 4f 56  TATUS_SCRATCH_OV
48d0: 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20  ERFLOW 0].  set 
48e0: 79 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75  y [sqlite3_statu
48f0: 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  s SQLITE_STATUS_
4900: 53 43 52 41 54 43 48 5f 53 49 5a 45 20 30 5d 0a  SCRATCH_SIZE 0].
4910: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
4920: 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61 78  t {now %10d  max
4930: 20 25 31 30 64 20 20 6d 61 78 2d 73 69 7a 65 20   %10d  max-size 
4940: 25 31 30 64 7d 20 5c 0a 20 20 20 20 20 20 20 20  %10d} \.        
4950: 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24         [lindex $
4960: 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20  x 1] [lindex $x 
4970: 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d  2] [lindex $y 2]
4980: 5d 0a 20 20 70 75 74 73 20 22 53 63 72 61 74 63  ].  puts "Scratc
4990: 68 20 6f 76 65 72 66 6c 6f 77 3a 20 20 20 20 20  h overflow:     
49a0: 24 76 61 6c 22 0a 20 20 69 66 63 61 70 61 62 6c  $val".  ifcapabl
49b0: 65 20 79 79 74 72 61 63 6b 6d 61 78 73 74 61 63  e yytrackmaxstac
49c0: 6b 64 65 70 74 68 20 7b 0a 20 20 20 20 73 65 74  kdepth {.    set
49d0: 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   x [sqlite3_stat
49e0: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
49f0: 5f 50 41 52 53 45 52 5f 53 54 41 43 4b 20 30 5d  _PARSER_STACK 0]
4a00: 0a 20 20 20 20 73 65 74 20 76 61 6c 20 5b 66 6f  .    set val [fo
4a10: 72 6d 61 74 20 7b 20 20 20 20 20 20 20 20 20 20  rmat {          
4a20: 20 20 20 20 20 6d 61 78 20 25 31 30 64 7d 20 5b       max %10d} [
4a30: 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20  lindex $x 2]].  
4a40: 20 20 70 75 74 73 20 22 50 61 72 73 65 72 20 73    puts "Parser s
4a50: 74 61 63 6b 20 64 65 70 74 68 3a 20 20 20 20 24  tack depth:    $
4a60: 76 61 6c 22 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20  val".  }.}..# A 
4a70: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65  procedure to exe
4a80: 63 75 74 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20  cute SQL.#.proc 
4a90: 65 78 65 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62  execsql {sql {db
4aa0: 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73   db}} {.  # puts
4ab0: 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20   "SQL = $sql".  
4ac0: 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64  uplevel [list $d
4ad0: 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a  b eval $sql].}..
4ae0: 23 20 45 78 65 63 75 74 65 20 53 51 4c 20 61 6e  # Execute SQL an
4af0: 64 20 63 61 74 63 68 20 65 78 63 65 70 74 69 6f  d catch exceptio
4b00: 6e 73 2e 0a 23 0a 70 72 6f 63 20 63 61 74 63 68  ns..#.proc catch
4b10: 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d  sql {sql {db db}
4b20: 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51  } {.  # puts "SQ
4b30: 4c 20 3d 20 24 73 71 6c 22 0a 20 20 73 65 74 20  L = $sql".  set 
4b40: 72 20 5b 63 61 74 63 68 20 5b 6c 69 73 74 20 75  r [catch [list u
4b50: 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62  plevel [list $db
4b60: 20 65 76 61 6c 20 24 73 71 6c 5d 5d 20 6d 73 67   eval $sql]] msg
4b70: 5d 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d  ].  lappend r $m
4b80: 73 67 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d  sg.  return $r.}
4b90: 0a 0a 23 20 44 6f 20 61 6e 20 56 44 42 45 20 63  ..# Do an VDBE c
4ba0: 6f 64 65 20 64 75 6d 70 20 6f 6e 20 74 68 65 20  ode dump on the 
4bb0: 53 51 4c 20 67 69 76 65 6e 0a 23 0a 70 72 6f 63  SQL given.#.proc
4bc0: 20 65 78 70 6c 61 69 6e 20 7b 73 71 6c 20 7b 64   explain {sql {d
4bd0: 62 20 64 62 7d 7d 20 7b 0a 20 20 70 75 74 73 20  b db}} {.  puts 
4be0: 22 22 0a 20 20 70 75 74 73 20 22 61 64 64 72 20  "".  puts "addr 
4bf0: 20 6f 70 63 6f 64 65 20 20 20 20 20 20 20 20 70   opcode        p
4c00: 31 20 20 20 20 20 20 70 32 20 20 20 20 20 20 70  1      p2      p
4c10: 33 20 20 20 20 20 20 70 34 20 20 20 20 20 20 20  3      p4       
4c20: 20 20 20 20 20 20 20 20 70 35 20 20 23 22 0a 20          p5  #". 
4c30: 20 70 75 74 73 20 22 2d 2d 2d 2d 20 20 2d 2d 2d   puts "----  ---
4c40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  ---------  -----
4c50: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
4c60: 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  -  -------------
4c70: 2d 2d 20 20 2d 2d 20 20 2d 22 0a 20 20 24 64 62  --  --  -".  $db
4c80: 20 65 76 61 6c 20 22 65 78 70 6c 61 69 6e 20 24   eval "explain $
4c90: 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20 70 75  sql" {} {.    pu
4ca0: 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64  ts [format {%-4d
4cb0: 20 20 25 2d 31 32 2e 31 32 73 20 20 25 2d 36 64    %-12.12s  %-6d
4cc0: 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20 25 20    %-6d  %-6d  % 
4cd0: 2d 31 37 73 20 25 73 20 20 25 73 7d 20 5c 0a 20  -17s %s  %s} \. 
4ce0: 20 20 20 20 20 24 61 64 64 72 20 24 6f 70 63 6f       $addr $opco
4cf0: 64 65 20 24 70 31 20 24 70 32 20 24 70 33 20 24  de $p1 $p2 $p3 $
4d00: 70 34 20 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a  p4 $p5 $comment.
4d10: 20 20 20 20 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 53      ].  }.}..# S
4d20: 68 6f 77 20 74 68 65 20 56 44 42 45 20 70 72 6f  how the VDBE pro
4d30: 67 72 61 6d 20 66 6f 72 20 61 6e 20 53 51 4c 20  gram for an SQL 
4d40: 73 74 61 74 65 6d 65 6e 74 20 62 75 74 20 6f 6d  statement but om
4d50: 69 74 20 74 68 65 20 54 72 61 63 65 0a 23 20 6f  it the Trace.# o
4d60: 70 63 6f 64 65 20 61 74 20 74 68 65 20 62 65 67  pcode at the beg
4d70: 69 6e 6e 69 6e 67 2e 20 20 54 68 69 73 20 70 72  inning.  This pr
4d80: 6f 63 65 64 75 72 65 20 63 61 6e 20 62 65 20 75  ocedure can be u
4d90: 73 65 64 20 74 6f 20 70 72 6f 76 65 0a 23 20 74  sed to prove.# t
4da0: 68 61 74 20 64 69 66 66 65 72 65 6e 74 20 53 51  hat different SQ
4db0: 4c 20 73 74 61 74 65 6d 65 6e 74 73 20 67 65 6e  L statements gen
4dc0: 65 72 61 74 65 20 65 78 61 63 74 6c 79 20 74 68  erate exactly th
4dd0: 65 20 73 61 6d 65 20 56 44 42 45 20 63 6f 64 65  e same VDBE code
4de0: 2e 0a 23 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e  ..#.proc explain
4df0: 5f 6e 6f 5f 74 72 61 63 65 20 7b 73 71 6c 7d 20  _no_trace {sql} 
4e00: 7b 0a 20 20 73 65 74 20 74 72 20 5b 64 62 20 65  {.  set tr [db e
4e10: 76 61 6c 20 22 45 58 50 4c 41 49 4e 20 24 73 71  val "EXPLAIN $sq
4e20: 6c 22 5d 0a 20 20 72 65 74 75 72 6e 20 5b 6c 72  l"].  return [lr
4e30: 61 6e 67 65 20 24 74 72 20 37 20 65 6e 64 5d 0a  ange $tr 7 end].
4e40: 7d 0a 0a 23 20 41 6e 6f 74 68 65 72 20 70 72 6f  }..# Another pro
4e50: 63 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74  cedure to execut
4e60: 65 20 53 51 4c 2e 20 20 54 68 69 73 20 6f 6e 65  e SQL.  This one
4e70: 20 69 6e 63 6c 75 64 65 73 20 74 68 65 20 66 69   includes the fi
4e80: 65 6c 64 0a 23 20 6e 61 6d 65 73 20 69 6e 20 74  eld.# names in t
4e90: 68 65 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74  he returned list
4ea0: 2e 0a 23 0a 70 72 6f 63 20 65 78 65 63 73 71 6c  ..#.proc execsql
4eb0: 32 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20  2 {sql} {.  set 
4ec0: 72 65 73 75 6c 74 20 7b 7d 0a 20 20 64 62 20 65  result {}.  db e
4ed0: 76 61 6c 20 24 73 71 6c 20 64 61 74 61 20 7b 0a  val $sql data {.
4ee0: 20 20 20 20 66 6f 72 65 61 63 68 20 66 20 24 64      foreach f $d
4ef0: 61 74 61 28 2a 29 20 7b 0a 20 20 20 20 20 20 6c  ata(*) {.      l
4f00: 61 70 70 65 6e 64 20 72 65 73 75 6c 74 20 24 66  append result $f
4f10: 20 24 64 61 74 61 28 24 66 29 0a 20 20 20 20 7d   $data($f).    }
4f20: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72  .  }.  return $r
4f30: 65 73 75 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 74  esult.}..# Use t
4f40: 68 65 20 6e 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20  he non-callback 
4f50: 41 50 49 20 74 6f 20 65 78 65 63 75 74 65 20 6d  API to execute m
4f60: 75 6c 74 69 70 6c 65 20 53 51 4c 20 73 74 61 74  ultiple SQL stat
4f70: 65 6d 65 6e 74 73 0a 23 0a 70 72 6f 63 20 73 74  ements.#.proc st
4f80: 65 70 73 71 6c 20 7b 64 62 70 74 72 20 73 71 6c  epsql {dbptr sql
4f90: 7d 20 7b 0a 20 20 73 65 74 20 73 71 6c 20 5b 73  } {.  set sql [s
4fa0: 74 72 69 6e 67 20 74 72 69 6d 20 24 73 71 6c 5d  tring trim $sql]
4fb0: 0a 20 20 73 65 74 20 72 20 30 0a 20 20 77 68 69  .  set r 0.  whi
4fc0: 6c 65 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67  le {[string leng
4fd0: 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20  th $sql]>0} {.  
4fe0: 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 73 71    if {[catch {sq
4ff0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 20 24 64  lite3_prepare $d
5000: 62 70 74 72 20 24 73 71 6c 20 2d 31 20 73 71 6c  bptr $sql -1 sql
5010: 74 61 69 6c 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20  tail} vm]} {.   
5020: 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20     return [list 
5030: 31 20 24 76 6d 5d 0a 20 20 20 20 7d 0a 20 20 20  1 $vm].    }.   
5040: 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69 6e 67   set sql [string
5050: 20 74 72 69 6d 20 24 73 71 6c 74 61 69 6c 5d 0a   trim $sqltail].
5060: 23 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c  #    while {[sql
5070: 69 74 65 5f 73 74 65 70 20 24 76 6d 20 4e 20 56  ite_step $vm N V
5080: 41 4c 20 43 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45  AL COL]=="SQLITE
5090: 5f 52 4f 57 22 7d 20 7b 0a 23 20 20 20 20 20 20  _ROW"} {.#      
50a0: 66 6f 72 65 61 63 68 20 76 20 24 56 41 4c 20 7b  foreach v $VAL {
50b0: 6c 61 70 70 65 6e 64 20 72 20 24 76 7d 0a 23 20  lappend r $v}.# 
50c0: 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65 20 7b     }.    while {
50d0: 5b 73 71 6c 69 74 65 33 5f 73 74 65 70 20 24 76  [sqlite3_step $v
50e0: 6d 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22  m]=="SQLITE_ROW"
50f0: 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73  } {.      for {s
5100: 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b 73 71 6c  et i 0} {$i<[sql
5110: 69 74 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 20  ite3_data_count 
5120: 24 76 6d 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  $vm]} {incr i} {
5130: 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64  .        lappend
5140: 20 72 20 5b 73 71 6c 69 74 65 33 5f 63 6f 6c 75   r [sqlite3_colu
5150: 6d 6e 5f 74 65 78 74 20 24 76 6d 20 24 69 5d 0a  mn_text $vm $i].
5160: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
5170: 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 73 71    if {[catch {sq
5180: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24  lite3_finalize $
5190: 76 6d 7d 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20  vm} errmsg]} {. 
51a0: 20 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73       return [lis
51b0: 74 20 31 20 24 65 72 72 6d 73 67 5d 0a 20 20 20  t 1 $errmsg].   
51c0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
51d0: 24 72 0a 7d 0a 0a 23 20 44 65 6c 65 74 65 20 61  $r.}..# Delete a
51e0: 20 66 69 6c 65 20 6f 72 20 64 69 72 65 63 74 6f   file or directo
51f0: 72 79 0a 23 0a 70 72 6f 63 20 66 6f 72 63 65 64  ry.#.proc forced
5200: 65 6c 65 74 65 20 7b 61 72 67 73 7d 20 7b 0a 20  elete {args} {. 
5210: 20 66 6f 72 65 61 63 68 20 66 69 6c 65 6e 61 6d   foreach filenam
5220: 65 20 24 61 72 67 73 20 7b 0a 20 20 20 20 23 20  e $args {.    # 
5230: 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65  On windows, some
5240: 74 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 66 69  times even a [fi
5250: 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65  le delete -force
5260: 5d 20 63 61 6e 20 66 61 69 6c 20 6a 75 73 74 20  ] can fail just 
5270: 61 66 74 65 72 0a 20 20 20 20 23 20 61 20 66 69  after.    # a fi
5280: 6c 65 20 69 73 20 63 6c 6f 73 65 64 2e 20 54 68  le is closed. Th
5290: 65 20 63 61 75 73 65 20 69 73 20 75 73 75 61 6c  e cause is usual
52a0: 6c 79 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22 20  ly "tag-alongs" 
52b0: 2d 20 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65 0a  - programs like.
52c0: 20 20 20 20 23 20 61 6e 74 69 2d 76 69 72 75 73      # anti-virus
52d0: 20 73 6f 66 74 77 61 72 65 2c 20 61 75 74 6f 6d   software, autom
52e0: 61 74 69 63 20 62 61 63 6b 75 70 20 74 6f 6f 6c  atic backup tool
52f0: 73 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65 78  s and various ex
5300: 70 6c 6f 72 65 72 0a 20 20 20 20 23 20 65 78 74  plorer.    # ext
5310: 65 6e 73 69 6f 6e 73 20 74 68 61 74 20 6b 65 65  ensions that kee
5320: 70 20 61 20 66 69 6c 65 20 6f 70 65 6e 20 61 20  p a file open a 
5330: 6c 69 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74 68  little longer th
5340: 61 6e 20 77 65 20 65 78 70 65 63 74 2c 20 63 61  an we expect, ca
5350: 75 73 69 6e 67 0a 20 20 20 20 23 20 74 68 65 20  using.    # the 
5360: 64 65 6c 65 74 65 20 74 6f 20 66 61 69 6c 2e 0a  delete to fail..
5370: 20 20 20 20 23 0a 20 20 20 20 23 20 54 68 65 20      #.    # The 
5380: 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20 77  solution is to w
5390: 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f 75  ait a short amou
53a0: 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f 72  nt of time befor
53b0: 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 20 0a  e retrying the .
53c0: 20 20 20 20 23 20 64 65 6c 65 74 65 2e 0a 20 20      # delete..  
53d0: 20 20 23 0a 20 20 20 20 73 65 74 20 6e 52 65 74    #.    set nRet
53e0: 72 79 20 20 35 30 20 20 20 20 20 20 20 20 20 20  ry  50          
53f0: 20 20 20 20 20 20 20 20 3b 23 20 4d 61 78 69 6d          ;# Maxim
5400: 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 74  um number of ret
5410: 72 69 65 73 2e 0a 20 20 20 20 73 65 74 20 6e 44  ries..    set nD
5420: 65 6c 61 79 20 31 30 30 20 20 20 20 20 20 20 20  elay 100        
5430: 20 20 20 20 20 20 20 20 20 20 3b 23 20 44 65 6c            ;# Del
5440: 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72 65 20  ay in ms before 
5450: 72 65 74 72 79 69 6e 67 2e 0a 20 20 20 20 66 6f  retrying..    fo
5460: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c  r {set i 0} {$i<
5470: 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63 72 20 69  $nRetry} {incr i
5480: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 72 63  } {.      set rc
5490: 20 5b 63 61 74 63 68 20 7b 66 69 6c 65 20 64 65   [catch {file de
54a0: 6c 65 74 65 20 2d 66 6f 72 63 65 20 24 66 69 6c  lete -force $fil
54b0: 65 6e 61 6d 65 7d 20 6d 73 67 5d 0a 20 20 20 20  ename} msg].    
54c0: 20 20 69 66 20 7b 24 72 63 3d 3d 30 7d 20 62 72    if {$rc==0} br
54d0: 65 61 6b 0a 20 20 20 20 20 20 61 66 74 65 72 20  eak.      after 
54e0: 24 6e 44 65 6c 61 79 0a 20 20 20 20 7d 0a 20 20  $nDelay.    }.  
54f0: 20 20 69 66 20 7b 24 72 63 7d 20 7b 20 65 72 72    if {$rc} { err
5500: 6f 72 20 24 6d 73 67 20 7d 0a 20 20 7d 0a 7d 0a  or $msg }.  }.}.
5510: 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67 72 69  .# Do an integri
5520: 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68 65 20  ty check of the 
5530: 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65 0a  entire database.
5540: 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69 74 79  #.proc integrity
5550: 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20 7b 64 62  _check {name {db
5560: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61   db}} {.  ifcapa
5570: 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20  ble integrityck 
5580: 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e  {.    do_test $n
5590: 61 6d 65 20 5b 6c 69 73 74 20 65 78 65 63 73 71  ame [list execsq
55a0: 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72  l {PRAGMA integr
55b0: 69 74 79 5f 63 68 65 63 6b 7d 20 24 64 62 5d 20  ity_check} $db] 
55c0: 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 0a 23 20 52  {ok}.  }.}...# R
55d0: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68  eturn true if th
55e0: 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20  e SQL statement 
55f0: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73 65  passed as the se
5600: 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 75 73  cond argument us
5610: 65 73 20 61 0a 23 20 73 74 61 74 65 6d 65 6e 74  es a.# statement
5620: 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 23 0a   transaction..#.
5630: 70 72 6f 63 20 73 71 6c 5f 75 73 65 73 5f 73 74  proc sql_uses_st
5640: 6d 74 20 7b 64 62 20 73 71 6c 7d 20 7b 0a 20 20  mt {db sql} {.  
5650: 73 65 74 20 73 74 6d 74 20 5b 73 71 6c 69 74 65  set stmt [sqlite
5660: 33 5f 70 72 65 70 61 72 65 20 24 64 62 20 24 73  3_prepare $db $s
5670: 71 6c 20 2d 31 20 64 75 6d 6d 79 5d 0a 20 20 73  ql -1 dummy].  s
5680: 65 74 20 75 73 65 73 20 5b 75 73 65 73 5f 73 74  et uses [uses_st
5690: 6d 74 5f 6a 6f 75 72 6e 61 6c 20 24 73 74 6d 74  mt_journal $stmt
56a0: 5d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  ].  sqlite3_fina
56b0: 6c 69 7a 65 20 24 73 74 6d 74 0a 20 20 72 65 74  lize $stmt.  ret
56c0: 75 72 6e 20 24 75 73 65 73 0a 7d 0a 0a 70 72 6f  urn $uses.}..pro
56d0: 63 20 66 69 78 5f 69 66 63 61 70 61 62 6c 65 5f  c fix_ifcapable_
56e0: 65 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a 20 20  expr {expr} {.  
56f0: 73 65 74 20 72 65 74 20 22 22 0a 20 20 73 65 74  set ret "".  set
5700: 20 73 74 61 74 65 20 30 0a 20 20 66 6f 72 20 7b   state 0.  for {
5710: 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b  set i 0} {$i < [
5720: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 65  string length $e
5730: 78 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  xpr]} {incr i} {
5740: 0a 20 20 20 20 73 65 74 20 63 68 61 72 20 5b 73  .    set char [s
5750: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70  tring range $exp
5760: 72 20 24 69 20 24 69 5d 0a 20 20 20 20 73 65 74  r $i $i].    set
5770: 20 6e 65 77 73 74 61 74 65 20 5b 65 78 70 72 20   newstate [expr 
5780: 7b 5b 73 74 72 69 6e 67 20 69 73 20 61 6c 6e 75  {[string is alnu
5790: 6d 20 24 63 68 61 72 5d 20 7c 7c 20 24 63 68 61  m $char] || $cha
57a0: 72 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20 20 69  r eq "_"}].    i
57b0: 66 20 7b 24 6e 65 77 73 74 61 74 65 20 26 26 20  f {$newstate && 
57c0: 21 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20  !$state} {.     
57d0: 20 61 70 70 65 6e 64 20 72 65 74 20 7b 24 3a 3a   append ret {$::
57e0: 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 7d  sqlite_options(}
57f0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 21  .    }.    if {!
5800: 24 6e 65 77 73 74 61 74 65 20 26 26 20 24 73 74  $newstate && $st
5810: 61 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70 70  ate} {.      app
5820: 65 6e 64 20 72 65 74 20 29 0a 20 20 20 20 7d 0a  end ret ).    }.
5830: 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 24      append ret $
5840: 63 68 61 72 0a 20 20 20 20 73 65 74 20 73 74 61  char.    set sta
5850: 74 65 20 24 6e 65 77 73 74 61 74 65 0a 20 20 7d  te $newstate.  }
5860: 0a 20 20 69 66 20 7b 24 73 74 61 74 65 7d 20 7b  .  if {$state} {
5870: 61 70 70 65 6e 64 20 72 65 74 20 29 7d 0a 20 20  append ret )}.  
5880: 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23  return $ret.}..#
5890: 20 45 76 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c   Evaluate a bool
58a0: 65 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 6f  ean expression o
58b0: 66 20 63 61 70 61 62 69 6c 69 74 69 65 73 2e 20  f capabilities. 
58c0: 20 49 66 20 74 72 75 65 2c 20 65 78 65 63 75 74   If true, execut
58d0: 65 20 74 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f  e the.# code.  O
58e0: 6d 69 74 20 74 68 65 20 63 6f 64 65 20 69 66 20  mit the code if 
58f0: 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66  false..#.proc if
5900: 63 61 70 61 62 6c 65 20 7b 65 78 70 72 20 63 6f  capable {expr co
5910: 64 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c  de {else ""} {el
5920: 73 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20  secode ""}} {.  
5930: 23 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61  #regsub -all {[a
5940: 2d 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20  -z_0-9]+} $expr 
5950: 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f  {$::sqlite_optio
5960: 6e 73 28 26 29 7d 20 65 32 0a 20 20 73 65 74 20  ns(&)} e2.  set 
5970: 65 32 20 5b 66 69 78 5f 69 66 63 61 70 61 62 6c  e2 [fix_ifcapabl
5980: 65 5f 65 78 70 72 20 24 65 78 70 72 5d 0a 20 20  e_expr $expr].  
5990: 69 66 20 28 24 65 32 29 20 7b 0a 20 20 20 20 73  if ($e2) {.    s
59a0: 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c  et c [catch {upl
59b0: 65 76 65 6c 20 31 20 24 63 6f 64 65 7d 20 72 5d  evel 1 $code} r]
59c0: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
59d0: 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70  set c [catch {up
59e0: 6c 65 76 65 6c 20 31 20 24 65 6c 73 65 63 6f 64  level 1 $elsecod
59f0: 65 7d 20 72 5d 0a 20 20 7d 0a 20 20 72 65 74 75  e} r].  }.  retu
5a00: 72 6e 20 2d 63 6f 64 65 20 24 63 20 24 72 0a 7d  rn -code $c $r.}
5a10: 0a 0a 23 20 54 68 69 73 20 70 72 6f 63 20 65 78  ..# This proc ex
5a20: 65 63 73 20 61 20 73 65 70 65 72 61 74 65 20 70  ecs a seperate p
5a30: 72 6f 63 65 73 73 20 74 68 61 74 20 63 72 61 73  rocess that cras
5a40: 68 65 73 20 6d 69 64 77 61 79 20 74 68 72 6f 75  hes midway throu
5a50: 67 68 20 65 78 65 63 75 74 69 6e 67 0a 23 20 74  gh executing.# t
5a60: 68 65 20 53 51 4c 20 73 63 72 69 70 74 20 24 73  he SQL script $s
5a70: 71 6c 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74  ql on database t
5a80: 65 73 74 2e 64 62 2e 0a 23 0a 23 20 54 68 65 20  est.db..#.# The 
5a90: 63 72 61 73 68 20 6f 63 63 75 72 73 20 64 75 72  crash occurs dur
5aa0: 69 6e 67 20 61 20 73 79 6e 63 28 29 20 6f 66 20  ing a sync() of 
5ab0: 66 69 6c 65 20 24 63 72 61 73 68 66 69 6c 65 2e  file $crashfile.
5ac0: 20 57 68 65 6e 20 74 68 65 20 63 72 61 73 68 0a   When the crash.
5ad0: 23 20 6f 63 63 75 72 73 20 61 20 72 61 6e 64 6f  # occurs a rando
5ae0: 6d 20 73 75 62 73 65 74 20 6f 66 20 61 6c 6c 20  m subset of all 
5af0: 75 6e 73 79 6e 63 65 64 20 77 72 69 74 65 73 20  unsynced writes 
5b00: 6d 61 64 65 20 62 79 20 74 68 65 20 70 72 6f 63  made by the proc
5b10: 65 73 73 20 61 72 65 0a 23 20 77 72 69 74 74 65  ess are.# writte
5b20: 6e 20 69 6e 74 6f 20 74 68 65 20 66 69 6c 65 73  n into the files
5b30: 20 6f 6e 20 64 69 73 6b 2e 20 41 72 67 75 6d 65   on disk. Argume
5b40: 6e 74 20 24 63 72 61 73 68 64 65 6c 61 79 20 69  nt $crashdelay i
5b50: 6e 64 69 63 61 74 65 73 20 74 68 65 0a 23 20 6e  ndicates the.# n
5b60: 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 20 73 79  umber of file sy
5b70: 6e 63 73 20 74 6f 20 77 61 69 74 20 62 65 66 6f  ncs to wait befo
5b80: 72 65 20 63 72 61 73 68 69 6e 67 2e 0a 23 0a 23  re crashing..#.#
5b90: 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   The return valu
5ba0: 65 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 74  e is a list of t
5bb0: 77 6f 20 65 6c 65 6d 65 6e 74 73 2e 20 54 68 65  wo elements. The
5bc0: 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20 69   first element i
5bd0: 73 20 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20 69  s a.# boolean, i
5be0: 6e 64 69 63 61 74 69 6e 67 20 77 68 65 74 68 65  ndicating whethe
5bf0: 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 70 72 6f  r or not the pro
5c00: 63 65 73 73 20 61 63 74 75 61 6c 6c 79 20 63 72  cess actually cr
5c10: 61 73 68 65 64 20 6f 72 0a 23 20 72 65 70 6f 72  ashed or.# repor
5c20: 74 65 64 20 73 6f 6d 65 20 6f 74 68 65 72 20 65  ted some other e
5c30: 72 72 6f 72 2e 20 54 68 65 20 73 65 63 6f 6e 64  rror. The second
5c40: 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20   element in the 
5c50: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 20 69 73  returned list is
5c60: 20 74 68 65 0a 23 20 65 72 72 6f 72 20 6d 65 73   the.# error mes
5c70: 73 61 67 65 2e 20 54 68 69 73 20 69 73 20 22 63  sage. This is "c
5c80: 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78 69  hild process exi
5c90: 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 20  ted abnormally" 
5ca0: 69 66 20 74 68 65 20 63 72 61 73 68 0a 23 20 6f  if the crash.# o
5cb0: 63 63 75 72 65 64 2e 0a 23 0a 23 20 20 20 63 72  ccured..#.#   cr
5cc0: 61 73 68 73 71 6c 20 2d 64 65 6c 61 79 20 43 52  ashsql -delay CR
5cd0: 41 53 48 44 45 4c 41 59 20 2d 66 69 6c 65 20 43  ASHDELAY -file C
5ce0: 52 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f 63 6b  RASHFILE ?-block
5cf0: 73 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45 3f 20  size BLOCKSIZE? 
5d00: 24 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72 61 73  $sql.#.proc cras
5d10: 68 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a 0a 20  hsql {args} {.. 
5d20: 20 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22   set blocksize "
5d30: 22 0a 20 20 73 65 74 20 63 72 61 73 68 64 65 6c  ".  set crashdel
5d40: 61 79 20 31 0a 20 20 73 65 74 20 70 72 6e 67 73  ay 1.  set prngs
5d50: 65 65 64 20 30 0a 20 20 73 65 74 20 74 63 6c 62  eed 0.  set tclb
5d60: 6f 64 79 20 7b 7d 0a 20 20 73 65 74 20 63 72 61  ody {}.  set cra
5d70: 73 68 66 69 6c 65 20 22 22 0a 20 20 73 65 74 20  shfile "".  set 
5d80: 64 63 20 22 22 0a 20 20 73 65 74 20 73 71 6c 20  dc "".  set sql 
5d90: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65 6e  [lindex $args en
5da0: 64 5d 0a 20 20 0a 20 20 66 6f 72 20 7b 73 65 74  d].  .  for {set
5db0: 20 69 69 20 30 7d 20 7b 24 69 69 20 3c 20 5b 6c   ii 0} {$ii < [l
5dc0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 2d 31 7d  length $args]-1}
5dd0: 20 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b 0a 20   {incr ii 2} {. 
5de0: 20 20 20 73 65 74 20 7a 20 5b 6c 69 6e 64 65 78     set z [lindex
5df0: 20 24 61 72 67 73 20 24 69 69 5d 0a 20 20 20 20   $args $ii].    
5e00: 73 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65  set n [string le
5e10: 6e 67 74 68 20 24 7a 5d 0a 20 20 20 20 73 65 74  ngth $z].    set
5e20: 20 7a 32 20 5b 6c 69 6e 64 65 78 20 24 61 72 67   z2 [lindex $arg
5e30: 73 20 5b 65 78 70 72 20 24 69 69 2b 31 5d 5d 0a  s [expr $ii+1]].
5e40: 0a 20 20 20 20 69 66 20 20 20 20 20 7b 24 6e 3e  .    if     {$n>
5e50: 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72  1 && [string fir
5e60: 73 74 20 24 7a 20 2d 64 65 6c 61 79 5d 3d 3d 30  st $z -delay]==0
5e70: 7d 20 20 20 20 20 7b 73 65 74 20 63 72 61 73 68  }     {set crash
5e80: 64 65 6c 61 79 20 24 7a 32 7d 20 5c 0a 20 20 20  delay $z2} \.   
5e90: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
5ea0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
5eb0: 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20 20 20  z -seed]==0}    
5ec0: 20 20 7b 73 65 74 20 70 72 6e 67 73 65 65 64 20    {set prngseed 
5ed0: 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69  $z2} \.    elsei
5ee0: 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69  f {$n>1 && [stri
5ef0: 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66 69 6c  ng first $z -fil
5f00: 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65 74  e]==0}      {set
5f10: 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32 7d 20   crashfile $z2} 
5f20: 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24   \.    elseif {$
5f30: 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66  n>1 && [string f
5f40: 69 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f 64 79  irst $z -tclbody
5f50: 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74 63 6c  ]==0}   {set tcl
5f60: 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20 20 20  body $z2}  \.   
5f70: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
5f80: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
5f90: 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30  z -blocksize]==0
5fa0: 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  } {set blocksize
5fb0: 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a 20 20   "-s $z2" } \.  
5fc0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
5fd0: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
5fe0: 24 7a 20 2d 63 68 61 72 61 63 74 65 72 69 73 74  $z -characterist
5ff0: 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 63  ics]==0} {set dc
6000: 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 20 5c 0a   "-c {$z2}" } \.
6010: 20 20 20 20 65 6c 73 65 20 20 20 7b 20 65 72 72      else   { err
6020: 6f 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a 65 64  or "Unrecognized
6030: 20 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a 20   option: $z" }. 
6040: 20 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61 73 68   }..  if {$crash
6050: 66 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a 20 20  file eq ""} {.  
6060: 20 20 65 72 72 6f 72 20 22 43 6f 6d 70 75 6c 73    error "Compuls
6070: 6f 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69 6c 65  ory option -file
6080: 20 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a 0a 20   missing".  }.. 
6090: 20 23 20 24 63 72 61 73 68 66 69 6c 65 20 67 65   # $crashfile ge
60a0: 74 73 20 63 6f 6d 70 61 72 65 64 20 74 6f 20 74  ts compared to t
60b0: 68 65 20 6e 61 74 69 76 65 20 66 69 6c 65 6e 61  he native filena
60c0: 6d 65 20 69 6e 20 0a 20 20 23 20 63 66 53 79 6e  me in .  # cfSyn
60d0: 63 28 29 2c 20 77 68 69 63 68 20 63 61 6e 20 62  c(), which can b
60e0: 65 20 64 69 66 66 65 72 65 6e 74 20 74 68 65 6e  e different then
60f0: 20 77 68 61 74 20 54 43 4c 20 75 73 65 73 20 62   what TCL uses b
6100: 79 0a 20 20 23 20 64 65 66 61 75 6c 74 2c 20 73  y.  # default, s
6110: 6f 20 68 65 72 65 20 77 65 20 66 6f 72 63 65 20  o here we force 
6120: 69 74 20 74 6f 20 74 68 65 20 22 6e 61 74 69 76  it to the "nativ
6130: 65 6e 61 6d 65 22 20 66 6f 72 6d 61 74 2e 0a 20  ename" format.. 
6140: 20 73 65 74 20 63 66 69 6c 65 20 5b 73 74 72 69   set cfile [stri
6150: 6e 67 20 6d 61 70 20 7b 5c 5c 20 5c 5c 5c 5c 7d  ng map {\\ \\\\}
6160: 20 5b 66 69 6c 65 20 6e 61 74 69 76 65 6e 61 6d   [file nativenam
6170: 65 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b 70 77  e [file join [pw
6180: 64 5d 20 24 63 72 61 73 68 66 69 6c 65 5d 5d 5d  d] $crashfile]]]
6190: 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20  ..  set f [open 
61a0: 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70  crash.tcl w].  p
61b0: 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f  uts $f "sqlite3_
61c0: 63 72 61 73 68 5f 65 6e 61 62 6c 65 20 31 22 0a  crash_enable 1".
61d0: 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74    puts $f "sqlit
61e0: 65 33 5f 63 72 61 73 68 70 61 72 61 6d 73 20 24  e3_crashparams $
61f0: 62 6c 6f 63 6b 73 69 7a 65 20 24 64 63 20 24 63  blocksize $dc $c
6200: 72 61 73 68 64 65 6c 61 79 20 24 63 66 69 6c 65  rashdelay $cfile
6210: 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 71 6c  ".  puts $f "sql
6220: 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f  ite3_test_contro
6230: 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 24  l_pending_byte $
6240: 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67  ::sqlite_pending
6250: 5f 62 79 74 65 22 0a 20 20 70 75 74 73 20 24 66  _byte".  puts $f
6260: 20 22 73 71 6c 69 74 65 33 20 64 62 20 74 65 73   "sqlite3 db tes
6270: 74 2e 64 62 20 2d 76 66 73 20 63 72 61 73 68 22  t.db -vfs crash"
6280: 0a 0a 20 20 23 20 54 68 69 73 20 62 6c 6f 63 6b  ..  # This block
6290: 20 73 65 74 73 20 74 68 65 20 63 61 63 68 65 20   sets the cache 
62a0: 73 69 7a 65 20 6f 66 20 74 68 65 20 6d 61 69 6e  size of the main
62b0: 20 64 61 74 61 62 61 73 65 20 74 6f 20 31 30 0a   database to 10.
62c0: 20 20 23 20 70 61 67 65 73 2e 20 54 68 69 73 20    # pages. This 
62d0: 69 73 20 64 6f 6e 65 20 69 6e 20 63 61 73 65 20  is done in case 
62e0: 74 68 65 20 62 75 69 6c 64 20 69 73 20 63 6f 6e  the build is con
62f0: 66 69 67 75 72 65 64 20 74 6f 20 6f 6d 69 74 0a  figured to omit.
6300: 20 20 23 20 22 50 52 41 47 4d 41 20 63 61 63 68    # "PRAGMA cach
6310: 65 5f 73 69 7a 65 22 2e 0a 20 20 70 75 74 73 20  e_size"..  puts 
6320: 24 66 20 7b 64 62 20 65 76 61 6c 20 7b 53 45 4c  $f {db eval {SEL
6330: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
6340: 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a 20 20 70 75  e_master;}}.  pu
6350: 74 73 20 24 66 20 7b 73 65 74 20 62 74 20 5b 62  ts $f {set bt [b
6360: 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d  tree_from_db db]
6370: 7d 0a 20 20 70 75 74 73 20 24 66 20 7b 62 74 72  }.  puts $f {btr
6380: 65 65 5f 73 65 74 5f 63 61 63 68 65 5f 73 69 7a  ee_set_cache_siz
6390: 65 20 24 62 74 20 31 30 7d 0a 20 20 69 66 20 7b  e $bt 10}.  if {
63a0: 24 70 72 6e 67 73 65 65 64 7d 20 7b 0a 20 20 20  $prngseed} {.   
63b0: 20 73 65 74 20 73 65 65 64 20 5b 65 78 70 72 20   set seed [expr 
63c0: 7b 24 70 72 6e 67 73 65 65 64 25 31 30 30 30 37  {$prngseed%10007
63d0: 2b 31 7d 5d 0a 20 20 20 20 23 20 70 75 74 73 20  +1}].    # puts 
63e0: 73 65 65 64 3d 24 73 65 65 64 0a 20 20 20 20 70  seed=$seed.    p
63f0: 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c 20  uts $f "db eval 
6400: 7b 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c  {SELECT randombl
6410: 6f 62 28 24 73 65 65 64 29 7d 22 0a 20 20 7d 0a  ob($seed)}".  }.
6420: 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c  .  if {[string l
6430: 65 6e 67 74 68 20 24 74 63 6c 62 6f 64 79 5d 3e  ength $tclbody]>
6440: 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24 66  0} {.    puts $f
6450: 20 24 74 63 6c 62 6f 64 79 0a 20 20 7d 0a 20 20   $tclbody.  }.  
6460: 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67  if {[string leng
6470: 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20  th $sql]>0} {.  
6480: 20 20 70 75 74 73 20 24 66 20 22 64 62 20 65 76    puts $f "db ev
6490: 61 6c 20 7b 22 0a 20 20 20 20 70 75 74 73 20 24  al {".    puts $
64a0: 66 20 20 20 22 24 73 71 6c 22 0a 20 20 20 20 70  f   "$sql".    p
64b0: 75 74 73 20 24 66 20 22 7d 22 0a 20 20 7d 0a 20  uts $f "}".  }. 
64c0: 20 63 6c 6f 73 65 20 24 66 0a 20 20 73 65 74 20   close $f.  set 
64d0: 72 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 65  r [catch {.    e
64e0: 78 65 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66  xec [info nameof
64f0: 65 78 65 63 5d 20 63 72 61 73 68 2e 74 63 6c 20  exec] crash.tcl 
6500: 3e 40 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67  >@stdout.  } msg
6510: 5d 0a 20 20 0a 20 20 23 20 57 69 6e 64 6f 77 73  ].  .  # Windows
6520: 2f 41 63 74 69 76 65 53 74 61 74 65 20 54 43 4c  /ActiveState TCL
6530: 20 72 65 74 75 72 6e 73 20 61 20 73 6c 69 67 68   returns a sligh
6540: 74 6c 79 20 64 69 66 66 65 72 65 6e 74 0a 20 20  tly different.  
6550: 23 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e  # error message.
6560: 20 20 57 65 20 6d 61 70 20 74 68 61 74 20 74 6f    We map that to
6570: 20 74 68 65 20 65 78 70 65 63 74 65 64 20 6d 65   the expected me
6580: 73 73 61 67 65 0a 20 20 23 20 73 6f 20 74 68 61  ssage.  # so tha
6590: 74 20 77 65 20 64 6f 6e 27 74 20 68 61 76 65 20  t we don't have 
65a0: 74 6f 20 63 68 61 6e 67 65 20 61 6c 6c 20 6f 66  to change all of
65b0: 20 74 68 65 20 74 65 73 74 0a 20 20 23 20 63 61   the test.  # ca
65c0: 73 65 73 2e 0a 20 20 69 66 20 7b 24 3a 3a 74 63  ses..  if {$::tc
65d0: 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66  l_platform(platf
65e0: 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d  orm)=="windows"}
65f0: 20 7b 0a 20 20 20 20 69 66 20 7b 24 6d 73 67 3d   {.    if {$msg=
6600: 3d 22 63 68 69 6c 64 20 6b 69 6c 6c 65 64 3a 20  ="child killed: 
6610: 75 6e 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c 22 7d  unknown signal"}
6620: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 73 67   {.      set msg
6630: 20 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20   "child process 
6640: 65 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c  exited abnormall
6650: 79 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a  y".    }.  }.  .
6660: 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67    lappend r $msg
6670: 0a 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64 6f 5f  .}..# Usage: do_
6680: 69 6f 65 72 72 5f 74 65 73 74 20 3c 74 65 73 74  ioerr_test <test
6690: 20 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69 6f 6e   number> <option
66a0: 73 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73 20 70  s...>.#.# This p
66b0: 72 6f 63 20 69 73 20 75 73 65 64 20 74 6f 20 69  roc is used to i
66c0: 6d 70 6c 65 6d 65 6e 74 20 74 65 73 74 20 63 61  mplement test ca
66d0: 73 65 73 20 74 68 61 74 20 63 68 65 63 6b 20 74  ses that check t
66e0: 68 61 74 20 49 4f 20 65 72 72 6f 72 73 0a 23 20  hat IO errors.# 
66f0: 61 72 65 20 63 6f 72 72 65 63 74 6c 79 20 68 61  are correctly ha
6700: 6e 64 6c 65 64 2e 20 54 68 65 20 66 69 72 73 74  ndled. The first
6710: 20 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65 73 74   argument, <test
6720: 20 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61 6e 20   number>, is an 
6730: 69 6e 74 65 67 65 72 20 0a 23 20 75 73 65 64 20  integer .# used 
6740: 74 6f 20 6e 61 6d 65 20 74 68 65 20 74 65 73 74  to name the test
6750: 73 20 65 78 65 63 75 74 65 64 20 62 79 20 74 68  s executed by th
6760: 69 73 20 70 72 6f 63 2e 20 4f 70 74 69 6f 6e 73  is proc. Options
6770: 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a   are as follows:
6780: 0a 23 0a 23 20 20 20 20 20 2d 74 63 6c 70 72 65  .#.#     -tclpre
6790: 70 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73  p          TCL s
67a0: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74 6f 20  cript to run to 
67b0: 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a 23 20  prepare test..# 
67c0: 20 20 20 20 2d 73 71 6c 70 72 65 70 20 20 20 20      -sqlprep    
67d0: 20 20 20 20 20 20 53 51 4c 20 73 63 72 69 70 74        SQL script
67e0: 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61   to run to prepa
67f0: 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  re test..#     -
6800: 74 63 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20  tclbody         
6810: 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72   TCL script to r
6820: 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72  un with IO error
6830: 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20   simulation..#  
6840: 20 20 20 2d 73 71 6c 62 6f 64 79 20 20 20 20 20     -sqlbody     
6850: 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20       TCL script 
6860: 74 6f 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65  to run with IO e
6870: 72 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e  rror simulation.
6880: 0a 23 20 20 20 20 20 2d 65 78 63 6c 75 64 65 20  .#     -exclude 
6890: 20 20 20 20 20 20 20 20 20 4c 69 73 74 20 6f 66           List of
68a0: 20 27 4e 27 20 76 61 6c 75 65 73 20 6e 6f 74 20   'N' values not 
68b0: 74 6f 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  to test..#     -
68c0: 65 72 63 20 20 20 20 20 20 20 20 20 20 20 20 20  erc             
68d0: 20 55 73 65 20 65 78 74 65 6e 64 65 64 20 72 65   Use extended re
68e0: 73 75 6c 74 20 63 6f 64 65 73 0a 23 20 20 20 20  sult codes.#    
68f0: 20 2d 70 65 72 73 69 73 74 20 20 20 20 20 20 20   -persist       
6900: 20 20 20 4d 61 6b 65 20 73 69 6d 75 6c 61 74 65     Make simulate
6910: 64 20 49 2f 4f 20 65 72 72 6f 72 73 20 70 65 72  d I/O errors per
6920: 73 69 73 74 65 6e 74 0a 23 20 20 20 20 20 2d 73  sistent.#     -s
6930: 74 61 72 74 20 20 20 20 20 20 20 20 20 20 20 20  tart            
6940: 56 61 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f 20  Value of 'N' to 
6950: 62 65 67 69 6e 20 77 69 74 68 20 28 64 65 66 61  begin with (defa
6960: 75 6c 74 20 31 29 0a 23 0a 23 20 20 20 20 20 2d  ult 1).#.#     -
6970: 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20  cksum           
6980: 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72 75   Boolean. If tru
6990: 65 2c 20 74 65 73 74 20 74 68 61 74 20 74 68 65  e, test that the
69a0: 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 0a 23   database does.#
69b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69c0: 20 20 20 20 20 20 20 6e 6f 74 20 63 68 61 6e 67         not chang
69d0: 65 20 64 75 72 69 6e 67 20 74 68 65 20 65 78 65  e during the exe
69e0: 63 75 74 69 6f 6e 20 6f 66 20 74 68 65 20 74 65  cution of the te
69f0: 73 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63 20  st case..#.proc 
6a00: 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b 74  do_ioerr_test {t
6a10: 65 73 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b 0a  estname args} {.
6a20: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
6a30: 74 73 28 2d 73 74 61 72 74 29 20 31 0a 20 20 73  ts(-start) 1.  s
6a40: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
6a50: 63 6b 73 75 6d 29 20 30 0a 20 20 73 65 74 20 3a  cksum) 0.  set :
6a60: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
6a70: 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   0.  set ::ioerr
6a80: 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20 31 30 30  opts(-count) 100
6a90: 30 30 30 30 30 30 0a 20 20 73 65 74 20 3a 3a 69  000000.  set ::i
6aa0: 6f 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73  oerropts(-persis
6ab0: 74 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65  t) 1.  set ::ioe
6ac0: 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75  rropts(-ckrefcou
6ad0: 6e 74 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f  nt) 0.  set ::io
6ae0: 65 72 72 6f 70 74 73 28 2d 72 65 73 74 6f 72 65  erropts(-restore
6af0: 70 72 6e 67 29 20 31 0a 20 20 61 72 72 61 79 20  prng) 1.  array 
6b00: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 20  set ::ioerropts 
6b10: 24 61 72 67 73 0a 0a 20 20 23 20 54 45 4d 50 4f  $args..  # TEMPO
6b20: 52 41 52 59 3a 20 46 6f 72 20 33 2e 35 2e 39 2c  RARY: For 3.5.9,
6b30: 20 64 69 73 61 62 6c 65 20 74 65 73 74 69 6e 67   disable testing
6b40: 20 6f 66 20 65 78 74 65 6e 64 65 64 20 72 65 73   of extended res
6b50: 75 6c 74 20 63 6f 64 65 73 2e 20 54 68 65 72 65  ult codes. There
6b60: 20 61 72 65 0a 20 20 23 20 61 20 63 6f 75 70 6c   are.  # a coupl
6b70: 65 20 6f 66 20 6f 62 73 63 75 72 65 20 49 4f 20  e of obscure IO 
6b80: 65 72 72 6f 72 73 20 74 68 61 74 20 64 6f 20 6e  errors that do n
6b90: 6f 74 20 72 65 74 75 72 6e 20 74 68 65 6d 2e 0a  ot return them..
6ba0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
6bb0: 73 28 2d 65 72 63 29 20 30 0a 0a 20 20 73 65 74  s(-erc) 0..  set
6bc0: 20 3a 3a 67 6f 20 31 0a 20 20 23 72 65 73 65 74   ::go 1.  #reset
6bd0: 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 73 61  _prng_state.  sa
6be0: 76 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20  ve_prng_state.  
6bf0: 66 6f 72 20 7b 73 65 74 20 6e 20 24 3a 3a 69 6f  for {set n $::io
6c00: 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74 29 7d  erropts(-start)}
6c10: 20 7b 24 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20 6e   {$::go} {incr n
6c20: 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 54 4e  } {.    set ::TN
6c30: 20 24 6e 0a 20 20 20 20 69 6e 63 72 20 3a 3a 69   $n.    incr ::i
6c40: 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29  oerropts(-count)
6c50: 20 2d 31 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69   -1.    if {$::i
6c60: 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29  oerropts(-count)
6c70: 3c 30 7d 20 62 72 65 61 6b 0a 20 0a 20 20 20 20  <0} break. .    
6c80: 23 20 53 6b 69 70 20 74 68 69 73 20 49 4f 20 65  # Skip this IO e
6c90: 72 72 6f 72 20 69 66 20 69 74 20 77 61 73 20 73  rror if it was s
6ca0: 70 65 63 69 66 69 65 64 20 77 69 74 68 20 74 68  pecified with th
6cb0: 65 20 22 2d 65 78 63 6c 75 64 65 22 20 6f 70 74  e "-exclude" opt
6cc0: 69 6f 6e 2e 0a 20 20 20 20 69 66 20 7b 5b 69 6e  ion..    if {[in
6cd0: 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72  fo exists ::ioer
6ce0: 72 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29 5d  ropts(-exclude)]
6cf0: 7d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 6c  } {.      if {[l
6d00: 73 65 61 72 63 68 20 24 3a 3a 69 6f 65 72 72 6f  search $::ioerro
6d10: 70 74 73 28 2d 65 78 63 6c 75 64 65 29 20 24 6e  pts(-exclude) $n
6d20: 5d 21 3d 2d 31 7d 20 63 6f 6e 74 69 6e 75 65 0a  ]!=-1} continue.
6d30: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24 3a      }.    if {$:
6d40: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 72 65 73 74  :ioerropts(-rest
6d50: 6f 72 65 70 72 6e 67 29 7d 20 7b 0a 20 20 20 20  oreprng)} {.    
6d60: 20 20 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f 73    restore_prng_s
6d70: 74 61 74 65 0a 20 20 20 20 7d 0a 0a 20 20 20 20  tate.    }..    
6d80: 23 20 44 65 6c 65 74 65 20 74 68 65 20 66 69 6c  # Delete the fil
6d90: 65 73 20 74 65 73 74 2e 64 62 20 61 6e 64 20 74  es test.db and t
6da0: 65 73 74 32 2e 64 62 2c 20 74 68 65 6e 20 65 78  est2.db, then ex
6db0: 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 61 6e  ecute the TCL an
6dc0: 64 20 0a 20 20 20 20 23 20 53 51 4c 20 28 69 6e  d .    # SQL (in
6dd0: 20 74 68 61 74 20 6f 72 64 65 72 29 20 74 6f 20   that order) to 
6de0: 70 72 65 70 61 72 65 20 66 6f 72 20 74 68 65 20  prepare for the 
6df0: 74 65 73 74 20 63 61 73 65 2e 0a 20 20 20 20 64  test case..    d
6e00: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
6e10: 2e 24 6e 2e 31 20 7b 0a 20 20 20 20 20 20 73 65  .$n.1 {.      se
6e20: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
6e30: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20  ror_pending 0.  
6e40: 20 20 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c      catch {db cl
6e50: 6f 73 65 7d 0a 20 20 20 20 20 20 63 61 74 63 68  ose}.      catch
6e60: 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 20   {db2 close}.   
6e70: 20 20 20 63 61 74 63 68 20 7b 66 69 6c 65 20 64     catch {file d
6e80: 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74 65 73  elete -force tes
6e90: 74 2e 64 62 7d 0a 20 20 20 20 20 20 63 61 74 63  t.db}.      catc
6ea0: 68 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d  h {file delete -
6eb0: 66 6f 72 63 65 20 74 65 73 74 2e 64 62 2d 6a 6f  force test.db-jo
6ec0: 75 72 6e 61 6c 7d 0a 20 20 20 20 20 20 63 61 74  urnal}.      cat
6ed0: 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20  ch {file delete 
6ee0: 2d 66 6f 72 63 65 20 74 65 73 74 32 2e 64 62 7d  -force test2.db}
6ef0: 0a 20 20 20 20 20 20 63 61 74 63 68 20 7b 66 69  .      catch {fi
6f00: 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65  le delete -force
6f10: 20 74 65 73 74 32 2e 64 62 2d 6a 6f 75 72 6e 61   test2.db-journa
6f20: 6c 7d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 44  l}.      set ::D
6f30: 42 20 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65  B [sqlite3 db te
6f40: 73 74 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63  st.db; sqlite3_c
6f50: 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65  onnection_pointe
6f60: 72 20 64 62 5d 0a 20 20 20 20 20 20 73 71 6c 69  r db].      sqli
6f70: 74 65 33 5f 65 78 74 65 6e 64 65 64 5f 72 65 73  te3_extended_res
6f80: 75 6c 74 5f 63 6f 64 65 73 20 24 3a 3a 44 42 20  ult_codes $::DB 
6f90: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72  $::ioerropts(-er
6fa0: 63 29 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e  c).      if {[in
6fb0: 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72  fo exists ::ioer
6fc0: 72 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29 5d  ropts(-tclprep)]
6fd0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 65 76 61 6c  } {.        eval
6fe0: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74   $::ioerropts(-t
6ff0: 63 6c 70 72 65 70 29 0a 20 20 20 20 20 20 7d 0a  clprep).      }.
7000: 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20        if {[info 
7010: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
7020: 74 73 28 2d 73 71 6c 70 72 65 70 29 5d 7d 20 7b  ts(-sqlprep)]} {
7030: 0a 20 20 20 20 20 20 20 20 65 78 65 63 73 71 6c  .        execsql
7040: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73   $::ioerropts(-s
7050: 71 6c 70 72 65 70 29 0a 20 20 20 20 20 20 7d 0a  qlprep).      }.
7060: 20 20 20 20 20 20 65 78 70 72 20 30 0a 20 20 20        expr 0.   
7070: 20 7d 20 7b 30 7d 0a 0a 20 20 20 20 23 20 52 65   } {0}..    # Re
7080: 61 64 20 74 68 65 20 27 63 68 65 63 6b 73 75 6d  ad the 'checksum
7090: 27 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  ' of the databas
70a0: 65 2e 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f  e..    if {$::io
70b0: 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d  erropts(-cksum)}
70c0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 63 68 65   {.      set che
70d0: 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20  cksum [cksum].  
70e0: 20 20 7d 0a 0a 20 20 20 20 23 20 53 65 74 20 74    }..    # Set t
70f0: 68 65 20 4e 74 68 20 49 4f 20 65 72 72 6f 72 20  he Nth IO error 
7100: 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f  to fail..    do_
7110: 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24  test $testname.$
7120: 6e 2e 32 20 5b 73 75 62 73 74 20 7b 0a 20 20 20  n.2 [subst {.   
7130: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
7140: 69 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74  io_error_persist
7150: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70   $::ioerropts(-p
7160: 65 72 73 69 73 74 29 0a 20 20 20 20 20 20 73 65  ersist).      se
7170: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
7180: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 24 6e 0a 20  ror_pending $n. 
7190: 20 20 20 7d 5d 20 24 6e 0a 20 20 0a 20 20 20 20     }] $n.  .    
71a0: 23 20 43 72 65 61 74 65 20 61 20 73 69 6e 67 6c  # Create a singl
71b0: 65 20 54 43 4c 20 73 63 72 69 70 74 20 66 72 6f  e TCL script fro
71c0: 6d 20 74 68 65 20 54 43 4c 20 61 6e 64 20 53 51  m the TCL and SQ
71d0: 4c 20 73 70 65 63 69 66 69 65 64 0a 20 20 20 20  L specified.    
71e0: 23 20 61 73 20 74 68 65 20 62 6f 64 79 20 6f 66  # as the body of
71f0: 20 74 68 65 20 74 65 73 74 2e 0a 20 20 20 20 73   the test..    s
7200: 65 74 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  et ::ioerrorbody
7210: 20 7b 7d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66   {}.    if {[inf
7220: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
7230: 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5d 7d  opts(-tclbody)]}
7240: 20 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20   {.      append 
7250: 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 24  ::ioerrorbody "$
7260: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c  ::ioerropts(-tcl
7270: 62 6f 64 79 29 5c 6e 22 0a 20 20 20 20 7d 0a 20  body)\n".    }. 
7280: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
7290: 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  sts ::ioerropts(
72a0: 2d 73 71 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20  -sqlbody)]} {.  
72b0: 20 20 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65      append ::ioe
72c0: 72 72 6f 72 62 6f 64 79 20 22 64 62 20 65 76 61  rrorbody "db eva
72d0: 6c 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  l {$::ioerropts(
72e0: 2d 73 71 6c 62 6f 64 79 29 7d 22 0a 20 20 20 20  -sqlbody)}".    
72f0: 7d 0a 0a 20 20 20 20 23 20 45 78 65 63 75 74 65  }..    # Execute
7300: 20 74 68 65 20 54 43 4c 20 53 63 72 69 70 74 20   the TCL Script 
7310: 63 72 65 61 74 65 64 20 69 6e 20 74 68 65 20 61  created in the a
7320: 62 6f 76 65 20 62 6c 6f 63 6b 2e 20 49 66 0a 20  bove block. If. 
7330: 20 20 20 23 20 74 68 65 72 65 20 61 72 65 20 61     # there are a
7340: 74 20 6c 65 61 73 74 20 4e 20 49 4f 20 6f 70 65  t least N IO ope
7350: 72 61 74 69 6f 6e 73 20 70 65 72 66 6f 72 6d 65  rations performe
7360: 64 20 62 79 20 53 51 4c 69 74 65 20 61 73 0a 20  d by SQLite as. 
7370: 20 20 20 23 20 61 20 72 65 73 75 6c 74 20 6f 66     # a result of
7380: 20 74 68 65 20 73 63 72 69 70 74 2c 20 74 68 65   the script, the
7390: 20 4e 74 68 20 77 69 6c 6c 20 66 61 69 6c 2e 0a   Nth will fail..
73a0: 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73      do_test $tes
73b0: 74 6e 61 6d 65 2e 24 6e 2e 33 20 7b 0a 20 20 20  tname.$n.3 {.   
73c0: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
73d0: 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 20  io_error_hit 0. 
73e0: 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74       set ::sqlit
73f0: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68  e_io_error_hardh
7400: 69 74 20 30 0a 20 20 20 20 20 20 73 65 74 20 72  it 0.      set r
7410: 20 5b 63 61 74 63 68 20 24 3a 3a 69 6f 65 72 72   [catch $::ioerr
7420: 6f 72 62 6f 64 79 20 6d 73 67 5d 0a 20 20 20 20  orbody msg].    
7430: 20 20 73 65 74 20 3a 3a 65 72 72 73 65 65 6e 20    set ::errseen 
7440: 24 72 0a 20 20 20 20 20 20 73 65 74 20 72 63 20  $r.      set rc 
7450: 5b 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65  [sqlite3_errcode
7460: 20 24 3a 3a 44 42 5d 0a 20 20 20 20 20 20 69 66   $::DB].      if
7470: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
7480: 65 72 63 29 7d 20 7b 0a 20 20 20 20 20 20 20 20  erc)} {.        
7490: 23 20 49 66 20 77 65 20 61 72 65 20 69 6e 20 65  # If we are in e
74a0: 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63  xtended result c
74b0: 6f 64 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73  ode mode, make s
74c0: 75 72 65 20 61 6c 6c 20 6f 66 20 74 68 65 0a 20  ure all of the. 
74d0: 20 20 20 20 20 20 20 23 20 49 4f 45 52 52 73 20         # IOERRs 
74e0: 77 65 20 67 65 74 20 62 61 63 6b 20 72 65 61 6c  we get back real
74f0: 6c 79 20 64 6f 20 68 61 76 65 20 74 68 65 69 72  ly do have their
7500: 20 65 78 74 65 6e 64 65 64 20 63 6f 64 65 20 76   extended code v
7510: 61 6c 75 65 73 2e 0a 20 20 20 20 20 20 20 20 23  alues..        #
7520: 20 49 66 20 61 6e 20 65 78 74 65 6e 64 65 64 20   If an extended 
7530: 72 65 73 75 6c 74 20 63 6f 64 65 20 69 73 20 72  result code is r
7540: 65 74 75 72 6e 65 64 2c 20 74 68 65 20 73 71 6c  eturned, the sql
7550: 69 74 65 33 5f 65 72 72 63 6f 64 65 0a 20 20 20  ite3_errcode.   
7560: 20 20 20 20 20 23 20 54 43 4c 63 6f 6d 6d 61 6e       # TCLcomman
7570: 64 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 61 20  d will return a 
7580: 73 74 72 69 6e 67 20 6f 66 20 74 68 65 20 66 6f  string of the fo
7590: 72 6d 3a 20 20 53 51 4c 49 54 45 5f 49 4f 45 52  rm:  SQLITE_IOER
75a0: 52 2b 6e 6e 6e 6e 0a 20 20 20 20 20 20 20 20 23  R+nnnn.        #
75b0: 20 77 68 65 72 65 20 6e 6e 6e 6e 20 69 73 20 61   where nnnn is a
75c0: 20 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 20 20   number.        
75d0: 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 53 51  if {[regexp {^SQ
75e0: 4c 49 54 45 5f 49 4f 45 52 52 7d 20 24 72 63 5d  LITE_IOERR} $rc]
75f0: 20 26 26 20 21 5b 72 65 67 65 78 70 20 7b 49 4f   && ![regexp {IO
7600: 45 52 52 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b  ERR\+\d} $rc]} {
7610: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
7620: 6e 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a  n $rc.        }.
7630: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
7640: 20 20 20 20 20 20 20 23 20 49 66 20 77 65 20 61         # If we a
7650: 72 65 20 6e 6f 74 20 69 6e 20 65 78 74 65 6e 64  re not in extend
7660: 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d  ed result code m
7670: 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 6e  ode, make sure n
7680: 6f 0a 20 20 20 20 20 20 20 20 23 20 65 78 74 65  o.        # exte
7690: 6e 64 65 64 20 65 72 72 6f 72 20 63 6f 64 65 73  nded error codes
76a0: 20 61 72 65 20 72 65 74 75 72 6e 65 64 2e 0a 20   are returned.. 
76b0: 20 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65         if {[rege
76c0: 78 70 20 7b 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20  xp {\+\d} $rc]} 
76d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75  {.          retu
76e0: 72 6e 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d  rn $rc.        }
76f0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 23  .      }.      #
7700: 20 54 68 65 20 74 65 73 74 20 72 65 70 65 61 74   The test repeat
7710: 73 20 61 73 20 6c 6f 6e 67 20 61 73 20 24 3a 3a  s as long as $::
7720: 67 6f 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 20  go is non-zero. 
7730: 20 24 3a 3a 67 6f 20 73 74 61 72 74 73 20 6f 75   $::go starts ou
7740: 74 0a 20 20 20 20 20 20 23 20 61 73 20 31 2e 20  t.      # as 1. 
7750: 20 57 68 65 6e 20 61 20 74 65 73 74 20 72 75 6e   When a test run
7760: 73 20 74 6f 20 63 6f 6d 70 6c 65 74 69 6f 6e 20  s to completion 
7770: 77 69 74 68 6f 75 74 20 68 69 74 74 69 6e 67 20  without hitting 
7780: 61 6e 20 49 2f 4f 0a 20 20 20 20 20 20 23 20 65  an I/O.      # e
7790: 72 72 6f 72 2c 20 74 68 61 74 20 6d 65 61 6e 73  rror, that means
77a0: 20 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f 69   there is no poi
77b0: 6e 74 20 69 6e 20 63 6f 6e 74 69 6e 75 69 6e 67  nt in continuing
77c0: 20 77 69 74 68 20 74 68 69 73 20 74 65 73 74 0a   with this test.
77d0: 20 20 20 20 20 20 23 20 63 61 73 65 20 73 6f 20        # case so 
77e0: 73 65 74 20 24 3a 3a 67 6f 20 74 6f 20 7a 65 72  set $::go to zer
77f0: 6f 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20  o..      #.     
7800: 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69   if {$::sqlite_i
7810: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 3e  o_error_pending>
7820: 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74  0} {.        set
7830: 20 3a 3a 67 6f 20 30 0a 20 20 20 20 20 20 20 20   ::go 0.        
7840: 73 65 74 20 71 20 30 0a 20 20 20 20 20 20 20 20  set q 0.        
7850: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
7860: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a  error_pending 0.
7870: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
7880: 20 20 20 20 20 20 20 73 65 74 20 71 20 31 0a 20         set q 1. 
7890: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 73 65       }..      se
78a0: 74 20 73 20 5b 65 78 70 72 20 24 3a 3a 73 71 6c  t s [expr $::sql
78b0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74  ite_io_error_hit
78c0: 3d 3d 30 5d 0a 20 20 20 20 20 20 69 66 20 7b 24  ==0].      if {$
78d0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
78e0: 72 5f 68 69 74 3e 24 3a 3a 73 71 6c 69 74 65 5f  r_hit>$::sqlite_
78f0: 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74  io_error_hardhit
7900: 20 26 26 20 24 72 3d 3d 30 7d 20 7b 0a 20 20 20   && $r==0} {.   
7910: 20 20 20 20 20 73 65 74 20 72 20 31 0a 20 20 20       set r 1.   
7920: 20 20 20 7d 0a 20 20 20 20 20 20 73 65 74 20 3a     }.      set :
7930: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
7940: 5f 68 69 74 20 30 0a 0a 20 20 20 20 20 20 23 20  _hit 0..      # 
7950: 4f 6e 65 20 6f 66 20 74 77 6f 20 74 68 69 6e 67  One of two thing
7960: 73 20 6d 75 73 74 20 68 61 76 65 20 68 61 70 70  s must have happ
7970: 65 6e 65 64 2e 20 65 69 74 68 65 72 0a 20 20 20  ened. either.   
7980: 20 20 20 23 20 20 20 31 2e 20 20 57 65 20 6e 65     #   1.  We ne
7990: 76 65 72 20 68 69 74 20 74 68 65 20 49 4f 20 65  ver hit the IO e
79a0: 72 72 6f 72 20 61 6e 64 20 74 68 65 20 53 51 4c  rror and the SQL
79b0: 20 72 65 74 75 72 6e 65 64 20 4f 4b 0a 20 20 20   returned OK.   
79c0: 20 20 20 23 20 20 20 32 2e 20 20 41 6e 20 49 4f     #   2.  An IO
79d0: 20 65 72 72 6f 72 20 77 61 73 20 68 69 74 20 61   error was hit a
79e0: 6e 64 20 74 68 65 20 53 51 4c 20 66 61 69 6c 65  nd the SQL faile
79f0: 64 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20  d.      #.      
7a00: 23 70 75 74 73 20 22 73 3d 24 73 20 72 3d 24 72  #puts "s=$s r=$r
7a10: 20 71 3d 24 71 22 0a 20 20 20 20 20 20 65 78 70   q=$q".      exp
7a20: 72 20 7b 20 28 24 73 20 26 26 20 21 24 72 20 26  r { ($s && !$r &
7a30: 26 20 21 24 71 29 20 7c 7c 20 28 21 24 73 20 26  & !$q) || (!$s &
7a40: 26 20 24 72 20 26 26 20 24 71 29 20 7d 0a 20 20  & $r && $q) }.  
7a50: 20 20 7d 20 7b 31 7d 0a 0a 20 20 20 20 73 65 74    } {1}..    set
7a60: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
7a70: 6f 72 5f 68 69 74 20 30 0a 20 20 20 20 73 65 74  or_hit 0.    set
7a80: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
7a90: 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 0a 20 20  or_pending 0..  
7aa0: 20 20 23 20 43 68 65 63 6b 20 74 68 61 74 20 6e    # Check that n
7ab0: 6f 20 70 61 67 65 20 72 65 66 65 72 65 6e 63 65  o page reference
7ac0: 73 20 77 65 72 65 20 6c 65 61 6b 65 64 2e 20 54  s were leaked. T
7ad0: 68 65 72 65 20 73 68 6f 75 6c 64 20 62 65 20 0a  here should be .
7ae0: 20 20 20 20 23 20 61 20 73 69 6e 67 6c 65 20 72      # a single r
7af0: 65 66 65 72 65 6e 63 65 20 69 66 20 74 68 65 72  eference if ther
7b00: 65 20 69 73 20 73 74 69 6c 6c 20 61 6e 20 61 63  e is still an ac
7b10: 74 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  tive transaction
7b20: 2c 20 0a 20 20 20 20 23 20 6f 72 20 7a 65 72 6f  , .    # or zero
7b30: 20 6f 74 68 65 72 77 69 73 65 2e 0a 20 20 20 20   otherwise..    
7b40: 23 0a 20 20 20 20 23 20 55 50 44 41 54 45 3a 20  #.    # UPDATE: 
7b50: 49 66 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20  If the IO error 
7b60: 6f 63 63 75 72 73 20 61 66 74 65 72 20 61 20 27  occurs after a '
7b70: 42 45 47 49 4e 27 20 62 75 74 20 62 65 66 6f 72  BEGIN' but befor
7b80: 65 20 61 6e 79 0a 20 20 20 20 23 20 6c 6f 63 6b  e any.    # lock
7b90: 73 20 61 72 65 20 65 73 74 61 62 6c 69 73 68 65  s are establishe
7ba0: 64 20 6f 6e 20 64 61 74 61 62 61 73 65 20 66 69  d on database fi
7bb0: 6c 65 73 20 28 69 2e 65 2e 20 69 66 20 74 68 65  les (i.e. if the
7bc0: 20 65 72 72 6f 72 20 0a 20 20 20 20 23 20 6f 63   error .    # oc
7bd0: 63 75 72 73 20 77 68 69 6c 65 20 61 74 74 65 6d  curs while attem
7be0: 70 74 69 6e 67 20 74 6f 20 64 65 74 65 63 74 20  pting to detect 
7bf0: 61 20 68 6f 74 2d 6a 6f 75 72 6e 61 6c 20 66 69  a hot-journal fi
7c00: 6c 65 29 2c 20 74 68 65 6e 0a 20 20 20 20 23 20  le), then.    # 
7c10: 74 68 65 72 65 20 6d 61 79 20 30 20 70 61 67 65  there may 0 page
7c20: 20 72 65 66 65 72 65 6e 63 65 73 20 61 6e 64 20   references and 
7c30: 61 6e 20 61 63 74 69 76 65 20 74 72 61 6e 73 61  an active transa
7c40: 63 74 69 6f 6e 20 61 63 63 6f 72 64 69 6e 67 0a  ction according.
7c50: 20 20 20 20 23 20 74 6f 20 5b 73 71 6c 69 74 65      # to [sqlite
7c60: 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74  3_get_autocommit
7c70: 5d 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20  ]..    #.    if 
7c80: 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71 6c  {$::go && $::sql
7c90: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72  ite_io_error_har
7ca0: 64 68 69 74 20 26 26 20 24 3a 3a 69 6f 65 72 72  dhit && $::ioerr
7cb0: 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74  opts(-ckrefcount
7cc0: 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65  )} {.      do_te
7cd0: 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e  st $testname.$n.
7ce0: 34 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  4 {.        set 
7cf0: 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64  bt [btree_from_d
7d00: 62 20 64 62 5d 0a 20 20 20 20 20 20 20 20 64 62  b db].        db
7d10: 5f 65 6e 74 65 72 20 64 62 0a 20 20 20 20 20 20  _enter db.      
7d20: 20 20 61 72 72 61 79 20 73 65 74 20 73 74 61 74    array set stat
7d30: 73 20 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73  s [btree_pager_s
7d40: 74 61 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20  tats $bt].      
7d50: 20 20 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20    db_leave db.  
7d60: 20 20 20 20 20 20 73 65 74 20 6e 52 65 66 20 24        set nRef $
7d70: 73 74 61 74 73 28 72 65 66 29 0a 20 20 20 20 20  stats(ref).     
7d80: 20 20 20 65 78 70 72 20 7b 24 6e 52 65 66 20 3d     expr {$nRef =
7d90: 3d 20 30 20 7c 7c 20 28 5b 73 71 6c 69 74 65 33  = 0 || ([sqlite3
7da0: 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20  _get_autocommit 
7db0: 64 62 5d 3d 3d 30 20 26 26 20 24 6e 52 65 66 20  db]==0 && $nRef 
7dc0: 3d 3d 20 31 29 7d 0a 20 20 20 20 20 20 7d 20 7b  == 1)}.      } {
7dd0: 31 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20  1}.    }..    # 
7de0: 49 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 6f  If there is an o
7df0: 70 65 6e 20 64 61 74 61 62 61 73 65 20 68 61 6e  pen database han
7e00: 64 6c 65 20 61 6e 64 20 6e 6f 20 6f 70 65 6e 20  dle and no open 
7e10: 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 0a 20 20  transaction, .  
7e20: 20 20 23 20 61 6e 64 20 74 68 65 20 70 61 67 65    # and the page
7e30: 72 20 69 73 20 6e 6f 74 20 72 75 6e 6e 69 6e 67  r is not running
7e40: 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f   in exclusive-lo
7e50: 63 6b 69 6e 67 20 6d 6f 64 65 2c 0a 20 20 20 20  cking mode,.    
7e60: 23 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65  # check that the
7e70: 20 70 61 67 65 72 20 69 73 20 69 6e 20 22 75 6e   pager is in "un
7e80: 6c 6f 63 6b 65 64 22 20 73 74 61 74 65 2e 20 54  locked" state. T
7e90: 68 65 6f 72 65 74 69 63 61 6c 6c 79 2c 0a 20 20  heoretically,.  
7ea0: 20 20 23 20 69 66 20 61 20 63 61 6c 6c 20 74 6f    # if a call to
7eb0: 20 78 55 6e 6c 6f 63 6b 28 29 20 66 61 69 6c 65   xUnlock() faile
7ec0: 64 20 64 75 65 20 74 6f 20 61 6e 20 49 4f 20 65  d due to an IO e
7ed0: 72 72 6f 72 20 74 68 65 20 75 6e 64 65 72 6c 79  rror the underly
7ee0: 69 6e 67 0a 20 20 20 20 23 20 66 69 6c 65 20 6d  ing.    # file m
7ef0: 61 79 20 73 74 69 6c 6c 20 62 65 20 6c 6f 63 6b  ay still be lock
7f00: 65 64 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66  ed..    #.    if
7f10: 63 61 70 61 62 6c 65 20 70 72 61 67 6d 61 20 7b  capable pragma {
7f20: 0a 20 20 20 20 20 20 69 66 20 7b 20 5b 69 6e 66  .      if { [inf
7f30: 6f 20 63 6f 6d 6d 61 6e 64 73 20 64 62 5d 20 6e  o commands db] n
7f40: 65 20 22 22 0a 20 20 20 20 20 20 20 20 26 26 20  e "".        && 
7f50: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b  $::ioerropts(-ck
7f60: 72 65 66 63 6f 75 6e 74 29 0a 20 20 20 20 20 20  refcount).      
7f70: 20 20 26 26 20 5b 64 62 20 6f 6e 65 20 7b 70 72    && [db one {pr
7f80: 61 67 6d 61 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64  agma locking_mod
7f90: 65 7d 5d 20 65 71 20 22 6e 6f 72 6d 61 6c 22 0a  e}] eq "normal".
7fa0: 20 20 20 20 20 20 20 20 26 26 20 5b 73 71 6c 69          && [sqli
7fb0: 74 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d  te3_get_autocomm
7fc0: 69 74 20 64 62 5d 0a 20 20 20 20 20 20 7d 20 7b  it db].      } {
7fd0: 0a 20 20 20 20 20 20 20 20 64 6f 5f 74 65 73 74  .        do_test
7fe0: 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 35 20   $testname.$n.5 
7ff0: 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  {.          set 
8000: 62 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64  bt [btree_from_d
8010: 62 20 64 62 5d 0a 20 20 20 20 20 20 20 20 20 20  b db].          
8020: 64 62 5f 65 6e 74 65 72 20 64 62 0a 20 20 20 20  db_enter db.    
8030: 20 20 20 20 20 20 61 72 72 61 79 20 73 65 74 20        array set 
8040: 73 74 61 74 73 20 5b 62 74 72 65 65 5f 70 61 67  stats [btree_pag
8050: 65 72 5f 73 74 61 74 73 20 24 62 74 5d 0a 20 20  er_stats $bt].  
8060: 20 20 20 20 20 20 20 20 64 62 5f 6c 65 61 76 65          db_leave
8070: 20 64 62 0a 20 20 20 20 20 20 20 20 20 20 73 65   db.          se
8080: 74 20 73 74 61 74 73 28 73 74 61 74 65 29 0a 20  t stats(state). 
8090: 20 20 20 20 20 20 20 7d 20 30 0a 20 20 20 20 20         } 0.     
80a0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20   }.    }..    # 
80b0: 49 66 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 6f  If an IO error o
80c0: 63 63 75 72 65 64 2c 20 74 68 65 6e 20 74 68 65  ccured, then the
80d0: 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65   checksum of the
80e0: 20 64 61 74 61 62 61 73 65 20 73 68 6f 75 6c 64   database should
80f0: 0a 20 20 20 20 23 20 62 65 20 74 68 65 20 73 61  .    # be the sa
8100: 6d 65 20 61 73 20 62 65 66 6f 72 65 20 74 68 65  me as before the
8110: 20 73 63 72 69 70 74 20 74 68 61 74 20 63 61 75   script that cau
8120: 73 65 64 20 74 68 65 20 49 4f 20 65 72 72 6f 72  sed the IO error
8130: 20 77 61 73 20 72 75 6e 2e 0a 20 20 20 20 23 0a   was run..    #.
8140: 20 20 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26      if {$::go &&
8150: 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72   $::sqlite_io_er
8160: 72 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24  ror_hardhit && $
8170: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73  ::ioerropts(-cks
8180: 75 6d 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f  um)} {.      do_
8190: 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24  test $testname.$
81a0: 6e 2e 36 20 7b 0a 20 20 20 20 20 20 20 20 63 61  n.6 {.        ca
81b0: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
81c0: 20 20 20 20 20 20 20 63 61 74 63 68 20 7b 64 62         catch {db
81d0: 32 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20  2 close}.       
81e0: 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74   set ::DB [sqlit
81f0: 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73  e3 db test.db; s
8200: 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f  qlite3_connectio
8210: 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20  n_pointer db].  
8220: 20 20 20 20 20 20 63 6b 73 75 6d 0a 20 20 20 20        cksum.    
8230: 20 20 7d 20 24 63 68 65 63 6b 73 75 6d 0a 20 20    } $checksum.  
8240: 20 20 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73    }..    set ::s
8250: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
8260: 61 72 64 68 69 74 20 30 0a 20 20 20 20 73 65 74  ardhit 0.    set
8270: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
8280: 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 20  or_pending 0.   
8290: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
82a0: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  s ::ioerropts(-c
82b0: 6c 65 61 6e 75 70 29 5d 7d 20 7b 0a 20 20 20 20  leanup)]} {.    
82c0: 20 20 63 61 74 63 68 20 24 3a 3a 69 6f 65 72 72    catch $::ioerr
82d0: 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70 29 0a 20  opts(-cleanup). 
82e0: 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a     }.  }.  set :
82f0: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
8300: 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 73 65 74  _pending 0.  set
8310: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
8320: 6f 72 5f 70 65 72 73 69 73 74 20 30 0a 20 20 75  or_persist 0.  u
8330: 6e 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73  nset ::ioerropts
8340: 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 20 61 20 63  .}..# Return a c
8350: 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e  hecksum based on
8360: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
8370: 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61   the main databa
8380: 73 65 20 61 73 73 6f 63 69 61 74 65 64 0a 23 20  se associated.# 
8390: 77 69 74 68 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  with connection 
83a0: 24 64 62 0a 23 0a 70 72 6f 63 20 63 6b 73 75 6d  $db.#.proc cksum
83b0: 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73   {{db db}} {.  s
83c0: 65 74 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c  et txt [$db eval
83d0: 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20   {.      SELECT 
83e0: 6e 61 6d 65 2c 20 74 79 70 65 2c 20 73 71 6c 20  name, type, sql 
83f0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
8400: 65 72 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65  er order by name
8410: 0a 20 20 7d 5d 5c 6e 0a 20 20 66 6f 72 65 61 63  .  }]\n.  foreac
8420: 68 20 74 62 6c 20 5b 24 64 62 20 65 76 61 6c 20  h tbl [$db eval 
8430: 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e  {.      SELECT n
8440: 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  ame FROM sqlite_
8450: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
8460: 65 3d 27 74 61 62 6c 65 27 20 6f 72 64 65 72 20  e='table' order 
8470: 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 20 7b 0a 20  by name.  }] {. 
8480: 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24     append txt [$
8490: 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20  db eval "SELECT 
84a0: 2a 20 46 52 4f 4d 20 24 74 62 6c 22 5d 5c 6e 0a  * FROM $tbl"]\n.
84b0: 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 70 72    }.  foreach pr
84c0: 61 67 20 7b 64 65 66 61 75 6c 74 5f 73 79 6e 63  ag {default_sync
84d0: 68 72 6f 6e 6f 75 73 20 64 65 66 61 75 6c 74 5f  hronous default_
84e0: 63 61 63 68 65 5f 73 69 7a 65 7d 20 7b 0a 20 20  cache_size} {.  
84f0: 20 20 61 70 70 65 6e 64 20 74 78 74 20 24 70 72    append txt $pr
8500: 61 67 2d 5b 24 64 62 20 65 76 61 6c 20 22 50 52  ag-[$db eval "PR
8510: 41 47 4d 41 20 24 70 72 61 67 22 5d 5c 6e 0a 20  AGMA $prag"]\n. 
8520: 20 7d 0a 20 20 73 65 74 20 63 6b 73 75 6d 20 5b   }.  set cksum [
8530: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 74  string length $t
8540: 78 74 5d 2d 5b 6d 64 35 20 24 74 78 74 5d 0a 20  xt]-[md5 $txt]. 
8550: 20 23 20 70 75 74 73 20 24 63 6b 73 75 6d 2d 5b   # puts $cksum-[
8560: 66 69 6c 65 20 73 69 7a 65 20 74 65 73 74 2e 64  file size test.d
8570: 62 5d 0a 20 20 72 65 74 75 72 6e 20 24 63 6b 73  b].  return $cks
8580: 75 6d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65  um.}..# Generate
8590: 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73 65   a checksum base
85a0: 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74  d on the content
85b0: 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 61 6e  s of the main an
85c0: 64 20 74 65 6d 70 20 74 61 62 6c 65 73 0a 23 20  d temp tables.# 
85d0: 64 61 74 61 62 61 73 65 20 24 64 62 2e 20 49 66  database $db. If
85e0: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 66   the checksum of
85f0: 20 74 77 6f 20 64 61 74 61 62 61 73 65 73 20 69   two databases i
8600: 73 20 74 68 65 20 73 61 6d 65 2c 20 61 6e 64 20  s the same, and 
8610: 74 68 65 0a 23 20 69 6e 74 65 67 72 69 74 79 2d  the.# integrity-
8620: 63 68 65 63 6b 20 70 61 73 73 65 73 20 66 6f 72  check passes for
8630: 20 62 6f 74 68 2c 20 74 68 65 20 74 77 6f 20 64   both, the two d
8640: 61 74 61 62 61 73 65 73 20 61 72 65 20 69 64 65  atabases are ide
8650: 6e 74 69 63 61 6c 2e 0a 23 0a 70 72 6f 63 20 61  ntical..#.proc a
8660: 6c 6c 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d  llcksum {{db db}
8670: 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 5b 6c  } {.  set ret [l
8680: 69 73 74 5d 0a 20 20 69 66 63 61 70 61 62 6c 65  ist].  ifcapable
8690: 20 74 65 6d 70 64 62 20 7b 0a 20 20 20 20 73 65   tempdb {.    se
86a0: 74 20 73 71 6c 20 7b 0a 20 20 20 20 20 20 53 45  t sql {.      SE
86b0: 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73  LECT name FROM s
86c0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45  qlite_master WHE
86d0: 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65  RE type = 'table
86e0: 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45  ' UNION.      SE
86f0: 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73  LECT name FROM s
8700: 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65  qlite_temp_maste
8710: 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27  r WHERE type = '
8720: 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20  table' UNION.   
8730: 20 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74     SELECT 'sqlit
8740: 65 5f 6d 61 73 74 65 72 27 20 55 4e 49 4f 4e 0a  e_master' UNION.
8750: 20 20 20 20 20 20 53 45 4c 45 43 54 20 27 73 71        SELECT 'sq
8760: 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72  lite_temp_master
8770: 27 20 4f 52 44 45 52 20 42 59 20 31 0a 20 20 20  ' ORDER BY 1.   
8780: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
8790: 20 20 73 65 74 20 73 71 6c 20 7b 0a 20 20 20 20    set sql {.    
87a0: 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52    SELECT name FR
87b0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
87c0: 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74   WHERE type = 't
87d0: 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20  able' UNION.    
87e0: 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65    SELECT 'sqlite
87f0: 5f 6d 61 73 74 65 72 27 20 4f 52 44 45 52 20 42  _master' ORDER B
8800: 59 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  Y 1.    }.  }.  
8810: 73 65 74 20 74 62 6c 6c 69 73 74 20 5b 24 64 62  set tbllist [$db
8820: 20 65 76 61 6c 20 24 73 71 6c 5d 0a 20 20 73 65   eval $sql].  se
8830: 74 20 74 78 74 20 7b 7d 0a 20 20 66 6f 72 65 61  t txt {}.  forea
8840: 63 68 20 74 62 6c 20 24 74 62 6c 6c 69 73 74 20  ch tbl $tbllist 
8850: 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78 74  {.    append txt
8860: 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45   [$db eval "SELE
8870: 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c 22 5d  CT * FROM $tbl"]
8880: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 70  .  }.  foreach p
8890: 72 61 67 20 7b 64 65 66 61 75 6c 74 5f 63 61 63  rag {default_cac
88a0: 68 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61  he_size} {.    a
88b0: 70 70 65 6e 64 20 74 78 74 20 24 70 72 61 67 2d  ppend txt $prag-
88c0: 5b 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d  [$db eval "PRAGM
88d0: 41 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a  A $prag"]\n.  }.
88e0: 20 20 23 20 70 75 74 73 20 74 78 74 3d 24 74 78    # puts txt=$tx
88f0: 74 0a 20 20 72 65 74 75 72 6e 20 5b 6d 64 35 20  t.  return [md5 
8900: 24 74 78 74 5d 0a 7d 0a 0a 23 20 47 65 6e 65 72  $txt].}..# Gener
8910: 61 74 65 20 61 20 63 68 65 63 6b 73 75 6d 20 62  ate a checksum b
8920: 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74  ased on the cont
8930: 65 6e 74 73 20 6f 66 20 61 20 73 69 6e 67 6c 65  ents of a single
8940: 20 64 61 74 61 62 61 73 65 20 77 69 74 68 0a 23   database with.#
8950: 20 61 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e   a database conn
8960: 65 63 74 69 6f 6e 2e 20 20 54 68 65 20 6e 61 6d  ection.  The nam
8970: 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  e of the databas
8980: 65 20 69 73 20 24 64 62 6e 61 6d 65 2e 20 20 0a  e is $dbname.  .
8990: 23 20 45 78 61 6d 70 6c 65 73 20 6f 66 20 24 64  # Examples of $d
89a0: 62 6e 61 6d 65 20 61 72 65 20 22 74 65 6d 70 22  bname are "temp"
89b0: 20 6f 72 20 22 6d 61 69 6e 22 2e 0a 23 0a 70 72   or "main"..#.pr
89c0: 6f 63 20 64 62 63 6b 73 75 6d 20 7b 64 62 20 64  oc dbcksum {db d
89d0: 62 6e 61 6d 65 7d 20 7b 0a 20 20 69 66 20 7b 24  bname} {.  if {$
89e0: 64 62 6e 61 6d 65 3d 3d 22 74 65 6d 70 22 7d 20  dbname=="temp"} 
89f0: 7b 0a 20 20 20 20 73 65 74 20 6d 61 73 74 65 72  {.    set master
8a00: 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73   sqlite_temp_mas
8a10: 74 65 72 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  ter.  } else {. 
8a20: 20 20 20 73 65 74 20 6d 61 73 74 65 72 20 24 64     set master $d
8a30: 62 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d 61 73  bname.sqlite_mas
8a40: 74 65 72 0a 20 20 7d 0a 20 20 73 65 74 20 61 6c  ter.  }.  set al
8a50: 6c 74 61 62 20 5b 24 64 62 20 65 76 61 6c 20 22  ltab [$db eval "
8a60: 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d  SELECT name FROM
8a70: 20 24 6d 61 73 74 65 72 20 57 48 45 52 45 20 74   $master WHERE t
8a80: 79 70 65 3d 27 74 61 62 6c 65 27 22 5d 0a 20 20  ype='table'"].  
8a90: 73 65 74 20 74 78 74 20 5b 24 64 62 20 65 76 61  set txt [$db eva
8aa0: 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  l "SELECT * FROM
8ab0: 20 24 6d 61 73 74 65 72 22 5d 5c 6e 0a 20 20 66   $master"]\n.  f
8ac0: 6f 72 65 61 63 68 20 74 61 62 20 24 61 6c 6c 74  oreach tab $allt
8ad0: 61 62 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20  ab {.    append 
8ae0: 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53  txt [$db eval "S
8af0: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 64 62  ELECT * FROM $db
8b00: 6e 61 6d 65 2e 24 74 61 62 22 5d 5c 6e 0a 20 20  name.$tab"]\n.  
8b10: 7d 0a 20 20 72 65 74 75 72 6e 20 5b 6d 64 35 20  }.  return [md5 
8b20: 24 74 78 74 5d 0a 7d 0a 0a 70 72 6f 63 20 6d 65  $txt].}..proc me
8b30: 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 20 7b  mdebug_log_sql {
8b40: 7b 66 69 6c 65 6e 61 6d 65 20 6d 61 6c 6c 6f 63  {filename malloc
8b50: 73 2e 73 71 6c 7d 7d 20 7b 0a 0a 20 20 73 65 74  s.sql}} {..  set
8b60: 20 64 61 74 61 20 5b 73 71 6c 69 74 65 33 5f 6d   data [sqlite3_m
8b70: 65 6d 64 65 62 75 67 5f 6c 6f 67 20 64 75 6d 70  emdebug_log dump
8b80: 5d 0a 20 20 73 65 74 20 6e 46 72 61 6d 65 20 5b  ].  set nFrame [
8b90: 65 78 70 72 20 5b 6c 6c 65 6e 67 74 68 20 5b 6c  expr [llength [l
8ba0: 69 6e 64 65 78 20 24 64 61 74 61 20 30 5d 5d 2d  index $data 0]]-
8bb0: 32 5d 0a 20 20 69 66 20 7b 24 6e 46 72 61 6d 65  2].  if {$nFrame
8bc0: 20 3c 20 30 7d 20 7b 20 72 65 74 75 72 6e 20 22   < 0} { return "
8bd0: 22 20 7d 0a 0a 20 20 73 65 74 20 64 61 74 61 62  " }..  set datab
8be0: 61 73 65 20 74 65 6d 70 0a 0a 20 20 73 65 74 20  ase temp..  set 
8bf0: 74 62 6c 20 22 43 52 45 41 54 45 20 54 41 42 4c  tbl "CREATE TABL
8c00: 45 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61  E ${database}.ma
8c10: 6c 6c 6f 63 28 7a 54 65 73 74 2c 20 6e 43 61 6c  lloc(zTest, nCal
8c20: 6c 2c 20 6e 42 79 74 65 2c 20 6c 53 74 61 63 6b  l, nByte, lStack
8c30: 29 3b 22 0a 0a 20 20 73 65 74 20 73 71 6c 20 22  );"..  set sql "
8c40: 22 0a 20 20 66 6f 72 65 61 63 68 20 65 20 24 64  ".  foreach e $d
8c50: 61 74 61 20 7b 0a 20 20 20 20 73 65 74 20 6e 43  ata {.    set nC
8c60: 61 6c 6c 20 5b 6c 69 6e 64 65 78 20 24 65 20 30  all [lindex $e 0
8c70: 5d 0a 20 20 20 20 73 65 74 20 6e 42 79 74 65 20  ].    set nByte 
8c80: 5b 6c 69 6e 64 65 78 20 24 65 20 31 5d 0a 20 20  [lindex $e 1].  
8c90: 20 20 73 65 74 20 6c 53 74 61 63 6b 20 5b 6c 72    set lStack [lr
8ca0: 61 6e 67 65 20 24 65 20 32 20 65 6e 64 5d 0a 20  ange $e 2 end]. 
8cb0: 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49     append sql "I
8cc0: 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74  NSERT INTO ${dat
8cd0: 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63 20 56 41  abase}.malloc VA
8ce0: 4c 55 45 53 22 0a 20 20 20 20 61 70 70 65 6e 64  LUES".    append
8cf0: 20 73 71 6c 20 22 28 27 74 65 73 74 27 2c 20 24   sql "('test', $
8d00: 6e 43 61 6c 6c 2c 20 24 6e 42 79 74 65 2c 20 27  nCall, $nByte, '
8d10: 24 6c 53 74 61 63 6b 27 29 3b 5c 6e 22 0a 20 20  $lStack');\n".  
8d20: 20 20 66 6f 72 65 61 63 68 20 66 20 24 6c 53 74    foreach f $lSt
8d30: 61 63 6b 20 7b 0a 20 20 20 20 20 20 73 65 74 20  ack {.      set 
8d40: 66 72 61 6d 65 73 28 24 66 29 20 31 0a 20 20 20  frames($f) 1.   
8d50: 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74 20 74 62   }.  }..  set tb
8d60: 6c 32 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  l2 "CREATE TABLE
8d70: 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 72 61   ${database}.fra
8d80: 6d 65 28 66 72 61 6d 65 20 49 4e 54 45 47 45 52  me(frame INTEGER
8d90: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 6c 69   PRIMARY KEY, li
8da0: 6e 65 29 3b 5c 6e 22 0a 20 20 73 65 74 20 74 62  ne);\n".  set tb
8db0: 6c 33 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  l3 "CREATE TABLE
8dc0: 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 69 6c   ${database}.fil
8dd0: 65 28 6e 61 6d 65 20 50 52 49 4d 41 52 59 20 4b  e(name PRIMARY K
8de0: 45 59 2c 20 63 6f 6e 74 65 6e 74 29 3b 5c 6e 22  EY, content);\n"
8df0: 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 61  ..  foreach f [a
8e00: 72 72 61 79 20 6e 61 6d 65 73 20 66 72 61 6d 65  rray names frame
8e10: 73 5d 20 7b 0a 20 20 20 20 73 65 74 20 61 64 64  s] {.    set add
8e20: 72 20 5b 66 6f 72 6d 61 74 20 25 78 20 24 66 5d  r [format %x $f]
8e30: 0a 20 20 20 20 73 65 74 20 63 6d 64 20 22 61 64  .    set cmd "ad
8e40: 64 72 32 6c 69 6e 65 20 2d 65 20 5b 69 6e 66 6f  dr2line -e [info
8e50: 20 6e 61 6d 65 6f 66 65 78 65 63 5d 20 24 61 64   nameofexec] $ad
8e60: 64 72 22 0a 20 20 20 20 73 65 74 20 6c 69 6e 65  dr".    set line
8e70: 20 5b 65 76 61 6c 20 65 78 65 63 20 24 63 6d 64   [eval exec $cmd
8e80: 5d 0a 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c  ].    append sql
8e90: 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b   "INSERT INTO ${
8ea0: 64 61 74 61 62 61 73 65 7d 2e 66 72 61 6d 65 20  database}.frame 
8eb0: 56 41 4c 55 45 53 28 24 66 2c 20 27 24 6c 69 6e  VALUES($f, '$lin
8ec0: 65 27 29 3b 5c 6e 22 0a 0a 20 20 20 20 73 65 74  e');\n"..    set
8ed0: 20 66 69 6c 65 20 5b 6c 69 6e 64 65 78 20 5b 73   file [lindex [s
8ee0: 70 6c 69 74 20 24 6c 69 6e 65 20 3a 5d 20 30 5d  plit $line :] 0]
8ef0: 0a 20 20 20 20 73 65 74 20 66 69 6c 65 73 28 24  .    set files($
8f00: 66 69 6c 65 29 20 31 0a 20 20 7d 0a 0a 20 20 66  file) 1.  }..  f
8f10: 6f 72 65 61 63 68 20 66 20 5b 61 72 72 61 79 20  oreach f [array 
8f20: 6e 61 6d 65 73 20 66 69 6c 65 73 5d 20 7b 0a 20  names files] {. 
8f30: 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20     set contents 
8f40: 22 22 0a 20 20 20 20 63 61 74 63 68 20 7b 0a 20  "".    catch {. 
8f50: 20 20 20 20 20 73 65 74 20 66 64 20 5b 6f 70 65       set fd [ope
8f60: 6e 20 24 66 5d 0a 20 20 20 20 20 20 73 65 74 20  n $f].      set 
8f70: 63 6f 6e 74 65 6e 74 73 20 5b 72 65 61 64 20 24  contents [read $
8f80: 66 64 5d 0a 20 20 20 20 20 20 63 6c 6f 73 65 20  fd].      close 
8f90: 24 66 64 0a 20 20 20 20 7d 0a 20 20 20 20 73 65  $fd.    }.    se
8fa0: 74 20 63 6f 6e 74 65 6e 74 73 20 5b 73 74 72 69  t contents [stri
8fb0: 6e 67 20 6d 61 70 20 7b 27 20 27 27 7d 20 24 63  ng map {' ''} $c
8fc0: 6f 6e 74 65 6e 74 73 5d 0a 20 20 20 20 61 70 70  ontents].    app
8fd0: 65 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20  end sql "INSERT 
8fe0: 49 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d  INTO ${database}
8ff0: 2e 66 69 6c 65 20 56 41 4c 55 45 53 28 27 24 66  .file VALUES('$f
9000: 27 2c 20 27 24 63 6f 6e 74 65 6e 74 73 27 29 3b  ', '$contents');
9010: 5c 6e 22 0a 20 20 7d 0a 0a 20 20 73 65 74 20 66  \n".  }..  set f
9020: 64 20 5b 6f 70 65 6e 20 24 66 69 6c 65 6e 61 6d  d [open $filenam
9030: 65 20 77 5d 0a 20 20 70 75 74 73 20 24 66 64 20  e w].  puts $fd 
9040: 22 42 45 47 49 4e 3b 20 24 7b 74 62 6c 7d 24 7b  "BEGIN; ${tbl}${
9050: 74 62 6c 32 7d 24 7b 74 62 6c 33 7d 24 7b 73 71  tbl2}${tbl3}${sq
9060: 6c 7d 20 3b 20 43 4f 4d 4d 49 54 3b 22 0a 20 20  l} ; COMMIT;".  
9070: 63 6c 6f 73 65 20 24 66 64 0a 7d 0a 0a 23 20 43  close $fd.}..# C
9080: 6f 70 79 20 66 69 6c 65 20 24 66 72 6f 6d 20 69  opy file $from i
9090: 6e 74 6f 20 24 74 6f 2e 20 54 68 69 73 20 69 73  nto $to. This is
90a0: 20 75 73 65 64 20 62 65 63 61 75 73 65 20 73 6f   used because so
90b0: 6d 65 20 76 65 72 73 69 6f 6e 73 20 6f 66 0a 23  me versions of.#
90c0: 20 54 43 4c 20 66 6f 72 20 77 69 6e 64 6f 77 73   TCL for windows
90d0: 20 28 6e 6f 74 61 62 6c 79 20 74 68 65 20 38 2e   (notably the 8.
90e0: 34 2e 31 20 62 69 6e 61 72 79 20 70 61 63 6b 61  4.1 binary packa
90f0: 67 65 20 73 68 69 70 70 65 64 20 77 69 74 68 20  ge shipped with 
9100: 74 68 65 0a 23 20 63 75 72 72 65 6e 74 20 6d 69  the.# current mi
9110: 6e 67 77 20 72 65 6c 65 61 73 65 29 20 68 61 76  ngw release) hav
9120: 65 20 61 20 62 72 6f 6b 65 6e 20 22 66 69 6c 65  e a broken "file
9130: 20 63 6f 70 79 22 20 63 6f 6d 6d 61 6e 64 2e 0a   copy" command..
9140: 23 0a 70 72 6f 63 20 63 6f 70 79 5f 66 69 6c 65  #.proc copy_file
9150: 20 7b 66 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 69   {from to} {.  i
9160: 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f  f {$::tcl_platfo
9170: 72 6d 28 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 75  rm(platform)=="u
9180: 6e 69 78 22 7d 20 7b 0a 20 20 20 20 66 69 6c 65  nix"} {.    file
9190: 20 63 6f 70 79 20 2d 66 6f 72 63 65 20 24 66 72   copy -force $fr
91a0: 6f 6d 20 24 74 6f 0a 20 20 7d 20 65 6c 73 65 20  om $to.  } else 
91b0: 7b 0a 20 20 20 20 73 65 74 20 66 20 5b 6f 70 65  {.    set f [ope
91c0: 6e 20 24 66 72 6f 6d 5d 0a 20 20 20 20 66 63 6f  n $from].    fco
91d0: 6e 66 69 67 75 72 65 20 24 66 20 2d 74 72 61 6e  nfigure $f -tran
91e0: 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20  slation binary. 
91f0: 20 20 20 73 65 74 20 74 20 5b 6f 70 65 6e 20 24     set t [open $
9200: 74 6f 20 77 5d 0a 20 20 20 20 66 63 6f 6e 66 69  to w].    fconfi
9210: 67 75 72 65 20 24 74 20 2d 74 72 61 6e 73 6c 61  gure $t -transla
9220: 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 20 20  tion binary.    
9230: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
9240: 24 74 20 5b 72 65 61 64 20 24 66 20 5b 66 69 6c  $t [read $f [fil
9250: 65 20 73 69 7a 65 20 24 66 72 6f 6d 5d 5d 0a 20  e size $from]]. 
9260: 20 20 20 63 6c 6f 73 65 20 24 74 0a 20 20 20 20     close $t.    
9270: 63 6c 6f 73 65 20 24 66 0a 20 20 7d 0a 7d 0a 0a  close $f.  }.}..
9280: 23 20 44 72 6f 70 20 61 6c 6c 20 74 61 62 6c 65  # Drop all table
9290: 73 20 69 6e 20 64 61 74 61 62 61 73 65 20 5b 64  s in database [d
92a0: 62 5d 0a 70 72 6f 63 20 64 72 6f 70 5f 61 6c 6c  b].proc drop_all
92b0: 5f 74 61 62 6c 65 73 20 7b 7b 64 62 20 64 62 7d  _tables {{db db}
92c0: 7d 20 7b 0a 20 20 69 66 63 61 70 61 62 6c 65 20  } {.  ifcapable 
92d0: 74 72 69 67 67 65 72 26 26 66 6f 72 65 69 67 6e  trigger&&foreign
92e0: 6b 65 79 20 7b 0a 20 20 20 20 73 65 74 20 70 6b  key {.    set pk
92f0: 20 5b 24 64 62 20 6f 6e 65 20 22 50 52 41 47 4d   [$db one "PRAGM
9300: 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73 22 5d  A foreign_keys"]
9310: 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20 22 50  .    $db eval "P
9320: 52 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65  RAGMA foreign_ke
9330: 79 73 20 3d 20 4f 46 46 22 0a 20 20 7d 0a 20 20  ys = OFF".  }.  
9340: 66 6f 72 65 61 63 68 20 7b 69 64 78 20 6e 61 6d  foreach {idx nam
9350: 65 20 66 69 6c 65 7d 20 5b 64 62 20 65 76 61 6c  e file} [db eval
9360: 20 7b 50 52 41 47 4d 41 20 64 61 74 61 62 61 73   {PRAGMA databas
9370: 65 5f 6c 69 73 74 7d 5d 20 7b 0a 20 20 20 20 69  e_list}] {.    i
9380: 66 20 7b 24 69 64 78 3d 3d 31 7d 20 7b 0a 20 20  f {$idx==1} {.  
9390: 20 20 20 20 73 65 74 20 6d 61 73 74 65 72 20 73      set master s
93a0: 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65  qlite_temp_maste
93b0: 72 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20  r.    } else {. 
93c0: 20 20 20 20 20 73 65 74 20 6d 61 73 74 65 72 20       set master 
93d0: 24 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d 61 73  $name.sqlite_mas
93e0: 74 65 72 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f  ter.    }.    fo
93f0: 72 65 61 63 68 20 7b 74 20 74 79 70 65 7d 20 5b  reach {t type} [
9400: 24 64 62 20 65 76 61 6c 20 22 0a 20 20 20 20 20  $db eval ".     
9410: 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79   SELECT name, ty
9420: 70 65 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 0a  pe FROM $master.
9430: 20 20 20 20 20 20 57 48 45 52 45 20 74 79 70 65        WHERE type
9440: 20 49 4e 28 27 74 61 62 6c 65 27 2c 20 27 76 69   IN('table', 'vi
9450: 65 77 27 29 20 41 4e 44 20 6e 61 6d 65 20 4e 4f  ew') AND name NO
9460: 54 20 4c 49 4b 45 20 27 73 71 6c 69 74 65 58 5f  T LIKE 'sqliteX_
9470: 25 27 20 45 53 43 41 50 45 20 27 58 27 0a 20 20  %' ESCAPE 'X'.  
9480: 20 20 22 5d 20 7b 0a 20 20 20 20 20 20 24 64 62    "] {.      $db
9490: 20 65 76 61 6c 20 22 44 52 4f 50 20 24 74 79 70   eval "DROP $typ
94a0: 65 20 5c 22 24 74 5c 22 22 0a 20 20 20 20 7d 0a  e \"$t\"".    }.
94b0: 20 20 7d 0a 20 20 69 66 63 61 70 61 62 6c 65 20    }.  ifcapable 
94c0: 74 72 69 67 67 65 72 26 26 66 6f 72 65 69 67 6e  trigger&&foreign
94d0: 6b 65 79 20 7b 0a 20 20 20 20 24 64 62 20 65 76  key {.    $db ev
94e0: 61 6c 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69  al "PRAGMA forei
94f0: 67 6e 5f 6b 65 79 73 20 3d 20 24 70 6b 22 0a 20  gn_keys = $pk". 
9500: 20 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d   }.}..#---------
9510: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9520: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9530: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9540: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9550: 0a 23 20 49 66 20 61 20 74 65 73 74 20 73 63 72  .# If a test scr
9560: 69 70 74 20 69 73 20 65 78 65 63 75 74 65 64 20  ipt is executed 
9570: 77 69 74 68 20 67 6c 6f 62 61 6c 20 76 61 72 69  with global vari
9580: 61 62 6c 65 20 24 3a 3a 47 28 70 65 72 6d 3a 6e  able $::G(perm:n
9590: 61 6d 65 29 20 73 65 74 20 74 6f 0a 23 20 22 77  ame) set to.# "w
95a0: 61 6c 22 2c 20 74 68 65 6e 20 74 68 65 20 74 65  al", then the te
95b0: 73 74 73 20 61 72 65 20 72 75 6e 20 69 6e 20 57  sts are run in W
95c0: 41 4c 20 6d 6f 64 65 2e 20 4f 74 68 65 72 77 69  AL mode. Otherwi
95d0: 73 65 2c 20 74 68 65 79 20 73 68 6f 75 6c 64 20  se, they should 
95e0: 62 65 20 72 75 6e 20 0a 23 20 69 6e 20 72 6f 6c  be run .# in rol
95f0: 6c 62 61 63 6b 20 6d 6f 64 65 2e 20 54 68 65 20  lback mode. The 
9600: 66 6f 6c 6c 6f 77 69 6e 67 20 54 63 6c 20 70 72  following Tcl pr
9610: 6f 63 73 20 61 72 65 20 75 73 65 64 20 74 6f 20  ocs are used to 
9620: 6d 61 6b 65 20 74 68 69 73 20 6c 65 73 73 20 0a  make this less .
9630: 23 20 69 6e 74 72 75 73 69 76 65 3a 0a 23 0a 23  # intrusive:.#.#
9640: 20 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e     wal_set_journ
9650: 61 6c 5f 6d 6f 64 65 20 3f 44 42 3f 0a 23 0a 23  al_mode ?DB?.#.#
9660: 20 20 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20       If running 
9670: 61 20 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63  a WAL test, exec
9680: 75 74 65 20 22 50 52 41 47 4d 41 20 6a 6f 75 72  ute "PRAGMA jour
9690: 6e 61 6c 5f 6d 6f 64 65 20 3d 20 77 61 6c 22 20  nal_mode = wal" 
96a0: 75 73 69 6e 67 0a 23 20 20 20 20 20 63 6f 6e 6e  using.#     conn
96b0: 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42  ection handle DB
96c0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74 68 69  . Otherwise, thi
96d0: 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61 20 6e  s command is a n
96e0: 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f  o-op..#.#   wal_
96f0: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
9700: 64 65 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f  de TESTNAME ?DB?
9710: 0a 23 0a 23 20 20 20 20 20 49 66 20 72 75 6e 6e  .#.#     If runn
9720: 69 6e 67 20 61 20 57 41 4c 20 74 65 73 74 2c 20  ing a WAL test, 
9730: 65 78 65 63 75 74 65 20 61 20 74 65 73 74 73 20  execute a tests 
9740: 63 61 73 65 20 74 68 61 74 20 66 61 69 6c 73 20  case that fails 
9750: 69 66 20 74 68 65 20 6d 61 69 6e 0a 23 20 20 20  if the main.#   
9760: 20 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 63    database for c
9770: 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65  onnection handle
9780: 20 44 42 20 69 73 20 6e 6f 74 20 63 75 72 72 65   DB is not curre
9790: 6e 74 6c 79 20 61 20 57 41 4c 20 64 61 74 61 62  ntly a WAL datab
97a0: 61 73 65 2e 0a 23 20 20 20 20 20 4f 74 68 65 72  ase..#     Other
97b0: 77 69 73 65 20 28 69 66 20 6e 6f 74 20 72 75 6e  wise (if not run
97c0: 6e 69 6e 67 20 61 20 57 41 4c 20 70 65 72 6d 75  ning a WAL permu
97d0: 74 61 74 69 6f 6e 29 20 74 68 69 73 20 69 73 20  tation) this is 
97e0: 61 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77  a no-op..#.#   w
97f0: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23  al_is_wal_mode.#
9800: 20 20 20 0a 23 20 20 20 20 20 52 65 74 75 72 6e     .#     Return
9810: 73 20 74 72 75 65 20 69 66 20 74 68 69 73 20 74  s true if this t
9820: 65 73 74 20 73 68 6f 75 6c 64 20 62 65 20 72 75  est should be ru
9830: 6e 20 69 6e 20 57 41 4c 20 6d 6f 64 65 2e 20 46  n in WAL mode. F
9840: 61 6c 73 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  alse otherwise..
9850: 23 20 0a 70 72 6f 63 20 77 61 6c 5f 69 73 5f 77  # .proc wal_is_w
9860: 61 6c 5f 6d 6f 64 65 20 7b 7d 20 7b 0a 20 20 65  al_mode {} {.  e
9870: 78 70 72 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f  xpr {[permutatio
9880: 6e 5d 20 65 71 20 22 77 61 6c 22 7d 0a 7d 0a 70  n] eq "wal"}.}.p
9890: 72 6f 63 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72  roc wal_set_jour
98a0: 6e 61 6c 5f 6d 6f 64 65 20 7b 7b 64 62 20 64 62  nal_mode {{db db
98b0: 7d 7d 20 7b 0a 20 20 69 66 20 7b 20 5b 77 61 6c  }} {.  if { [wal
98c0: 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20  _is_wal_mode] } 
98d0: 7b 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20 22  {.    $db eval "
98e0: 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d  PRAGMA journal_m
98f0: 6f 64 65 20 3d 20 57 41 4c 22 0a 20 20 7d 0a 7d  ode = WAL".  }.}
9900: 0a 70 72 6f 63 20 77 61 6c 5f 63 68 65 63 6b 5f  .proc wal_check_
9910: 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b 74 65  journal_mode {te
9920: 73 74 6e 61 6d 65 20 7b 64 62 20 64 62 7d 7d 20  stname {db db}} 
9930: 7b 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f 69 73  {.  if { [wal_is
9940: 5f 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20  _wal_mode] } {. 
9950: 20 20 20 24 64 62 20 65 76 61 6c 20 7b 20 53 45     $db eval { SE
9960: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69  LECT * FROM sqli
9970: 74 65 5f 6d 61 73 74 65 72 20 7d 0a 20 20 20 20  te_master }.    
9980: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
9990: 65 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c  e [list $db eval
99a0: 20 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 6a 6f   "PRAGMA main.jo
99b0: 75 72 6e 61 6c 5f 6d 6f 64 65 22 5d 20 7b 77 61  urnal_mode"] {wa
99c0: 6c 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 70  l}.  }.}..proc p
99d0: 65 72 6d 75 74 61 74 69 6f 6e 20 7b 7d 20 7b 0a  ermutation {} {.
99e0: 20 20 73 65 74 20 70 65 72 6d 20 22 22 0a 20 20    set perm "".  
99f0: 63 61 74 63 68 20 7b 73 65 74 20 70 65 72 6d 20  catch {set perm 
9a00: 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65 29 7d  $::G(perm:name)}
9a10: 0a 20 20 73 65 74 20 70 65 72 6d 0a 7d 0a 70 72  .  set perm.}.pr
9a20: 6f 63 20 70 72 65 73 71 6c 20 7b 7d 20 7b 0a 20  oc presql {} {. 
9a30: 20 73 65 74 20 70 72 65 73 71 6c 20 22 22 0a 20   set presql "". 
9a40: 20 63 61 74 63 68 20 7b 73 65 74 20 70 72 65 73   catch {set pres
9a50: 71 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65  ql $::G(perm:pre
9a60: 73 71 6c 29 7d 0a 20 20 73 65 74 20 70 72 65 73  sql)}.  set pres
9a70: 71 6c 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  ql.}..#---------
9a80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9a90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9aa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9ab0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
9ac0: 0a 23 0a 70 72 6f 63 20 73 6c 61 76 65 5f 74 65  .#.proc slave_te
9ad0: 73 74 5f 73 63 72 69 70 74 20 7b 73 63 72 69 70  st_script {scrip
9ae0: 74 7d 20 7b 0a 0a 20 20 23 20 43 72 65 61 74 65  t} {..  # Create
9af0: 20 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72   the interpreter
9b00: 20 75 73 65 64 20 74 6f 20 72 75 6e 20 74 68 65   used to run the
9b10: 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20   test script..  
9b20: 69 6e 74 65 72 70 20 63 72 65 61 74 65 20 74 69  interp create ti
9b30: 6e 74 65 72 70 0a 0a 20 20 23 20 50 6f 70 75 6c  nterp..  # Popul
9b40: 61 74 65 20 73 6f 6d 65 20 67 6c 6f 62 61 6c 20  ate some global 
9b50: 76 61 72 69 61 62 6c 65 73 20 74 68 61 74 20 74  variables that t
9b60: 65 73 74 65 72 2e 74 63 6c 20 65 78 70 65 63 74  ester.tcl expect
9b70: 73 20 74 6f 20 73 65 65 2e 0a 20 20 66 6f 72 65  s to see..  fore
9b80: 61 63 68 20 7b 76 61 72 20 76 61 6c 75 65 7d 20  ach {var value} 
9b90: 5b 6c 69 73 74 20 20 20 20 20 20 20 20 20 20 20  [list           
9ba0: 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72 67 76 30     \.    ::argv0
9bb0: 20 24 3a 3a 61 72 67 76 30 20 20 20 20 20 20 20   $::argv0       
9bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
9bd0: 20 20 20 20 3a 3a 61 72 67 76 20 20 7b 7d 20 20      ::argv  {}  
9be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9bf0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 3a           \.    :
9c00: 3a 53 4c 41 56 45 20 31 20 20 20 20 20 20 20 20  :SLAVE 1        
9c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9c20: 20 20 20 20 5c 0a 20 20 5d 20 7b 0a 20 20 20 20      \.  ] {.    
9c30: 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74  interp eval tint
9c40: 65 72 70 20 5b 6c 69 73 74 20 73 65 74 20 24 76  erp [list set $v
9c50: 61 72 20 24 76 61 6c 75 65 5d 0a 20 20 7d 0a 0a  ar $value].  }..
9c60: 20 20 23 20 54 68 65 20 61 6c 69 61 73 20 75 73    # The alias us
9c70: 65 64 20 74 6f 20 61 63 63 65 73 73 20 74 68 65  ed to access the
9c80: 20 67 6c 6f 62 61 6c 20 74 65 73 74 20 63 6f 75   global test cou
9c90: 6e 74 65 72 73 2e 0a 20 20 74 69 6e 74 65 72 70  nters..  tinterp
9ca0: 20 61 6c 69 61 73 20 73 65 74 5f 74 65 73 74 5f   alias set_test_
9cb0: 63 6f 75 6e 74 65 72 20 73 65 74 5f 74 65 73 74  counter set_test
9cc0: 5f 63 6f 75 6e 74 65 72 0a 0a 20 20 23 20 53 65  _counter..  # Se
9cd0: 74 20 75 70 20 74 68 65 20 3a 3a 63 6d 64 6c 69  t up the ::cmdli
9ce0: 6e 65 61 72 67 20 61 72 72 61 79 20 69 6e 20 74  nearg array in t
9cf0: 68 65 20 73 6c 61 76 65 2e 0a 20 20 69 6e 74 65  he slave..  inte
9d00: 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20  rp eval tinterp 
9d10: 5b 6c 69 73 74 20 61 72 72 61 79 20 73 65 74 20  [list array set 
9d20: 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 5b 61 72  ::cmdlinearg [ar
9d30: 72 61 79 20 67 65 74 20 3a 3a 63 6d 64 6c 69 6e  ray get ::cmdlin
9d40: 65 61 72 67 5d 5d 0a 0a 20 20 23 20 53 65 74 20  earg]]..  # Set 
9d50: 75 70 20 74 68 65 20 3a 3a 47 20 61 72 72 61 79  up the ::G array
9d60: 20 69 6e 20 74 68 65 20 73 6c 61 76 65 2e 0a 20   in the slave.. 
9d70: 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e   interp eval tin
9d80: 74 65 72 70 20 5b 6c 69 73 74 20 61 72 72 61 79  terp [list array
9d90: 20 73 65 74 20 3a 3a 47 20 5b 61 72 72 61 79 20   set ::G [array 
9da0: 67 65 74 20 3a 3a 47 5d 5d 0a 0a 20 20 23 20 4c  get ::G]]..  # L
9db0: 6f 61 64 20 74 68 65 20 76 61 72 69 6f 75 73 20  oad the various 
9dc0: 74 65 73 74 20 69 6e 74 65 72 66 61 63 65 73 20  test interfaces 
9dd0: 69 6d 70 6c 65 6d 65 6e 74 65 64 20 69 6e 20 43  implemented in C
9de0: 2e 0a 20 20 6c 6f 61 64 5f 74 65 73 74 66 69 78  ..  load_testfix
9df0: 74 75 72 65 5f 65 78 74 65 6e 73 69 6f 6e 73 20  ture_extensions 
9e00: 74 69 6e 74 65 72 70 0a 0a 20 20 23 20 52 75 6e  tinterp..  # Run
9e10: 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74   the test script
9e20: 2e 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20  ..  interp eval 
9e30: 74 69 6e 74 65 72 70 20 24 73 63 72 69 70 74 0a  tinterp $script.
9e40: 0a 20 20 23 20 43 68 65 63 6b 20 69 66 20 74 68  .  # Check if th
9e50: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 63 61  e interpreter ca
9e60: 6c 6c 20 5b 72 75 6e 5f 74 68 72 65 61 64 5f 74  ll [run_thread_t
9e70: 65 73 74 73 5d 0a 20 20 69 66 20 7b 20 5b 69 6e  ests].  if { [in
9e80: 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72  terp eval tinter
9e90: 70 20 7b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a  p {info exists :
9ea0: 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74  :run_thread_test
9eb0: 73 5f 63 61 6c 6c 65 64 7d 5d 20 7d 20 7b 0a 20  s_called}] } {. 
9ec0: 20 20 20 73 65 74 20 3a 3a 72 75 6e 5f 74 68 72     set ::run_thr
9ed0: 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64  ead_tests_called
9ee0: 20 31 0a 20 20 7d 0a 0a 20 20 23 20 44 65 6c 65   1.  }..  # Dele
9ef0: 74 65 20 74 68 65 20 69 6e 74 65 72 70 72 65 74  te the interpret
9f00: 65 72 20 75 73 65 64 20 74 6f 20 72 75 6e 20 74  er used to run t
9f10: 68 65 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a  he test script..
9f20: 20 20 69 6e 74 65 72 70 20 64 65 6c 65 74 65 20    interp delete 
9f30: 74 69 6e 74 65 72 70 0a 7d 0a 0a 70 72 6f 63 20  tinterp.}..proc 
9f40: 73 6c 61 76 65 5f 74 65 73 74 5f 66 69 6c 65 20  slave_test_file 
9f50: 7b 7a 46 69 6c 65 7d 20 7b 0a 20 20 73 65 74 20  {zFile} {.  set 
9f60: 74 61 69 6c 20 5b 66 69 6c 65 20 74 61 69 6c 20  tail [file tail 
9f70: 24 7a 46 69 6c 65 5d 0a 0a 20 20 69 66 20 7b 5b  $zFile]..  if {[
9f80: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
9f90: 73 74 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f  start:permutatio
9fa0: 6e 29 5d 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b  n)]} {.    if {[
9fb0: 70 65 72 6d 75 74 61 74 69 6f 6e 5d 20 21 3d 20  permutation] != 
9fc0: 24 3a 3a 47 28 73 74 61 72 74 3a 70 65 72 6d 75  $::G(start:permu
9fd0: 74 61 74 69 6f 6e 29 7d 20 72 65 74 75 72 6e 0a  tation)} return.
9fe0: 20 20 20 20 75 6e 73 65 74 20 3a 3a 47 28 73 74      unset ::G(st
9ff0: 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29  art:permutation)
a000: 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f  .  }.  if {[info
a010: 20 65 78 69 73 74 73 20 3a 3a 47 28 73 74 61 72   exists ::G(star
a020: 74 3a 66 69 6c 65 29 5d 7d 20 7b 0a 20 20 20 20  t:file)]} {.    
a030: 69 66 20 7b 24 74 61 69 6c 20 21 3d 20 24 3a 3a  if {$tail != $::
a040: 47 28 73 74 61 72 74 3a 66 69 6c 65 29 20 26 26  G(start:file) &&
a050: 20 24 74 61 69 6c 21 3d 22 24 3a 3a 47 28 73 74   $tail!="$::G(st
a060: 61 72 74 3a 66 69 6c 65 29 2e 74 65 73 74 22 7d  art:file).test"}
a070: 20 72 65 74 75 72 6e 0a 20 20 20 20 75 6e 73 65   return.    unse
a080: 74 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65  t ::G(start:file
a090: 29 0a 20 20 7d 0a 0a 20 20 23 20 52 65 6d 65 6d  ).  }..  # Remem
a0a0: 62 65 72 20 74 68 65 20 76 61 6c 75 65 20 6f 66  ber the value of
a0b0: 20 74 68 65 20 73 68 61 72 65 64 2d 63 61 63 68   the shared-cach
a0c0: 65 20 73 65 74 74 69 6e 67 2e 20 53 6f 20 74 68  e setting. So th
a0d0: 61 74 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  at it is possibl
a0e0: 65 0a 20 20 23 20 74 6f 20 63 68 65 63 6b 20 61  e.  # to check a
a0f0: 66 74 65 72 77 61 72 64 73 20 74 68 61 74 20 69  fterwards that i
a100: 74 20 77 61 73 20 6e 6f 74 20 6d 6f 64 69 66 69  t was not modifi
a110: 65 64 20 62 79 20 74 68 65 20 74 65 73 74 20 73  ed by the test s
a120: 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69 66 63  cript..  #.  ifc
a130: 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f 63 61  apable shared_ca
a140: 63 68 65 20 7b 20 73 65 74 20 73 63 73 20 5b 73  che { set scs [s
a150: 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68  qlite3_enable_sh
a160: 61 72 65 64 5f 63 61 63 68 65 5d 20 7d 0a 0a 20  ared_cache] }.. 
a170: 20 23 20 52 75 6e 20 74 68 65 20 74 65 73 74 20   # Run the test 
a180: 73 63 72 69 70 74 20 69 6e 20 61 20 73 6c 61 76  script in a slav
a190: 65 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 20  e interpreter.. 
a1a0: 20 23 0a 20 20 75 6e 73 65 74 20 2d 6e 6f 63 6f   #.  unset -noco
a1b0: 6d 70 6c 61 69 6e 20 3a 3a 72 75 6e 5f 74 68 72  mplain ::run_thr
a1c0: 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64  ead_tests_called
a1d0: 0a 20 20 72 65 73 65 74 5f 70 72 6e 67 5f 73 74  .  reset_prng_st
a1e0: 61 74 65 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69  ate.  set ::sqli
a1f0: 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75  te_open_file_cou
a200: 6e 74 20 30 0a 20 20 73 65 74 20 74 69 6d 65 20  nt 0.  set time 
a210: 5b 74 69 6d 65 20 7b 20 73 6c 61 76 65 5f 74 65  [time { slave_te
a220: 73 74 5f 73 63 72 69 70 74 20 5b 6c 69 73 74 20  st_script [list 
a230: 73 6f 75 72 63 65 20 24 7a 46 69 6c 65 5d 20 7d  source $zFile] }
a240: 5d 0a 20 20 73 65 74 20 6d 73 20 5b 65 78 70 72  ].  set ms [expr
a250: 20 5b 6c 69 6e 64 65 78 20 24 74 69 6d 65 20 30   [lindex $time 0
a260: 5d 20 2f 20 31 30 30 30 5d 0a 0a 20 20 23 20 54  ] / 1000]..  # T
a270: 65 73 74 20 74 68 61 74 20 61 6c 6c 20 66 69 6c  est that all fil
a280: 65 73 20 6f 70 65 6e 65 64 20 62 79 20 74 68 65  es opened by the
a290: 20 74 65 73 74 20 73 63 72 69 70 74 20 77 65 72   test script wer
a2a0: 65 20 63 6c 6f 73 65 64 2e 20 4f 6d 69 74 20 74  e closed. Omit t
a2b0: 68 69 73 0a 20 20 23 20 69 66 20 74 68 65 20 74  his.  # if the t
a2c0: 65 73 74 20 73 63 72 69 70 74 20 68 61 73 20 22  est script has "
a2d0: 74 68 72 65 61 64 22 20 69 6e 20 69 74 73 20 6e  thread" in its n
a2e0: 61 6d 65 2e 20 54 68 65 20 6f 70 65 6e 20 66 69  ame. The open fi
a2f0: 6c 65 20 63 6f 75 6e 74 65 72 0a 20 20 23 20 69  le counter.  # i
a300: 73 20 6e 6f 74 20 74 68 72 65 61 64 2d 73 61 66  s not thread-saf
a310: 65 2e 0a 20 20 23 0a 20 20 69 66 20 7b 5b 69 6e  e..  #.  if {[in
a320: 66 6f 20 65 78 69 73 74 73 20 3a 3a 72 75 6e 5f  fo exists ::run_
a330: 74 68 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c  thread_tests_cal
a340: 6c 65 64 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 64  led]==0} {.    d
a350: 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c 7d 2d 63  o_test ${tail}-c
a360: 6c 6f 73 65 61 6c 6c 66 69 6c 65 73 20 7b 20 65  loseallfiles { e
a370: 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f  xpr {$::sqlite_o
a380: 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 3e 30  pen_file_count>0
a390: 7d 20 7d 20 7b 30 7d 0a 20 20 7d 0a 20 20 73 65  } } {0}.  }.  se
a3a0: 74 20 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f  t ::sqlite_open_
a3b0: 66 69 6c 65 5f 63 6f 75 6e 74 20 30 0a 0a 20 20  file_count 0..  
a3c0: 23 20 54 65 73 74 20 74 68 61 74 20 74 68 65 20  # Test that the 
a3d0: 67 6c 6f 62 61 6c 20 22 73 68 61 72 65 64 2d 63  global "shared-c
a3e0: 61 63 68 65 22 20 73 65 74 74 69 6e 67 20 77 61  ache" setting wa
a3f0: 73 20 6e 6f 74 20 61 6c 74 65 72 65 64 20 62 79  s not altered by
a400: 20 0a 20 20 23 20 74 68 65 20 74 65 73 74 20 73   .  # the test s
a410: 63 72 69 70 74 2e 0a 20 20 23 0a 20 20 69 66 63  cript..  #.  ifc
a420: 61 70 61 62 6c 65 20 73 68 61 72 65 64 5f 63 61  apable shared_ca
a430: 63 68 65 20 7b 20 0a 20 20 20 20 73 65 74 20 72  che { .    set r
a440: 65 73 20 5b 65 78 70 72 20 7b 5b 73 71 6c 69 74  es [expr {[sqlit
a450: 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65 64  e3_enable_shared
a460: 5f 63 61 63 68 65 5d 20 3d 3d 20 24 73 63 73 7d  _cache] == $scs}
a470: 5d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 7b  ].    do_test ${
a480: 74 61 69 6c 7d 2d 73 68 61 72 65 64 63 61 63 68  tail}-sharedcach
a490: 65 73 65 74 74 69 6e 67 20 5b 6c 69 73 74 20 73  esetting [list s
a4a0: 65 74 20 7b 7d 20 24 72 65 73 5d 20 31 0a 20 20  et {} $res] 1.  
a4b0: 7d 0a 0a 20 20 23 20 41 64 64 20 73 6f 6d 65 20  }..  # Add some 
a4c0: 69 6e 66 6f 20 74 6f 20 74 68 65 20 6f 75 74 70  info to the outp
a4d0: 75 74 2e 0a 20 20 23 0a 20 20 70 75 74 73 20 22  ut..  #.  puts "
a4e0: 54 69 6d 65 3a 20 24 74 61 69 6c 20 24 6d 73 20  Time: $tail $ms 
a4f0: 6d 73 22 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74  ms".  show_memst
a500: 61 74 73 0a 7d 0a 0a 23 20 4f 70 65 6e 20 61 20  ats.}..# Open a 
a510: 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6f  new connection o
a520: 6e 20 64 61 74 61 62 61 73 65 20 74 65 73 74 2e  n database test.
a530: 64 62 20 61 6e 64 20 65 78 65 63 75 74 65 20 74  db and execute t
a540: 68 65 20 53 51 4c 20 73 63 72 69 70 74 0a 23 20  he SQL script.# 
a550: 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61  supplied as an a
a560: 72 67 75 6d 65 6e 74 2e 20 42 65 66 6f 72 65 20  rgument. Before 
a570: 72 65 74 75 72 6e 69 6e 67 2c 20 63 6c 6f 73 65  returning, close
a580: 20 74 68 65 20 6e 65 77 20 63 6f 6e 65 63 74 69   the new conecti
a590: 6f 6e 20 61 6e 64 0a 23 20 72 65 73 74 6f 72 65  on and.# restore
a5a0: 20 74 68 65 20 34 20 62 79 74 65 20 66 69 65 6c   the 4 byte fiel
a5b0: 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20 68  ds starting at h
a5c0: 65 61 64 65 72 20 6f 66 66 73 65 74 73 20 32 38  eader offsets 28
a5d0: 2c 20 39 32 20 61 6e 64 20 39 36 0a 23 20 74 6f  , 92 and 96.# to
a5e0: 20 74 68 65 20 76 61 6c 75 65 73 20 74 68 65 79   the values they
a5f0: 20 68 65 6c 64 20 62 65 66 6f 72 65 20 74 68 65   held before the
a600: 20 53 51 4c 20 77 61 73 20 65 78 65 63 75 74 65   SQL was execute
a610: 64 2e 20 54 68 69 73 20 73 69 6d 75 6c 61 74 65  d. This simulate
a620: 73 0a 23 20 61 20 77 72 69 74 65 20 62 79 20 61  s.# a write by a
a630: 20 70 72 65 2d 33 2e 37 2e 30 20 63 6c 69 65 6e   pre-3.7.0 clien
a640: 74 2e 0a 23 0a 70 72 6f 63 20 73 71 6c 33 36 32  t..#.proc sql362
a650: 33 31 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74  31 {sql} {.  set
a660: 20 42 20 5b 68 65 78 69 6f 5f 72 65 61 64 20 74   B [hexio_read t
a670: 65 73 74 2e 64 62 20 39 32 20 38 5d 0a 20 20 73  est.db 92 8].  s
a680: 65 74 20 41 20 5b 68 65 78 69 6f 5f 72 65 61 64  et A [hexio_read
a690: 20 74 65 73 74 2e 64 62 20 32 38 20 34 5d 0a 20   test.db 28 4]. 
a6a0: 20 73 71 6c 69 74 65 33 20 64 62 33 36 32 33 31   sqlite3 db36231
a6b0: 20 74 65 73 74 2e 64 62 0a 20 20 63 61 74 63 68   test.db.  catch
a6c0: 20 7b 20 64 62 33 36 32 33 31 20 66 75 6e 63 20   { db36231 func 
a6d0: 61 5f 73 74 72 69 6e 67 20 61 5f 73 74 72 69 6e  a_string a_strin
a6e0: 67 20 7d 0a 20 20 65 78 65 63 73 71 6c 20 24 73  g }.  execsql $s
a6f0: 71 6c 20 64 62 33 36 32 33 31 0a 20 20 64 62 33  ql db36231.  db3
a700: 36 32 33 31 20 63 6c 6f 73 65 0a 20 20 68 65 78  6231 close.  hex
a710: 69 6f 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62  io_write test.db
a720: 20 32 38 20 24 41 0a 20 20 68 65 78 69 6f 5f 77   28 $A.  hexio_w
a730: 72 69 74 65 20 74 65 73 74 2e 64 62 20 39 32 20  rite test.db 92 
a740: 24 42 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d  $B.  return "".}
a750: 0a 0a 70 72 6f 63 20 64 62 5f 73 61 76 65 20 7b  ..proc db_save {
a760: 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20 66 20  } {.  foreach f 
a770: 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69  [glob -nocomplai
a780: 6e 20 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b  n sv_test.db*] {
a790: 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20   forcedelete $f 
a7a0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  }.  foreach f [g
a7b0: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
a7c0: 74 65 73 74 2e 64 62 2a 5d 20 7b 0a 20 20 20 20  test.db*] {.    
a7d0: 73 65 74 20 66 32 20 22 73 76 5f 24 66 22 0a 20  set f2 "sv_$f". 
a7e0: 20 20 20 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f     file copy -fo
a7f0: 72 63 65 20 24 66 20 24 66 32 0a 20 20 7d 0a 7d  rce $f $f2.  }.}
a800: 0a 70 72 6f 63 20 64 62 5f 73 61 76 65 5f 61 6e  .proc db_save_an
a810: 64 5f 63 6c 6f 73 65 20 7b 7d 20 7b 0a 20 20 64  d_close {} {.  d
a820: 62 5f 73 61 76 65 0a 20 20 63 61 74 63 68 20 7b  b_save.  catch {
a830: 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20 20 72 65   db close }.  re
a840: 74 75 72 6e 20 22 22 0a 7d 0a 70 72 6f 63 20 64  turn "".}.proc d
a850: 62 5f 72 65 73 74 6f 72 65 20 7b 7d 20 7b 0a 20  b_restore {} {. 
a860: 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62   foreach f [glob
a870: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73   -nocomplain tes
a880: 74 2e 64 62 2a 5d 20 7b 20 66 6f 72 63 65 64 65  t.db*] { forcede
a890: 6c 65 74 65 20 24 66 20 7d 0a 20 20 66 6f 72 65  lete $f }.  fore
a8a0: 61 63 68 20 66 32 20 5b 67 6c 6f 62 20 2d 6e 6f  ach f2 [glob -no
a8b0: 63 6f 6d 70 6c 61 69 6e 20 73 76 5f 74 65 73 74  complain sv_test
a8c0: 2e 64 62 2a 5d 20 7b 0a 20 20 20 20 73 65 74 20  .db*] {.    set 
a8d0: 66 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  f [string range 
a8e0: 24 66 32 20 33 20 65 6e 64 5d 0a 20 20 20 20 66  $f2 3 end].    f
a8f0: 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 20  ile copy -force 
a900: 24 66 32 20 24 66 0a 20 20 7d 0a 7d 0a 70 72 6f  $f2 $f.  }.}.pro
a910: 63 20 64 62 5f 72 65 73 74 6f 72 65 5f 61 6e 64  c db_restore_and
a920: 5f 72 65 6f 70 65 6e 20 7b 7b 64 62 66 69 6c 65  _reopen {{dbfile
a930: 20 74 65 73 74 2e 64 62 7d 7d 20 7b 0a 20 20 63   test.db}} {.  c
a940: 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65 20  atch { db close 
a950: 7d 0a 20 20 64 62 5f 72 65 73 74 6f 72 65 0a 20  }.  db_restore. 
a960: 20 73 71 6c 69 74 65 33 20 64 62 20 24 64 62 66   sqlite3 db $dbf
a970: 69 6c 65 0a 7d 0a 70 72 6f 63 20 64 62 5f 64 65  ile.}.proc db_de
a980: 6c 65 74 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 20  lete_and_reopen 
a990: 7b 7b 66 69 6c 65 20 74 65 73 74 2e 64 62 7d 7d  {{file test.db}}
a9a0: 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62 20   {.  catch { db 
a9b0: 63 6c 6f 73 65 20 7d 0a 20 20 66 6f 72 65 61 63  close }.  foreac
a9c0: 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d  h f [glob -nocom
a9d0: 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20  plain test.db*] 
a9e0: 7b 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66  { file delete -f
a9f0: 6f 72 63 65 20 24 66 20 7d 0a 20 20 73 71 6c 69  orce $f }.  sqli
aa00: 74 65 33 20 64 62 20 24 66 69 6c 65 0a 7d 0a 0a  te3 db $file.}..
aa10: 23 20 49 66 20 74 68 65 20 6c 69 62 72 61 72 79  # If the library
aa20: 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77 69 74   is compiled wit
aa30: 68 20 74 68 65 20 53 51 4c 49 54 45 5f 44 45 46  h the SQLITE_DEF
aa40: 41 55 4c 54 5f 41 55 54 4f 56 41 43 55 55 4d 20  AULT_AUTOVACUUM 
aa50: 6d 61 63 72 6f 20 73 65 74 0a 23 20 74 6f 20 6e  macro set.# to n
aa60: 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 73 65  on-zero, then se
aa70: 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72  t the global var
aa80: 69 61 62 6c 65 20 24 41 55 54 4f 56 41 43 55 55  iable $AUTOVACUU
aa90: 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41 55 54 4f  M to 1..set AUTO
aaa0: 56 41 43 55 55 4d 20 24 73 71 6c 69 74 65 5f 6f  VACUUM $sqlite_o
aab0: 70 74 69 6f 6e 73 28 64 65 66 61 75 6c 74 5f 61  ptions(default_a
aac0: 75 74 6f 76 61 63 75 75 6d 29 0a 0a 73 6f 75 72  utovacuum)..sour
aad0: 63 65 20 24 74 65 73 74 64 69 72 2f 74 68 72 65  ce $testdir/thre
aae0: 61 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f  ad_common.tcl.so
aaf0: 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 6d 61  urce $testdir/ma
ab00: 6c 6c 6f 63 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a  lloc_common.tcl.