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