check.test 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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.13 2009/06/05 17:09:12 drh Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. set ::testprefix check
  18. # Only run these tests if the build includes support for CHECK constraints
  19. ifcapable !check {
  20. finish_test
  21. return
  22. }
  23. do_test check-1.1 {
  24. execsql {
  25. CREATE TABLE t1(
  26. x INTEGER CHECK( x<5 ),
  27. y REAL CHECK( y>x )
  28. );
  29. }
  30. } {}
  31. do_test check-1.2 {
  32. execsql {
  33. INSERT INTO t1 VALUES(3,4);
  34. SELECT * FROM t1;
  35. }
  36. } {3 4.0}
  37. do_test check-1.3 {
  38. catchsql {
  39. INSERT INTO t1 VALUES(6,7);
  40. }
  41. } {1 {constraint failed}}
  42. do_test check-1.4 {
  43. execsql {
  44. SELECT * FROM t1;
  45. }
  46. } {3 4.0}
  47. do_test check-1.5 {
  48. catchsql {
  49. INSERT INTO t1 VALUES(4,3);
  50. }
  51. } {1 {constraint failed}}
  52. do_test check-1.6 {
  53. execsql {
  54. SELECT * FROM t1;
  55. }
  56. } {3 4.0}
  57. do_test check-1.7 {
  58. catchsql {
  59. INSERT INTO t1 VALUES(NULL,6);
  60. }
  61. } {0 {}}
  62. do_test check-1.8 {
  63. execsql {
  64. SELECT * FROM t1;
  65. }
  66. } {3 4.0 {} 6.0}
  67. do_test check-1.9 {
  68. catchsql {
  69. INSERT INTO t1 VALUES(2,NULL);
  70. }
  71. } {0 {}}
  72. do_test check-1.10 {
  73. execsql {
  74. SELECT * FROM t1;
  75. }
  76. } {3 4.0 {} 6.0 2 {}}
  77. do_test check-1.11 {
  78. execsql {
  79. DELETE FROM t1 WHERE x IS NULL OR x!=3;
  80. UPDATE t1 SET x=2 WHERE x==3;
  81. SELECT * FROM t1;
  82. }
  83. } {2 4.0}
  84. do_test check-1.12 {
  85. catchsql {
  86. UPDATE t1 SET x=7 WHERE x==2
  87. }
  88. } {1 {constraint failed}}
  89. do_test check-1.13 {
  90. execsql {
  91. SELECT * FROM t1;
  92. }
  93. } {2 4.0}
  94. do_test check-1.14 {
  95. catchsql {
  96. UPDATE t1 SET x=5 WHERE x==2
  97. }
  98. } {1 {constraint failed}}
  99. do_test check-1.15 {
  100. execsql {
  101. SELECT * FROM t1;
  102. }
  103. } {2 4.0}
  104. do_test check-1.16 {
  105. catchsql {
  106. UPDATE t1 SET x=4, y=11 WHERE x==2
  107. }
  108. } {0 {}}
  109. do_test check-1.17 {
  110. execsql {
  111. SELECT * FROM t1;
  112. }
  113. } {4 11.0}
  114. do_test check-2.1 {
  115. execsql {
  116. CREATE TABLE t2(
  117. x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
  118. y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
  119. z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
  120. );
  121. }
  122. } {}
  123. do_test check-2.2 {
  124. execsql {
  125. INSERT INTO t2 VALUES(1,2.2,'three');
  126. SELECT * FROM t2;
  127. }
  128. } {1 2.2 three}
  129. db close
  130. sqlite3 db test.db
  131. do_test check-2.3 {
  132. execsql {
  133. INSERT INTO t2 VALUES(NULL, NULL, NULL);
  134. SELECT * FROM t2;
  135. }
  136. } {1 2.2 three {} {} {}}
  137. do_test check-2.4 {
  138. catchsql {
  139. INSERT INTO t2 VALUES(1.1, NULL, NULL);
  140. }
  141. } {1 {constraint one failed}}
  142. do_test check-2.5 {
  143. catchsql {
  144. INSERT INTO t2 VALUES(NULL, 5, NULL);
  145. }
  146. } {1 {constraint two failed}}
  147. do_test check-2.6 {
  148. catchsql {
  149. INSERT INTO t2 VALUES(NULL, NULL, 3.14159);
  150. }
  151. } {1 {constraint three failed}}
  152. # Undocumented behavior: The CONSTRAINT name clause can follow a constraint.
  153. # Such a clause is ignored. But the parser must accept it for backwards
  154. # compatibility.
  155. #
  156. do_test check-2.10 {
  157. execsql {
  158. CREATE TABLE t2b(
  159. x INTEGER CHECK( typeof(coalesce(x,0))=='integer' ) CONSTRAINT one,
  160. y TEXT PRIMARY KEY constraint two,
  161. z INTEGER,
  162. UNIQUE(x,z) constraint three
  163. );
  164. }
  165. } {}
  166. do_test check-2.11 {
  167. catchsql {
  168. INSERT INTO t2b VALUES('xyzzy','hi',5);
  169. }
  170. } {1 {constraint failed}}
  171. do_test check-2.12 {
  172. execsql {
  173. CREATE TABLE t2c(
  174. x INTEGER CONSTRAINT x_one CONSTRAINT x_two
  175. CHECK( typeof(coalesce(x,0))=='integer' )
  176. CONSTRAINT x_two CONSTRAINT x_three,
  177. y INTEGER, z INTEGER,
  178. CONSTRAINT u_one UNIQUE(x,y,z) CONSTRAINT u_two
  179. );
  180. }
  181. } {}
  182. do_test check-2.13 {
  183. catchsql {
  184. INSERT INTO t2c VALUES('xyzzy',7,8);
  185. }
  186. } {1 {constraint x_two failed}}
  187. do_test check-2.cleanup {
  188. execsql {
  189. DROP TABLE IF EXISTS t2b;
  190. DROP TABLE IF EXISTS t2c;
  191. }
  192. } {}
  193. ifcapable subquery {
  194. do_test check-3.1 {
  195. catchsql {
  196. CREATE TABLE t3(
  197. x, y, z,
  198. CHECK( x<(SELECT min(x) FROM t1) )
  199. );
  200. }
  201. } {1 {subqueries prohibited in CHECK constraints}}
  202. }
  203. do_test check-3.2 {
  204. execsql {
  205. SELECT name FROM sqlite_master ORDER BY name
  206. }
  207. } {t1 t2}
  208. do_test check-3.3 {
  209. catchsql {
  210. CREATE TABLE t3(
  211. x, y, z,
  212. CHECK( q<x )
  213. );
  214. }
  215. } {1 {no such column: q}}
  216. do_test check-3.4 {
  217. execsql {
  218. SELECT name FROM sqlite_master ORDER BY name
  219. }
  220. } {t1 t2}
  221. do_test check-3.5 {
  222. catchsql {
  223. CREATE TABLE t3(
  224. x, y, z,
  225. CHECK( t2.x<x )
  226. );
  227. }
  228. } {1 {no such column: t2.x}}
  229. do_test check-3.6 {
  230. execsql {
  231. SELECT name FROM sqlite_master ORDER BY name
  232. }
  233. } {t1 t2}
  234. do_test check-3.7 {
  235. catchsql {
  236. CREATE TABLE t3(
  237. x, y, z,
  238. CHECK( t3.x<25 )
  239. );
  240. }
  241. } {0 {}}
  242. do_test check-3.8 {
  243. execsql {
  244. INSERT INTO t3 VALUES(1,2,3);
  245. SELECT * FROM t3;
  246. }
  247. } {1 2 3}
  248. do_test check-3.9 {
  249. catchsql {
  250. INSERT INTO t3 VALUES(111,222,333);
  251. }
  252. } {1 {constraint failed}}
  253. do_test check-4.1 {
  254. execsql {
  255. CREATE TABLE t4(x, y,
  256. CHECK (
  257. x+y==11
  258. OR x*y==12
  259. OR x/y BETWEEN 5 AND 8
  260. OR -x==y+10
  261. )
  262. );
  263. }
  264. } {}
  265. do_test check-4.2 {
  266. execsql {
  267. INSERT INTO t4 VALUES(1,10);
  268. SELECT * FROM t4
  269. }
  270. } {1 10}
  271. do_test check-4.3 {
  272. execsql {
  273. UPDATE t4 SET x=4, y=3;
  274. SELECT * FROM t4
  275. }
  276. } {4 3}
  277. do_test check-4.4 {
  278. execsql {
  279. UPDATE t4 SET x=12, y=2;
  280. SELECT * FROM t4
  281. }
  282. } {12 2}
  283. do_test check-4.5 {
  284. execsql {
  285. UPDATE t4 SET x=12, y=-22;
  286. SELECT * FROM t4
  287. }
  288. } {12 -22}
  289. do_test check-4.6 {
  290. catchsql {
  291. UPDATE t4 SET x=0, y=1;
  292. }
  293. } {1 {constraint failed}}
  294. do_test check-4.7 {
  295. execsql {
  296. SELECT * FROM t4;
  297. }
  298. } {12 -22}
  299. do_test check-4.8 {
  300. execsql {
  301. PRAGMA ignore_check_constraints=ON;
  302. UPDATE t4 SET x=0, y=1;
  303. SELECT * FROM t4;
  304. }
  305. } {0 1}
  306. do_test check-4.9 {
  307. catchsql {
  308. PRAGMA ignore_check_constraints=OFF;
  309. UPDATE t4 SET x=0, y=2;
  310. }
  311. } {1 {constraint failed}}
  312. ifcapable vacuum {
  313. do_test check_4.10 {
  314. catchsql {
  315. VACUUM
  316. }
  317. } {0 {}}
  318. }
  319. do_test check-5.1 {
  320. catchsql {
  321. CREATE TABLE t5(x, y,
  322. CHECK( x*y<:abc )
  323. );
  324. }
  325. } {1 {parameters prohibited in CHECK constraints}}
  326. do_test check-5.2 {
  327. catchsql {
  328. CREATE TABLE t5(x, y,
  329. CHECK( x*y<? )
  330. );
  331. }
  332. } {1 {parameters prohibited in CHECK constraints}}
  333. ifcapable conflict {
  334. do_test check-6.1 {
  335. execsql {SELECT * FROM t1}
  336. } {4 11.0}
  337. do_test check-6.2 {
  338. execsql {
  339. UPDATE OR IGNORE t1 SET x=5;
  340. SELECT * FROM t1;
  341. }
  342. } {4 11.0}
  343. do_test check-6.3 {
  344. execsql {
  345. INSERT OR IGNORE INTO t1 VALUES(5,4.0);
  346. SELECT * FROM t1;
  347. }
  348. } {4 11.0}
  349. do_test check-6.4 {
  350. execsql {
  351. INSERT OR IGNORE INTO t1 VALUES(2,20.0);
  352. SELECT * FROM t1;
  353. }
  354. } {4 11.0 2 20.0}
  355. do_test check-6.5 {
  356. catchsql {
  357. UPDATE OR FAIL t1 SET x=7-x, y=y+1;
  358. }
  359. } {1 {constraint failed}}
  360. do_test check-6.6 {
  361. execsql {
  362. SELECT * FROM t1;
  363. }
  364. } {3 12.0 2 20.0}
  365. do_test check-6.7 {
  366. catchsql {
  367. BEGIN;
  368. INSERT INTO t1 VALUES(1,30.0);
  369. INSERT OR ROLLBACK INTO t1 VALUES(8,40.0);
  370. }
  371. } {1 {constraint failed}}
  372. do_test check-6.8 {
  373. catchsql {
  374. COMMIT;
  375. }
  376. } {1 {cannot commit - no transaction is active}}
  377. do_test check-6.9 {
  378. execsql {
  379. SELECT * FROM t1
  380. }
  381. } {3 12.0 2 20.0}
  382. do_test check-6.11 {
  383. execsql {SELECT * FROM t1}
  384. } {3 12.0 2 20.0}
  385. do_test check-6.12 {
  386. catchsql {
  387. REPLACE INTO t1 VALUES(6,7);
  388. }
  389. } {1 {constraint failed}}
  390. do_test check-6.13 {
  391. execsql {SELECT * FROM t1}
  392. } {3 12.0 2 20.0}
  393. do_test check-6.14 {
  394. catchsql {
  395. INSERT OR IGNORE INTO t1 VALUES(6,7);
  396. }
  397. } {0 {}}
  398. do_test check-6.15 {
  399. execsql {SELECT * FROM t1}
  400. } {3 12.0 2 20.0}
  401. }
  402. #--------------------------------------------------------------------------
  403. # If a connection opens a database that contains a CHECK constraint that
  404. # uses an unknown UDF, the schema should not be considered malformed.
  405. # Attempting to modify the table should fail (since the CHECK constraint
  406. # cannot be tested).
  407. #
  408. reset_db
  409. proc myfunc {x} {expr $x < 10}
  410. db func myfunc myfunc
  411. do_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
  412. do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) }
  413. do_catchsql_test 7.3 { INSERT INTO t6 VALUES(11) } {1 {constraint failed}}
  414. do_test 7.4 {
  415. sqlite3 db2 test.db
  416. execsql { SELECT * FROM t6 } db2
  417. } {9}
  418. do_test 7.5 {
  419. catchsql { INSERT INTO t6 VALUES(8) } db2
  420. } {1 {unknown function: myfunc()}}
  421. do_test 7.6 {
  422. catchsql { CREATE TABLE t7(a CHECK (myfunc(a))) } db2
  423. } {1 {no such function: myfunc}}
  424. do_test 7.7 {
  425. db2 func myfunc myfunc
  426. execsql { INSERT INTO t6 VALUES(8) } db2
  427. } {}
  428. do_test 7.8 {
  429. db2 func myfunc myfunc
  430. catchsql { INSERT INTO t6 VALUES(12) } db2
  431. } {1 {constraint failed}}
  432. # 2013-08-02: Silently ignore database name qualifiers in CHECK constraints.
  433. #
  434. do_execsql_test 8.1 {
  435. CREATE TABLE t810(a, CHECK( main.t810.a>0 ));
  436. CREATE TABLE t811(b, CHECK( xyzzy.t811.b BETWEEN 5 AND 10 ));
  437. } {}
  438. finish_test