/ Hex Artifact Content
Login

Artifact 2a93004bc0fb2b5c29888964024695bade278ab2:


0000: 23 20 32 30 31 30 20 41 70 72 69 6c 20 31 33 0a  # 2010 April 13.
0010: 23 0a 23 20 54 68 65 20 61 75 74 68 6f 72 20 64  #.# The author d
0020: 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67  isclaims copyrig
0030: 68 74 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63  ht to this sourc
0040: 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61 63  e code.  In plac
0050: 65 20 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20 6e  e of.# a legal n
0060: 6f 74 69 63 65 2c 20 68 65 72 65 20 69 73 20 61  otice, here is a
0070: 20 62 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20 20   blessing:.#.#  
0080: 20 20 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f    May you do goo
0090: 64 20 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a  d and not evil..
00a0: 23 20 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e  #    May you fin
00b0: 64 20 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f  d forgiveness fo
00c0: 72 20 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66  r yourself and f
00d0: 6f 72 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 23  orgive others..#
00e0: 20 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72      May you shar
00f0: 65 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20  e freely, never 
0100: 74 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e  taking more than
0110: 20 79 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a 2a   you give..#.#**
0120: 2a 2a 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 0a 23 20 54 68 69 73 20 66 69 6c  *****.# This fil
0170: 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 72 65 67  e implements reg
0180: 72 65 73 73 69 6f 6e 20 74 65 73 74 73 20 66 6f  ression tests fo
0190: 72 20 53 51 4c 69 74 65 20 6c 69 62 72 61 72 79  r SQLite library
01a0: 2e 20 20 54 68 65 0a 23 20 66 6f 63 75 73 20 6f  .  The.# focus o
01b0: 66 20 74 68 69 73 20 66 69 6c 65 20 69 73 20 74  f this file is t
01c0: 65 73 74 69 6e 67 20 74 68 65 20 6f 70 65 72 61  esting the opera
01d0: 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c 69 62 72  tion of the libr
01e0: 61 72 79 20 69 6e 0a 23 20 22 50 52 41 47 4d 41  ary in.# "PRAGMA
01f0: 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 3d 57 41   journal_mode=WA
0200: 4c 22 20 6d 6f 64 65 2e 0a 23 0a 0a 73 65 74 20  L" mode..#..set 
0210: 74 65 73 74 64 69 72 20 5b 66 69 6c 65 20 64 69  testdir [file di
0220: 72 6e 61 6d 65 20 24 61 72 67 76 30 5d 0a 73 6f  rname $argv0].so
0230: 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 74 65  urce $testdir/te
0240: 73 74 65 72 2e 74 63 6c 0a 73 6f 75 72 63 65 20  ster.tcl.source 
0250: 24 74 65 73 74 64 69 72 2f 6c 6f 63 6b 5f 63 6f  $testdir/lock_co
0260: 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f 75 72 63 65 20  mmon.tcl.source 
0270: 24 74 65 73 74 64 69 72 2f 77 61 6c 5f 63 6f 6d  $testdir/wal_com
0280: 6d 6f 6e 2e 74 63 6c 0a 73 6f 75 72 63 65 20 24  mon.tcl.source $
0290: 74 65 73 74 64 69 72 2f 6d 61 6c 6c 6f 63 5f 63  testdir/malloc_c
02a0: 6f 6d 6d 6f 6e 2e 74 63 6c 0a 69 66 63 61 70 61  ommon.tcl.ifcapa
02b0: 62 6c 65 20 21 77 61 6c 20 7b 66 69 6e 69 73 68  ble !wal {finish
02c0: 5f 74 65 73 74 20 3b 20 72 65 74 75 72 6e 20 7d  _test ; return }
02d0: 0a 0a 73 65 74 20 61 5f 73 74 72 69 6e 67 5f 63  ..set a_string_c
02e0: 6f 75 6e 74 65 72 20 31 0a 70 72 6f 63 20 61 5f  ounter 1.proc a_
02f0: 73 74 72 69 6e 67 20 7b 6e 7d 20 7b 0a 20 20 67  string {n} {.  g
0300: 6c 6f 62 61 6c 20 61 5f 73 74 72 69 6e 67 5f 63  lobal a_string_c
0310: 6f 75 6e 74 65 72 0a 20 20 69 6e 63 72 20 61 5f  ounter.  incr a_
0320: 73 74 72 69 6e 67 5f 63 6f 75 6e 74 65 72 0a 20  string_counter. 
0330: 20 73 74 72 69 6e 67 20 72 61 6e 67 65 20 5b 73   string range [s
0340: 74 72 69 6e 67 20 72 65 70 65 61 74 20 22 24 7b  tring repeat "${
0350: 61 5f 73 74 72 69 6e 67 5f 63 6f 75 6e 74 65 72  a_string_counter
0360: 7d 2e 22 20 24 6e 5d 20 31 20 24 6e 0a 7d 0a 64  }." $n] 1 $n.}.d
0370: 62 20 66 75 6e 63 20 61 5f 73 74 72 69 6e 67 20  b func a_string 
0380: 61 5f 73 74 72 69 6e 67 0a 0a 23 2d 2d 2d 2d 2d  a_string..#-----
0390: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03d0: 2d 2d 2d 2d 0a 23 20 57 68 65 6e 20 61 20 72 6f  ----.# When a ro
03e0: 6c 6c 62 61 63 6b 20 6f 72 20 73 61 76 65 70 6f  llback or savepo
03f0: 69 6e 74 20 72 6f 6c 6c 62 61 63 6b 20 6f 63 63  int rollback occ
0400: 75 72 73 2c 20 74 68 65 20 63 6c 69 65 6e 74 20  urs, the client 
0410: 6d 61 79 20 72 65 6d 6f 76 65 0a 23 20 65 6c 65  may remove.# ele
0420: 6d 65 6e 74 73 20 66 72 6f 6d 20 6f 6e 65 20 6f  ments from one o
0430: 66 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  f the hash table
0440: 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  s in the wal-ind
0450: 65 78 2e 20 54 68 69 73 20 62 6c 6f 63 6b 0a 23  ex. This block.#
0460: 20 6f 66 20 74 65 73 74 20 63 61 73 65 73 20 74   of test cases t
0470: 65 73 74 73 20 74 68 61 74 20 6e 6f 74 68 69 6e  ests that nothin
0480: 67 20 61 70 70 65 61 72 73 20 74 6f 20 67 6f 20  g appears to go 
0490: 77 72 6f 6e 67 20 77 68 65 6e 20 74 68 69 73 20  wrong when this 
04a0: 69 73 0a 23 20 64 6f 6e 65 2e 0a 23 0a 64 6f 5f  is.# done..#.do_
04b0: 74 65 73 74 20 77 61 6c 33 2d 31 2e 30 20 7b 0a  test wal3-1.0 {.
04c0: 20 20 65 78 65 63 73 71 6c 20 7b 0a 20 20 20 20    execsql {.    
04d0: 50 52 41 47 4d 41 20 63 61 63 68 65 5f 73 69 7a  PRAGMA cache_siz
04e0: 65 20 3d 20 32 30 30 30 3b 0a 20 20 20 20 50 52  e = 2000;.    PR
04f0: 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65 20 3d  AGMA page_size =
0500: 20 31 30 32 34 3b 0a 20 20 20 20 50 52 41 47 4d   1024;.    PRAGM
0510: 41 20 61 75 74 6f 5f 76 61 63 75 75 6d 20 3d 20  A auto_vacuum = 
0520: 6f 66 66 3b 0a 20 20 20 20 50 52 41 47 4d 41 20  off;.    PRAGMA 
0530: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 3d 20 6e 6f  synchronous = no
0540: 72 6d 61 6c 3b 0a 20 20 20 20 50 52 41 47 4d 41  rmal;.    PRAGMA
0550: 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20   journal_mode = 
0560: 57 41 4c 3b 0a 20 20 20 20 50 52 41 47 4d 41 20  WAL;.    PRAGMA 
0570: 77 61 6c 5f 61 75 74 6f 63 68 65 63 6b 70 6f 69  wal_autocheckpoi
0580: 6e 74 20 3d 20 30 3b 0a 20 20 20 20 42 45 47 49  nt = 0;.    BEGI
0590: 4e 3b 0a 20 20 20 20 20 20 43 52 45 41 54 45 20  N;.      CREATE 
05a0: 54 41 42 4c 45 20 74 31 28 78 29 3b 0a 20 20 20  TABLE t1(x);.   
05b0: 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74     INSERT INTO t
05c0: 31 20 56 41 4c 55 45 53 28 20 61 5f 73 74 72 69  1 VALUES( a_stri
05d0: 6e 67 28 38 30 30 29 20 29 3b 20 20 20 20 20 20  ng(800) );      
05e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 20              /*  
05f0: 20 20 31 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53    1 */.      INS
0600: 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45  ERT INTO t1 SELE
0610: 43 54 20 61 5f 73 74 72 69 6e 67 28 38 30 30 29  CT a_string(800)
0620: 20 46 52 4f 4d 20 74 31 3b 20 20 20 20 20 20 20   FROM t1;       
0630: 20 20 20 20 20 20 2f 2a 20 20 20 20 32 20 2a 2f        /*    2 */
0640: 0a 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e  .      INSERT IN
0650: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 61 5f 73  TO t1 SELECT a_s
0660: 74 72 69 6e 67 28 38 30 30 29 20 46 52 4f 4d 20  tring(800) FROM 
0670: 74 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  t1;             
0680: 2f 2a 20 20 20 20 34 20 2a 2f 0a 20 20 20 20 20  /*    4 */.     
0690: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
06a0: 53 45 4c 45 43 54 20 61 5f 73 74 72 69 6e 67 28  SELECT a_string(
06b0: 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20 20  800) FROM t1;   
06c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 20 20 20            /*    
06d0: 38 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45 52  8 */.      INSER
06e0: 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54  T INTO t1 SELECT
06f0: 20 61 5f 73 74 72 69 6e 67 28 38 30 30 29 20 46   a_string(800) F
0700: 52 4f 4d 20 74 31 3b 20 20 20 20 20 20 20 20 20  ROM t1;         
0710: 20 20 20 20 2f 2a 20 20 20 31 36 20 2a 2f 0a 20      /*   16 */. 
0720: 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f       INSERT INTO
0730: 20 74 31 20 53 45 4c 45 43 54 20 61 5f 73 74 72   t1 SELECT a_str
0740: 69 6e 67 28 38 30 30 29 20 46 52 4f 4d 20 74 31  ing(800) FROM t1
0750: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
0760: 20 20 20 33 32 20 2a 2f 0a 20 20 20 20 20 20 49     32 */.      I
0770: 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45  NSERT INTO t1 SE
0780: 4c 45 43 54 20 61 5f 73 74 72 69 6e 67 28 38 30  LECT a_string(80
0790: 30 29 20 46 52 4f 4d 20 74 31 3b 20 20 20 20 20  0) FROM t1;     
07a0: 20 20 20 20 20 20 20 20 2f 2a 20 20 20 36 34 20          /*   64 
07b0: 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45 52 54 20  */.      INSERT 
07c0: 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 61  INTO t1 SELECT a
07d0: 5f 73 74 72 69 6e 67 28 38 30 30 29 20 46 52 4f  _string(800) FRO
07e0: 4d 20 74 31 3b 20 20 20 20 20 20 20 20 20 20 20  M t1;           
07f0: 20 20 2f 2a 20 20 31 32 38 2a 2f 0a 20 20 20 20    /*  128*/.    
0800: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
0810: 20 53 45 4c 45 43 54 20 61 5f 73 74 72 69 6e 67   SELECT a_string
0820: 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (800) FROM t1;  
0830: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 20 32             /*  2
0840: 35 36 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45  56 */.      INSE
0850: 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43  RT INTO t1 SELEC
0860: 54 20 61 5f 73 74 72 69 6e 67 28 38 30 30 29 20  T a_string(800) 
0870: 46 52 4f 4d 20 74 31 3b 20 20 20 20 20 20 20 20  FROM t1;        
0880: 20 20 20 20 20 2f 2a 20 20 35 31 32 20 2a 2f 0a       /*  512 */.
0890: 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54        INSERT INT
08a0: 4f 20 74 31 20 53 45 4c 45 43 54 20 61 5f 73 74  O t1 SELECT a_st
08b0: 72 69 6e 67 28 38 30 30 29 20 46 52 4f 4d 20 74  ring(800) FROM t
08c0: 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  1;             /
08d0: 2a 20 31 30 32 34 20 2a 2f 0a 20 20 20 20 20 20  * 1024 */.      
08e0: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
08f0: 45 4c 45 43 54 20 61 5f 73 74 72 69 6e 67 28 38  ELECT a_string(8
0900: 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20 20 20  00) FROM t1;    
0910: 20 20 20 20 20 20 20 20 20 2f 2a 20 32 30 34 38           /* 2048
0920: 20 2a 2f 0a 20 20 20 20 20 20 49 4e 53 45 52 54   */.      INSERT
0930: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
0940: 61 5f 73 74 72 69 6e 67 28 38 30 30 29 20 46 52  a_string(800) FR
0950: 4f 4d 20 74 31 20 4c 49 4d 49 54 20 31 39 37 30  OM t1 LIMIT 1970
0960: 3b 20 20 2f 2a 20 34 30 31 38 20 2a 2f 0a 20 20  ;  /* 4018 */.  
0970: 20 20 43 4f 4d 4d 49 54 3b 0a 20 20 20 20 50 52    COMMIT;.    PR
0980: 41 47 4d 41 20 63 61 63 68 65 5f 73 69 7a 65 20  AGMA cache_size 
0990: 3d 20 31 30 3b 0a 20 20 7d 0a 20 20 73 65 74 20  = 10;.  }.  set 
09a0: 78 20 5b 77 61 6c 5f 66 72 61 6d 65 5f 63 6f 75  x [wal_frame_cou
09b0: 6e 74 20 74 65 73 74 2e 64 62 2d 77 61 6c 20 31  nt test.db-wal 1
09c0: 30 32 34 5d 0a 20 20 69 66 20 7b 5b 70 65 72 6d  024].  if {[perm
09d0: 75 74 61 74 69 6f 6e 5d 3d 3d 22 6d 65 6d 73 75  utation]=="memsu
09e0: 62 73 79 73 31 22 7d 20 7b 0a 20 20 20 20 69 66  bsys1"} {.    if
09f0: 20 7b 24 78 3d 3d 34 32 35 31 20 7c 7c 20 24 78   {$x==4251 || $x
0a00: 3d 3d 34 32 39 30 7d 20 7b 73 65 74 20 78 20 34  ==4290} {set x 4
0a10: 30 35 36 7d 0a 20 20 7d 0a 20 20 73 65 74 20 78  056}.  }.  set x
0a20: 0a 7d 20 34 30 35 36 0a 0a 66 6f 72 20 7b 73 65  .} 4056..for {se
0a30: 74 20 69 20 31 7d 20 7b 24 69 20 3c 20 35 30 7d  t i 1} {$i < 50}
0a40: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 0a 20 20 64   {incr i} {..  d
0a50: 6f 5f 74 65 73 74 20 77 61 6c 33 2d 31 2e 24 69  o_test wal3-1.$i
0a60: 2e 31 20 7b 0a 20 20 20 20 73 65 74 20 73 74 72  .1 {.    set str
0a70: 20 5b 61 5f 73 74 72 69 6e 67 20 38 30 30 5d 0a   [a_string 800].
0a80: 20 20 20 20 65 78 65 63 73 71 6c 20 7b 20 55 50      execsql { UP
0a90: 44 41 54 45 20 74 31 20 53 45 54 20 78 20 3d 20  DATE t1 SET x = 
0aa0: 24 73 74 72 20 57 48 45 52 45 20 72 6f 77 69 64  $str WHERE rowid
0ab0: 20 3d 20 24 69 20 7d 0a 20 20 20 20 6c 61 70 70   = $i }.    lapp
0ac0: 65 6e 64 20 4c 20 5b 77 61 6c 5f 66 72 61 6d 65  end L [wal_frame
0ad0: 5f 63 6f 75 6e 74 20 74 65 73 74 2e 64 62 2d 77  _count test.db-w
0ae0: 61 6c 20 31 30 32 34 5d 0a 20 20 20 20 65 78 65  al 1024].    exe
0af0: 63 73 71 6c 20 7b 0a 20 20 20 20 20 20 42 45 47  csql {.      BEG
0b00: 49 4e 3b 0a 20 20 20 20 20 20 20 20 49 4e 53 45  IN;.        INSE
0b10: 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43  RT INTO t1 SELEC
0b20: 54 20 61 5f 73 74 72 69 6e 67 28 38 30 30 29 20  T a_string(800) 
0b30: 46 52 4f 4d 20 74 31 20 4c 49 4d 49 54 20 31 30  FROM t1 LIMIT 10
0b40: 30 3b 0a 20 20 20 20 20 20 52 4f 4c 4c 42 41 43  0;.      ROLLBAC
0b50: 4b 3b 0a 20 20 20 20 20 20 50 52 41 47 4d 41 20  K;.      PRAGMA 
0b60: 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 3b  integrity_check;
0b70: 0a 20 20 20 20 7d 0a 20 20 7d 20 7b 6f 6b 7d 0a  .    }.  } {ok}.
0b80: 0a 20 20 23 20 43 68 65 63 6b 20 74 68 61 74 20  .  # Check that 
0b90: 65 76 65 72 79 74 68 69 6e 67 20 6c 6f 6f 6b 73  everything looks
0ba0: 20 4f 4b 20 66 72 6f 6d 20 74 68 65 20 70 6f 69   OK from the poi
0bb0: 6e 74 20 6f 66 20 76 69 65 77 20 6f 66 20 61 6e  nt of view of an
0bc0: 20 0a 20 20 23 20 65 78 74 65 72 6e 61 6c 20 63   .  # external c
0bd0: 6f 6e 6e 65 63 74 69 6f 6e 2e 0a 20 20 23 0a 20  onnection..  #. 
0be0: 20 73 71 6c 69 74 65 33 20 64 62 32 20 74 65 73   sqlite3 db2 tes
0bf0: 74 2e 64 62 0a 20 20 64 6f 5f 74 65 73 74 20 77  t.db.  do_test w
0c00: 61 6c 33 2d 31 2e 24 69 2e 32 20 7b 0a 20 20 20  al3-1.$i.2 {.   
0c10: 20 65 78 65 63 73 71 6c 20 7b 20 53 45 4c 45 43   execsql { SELEC
0c20: 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20  T count(*) FROM 
0c30: 74 31 20 7d 20 64 62 32 0a 20 20 7d 20 34 30 31  t1 } db2.  } 401
0c40: 38 0a 20 20 64 6f 5f 74 65 73 74 20 77 61 6c 33  8.  do_test wal3
0c50: 2d 31 2e 24 69 2e 33 20 7b 0a 20 20 20 20 65 78  -1.$i.3 {.    ex
0c60: 65 63 73 71 6c 20 7b 20 53 45 4c 45 43 54 20 78  ecsql { SELECT x
0c70: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 72   FROM t1 WHERE r
0c80: 6f 77 69 64 20 3d 20 24 69 20 7d 0a 20 20 7d 20  owid = $i }.  } 
0c90: 24 73 74 72 0a 20 20 64 6f 5f 74 65 73 74 20 77  $str.  do_test w
0ca0: 61 6c 33 2d 31 2e 24 69 2e 34 20 7b 0a 20 20 20  al3-1.$i.4 {.   
0cb0: 20 65 78 65 63 73 71 6c 20 7b 20 50 52 41 47 4d   execsql { PRAGM
0cc0: 41 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63  A integrity_chec
0cd0: 6b 20 7d 20 64 62 32 0a 20 20 7d 20 7b 6f 6b 7d  k } db2.  } {ok}
0ce0: 0a 20 20 64 62 32 20 63 6c 6f 73 65 0a 20 20 0a  .  db2 close.  .
0cf0: 20 20 23 20 43 68 65 63 6b 20 74 68 61 74 20 74    # Check that t
0d00: 68 65 20 66 69 6c 65 2d 73 79 73 74 65 6d 20 69  he file-system i
0d10: 6e 20 69 74 73 20 63 75 72 72 65 6e 74 20 73 74  n its current st
0d20: 61 74 65 20 63 61 6e 20 62 65 20 72 65 63 6f 76  ate can be recov
0d30: 65 72 65 64 2e 0a 20 20 23 20 0a 20 20 66 6f 72  ered..  # .  for
0d40: 63 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 74  cecopy test.db t
0d50: 65 73 74 32 2e 64 62 0a 20 20 66 6f 72 63 65 63  est2.db.  forcec
0d60: 6f 70 79 20 74 65 73 74 2e 64 62 2d 77 61 6c 20  opy test.db-wal 
0d70: 74 65 73 74 32 2e 64 62 2d 77 61 6c 0a 20 20 66  test2.db-wal.  f
0d80: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 32  orcedelete test2
0d90: 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 73 71  .db-journal.  sq
0da0: 6c 69 74 65 33 20 64 62 32 20 74 65 73 74 32 2e  lite3 db2 test2.
0db0: 64 62 0a 20 20 64 6f 5f 74 65 73 74 20 77 61 6c  db.  do_test wal
0dc0: 33 2d 31 2e 24 69 2e 35 20 7b 0a 20 20 20 20 65  3-1.$i.5 {.    e
0dd0: 78 65 63 73 71 6c 20 7b 20 53 45 4c 45 43 54 20  xecsql { SELECT 
0de0: 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 74 31  count(*) FROM t1
0df0: 20 7d 20 64 62 32 0a 20 20 7d 20 34 30 31 38 0a   } db2.  } 4018.
0e00: 20 20 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 31    do_test wal3-1
0e10: 2e 24 69 2e 36 20 7b 0a 20 20 20 20 65 78 65 63  .$i.6 {.    exec
0e20: 73 71 6c 20 7b 20 53 45 4c 45 43 54 20 78 20 46  sql { SELECT x F
0e30: 52 4f 4d 20 74 31 20 57 48 45 52 45 20 72 6f 77  ROM t1 WHERE row
0e40: 69 64 20 3d 20 24 69 20 7d 0a 20 20 7d 20 24 73  id = $i }.  } $s
0e50: 74 72 0a 20 20 64 6f 5f 74 65 73 74 20 77 61 6c  tr.  do_test wal
0e60: 33 2d 31 2e 24 69 2e 37 20 7b 0a 20 20 20 20 65  3-1.$i.7 {.    e
0e70: 78 65 63 73 71 6c 20 7b 20 50 52 41 47 4d 41 20  xecsql { PRAGMA 
0e80: 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20  integrity_check 
0e90: 7d 20 64 62 32 0a 20 20 7d 20 7b 6f 6b 7d 0a 20  } db2.  } {ok}. 
0ea0: 20 64 62 32 20 63 6c 6f 73 65 0a 7d 0a 0a 70 72   db2 close.}..pr
0eb0: 6f 63 20 62 79 74 65 5f 69 73 5f 7a 65 72 6f 20  oc byte_is_zero 
0ec0: 7b 66 69 6c 65 20 6f 66 66 73 65 74 7d 20 7b 0a  {file offset} {.
0ed0: 20 20 69 66 20 7b 5b 66 69 6c 65 20 73 69 7a 65    if {[file size
0ee0: 20 74 65 73 74 2e 64 62 5d 20 3c 3d 20 24 6f 66   test.db] <= $of
0ef0: 66 73 65 74 7d 20 7b 20 72 65 74 75 72 6e 20 31  fset} { return 1
0f00: 20 7d 0a 20 20 65 78 70 72 20 7b 20 5b 68 65 78   }.  expr { [hex
0f10: 69 6f 5f 72 65 61 64 20 24 66 69 6c 65 20 24 6f  io_read $file $o
0f20: 66 66 73 65 74 20 31 5d 20 3d 3d 20 22 30 30 22  ffset 1] == "00"
0f30: 20 7d 0a 7d 0a 0a 64 6f 5f 6d 75 6c 74 69 63 6c   }.}..do_multicl
0f40: 69 65 6e 74 5f 74 65 73 74 20 69 20 7b 0a 0a 20  ient_test i {.. 
0f50: 20 73 65 74 20 74 65 73 74 6e 61 6d 65 28 31 29   set testname(1)
0f60: 20 6d 75 6c 74 69 70 72 6f 63 0a 20 20 73 65 74   multiproc.  set
0f70: 20 74 65 73 74 6e 61 6d 65 28 32 29 20 73 69 6e   testname(2) sin
0f80: 67 6c 65 70 72 6f 63 0a 20 20 73 65 74 20 74 6e  gleproc.  set tn
0f90: 20 24 74 65 73 74 6e 61 6d 65 28 24 69 29 0a 0a   $testname($i)..
0fa0: 20 20 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 32    do_test wal3-2
0fb0: 2e 24 74 6e 2e 31 20 7b 0a 20 20 20 20 73 71 6c  .$tn.1 {.    sql
0fc0: 31 20 7b 20 0a 20 20 20 20 20 20 50 52 41 47 4d  1 { .      PRAGM
0fd0: 41 20 70 61 67 65 5f 73 69 7a 65 20 3d 20 31 30  A page_size = 10
0fe0: 32 34 3b 0a 20 20 20 20 20 20 50 52 41 47 4d 41  24;.      PRAGMA
0ff0: 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20   journal_mode = 
1000: 57 41 4c 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  WAL;.    }.    s
1010: 71 6c 31 20 7b 0a 20 20 20 20 20 20 43 52 45 41  ql1 {.      CREA
1020: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 20 62  TE TABLE t1(a, b
1030: 29 3b 0a 20 20 20 20 20 20 49 4e 53 45 52 54 20  );.      INSERT 
1040: 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 31  INTO t1 VALUES(1
1050: 2c 20 27 6f 6e 65 27 29 3b 0a 20 20 20 20 20 20  , 'one');.      
1060: 42 45 47 49 4e 3b 0a 20 20 20 20 20 20 20 20 53  BEGIN;.        S
1070: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 31 3b  ELECT * FROM t1;
1080: 0a 20 20 20 20 7d 0a 20 20 7d 20 7b 31 20 6f 6e  .    }.  } {1 on
1090: 65 7d 0a 20 20 64 6f 5f 74 65 73 74 20 77 61 6c  e}.  do_test wal
10a0: 33 2d 32 2e 24 74 6e 2e 32 20 7b 0a 20 20 20 20  3-2.$tn.2 {.    
10b0: 73 71 6c 32 20 7b 0a 20 20 20 20 20 20 43 52 45  sql2 {.      CRE
10c0: 41 54 45 20 54 41 42 4c 45 20 74 32 28 61 2c 20  ATE TABLE t2(a, 
10d0: 62 29 3b 0a 20 20 20 20 20 20 49 4e 53 45 52 54  b);.      INSERT
10e0: 20 49 4e 54 4f 20 74 32 20 56 41 4c 55 45 53 28   INTO t2 VALUES(
10f0: 32 2c 20 27 74 77 6f 27 29 3b 0a 20 20 20 20 20  2, 'two');.     
1100: 20 42 45 47 49 4e 3b 0a 20 20 20 20 20 20 20 20   BEGIN;.        
1110: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 32  SELECT * FROM t2
1120: 3b 0a 20 20 20 20 7d 0a 20 20 7d 20 7b 32 20 74  ;.    }.  } {2 t
1130: 77 6f 7d 0a 20 20 64 6f 5f 74 65 73 74 20 77 61  wo}.  do_test wa
1140: 6c 33 2d 32 2e 24 74 6e 2e 33 20 7b 0a 20 20 20  l3-2.$tn.3 {.   
1150: 20 73 71 6c 33 20 7b 0a 20 20 20 20 20 20 43 52   sql3 {.      CR
1160: 45 41 54 45 20 54 41 42 4c 45 20 74 33 28 61 2c  EATE TABLE t3(a,
1170: 20 62 29 3b 0a 20 20 20 20 20 20 49 4e 53 45 52   b);.      INSER
1180: 54 20 49 4e 54 4f 20 74 33 20 56 41 4c 55 45 53  T INTO t3 VALUES
1190: 28 33 2c 20 27 74 68 72 65 65 27 29 3b 0a 20 20  (3, 'three');.  
11a0: 20 20 20 20 42 45 47 49 4e 3b 0a 20 20 20 20 20      BEGIN;.     
11b0: 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d     SELECT * FROM
11c0: 20 74 33 3b 0a 20 20 20 20 7d 0a 20 20 7d 20 7b   t3;.    }.  } {
11d0: 33 20 74 68 72 65 65 7d 0a 0a 20 20 23 20 54 72  3 three}..  # Tr
11e0: 79 20 74 6f 20 63 68 65 63 6b 70 6f 69 6e 74 20  y to checkpoint 
11f0: 74 68 65 20 64 61 74 61 62 61 73 65 20 75 73 69  the database usi
1200: 6e 67 20 5b 64 62 5d 2e 20 49 74 20 73 68 6f 75  ng [db]. It shou
1210: 6c 64 20 62 65 20 70 6f 73 73 69 62 6c 65 20 74  ld be possible t
1220: 6f 0a 20 20 23 20 63 68 65 63 6b 70 6f 69 6e 74  o.  # checkpoint
1230: 20 65 76 65 72 79 74 68 69 6e 67 20 65 78 63 65   everything exce
1240: 70 74 20 74 68 65 20 74 61 62 6c 65 20 61 64 64  pt the table add
1250: 65 64 20 62 79 20 5b 64 62 33 5d 20 28 63 68 65  ed by [db3] (che
1260: 63 6b 70 6f 69 6e 74 69 6e 67 0a 20 20 23 20 74  ckpointing.  # t
1270: 68 65 73 65 20 66 72 61 6d 65 73 20 77 6f 75 6c  hese frames woul
1280: 64 20 63 6c 6f 62 62 65 72 20 74 68 65 20 73 6e  d clobber the sn
1290: 61 70 73 68 6f 74 20 63 75 72 72 65 6e 74 6c 79  apshot currently
12a0: 20 62 65 69 6e 67 20 75 73 65 64 20 62 79 20 5b   being used by [
12b0: 64 62 32 5d 29 2e 0a 20 20 23 0a 20 20 23 20 41  db2])..  #.  # A
12c0: 66 74 65 72 20 5b 64 62 32 5d 20 68 61 73 20 63  fter [db2] has c
12d0: 6f 6d 6d 69 74 74 65 64 2c 20 61 20 63 68 65 63  ommitted, a chec
12e0: 6b 70 6f 69 6e 74 20 63 61 6e 20 63 6f 70 79 20  kpoint can copy 
12f0: 74 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20 74  the entire log t
1300: 6f 20 74 68 65 0a 20 20 23 20 64 61 74 61 62 61  o the.  # databa
1310: 73 65 20 66 69 6c 65 2e 20 43 68 65 63 6b 70 6f  se file. Checkpo
1320: 69 6e 74 69 6e 67 20 61 66 74 65 72 20 5b 64 62  inting after [db
1330: 33 5d 20 68 61 73 20 63 6f 6d 6d 69 74 74 65 64  3] has committed
1340: 20 69 73 20 74 68 65 72 65 66 6f 72 65 20 61 0a   is therefore a.
1350: 20 20 23 20 6e 6f 2d 6f 70 2c 20 61 73 20 74 68    # no-op, as th
1360: 65 20 65 6e 74 69 72 65 20 6c 6f 67 20 68 61 73  e entire log has
1370: 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 62 61   already been ba
1380: 63 6b 66 69 6c 6c 65 64 2e 0a 20 20 23 0a 20 20  ckfilled..  #.  
1390: 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 32 2e 24  do_test wal3-2.$
13a0: 74 6e 2e 34 20 7b 0a 20 20 20 20 73 71 6c 31 20  tn.4 {.    sql1 
13b0: 7b 0a 20 20 20 20 20 20 43 4f 4d 4d 49 54 3b 0a  {.      COMMIT;.
13c0: 20 20 20 20 20 20 50 52 41 47 4d 41 20 77 61 6c        PRAGMA wal
13d0: 5f 63 68 65 63 6b 70 6f 69 6e 74 3b 0a 20 20 20  _checkpoint;.   
13e0: 20 7d 0a 20 20 20 20 62 79 74 65 5f 69 73 5f 7a   }.    byte_is_z
13f0: 65 72 6f 20 74 65 73 74 2e 64 62 20 5b 65 78 70  ero test.db [exp
1400: 72 20 24 41 55 54 4f 56 41 43 55 55 4d 20 3f 20  r $AUTOVACUUM ? 
1410: 34 2a 31 30 32 34 20 3a 20 33 2a 31 30 32 34 5d  4*1024 : 3*1024]
1420: 0a 20 20 7d 20 7b 31 7d 0a 20 20 64 6f 5f 74 65  .  } {1}.  do_te
1430: 73 74 20 77 61 6c 33 2d 32 2e 24 74 6e 2e 35 20  st wal3-2.$tn.5 
1440: 7b 0a 20 20 20 20 73 71 6c 32 20 7b 0a 20 20 20  {.    sql2 {.   
1450: 20 20 20 43 4f 4d 4d 49 54 3b 0a 20 20 20 20 20     COMMIT;.     
1460: 20 50 52 41 47 4d 41 20 77 61 6c 5f 63 68 65 63   PRAGMA wal_chec
1470: 6b 70 6f 69 6e 74 3b 0a 20 20 20 20 7d 0a 20 20  kpoint;.    }.  
1480: 20 20 6c 69 73 74 20 5b 62 79 74 65 5f 69 73 5f    list [byte_is_
1490: 7a 65 72 6f 20 74 65 73 74 2e 64 62 20 5b 65 78  zero test.db [ex
14a0: 70 72 20 24 41 55 54 4f 56 41 43 55 55 4d 20 3f  pr $AUTOVACUUM ?
14b0: 20 34 2a 31 30 32 34 20 3a 20 33 2a 31 30 32 34   4*1024 : 3*1024
14c0: 5d 5d 20 20 20 5c 0a 20 20 20 20 20 20 20 20 20  ]]   \.         
14d0: 5b 62 79 74 65 5f 69 73 5f 7a 65 72 6f 20 74 65  [byte_is_zero te
14e0: 73 74 2e 64 62 20 5b 65 78 70 72 20 24 41 55 54  st.db [expr $AUT
14f0: 4f 56 41 43 55 55 4d 20 3f 20 35 2a 31 30 32 34  OVACUUM ? 5*1024
1500: 20 3a 20 34 2a 31 30 32 34 5d 5d 0a 20 20 7d 20   : 4*1024]].  } 
1510: 7b 30 20 31 7d 0a 20 20 64 6f 5f 74 65 73 74 20  {0 1}.  do_test 
1520: 77 61 6c 33 2d 32 2e 24 74 6e 2e 36 20 7b 0a 20  wal3-2.$tn.6 {. 
1530: 20 20 20 73 71 6c 33 20 7b 0a 20 20 20 20 20 20     sql3 {.      
1540: 43 4f 4d 4d 49 54 3b 0a 20 20 20 20 20 20 50 52  COMMIT;.      PR
1550: 41 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70 6f  AGMA wal_checkpo
1560: 69 6e 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6c  int;.    }.    l
1570: 69 73 74 20 5b 62 79 74 65 5f 69 73 5f 7a 65 72  ist [byte_is_zer
1580: 6f 20 74 65 73 74 2e 64 62 20 5b 65 78 70 72 20  o test.db [expr 
1590: 24 41 55 54 4f 56 41 43 55 55 4d 20 3f 20 34 2a  $AUTOVACUUM ? 4*
15a0: 31 30 32 34 20 3a 20 33 2a 31 30 32 34 5d 5d 20  1024 : 3*1024]] 
15b0: 20 20 5c 0a 20 20 20 20 20 20 20 20 20 5b 62 79    \.         [by
15c0: 74 65 5f 69 73 5f 7a 65 72 6f 20 74 65 73 74 2e  te_is_zero test.
15d0: 64 62 20 5b 65 78 70 72 20 24 41 55 54 4f 56 41  db [expr $AUTOVA
15e0: 43 55 55 4d 20 3f 20 35 2a 31 30 32 34 20 3a 20  CUUM ? 5*1024 : 
15f0: 34 2a 31 30 32 34 5d 5d 0a 20 20 7d 20 7b 30 20  4*1024]].  } {0 
1600: 31 7d 0a 7d 0a 63 61 74 63 68 20 7b 64 62 20 63  1}.}.catch {db c
1610: 6c 6f 73 65 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  lose}..#--------
1620: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1630: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1640: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1650: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1660: 2d 0a 23 20 54 65 73 74 20 74 68 61 74 20 74 68  -.# Test that th
1670: 61 74 20 66 6f 72 20 74 68 65 20 73 69 6d 70 6c  at for the simpl
1680: 65 20 74 65 73 74 3a 0a 23 0a 23 20 20 20 43 52  e test:.#.#   CR
1690: 45 41 54 45 20 54 41 42 4c 45 20 78 28 79 29 3b  EATE TABLE x(y);
16a0: 0a 23 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  .#   INSERT INTO
16b0: 20 78 20 56 41 4c 55 45 53 28 27 7a 27 29 3b 0a   x VALUES('z');.
16c0: 23 20 20 20 50 52 41 47 4d 41 20 77 61 6c 5f 63  #   PRAGMA wal_c
16d0: 68 65 63 6b 70 6f 69 6e 74 3b 0a 23 0a 23 20 69  heckpoint;.#.# i
16e0: 6e 20 57 41 4c 20 6d 6f 64 65 20 74 68 65 20 78  n WAL mode the x
16f0: 53 79 6e 63 20 6d 65 74 68 6f 64 20 69 73 20 69  Sync method is i
1700: 6e 76 6f 6b 65 64 20 61 73 20 65 78 70 65 63 74  nvoked as expect
1710: 65 64 20 66 6f 72 20 65 61 63 68 20 6f 66 0a 23  ed for each of.#
1720: 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 6f 66 66   synchronous=off
1730: 2c 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 6e 6f  , synchronous=no
1740: 72 6d 61 6c 20 61 6e 64 20 73 79 6e 63 68 72 6f  rmal and synchro
1750: 6e 6f 75 73 3d 66 75 6c 6c 2e 0a 23 0a 66 6f 72  nous=full..#.for
1760: 65 61 63 68 20 7b 74 6e 20 73 79 6e 63 6d 6f 64  each {tn syncmod
1770: 65 20 73 79 6e 63 63 6f 75 6e 74 7d 20 7b 0a 20  e synccount} {. 
1780: 20 31 20 6f 66 66 20 20 20 20 20 0a 20 20 20 20   1 off     .    
1790: 7b 7d 0a 20 20 32 20 6e 6f 72 6d 61 6c 20 20 0a  {}.  2 normal  .
17a0: 20 20 20 20 7b 74 65 73 74 2e 64 62 2d 77 61 6c      {test.db-wal
17b0: 20 6e 6f 72 6d 61 6c 20 74 65 73 74 2e 64 62 20   normal test.db 
17c0: 6e 6f 72 6d 61 6c 7d 0a 20 20 33 20 66 75 6c 6c  normal}.  3 full
17d0: 20 20 20 20 0a 20 20 20 20 7b 74 65 73 74 2e 64      .    {test.d
17e0: 62 2d 77 61 6c 20 6e 6f 72 6d 61 6c 20 74 65 73  b-wal normal tes
17f0: 74 2e 64 62 2d 77 61 6c 20 6e 6f 72 6d 61 6c 20  t.db-wal normal 
1800: 74 65 73 74 2e 64 62 2d 77 61 6c 20 6e 6f 72 6d  test.db-wal norm
1810: 61 6c 20 74 65 73 74 2e 64 62 20 6e 6f 72 6d 61  al test.db norma
1820: 6c 7d 0a 7d 20 7b 0a 0a 20 20 70 72 6f 63 20 73  l}.} {..  proc s
1830: 79 6e 63 5f 63 6f 75 6e 74 65 72 20 7b 61 72 67  ync_counter {arg
1840: 73 7d 20 7b 20 0a 20 20 20 20 66 6f 72 65 61 63  s} { .    foreac
1850: 68 20 7b 6d 65 74 68 6f 64 20 66 69 6c 65 6e 61  h {method filena
1860: 6d 65 20 69 64 20 66 6c 61 67 73 7d 20 24 61 72  me id flags} $ar
1870: 67 73 20 62 72 65 61 6b 0a 20 20 20 20 6c 61 70  gs break.    lap
1880: 70 65 6e 64 20 3a 3a 73 79 6e 63 73 20 5b 66 69  pend ::syncs [fi
1890: 6c 65 20 74 61 69 6c 20 24 66 69 6c 65 6e 61 6d  le tail $filenam
18a0: 65 5d 20 24 66 6c 61 67 73 0a 20 20 7d 0a 20 20  e] $flags.  }.  
18b0: 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 33 2e 24  do_test wal3-3.$
18c0: 74 6e 20 7b 0a 20 20 20 20 66 6f 72 63 65 64 65  tn {.    forcede
18d0: 6c 65 74 65 20 74 65 73 74 2e 64 62 20 74 65 73  lete test.db tes
18e0: 74 2e 64 62 2d 77 61 6c 20 74 65 73 74 2e 64 62  t.db-wal test.db
18f0: 2d 6a 6f 75 72 6e 61 6c 0a 20 20 0a 20 20 20 20  -journal.  .    
1900: 74 65 73 74 76 66 73 20 54 0a 20 20 20 20 54 20  testvfs T.    T 
1910: 66 69 6c 74 65 72 20 7b 7d 20 0a 20 20 20 20 54  filter {} .    T
1920: 20 73 63 72 69 70 74 20 73 79 6e 63 5f 63 6f 75   script sync_cou
1930: 6e 74 65 72 0a 20 20 20 20 73 71 6c 69 74 65 33  nter.    sqlite3
1940: 20 64 62 20 74 65 73 74 2e 64 62 20 2d 76 66 73   db test.db -vfs
1950: 20 54 0a 20 20 0a 20 20 20 20 65 78 65 63 73 71   T.  .    execsq
1960: 6c 20 22 50 52 41 47 4d 41 20 73 79 6e 63 68 72  l "PRAGMA synchr
1970: 6f 6e 6f 75 73 20 3d 20 24 73 79 6e 63 6d 6f 64  onous = $syncmod
1980: 65 22 0a 20 20 20 20 65 78 65 63 73 71 6c 20 22  e".    execsql "
1990: 50 52 41 47 4d 41 20 63 68 65 63 6b 70 6f 69 6e  PRAGMA checkpoin
19a0: 74 5f 66 75 6c 6c 66 73 79 6e 63 20 3d 20 30 22  t_fullfsync = 0"
19b0: 0a 20 20 20 20 65 78 65 63 73 71 6c 20 7b 20 50  .    execsql { P
19c0: 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f  RAGMA journal_mo
19d0: 64 65 20 3d 20 57 41 4c 20 7d 0a 20 20 20 20 65  de = WAL }.    e
19e0: 78 65 63 73 71 6c 20 7b 20 43 52 45 41 54 45 20  xecsql { CREATE 
19f0: 54 41 42 4c 45 20 66 69 6c 6c 65 72 28 61 2c 62  TABLE filler(a,b
1a00: 2c 63 29 3b 20 7d 0a 0a 20 20 20 20 73 65 74 20  ,c); }..    set 
1a10: 3a 3a 73 79 6e 63 73 20 5b 6c 69 73 74 5d 0a 20  ::syncs [list]. 
1a20: 20 20 20 54 20 66 69 6c 74 65 72 20 78 53 79 6e     T filter xSyn
1a30: 63 0a 20 20 20 20 65 78 65 63 73 71 6c 20 7b 0a  c.    execsql {.
1a40: 20 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42        CREATE TAB
1a50: 4c 45 20 78 28 79 29 3b 0a 20 20 20 20 20 20 49  LE x(y);.      I
1a60: 4e 53 45 52 54 20 49 4e 54 4f 20 78 20 56 41 4c  NSERT INTO x VAL
1a70: 55 45 53 28 27 7a 27 29 3b 0a 20 20 20 20 20 20  UES('z');.      
1a80: 50 52 41 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b  PRAGMA wal_check
1a90: 70 6f 69 6e 74 3b 0a 20 20 20 20 7d 0a 20 20 20  point;.    }.   
1aa0: 20 54 20 66 69 6c 74 65 72 20 7b 7d 0a 20 20 20   T filter {}.   
1ab0: 20 73 65 74 20 3a 3a 73 79 6e 63 73 0a 20 20 7d   set ::syncs.  }
1ac0: 20 24 73 79 6e 63 63 6f 75 6e 74 0a 0a 20 20 64   $synccount..  d
1ad0: 62 20 63 6c 6f 73 65 0a 20 20 54 20 64 65 6c 65  b close.  T dele
1ae0: 74 65 0a 7d 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  te.}...#--------
1af0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b30: 2d 0a 23 20 4f 6e 6c 79 20 6f 6e 65 20 63 6c 69  -.# Only one cli
1b40: 65 6e 74 20 6d 61 79 20 72 75 6e 20 72 65 63 6f  ent may run reco
1b50: 76 65 72 79 20 61 74 20 61 20 74 69 6d 65 2e 20  very at a time. 
1b60: 54 65 73 74 20 74 68 69 73 20 6d 65 63 68 61 6e  Test this mechan
1b70: 69 73 6d 2e 0a 23 0a 23 20 57 68 65 6e 20 63 6c  ism..#.# When cl
1b80: 69 65 6e 74 2d 32 20 74 72 69 65 73 20 74 6f 20  ient-2 tries to 
1b90: 6f 70 65 6e 20 61 20 72 65 61 64 20 74 72 61 6e  open a read tran
1ba0: 73 61 63 74 69 6f 6e 20 77 68 69 6c 65 20 63 6c  saction while cl
1bb0: 69 65 6e 74 2d 31 20 69 73 20 0a 23 20 72 75 6e  ient-1 is .# run
1bc0: 6e 69 6e 67 20 72 65 63 6f 76 65 72 79 2c 20 69  ning recovery, i
1bd0: 74 20 66 61 69 6c 73 20 74 6f 20 6f 62 74 61 69  t fails to obtai
1be0: 6e 20 61 20 6c 6f 63 6b 20 6f 6e 20 61 6e 20 61  n a lock on an a
1bf0: 52 65 61 64 4d 61 72 6b 5b 5d 20 73 6c 6f 74 0a  ReadMark[] slot.
1c00: 23 20 28 62 65 63 61 75 73 65 20 74 68 65 79 20  # (because they 
1c10: 61 72 65 20 61 6c 6c 20 6c 6f 63 6b 65 64 20 62  are all locked b
1c20: 79 20 72 65 63 6f 76 65 72 79 29 2e 20 49 74 20  y recovery). It 
1c30: 74 68 65 6e 20 74 72 69 65 73 20 74 6f 20 6f 62  then tries to ob
1c40: 74 61 69 6e 0a 23 20 61 20 73 68 61 72 65 64 20  tain.# a shared 
1c50: 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 52 45 43 4f  lock on the RECO
1c60: 56 45 52 20 6c 6f 63 6b 20 74 6f 20 73 65 65 20  VER lock to see 
1c70: 69 66 20 74 68 65 72 65 20 72 65 61 6c 6c 79 20  if there really 
1c80: 69 73 20 61 0a 23 20 72 65 63 6f 76 65 72 79 20  is a.# recovery 
1c90: 72 75 6e 6e 69 6e 67 20 6f 72 20 6e 6f 74 2e 0a  running or not..
1ca0: 23 0a 23 20 54 68 69 73 20 62 6c 6f 63 6b 20 6f  #.# This block o
1cb0: 66 20 74 65 73 74 73 20 63 68 65 63 6b 73 20 74  f tests checks t
1cc0: 68 65 20 65 66 66 65 63 74 20 6f 66 20 61 6e 20  he effect of an 
1cd0: 53 51 4c 49 54 45 5f 42 55 53 59 20 6f 72 20 53  SQLITE_BUSY or S
1ce0: 51 4c 49 54 45 5f 49 4f 45 52 52 0a 23 20 62 65  QLITE_IOERR.# be
1cf0: 69 6e 67 20 72 65 74 75 72 6e 65 64 20 77 68 65  ing returned whe
1d00: 6e 20 63 6c 69 65 6e 74 2d 32 20 61 74 74 65 6d  n client-2 attem
1d10: 70 74 73 20 61 20 73 68 61 72 65 64 20 6c 6f 63  pts a shared loc
1d20: 6b 20 6f 6e 20 74 68 65 20 52 45 43 4f 56 45 52  k on the RECOVER
1d30: 20 62 79 74 65 2e 0a 23 0a 23 20 41 6e 20 53 51   byte..#.# An SQ
1d40: 4c 49 54 45 5f 42 55 53 59 20 73 68 6f 75 6c 64  LITE_BUSY should
1d50: 20 62 65 20 63 6f 6e 76 65 72 74 65 64 20 74 6f   be converted to
1d60: 20 61 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 5f   an SQLITE_BUSY_
1d70: 52 45 43 4f 56 45 52 59 2e 20 41 6e 0a 23 20 53  RECOVERY. An.# S
1d80: 51 4c 49 54 45 5f 49 4f 45 52 52 20 73 68 6f 75  QLITE_IOERR shou
1d90: 6c 64 20 62 65 20 72 65 74 75 72 6e 65 64 20 74  ld be returned t
1da0: 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 23 0a  o the caller..#.
1db0: 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 35 2e 31  do_test wal3-5.1
1dc0: 20 7b 0a 20 20 66 61 75 6c 74 73 69 6d 5f 64 65   {.  faultsim_de
1dd0: 6c 65 74 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 0a  lete_and_reopen.
1de0: 20 20 65 78 65 63 73 71 6c 20 7b 0a 20 20 20 20    execsql {.    
1df0: 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d  PRAGMA journal_m
1e00: 6f 64 65 20 3d 20 57 41 4c 3b 0a 20 20 20 20 43  ode = WAL;.    C
1e10: 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61  REATE TABLE t1(a
1e20: 2c 20 62 29 3b 0a 20 20 20 20 49 4e 53 45 52 54  , b);.    INSERT
1e30: 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28   INTO t1 VALUES(
1e40: 31 2c 20 32 29 3b 0a 20 20 20 20 49 4e 53 45 52  1, 2);.    INSER
1e50: 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53  T INTO t1 VALUES
1e60: 28 33 2c 20 34 29 3b 0a 20 20 7d 0a 20 20 66 61  (3, 4);.  }.  fa
1e70: 75 6c 74 73 69 6d 5f 73 61 76 65 5f 61 6e 64 5f  ultsim_save_and_
1e80: 63 6c 6f 73 65 0a 7d 20 7b 7d 0a 0a 74 65 73 74  close.} {}..test
1e90: 76 66 73 20 54 20 2d 64 65 66 61 75 6c 74 20 31  vfs T -default 1
1ea0: 0a 54 20 73 63 72 69 70 74 20 6d 65 74 68 6f 64  .T script method
1eb0: 5f 63 61 6c 6c 62 61 63 6b 0a 0a 70 72 6f 63 20  _callback..proc 
1ec0: 6d 65 74 68 6f 64 5f 63 61 6c 6c 62 61 63 6b 20  method_callback 
1ed0: 7b 6d 65 74 68 6f 64 20 61 72 67 73 7d 20 7b 0a  {method args} {.
1ee0: 20 20 69 66 20 7b 24 6d 65 74 68 6f 64 20 3d 3d    if {$method ==
1ef0: 20 22 78 53 68 6d 42 61 72 72 69 65 72 22 7d 20   "xShmBarrier"} 
1f00: 7b 0a 20 20 20 20 69 6e 63 72 20 3a 3a 62 61 72  {.    incr ::bar
1f10: 72 69 65 72 5f 63 6f 75 6e 74 0a 20 20 20 20 69  rier_count.    i
1f20: 66 20 7b 24 3a 3a 62 61 72 72 69 65 72 5f 63 6f  f {$::barrier_co
1f30: 75 6e 74 20 3d 3d 20 32 7d 20 7b 0a 20 20 20 20  unt == 2} {.    
1f40: 20 20 23 20 54 68 69 73 20 63 6f 64 65 20 69 73    # This code is
1f50: 20 65 78 65 63 75 74 65 64 20 77 69 74 68 69 6e   executed within
1f60: 20 74 68 65 20 78 53 68 6d 42 61 72 72 69 65 72   the xShmBarrier
1f70: 28 29 20 63 61 6c 6c 62 61 63 6b 20 69 6e 76 6f  () callback invo
1f80: 6b 65 64 0a 20 20 20 20 20 20 23 20 62 79 20 74  ked.      # by t
1f90: 68 65 20 63 6c 69 65 6e 74 20 72 75 6e 6e 69 6e  he client runnin
1fa0: 67 20 72 65 63 6f 76 65 72 79 20 61 73 20 70 61  g recovery as pa
1fb0: 72 74 20 6f 66 20 77 72 69 74 69 6e 67 20 74 68  rt of writing th
1fc0: 65 20 72 65 63 6f 76 65 72 65 64 0a 20 20 20 20  e recovered.    
1fd0: 20 20 23 20 77 61 6c 2d 69 6e 64 65 78 20 68 65    # wal-index he
1fe0: 61 64 65 72 2e 20 49 66 20 61 20 73 65 63 6f 6e  ader. If a secon
1ff0: 64 20 63 6c 69 65 6e 74 20 61 74 74 65 6d 70 74  d client attempt
2000: 73 20 74 6f 20 61 63 63 65 73 73 20 74 68 65 20  s to access the 
2010: 0a 20 20 20 20 20 20 23 20 64 61 74 61 62 61 73  .      # databas
2020: 65 20 6e 6f 77 2c 20 69 74 20 72 65 61 64 73 20  e now, it reads 
2030: 61 20 63 6f 72 72 75 70 74 20 28 70 61 72 74 69  a corrupt (parti
2040: 61 6c 6c 79 20 77 72 69 74 74 65 6e 29 20 77 61  ally written) wa
2050: 6c 2d 69 6e 64 65 78 0a 20 20 20 20 20 20 23 20  l-index.      # 
2060: 68 65 61 64 65 72 2e 20 42 75 74 20 69 74 20 63  header. But it c
2070: 61 6e 6e 6f 74 20 65 76 65 6e 20 67 65 74 20 74  annot even get t
2080: 68 61 74 20 66 61 72 2c 20 61 73 20 74 68 65 20  hat far, as the 
2090: 66 69 72 73 74 20 63 6c 69 65 6e 74 0a 20 20 20  first client.   
20a0: 20 20 20 23 20 69 73 20 73 74 69 6c 6c 20 68 6f     # is still ho
20b0: 6c 64 69 6e 67 20 61 6c 6c 20 74 68 65 20 6c 6f  lding all the lo
20c0: 63 6b 73 20 28 72 65 63 6f 76 65 72 79 20 74 61  cks (recovery ta
20d0: 6b 65 73 20 61 6e 20 65 78 63 6c 75 73 69 76 65  kes an exclusive
20e0: 20 6c 6f 63 6b 0a 20 20 20 20 20 20 23 20 6f 6e   lock.      # on
20f0: 20 2a 61 6c 6c 2a 20 64 62 20 6c 6f 63 6b 73 2c   *all* db locks,
2100: 20 70 72 65 76 65 6e 74 69 6e 67 20 61 63 63 65   preventing acce
2110: 73 73 20 62 79 20 61 6e 79 20 6f 74 68 65 72 20  ss by any other 
2120: 63 6c 69 65 6e 74 29 2e 0a 20 20 20 20 20 20 23  client)..      #
2130: 0a 20 20 20 20 20 20 23 20 49 66 20 67 6c 6f 62  .      # If glob
2140: 61 6c 20 76 61 72 69 61 62 6c 65 20 3a 3a 77 61  al variable ::wa
2150: 6c 33 5f 64 6f 5f 6c 6f 63 6b 66 61 69 6c 75 72  l3_do_lockfailur
2160: 65 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74  e is non-zero, t
2170: 68 65 6e 20 73 65 74 0a 20 20 20 20 20 20 23 20  hen set.      # 
2180: 74 68 69 6e 67 73 20 75 70 20 73 6f 20 74 68 61  things up so tha
2190: 74 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63  t an IO error oc
21a0: 63 75 72 73 20 77 69 74 68 69 6e 20 61 6e 20 78  curs within an x
21b0: 53 68 6d 4c 6f 63 6b 28 29 20 63 61 6c 6c 62 61  ShmLock() callba
21c0: 63 6b 0a 20 20 20 20 20 20 23 20 6d 61 64 65 20  ck.      # made 
21d0: 62 79 20 74 68 65 20 73 65 63 6f 6e 64 20 63 6c  by the second cl
21e0: 69 65 6e 74 20 28 61 6b 61 20 5b 64 62 32 5d 29  ient (aka [db2])
21f0: 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20  ..      #.      
2200: 73 71 6c 69 74 65 33 20 64 62 32 20 74 65 73 74  sqlite3 db2 test
2210: 2e 64 62 0a 20 20 20 20 20 20 69 66 20 7b 20 24  .db.      if { $
2220: 3a 3a 77 61 6c 33 5f 64 6f 5f 6c 6f 63 6b 66 61  ::wal3_do_lockfa
2230: 69 6c 75 72 65 20 7d 20 7b 20 54 20 66 69 6c 74  ilure } { T filt
2240: 65 72 20 78 53 68 6d 4c 6f 63 6b 20 7d 0a 20 20  er xShmLock }.  
2250: 20 20 20 20 73 65 74 20 3a 3a 74 65 73 74 72 63      set ::testrc
2260: 20 5b 20 63 61 74 63 68 20 7b 20 64 62 32 20 65   [ catch { db2 e
2270: 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  val "SELECT * FR
2280: 4f 4d 20 74 31 22 20 7d 20 3a 3a 74 65 73 74 6d  OM t1" } ::testm
2290: 73 67 20 5d 0a 20 20 20 20 20 20 54 20 66 69 6c  sg ].      T fil
22a0: 74 65 72 20 7b 7d 0a 20 20 20 20 20 20 64 62 32  ter {}.      db2
22b0: 20 63 6c 6f 73 65 0a 20 20 20 20 7d 0a 20 20 7d   close.    }.  }
22c0: 0a 0a 20 20 69 66 20 7b 24 6d 65 74 68 6f 64 20  ..  if {$method 
22d0: 3d 3d 20 22 78 53 68 6d 4c 6f 63 6b 22 7d 20 7b  == "xShmLock"} {
22e0: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 66 69  .    foreach {fi
22f0: 6c 65 20 68 61 6e 64 6c 65 20 73 70 65 63 7d 20  le handle spec} 
2300: 24 61 72 67 73 20 62 72 65 61 6b 0a 20 20 20 20  $args break.    
2310: 69 66 20 7b 20 24 73 70 65 63 20 3d 3d 20 22 32  if { $spec == "2
2320: 20 31 20 6c 6f 63 6b 20 73 68 61 72 65 64 22 20   1 lock shared" 
2330: 7d 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  } {.      return
2340: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 0a 20 20   SQLITE_IOERR.  
2350: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
2360: 6e 20 53 51 4c 49 54 45 5f 4f 4b 0a 7d 0a 0a 23  n SQLITE_OK.}..#
2370: 20 54 65 73 74 20 61 20 6e 6f 72 6d 61 6c 20 53   Test a normal S
2380: 51 4c 49 54 45 5f 42 55 53 59 20 72 65 74 75 72  QLITE_BUSY retur
2390: 6e 2e 0a 23 0a 54 20 66 69 6c 74 65 72 20 78 53  n..#.T filter xS
23a0: 68 6d 42 61 72 72 69 65 72 0a 73 65 74 20 74 65  hmBarrier.set te
23b0: 73 74 72 63 20 22 22 0a 73 65 74 20 74 65 73 74  strc "".set test
23c0: 6d 73 67 20 22 22 0a 73 65 74 20 62 61 72 72 69  msg "".set barri
23d0: 65 72 5f 63 6f 75 6e 74 20 30 0a 73 65 74 20 77  er_count 0.set w
23e0: 61 6c 33 5f 64 6f 5f 6c 6f 63 6b 66 61 69 6c 75  al3_do_lockfailu
23f0: 72 65 20 30 0a 64 6f 5f 74 65 73 74 20 77 61 6c  re 0.do_test wal
2400: 33 2d 35 2e 32 20 7b 0a 20 20 66 61 75 6c 74 73  3-5.2 {.  faults
2410: 69 6d 5f 72 65 73 74 6f 72 65 5f 61 6e 64 5f 72  im_restore_and_r
2420: 65 6f 70 65 6e 0a 20 20 65 78 65 63 73 71 6c 20  eopen.  execsql 
2430: 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20  { SELECT * FROM 
2440: 74 31 20 7d 0a 7d 20 7b 31 20 32 20 33 20 34 7d  t1 }.} {1 2 3 4}
2450: 0a 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 35 2e  .do_test wal3-5.
2460: 33 20 7b 0a 20 20 6c 69 73 74 20 24 3a 3a 74 65  3 {.  list $::te
2470: 73 74 72 63 20 24 3a 3a 74 65 73 74 6d 73 67 0a  strc $::testmsg.
2480: 7d 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20 69  } {1 {database i
2490: 73 20 6c 6f 63 6b 65 64 7d 7d 0a 64 62 20 63 6c  s locked}}.db cl
24a0: 6f 73 65 0a 0a 23 20 54 65 73 74 20 61 6e 20 53  ose..# Test an S
24b0: 51 4c 49 54 45 5f 49 4f 45 52 52 20 72 65 74 75  QLITE_IOERR retu
24c0: 72 6e 2e 0a 23 0a 54 20 66 69 6c 74 65 72 20 78  rn..#.T filter x
24d0: 53 68 6d 42 61 72 72 69 65 72 0a 73 65 74 20 62  ShmBarrier.set b
24e0: 61 72 72 69 65 72 5f 63 6f 75 6e 74 20 30 0a 73  arrier_count 0.s
24f0: 65 74 20 77 61 6c 33 5f 64 6f 5f 6c 6f 63 6b 66  et wal3_do_lockf
2500: 61 69 6c 75 72 65 20 31 0a 73 65 74 20 74 65 73  ailure 1.set tes
2510: 74 72 63 20 22 22 0a 73 65 74 20 74 65 73 74 6d  trc "".set testm
2520: 73 67 20 22 22 0a 64 6f 5f 74 65 73 74 20 77 61  sg "".do_test wa
2530: 6c 33 2d 35 2e 34 20 7b 0a 20 20 66 61 75 6c 74  l3-5.4 {.  fault
2540: 73 69 6d 5f 72 65 73 74 6f 72 65 5f 61 6e 64 5f  sim_restore_and_
2550: 72 65 6f 70 65 6e 0a 20 20 65 78 65 63 73 71 6c  reopen.  execsql
2560: 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d   { SELECT * FROM
2570: 20 74 31 20 7d 0a 7d 20 7b 31 20 32 20 33 20 34   t1 }.} {1 2 3 4
2580: 7d 0a 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 35  }.do_test wal3-5
2590: 2e 35 20 7b 0a 20 20 6c 69 73 74 20 24 3a 3a 74  .5 {.  list $::t
25a0: 65 73 74 72 63 20 24 3a 3a 74 65 73 74 6d 73 67  estrc $::testmsg
25b0: 0a 7d 20 7b 31 20 7b 64 69 73 6b 20 49 2f 4f 20  .} {1 {disk I/O 
25c0: 65 72 72 6f 72 7d 7d 0a 0a 64 62 20 63 6c 6f 73  error}}..db clos
25d0: 65 0a 54 20 64 65 6c 65 74 65 0a 0a 23 2d 2d 2d  e.T delete..#---
25e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
25f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2600: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2610: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2620: 2d 2d 2d 2d 2d 2d 0a 23 20 57 68 65 6e 20 6f 70  ------.# When op
2630: 65 6e 69 6e 67 20 61 20 72 65 61 64 2d 74 72 61  ening a read-tra
2640: 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 61 20 64 61  nsaction on a da
2650: 74 61 62 61 73 65 2c 20 69 66 20 74 68 65 20 65  tabase, if the e
2660: 6e 74 69 72 65 20 6c 6f 67 20 68 61 73 0a 23 20  ntire log has.# 
2670: 61 6c 72 65 61 64 79 20 62 65 65 6e 20 63 6f 70  already been cop
2680: 69 65 64 20 74 6f 20 74 68 65 20 64 61 74 61 62  ied to the datab
2690: 61 73 65 20 66 69 6c 65 2c 20 74 68 65 20 72 65  ase file, the re
26a0: 61 64 65 72 20 67 72 61 62 73 20 61 20 73 70 65  ader grabs a spe
26b0: 63 69 61 6c 0a 23 20 6b 69 6e 64 20 6f 66 20 72  cial.# kind of r
26c0: 65 61 64 20 6c 6f 63 6b 20 28 6f 6e 20 61 52 65  ead lock (on aRe
26d0: 61 64 4d 61 72 6b 5b 30 5d 29 2e 20 54 68 69 73  adMark[0]). This
26e0: 20 73 65 74 20 6f 66 20 74 65 73 74 20 63 61 73   set of test cas
26f0: 65 73 20 74 65 73 74 73 20 74 68 65 20 0a 23 20  es tests the .# 
2700: 6f 75 74 63 6f 6d 65 20 6f 66 20 74 68 65 20 66  outcome of the f
2710: 6f 6c 6c 6f 77 69 6e 67 3a 0a 23 0a 23 20 20 20  ollowing:.#.#   
2720: 2b 20 54 68 65 20 72 65 61 64 65 72 20 64 69 73  + The reader dis
2730: 63 6f 76 65 72 69 6e 67 20 74 68 61 74 20 62 65  covering that be
2740: 74 77 65 65 6e 20 74 68 65 20 74 69 6d 65 20 77  tween the time w
2750: 68 65 6e 20 69 74 20 64 65 74 65 72 6d 69 6e 65  hen it determine
2760: 64 20 0a 23 20 20 20 20 20 74 68 61 74 20 74 68  d .#     that th
2770: 65 20 6c 6f 67 20 68 61 64 20 62 65 65 6e 20 63  e log had been c
2780: 6f 6d 70 6c 65 74 65 6c 79 20 62 61 63 6b 66 69  ompletely backfi
2790: 6c 6c 65 64 20 61 6e 64 20 74 68 65 20 6c 6f 63  lled and the loc
27a0: 6b 20 69 73 20 6f 62 74 61 69 6e 65 64 0a 23 20  k is obtained.# 
27b0: 20 20 20 20 74 68 61 74 20 61 20 77 72 69 74 65      that a write
27c0: 72 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 6f  r has written to
27d0: 20 74 68 65 20 6c 6f 67 2e 20 49 6e 20 74 68 69   the log. In thi
27e0: 73 20 63 61 73 65 20 74 68 65 20 72 65 61 64 65  s case the reade
27f0: 72 20 73 68 6f 75 6c 64 0a 23 20 20 20 20 20 61  r should.#     a
2800: 63 71 75 69 72 65 20 61 20 64 69 66 66 65 72 65  cquire a differe
2810: 6e 74 20 72 65 61 64 2d 6c 6f 63 6b 20 28 6e 6f  nt read-lock (no
2820: 74 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d 29 20  t aReadMark[0]) 
2830: 61 6e 64 20 72 65 61 64 20 74 68 65 20 6e 65 77  and read the new
2840: 0a 23 20 20 20 20 20 73 6e 61 70 73 68 6f 74 2e  .#     snapshot.
2850: 0a 23 0a 23 20 20 20 2b 20 54 68 65 20 61 74 74  .#.#   + The att
2860: 65 6d 70 74 20 74 6f 20 6f 62 74 61 69 6e 20 74  empt to obtain t
2870: 68 65 20 6c 6f 63 6b 20 6f 6e 20 61 52 65 61 64  he lock on aRead
2880: 4d 61 72 6b 5b 30 5d 20 66 61 69 6c 73 20 77 69  Mark[0] fails wi
2890: 74 68 20 53 51 4c 49 54 45 5f 42 55 53 59 2e 0a  th SQLITE_BUSY..
28a0: 23 20 20 20 20 20 54 68 69 73 20 63 61 6e 20 68  #     This can h
28b0: 61 70 70 65 6e 20 69 66 20 61 20 63 68 65 63 6b  appen if a check
28c0: 70 6f 69 6e 74 20 69 73 20 6f 6e 67 6f 69 6e 67  point is ongoing
28d0: 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 61  . In this case a
28e0: 6c 73 6f 20 73 69 6d 70 6c 79 0a 23 20 20 20 20  lso simply.#    
28f0: 20 6f 62 74 61 69 6e 20 61 20 64 69 66 66 65 72   obtain a differ
2900: 65 6e 74 20 72 65 61 64 2d 6c 6f 63 6b 2e 0a 23  ent read-lock..#
2910: 0a 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65  .catch {db close
2920: 7d 0a 74 65 73 74 76 66 73 20 54 20 2d 64 65 66  }.testvfs T -def
2930: 61 75 6c 74 20 31 0a 64 6f 5f 74 65 73 74 20 77  ault 1.do_test w
2940: 61 6c 33 2d 36 2e 31 2e 31 20 7b 0a 20 20 66 6f  al3-6.1.1 {.  fo
2950: 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64  rcedelete test.d
2960: 62 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61  b test.db-journa
2970: 6c 20 74 65 73 74 2e 64 62 20 77 61 6c 0a 20 20  l test.db wal.  
2980: 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e  sqlite3 db test.
2990: 64 62 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 50  db.  execsql { P
29a0: 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75  RAGMA auto_vacuu
29b0: 6d 20 3d 20 6f 66 66 20 7d 0a 20 20 65 78 65 63  m = off }.  exec
29c0: 73 71 6c 20 7b 20 50 52 41 47 4d 41 20 6a 6f 75  sql { PRAGMA jou
29d0: 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c 20  rnal_mode = WAL 
29e0: 7d 0a 20 20 65 78 65 63 73 71 6c 20 7b 0a 20 20  }.  execsql {.  
29f0: 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74    CREATE TABLE t
2a00: 31 28 61 2c 20 62 29 3b 0a 20 20 20 20 49 4e 53  1(a, b);.    INS
2a10: 45 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55  ERT INTO t1 VALU
2a20: 45 53 28 27 6f 27 2c 20 27 74 27 29 3b 0a 20 20  ES('o', 't');.  
2a30: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
2a40: 20 56 41 4c 55 45 53 28 27 74 27 2c 20 27 66 27   VALUES('t', 'f'
2a50: 29 3b 0a 20 20 7d 0a 7d 20 7b 7d 0a 64 6f 5f 74  );.  }.} {}.do_t
2a60: 65 73 74 20 77 61 6c 33 2d 36 2e 31 2e 32 20 7b  est wal3-6.1.2 {
2a70: 0a 20 20 73 71 6c 69 74 65 33 20 64 62 32 20 74  .  sqlite3 db2 t
2a80: 65 73 74 2e 64 62 0a 20 20 73 71 6c 69 74 65 33  est.db.  sqlite3
2a90: 20 64 62 33 20 74 65 73 74 2e 64 62 0a 20 20 65   db3 test.db.  e
2aa0: 78 65 63 73 71 6c 20 7b 20 42 45 47 49 4e 20 3b  xecsql { BEGIN ;
2ab0: 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74   SELECT * FROM t
2ac0: 31 20 7d 20 64 62 33 0a 7d 20 7b 6f 20 74 20 74  1 } db3.} {o t t
2ad0: 20 66 7d 0a 64 6f 5f 74 65 73 74 20 77 61 6c 33   f}.do_test wal3
2ae0: 2d 36 2e 31 2e 33 20 7b 0a 20 20 65 78 65 63 73  -6.1.3 {.  execs
2af0: 71 6c 20 7b 20 50 52 41 47 4d 41 20 77 61 6c 5f  ql { PRAGMA wal_
2b00: 63 68 65 63 6b 70 6f 69 6e 74 20 7d 20 64 62 32  checkpoint } db2
2b10: 0a 7d 20 7b 30 20 34 20 34 7d 0a 0a 23 20 41 74  .} {0 4 4}..# At
2b20: 20 74 68 69 73 20 70 6f 69 6e 74 20 74 68 65 20   this point the 
2b30: 6c 6f 67 20 66 69 6c 65 20 68 61 73 20 62 65 65  log file has bee
2b40: 6e 20 66 75 6c 6c 79 20 63 68 65 63 6b 70 6f 69  n fully checkpoi
2b50: 6e 74 65 64 2e 20 48 6f 77 65 76 65 72 2c 20 0a  nted. However, .
2b60: 23 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b 64 62  # connection [db
2b70: 33 5d 20 68 6f 6c 64 73 20 61 20 6c 6f 63 6b 20  3] holds a lock 
2b80: 74 68 61 74 20 70 72 65 76 65 6e 74 73 20 74 68  that prevents th
2b90: 65 20 6c 6f 67 20 66 72 6f 6d 20 62 65 69 6e 67  e log from being
2ba0: 20 77 72 61 70 70 65 64 2e 0a 23 20 54 65 73 74   wrapped..# Test
2bb0: 20 63 61 73 65 20 33 2e 36 2e 31 2e 34 20 68 61   case 3.6.1.4 ha
2bc0: 73 20 5b 64 62 5d 20 61 74 74 65 6d 70 74 20 61  s [db] attempt a
2bd0: 20 72 65 61 64 2d 6c 6f 63 6b 20 6f 6e 20 61 52   read-lock on aR
2be0: 65 61 64 4d 61 72 6b 5b 30 5d 2e 20 42 75 74 0a  eadMark[0]. But.
2bf0: 23 20 61 73 20 69 74 20 69 73 20 6f 62 74 61 69  # as it is obtai
2c00: 6e 69 6e 67 20 74 68 65 20 6c 6f 63 6b 2c 20 5b  ning the lock, [
2c10: 64 62 32 5d 20 61 70 70 65 6e 64 73 20 74 6f 20  db2] appends to 
2c20: 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 23 0a  the log file..#.
2c30: 54 20 66 69 6c 74 65 72 20 78 53 68 6d 4c 6f 63  T filter xShmLoc
2c40: 6b 0a 54 20 73 63 72 69 70 74 20 6c 6f 63 6b 5f  k.T script lock_
2c50: 63 61 6c 6c 62 61 63 6b 0a 70 72 6f 63 20 6c 6f  callback.proc lo
2c60: 63 6b 5f 63 61 6c 6c 62 61 63 6b 20 7b 6d 65 74  ck_callback {met
2c70: 68 6f 64 20 66 69 6c 65 20 68 61 6e 64 6c 65 20  hod file handle 
2c80: 73 70 65 63 7d 20 7b 0a 20 20 69 66 20 7b 24 73  spec} {.  if {$s
2c90: 70 65 63 20 3d 3d 20 22 33 20 31 20 6c 6f 63 6b  pec == "3 1 lock
2ca0: 20 73 68 61 72 65 64 22 7d 20 7b 0a 20 20 20 20   shared"} {.    
2cb0: 23 20 54 68 69 73 20 69 73 20 74 68 65 20 63 61  # This is the ca
2cc0: 6c 6c 62 61 63 6b 20 66 6f 72 20 5b 64 62 5d 20  llback for [db] 
2cd0: 74 6f 20 6f 62 74 61 69 6e 20 74 68 65 20 72 65  to obtain the re
2ce0: 61 64 20 6c 6f 63 6b 20 6f 6e 20 61 52 65 61 64  ad lock on aRead
2cf0: 4d 61 72 6b 5b 30 5d 2e 0a 20 20 20 20 23 20 44  Mark[0]..    # D
2d00: 69 73 61 62 6c 65 20 66 75 74 75 72 65 20 63 61  isable future ca
2d10: 6c 6c 62 61 63 6b 73 20 75 73 69 6e 67 20 5b 54  llbacks using [T
2d20: 20 66 69 6c 74 65 72 20 7b 7d 5d 20 61 6e 64 20   filter {}] and 
2d30: 77 72 69 74 65 20 74 6f 20 74 68 65 20 6c 6f 67  write to the log
2d40: 0a 20 20 20 20 23 20 66 69 6c 65 20 75 73 69 6e  .    # file usin
2d50: 67 20 5b 64 62 32 5d 2e 20 5b 64 62 33 5d 20 69  g [db2]. [db3] i
2d60: 73 20 70 72 65 76 65 6e 74 69 6e 67 20 5b 64 62  s preventing [db
2d70: 32 5d 20 66 72 6f 6d 20 77 72 61 70 70 69 6e 67  2] from wrapping
2d80: 20 74 68 65 20 6c 6f 67 0a 20 20 20 20 23 20 68   the log.    # h
2d90: 65 72 65 2c 20 73 6f 20 74 68 69 73 20 69 73 20  ere, so this is 
2da0: 61 6e 20 61 70 70 65 6e 64 2e 0a 20 20 20 20 54  an append..    T
2db0: 20 66 69 6c 74 65 72 20 7b 7d 0a 20 20 20 20 64   filter {}.    d
2dc0: 62 32 20 65 76 61 6c 20 7b 20 49 4e 53 45 52 54  b2 eval { INSERT
2dd0: 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28   INTO t1 VALUES(
2de0: 27 66 27 2c 20 27 73 27 29 20 7d 0a 20 20 7d 0a  'f', 's') }.  }.
2df0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2e00: 4f 4b 0a 7d 0a 64 6f 5f 74 65 73 74 20 77 61 6c  OK.}.do_test wal
2e10: 33 2d 36 2e 31 2e 34 20 7b 0a 20 20 65 78 65 63  3-6.1.4 {.  exec
2e20: 73 71 6c 20 7b 0a 20 20 20 20 42 45 47 49 4e 3b  sql {.    BEGIN;
2e30: 0a 20 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52  .    SELECT * FR
2e40: 4f 4d 20 74 31 3b 0a 20 20 7d 0a 7d 20 7b 6f 20  OM t1;.  }.} {o 
2e50: 74 20 74 20 66 20 66 20 73 7d 0a 0a 23 20 5b 64  t t f f s}..# [d
2e60: 62 5d 20 73 68 6f 75 6c 64 20 62 65 20 6c 65 66  b] should be lef
2e70: 74 20 68 6f 6c 64 69 6e 67 20 61 20 72 65 61 64  t holding a read
2e80: 2d 6c 6f 63 6b 20 6f 6e 20 73 6f 6d 65 20 73 6c  -lock on some sl
2e90: 6f 74 20 6f 74 68 65 72 20 74 68 61 6e 20 0a 23  ot other than .#
2ea0: 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d 2e 20 54   aReadMark[0]. T
2eb0: 65 73 74 20 74 68 69 73 20 62 79 20 64 65 6d 6f  est this by demo
2ec0: 6e 73 74 72 61 74 69 6e 67 20 74 68 61 74 20 74  nstrating that t
2ed0: 68 65 20 72 65 61 64 2d 6c 6f 63 6b 20 69 73 20  he read-lock is 
2ee0: 70 72 65 76 65 6e 74 69 6e 67 0a 23 20 74 68 65  preventing.# the
2ef0: 20 6c 6f 67 20 66 72 6f 6d 20 62 65 69 6e 67 20   log from being 
2f00: 77 72 61 70 70 65 64 2e 0a 23 0a 64 6f 5f 74 65  wrapped..#.do_te
2f10: 73 74 20 77 61 6c 33 2d 36 2e 31 2e 35 20 7b 0a  st wal3-6.1.5 {.
2f20: 20 20 64 62 33 20 65 76 61 6c 20 43 4f 4d 4d 49    db3 eval COMMI
2f30: 54 0a 20 20 64 62 32 20 65 76 61 6c 20 7b 20 50  T.  db2 eval { P
2f40: 52 41 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70  RAGMA wal_checkp
2f50: 6f 69 6e 74 20 7d 0a 20 20 73 65 74 20 73 7a 31  oint }.  set sz1
2f60: 20 5b 66 69 6c 65 20 73 69 7a 65 20 74 65 73 74   [file size test
2f70: 2e 64 62 2d 77 61 6c 5d 0a 20 20 64 62 32 20 65  .db-wal].  db2 e
2f80: 76 61 6c 20 7b 20 49 4e 53 45 52 54 20 49 4e 54  val { INSERT INT
2f90: 4f 20 74 31 20 56 41 4c 55 45 53 28 27 73 27 2c  O t1 VALUES('s',
2fa0: 20 27 65 27 29 20 7d 0a 20 20 73 65 74 20 73 7a   'e') }.  set sz
2fb0: 32 20 5b 66 69 6c 65 20 73 69 7a 65 20 74 65 73  2 [file size tes
2fc0: 74 2e 64 62 2d 77 61 6c 5d 0a 20 20 65 78 70 72  t.db-wal].  expr
2fd0: 20 7b 24 73 7a 32 3e 24 73 7a 31 7d 0a 7d 20 7b   {$sz2>$sz1}.} {
2fe0: 31 7d 0a 0a 23 20 54 65 73 74 20 74 68 61 74 20  1}..# Test that 
2ff0: 69 66 20 5b 64 62 32 5d 20 68 61 64 20 6e 6f 74  if [db2] had not
3000: 20 69 6e 74 65 72 66 65 72 65 64 20 77 68 65 6e   interfered when
3010: 20 5b 64 62 5d 20 77 61 73 20 74 72 79 69 6e 67   [db] was trying
3020: 20 74 6f 20 67 72 61 62 0a 23 20 61 52 65 61 64   to grab.# aRead
3030: 4d 61 72 6b 5b 30 5d 2c 20 69 74 20 77 6f 75 6c  Mark[0], it woul
3040: 64 20 68 61 76 65 20 62 65 65 6e 20 70 6f 73 73  d have been poss
3050: 69 62 6c 65 20 74 6f 20 77 72 61 70 20 74 68 65  ible to wrap the
3060: 20 6c 6f 67 20 69 6e 20 33 2e 36 2e 31 2e 35 2e   log in 3.6.1.5.
3070: 0a 23 0a 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d  .#.do_test wal3-
3080: 36 2e 31 2e 36 20 7b 0a 20 20 65 78 65 63 73 71  6.1.6 {.  execsq
3090: 6c 20 7b 20 43 4f 4d 4d 49 54 20 7d 0a 20 20 65  l { COMMIT }.  e
30a0: 78 65 63 73 71 6c 20 7b 20 50 52 41 47 4d 41 20  xecsql { PRAGMA 
30b0: 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 20 7d  wal_checkpoint }
30c0: 20 64 62 32 0a 20 20 65 78 65 63 73 71 6c 20 7b   db2.  execsql {
30d0: 0a 20 20 20 20 42 45 47 49 4e 3b 0a 20 20 20 20  .    BEGIN;.    
30e0: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 31  SELECT * FROM t1
30f0: 3b 0a 20 20 7d 0a 7d 20 7b 6f 20 74 20 74 20 66  ;.  }.} {o t t f
3100: 20 66 20 73 20 73 20 65 7d 0a 64 6f 5f 74 65 73   f s s e}.do_tes
3110: 74 20 77 61 6c 33 2d 36 2e 31 2e 37 20 7b 0a 20  t wal3-6.1.7 {. 
3120: 20 64 62 32 20 65 76 61 6c 20 7b 20 50 52 41 47   db2 eval { PRAG
3130: 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e  MA wal_checkpoin
3140: 74 20 7d 0a 20 20 73 65 74 20 73 7a 31 20 5b 66  t }.  set sz1 [f
3150: 69 6c 65 20 73 69 7a 65 20 74 65 73 74 2e 64 62  ile size test.db
3160: 2d 77 61 6c 5d 0a 20 20 64 62 32 20 65 76 61 6c  -wal].  db2 eval
3170: 20 7b 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74   { INSERT INTO t
3180: 31 20 56 41 4c 55 45 53 28 27 6e 27 2c 20 27 74  1 VALUES('n', 't
3190: 27 29 20 7d 0a 20 20 73 65 74 20 73 7a 32 20 5b  ') }.  set sz2 [
31a0: 66 69 6c 65 20 73 69 7a 65 20 74 65 73 74 2e 64  file size test.d
31b0: 62 2d 77 61 6c 5d 0a 20 20 65 78 70 72 20 7b 24  b-wal].  expr {$
31c0: 73 7a 32 3d 3d 24 73 7a 31 7d 0a 7d 20 7b 31 7d  sz2==$sz1}.} {1}
31d0: 0a 0a 64 62 33 20 63 6c 6f 73 65 0a 64 62 32 20  ..db3 close.db2 
31e0: 63 6c 6f 73 65 0a 64 62 20 63 6c 6f 73 65 0a 0a  close.db close..
31f0: 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 36 2e 32  do_test wal3-6.2
3200: 2e 31 20 7b 0a 20 20 66 6f 72 63 65 64 65 6c 65  .1 {.  forcedele
3210: 74 65 20 74 65 73 74 2e 64 62 20 74 65 73 74 2e  te test.db test.
3220: 64 62 2d 6a 6f 75 72 6e 61 6c 20 74 65 73 74 2e  db-journal test.
3230: 64 62 20 77 61 6c 0a 20 20 73 71 6c 69 74 65 33  db wal.  sqlite3
3240: 20 64 62 20 74 65 73 74 2e 64 62 0a 20 20 73 71   db test.db.  sq
3250: 6c 69 74 65 33 20 64 62 32 20 74 65 73 74 2e 64  lite3 db2 test.d
3260: 62 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 50 52  b.  execsql { PR
3270: 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75 6d  AGMA auto_vacuum
3280: 20 3d 20 6f 66 66 20 7d 0a 20 20 65 78 65 63 73   = off }.  execs
3290: 71 6c 20 7b 20 50 52 41 47 4d 41 20 6a 6f 75 72  ql { PRAGMA jour
32a0: 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c 20 7d  nal_mode = WAL }
32b0: 0a 20 20 65 78 65 63 73 71 6c 20 7b 0a 20 20 20  .  execsql {.   
32c0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31   CREATE TABLE t1
32d0: 28 61 2c 20 62 29 3b 0a 20 20 20 20 49 4e 53 45  (a, b);.    INSE
32e0: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
32f0: 53 28 27 68 27 2c 20 27 68 27 29 3b 0a 20 20 20  S('h', 'h');.   
3300: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
3310: 56 41 4c 55 45 53 28 27 6c 27 2c 20 27 62 27 29  VALUES('l', 'b')
3320: 3b 0a 20 20 7d 0a 7d 20 7b 7d 0a 0a 54 20 66 69  ;.  }.} {}..T fi
3330: 6c 74 65 72 20 78 53 68 6d 4c 6f 63 6b 0a 54 20  lter xShmLock.T 
3340: 73 63 72 69 70 74 20 6c 6f 63 6b 5f 63 61 6c 6c  script lock_call
3350: 62 61 63 6b 0a 70 72 6f 63 20 6c 6f 63 6b 5f 63  back.proc lock_c
3360: 61 6c 6c 62 61 63 6b 20 7b 6d 65 74 68 6f 64 20  allback {method 
3370: 66 69 6c 65 20 68 61 6e 64 6c 65 20 73 70 65 63  file handle spec
3380: 7d 20 7b 0a 20 20 69 66 20 7b 24 73 70 65 63 20  } {.  if {$spec 
3390: 3d 3d 20 22 33 20 31 20 75 6e 6c 6f 63 6b 20 65  == "3 1 unlock e
33a0: 78 63 6c 75 73 69 76 65 22 7d 20 7b 0a 20 20 20  xclusive"} {.   
33b0: 20 54 20 66 69 6c 74 65 72 20 7b 7d 0a 20 20 20   T filter {}.   
33c0: 20 73 65 74 20 3a 3a 52 20 5b 64 62 32 20 65 76   set ::R [db2 ev
33d0: 61 6c 20 7b 0a 20 20 20 20 20 20 42 45 47 49 4e  al {.      BEGIN
33e0: 3b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 2a  ;.      SELECT *
33f0: 20 46 52 4f 4d 20 74 31 3b 0a 20 20 20 20 7d 5d   FROM t1;.    }]
3400: 0a 20 20 7d 0a 7d 0a 64 6f 5f 74 65 73 74 20 77  .  }.}.do_test w
3410: 61 6c 33 2d 36 2e 32 2e 32 20 7b 0a 20 20 65 78  al3-6.2.2 {.  ex
3420: 65 63 73 71 6c 20 7b 20 50 52 41 47 4d 41 20 77  ecsql { PRAGMA w
3430: 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 20 7d 0a  al_checkpoint }.
3440: 7d 20 7b 30 20 34 20 34 7d 0a 64 6f 5f 74 65 73  } {0 4 4}.do_tes
3450: 74 20 77 61 6c 33 2d 36 2e 32 2e 33 20 7b 0a 20  t wal3-6.2.3 {. 
3460: 20 73 65 74 20 3a 3a 52 0a 7d 20 7b 68 20 68 20   set ::R.} {h h 
3470: 6c 20 62 7d 0a 64 6f 5f 74 65 73 74 20 77 61 6c  l b}.do_test wal
3480: 33 2d 36 2e 32 2e 34 20 7b 0a 20 20 73 65 74 20  3-6.2.4 {.  set 
3490: 73 7a 31 20 5b 66 69 6c 65 20 73 69 7a 65 20 74  sz1 [file size t
34a0: 65 73 74 2e 64 62 2d 77 61 6c 5d 0a 20 20 65 78  est.db-wal].  ex
34b0: 65 63 73 71 6c 20 7b 20 49 4e 53 45 52 54 20 49  ecsql { INSERT I
34c0: 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 27 62  NTO t1 VALUES('b
34d0: 27 2c 20 27 63 27 29 3b 20 7d 0a 20 20 73 65 74  ', 'c'); }.  set
34e0: 20 73 7a 32 20 5b 66 69 6c 65 20 73 69 7a 65 20   sz2 [file size 
34f0: 74 65 73 74 2e 64 62 2d 77 61 6c 5d 0a 20 20 65  test.db-wal].  e
3500: 78 70 72 20 7b 24 73 7a 32 20 3e 20 24 73 7a 31  xpr {$sz2 > $sz1
3510: 7d 0a 7d 20 7b 31 7d 0a 64 6f 5f 74 65 73 74 20  }.} {1}.do_test 
3520: 77 61 6c 33 2d 36 2e 32 2e 35 20 7b 0a 20 20 64  wal3-6.2.5 {.  d
3530: 62 32 20 65 76 61 6c 20 7b 20 43 4f 4d 4d 49 54  b2 eval { COMMIT
3540: 20 7d 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 50   }.  execsql { P
3550: 52 41 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70  RAGMA wal_checkp
3560: 6f 69 6e 74 20 7d 0a 20 20 73 65 74 20 73 7a 31  oint }.  set sz1
3570: 20 5b 66 69 6c 65 20 73 69 7a 65 20 74 65 73 74   [file size test
3580: 2e 64 62 2d 77 61 6c 5d 0a 20 20 65 78 65 63 73  .db-wal].  execs
3590: 71 6c 20 7b 20 49 4e 53 45 52 54 20 49 4e 54 4f  ql { INSERT INTO
35a0: 20 74 31 20 56 41 4c 55 45 53 28 27 6e 27 2c 20   t1 VALUES('n', 
35b0: 27 6f 27 29 3b 20 7d 0a 20 20 73 65 74 20 73 7a  'o'); }.  set sz
35c0: 32 20 5b 66 69 6c 65 20 73 69 7a 65 20 74 65 73  2 [file size tes
35d0: 74 2e 64 62 2d 77 61 6c 5d 0a 20 20 65 78 70 72  t.db-wal].  expr
35e0: 20 7b 24 73 7a 32 20 3d 3d 20 24 73 7a 31 7d 0a   {$sz2 == $sz1}.
35f0: 7d 20 7b 31 7d 0a 20 0a 64 62 32 20 63 6c 6f 73  } {1}. .db2 clos
3600: 65 0a 64 62 20 63 6c 6f 73 65 0a 54 20 64 65 6c  e.db close.T del
3610: 65 74 65 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ete..#----------
3620: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3630: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3640: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3650: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
3660: 23 20 57 68 65 6e 20 6f 70 65 6e 69 6e 67 20 61  # When opening a
3670: 20 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f   read-transactio
3680: 6e 20 6f 6e 20 61 20 64 61 74 61 62 61 73 65 2c  n on a database,
3690: 20 69 66 20 74 68 65 20 65 6e 74 69 72 65 20 6c   if the entire l
36a0: 6f 67 20 68 61 73 0a 23 20 6e 6f 74 20 79 65 74  og has.# not yet
36b0: 20 62 65 65 6e 20 63 6f 70 69 65 64 20 74 6f 20   been copied to 
36c0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
36d0: 65 2c 20 74 68 65 20 72 65 61 64 65 72 20 67 72  e, the reader gr
36e0: 61 62 73 20 61 20 72 65 61 64 0a 23 20 6c 6f 63  abs a read.# loc
36f0: 6b 20 6f 6e 20 61 52 65 61 64 4d 61 72 6b 5b 78  k on aReadMark[x
3700: 5d 2c 20 77 68 65 72 65 20 78 3e 30 2e 20 54 68  ], where x>0. Th
3710: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 65 73 74  e following test
3720: 20 63 61 73 65 73 20 65 78 70 65 72 69 6d 65 6e   cases experimen
3730: 74 0a 23 20 77 69 74 68 20 74 68 65 20 6f 75 74  t.# with the out
3740: 63 6f 6d 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  come of the foll
3750: 6f 77 69 6e 67 3a 0a 23 0a 23 20 20 20 2b 20 54  owing:.#.#   + T
3760: 68 65 20 72 65 61 64 65 72 20 64 69 73 63 6f 76  he reader discov
3770: 65 72 69 6e 67 20 74 68 61 74 20 62 65 74 77 65  ering that betwe
3780: 65 6e 20 74 68 65 20 74 69 6d 65 20 77 68 65 6e  en the time when
3790: 20 69 74 20 72 65 61 64 20 74 68 65 0a 23 20 20   it read the.#  
37a0: 20 20 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61     wal-index hea
37b0: 64 65 72 20 61 6e 64 20 74 68 65 20 6c 6f 63 6b  der and the lock
37c0: 20 77 61 73 20 6f 62 74 61 69 6e 65 64 20 74 68   was obtained th
37d0: 61 74 20 61 20 77 72 69 74 65 72 20 68 61 73 20  at a writer has 
37e0: 0a 23 20 20 20 20 20 77 72 69 74 74 65 6e 20 74  .#     written t
37f0: 6f 20 74 68 65 20 6c 6f 67 2e 20 49 6e 20 74 68  o the log. In th
3800: 69 73 20 63 61 73 65 20 74 68 65 20 72 65 61 64  is case the read
3810: 65 72 20 73 68 6f 75 6c 64 20 72 65 2d 72 65 61  er should re-rea
3820: 64 20 74 68 65 20 0a 23 20 20 20 20 20 77 61 6c  d the .#     wal
3830: 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 61 6e  -index header an
3840: 64 20 6c 6f 63 6b 20 61 20 73 6e 61 70 73 68 6f  d lock a snapsho
3850: 74 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  t corresponding 
3860: 74 6f 20 74 68 65 20 6e 65 77 20 0a 23 20 20 20  to the new .#   
3870: 20 20 68 65 61 64 65 72 2e 0a 23 0a 23 20 20 20    header..#.#   
3880: 2b 20 54 68 65 20 76 61 6c 75 65 20 69 6e 20 74  + The value in t
3890: 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 78 5d 20  he aReadMark[x] 
38a0: 73 6c 6f 74 20 68 61 73 20 62 65 65 6e 20 6d 6f  slot has been mo
38b0: 64 69 66 69 65 64 20 73 69 6e 63 65 20 69 74 20  dified since it 
38c0: 77 61 73 0a 23 20 20 20 20 20 72 65 61 64 2e 0a  was.#     read..
38d0: 23 0a 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73  #.catch {db clos
38e0: 65 7d 0a 74 65 73 74 76 66 73 20 54 20 2d 64 65  e}.testvfs T -de
38f0: 66 61 75 6c 74 20 31 0a 64 6f 5f 74 65 73 74 20  fault 1.do_test 
3900: 77 61 6c 33 2d 37 2e 31 2e 31 20 7b 0a 20 20 66  wal3-7.1.1 {.  f
3910: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e  orcedelete test.
3920: 64 62 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e  db test.db-journ
3930: 61 6c 20 74 65 73 74 2e 64 62 20 77 61 6c 0a 20  al test.db wal. 
3940: 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74   sqlite3 db test
3950: 2e 64 62 0a 20 20 65 78 65 63 73 71 6c 20 7b 0a  .db.  execsql {.
3960: 20 20 20 20 50 52 41 47 4d 41 20 6a 6f 75 72 6e      PRAGMA journ
3970: 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c 3b 0a 20  al_mode = WAL;. 
3980: 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20     CREATE TABLE 
3990: 62 6c 75 65 28 72 65 64 20 50 52 49 4d 41 52 59  blue(red PRIMARY
39a0: 20 4b 45 59 2c 20 67 72 65 65 6e 29 3b 0a 20 20   KEY, green);.  
39b0: 7d 0a 7d 20 7b 77 61 6c 7d 0a 0a 54 20 73 63 72  }.} {wal}..T scr
39c0: 69 70 74 20 6d 65 74 68 6f 64 5f 63 61 6c 6c 62  ipt method_callb
39d0: 61 63 6b 0a 54 20 66 69 6c 74 65 72 20 78 4f 70  ack.T filter xOp
39e0: 65 6e 0a 70 72 6f 63 20 6d 65 74 68 6f 64 5f 63  en.proc method_c
39f0: 61 6c 6c 62 61 63 6b 20 7b 6d 65 74 68 6f 64 20  allback {method 
3a00: 61 72 67 73 7d 20 7b 0a 20 20 69 66 20 7b 24 6d  args} {.  if {$m
3a10: 65 74 68 6f 64 20 3d 3d 20 22 78 4f 70 65 6e 22  ethod == "xOpen"
3a20: 7d 20 7b 20 72 65 74 75 72 6e 20 22 72 65 61 64  } { return "read
3a30: 65 72 22 20 7d 0a 7d 0a 64 6f 5f 74 65 73 74 20  er" }.}.do_test 
3a40: 77 61 6c 33 2d 37 2e 31 2e 32 20 7b 0a 20 20 73  wal3-7.1.2 {.  s
3a50: 71 6c 69 74 65 33 20 64 62 32 20 74 65 73 74 2e  qlite3 db2 test.
3a60: 64 62 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 53  db.  execsql { S
3a70: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 62 6c 75  ELECT * FROM blu
3a80: 65 20 7d 20 64 62 32 0a 7d 20 7b 7d 0a 0a 54 20  e } db2.} {}..T 
3a90: 66 69 6c 74 65 72 20 78 53 68 6d 4c 6f 63 6b 0a  filter xShmLock.
3aa0: 73 65 74 20 3a 3a 6c 6f 63 6b 73 20 5b 6c 69 73  set ::locks [lis
3ab0: 74 5d 0a 70 72 6f 63 20 6d 65 74 68 6f 64 5f 63  t].proc method_c
3ac0: 61 6c 6c 62 61 63 6b 20 7b 6d 65 74 68 6f 64 20  allback {method 
3ad0: 66 69 6c 65 20 68 61 6e 64 6c 65 20 73 70 65 63  file handle spec
3ae0: 7d 20 7b 0a 20 20 69 66 20 7b 24 68 61 6e 64 6c  } {.  if {$handl
3af0: 65 20 21 3d 20 22 72 65 61 64 65 72 22 20 7d 20  e != "reader" } 
3b00: 7b 20 72 65 74 75 72 6e 20 7d 0a 20 20 69 66 20  { return }.  if 
3b10: 7b 24 6d 65 74 68 6f 64 20 3d 3d 20 22 78 53 68  {$method == "xSh
3b20: 6d 4c 6f 63 6b 22 7d 20 7b 0a 20 20 20 20 63 61  mLock"} {.    ca
3b30: 74 63 68 20 7b 20 65 78 65 63 73 71 6c 20 7b 20  tch { execsql { 
3b40: 49 4e 53 45 52 54 20 49 4e 54 4f 20 62 6c 75 65  INSERT INTO blue
3b50: 20 56 41 4c 55 45 53 28 31 2c 20 32 29 20 7d 20   VALUES(1, 2) } 
3b60: 7d 0a 20 20 20 20 63 61 74 63 68 20 7b 20 65 78  }.    catch { ex
3b70: 65 63 73 71 6c 20 7b 20 49 4e 53 45 52 54 20 49  ecsql { INSERT I
3b80: 4e 54 4f 20 62 6c 75 65 20 56 41 4c 55 45 53 28  NTO blue VALUES(
3b90: 33 2c 20 34 29 20 7d 20 7d 0a 20 20 7d 0a 20 20  3, 4) } }.  }.  
3ba0: 6c 61 70 70 65 6e 64 20 3a 3a 6c 6f 63 6b 73 20  lappend ::locks 
3bb0: 24 73 70 65 63 0a 7d 0a 64 6f 5f 74 65 73 74 20  $spec.}.do_test 
3bc0: 77 61 6c 33 2d 37 2e 31 2e 33 20 7b 0a 20 20 65  wal3-7.1.3 {.  e
3bd0: 78 65 63 73 71 6c 20 7b 20 53 45 4c 45 43 54 20  xecsql { SELECT 
3be0: 2a 20 46 52 4f 4d 20 62 6c 75 65 20 7d 20 64 62  * FROM blue } db
3bf0: 32 0a 7d 20 7b 31 20 32 20 33 20 34 7d 0a 64 6f  2.} {1 2 3 4}.do
3c00: 5f 74 65 73 74 20 77 61 6c 33 2d 37 2e 31 2e 34  _test wal3-7.1.4
3c10: 20 7b 0a 20 20 73 65 74 20 3a 3a 6c 6f 63 6b 73   {.  set ::locks
3c20: 0a 7d 20 7b 7b 34 20 31 20 6c 6f 63 6b 20 73 68  .} {{4 1 lock sh
3c30: 61 72 65 64 7d 20 7b 34 20 31 20 75 6e 6c 6f 63  ared} {4 1 unloc
3c40: 6b 20 73 68 61 72 65 64 7d 20 7b 35 20 31 20 6c  k shared} {5 1 l
3c50: 6f 63 6b 20 73 68 61 72 65 64 7d 20 7b 35 20 31  ock shared} {5 1
3c60: 20 75 6e 6c 6f 63 6b 20 73 68 61 72 65 64 7d 7d   unlock shared}}
3c70: 0a 0a 73 65 74 20 3a 3a 6c 6f 63 6b 73 20 5b 6c  ..set ::locks [l
3c80: 69 73 74 5d 0a 70 72 6f 63 20 6d 65 74 68 6f 64  ist].proc method
3c90: 5f 63 61 6c 6c 62 61 63 6b 20 7b 6d 65 74 68 6f  _callback {metho
3ca0: 64 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 73 70  d file handle sp
3cb0: 65 63 7d 20 7b 0a 20 20 69 66 20 7b 24 68 61 6e  ec} {.  if {$han
3cc0: 64 6c 65 20 21 3d 20 22 72 65 61 64 65 72 22 20  dle != "reader" 
3cd0: 7d 20 7b 20 72 65 74 75 72 6e 20 7d 0a 20 20 69  } { return }.  i
3ce0: 66 20 7b 24 6d 65 74 68 6f 64 20 3d 3d 20 22 78  f {$method == "x
3cf0: 53 68 6d 4c 6f 63 6b 22 7d 20 7b 0a 20 20 20 20  ShmLock"} {.    
3d00: 63 61 74 63 68 20 7b 20 65 78 65 63 73 71 6c 20  catch { execsql 
3d10: 7b 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 62 6c  { INSERT INTO bl
3d20: 75 65 20 56 41 4c 55 45 53 28 35 2c 20 36 29 20  ue VALUES(5, 6) 
3d30: 7d 20 7d 0a 20 20 7d 0a 20 20 6c 61 70 70 65 6e  } }.  }.  lappen
3d40: 64 20 3a 3a 6c 6f 63 6b 73 20 24 73 70 65 63 0a  d ::locks $spec.
3d50: 7d 0a 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 37  }.do_test wal3-7
3d60: 2e 32 2e 31 20 7b 0a 20 20 65 78 65 63 73 71 6c  .2.1 {.  execsql
3d70: 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d   { SELECT * FROM
3d80: 20 62 6c 75 65 20 7d 20 64 62 32 0a 7d 20 7b 31   blue } db2.} {1
3d90: 20 32 20 33 20 34 20 35 20 36 7d 0a 64 6f 5f 74   2 3 4 5 6}.do_t
3da0: 65 73 74 20 77 61 6c 33 2d 37 2e 32 2e 32 20 7b  est wal3-7.2.2 {
3db0: 0a 20 20 73 65 74 20 3a 3a 6c 6f 63 6b 73 0a 7d  .  set ::locks.}
3dc0: 20 7b 7b 35 20 31 20 6c 6f 63 6b 20 73 68 61 72   {{5 1 lock shar
3dd0: 65 64 7d 20 7b 35 20 31 20 75 6e 6c 6f 63 6b 20  ed} {5 1 unlock 
3de0: 73 68 61 72 65 64 7d 20 7b 34 20 31 20 6c 6f 63  shared} {4 1 loc
3df0: 6b 20 73 68 61 72 65 64 7d 20 7b 34 20 31 20 75  k shared} {4 1 u
3e00: 6e 6c 6f 63 6b 20 73 68 61 72 65 64 7d 7d 0a 0a  nlock shared}}..
3e10: 64 62 20 63 6c 6f 73 65 0a 64 62 32 20 63 6c 6f  db close.db2 clo
3e20: 73 65 0a 54 20 64 65 6c 65 74 65 0a 0a 0a 23 2d  se.T delete...#-
3e30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3e40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3e50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3e60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3e70: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 57 68 65 6e 20  --------.# When 
3e80: 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6f 70 65  a connection ope
3e90: 6e 73 20 61 20 72 65 61 64 2d 6c 6f 63 6b 20 6f  ns a read-lock o
3ea0: 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 2c 20  n the database, 
3eb0: 69 74 20 73 65 61 72 63 68 65 73 20 66 6f 72 0a  it searches for.
3ec0: 23 20 61 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d  # an aReadMark[]
3ed0: 20 73 6c 6f 74 20 74 68 61 74 20 69 73 20 61 6c   slot that is al
3ee0: 72 65 61 64 79 20 73 65 74 20 74 6f 20 74 68 65  ready set to the
3ef0: 20 6d 78 46 72 61 6d 65 20 76 61 6c 75 65 20 66   mxFrame value f
3f00: 6f 72 20 74 68 65 0a 23 20 6e 65 77 20 74 72 61  or the.# new tra
3f10: 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20 69 74 20  nsaction. If it 
3f20: 63 61 6e 6e 6f 74 20 66 69 6e 64 20 6f 6e 65 2c  cannot find one,
3f30: 20 69 74 20 61 74 74 65 6d 70 74 73 20 74 6f 20   it attempts to 
3f40: 6f 62 74 61 69 6e 20 61 6e 20 0a 23 20 65 78 63  obtain an .# exc
3f50: 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 61  lusive lock on a
3f60: 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 73 6c  n aReadMark[] sl
3f70: 6f 74 20 66 6f 72 20 74 68 65 20 70 75 72 70 6f  ot for the purpo
3f80: 73 65 73 20 6f 66 20 6d 6f 64 69 66 79 69 6e 67  ses of modifying
3f90: 0a 23 20 74 68 65 20 76 61 6c 75 65 2c 20 74 68  .# the value, th
3fa0: 65 6e 20 64 72 6f 70 73 20 62 61 63 6b 20 74 6f  en drops back to
3fb0: 20 61 20 73 68 61 72 65 64 2d 6c 6f 63 6b 20 66   a shared-lock f
3fc0: 6f 72 20 74 68 65 20 64 75 72 61 74 69 6f 6e 20  or the duration 
3fd0: 6f 66 20 74 68 65 0a 23 20 74 72 61 6e 73 61 63  of the.# transac
3fe0: 74 69 6f 6e 2e 0a 23 0a 23 20 54 68 69 73 20 74  tion..#.# This t
3ff0: 65 73 74 20 63 61 73 65 20 76 65 72 69 66 69 65  est case verifie
4000: 73 20 74 68 61 74 20 69 66 20 61 6e 20 65 78 63  s that if an exc
4010: 6c 75 73 69 76 65 20 6c 6f 63 6b 20 63 61 6e 6e  lusive lock cann
4020: 6f 74 20 62 65 20 6f 62 74 61 69 6e 65 64 0a 23  ot be obtained.#
4030: 20 6f 6e 20 61 6e 79 20 61 52 65 61 64 4d 61 72   on any aReadMar
4040: 6b 5b 5d 20 73 6c 6f 74 20 28 62 65 63 61 75 73  k[] slot (becaus
4050: 65 20 74 68 65 72 65 20 61 72 65 20 61 6c 72 65  e there are alre
4060: 61 64 79 20 73 65 76 65 72 61 6c 20 72 65 61 64  ady several read
4070: 65 72 73 29 2c 0a 23 20 74 68 65 20 63 6c 69 65  ers),.# the clie
4080: 6e 74 20 74 61 6b 65 73 20 61 20 73 68 61 72 65  nt takes a share
4090: 64 2d 6c 6f 63 6b 20 6f 6e 20 61 20 73 6c 6f 74  d-lock on a slot
40a0: 20 77 69 74 68 6f 75 74 20 6d 6f 64 69 66 79 69   without modifyi
40b0: 6e 67 20 74 68 65 20 76 61 6c 75 65 0a 23 20 61  ng the value.# a
40c0: 6e 64 20 63 6f 6e 74 69 6e 75 65 73 2e 0a 23 0a  nd continues..#.
40d0: 73 65 74 20 6e 43 6f 6e 6e 20 35 30 0a 69 66 20  set nConn 50.if 
40e0: 7b 20 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20  { [string match 
40f0: 2a 42 53 44 20 24 74 63 6c 5f 70 6c 61 74 66 6f  *BSD $tcl_platfo
4100: 72 6d 28 6f 73 29 5d 20 7d 20 7b 20 73 65 74 20  rm(os)] } { set 
4110: 6e 43 6f 6e 6e 20 32 35 20 7d 0a 64 6f 5f 74 65  nConn 25 }.do_te
4120: 73 74 20 77 61 6c 33 2d 39 2e 30 20 7b 0a 20 20  st wal3-9.0 {.  
4130: 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74  forcedelete test
4140: 2e 64 62 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72  .db test.db-jour
4150: 6e 61 6c 20 74 65 73 74 2e 64 62 20 77 61 6c 0a  nal test.db wal.
4160: 20 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73    sqlite3 db tes
4170: 74 2e 64 62 0a 20 20 65 78 65 63 73 71 6c 20 7b  t.db.  execsql {
4180: 0a 20 20 20 20 50 52 41 47 4d 41 20 70 61 67 65  .    PRAGMA page
4190: 5f 73 69 7a 65 20 3d 20 31 30 32 34 3b 0a 20 20  _size = 1024;.  
41a0: 20 20 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c    PRAGMA journal
41b0: 5f 6d 6f 64 65 20 3d 20 57 41 4c 3b 0a 20 20 20  _mode = WAL;.   
41c0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 77 68   CREATE TABLE wh
41d0: 6f 61 6d 69 28 78 29 3b 0a 20 20 20 20 49 4e 53  oami(x);.    INS
41e0: 45 52 54 20 49 4e 54 4f 20 77 68 6f 61 6d 69 20  ERT INTO whoami 
41f0: 56 41 4c 55 45 53 28 27 6e 6f 62 6f 64 79 27 29  VALUES('nobody')
4200: 3b 0a 20 20 7d 0a 7d 20 7b 77 61 6c 7d 0a 66 6f  ;.  }.} {wal}.fo
4210: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20  r {set i 0} {$i 
4220: 3c 20 24 6e 43 6f 6e 6e 7d 20 7b 69 6e 63 72 20  < $nConn} {incr 
4230: 69 7d 20 7b 0a 20 20 73 65 74 20 63 20 64 62 24  i} {.  set c db$
4240: 69 0a 20 20 64 6f 5f 74 65 73 74 20 77 61 6c 33  i.  do_test wal3
4250: 2d 39 2e 31 2e 24 69 20 7b 0a 20 20 20 20 73 71  -9.1.$i {.    sq
4260: 6c 69 74 65 33 20 24 63 20 74 65 73 74 2e 64 62  lite3 $c test.db
4270: 0a 20 20 20 20 65 78 65 63 73 71 6c 20 7b 20 55  .    execsql { U
4280: 50 44 41 54 45 20 77 68 6f 61 6d 69 20 53 45 54  PDATE whoami SET
4290: 20 78 20 3d 20 24 63 20 7d 0a 20 20 20 20 65 78   x = $c }.    ex
42a0: 65 63 73 71 6c 20 7b 0a 20 20 20 20 20 20 42 45  ecsql {.      BE
42b0: 47 49 4e 3b 0a 20 20 20 20 20 20 53 45 4c 45 43  GIN;.      SELEC
42c0: 54 20 2a 20 46 52 4f 4d 20 77 68 6f 61 6d 69 0a  T * FROM whoami.
42d0: 20 20 20 20 7d 20 24 63 0a 20 20 7d 20 24 63 0a      } $c.  } $c.
42e0: 7d 0a 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20  }.for {set i 0} 
42f0: 7b 24 69 20 3c 20 24 6e 43 6f 6e 6e 7d 20 7b 69  {$i < $nConn} {i
4300: 6e 63 72 20 69 7d 20 7b 0a 20 20 73 65 74 20 63  ncr i} {.  set c
4310: 20 64 62 24 69 0a 20 20 64 6f 5f 74 65 73 74 20   db$i.  do_test 
4320: 77 61 6c 33 2d 39 2e 32 2e 24 69 20 7b 0a 20 20  wal3-9.2.$i {.  
4330: 20 20 65 78 65 63 73 71 6c 20 7b 20 53 45 4c 45    execsql { SELE
4340: 43 54 20 2a 20 46 52 4f 4d 20 77 68 6f 61 6d 69  CT * FROM whoami
4350: 20 7d 20 24 63 0a 20 20 7d 20 24 63 0a 7d 0a 0a   } $c.  } $c.}..
4360: 73 65 74 20 73 7a 20 5b 65 78 70 72 20 31 30 32  set sz [expr 102
4370: 34 20 2a 20 28 32 2b 24 41 55 54 4f 56 41 43 55  4 * (2+$AUTOVACU
4380: 55 4d 29 5d 0a 64 6f 5f 74 65 73 74 20 77 61 6c  UM)].do_test wal
4390: 33 2d 39 2e 33 20 7b 0a 20 20 66 6f 72 20 7b 73  3-9.3 {.  for {s
43a0: 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 28 24  et i 0} {$i < ($
43b0: 6e 43 6f 6e 6e 2d 31 29 7d 20 7b 69 6e 63 72 20  nConn-1)} {incr 
43c0: 69 7d 20 7b 20 64 62 24 69 20 63 6c 6f 73 65 20  i} { db$i close 
43d0: 7d 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 50 52  }.  execsql { PR
43e0: 41 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70 6f  AGMA wal_checkpo
43f0: 69 6e 74 20 7d 20 0a 20 20 62 79 74 65 5f 69 73  int } .  byte_is
4400: 5f 7a 65 72 6f 20 74 65 73 74 2e 64 62 20 5b 65  _zero test.db [e
4410: 78 70 72 20 24 73 7a 2d 31 30 32 34 5d 0a 7d 20  xpr $sz-1024].} 
4420: 7b 31 7d 0a 64 6f 5f 74 65 73 74 20 77 61 6c 33  {1}.do_test wal3
4430: 2d 39 2e 34 20 7b 0a 20 20 64 62 5b 65 78 70 72  -9.4 {.  db[expr
4440: 20 24 6e 43 6f 6e 6e 2d 31 5d 20 63 6c 6f 73 65   $nConn-1] close
4450: 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 50 52 41  .  execsql { PRA
4460: 47 4d 41 20 77 61 6c 5f 63 68 65 63 6b 70 6f 69  GMA wal_checkpoi
4470: 6e 74 20 7d 20 0a 20 20 73 65 74 20 73 7a 32 20  nt } .  set sz2 
4480: 5b 66 69 6c 65 20 73 69 7a 65 20 74 65 73 74 2e  [file size test.
4490: 64 62 5d 0a 20 20 62 79 74 65 5f 69 73 5f 7a 65  db].  byte_is_ze
44a0: 72 6f 20 74 65 73 74 2e 64 62 20 5b 65 78 70 72  ro test.db [expr
44b0: 20 24 73 7a 2d 31 30 32 34 5d 0a 7d 20 7b 30 7d   $sz-1024].} {0}
44c0: 0a 0a 64 6f 5f 6d 75 6c 74 69 63 6c 69 65 6e 74  ..do_multiclient
44d0: 5f 74 65 73 74 20 74 6e 20 7b 0a 20 20 64 6f 5f  _test tn {.  do_
44e0: 74 65 73 74 20 77 61 6c 33 2d 31 30 2e 24 74 6e  test wal3-10.$tn
44f0: 2e 31 20 7b 0a 20 20 20 20 73 71 6c 31 20 7b 0a  .1 {.    sql1 {.
4500: 20 20 20 20 20 20 50 52 41 47 4d 41 20 70 61 67        PRAGMA pag
4510: 65 5f 73 69 7a 65 20 3d 20 31 30 32 34 3b 0a 20  e_size = 1024;. 
4520: 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c       CREATE TABL
4530: 45 20 74 31 28 78 29 3b 0a 20 20 20 20 20 20 50  E t1(x);.      P
4540: 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f  RAGMA journal_mo
4550: 64 65 20 3d 20 57 41 4c 3b 0a 20 20 20 20 20 20  de = WAL;.      
4560: 50 52 41 47 4d 41 20 77 61 6c 5f 61 75 74 6f 63  PRAGMA wal_autoc
4570: 68 65 63 6b 70 6f 69 6e 74 20 3d 20 31 30 30 30  heckpoint = 1000
4580: 30 30 3b 0a 20 20 20 20 20 20 42 45 47 49 4e 3b  00;.      BEGIN;
4590: 0a 20 20 20 20 20 20 20 20 49 4e 53 45 52 54 20  .        INSERT 
45a0: 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 72  INTO t1 VALUES(r
45b0: 61 6e 64 6f 6d 62 6c 6f 62 28 38 30 30 29 29 3b  andomblob(800));
45c0: 0a 20 20 20 20 20 20 20 20 49 4e 53 45 52 54 20  .        INSERT 
45d0: 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 72  INTO t1 SELECT r
45e0: 61 6e 64 6f 6d 62 6c 6f 62 28 38 30 30 29 20 46  andomblob(800) F
45f0: 52 4f 4d 20 74 31 3b 20 20 20 2d 2d 20 32 0a 20  ROM t1;   -- 2. 
4600: 20 20 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e         INSERT IN
4610: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 72 61 6e  TO t1 SELECT ran
4620: 64 6f 6d 62 6c 6f 62 28 38 30 30 29 20 46 52 4f  domblob(800) FRO
4630: 4d 20 74 31 3b 20 20 20 2d 2d 20 34 0a 20 20 20  M t1;   -- 4.   
4640: 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f       INSERT INTO
4650: 20 74 31 20 53 45 4c 45 43 54 20 72 61 6e 64 6f   t1 SELECT rando
4660: 6d 62 6c 6f 62 28 38 30 30 29 20 46 52 4f 4d 20  mblob(800) FROM 
4670: 74 31 3b 20 20 20 2d 2d 20 38 0a 20 20 20 20 20  t1;   -- 8.     
4680: 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74     INSERT INTO t
4690: 31 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62  1 SELECT randomb
46a0: 6c 6f 62 28 38 30 30 29 20 46 52 4f 4d 20 74 31  lob(800) FROM t1
46b0: 3b 20 20 20 2d 2d 20 31 36 0a 20 20 20 20 20 20  ;   -- 16.      
46c0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
46d0: 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c   SELECT randombl
46e0: 6f 62 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b  ob(800) FROM t1;
46f0: 20 20 20 2d 2d 20 33 32 0a 20 20 20 20 20 20 20     -- 32.       
4700: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
4710: 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f  SELECT randomblo
4720: 62 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20  b(800) FROM t1; 
4730: 20 20 2d 2d 20 36 34 0a 20 20 20 20 20 20 20 20    -- 64.        
4740: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
4750: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
4760: 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (800) FROM t1;  
4770: 20 2d 2d 20 31 32 38 0a 20 20 20 20 20 20 20 20   -- 128.        
4780: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
4790: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
47a0: 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (800) FROM t1;  
47b0: 20 2d 2d 20 32 35 36 0a 20 20 20 20 20 20 20 20   -- 256.        
47c0: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
47d0: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
47e0: 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (800) FROM t1;  
47f0: 20 2d 2d 20 35 31 32 0a 20 20 20 20 20 20 20 20   -- 512.        
4800: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
4810: 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62  ELECT randomblob
4820: 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20 20  (800) FROM t1;  
4830: 20 2d 2d 20 31 30 32 34 0a 20 20 20 20 20 20 20   -- 1024.       
4840: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
4850: 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f  SELECT randomblo
4860: 62 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b 20  b(800) FROM t1; 
4870: 20 20 2d 2d 20 32 30 34 38 0a 20 20 20 20 20 20    -- 2048.      
4880: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
4890: 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c   SELECT randombl
48a0: 6f 62 28 38 30 30 29 20 46 52 4f 4d 20 74 31 3b  ob(800) FROM t1;
48b0: 20 20 20 2d 2d 20 34 30 39 36 0a 20 20 20 20 20     -- 4096.     
48c0: 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74     INSERT INTO t
48d0: 31 20 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62  1 SELECT randomb
48e0: 6c 6f 62 28 38 30 30 29 20 46 52 4f 4d 20 74 31  lob(800) FROM t1
48f0: 3b 20 20 20 2d 2d 20 38 31 39 32 0a 20 20 20 20  ;   -- 8192.    
4900: 20 20 43 4f 4d 4d 49 54 3b 0a 20 20 20 20 20 20    COMMIT;.      
4910: 43 52 45 41 54 45 20 49 4e 44 45 58 20 69 31 20  CREATE INDEX i1 
4920: 4f 4e 20 74 31 28 78 29 3b 0a 20 20 20 20 7d 0a  ON t1(x);.    }.
4930: 0a 20 20 20 20 65 78 70 72 20 7b 5b 66 69 6c 65  .    expr {[file
4940: 20 73 69 7a 65 20 74 65 73 74 2e 64 62 2d 77 61   size test.db-wa
4950: 6c 5d 20 3e 20 5b 65 78 70 72 20 31 30 33 32 2a  l] > [expr 1032*
4960: 39 30 30 30 5d 7d 0a 20 20 7d 20 31 0a 0a 20 20  9000]}.  } 1..  
4970: 64 6f 5f 74 65 73 74 20 77 61 6c 33 2d 31 30 2e  do_test wal3-10.
4980: 24 74 6e 2e 32 20 7b 0a 20 20 20 20 73 71 6c 32  $tn.2 {.    sql2
4990: 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72 69   {PRAGMA integri
49a0: 74 79 5f 63 68 65 63 6b 7d 0a 20 20 7d 20 7b 6f  ty_check}.  } {o
49b0: 6b 7d 0a 7d 0a 0a 66 69 6e 69 73 68 5f 74 65 73  k}.}..finish_tes
49c0: 74 0a                                            t.