walmode.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. # 2010 April 19
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library. The
  12. # focus of this file is testing the operation of the library in
  13. # "PRAGMA journal_mode=WAL" mode.
  14. #
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. source $testdir/malloc_common.tcl
  18. # If the library was compiled without WAL support, check that the
  19. # "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode.
  20. #
  21. ifcapable !wal {
  22. do_test walmode-0.1 {
  23. execsql { PRAGMA journal_mode = wal }
  24. } {delete}
  25. do_test walmode-0.2 {
  26. execsql { PRAGMA main.journal_mode = wal }
  27. } {delete}
  28. do_test walmode-0.3 {
  29. execsql { PRAGMA main.journal_mode }
  30. } {delete}
  31. finish_test
  32. return
  33. }
  34. do_test walmode-1.1 {
  35. set sqlite_sync_count 0
  36. execsql { PRAGMA page_size = 1024 }
  37. execsql { PRAGMA journal_mode = wal }
  38. } {wal}
  39. do_test walmode-1.2 {
  40. file size test.db
  41. } {1024}
  42. set expected_sync_count 3
  43. if {$::tcl_platform(platform)!="windows"} {
  44. ifcapable dirsync {
  45. incr expected_sync_count
  46. }
  47. }
  48. do_test walmode-1.3 {
  49. set sqlite_sync_count
  50. } $expected_sync_count
  51. do_test walmode-1.4 {
  52. file exists test.db-wal
  53. } {0}
  54. do_test walmode-1.5 {
  55. execsql { CREATE TABLE t1(a, b) }
  56. file size test.db
  57. } {1024}
  58. do_test walmode-1.6 {
  59. file exists test.db-wal
  60. } {1}
  61. do_test walmode-1.7 {
  62. db close
  63. file exists test.db-wal
  64. } {0}
  65. # There is now a database file with the read and write versions set to 2
  66. # in the file system. This file should default to WAL mode.
  67. #
  68. do_test walmode-2.1 {
  69. sqlite3 db test.db
  70. file exists test.db-wal
  71. } {0}
  72. do_test walmode-2.2 {
  73. execsql { SELECT * FROM sqlite_master }
  74. file exists test.db-wal
  75. } {1}
  76. do_test walmode-2.3 {
  77. db close
  78. file exists test.db-wal
  79. } {0}
  80. # If the first statement executed is "PRAGMA journal_mode = wal", and
  81. # the file is already configured for WAL (read and write versions set
  82. # to 2), then there should be no need to write the database. The
  83. # statement should cause the client to connect to the log file.
  84. #
  85. set sqlite_sync_count 0
  86. do_test walmode-3.1 {
  87. sqlite3 db test.db
  88. execsql { PRAGMA journal_mode = wal }
  89. } {wal}
  90. do_test walmode-3.2 {
  91. list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal]
  92. } {0 1 0}
  93. # Test that changing back to journal_mode=persist works.
  94. #
  95. do_test walmode-4.1 {
  96. execsql { INSERT INTO t1 VALUES(1, 2) }
  97. execsql { PRAGMA journal_mode = persist }
  98. } {persist}
  99. do_test walmode-4.2 {
  100. list [file exists test.db-journal] [file exists test.db-wal]
  101. } {1 0}
  102. do_test walmode-4.3 {
  103. execsql { SELECT * FROM t1 }
  104. } {1 2}
  105. do_test walmode-4.4 {
  106. db close
  107. sqlite3 db test.db
  108. execsql { SELECT * FROM t1 }
  109. } {1 2}
  110. do_test walmode-4.5 {
  111. list [file exists test.db-journal] [file exists test.db-wal]
  112. } {1 0}
  113. # Test that nothing goes wrong if a connection is prevented from changing
  114. # from WAL to rollback mode because a second connection has the database
  115. # open. Or from rollback to WAL.
  116. #
  117. do_test walmode-4.6 {
  118. sqlite3 db2 test.db
  119. execsql { PRAGMA main.journal_mode } db2
  120. } {delete}
  121. do_test walmode-4.7 {
  122. execsql { PRAGMA main.journal_mode = wal } db
  123. } {wal}
  124. do_test walmode-4.8 {
  125. execsql { SELECT * FROM t1 } db2
  126. } {1 2}
  127. do_test walmode-4.9 {
  128. catchsql { PRAGMA journal_mode = delete } db
  129. } {1 {database is locked}}
  130. do_test walmode-4.10 {
  131. execsql { PRAGMA main.journal_mode } db
  132. } {wal}
  133. do_test walmode-4.11 {
  134. db2 close
  135. execsql { PRAGMA journal_mode = delete } db
  136. } {delete}
  137. do_test walmode-4.12 {
  138. execsql { PRAGMA main.journal_mode } db
  139. } {delete}
  140. do_test walmode-4.13 {
  141. list [file exists test.db-journal] [file exists test.db-wal]
  142. } {0 0}
  143. do_test walmode-4.14 {
  144. sqlite3 db2 test.db
  145. execsql {
  146. BEGIN;
  147. SELECT * FROM t1;
  148. } db2
  149. } {1 2}
  150. do_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db } {delete}
  151. do_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete}
  152. do_test walmode-4.17 {
  153. catchsql { PRAGMA main.journal_mode = wal } db
  154. } {1 {database is locked}}
  155. do_test walmode-4.18 {
  156. execsql { PRAGMA main.journal_mode } db
  157. } {delete}
  158. catch { db close }
  159. catch { db2 close }
  160. # Test that it is not possible to change a temporary or in-memory database
  161. # to WAL mode. WAL mode is for persistent file-backed databases only.
  162. #
  163. # walmode-5.1.*: Try to set journal_mode=WAL on [sqlite3 db :memory:] database.
  164. # walmode-5.2.*: Try to set journal_mode=WAL on [sqlite3 db ""] database.
  165. # walmode-5.3.*: Try to set temp.journal_mode=WAL.
  166. #
  167. do_test walmode-5.1.1 {
  168. sqlite3 db :memory:
  169. execsql { PRAGMA main.journal_mode }
  170. } {memory}
  171. do_test walmode-5.1.2 {
  172. execsql { PRAGMA main.journal_mode = wal }
  173. } {memory}
  174. do_test walmode-5.1.3 {
  175. execsql {
  176. BEGIN;
  177. CREATE TABLE t1(a, b);
  178. INSERT INTO t1 VALUES(1, 2);
  179. COMMIT;
  180. SELECT * FROM t1;
  181. PRAGMA main.journal_mode;
  182. }
  183. } {1 2 memory}
  184. do_test walmode-5.1.4 {
  185. execsql { PRAGMA main.journal_mode = wal }
  186. } {memory}
  187. do_test walmode-5.1.5 {
  188. execsql {
  189. INSERT INTO t1 VALUES(3, 4);
  190. SELECT * FROM t1;
  191. PRAGMA main.journal_mode;
  192. }
  193. } {1 2 3 4 memory}
  194. if {$TEMP_STORE>=2} {
  195. set tempJrnlMode memory
  196. } else {
  197. set tempJrnlMode delete
  198. }
  199. do_test walmode-5.2.1 {
  200. sqlite3 db ""
  201. execsql { PRAGMA main.journal_mode }
  202. } $tempJrnlMode
  203. do_test walmode-5.2.2 {
  204. execsql { PRAGMA main.journal_mode = wal }
  205. } $tempJrnlMode
  206. do_test walmode-5.2.3 {
  207. execsql {
  208. BEGIN;
  209. CREATE TABLE t1(a, b);
  210. INSERT INTO t1 VALUES(1, 2);
  211. COMMIT;
  212. SELECT * FROM t1;
  213. PRAGMA main.journal_mode;
  214. }
  215. } [list 1 2 $tempJrnlMode]
  216. do_test walmode-5.2.4 {
  217. execsql { PRAGMA main.journal_mode = wal }
  218. } $tempJrnlMode
  219. do_test walmode-5.2.5 {
  220. execsql {
  221. INSERT INTO t1 VALUES(3, 4);
  222. SELECT * FROM t1;
  223. PRAGMA main.journal_mode;
  224. }
  225. } [list 1 2 3 4 $tempJrnlMode]
  226. do_test walmode-5.3.1 {
  227. sqlite3 db test.db
  228. execsql { PRAGMA temp.journal_mode }
  229. } $tempJrnlMode
  230. do_test walmode-5.3.2 {
  231. execsql { PRAGMA temp.journal_mode = wal }
  232. } $tempJrnlMode
  233. do_test walmode-5.3.3 {
  234. execsql {
  235. BEGIN;
  236. CREATE TEMP TABLE t1(a, b);
  237. INSERT INTO t1 VALUES(1, 2);
  238. COMMIT;
  239. SELECT * FROM t1;
  240. PRAGMA temp.journal_mode;
  241. }
  242. } [list 1 2 $tempJrnlMode]
  243. do_test walmode-5.3.4 {
  244. execsql { PRAGMA temp.journal_mode = wal }
  245. } $tempJrnlMode
  246. do_test walmode-5.3.5 {
  247. execsql {
  248. INSERT INTO t1 VALUES(3, 4);
  249. SELECT * FROM t1;
  250. PRAGMA temp.journal_mode;
  251. }
  252. } [list 1 2 3 4 $tempJrnlMode]
  253. #-------------------------------------------------------------------------
  254. # Test changing to WAL mode from journal_mode=off or journal_mode=memory
  255. #
  256. foreach {tn mode} {
  257. 1 off
  258. 2 memory
  259. 3 persist
  260. 4 delete
  261. 5 truncate
  262. } {
  263. do_test walmode-6.$tn {
  264. faultsim_delete_and_reopen
  265. execsql "
  266. PRAGMA journal_mode = $mode;
  267. PRAGMA journal_mode = wal;
  268. "
  269. } [list $mode wal]
  270. }
  271. db close
  272. #-------------------------------------------------------------------------
  273. # Test the effect of a "PRAGMA journal_mode" command being the first
  274. # thing executed by a new connection. This means that the schema is not
  275. # loaded when sqlite3_prepare_v2() is called to compile the statement.
  276. #
  277. do_test walmode-7.0 {
  278. forcedelete test.db
  279. sqlite3 db test.db
  280. execsql {
  281. PRAGMA journal_mode = WAL;
  282. CREATE TABLE t1(a, b);
  283. }
  284. } {wal}
  285. foreach {tn sql result} {
  286. 1 "PRAGMA journal_mode" wal
  287. 2 "PRAGMA main.journal_mode" wal
  288. 3 "PRAGMA journal_mode = delete" delete
  289. 4 "PRAGMA journal_mode" delete
  290. 5 "PRAGMA main.journal_mode" delete
  291. 6 "PRAGMA journal_mode = wal" wal
  292. 7 "PRAGMA journal_mode" wal
  293. 8 "PRAGMA main.journal_mode" wal
  294. 9 "PRAGMA journal_mode" wal
  295. 10 "PRAGMA main.journal_mode" wal
  296. 11 "PRAGMA main.journal_mode = delete" delete
  297. 12 "PRAGMA journal_mode" delete
  298. 13 "PRAGMA main.journal_mode" delete
  299. 14 "PRAGMA main.journal_mode = wal" wal
  300. 15 "PRAGMA journal_mode" wal
  301. 16 "PRAGMA main.journal_mode" wal
  302. } {
  303. do_test walmode-7.$tn {
  304. db close
  305. sqlite3 db test.db
  306. execsql $sql
  307. } $result
  308. }
  309. db close
  310. #-------------------------------------------------------------------------
  311. # Test the effect of a "PRAGMA journal_mode" command on an attached
  312. # database.
  313. #
  314. faultsim_delete_and_reopen
  315. do_execsql_test walmode-8.1 {
  316. CREATE TABLE t1(a, b);
  317. PRAGMA journal_mode = WAL;
  318. ATTACH 'test.db2' AS two;
  319. CREATE TABLE two.t2(a, b);
  320. } {wal}
  321. do_execsql_test walmode-8.2 { PRAGMA main.journal_mode } {wal}
  322. do_execsql_test walmode-8.3 { PRAGMA two.journal_mode } {delete}
  323. do_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete}
  324. db close
  325. sqlite3 db test.db
  326. do_execsql_test walmode-8.5 { ATTACH 'test.db2' AS two } {}
  327. do_execsql_test walmode-8.6 { PRAGMA main.journal_mode } {wal}
  328. do_execsql_test walmode-8.7 { PRAGMA two.journal_mode } {delete}
  329. do_execsql_test walmode-8.8 { INSERT INTO two.t2 DEFAULT VALUES } {}
  330. do_execsql_test walmode-8.9 { PRAGMA two.journal_mode } {delete}
  331. do_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {}
  332. do_execsql_test walmode-8.11 { PRAGMA main.journal_mode } {wal}
  333. do_execsql_test walmode-8.12 { PRAGMA journal_mode } {wal}
  334. # Change to WAL mode on test2.db and make sure (in the tests that follow)
  335. # that this mode change persists.
  336. do_test walmode-8.x1 {
  337. execsql {
  338. PRAGMA two.journal_mode=WAL;
  339. PRAGMA two.journal_mode;
  340. }
  341. } {wal wal}
  342. db close
  343. sqlite3 db test.db
  344. do_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL } {wal}
  345. do_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two } {}
  346. do_execsql_test walmode-8.15 { PRAGMA main.journal_mode } {wal}
  347. do_execsql_test walmode-8.16 { PRAGMA two.journal_mode } {wal}
  348. do_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {}
  349. do_execsql_test walmode-8.18 { PRAGMA two.journal_mode } {wal}
  350. sqlite3 db2 test.db2
  351. do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 } {wal}
  352. db2 close
  353. do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
  354. do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {delete}
  355. do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {delete}
  356. do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL } {wal}
  357. do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {wal}
  358. do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {wal}
  359. finish_test