index6.test 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. # 2013-07-31
  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. #
  12. # Test cases for partial indices
  13. #
  14. set testdir [file dirname $argv0]
  15. source $testdir/tester.tcl
  16. ifcapable !vtab {
  17. finish_test
  18. return
  19. }
  20. load_static_extension db wholenumber;
  21. do_test index6-1.1 {
  22. # Able to parse and manage partial indices
  23. execsql {
  24. CREATE TABLE t1(a,b,c);
  25. CREATE INDEX t1a ON t1(a) WHERE a IS NOT NULL;
  26. CREATE INDEX t1b ON t1(b) WHERE b>10;
  27. CREATE VIRTUAL TABLE nums USING wholenumber;
  28. INSERT INTO t1(a,b,c)
  29. SELECT CASE WHEN value%3!=0 THEN value END, value, value
  30. FROM nums WHERE value<=20;
  31. SELECT count(a), count(b) FROM t1;
  32. PRAGMA integrity_check;
  33. }
  34. } {14 20 ok}
  35. # Make sure the count(*) optimization works correctly with
  36. # partial indices. Ticket [a5c8ed66cae16243be6] 2013-10-03.
  37. #
  38. do_execsql_test index6-1.1.1 {
  39. SELECT count(*) FROM t1;
  40. } {20}
  41. # Error conditions during parsing...
  42. #
  43. do_test index6-1.2 {
  44. catchsql {
  45. CREATE INDEX bad1 ON t1(a,b) WHERE x IS NOT NULL;
  46. }
  47. } {1 {no such column: x}}
  48. do_test index6-1.3 {
  49. catchsql {
  50. CREATE INDEX bad1 ON t1(a,b) WHERE EXISTS(SELECT * FROM t1);
  51. }
  52. } {1 {subqueries prohibited in partial index WHERE clauses}}
  53. do_test index6-1.4 {
  54. catchsql {
  55. CREATE INDEX bad1 ON t1(a,b) WHERE a!=?1;
  56. }
  57. } {1 {parameters prohibited in partial index WHERE clauses}}
  58. do_test index6-1.5 {
  59. catchsql {
  60. CREATE INDEX bad1 ON t1(a,b) WHERE a!=random();
  61. }
  62. } {1 {functions prohibited in partial index WHERE clauses}}
  63. do_test index6-1.6 {
  64. catchsql {
  65. CREATE INDEX bad1 ON t1(a,b) WHERE a NOT LIKE 'abc%';
  66. }
  67. } {1 {functions prohibited in partial index WHERE clauses}}
  68. do_test index6-1.10 {
  69. execsql {
  70. ANALYZE;
  71. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  72. PRAGMA integrity_check;
  73. }
  74. } {{} 20 t1a {14 1} t1b {10 1} ok}
  75. # STAT1 shows the partial indices have a reduced number of
  76. # rows.
  77. #
  78. do_test index6-1.11 {
  79. execsql {
  80. UPDATE t1 SET a=b;
  81. ANALYZE;
  82. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  83. PRAGMA integrity_check;
  84. }
  85. } {{} 20 t1a {20 1} t1b {10 1} ok}
  86. do_test index6-1.11 {
  87. execsql {
  88. UPDATE t1 SET a=NULL WHERE b%3!=0;
  89. UPDATE t1 SET b=b+100;
  90. ANALYZE;
  91. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  92. PRAGMA integrity_check;
  93. }
  94. } {{} 20 t1a {6 1} t1b {20 1} ok}
  95. do_test index6-1.12 {
  96. execsql {
  97. UPDATE t1 SET a=CASE WHEN b%3!=0 THEN b END;
  98. UPDATE t1 SET b=b-100;
  99. ANALYZE;
  100. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  101. PRAGMA integrity_check;
  102. }
  103. } {{} 20 t1a {13 1} t1b {10 1} ok}
  104. do_test index6-1.13 {
  105. execsql {
  106. DELETE FROM t1 WHERE b BETWEEN 8 AND 12;
  107. ANALYZE;
  108. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  109. PRAGMA integrity_check;
  110. }
  111. } {{} 15 t1a {10 1} t1b {8 1} ok}
  112. do_test index6-1.14 {
  113. execsql {
  114. REINDEX;
  115. ANALYZE;
  116. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  117. PRAGMA integrity_check;
  118. }
  119. } {{} 15 t1a {10 1} t1b {8 1} ok}
  120. do_test index6-1.15 {
  121. execsql {
  122. CREATE INDEX t1c ON t1(c);
  123. ANALYZE;
  124. SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
  125. PRAGMA integrity_check;
  126. }
  127. } {t1a {10 1} t1b {8 1} t1c {15 1} ok}
  128. # Queries use partial indices as appropriate times.
  129. #
  130. do_test index6-2.1 {
  131. execsql {
  132. CREATE TABLE t2(a,b);
  133. INSERT INTO t2(a,b) SELECT value, value FROM nums WHERE value<1000;
  134. UPDATE t2 SET a=NULL WHERE b%5==0;
  135. CREATE INDEX t2a1 ON t2(a) WHERE a IS NOT NULL;
  136. SELECT count(*) FROM t2 WHERE a IS NOT NULL;
  137. }
  138. } {800}
  139. do_test index6-2.2 {
  140. execsql {
  141. EXPLAIN QUERY PLAN
  142. SELECT * FROM t2 WHERE a=5;
  143. }
  144. } {/.* TABLE t2 USING INDEX t2a1 .*/}
  145. ifcapable stat4||stat3 {
  146. do_test index6-2.3stat4 {
  147. execsql {
  148. EXPLAIN QUERY PLAN
  149. SELECT * FROM t2 WHERE a IS NOT NULL;
  150. }
  151. } {/.* TABLE t2 USING INDEX t2a1 .*/}
  152. } else {
  153. do_test index6-2.3stat4 {
  154. execsql {
  155. EXPLAIN QUERY PLAN
  156. SELECT * FROM t2 WHERE a IS NOT NULL AND a>0;
  157. }
  158. } {/.* TABLE t2 USING INDEX t2a1 .*/}
  159. }
  160. do_test index6-2.4 {
  161. execsql {
  162. EXPLAIN QUERY PLAN
  163. SELECT * FROM t2 WHERE a IS NULL;
  164. }
  165. } {~/.*INDEX t2a1.*/}
  166. do_execsql_test index6-2.101 {
  167. DROP INDEX t2a1;
  168. UPDATE t2 SET a=b, b=b+10000;
  169. SELECT b FROM t2 WHERE a=15;
  170. } {10015}
  171. do_execsql_test index6-2.102 {
  172. CREATE INDEX t2a2 ON t2(a) WHERE a<100 OR a>200;
  173. SELECT b FROM t2 WHERE a=15;
  174. PRAGMA integrity_check;
  175. } {10015 ok}
  176. do_execsql_test index6-2.102eqp {
  177. EXPLAIN QUERY PLAN
  178. SELECT b FROM t2 WHERE a=15;
  179. } {~/.*INDEX t2a2.*/}
  180. do_execsql_test index6-2.103 {
  181. SELECT b FROM t2 WHERE a=15 AND a<100;
  182. } {10015}
  183. do_execsql_test index6-2.103eqp {
  184. EXPLAIN QUERY PLAN
  185. SELECT b FROM t2 WHERE a=15 AND a<100;
  186. } {/.*INDEX t2a2.*/}
  187. do_execsql_test index6-2.104 {
  188. SELECT b FROM t2 WHERE a=515 AND a>200;
  189. } {10515}
  190. do_execsql_test index6-2.104eqp {
  191. EXPLAIN QUERY PLAN
  192. SELECT b FROM t2 WHERE a=515 AND a>200;
  193. } {/.*INDEX t2a2.*/}
  194. # Partial UNIQUE indices
  195. #
  196. do_execsql_test index6-3.1 {
  197. CREATE TABLE t3(a,b);
  198. INSERT INTO t3 SELECT value, value FROM nums WHERE value<200;
  199. UPDATE t3 SET a=999 WHERE b%5!=0;
  200. CREATE UNIQUE INDEX t3a ON t3(a) WHERE a<>999;
  201. } {}
  202. do_test index6-3.2 {
  203. # unable to insert a duplicate row a-value that is not 999.
  204. catchsql {
  205. INSERT INTO t3(a,b) VALUES(150, 'test1');
  206. }
  207. } {1 {column a is not unique}}
  208. do_test index6-3.3 {
  209. # can insert multiple rows with a==999 because such rows are not
  210. # part of the unique index.
  211. catchsql {
  212. INSERT INTO t3(a,b) VALUES(999, 'test1'), (999, 'test2');
  213. }
  214. } {0 {}}
  215. do_execsql_test index6-3.4 {
  216. SELECT count(*) FROM t3 WHERE a=999;
  217. } {162}
  218. integrity_check index6-3.5
  219. do_execsql_test index6-4.0 {
  220. VACUUM;
  221. PRAGMA integrity_check;
  222. } {ok}
  223. # Silently ignore database name qualifiers in partial indices.
  224. #
  225. do_execsql_test index6-5.0 {
  226. CREATE INDEX t3b ON t3(b) WHERE xyzzy.t3.b BETWEEN 5 AND 10;
  227. /* ^^^^^-- ignored */
  228. ANALYZE;
  229. SELECT count(*) FROM t3 WHERE t3.b BETWEEN 5 AND 10;
  230. SELECT stat+0 FROM sqlite_stat1 WHERE idx='t3b';
  231. } {6 6}
  232. finish_test