1
0

autovacuum.test 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  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 file is testing the SELECT statement.
  13. #
  14. # $Id: autovacuum.test,v 1.29 2009/04/06 17:50:03 danielk1977 Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. # If this build of the library does not support auto-vacuum, omit this
  18. # whole file.
  19. ifcapable {!autovacuum || !pragma} {
  20. finish_test
  21. return
  22. }
  23. # Return a string $len characters long. The returned string is $char repeated
  24. # over and over. For example, [make_str abc 8] returns "abcabcab".
  25. proc make_str {char len} {
  26. set str [string repeat $char. $len]
  27. return [string range $str 0 [expr $len-1]]
  28. }
  29. # Return the number of pages in the file test.db by looking at the file system.
  30. proc file_pages {} {
  31. return [expr [file size test.db] / 1024]
  32. }
  33. #-------------------------------------------------------------------------
  34. # Test cases autovacuum-1.* work as follows:
  35. #
  36. # 1. A table with a single indexed field is created.
  37. # 2. Approximately 20 rows are inserted into the table. Each row is long
  38. # enough such that it uses at least 2 overflow pages for both the table
  39. # and index entry.
  40. # 3. The rows are deleted in a psuedo-random order. Sometimes only one row
  41. # is deleted per transaction, sometimes more than one.
  42. # 4. After each transaction the table data is checked to ensure it is correct
  43. # and a "PRAGMA integrity_check" is executed.
  44. # 5. Once all the rows are deleted the file is checked to make sure it
  45. # consists of exactly 4 pages.
  46. #
  47. # Steps 2-5 are repeated for a few different psuedo-random delete patterns
  48. # (defined by the $delete_orders list).
  49. set delete_orders [list]
  50. lappend delete_orders {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}
  51. lappend delete_orders {20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
  52. lappend delete_orders {8 18 2 4 14 11 13 3 10 7 9 5 12 17 19 15 20 6 16 1}
  53. lappend delete_orders {10 3 11 17 19 20 7 4 13 6 1 14 16 12 9 18 8 15 5 2}
  54. lappend delete_orders {{1 2 3 4 5 6 7 8 9 10} {11 12 13 14 15 16 17 18 19 20}}
  55. lappend delete_orders {{19 8 17 15} {16 11 9 14} {18 5 3 1} {13 20 7 2} {6 12}}
  56. # The length of each table entry.
  57. # set ENTRY_LEN 3500
  58. set ENTRY_LEN 3500
  59. do_test autovacuum-1.1 {
  60. execsql {
  61. PRAGMA auto_vacuum = 1;
  62. CREATE TABLE av1(a);
  63. CREATE INDEX av1_idx ON av1(a);
  64. }
  65. } {}
  66. set tn 0
  67. foreach delete_order $delete_orders {
  68. incr tn
  69. # Set up the table.
  70. set ::tbl_data [list]
  71. foreach i [lsort -integer [eval concat $delete_order]] {
  72. execsql "INSERT INTO av1 (oid, a) VALUES($i, '[make_str $i $ENTRY_LEN]')"
  73. lappend ::tbl_data [make_str $i $ENTRY_LEN]
  74. }
  75. # Make sure the integrity check passes with the initial data.
  76. ifcapable {integrityck} {
  77. do_test autovacuum-1.$tn.1 {
  78. execsql {
  79. pragma integrity_check
  80. }
  81. } {ok}
  82. }
  83. foreach delete $delete_order {
  84. # Delete one set of rows from the table.
  85. do_test autovacuum-1.$tn.($delete).1 {
  86. execsql "
  87. DELETE FROM av1 WHERE oid = [join $delete " OR oid = "]
  88. "
  89. } {}
  90. # Do the integrity check.
  91. ifcapable {integrityck} {
  92. do_test autovacuum-1.$tn.($delete).2 {
  93. execsql {
  94. pragma integrity_check
  95. }
  96. } {ok}
  97. }
  98. # Ensure the data remaining in the table is what was expected.
  99. foreach d $delete {
  100. set idx [lsearch $::tbl_data [make_str $d $ENTRY_LEN]]
  101. set ::tbl_data [lreplace $::tbl_data $idx $idx]
  102. }
  103. do_test autovacuum-1.$tn.($delete).3 {
  104. execsql {
  105. select a from av1 order by rowid
  106. }
  107. } $::tbl_data
  108. }
  109. # All rows have been deleted. Ensure the file has shrunk to 4 pages.
  110. do_test autovacuum-1.$tn.3 {
  111. file_pages
  112. } {4}
  113. }
  114. #---------------------------------------------------------------------------
  115. # Tests cases autovacuum-2.* test that root pages are allocated
  116. # and deallocated correctly at the start of the file. Operation is roughly as
  117. # follows:
  118. #
  119. # autovacuum-2.1.*: Drop the tables that currently exist in the database.
  120. # autovacuum-2.2.*: Create some tables. Ensure that data pages can be
  121. # moved correctly to make space for new root-pages.
  122. # autovacuum-2.3.*: Drop one of the tables just created (not the last one),
  123. # and check that one of the other tables is moved to
  124. # the free root-page location.
  125. # autovacuum-2.4.*: Check that a table can be created correctly when the
  126. # root-page it requires is on the free-list.
  127. # autovacuum-2.5.*: Check that a table with indices can be dropped. This
  128. # is slightly tricky because dropping one of the
  129. # indices/table btrees could move the root-page of another.
  130. # The code-generation layer of SQLite overcomes this problem
  131. # by dropping the btrees in descending order of root-pages.
  132. # This test ensures that this actually happens.
  133. #
  134. do_test autovacuum-2.1.1 {
  135. execsql {
  136. DROP TABLE av1;
  137. }
  138. } {}
  139. do_test autovacuum-2.1.2 {
  140. file_pages
  141. } {1}
  142. # Create a table and put some data in it.
  143. do_test autovacuum-2.2.1 {
  144. execsql {
  145. CREATE TABLE av1(x);
  146. SELECT rootpage FROM sqlite_master ORDER BY rootpage;
  147. }
  148. } {3}
  149. do_test autovacuum-2.2.2 {
  150. execsql "
  151. INSERT INTO av1 VALUES('[make_str abc 3000]');
  152. INSERT INTO av1 VALUES('[make_str def 3000]');
  153. INSERT INTO av1 VALUES('[make_str ghi 3000]');
  154. INSERT INTO av1 VALUES('[make_str jkl 3000]');
  155. "
  156. set ::av1_data [db eval {select * from av1}]
  157. file_pages
  158. } {15}
  159. # Create another table. Check it is located immediately after the first.
  160. # This test case moves the second page in an over-flow chain.
  161. do_test autovacuum-2.2.3 {
  162. execsql {
  163. CREATE TABLE av2(x);
  164. SELECT rootpage FROM sqlite_master ORDER BY rootpage;
  165. }
  166. } {3 4}
  167. do_test autovacuum-2.2.4 {
  168. file_pages
  169. } {16}
  170. # Create another table. Check it is located immediately after the second.
  171. # This test case moves the first page in an over-flow chain.
  172. do_test autovacuum-2.2.5 {
  173. execsql {
  174. CREATE TABLE av3(x);
  175. SELECT rootpage FROM sqlite_master ORDER BY rootpage;
  176. }
  177. } {3 4 5}
  178. do_test autovacuum-2.2.6 {
  179. file_pages
  180. } {17}
  181. # Create another table. Check it is located immediately after the second.
  182. # This test case moves a btree leaf page.
  183. do_test autovacuum-2.2.7 {
  184. execsql {
  185. CREATE TABLE av4(x);
  186. SELECT rootpage FROM sqlite_master ORDER BY rootpage;
  187. }
  188. } {3 4 5 6}
  189. do_test autovacuum-2.2.8 {
  190. file_pages
  191. } {18}
  192. do_test autovacuum-2.2.9 {
  193. execsql {
  194. select * from av1
  195. }
  196. } $av1_data
  197. do_test autovacuum-2.3.1 {
  198. execsql {
  199. INSERT INTO av2 SELECT 'av1' || x FROM av1;
  200. INSERT INTO av3 SELECT 'av2' || x FROM av1;
  201. INSERT INTO av4 SELECT 'av3' || x FROM av1;
  202. }
  203. set ::av2_data [execsql {select x from av2}]
  204. set ::av3_data [execsql {select x from av3}]
  205. set ::av4_data [execsql {select x from av4}]
  206. file_pages
  207. } {54}
  208. do_test autovacuum-2.3.2 {
  209. execsql {
  210. DROP TABLE av2;
  211. SELECT rootpage FROM sqlite_master ORDER BY rootpage;
  212. }
  213. } {3 4 5}
  214. do_test autovacuum-2.3.3 {
  215. file_pages
  216. } {41}
  217. do_test autovacuum-2.3.4 {
  218. execsql {
  219. SELECT x FROM av3;
  220. }
  221. } $::av3_data
  222. do_test autovacuum-2.3.5 {
  223. execsql {
  224. SELECT x FROM av4;
  225. }
  226. } $::av4_data
  227. # Drop all the tables in the file. This puts all pages except the first 2
  228. # (the sqlite_master root-page and the first pointer map page) on the
  229. # free-list.
  230. do_test autovacuum-2.4.1 {
  231. execsql {
  232. DROP TABLE av1;
  233. DROP TABLE av3;
  234. BEGIN;
  235. DROP TABLE av4;
  236. }
  237. file_pages
  238. } {15}
  239. do_test autovacuum-2.4.2 {
  240. for {set i 3} {$i<=10} {incr i} {
  241. execsql "CREATE TABLE av$i (x)"
  242. }
  243. file_pages
  244. } {15}
  245. do_test autovacuum-2.4.3 {
  246. execsql {
  247. SELECT rootpage FROM sqlite_master ORDER by rootpage
  248. }
  249. } {3 4 5 6 7 8 9 10}
  250. # Right now there are 5 free pages in the database. Consume and then free
  251. # a 520 pages. Then create 520 tables. This ensures that at least some of the
  252. # desired root-pages reside on the second free-list trunk page, and that the
  253. # trunk itself is required at some point.
  254. do_test autovacuum-2.4.4 {
  255. execsql "
  256. INSERT INTO av3 VALUES ('[make_str abcde [expr 1020*520 + 500]]');
  257. DELETE FROM av3;
  258. "
  259. } {}
  260. set root_page_list [list]
  261. set pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1]
  262. for {set i 3} {$i<=532} {incr i} {
  263. # 207 and 412 are pointer-map pages.
  264. if { $i!=207 && $i!=412 && $i != $pending_byte_page} {
  265. lappend root_page_list $i
  266. }
  267. }
  268. if {$i >= $pending_byte_page} {
  269. lappend root_page_list $i
  270. }
  271. do_test autovacuum-2.4.5 {
  272. for {set i 11} {$i<=530} {incr i} {
  273. execsql "CREATE TABLE av$i (x)"
  274. }
  275. execsql {
  276. SELECT rootpage FROM sqlite_master ORDER by rootpage
  277. }
  278. } $root_page_list
  279. # Just for fun, delete all those tables and see if the database is 1 page.
  280. do_test autovacuum-2.4.6 {
  281. execsql COMMIT;
  282. file_pages
  283. } [expr 561 + (($i >= $pending_byte_page)?1:0)]
  284. integrity_check autovacuum-2.4.6
  285. do_test autovacuum-2.4.7 {
  286. execsql BEGIN
  287. for {set i 3} {$i<=530} {incr i} {
  288. execsql "DROP TABLE av$i"
  289. }
  290. execsql COMMIT
  291. file_pages
  292. } 1
  293. # Create some tables with indices to drop.
  294. do_test autovacuum-2.5.1 {
  295. execsql {
  296. CREATE TABLE av1(a PRIMARY KEY, b, c);
  297. INSERT INTO av1 VALUES('av1 a', 'av1 b', 'av1 c');
  298. CREATE TABLE av2(a PRIMARY KEY, b, c);
  299. CREATE INDEX av2_i1 ON av2(b);
  300. CREATE INDEX av2_i2 ON av2(c);
  301. INSERT INTO av2 VALUES('av2 a', 'av2 b', 'av2 c');
  302. CREATE TABLE av3(a PRIMARY KEY, b, c);
  303. CREATE INDEX av3_i1 ON av3(b);
  304. INSERT INTO av3 VALUES('av3 a', 'av3 b', 'av3 c');
  305. CREATE TABLE av4(a, b, c);
  306. CREATE INDEX av4_i1 ON av4(a);
  307. CREATE INDEX av4_i2 ON av4(b);
  308. CREATE INDEX av4_i3 ON av4(c);
  309. CREATE INDEX av4_i4 ON av4(a, b, c);
  310. INSERT INTO av4 VALUES('av4 a', 'av4 b', 'av4 c');
  311. }
  312. } {}
  313. do_test autovacuum-2.5.2 {
  314. execsql {
  315. SELECT name, rootpage FROM sqlite_master;
  316. }
  317. } [list av1 3 sqlite_autoindex_av1_1 4 \
  318. av2 5 sqlite_autoindex_av2_1 6 av2_i1 7 av2_i2 8 \
  319. av3 9 sqlite_autoindex_av3_1 10 av3_i1 11 \
  320. av4 12 av4_i1 13 av4_i2 14 av4_i3 15 av4_i4 16 \
  321. ]
  322. # The following 4 tests are SELECT queries that use the indices created.
  323. # If the root-pages in the internal schema are not updated correctly when
  324. # a table or indice is moved, these queries will fail. They are repeated
  325. # after each table is dropped (i.e. as test cases 2.5.*.[1..4]).
  326. do_test autovacuum-2.5.2.1 {
  327. execsql {
  328. SELECT * FROM av1 WHERE a = 'av1 a';
  329. }
  330. } {{av1 a} {av1 b} {av1 c}}
  331. do_test autovacuum-2.5.2.2 {
  332. execsql {
  333. SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  334. }
  335. } {{av2 a} {av2 b} {av2 c}}
  336. do_test autovacuum-2.5.2.3 {
  337. execsql {
  338. SELECT * FROM av3 WHERE a = 'av3 a' AND b = 'av3 b';
  339. }
  340. } {{av3 a} {av3 b} {av3 c}}
  341. do_test autovacuum-2.5.2.4 {
  342. execsql {
  343. SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  344. }
  345. } {{av4 a} {av4 b} {av4 c}}
  346. # Drop table av3. Indices av4_i2, av4_i3 and av4_i4 are moved to fill the two
  347. # root pages vacated. The operation proceeds as:
  348. # Step 1: Delete av3_i1 (root-page 11). Move root-page of av4_i4 to page 11.
  349. # Step 2: Delete av3 (root-page 10). Move root-page of av4_i3 to page 10.
  350. # Step 3: Delete sqlite_autoindex_av1_3 (root-page 9). Move av4_i2 to page 9.
  351. do_test autovacuum-2.5.3 {
  352. execsql {
  353. DROP TABLE av3;
  354. SELECT name, rootpage FROM sqlite_master;
  355. }
  356. } [list av1 3 sqlite_autoindex_av1_1 4 \
  357. av2 5 sqlite_autoindex_av2_1 6 av2_i1 7 av2_i2 8 \
  358. av4 12 av4_i1 13 av4_i2 9 av4_i3 10 av4_i4 11 \
  359. ]
  360. do_test autovacuum-2.5.3.1 {
  361. execsql {
  362. SELECT * FROM av1 WHERE a = 'av1 a';
  363. }
  364. } {{av1 a} {av1 b} {av1 c}}
  365. do_test autovacuum-2.5.3.2 {
  366. execsql {
  367. SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  368. }
  369. } {{av2 a} {av2 b} {av2 c}}
  370. do_test autovacuum-2.5.3.3 {
  371. execsql {
  372. SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  373. }
  374. } {{av4 a} {av4 b} {av4 c}}
  375. # Drop table av1:
  376. # Step 1: Delete av1 (root page 4). Root-page of av4_i1 fills the gap.
  377. # Step 2: Delete sqlite_autoindex_av1_1 (root page 3). Move av4 to the gap.
  378. do_test autovacuum-2.5.4 {
  379. execsql {
  380. DROP TABLE av1;
  381. SELECT name, rootpage FROM sqlite_master;
  382. }
  383. } [list av2 5 sqlite_autoindex_av2_1 6 av2_i1 7 av2_i2 8 \
  384. av4 3 av4_i1 4 av4_i2 9 av4_i3 10 av4_i4 11 \
  385. ]
  386. do_test autovacuum-2.5.4.2 {
  387. execsql {
  388. SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  389. }
  390. } {{av2 a} {av2 b} {av2 c}}
  391. do_test autovacuum-2.5.4.4 {
  392. execsql {
  393. SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  394. }
  395. } {{av4 a} {av4 b} {av4 c}}
  396. # Drop table av4:
  397. # Step 1: Delete av4_i4.
  398. # Step 2: Delete av4_i3.
  399. # Step 3: Delete av4_i2.
  400. # Step 4: Delete av4_i1. av2_i2 replaces it.
  401. # Step 5: Delete av4. av2_i1 replaces it.
  402. do_test autovacuum-2.5.5 {
  403. execsql {
  404. DROP TABLE av4;
  405. SELECT name, rootpage FROM sqlite_master;
  406. }
  407. } [list av2 5 sqlite_autoindex_av2_1 6 av2_i1 3 av2_i2 4]
  408. do_test autovacuum-2.5.5.2 {
  409. execsql {
  410. SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  411. }
  412. } {{av2 a} {av2 b} {av2 c}}
  413. #--------------------------------------------------------------------------
  414. # Test cases autovacuum-3.* test the operation of the "PRAGMA auto_vacuum"
  415. # command.
  416. #
  417. do_test autovacuum-3.1 {
  418. execsql {
  419. PRAGMA auto_vacuum;
  420. }
  421. } {1}
  422. do_test autovacuum-3.2 {
  423. db close
  424. sqlite3 db test.db
  425. execsql {
  426. PRAGMA auto_vacuum;
  427. }
  428. } {1}
  429. do_test autovacuum-3.3 {
  430. execsql {
  431. PRAGMA auto_vacuum = 0;
  432. PRAGMA auto_vacuum;
  433. }
  434. } {1}
  435. do_test autovacuum-3.4 {
  436. db close
  437. forcedelete test.db
  438. sqlite3 db test.db
  439. execsql {
  440. PRAGMA auto_vacuum;
  441. }
  442. } $AUTOVACUUM
  443. do_test autovacuum-3.5 {
  444. execsql {
  445. CREATE TABLE av1(x);
  446. PRAGMA auto_vacuum;
  447. }
  448. } $AUTOVACUUM
  449. do_test autovacuum-3.6 {
  450. execsql {
  451. PRAGMA auto_vacuum = 1;
  452. PRAGMA auto_vacuum;
  453. }
  454. } [expr $AUTOVACUUM ? 1 : 0]
  455. do_test autovacuum-3.7 {
  456. execsql {
  457. DROP TABLE av1;
  458. }
  459. file_pages
  460. } [expr $AUTOVACUUM?1:2]
  461. #-----------------------------------------------------------------------
  462. # Test that if a statement transaction around a CREATE INDEX statement is
  463. # rolled back no corruption occurs.
  464. #
  465. do_test autovacuum-4.0 {
  466. # The last round of tests may have left the db in non-autovacuum mode.
  467. # Reset everything just in case.
  468. #
  469. db close
  470. forcedelete test.db test.db-journal
  471. sqlite3 db test.db
  472. execsql {
  473. PRAGMA auto_vacuum = 1;
  474. PRAGMA auto_vacuum;
  475. }
  476. } {1}
  477. do_test autovacuum-4.1 {
  478. execsql {
  479. CREATE TABLE av1(a, b);
  480. BEGIN;
  481. }
  482. for {set i 0} {$i<100} {incr i} {
  483. execsql "INSERT INTO av1 VALUES($i, '[string repeat X 200]');"
  484. }
  485. execsql "INSERT INTO av1 VALUES(99, '[string repeat X 200]');"
  486. execsql {
  487. SELECT sum(a) FROM av1;
  488. }
  489. } {5049}
  490. do_test autovacuum-4.2 {
  491. catchsql {
  492. CREATE UNIQUE INDEX av1_i ON av1(a);
  493. }
  494. } {1 {indexed columns are not unique}}
  495. do_test autovacuum-4.3 {
  496. execsql {
  497. SELECT sum(a) FROM av1;
  498. }
  499. } {5049}
  500. do_test autovacuum-4.4 {
  501. execsql {
  502. COMMIT;
  503. }
  504. } {}
  505. ifcapable integrityck {
  506. # Ticket #1727
  507. do_test autovacuum-5.1 {
  508. db close
  509. sqlite3 db :memory:
  510. db eval {
  511. PRAGMA auto_vacuum=1;
  512. CREATE TABLE t1(a);
  513. CREATE TABLE t2(a);
  514. DROP TABLE t1;
  515. PRAGMA integrity_check;
  516. }
  517. } ok
  518. }
  519. # Ticket #1728.
  520. #
  521. # In autovacuum mode, when tables or indices are deleted, the rootpage
  522. # values in the symbol table have to be updated. There was a bug in this
  523. # logic so that if an index/table was moved twice, the second move might
  524. # not occur. This would leave the internal symbol table in an inconsistent
  525. # state causing subsequent statements to fail.
  526. #
  527. # The problem is difficult to reproduce. The sequence of statements in
  528. # the following test are carefully designed make it occur and thus to
  529. # verify that this very obscure bug has been resolved.
  530. #
  531. ifcapable integrityck&&memorydb {
  532. do_test autovacuum-6.1 {
  533. db close
  534. sqlite3 db :memory:
  535. db eval {
  536. PRAGMA auto_vacuum=1;
  537. CREATE TABLE t1(a, b);
  538. CREATE INDEX i1 ON t1(a);
  539. CREATE TABLE t2(a);
  540. CREATE INDEX i2 ON t2(a);
  541. CREATE TABLE t3(a);
  542. CREATE INDEX i3 ON t2(a);
  543. CREATE INDEX x ON t1(b);
  544. DROP TABLE t3;
  545. PRAGMA integrity_check;
  546. DROP TABLE t2;
  547. PRAGMA integrity_check;
  548. DROP TABLE t1;
  549. PRAGMA integrity_check;
  550. }
  551. } {ok ok ok}
  552. }
  553. #---------------------------------------------------------------------
  554. # Test cases autovacuum-7.X test the case where a page must be moved
  555. # and the destination location collides with at least one other
  556. # entry in the page hash-table (internal to the pager.c module.
  557. #
  558. do_test autovacuum-7.1 {
  559. db close
  560. forcedelete test.db
  561. forcedelete test.db-journal
  562. sqlite3 db test.db
  563. execsql {
  564. PRAGMA auto_vacuum=1;
  565. CREATE TABLE t1(a, b, PRIMARY KEY(a, b));
  566. INSERT INTO t1 VALUES(randstr(400,400),randstr(400,400));
  567. INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2
  568. INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 4
  569. INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 8
  570. INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 16
  571. INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 32
  572. }
  573. expr {[file size test.db] / 1024}
  574. } {73}
  575. do_test autovacuum-7.2 {
  576. execsql {
  577. CREATE TABLE t2(a, b, PRIMARY KEY(a, b));
  578. INSERT INTO t2 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2
  579. CREATE TABLE t3(a, b, PRIMARY KEY(a, b));
  580. INSERT INTO t3 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2
  581. CREATE TABLE t4(a, b, PRIMARY KEY(a, b));
  582. INSERT INTO t4 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2
  583. CREATE TABLE t5(a, b, PRIMARY KEY(a, b));
  584. INSERT INTO t5 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2
  585. }
  586. expr {[file size test.db] / 1024}
  587. } {354}
  588. do_test autovacuum-7.3 {
  589. db close
  590. sqlite3 db test.db
  591. execsql {
  592. BEGIN;
  593. DELETE FROM t4;
  594. COMMIT;
  595. SELECT count(*) FROM t1;
  596. }
  597. expr {[file size test.db] / 1024}
  598. } {286}
  599. #------------------------------------------------------------------------
  600. # Additional tests.
  601. #
  602. # Try to determine the autovacuum setting for a database that is locked.
  603. #
  604. do_test autovacuum-8.1 {
  605. db close
  606. sqlite3 db test.db
  607. sqlite3 db2 test.db
  608. db eval {PRAGMA auto_vacuum}
  609. } {1}
  610. if {[permutation] == ""} {
  611. do_test autovacuum-8.2 {
  612. db eval {BEGIN EXCLUSIVE}
  613. catchsql {PRAGMA auto_vacuum} db2
  614. } {1 {database is locked}}
  615. catch {db2 close}
  616. catch {db eval {COMMIT}}
  617. }
  618. do_test autovacuum-9.1 {
  619. execsql {
  620. DROP TABLE t1;
  621. DROP TABLE t2;
  622. DROP TABLE t3;
  623. DROP TABLE t4;
  624. DROP TABLE t5;
  625. PRAGMA page_count;
  626. }
  627. } {1}
  628. do_test autovacuum-9.2 {
  629. file size test.db
  630. } 1024
  631. do_test autovacuum-9.3 {
  632. execsql {
  633. CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  634. INSERT INTO t1 VALUES(NULL, randstr(50,50));
  635. }
  636. for {set ii 0} {$ii < 10} {incr ii} {
  637. db eval { INSERT INTO t1 SELECT NULL, randstr(50,50) FROM t1 }
  638. }
  639. file size test.db
  640. } $::sqlite_pending_byte
  641. do_test autovacuum-9.4 {
  642. execsql { INSERT INTO t1 SELECT NULL, randstr(50,50) FROM t1 }
  643. } {}
  644. do_test autovacuum-9.5 {
  645. execsql { DELETE FROM t1 WHERE rowid > (SELECT max(a)/2 FROM t1) }
  646. file size test.db
  647. } $::sqlite_pending_byte
  648. finish_test