|
1 # 2005 November 2 |
|
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 CHECK constraints |
|
13 # |
|
14 # $Id: check.test,v 1.11 2007/07/23 19:39:47 drh Exp $ |
|
15 |
|
16 set testdir [file dirname $argv0] |
|
17 source $testdir/tester.tcl |
|
18 |
|
19 # Only run these tests if the build includes support for CHECK constraints |
|
20 ifcapable !check { |
|
21 finish_test |
|
22 return |
|
23 } |
|
24 |
|
25 do_test check-1.1 { |
|
26 execsql { |
|
27 CREATE TABLE t1( |
|
28 x INTEGER CHECK( x<5 ), |
|
29 y REAL CHECK( y>x ) |
|
30 ); |
|
31 } |
|
32 } {} |
|
33 do_test check-1.2 { |
|
34 execsql { |
|
35 INSERT INTO t1 VALUES(3,4); |
|
36 SELECT * FROM t1; |
|
37 } |
|
38 } {3 4.0} |
|
39 do_test check-1.3 { |
|
40 catchsql { |
|
41 INSERT INTO t1 VALUES(6,7); |
|
42 } |
|
43 } {1 {constraint failed}} |
|
44 do_test check-1.4 { |
|
45 execsql { |
|
46 SELECT * FROM t1; |
|
47 } |
|
48 } {3 4.0} |
|
49 do_test check-1.5 { |
|
50 catchsql { |
|
51 INSERT INTO t1 VALUES(4,3); |
|
52 } |
|
53 } {1 {constraint failed}} |
|
54 do_test check-1.6 { |
|
55 execsql { |
|
56 SELECT * FROM t1; |
|
57 } |
|
58 } {3 4.0} |
|
59 do_test check-1.7 { |
|
60 catchsql { |
|
61 INSERT INTO t1 VALUES(NULL,6); |
|
62 } |
|
63 } {0 {}} |
|
64 do_test check-1.8 { |
|
65 execsql { |
|
66 SELECT * FROM t1; |
|
67 } |
|
68 } {3 4.0 {} 6.0} |
|
69 do_test check-1.9 { |
|
70 catchsql { |
|
71 INSERT INTO t1 VALUES(2,NULL); |
|
72 } |
|
73 } {0 {}} |
|
74 do_test check-1.10 { |
|
75 execsql { |
|
76 SELECT * FROM t1; |
|
77 } |
|
78 } {3 4.0 {} 6.0 2 {}} |
|
79 do_test check-1.11 { |
|
80 execsql { |
|
81 DELETE FROM t1 WHERE x IS NULL OR x!=3; |
|
82 UPDATE t1 SET x=2 WHERE x==3; |
|
83 SELECT * FROM t1; |
|
84 } |
|
85 } {2 4.0} |
|
86 do_test check-1.12 { |
|
87 catchsql { |
|
88 UPDATE t1 SET x=7 WHERE x==2 |
|
89 } |
|
90 } {1 {constraint failed}} |
|
91 do_test check-1.13 { |
|
92 execsql { |
|
93 SELECT * FROM t1; |
|
94 } |
|
95 } {2 4.0} |
|
96 do_test check-1.14 { |
|
97 catchsql { |
|
98 UPDATE t1 SET x=5 WHERE x==2 |
|
99 } |
|
100 } {1 {constraint failed}} |
|
101 do_test check-1.15 { |
|
102 execsql { |
|
103 SELECT * FROM t1; |
|
104 } |
|
105 } {2 4.0} |
|
106 do_test check-1.16 { |
|
107 catchsql { |
|
108 UPDATE t1 SET x=4, y=11 WHERE x==2 |
|
109 } |
|
110 } {0 {}} |
|
111 do_test check-1.17 { |
|
112 execsql { |
|
113 SELECT * FROM t1; |
|
114 } |
|
115 } {4 11.0} |
|
116 |
|
117 do_test check-2.1 { |
|
118 execsql { |
|
119 CREATE TABLE t2( |
|
120 x INTEGER CHECK( typeof(coalesce(x,0))=="integer" ), |
|
121 y REAL CHECK( typeof(coalesce(y,0.1))=="real" ), |
|
122 z TEXT CHECK( typeof(coalesce(z,''))=="text" ) |
|
123 ); |
|
124 } |
|
125 } {} |
|
126 do_test check-2.2 { |
|
127 execsql { |
|
128 INSERT INTO t2 VALUES(1,2.2,'three'); |
|
129 SELECT * FROM t2; |
|
130 } |
|
131 } {1 2.2 three} |
|
132 do_test check-2.3 { |
|
133 execsql { |
|
134 INSERT INTO t2 VALUES(NULL, NULL, NULL); |
|
135 SELECT * FROM t2; |
|
136 } |
|
137 } {1 2.2 three {} {} {}} |
|
138 do_test check-2.4 { |
|
139 catchsql { |
|
140 INSERT INTO t2 VALUES(1.1, NULL, NULL); |
|
141 } |
|
142 } {1 {constraint failed}} |
|
143 do_test check-2.5 { |
|
144 catchsql { |
|
145 INSERT INTO t2 VALUES(NULL, 5, NULL); |
|
146 } |
|
147 } {1 {constraint failed}} |
|
148 do_test check-2.6 { |
|
149 catchsql { |
|
150 INSERT INTO t2 VALUES(NULL, NULL, 3.14159); |
|
151 } |
|
152 } {1 {constraint failed}} |
|
153 |
|
154 ifcapable subquery { |
|
155 do_test check-3.1 { |
|
156 catchsql { |
|
157 CREATE TABLE t3( |
|
158 x, y, z, |
|
159 CHECK( x<(SELECT min(x) FROM t1) ) |
|
160 ); |
|
161 } |
|
162 } {1 {subqueries prohibited in CHECK constraints}} |
|
163 } |
|
164 |
|
165 do_test check-3.2 { |
|
166 execsql { |
|
167 SELECT name FROM sqlite_master ORDER BY name |
|
168 } |
|
169 } {t1 t2} |
|
170 do_test check-3.3 { |
|
171 catchsql { |
|
172 CREATE TABLE t3( |
|
173 x, y, z, |
|
174 CHECK( q<x ) |
|
175 ); |
|
176 } |
|
177 } {1 {no such column: q}} |
|
178 do_test check-3.4 { |
|
179 execsql { |
|
180 SELECT name FROM sqlite_master ORDER BY name |
|
181 } |
|
182 } {t1 t2} |
|
183 do_test check-3.5 { |
|
184 catchsql { |
|
185 CREATE TABLE t3( |
|
186 x, y, z, |
|
187 CHECK( t2.x<x ) |
|
188 ); |
|
189 } |
|
190 } {1 {no such column: t2.x}} |
|
191 do_test check-3.6 { |
|
192 execsql { |
|
193 SELECT name FROM sqlite_master ORDER BY name |
|
194 } |
|
195 } {t1 t2} |
|
196 do_test check-3.7 { |
|
197 catchsql { |
|
198 CREATE TABLE t3( |
|
199 x, y, z, |
|
200 CHECK( t3.x<25 ) |
|
201 ); |
|
202 } |
|
203 } {0 {}} |
|
204 do_test check-3.8 { |
|
205 execsql { |
|
206 INSERT INTO t3 VALUES(1,2,3); |
|
207 SELECT * FROM t3; |
|
208 } |
|
209 } {1 2 3} |
|
210 do_test check-3.9 { |
|
211 catchsql { |
|
212 INSERT INTO t3 VALUES(111,222,333); |
|
213 } |
|
214 } {1 {constraint failed}} |
|
215 |
|
216 do_test check-4.1 { |
|
217 execsql { |
|
218 CREATE TABLE t4(x, y, |
|
219 CHECK ( |
|
220 x+y==11 |
|
221 OR x*y==12 |
|
222 OR x/y BETWEEN 5 AND 8 |
|
223 OR -x==y+10 |
|
224 ) |
|
225 ); |
|
226 } |
|
227 } {} |
|
228 do_test check-4.2 { |
|
229 execsql { |
|
230 INSERT INTO t4 VALUES(1,10); |
|
231 SELECT * FROM t4 |
|
232 } |
|
233 } {1 10} |
|
234 do_test check-4.3 { |
|
235 execsql { |
|
236 UPDATE t4 SET x=4, y=3; |
|
237 SELECT * FROM t4 |
|
238 } |
|
239 } {4 3} |
|
240 do_test check-4.3 { |
|
241 execsql { |
|
242 UPDATE t4 SET x=12, y=2; |
|
243 SELECT * FROM t4 |
|
244 } |
|
245 } {12 2} |
|
246 do_test check-4.4 { |
|
247 execsql { |
|
248 UPDATE t4 SET x=12, y=-22; |
|
249 SELECT * FROM t4 |
|
250 } |
|
251 } {12 -22} |
|
252 do_test check-4.5 { |
|
253 catchsql { |
|
254 UPDATE t4 SET x=0, y=1; |
|
255 } |
|
256 } {1 {constraint failed}} |
|
257 do_test check-4.6 { |
|
258 execsql { |
|
259 SELECT * FROM t4; |
|
260 } |
|
261 } {12 -22} |
|
262 do_test check-4.7 { |
|
263 execsql { |
|
264 PRAGMA ignore_check_constraints=ON; |
|
265 UPDATE t4 SET x=0, y=1; |
|
266 SELECT * FROM t4; |
|
267 } |
|
268 } {0 1} |
|
269 do_test check-4.8 { |
|
270 catchsql { |
|
271 PRAGMA ignore_check_constraints=OFF; |
|
272 UPDATE t4 SET x=0, y=2; |
|
273 } |
|
274 } {1 {constraint failed}} |
|
275 ifcapable vacuum { |
|
276 do_test check_4.9 { |
|
277 catchsql { |
|
278 VACUUM |
|
279 } |
|
280 } {0 {}} |
|
281 } |
|
282 |
|
283 do_test check-5.1 { |
|
284 catchsql { |
|
285 CREATE TABLE t5(x, y, |
|
286 CHECK( x*y<:abc ) |
|
287 ); |
|
288 } |
|
289 } {1 {parameters prohibited in CHECK constraints}} |
|
290 do_test check-5.2 { |
|
291 catchsql { |
|
292 CREATE TABLE t5(x, y, |
|
293 CHECK( x*y<? ) |
|
294 ); |
|
295 } |
|
296 } {1 {parameters prohibited in CHECK constraints}} |
|
297 |
|
298 ifcapable conflict { |
|
299 |
|
300 do_test check-6.1 { |
|
301 execsql {SELECT * FROM t1} |
|
302 } {4 11.0} |
|
303 do_test check-6.2 { |
|
304 execsql { |
|
305 UPDATE OR IGNORE t1 SET x=5; |
|
306 SELECT * FROM t1; |
|
307 } |
|
308 } {4 11.0} |
|
309 do_test check-6.3 { |
|
310 execsql { |
|
311 INSERT OR IGNORE INTO t1 VALUES(5,4.0); |
|
312 SELECT * FROM t1; |
|
313 } |
|
314 } {4 11.0} |
|
315 do_test check-6.4 { |
|
316 execsql { |
|
317 INSERT OR IGNORE INTO t1 VALUES(2,20.0); |
|
318 SELECT * FROM t1; |
|
319 } |
|
320 } {4 11.0 2 20.0} |
|
321 do_test check-6.5 { |
|
322 catchsql { |
|
323 UPDATE OR FAIL t1 SET x=7-x, y=y+1; |
|
324 } |
|
325 } {1 {constraint failed}} |
|
326 do_test check-6.6 { |
|
327 execsql { |
|
328 SELECT * FROM t1; |
|
329 } |
|
330 } {3 12.0 2 20.0} |
|
331 do_test check-6.7 { |
|
332 catchsql { |
|
333 BEGIN; |
|
334 INSERT INTO t1 VALUES(1,30.0); |
|
335 INSERT OR ROLLBACK INTO t1 VALUES(8,40.0); |
|
336 } |
|
337 } {1 {constraint failed}} |
|
338 do_test check-6.8 { |
|
339 catchsql { |
|
340 COMMIT; |
|
341 } |
|
342 } {1 {cannot commit - no transaction is active}} |
|
343 do_test check-6.9 { |
|
344 execsql { |
|
345 SELECT * FROM t1 |
|
346 } |
|
347 } {3 12.0 2 20.0} |
|
348 |
|
349 do_test check-6.11 { |
|
350 execsql {SELECT * FROM t1} |
|
351 } {3 12.0 2 20.0} |
|
352 do_test check-6.12 { |
|
353 catchsql { |
|
354 REPLACE INTO t1 VALUES(6,7); |
|
355 } |
|
356 } {1 {constraint failed}} |
|
357 do_test check-6.13 { |
|
358 execsql {SELECT * FROM t1} |
|
359 } {3 12.0 2 20.0} |
|
360 do_test check-6.14 { |
|
361 catchsql { |
|
362 INSERT OR IGNORE INTO t1 VALUES(6,7); |
|
363 } |
|
364 } {0 {}} |
|
365 do_test check-6.15 { |
|
366 execsql {SELECT * FROM t1} |
|
367 } {3 12.0 2 20.0} |
|
368 |
|
369 |
|
370 } |
|
371 |
|
372 finish_test |