analyze.test 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. # 2005 July 22
  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.
  12. # This file implements tests for the ANALYZE command.
  13. #
  14. # $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. # There is nothing to test if ANALYZE is disable for this build.
  18. #
  19. ifcapable {!analyze} {
  20. finish_test
  21. return
  22. }
  23. # Basic sanity checks.
  24. #
  25. do_test analyze-1.1 {
  26. catchsql {
  27. ANALYZE no_such_table
  28. }
  29. } {1 {no such table: no_such_table}}
  30. do_test analyze-1.2 {
  31. execsql {
  32. SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
  33. }
  34. } {0}
  35. do_test analyze-1.3 {
  36. catchsql {
  37. ANALYZE no_such_db.no_such_table
  38. }
  39. } {1 {unknown database no_such_db}}
  40. do_test analyze-1.4 {
  41. execsql {
  42. SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
  43. }
  44. } {0}
  45. do_test analyze-1.5.1 {
  46. catchsql {
  47. ANALYZE
  48. }
  49. } {0 {}}
  50. do_test analyze-1.5.2 {
  51. catchsql {
  52. PRAGMA empty_result_callbacks=1;
  53. ANALYZE
  54. }
  55. } {0 {}}
  56. do_test analyze-1.6 {
  57. execsql {
  58. SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
  59. }
  60. } {1}
  61. do_test analyze-1.6.2 {
  62. catchsql {
  63. CREATE INDEX stat1idx ON sqlite_stat1(idx);
  64. }
  65. } {1 {table sqlite_stat1 may not be indexed}}
  66. do_test analyze-1.6.3 {
  67. catchsql {
  68. CREATE INDEX main.stat1idx ON SQLite_stat1(idx);
  69. }
  70. } {1 {table sqlite_stat1 may not be indexed}}
  71. do_test analyze-1.7 {
  72. execsql {
  73. SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
  74. }
  75. } {}
  76. do_test analyze-1.8 {
  77. catchsql {
  78. ANALYZE main
  79. }
  80. } {0 {}}
  81. do_test analyze-1.9 {
  82. execsql {
  83. SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
  84. }
  85. } {}
  86. do_test analyze-1.10 {
  87. catchsql {
  88. CREATE TABLE t1(a,b);
  89. ANALYZE main.t1;
  90. }
  91. } {0 {}}
  92. do_test analyze-1.11 {
  93. execsql {
  94. SELECT * FROM sqlite_stat1
  95. }
  96. } {}
  97. do_test analyze-1.12 {
  98. catchsql {
  99. ANALYZE t1;
  100. }
  101. } {0 {}}
  102. do_test analyze-1.13 {
  103. execsql {
  104. SELECT * FROM sqlite_stat1
  105. }
  106. } {}
  107. # Create some indices that can be analyzed. But do not yet add
  108. # data. Without data in the tables, no analysis is done.
  109. #
  110. do_test analyze-2.1 {
  111. execsql {
  112. CREATE INDEX t1i1 ON t1(a);
  113. ANALYZE main.t1;
  114. SELECT * FROM sqlite_stat1 ORDER BY idx;
  115. }
  116. } {}
  117. do_test analyze-2.2 {
  118. execsql {
  119. CREATE INDEX t1i2 ON t1(b);
  120. ANALYZE t1;
  121. SELECT * FROM sqlite_stat1 ORDER BY idx;
  122. }
  123. } {}
  124. do_test analyze-2.3 {
  125. execsql {
  126. CREATE INDEX t1i3 ON t1(a,b);
  127. ANALYZE main;
  128. SELECT * FROM sqlite_stat1 ORDER BY idx;
  129. }
  130. } {}
  131. # Start adding data to the table. Verify that the analysis
  132. # is done correctly.
  133. #
  134. do_test analyze-3.1 {
  135. execsql {
  136. INSERT INTO t1 VALUES(1,2);
  137. INSERT INTO t1 VALUES(1,3);
  138. ANALYZE main.t1;
  139. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  140. }
  141. } {t1i1 {2 2} t1i2 {2 1} t1i3 {2 2 1}}
  142. do_test analyze-3.2 {
  143. execsql {
  144. INSERT INTO t1 VALUES(1,4);
  145. INSERT INTO t1 VALUES(1,5);
  146. ANALYZE t1;
  147. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  148. }
  149. } {t1i1 {4 4} t1i2 {4 1} t1i3 {4 4 1}}
  150. do_test analyze-3.3 {
  151. execsql {
  152. INSERT INTO t1 VALUES(2,5);
  153. ANALYZE main;
  154. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  155. }
  156. } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1}}
  157. do_test analyze-3.4 {
  158. execsql {
  159. CREATE TABLE t2 AS SELECT * FROM t1;
  160. CREATE INDEX t2i1 ON t2(a);
  161. CREATE INDEX t2i2 ON t2(b);
  162. CREATE INDEX t2i3 ON t2(a,b);
  163. ANALYZE;
  164. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  165. }
  166. } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2} t2i3 {5 3 1}}
  167. do_test analyze-3.5 {
  168. execsql {
  169. DROP INDEX t2i3;
  170. ANALYZE t1;
  171. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  172. }
  173. } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2}}
  174. do_test analyze-3.6 {
  175. execsql {
  176. ANALYZE t2;
  177. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  178. }
  179. } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2}}
  180. do_test analyze-3.7 {
  181. execsql {
  182. DROP INDEX t2i2;
  183. ANALYZE t2;
  184. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  185. }
  186. } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3}}
  187. do_test analyze-3.8 {
  188. execsql {
  189. CREATE TABLE t3 AS SELECT a, b, rowid AS c, 'hi' AS d FROM t1;
  190. CREATE INDEX t3i1 ON t3(a);
  191. CREATE INDEX t3i2 ON t3(a,b,c,d);
  192. CREATE INDEX t3i3 ON t3(d,b,c,a);
  193. DROP TABLE t1;
  194. DROP TABLE t2;
  195. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  196. }
  197. } {}
  198. do_test analyze-3.9 {
  199. execsql {
  200. ANALYZE;
  201. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  202. }
  203. } {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
  204. do_test analyze-3.10 {
  205. execsql {
  206. CREATE TABLE [silly " name](a, b, c);
  207. CREATE INDEX 'foolish '' name' ON [silly " name](a, b);
  208. CREATE INDEX 'another foolish '' name' ON [silly " name](c);
  209. INSERT INTO [silly " name] VALUES(1, 2, 3);
  210. INSERT INTO [silly " name] VALUES(4, 5, 6);
  211. ANALYZE;
  212. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  213. }
  214. } {{another foolish ' name} {2 1} {foolish ' name} {2 1 1} t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
  215. do_test analyze-3.11 {
  216. execsql {
  217. DROP INDEX "foolish ' name";
  218. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  219. }
  220. } {{another foolish ' name} {2 1} t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
  221. do_test analyze-3.11 {
  222. execsql {
  223. DROP TABLE "silly "" name";
  224. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  225. }
  226. } {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
  227. # Try corrupting the sqlite_stat1 table and make sure the
  228. # database is still able to function.
  229. #
  230. do_test analyze-4.0 {
  231. sqlite3 db2 test.db
  232. db2 eval {
  233. CREATE TABLE t4(x,y,z);
  234. CREATE INDEX t4i1 ON t4(x);
  235. CREATE INDEX t4i2 ON t4(y);
  236. INSERT INTO t4 SELECT a,b,c FROM t3;
  237. }
  238. db2 close
  239. db close
  240. sqlite3 db test.db
  241. execsql {
  242. ANALYZE;
  243. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  244. }
  245. } {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1} t4i1 {5 3} t4i2 {5 2}}
  246. do_test analyze-4.1 {
  247. execsql {
  248. PRAGMA writable_schema=on;
  249. INSERT INTO sqlite_stat1 VALUES(null,null,null);
  250. PRAGMA writable_schema=off;
  251. }
  252. db close
  253. sqlite3 db test.db
  254. execsql {
  255. SELECT * FROM t4 WHERE x=1234;
  256. }
  257. } {}
  258. do_test analyze-4.2 {
  259. execsql {
  260. PRAGMA writable_schema=on;
  261. DELETE FROM sqlite_stat1;
  262. INSERT INTO sqlite_stat1 VALUES('t4','t4i1','nonsense');
  263. INSERT INTO sqlite_stat1 VALUES('t4','t4i2','120897349817238741092873198273409187234918720394817209384710928374109827172901827349871928741910');
  264. PRAGMA writable_schema=off;
  265. }
  266. db close
  267. sqlite3 db test.db
  268. execsql {
  269. SELECT * FROM t4 WHERE x=1234;
  270. }
  271. } {}
  272. do_test analyze-4.3 {
  273. execsql {
  274. INSERT INTO sqlite_stat1 VALUES('t4','xyzzy','0 1 2 3');
  275. }
  276. db close
  277. sqlite3 db test.db
  278. execsql {
  279. SELECT * FROM t4 WHERE x=1234;
  280. }
  281. } {}
  282. # Verify that DROP TABLE and DROP INDEX remove entries from the
  283. # sqlite_stat1, sqlite_stat3 and sqlite_stat4 tables.
  284. #
  285. do_test analyze-5.0 {
  286. execsql {
  287. DELETE FROM t3;
  288. DELETE FROM t4;
  289. INSERT INTO t3 VALUES(1,2,3,4);
  290. INSERT INTO t3 VALUES(5,6,7,8);
  291. INSERT INTO t3 SELECT a+8, b+8, c+8, d+8 FROM t3;
  292. INSERT INTO t3 SELECT a+16, b+16, c+16, d+16 FROM t3;
  293. INSERT INTO t3 SELECT a+32, b+32, c+32, d+32 FROM t3;
  294. INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3;
  295. INSERT INTO t4 SELECT a, b, c FROM t3;
  296. ANALYZE;
  297. SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
  298. SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
  299. }
  300. } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
  301. ifcapable stat4||stat3 {
  302. ifcapable stat4 {set stat sqlite_stat4} else {set stat sqlite_stat3}
  303. do_test analyze-5.1 {
  304. execsql "
  305. SELECT DISTINCT idx FROM $stat ORDER BY 1;
  306. SELECT DISTINCT tbl FROM $stat ORDER BY 1;
  307. "
  308. } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
  309. }
  310. do_test analyze-5.2 {
  311. execsql {
  312. DROP INDEX t3i2;
  313. SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
  314. SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
  315. }
  316. } {t3i1 t3i3 t4i1 t4i2 t3 t4}
  317. ifcapable stat4||stat3 {
  318. do_test analyze-5.3 {
  319. execsql "
  320. SELECT DISTINCT idx FROM $stat ORDER BY 1;
  321. SELECT DISTINCT tbl FROM $stat ORDER BY 1;
  322. "
  323. } {t3i1 t3i3 t4i1 t4i2 t3 t4}
  324. }
  325. do_test analyze-5.4 {
  326. execsql {
  327. DROP TABLE t3;
  328. SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
  329. SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
  330. }
  331. } {t4i1 t4i2 t4}
  332. ifcapable stat4||stat3 {
  333. do_test analyze-5.5 {
  334. execsql "
  335. SELECT DISTINCT idx FROM $stat ORDER BY 1;
  336. SELECT DISTINCT tbl FROM $stat ORDER BY 1;
  337. "
  338. } {t4i1 t4i2 t4}
  339. }
  340. # This test corrupts the database file so it must be the last test
  341. # in the series.
  342. #
  343. do_test analyze-99.1 {
  344. execsql {
  345. PRAGMA writable_schema=on;
  346. UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
  347. }
  348. db close
  349. catch { sqlite3 db test.db }
  350. catchsql {
  351. ANALYZE
  352. }
  353. } {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}
  354. finish_test