memdb.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. # 2001 September 15
  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 script is in-memory database backend.
  13. #
  14. # $Id: memdb.test,v 1.19 2009/05/18 16:04:38 danielk1977 Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. ifcapable memorydb {
  18. # In the following sequence of tests, compute the MD5 sum of the content
  19. # of a table, make lots of modifications to that table, then do a rollback.
  20. # Verify that after the rollback, the MD5 checksum is unchanged.
  21. #
  22. # These tests were browed from trans.tcl.
  23. #
  24. do_test memdb-1.1 {
  25. db close
  26. sqlite3 db :memory:
  27. # sqlite3 db test.db
  28. execsql {
  29. BEGIN;
  30. CREATE TABLE t3(x TEXT);
  31. INSERT INTO t3 VALUES(randstr(10,400));
  32. INSERT INTO t3 VALUES(randstr(10,400));
  33. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  34. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  35. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  36. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  37. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  38. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  39. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  40. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  41. INSERT INTO t3 SELECT randstr(10,400) FROM t3;
  42. COMMIT;
  43. SELECT count(*) FROM t3;
  44. }
  45. } {1024}
  46. # The following procedure computes a "signature" for table "t3". If
  47. # T3 changes in any way, the signature should change.
  48. #
  49. # This is used to test ROLLBACK. We gather a signature for t3, then
  50. # make lots of changes to t3, then rollback and take another signature.
  51. # The two signatures should be the same.
  52. #
  53. proc signature {{fn {}}} {
  54. set rx [db eval {SELECT x FROM t3}]
  55. # set r1 [md5 $rx\n]
  56. if {$fn!=""} {
  57. # set fd [open $fn w]
  58. # puts $fd $rx
  59. # close $fd
  60. }
  61. # set r [db eval {SELECT count(*), md5sum(x) FROM t3}]
  62. # puts "SIG($fn)=$r1"
  63. return [list [string length $rx] $rx]
  64. }
  65. # Do rollbacks. Make sure the signature does not change.
  66. #
  67. set limit 10
  68. for {set i 2} {$i<=$limit} {incr i} {
  69. set ::sig [signature one]
  70. # puts "sig=$sig"
  71. set cnt [lindex $::sig 0]
  72. if {$i%2==0} {
  73. execsql {PRAGMA synchronous=FULL}
  74. } else {
  75. execsql {PRAGMA synchronous=NORMAL}
  76. }
  77. do_test memdb-1.$i.1-$cnt {
  78. execsql {
  79. BEGIN;
  80. DELETE FROM t3 WHERE random()%10!=0;
  81. INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
  82. INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
  83. ROLLBACK;
  84. }
  85. set sig2 [signature two]
  86. } $sig
  87. # puts "sig2=$sig2"
  88. # if {$sig2!=$sig} exit
  89. do_test memdb-1.$i.2-$cnt {
  90. execsql {
  91. BEGIN;
  92. DELETE FROM t3 WHERE random()%10!=0;
  93. INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
  94. DELETE FROM t3 WHERE random()%10!=0;
  95. INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
  96. ROLLBACK;
  97. }
  98. signature
  99. } $sig
  100. if {$i<$limit} {
  101. do_test memdb-1.$i.9-$cnt {
  102. execsql {
  103. INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
  104. }
  105. } {}
  106. }
  107. set ::pager_old_format 0
  108. }
  109. integrity_check memdb-2.1
  110. do_test memdb-3.1 {
  111. execsql {
  112. CREATE TABLE t4(a,b,c,d);
  113. BEGIN;
  114. INSERT INTO t4 VALUES(1,2,3,4);
  115. SELECT * FROM t4;
  116. }
  117. } {1 2 3 4}
  118. do_test memdb-3.2 {
  119. execsql {
  120. SELECT name FROM sqlite_master WHERE type='table';
  121. }
  122. } {t3 t4}
  123. do_test memdb-3.3 {
  124. execsql {
  125. DROP TABLE t4;
  126. SELECT name FROM sqlite_master WHERE type='table';
  127. }
  128. } {t3}
  129. do_test memdb-3.4 {
  130. execsql {
  131. ROLLBACK;
  132. SELECT name FROM sqlite_master WHERE type='table';
  133. }
  134. } {t3 t4}
  135. # Create tables for the first group of tests.
  136. #
  137. do_test memdb-4.0 {
  138. execsql {
  139. CREATE TABLE t1(a, b, c, UNIQUE(a,b));
  140. CREATE TABLE t2(x);
  141. SELECT c FROM t1 ORDER BY c;
  142. }
  143. } {}
  144. # Six columns of configuration data as follows:
  145. #
  146. # i The reference number of the test
  147. # conf The conflict resolution algorithm on the BEGIN statement
  148. # cmd An INSERT or REPLACE command to execute against table t1
  149. # t0 True if there is an error from $cmd
  150. # t1 Content of "c" column of t1 assuming no error in $cmd
  151. # t2 Content of "x" column of t2
  152. #
  153. foreach {i conf cmd t0 t1 t2} {
  154. 1 {} INSERT 1 {} 1
  155. 2 {} {INSERT OR IGNORE} 0 3 1
  156. 3 {} {INSERT OR REPLACE} 0 4 1
  157. 4 {} REPLACE 0 4 1
  158. 5 {} {INSERT OR FAIL} 1 {} 1
  159. 6 {} {INSERT OR ABORT} 1 {} 1
  160. 7 {} {INSERT OR ROLLBACK} 1 {} {}
  161. } {
  162. # All tests after test 1 depend on conflict resolution. So end the
  163. # loop if that is not available in this build.
  164. ifcapable !conflict {if {$i>1} break}
  165. do_test memdb-4.$i {
  166. if {$conf!=""} {set conf "ON CONFLICT $conf"}
  167. set r0 [catch {execsql [subst {
  168. DELETE FROM t1;
  169. DELETE FROM t2;
  170. INSERT INTO t1 VALUES(1,2,3);
  171. BEGIN $conf;
  172. INSERT INTO t2 VALUES(1);
  173. $cmd INTO t1 VALUES(1,2,4);
  174. }]} r1]
  175. catch {execsql {COMMIT}}
  176. if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
  177. set r2 [execsql {SELECT x FROM t2}]
  178. list $r0 $r1 $r2
  179. } [list $t0 $t1 $t2]
  180. }
  181. do_test memdb-5.0 {
  182. execsql {
  183. DROP TABLE t2;
  184. DROP TABLE t3;
  185. CREATE TABLE t2(a,b,c);
  186. INSERT INTO t2 VALUES(1,2,1);
  187. INSERT INTO t2 VALUES(2,3,2);
  188. INSERT INTO t2 VALUES(3,4,1);
  189. INSERT INTO t2 VALUES(4,5,4);
  190. SELECT c FROM t2 ORDER BY b;
  191. CREATE TABLE t3(x);
  192. INSERT INTO t3 VALUES(1);
  193. }
  194. } {1 2 1 4}
  195. # Six columns of configuration data as follows:
  196. #
  197. # i The reference number of the test
  198. # conf1 The conflict resolution algorithm on the UNIQUE constraint
  199. # conf2 The conflict resolution algorithm on the BEGIN statement
  200. # cmd An UPDATE command to execute against table t1
  201. # t0 True if there is an error from $cmd
  202. # t1 Content of "b" column of t1 assuming no error in $cmd
  203. # t2 Content of "x" column of t3
  204. #
  205. foreach {i conf1 conf2 cmd t0 t1 t2} {
  206. 1 {} {} UPDATE 1 {6 7 8 9} 1
  207. 2 REPLACE {} UPDATE 0 {7 6 9} 1
  208. 3 IGNORE {} UPDATE 0 {6 7 3 9} 1
  209. 4 FAIL {} UPDATE 1 {6 7 3 4} 1
  210. 5 ABORT {} UPDATE 1 {1 2 3 4} 1
  211. 6 ROLLBACK {} UPDATE 1 {1 2 3 4} 0
  212. 7 REPLACE {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
  213. 8 IGNORE {} {UPDATE OR REPLACE} 0 {7 6 9} 1
  214. 9 FAIL {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
  215. 10 ABORT {} {UPDATE OR REPLACE} 0 {7 6 9} 1
  216. 11 ROLLBACK {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
  217. 12 {} {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
  218. 13 {} {} {UPDATE OR REPLACE} 0 {7 6 9} 1
  219. 14 {} {} {UPDATE OR FAIL} 1 {6 7 3 4} 1
  220. 15 {} {} {UPDATE OR ABORT} 1 {1 2 3 4} 1
  221. 16 {} {} {UPDATE OR ROLLBACK} 1 {1 2 3 4} 0
  222. } {
  223. # All tests after test 1 depend on conflict resolution. So end the
  224. # loop if that is not available in this build.
  225. ifcapable !conflict {
  226. if {$i>1} break
  227. }
  228. if {$t0} {set t1 {column a is not unique}}
  229. do_test memdb-5.$i {
  230. if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
  231. if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
  232. set r0 [catch {execsql "
  233. DROP TABLE t1;
  234. CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
  235. INSERT INTO t1 SELECT * FROM t2;
  236. UPDATE t3 SET x=0;
  237. BEGIN $conf2;
  238. $cmd t3 SET x=1;
  239. $cmd t1 SET b=b*2;
  240. $cmd t1 SET a=c+5;
  241. "} r1]
  242. catch {execsql {COMMIT}}
  243. if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
  244. set r2 [execsql {SELECT x FROM t3}]
  245. list $r0 $r1 $r2
  246. } [list $t0 $t1 $t2]
  247. }
  248. do_test memdb-6.1 {
  249. execsql {
  250. SELECT * FROM t2;
  251. }
  252. } {1 2 1 2 3 2 3 4 1 4 5 4}
  253. do_test memdb-6.2 {
  254. execsql {
  255. BEGIN;
  256. DROP TABLE t2;
  257. SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
  258. }
  259. } {t1 t3 t4}
  260. do_test memdb-6.3 {
  261. execsql {
  262. ROLLBACK;
  263. SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
  264. }
  265. } {t1 t2 t3 t4}
  266. do_test memdb-6.4 {
  267. execsql {
  268. SELECT * FROM t2;
  269. }
  270. } {1 2 1 2 3 2 3 4 1 4 5 4}
  271. ifcapable compound {
  272. do_test memdb-6.5 {
  273. execsql {
  274. SELECT a FROM t2 UNION SELECT b FROM t2 ORDER BY 1;
  275. }
  276. } {1 2 3 4 5}
  277. } ;# ifcapable compound
  278. do_test memdb-6.6 {
  279. execsql {
  280. CREATE INDEX i2 ON t2(c);
  281. SELECT a FROM t2 ORDER BY c;
  282. }
  283. } {1 3 2 4}
  284. do_test memdb-6.6 {
  285. execsql {
  286. SELECT a FROM t2 ORDER BY c DESC;
  287. }
  288. } {4 2 3 1}
  289. do_test memdb-6.7 {
  290. execsql {
  291. BEGIN;
  292. CREATE TABLE t5(x,y);
  293. INSERT INTO t5 VALUES(1,2);
  294. SELECT * FROM t5;
  295. }
  296. } {1 2}
  297. do_test memdb-6.8 {
  298. execsql {
  299. SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
  300. }
  301. } {t1 t2 t3 t4 t5}
  302. do_test memdb-6.9 {
  303. execsql {
  304. ROLLBACK;
  305. SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
  306. }
  307. } {t1 t2 t3 t4}
  308. do_test memdb-6.10 {
  309. execsql {
  310. CREATE TABLE t5(x PRIMARY KEY, y UNIQUE);
  311. SELECT * FROM t5;
  312. }
  313. } {}
  314. do_test memdb-6.11 {
  315. execsql {
  316. SELECT * FROM t5 ORDER BY y DESC;
  317. }
  318. } {}
  319. ifcapable conflict {
  320. do_test memdb-6.12 {
  321. execsql {
  322. INSERT INTO t5 VALUES(1,2);
  323. INSERT INTO t5 VALUES(3,4);
  324. REPLACE INTO t5 VALUES(1,4);
  325. SELECT rowid,* FROM t5;
  326. }
  327. } {3 1 4}
  328. do_test memdb-6.13 {
  329. execsql {
  330. DELETE FROM t5 WHERE x>5;
  331. SELECT * FROM t5;
  332. }
  333. } {1 4}
  334. do_test memdb-6.14 {
  335. execsql {
  336. DELETE FROM t5 WHERE y<3;
  337. SELECT * FROM t5;
  338. }
  339. } {1 4}
  340. }
  341. do_test memdb-6.15 {
  342. execsql {
  343. DELETE FROM t5 WHERE x>0;
  344. SELECT * FROM t5;
  345. }
  346. } {}
  347. ifcapable subquery&&vtab {
  348. do_test memdb-7.1 {
  349. load_static_extension db wholenumber
  350. execsql {
  351. CREATE TABLE t6(x);
  352. CREATE VIRTUAL TABLE nums USING wholenumber;
  353. INSERT INTO t6 SELECT value FROM nums WHERE value BETWEEN 1 AND 256;
  354. SELECT count(*) FROM (SELECT DISTINCT x FROM t6);
  355. }
  356. } {256}
  357. for {set i 1} {$i<=256} {incr i} {
  358. do_test memdb-7.2.$i {
  359. execsql "DELETE FROM t6 WHERE x=\
  360. (SELECT x FROM t6 ORDER BY random() LIMIT 1)"
  361. execsql {SELECT count(*) FROM t6}
  362. } [expr {256-$i}]
  363. }
  364. }
  365. # Ticket #1524
  366. #
  367. do_test memdb-8.1 {
  368. db close
  369. sqlite3 db {:memory:}
  370. execsql {
  371. PRAGMA auto_vacuum=TRUE;
  372. CREATE TABLE t1(a);
  373. INSERT INTO t1 VALUES(randstr(5000,6000));
  374. INSERT INTO t1 VALUES(randstr(5000,6000));
  375. INSERT INTO t1 VALUES(randstr(5000,6000));
  376. INSERT INTO t1 VALUES(randstr(5000,6000));
  377. INSERT INTO t1 VALUES(randstr(5000,6000));
  378. SELECT count(*) FROM t1;
  379. }
  380. } 5
  381. do_test memdb-8.2 {
  382. execsql {
  383. DELETE FROM t1;
  384. SELECT count(*) FROM t1;
  385. }
  386. } 0
  387. # Test that auto-vacuum works with in-memory databases.
  388. #
  389. ifcapable autovacuum {
  390. do_test memdb-9.1 {
  391. db close
  392. sqlite3 db test.db
  393. db cache size 0
  394. execsql {
  395. PRAGMA auto_vacuum = full;
  396. CREATE TABLE t1(a);
  397. INSERT INTO t1 VALUES(randstr(1000,1000));
  398. INSERT INTO t1 VALUES(randstr(1000,1000));
  399. INSERT INTO t1 VALUES(randstr(1000,1000));
  400. }
  401. set memused [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  402. set pgovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 1]
  403. execsql { DELETE FROM t1 }
  404. set memused2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  405. expr {($memused2 + 2048 < $memused) || $pgovfl==0}
  406. } {1}
  407. }
  408. } ;# ifcapable memorydb
  409. finish_test