3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing CHECK constraints
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set ::testprefix check
19 # Only run these tests if the build includes support for CHECK constraints
24 sqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 1
25 sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1
30 x INTEGER CHECK( x<5 ),
37 INSERT INTO t1 VALUES(3,4);
43 INSERT INTO t1 VALUES(6,7);
45 } {1 {CHECK constraint failed: x<5}}
53 INSERT INTO t1 VALUES(4,3);
55 } {1 {CHECK constraint failed: y>x}}
63 INSERT INTO t1 VALUES(NULL,6);
73 INSERT INTO t1 VALUES(2,NULL);
83 DELETE FROM t1 WHERE x IS NULL OR x!=3;
84 UPDATE t1 SET x=2 WHERE x==3;
90 UPDATE t1 SET x=7 WHERE x==2
92 } {1 {CHECK constraint failed: x<5}}
100 UPDATE t1 SET x=5 WHERE x==2
102 } {1 {CHECK constraint failed: x<5}}
110 UPDATE t1 SET x=4, y=11 WHERE x==2
121 PRAGMA writable_schema = 1;
123 x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
124 y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
125 z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
128 x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
129 y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
130 z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
132 PRAGMA writable_schema = 0;
137 INSERT INTO t2 VALUES(1,2.2,'three');
143 sqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 1
144 sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1
147 INSERT INTO t2 VALUES(NULL, NULL, NULL);
150 } {1 2.2 three {} {} {}}
153 INSERT INTO t2 VALUES(1.1, NULL, NULL);
155 } {1 {CHECK constraint failed: one}}
157 # The 5 gets automatically promoted to 5.0 because the column type is REAL
159 INSERT INTO t2 VALUES(NULL, 5, NULL);
163 # This time the column type is NUMERIC, so not automatic promption to REAL
164 # occurs and the constraint fails.
166 INSERT INTO t2n VALUES(NULL, 5, NULL);
168 } {1 {CHECK constraint failed: two}}
171 INSERT INTO t2 VALUES(NULL, NULL, 3.14159);
175 # Undocumented behavior: The CONSTRAINT name clause can follow a constraint.
176 # Such a clause is ignored. But the parser must accept it for backwards
182 x INTEGER CHECK( typeof(coalesce(x,0))=='integer' ) CONSTRAINT one,
183 y TEXT PRIMARY KEY constraint two,
185 UNIQUE(x,z) constraint three
191 INSERT INTO t2b VALUES('xyzzy','hi',5);
193 } {1 {CHECK constraint failed: typeof(coalesce(x,0))=='integer'}}
197 x INTEGER CONSTRAINT x_one CONSTRAINT x_two
198 CHECK( typeof(coalesce(x,0))=='integer' )
199 CONSTRAINT x_two CONSTRAINT x_three,
200 y INTEGER, z INTEGER,
201 CONSTRAINT u_one UNIQUE(x,y,z) CONSTRAINT u_two
207 INSERT INTO t2c VALUES('xyzzy',7,8);
209 } {1 {CHECK constraint failed: x_two}}
210 do_test check-2.cleanup {
212 DROP TABLE IF EXISTS t2b;
213 DROP TABLE IF EXISTS t2c;
214 DROP TABLE IF EXISTS t2n;
223 CHECK( x<(SELECT min(x) FROM t1) )
226 } {1 {subqueries prohibited in CHECK constraints}}
231 SELECT name FROM sqlite_master ORDER BY name
241 } {1 {no such column: q}}
244 SELECT name FROM sqlite_master ORDER BY name
254 } {1 {no such column: t2.x}}
257 SELECT name FROM sqlite_master ORDER BY name
270 INSERT INTO t3 VALUES(1,2,3);
276 INSERT INTO t3 VALUES(111,222,333);
278 } {1 {CHECK constraint failed: t3.x<25}}
282 CREATE TABLE t4(x, y,
286 OR x/y BETWEEN 5 AND 8
294 INSERT INTO t4 VALUES(1,10);
300 UPDATE t4 SET x=4, y=3;
306 UPDATE t4 SET x=12, y=2;
312 UPDATE t4 SET x=12, y=-22;
318 UPDATE t4 SET x=0, y=1;
320 } {1 {CHECK constraint failed: x+y==11
322 OR x/y BETWEEN 5 AND 8
331 PRAGMA ignore_check_constraints=ON;
332 UPDATE t4 SET x=0, y=1;
334 PRAGMA integrity_check;
337 do_execsql_test check-4.8.1 {
338 PRAGMA ignore_check_constraints=OFF;
339 PRAGMA integrity_check;
340 } {{CHECK constraint failed in t4}}
343 UPDATE t4 SET x=0, y=2;
345 } {1 {CHECK constraint failed: x+y==11
347 OR x/y BETWEEN 5 AND 8
359 CREATE TABLE t5(x, y,
363 } {1 {parameters prohibited in CHECK constraints}}
366 CREATE TABLE t5(x, y,
370 } {1 {parameters prohibited in CHECK constraints}}
375 execsql {SELECT * FROM t1}
379 UPDATE OR IGNORE t1 SET x=5;
385 INSERT OR IGNORE INTO t1 VALUES(5,4.0);
391 INSERT OR IGNORE INTO t1 VALUES(2,20.0);
397 UPDATE OR FAIL t1 SET x=7-x, y=y+1;
399 } {1 {CHECK constraint failed: x<5}}
408 INSERT INTO t1 VALUES(1,30.0);
409 INSERT OR ROLLBACK INTO t1 VALUES(8,40.0);
411 } {1 {CHECK constraint failed: x<5}}
416 } {1 {cannot commit - no transaction is active}}
424 execsql {SELECT * FROM t1}
428 REPLACE INTO t1 VALUES(6,7);
430 } {1 {CHECK constraint failed: x<5}}
432 execsql {SELECT * FROM t1}
436 INSERT OR IGNORE INTO t1 VALUES(6,7);
440 execsql {SELECT * FROM t1}
446 #--------------------------------------------------------------------------
447 # If a connection opens a database that contains a CHECK constraint that
448 # uses an unknown UDF, the schema should not be considered malformed.
449 # Attempting to modify the table should fail (since the CHECK constraint
453 proc myfunc {x} {expr $x < 10}
454 db func myfunc -deterministic myfunc
456 do_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
457 do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) }
458 do_catchsql_test 7.3 { INSERT INTO t6 VALUES(11) } \
459 {1 {CHECK constraint failed: myfunc(a)}}
463 execsql { SELECT * FROM t6 } db2
467 catchsql { INSERT INTO t6 VALUES(8) } db2
468 } {1 {unknown function: myfunc()}}
471 catchsql { CREATE TABLE t7(a CHECK (myfunc(a))) } db2
472 } {1 {no such function: myfunc}}
475 db2 func myfunc myfunc
476 execsql { INSERT INTO t6 VALUES(8) } db2
480 db2 func myfunc myfunc
481 catchsql { INSERT INTO t6 VALUES(12) } db2
482 } {1 {CHECK constraint failed: myfunc(a)}}
484 # 2013-08-02: Silently ignore database name qualifiers in CHECK constraints.
486 do_execsql_test 8.1 {
487 CREATE TABLE t810(a, CHECK( main.t810.a>0 ));
488 CREATE TABLE t811(b, CHECK( xyzzy.t811.b BETWEEN 5 AND 10 ));
491 # Make sure check constraints involving the ROWID are not ignored
493 do_execsql_test 9.1 {
495 a INTEGER PRIMARY KEY,
496 b INTEGER NOT NULL CONSTRAINT 'b-check' CHECK( b>a ),
497 c INTEGER NOT NULL CONSTRAINT 'c-check' CHECK( c>rowid*2 ),
498 d INTEGER NOT NULL CONSTRAINT 'd-check' CHECK( d BETWEEN b AND c )
500 INSERT INTO t1(a,b,c,d) VALUES(1,2,4,3),(2,4,6,5),(3,10,30,20);
502 do_catchsql_test 9.2 {
503 UPDATE t1 SET b=0 WHERE a=1;
504 } {1 {CHECK constraint failed: b-check}}
505 do_catchsql_test 9.3 {
506 UPDATE t1 SET c=a*2 WHERE a=1;
507 } {1 {CHECK constraint failed: c-check}}
509 # Integrity check on a VIEW with columns.
515 do_execsql_test 10.1 {
517 CREATE VIEW v1(y) AS SELECT x FROM t1;
518 PRAGMA integrity_check;
521 #-------------------------------------------------------------------------
523 do_execsql_test 11.0 {
524 CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ;
526 do_execsql_test 11.1 {
527 INSERT INTO t1 VALUES (NULL);
529 do_execsql_test 11.2 {
530 INSERT INTO t1 VALUES (NULL);
533 do_execsql_test 11.3 {
534 CREATE TABLE t2(b, a CHECK(
535 CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END)
538 do_execsql_test 11.4 {
539 INSERT INTO t2(a) VALUES('abc');
541 do_execsql_test 11.5 {
542 INSERT INTO t2(b, a) VALUES(1, 'abc'||'');
544 do_execsql_test 11.6 {
545 INSERT INTO t2(b, a) VALUES(2, 'abc');
548 # 2019-12-24 ticket b383b90278186263
551 do_execsql_test 12.10 {
552 CREATE TABLE t1(a TEXT, CHECK(a=+a));
553 INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75);
554 SELECT quote(a) FROM t1 ORDER BY rowid;
555 } {NULL 'xyz' '5' X'303132' '4.75'}
556 do_execsql_test 12.20 {
558 CREATE TABLE t1(a TEXT, CHECK(a<>+a));
559 INSERT INTO t1(a) VALUES(NULL);
561 do_catchsql_test 12.21 {
562 INSERT INTO t1(a) VALUES('xyz');
563 } {1 {CHECK constraint failed: a<>+a}}
564 do_catchsql_test 12.22 {
565 INSERT INTO t1(a) VALUES(123);
566 } {1 {CHECK constraint failed: a<>+a}}
567 do_execsql_test 12.30 {
569 CREATE TABLE t1(a TEXT, CHECK(NOT(a=+a)));
570 INSERT INTO t1(a) VALUES(NULL);
572 do_catchsql_test 12.31 {
573 INSERT INTO t1(a) VALUES('xyz');
574 } {1 {CHECK constraint failed: NOT(a=+a)}}
575 do_catchsql_test 12.32 {
576 INSERT INTO t1(a) VALUES(123);
577 } {1 {CHECK constraint failed: NOT(a=+a)}}
578 do_execsql_test 12.40 {
580 CREATE TABLE t1(a TEXT, CHECK(NOT(a<>+a)));
581 INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75);
582 SELECT quote(a) FROM t1 ORDER BY rowid;
583 } {NULL 'xyz' '5' X'303132' '4.75'}
584 do_execsql_test 12.50 {
586 CREATE TABLE t1(a TEXT, CHECK(a BETWEEN 0 AND +a));
587 INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75);
588 SELECT quote(a) FROM t1 ORDER BY rowid;
589 } {NULL 'xyz' '5' X'303132' '4.75'}
590 do_execsql_test 12.60 {
592 CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN 0 AND +a));
593 INSERT INTO t1(a) VALUES(NULL);
594 SELECT quote(a) FROM t1 ORDER BY rowid;
596 do_catchsql_test 12.61 {
597 INSERT INTO t1(a) VALUES(456);
598 } {1 {CHECK constraint failed: a NOT BETWEEN 0 AND +a}}
599 do_execsql_test 12.70 {
601 CREATE TABLE t1(a TEXT, CHECK(a BETWEEN +a AND 999999));
602 INSERT INTO t1(a) VALUES(NULL),(5);
603 SELECT quote(a) FROM t1 ORDER BY rowid;
605 do_execsql_test 12.80 {
607 CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN +a AND 999999));
608 INSERT INTO t1(a) VALUES(NULL);
609 SELECT quote(a) FROM t1 ORDER BY rowid;
611 do_catchsql_test 12.81 {
612 INSERT INTO t1(a) VALUES(456);
613 } {1 {CHECK constraint failed: a NOT BETWEEN +a AND 999999}}