SQLite

Check-in [62ef45140c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add new test file e_walauto.test.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 62ef45140cdbff5eeb8bef506db8b78ced3ace94
User & Date: dan 2014-12-15 16:27:12.622
Context
2014-12-16
00:08
Make sure the sqlite3BtreeCount() routine does not leave index cursors in an inconsistent state, as doing so might result in an assertion fault inside of sqlite3BtreeKey() called from saveAllCursors() if content is deleted out from under the statement that issued the sqlite3BtreeCount() call. (check-in: 5b1b697040 user: drh tags: trunk)
2014-12-15
20:49
Changes to threadtest3 so that "stress2" is more similar to the SDS stress test. (Closed-Leaf check-in: 5648af96d8 user: dan tags: threadtest3)
16:27
Add new test file e_walauto.test. (check-in: 62ef45140c user: dan tags: trunk)
08:46
Fix errors in threadtest3 tests caused by earlier tests neglecting to close database handles. (check-in: 1d44f1b1a9 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test1.c.
5721
5722
5723
5724
5725
5726
5727





































5728
5729
5730
5731
5732
5733
5734
  Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(rc==SQLITE_BUSY?1:0));
  Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nLog));
  Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCkpt));
  Tcl_SetObjResult(interp, pRet);

  return TCL_OK;
}






































/*
** tclcmd:  test_sqlite3_log ?SCRIPT?
*/
static struct LogCallback {
  Tcl_Interp *pInterp;
  Tcl_Obj *pObj;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
  Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(rc==SQLITE_BUSY?1:0));
  Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nLog));
  Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCkpt));
  Tcl_SetObjResult(interp, pRet);

  return TCL_OK;
}

/*
** tclcmd:  sqlite3_wal_autocheckpoint db VALUE
*/
static int test_wal_autocheckpoint(
  ClientData clientData, /* Unused */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3 *db;
  int rc;
  int iVal;


  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB VALUE");
    return TCL_ERROR;
  }

  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
   || Tcl_GetIntFromObj(0, objv[2], &iVal)
  ){
    return TCL_ERROR;
  }

  rc = sqlite3_wal_autocheckpoint(db, iVal);
  Tcl_ResetResult(interp);
  if( rc!=SQLITE_OK ){
    const char *zErrCode = sqlite3ErrName(rc);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(zErrCode, -1));
    return TCL_ERROR;
  }

  return TCL_OK;
}


/*
** tclcmd:  test_sqlite3_log ?SCRIPT?
*/
static struct LogCallback {
  Tcl_Interp *pInterp;
  Tcl_Obj *pObj;
6783
6784
6785
6786
6787
6788
6789

6790
6791
6792
6793
6794
6795
6796
#endif
     { "pcache_stats",       test_pcache_stats, 0  },
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
     { "sqlite3_unlock_notify", test_unlock_notify, 0  },
#endif
     { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
     { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },

     { "test_sqlite3_log",         test_sqlite3_log, 0  },
#ifndef SQLITE_OMIT_EXPLAIN
     { "print_explain_query_plan", test_print_eqp, 0  },
#endif
     { "sqlite3_test_control", test_test_control },
#if SQLITE_OS_UNIX
     { "getrusage", test_getrusage },







>







6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
#endif
     { "pcache_stats",       test_pcache_stats, 0  },
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
     { "sqlite3_unlock_notify", test_unlock_notify, 0  },
#endif
     { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
     { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
     { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0  },
     { "test_sqlite3_log",         test_sqlite3_log, 0  },
#ifndef SQLITE_OMIT_EXPLAIN
     { "print_explain_query_plan", test_print_eqp, 0  },
#endif
     { "sqlite3_test_control", test_test_control },
#if SQLITE_OS_UNIX
     { "getrusage", test_getrusage },
Added test/e_walauto.test.


















































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# 2014 December 04
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/wal_common.tcl
set testprefix e_walauto


proc read_nbackfill {} {
  seek $::shmfd 96
  binary scan [read $::shmfd 4] i nBackfill
  set nBackfill
}
proc read_mxframe {} {
  seek $::shmfd 16
  binary scan [read $::shmfd 4] i mxFrame
  set mxFrame
}

# Assuming that the main db for database handle
#
proc do_autocommit_threshold_test {tn value} {

  set nBackfillSaved [read_nbackfill]
  while {1} {
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    if {[read_mxframe] >= $value} break
  }
  
  set nBackfillNew [read_nbackfill]
  uplevel [list do_test $tn "expr $nBackfillNew > $nBackfillSaved" 1]
}

# EVIDENCE-OF: R-30135-06439 The wal_autocheckpoint pragma can be used
# to invoke this interface from SQL.
#
#   All tests in this file are run twice - once using the
#   sqlite3_wal_autocheckpoint() API, and once using "PRAGMA
#   wal_autocheckpoint".
#
foreach {tn code} {
  1 {
    proc autocheckpoint {db value} {
      uplevel [list $db eval "PRAGMA wal_autocheckpoint = $value"]
    }
  }

  2 {
    proc autocheckpoint {db value} {
      uplevel [list sqlite3_wal_autocheckpoint $db $value]
      return $value
    }
  }
} {

  eval $code

  reset_db
  do_execsql_test 1.$tn.0 { PRAGMA journal_mode = WAL } {wal}
  do_execsql_test 1.$tn.1 { CREATE TABLE t1(a, b) }
  set shmfd [open "test.db-shm"]

  # EVIDENCE-OF: R-41531-51083 Every new database connection defaults to
  # having the auto-checkpoint enabled with a threshold of 1000 or
  # SQLITE_DEFAULT_WAL_AUTOCHECKPOINT pages.
  #
  do_autocommit_threshold_test 1.$tn.2 1000
  db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
  do_autocommit_threshold_test 1.$tn.3 1000

  # EVIDENCE-OF: R-38128-34102 The sqlite3_wal_autocheckpoint(D,N) is a
  # wrapper around sqlite3_wal_hook() that causes any database on database
  # connection D to automatically checkpoint after committing a
  # transaction if there are N or more frames in the write-ahead log file.
  #
  do_test 1.$tn.4 {
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    autocheckpoint db 100
  } {100}
  do_autocommit_threshold_test 1.$tn.5 100

  do_test 1.$tn.6 {
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    autocheckpoint db 500
  } {500}
  do_autocommit_threshold_test 1.$tn.7 500

  # EVIDENCE-OF: R-26993-43540 Passing zero or a negative value as the
  # nFrame parameter disables automatic checkpoints entirely.
  #
  do_test 1.$tn.7 {
    autocheckpoint db 0    ;# Set to zero
    for {set i 0} {$i < 10000} {incr i} {
      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    }
    expr {[file size test.db-wal] > (5 * 1024 * 1024)}
  } 1
  do_test 1.$tn.8 {
    sqlite3_wal_checkpoint_v2 db truncate
    file size test.db-wal
  } 0
  do_test 1.$tn.9 {
    autocheckpoint db -4    ;# Set to a negative value
    for {set i 0} {$i < 10000} {incr i} {
      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    }
    expr {[file size test.db-wal] > (5 * 1024 * 1024)}
  } 1

  # EVIDENCE-OF: R-10203-42688 The callback registered by this function
  # replaces any existing callback registered using sqlite3_wal_hook().
  #
  set ::wal_hook_callback 0
  proc wal_hook_callback {args} { incr ::wal_hook_callback ; return 0 }
  do_test 1.$tn.10.1 {
    db wal_hook wal_hook_callback
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    set ::wal_hook_callback
  } 2
  do_test 1.$tn.10.2 {
    autocheckpoint db 100
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    set ::wal_hook_callback
  } 2

  # EVIDENCE-OF: R-17497-43474 Likewise, registering a callback using
  # sqlite3_wal_hook() disables the automatic checkpoint mechanism
  # configured by this function.
  do_test 1.$tn.11.1 {
    sqlite3_wal_checkpoint_v2 db truncate
    file size test.db-wal
  } 0
  do_test 1.$tn.11.2 {
    autocheckpoint db 100 
    for {set i 0} {$i < 1000} {incr i} {
      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    }
    expr {[file size test.db-wal] < (1 * 1024 * 1024)}
  } 1
  do_test 1.$tn.11.3 {
    db wal_hook wal_hook_callback
    for {set i 0} {$i < 1000} {incr i} {
      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    }
    expr {[file size test.db-wal] < (1 * 1024 * 1024)}
  } 0

  # EVIDENCE-OF: R-33080-59193 Checkpoints initiated by this mechanism 
  # are PASSIVE.
  #
  set ::busy_callback_count 0
  proc busy_callback {args} {
  puts Hello
    incr ::busy_callback_count
    return 0
  }
  do_test 1.$tn.12.1 {
    sqlite3_wal_checkpoint_v2 db truncate
    autocheckpoint db 100 
    db busy busy_callback
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
  } {}
  do_test 1.$tn.12.2 {
    sqlite3 db2 test.db
    db2 eval { BEGIN; SELECT * FROM t1 LIMIT 10; }
    read_nbackfill
  } {0}
  do_test 1.$tn.12.3 {
    for {set i 0} {$i < 1000} {incr i} {
      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    }
    read_nbackfill
  } {2}
  do_test 1.$tn.12.4 {
    set ::busy_callback_count
  } {0}
  db2 close

  do_test 1.$tn.12.5 {
    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    read_nbackfill
  } {1559}

  db close
  close $shmfd
}

finish_test