1ffe07b2dSdrh# 2005 November 2 2ffe07b2dSdrh# 3ffe07b2dSdrh# The author disclaims copyright to this source code. In place of 4ffe07b2dSdrh# a legal notice, here is a blessing: 5ffe07b2dSdrh# 6ffe07b2dSdrh# May you do good and not evil. 7ffe07b2dSdrh# May you find forgiveness for yourself and forgive others. 8ffe07b2dSdrh# May you share freely, never taking more than you give. 9ffe07b2dSdrh# 10ffe07b2dSdrh#*********************************************************************** 11ffe07b2dSdrh# This file implements regression tests for SQLite library. The 12ffe07b2dSdrh# focus of this file is testing CHECK constraints 13ffe07b2dSdrh# 14ffe07b2dSdrh 15ffe07b2dSdrhset testdir [file dirname $argv0] 16ffe07b2dSdrhsource $testdir/tester.tcl 17ddd1fc72Sdrhset ::testprefix check 18ffe07b2dSdrh 19ffe07b2dSdrh# Only run these tests if the build includes support for CHECK constraints 20ffe07b2dSdrhifcapable !check { 21ffe07b2dSdrh finish_test 22ffe07b2dSdrh return 23ffe07b2dSdrh} 24*7d44b22dSdrhsqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 1 25*7d44b22dSdrhsqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1 26ffe07b2dSdrh 27ffe07b2dSdrhdo_test check-1.1 { 28ffe07b2dSdrh execsql { 29ffe07b2dSdrh CREATE TABLE t1( 30ffe07b2dSdrh x INTEGER CHECK( x<5 ), 31ffe07b2dSdrh y REAL CHECK( y>x ) 32ffe07b2dSdrh ); 33ffe07b2dSdrh } 34ffe07b2dSdrh} {} 35ffe07b2dSdrhdo_test check-1.2 { 36ffe07b2dSdrh execsql { 37ffe07b2dSdrh INSERT INTO t1 VALUES(3,4); 38ffe07b2dSdrh SELECT * FROM t1; 39ffe07b2dSdrh } 408a51256cSdrh} {3 4.0} 41ffe07b2dSdrhdo_test check-1.3 { 42ffe07b2dSdrh catchsql { 43ffe07b2dSdrh INSERT INTO t1 VALUES(6,7); 44ffe07b2dSdrh } 4592e21ef0Sdrh} {1 {CHECK constraint failed: x<5}} 46ffe07b2dSdrhdo_test check-1.4 { 47ffe07b2dSdrh execsql { 48ffe07b2dSdrh SELECT * FROM t1; 49ffe07b2dSdrh } 508a51256cSdrh} {3 4.0} 51ffe07b2dSdrhdo_test check-1.5 { 52ffe07b2dSdrh catchsql { 53ffe07b2dSdrh INSERT INTO t1 VALUES(4,3); 54ffe07b2dSdrh } 5592e21ef0Sdrh} {1 {CHECK constraint failed: y>x}} 56ffe07b2dSdrhdo_test check-1.6 { 57ffe07b2dSdrh execsql { 58ffe07b2dSdrh SELECT * FROM t1; 59ffe07b2dSdrh } 608a51256cSdrh} {3 4.0} 61ffe07b2dSdrhdo_test check-1.7 { 62ffe07b2dSdrh catchsql { 63ffe07b2dSdrh INSERT INTO t1 VALUES(NULL,6); 64ffe07b2dSdrh } 656275b88bSdrh} {0 {}} 66ffe07b2dSdrhdo_test check-1.8 { 67ffe07b2dSdrh execsql { 68ffe07b2dSdrh SELECT * FROM t1; 69ffe07b2dSdrh } 708a51256cSdrh} {3 4.0 {} 6.0} 71ffe07b2dSdrhdo_test check-1.9 { 72ffe07b2dSdrh catchsql { 73ffe07b2dSdrh INSERT INTO t1 VALUES(2,NULL); 74ffe07b2dSdrh } 756275b88bSdrh} {0 {}} 76ffe07b2dSdrhdo_test check-1.10 { 77ffe07b2dSdrh execsql { 78ffe07b2dSdrh SELECT * FROM t1; 79ffe07b2dSdrh } 808a51256cSdrh} {3 4.0 {} 6.0 2 {}} 81ffe07b2dSdrhdo_test check-1.11 { 82ffe07b2dSdrh execsql { 836275b88bSdrh DELETE FROM t1 WHERE x IS NULL OR x!=3; 84ffe07b2dSdrh UPDATE t1 SET x=2 WHERE x==3; 85ffe07b2dSdrh SELECT * FROM t1; 86ffe07b2dSdrh } 878a51256cSdrh} {2 4.0} 88ffe07b2dSdrhdo_test check-1.12 { 89ffe07b2dSdrh catchsql { 90ffe07b2dSdrh UPDATE t1 SET x=7 WHERE x==2 91ffe07b2dSdrh } 9292e21ef0Sdrh} {1 {CHECK constraint failed: x<5}} 93ffe07b2dSdrhdo_test check-1.13 { 94ffe07b2dSdrh execsql { 95ffe07b2dSdrh SELECT * FROM t1; 96ffe07b2dSdrh } 978a51256cSdrh} {2 4.0} 98ffe07b2dSdrhdo_test check-1.14 { 99ffe07b2dSdrh catchsql { 100ffe07b2dSdrh UPDATE t1 SET x=5 WHERE x==2 101ffe07b2dSdrh } 10292e21ef0Sdrh} {1 {CHECK constraint failed: x<5}} 103ffe07b2dSdrhdo_test check-1.15 { 104ffe07b2dSdrh execsql { 105ffe07b2dSdrh SELECT * FROM t1; 106ffe07b2dSdrh } 1078a51256cSdrh} {2 4.0} 108ffe07b2dSdrhdo_test check-1.16 { 109ffe07b2dSdrh catchsql { 110ffe07b2dSdrh UPDATE t1 SET x=4, y=11 WHERE x==2 111ffe07b2dSdrh } 112ffe07b2dSdrh} {0 {}} 113ffe07b2dSdrhdo_test check-1.17 { 114ffe07b2dSdrh execsql { 115ffe07b2dSdrh SELECT * FROM t1; 116ffe07b2dSdrh } 1178a51256cSdrh} {4 11.0} 118ffe07b2dSdrh 119ffe07b2dSdrhdo_test check-2.1 { 120ffe07b2dSdrh execsql { 1210d92571dSdan PRAGMA writable_schema = 1; 122ffe07b2dSdrh CREATE TABLE t2( 1232938f924Sdrh x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ), 1242938f924Sdrh y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), 1252938f924Sdrh z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) 126ffe07b2dSdrh ); 127bffdd636Sdrh CREATE TABLE t2n( 128bffdd636Sdrh x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ), 129bffdd636Sdrh y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), 130bffdd636Sdrh z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) 131bffdd636Sdrh ); 1320d92571dSdan PRAGMA writable_schema = 0; 133ffe07b2dSdrh } 134ffe07b2dSdrh} {} 135ffe07b2dSdrhdo_test check-2.2 { 136ffe07b2dSdrh execsql { 137ffe07b2dSdrh INSERT INTO t2 VALUES(1,2.2,'three'); 138ffe07b2dSdrh SELECT * FROM t2; 139ffe07b2dSdrh } 140ffe07b2dSdrh} {1 2.2 three} 141d9da78a2Sdrhdb close 142d9da78a2Sdrhsqlite3 db test.db 143*7d44b22dSdrhsqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 1 144*7d44b22dSdrhsqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1 145ffe07b2dSdrhdo_test check-2.3 { 146ffe07b2dSdrh execsql { 147ffe07b2dSdrh INSERT INTO t2 VALUES(NULL, NULL, NULL); 148ffe07b2dSdrh SELECT * FROM t2; 149ffe07b2dSdrh } 150ffe07b2dSdrh} {1 2.2 three {} {} {}} 151ffe07b2dSdrhdo_test check-2.4 { 152ffe07b2dSdrh catchsql { 153ffe07b2dSdrh INSERT INTO t2 VALUES(1.1, NULL, NULL); 154ffe07b2dSdrh } 155f9c8ce3cSdrh} {1 {CHECK constraint failed: one}} 156ffe07b2dSdrhdo_test check-2.5 { 157bffdd636Sdrh # The 5 gets automatically promoted to 5.0 because the column type is REAL 158ffe07b2dSdrh catchsql { 159ffe07b2dSdrh INSERT INTO t2 VALUES(NULL, 5, NULL); 160ffe07b2dSdrh } 161bffdd636Sdrh} {0 {}} 162bffdd636Sdrhdo_test check-2.5b { 163bffdd636Sdrh # This time the column type is NUMERIC, so not automatic promption to REAL 164bffdd636Sdrh # occurs and the constraint fails. 165bffdd636Sdrh catchsql { 166bffdd636Sdrh INSERT INTO t2n VALUES(NULL, 5, NULL); 167bffdd636Sdrh } 168f9c8ce3cSdrh} {1 {CHECK constraint failed: two}} 169ffe07b2dSdrhdo_test check-2.6 { 170ffe07b2dSdrh catchsql { 171ffe07b2dSdrh INSERT INTO t2 VALUES(NULL, NULL, 3.14159); 172ffe07b2dSdrh } 1739dce0ef4Sdrh} {0 {}} 174ffe07b2dSdrh 1754dc330ddSdrh# Undocumented behavior: The CONSTRAINT name clause can follow a constraint. 1764dc330ddSdrh# Such a clause is ignored. But the parser must accept it for backwards 1774dc330ddSdrh# compatibility. 1784dc330ddSdrh# 1794dc330ddSdrhdo_test check-2.10 { 1804dc330ddSdrh execsql { 1814dc330ddSdrh CREATE TABLE t2b( 1824dc330ddSdrh x INTEGER CHECK( typeof(coalesce(x,0))=='integer' ) CONSTRAINT one, 1834dc330ddSdrh y TEXT PRIMARY KEY constraint two, 1844dc330ddSdrh z INTEGER, 1854dc330ddSdrh UNIQUE(x,z) constraint three 1864dc330ddSdrh ); 1874dc330ddSdrh } 1884dc330ddSdrh} {} 1894dc330ddSdrhdo_test check-2.11 { 1904dc330ddSdrh catchsql { 1914dc330ddSdrh INSERT INTO t2b VALUES('xyzzy','hi',5); 1924dc330ddSdrh } 19392e21ef0Sdrh} {1 {CHECK constraint failed: typeof(coalesce(x,0))=='integer'}} 1944dc330ddSdrhdo_test check-2.12 { 1954dc330ddSdrh execsql { 1964dc330ddSdrh CREATE TABLE t2c( 1974dc330ddSdrh x INTEGER CONSTRAINT x_one CONSTRAINT x_two 1984dc330ddSdrh CHECK( typeof(coalesce(x,0))=='integer' ) 1994dc330ddSdrh CONSTRAINT x_two CONSTRAINT x_three, 2004dc330ddSdrh y INTEGER, z INTEGER, 2014dc330ddSdrh CONSTRAINT u_one UNIQUE(x,y,z) CONSTRAINT u_two 2024dc330ddSdrh ); 2034dc330ddSdrh } 2044dc330ddSdrh} {} 2054dc330ddSdrhdo_test check-2.13 { 2064dc330ddSdrh catchsql { 2074dc330ddSdrh INSERT INTO t2c VALUES('xyzzy',7,8); 2084dc330ddSdrh } 209f9c8ce3cSdrh} {1 {CHECK constraint failed: x_two}} 2104dc330ddSdrhdo_test check-2.cleanup { 2114dc330ddSdrh execsql { 2124dc330ddSdrh DROP TABLE IF EXISTS t2b; 2134dc330ddSdrh DROP TABLE IF EXISTS t2c; 214bffdd636Sdrh DROP TABLE IF EXISTS t2n; 2154dc330ddSdrh } 2164dc330ddSdrh} {} 2174dc330ddSdrh 2181576cd92Sdanielk1977ifcapable subquery { 21906f6541eSdrh do_test check-3.1 { 22006f6541eSdrh catchsql { 22106f6541eSdrh CREATE TABLE t3( 22206f6541eSdrh x, y, z, 22306f6541eSdrh CHECK( x<(SELECT min(x) FROM t1) ) 22406f6541eSdrh ); 22506f6541eSdrh } 22606f6541eSdrh } {1 {subqueries prohibited in CHECK constraints}} 2271576cd92Sdanielk1977} 2281576cd92Sdanielk1977 22906f6541eSdrhdo_test check-3.2 { 23006f6541eSdrh execsql { 23106f6541eSdrh SELECT name FROM sqlite_master ORDER BY name 23206f6541eSdrh } 23306f6541eSdrh} {t1 t2} 23406f6541eSdrhdo_test check-3.3 { 23506f6541eSdrh catchsql { 23606f6541eSdrh CREATE TABLE t3( 23706f6541eSdrh x, y, z, 23806f6541eSdrh CHECK( q<x ) 23906f6541eSdrh ); 24006f6541eSdrh } 24106f6541eSdrh} {1 {no such column: q}} 24206f6541eSdrhdo_test check-3.4 { 24306f6541eSdrh execsql { 24406f6541eSdrh SELECT name FROM sqlite_master ORDER BY name 24506f6541eSdrh } 24606f6541eSdrh} {t1 t2} 24706f6541eSdrhdo_test check-3.5 { 24806f6541eSdrh catchsql { 24906f6541eSdrh CREATE TABLE t3( 25006f6541eSdrh x, y, z, 25106f6541eSdrh CHECK( t2.x<x ) 25206f6541eSdrh ); 25306f6541eSdrh } 25406f6541eSdrh} {1 {no such column: t2.x}} 25506f6541eSdrhdo_test check-3.6 { 25606f6541eSdrh execsql { 25706f6541eSdrh SELECT name FROM sqlite_master ORDER BY name 25806f6541eSdrh } 25906f6541eSdrh} {t1 t2} 26006f6541eSdrhdo_test check-3.7 { 26106f6541eSdrh catchsql { 26206f6541eSdrh CREATE TABLE t3( 26306f6541eSdrh x, y, z, 26406f6541eSdrh CHECK( t3.x<25 ) 26506f6541eSdrh ); 26606f6541eSdrh } 26706f6541eSdrh} {0 {}} 26806f6541eSdrhdo_test check-3.8 { 26906f6541eSdrh execsql { 27006f6541eSdrh INSERT INTO t3 VALUES(1,2,3); 27106f6541eSdrh SELECT * FROM t3; 27206f6541eSdrh } 27306f6541eSdrh} {1 2 3} 27406f6541eSdrhdo_test check-3.9 { 27506f6541eSdrh catchsql { 27606f6541eSdrh INSERT INTO t3 VALUES(111,222,333); 27706f6541eSdrh } 27892e21ef0Sdrh} {1 {CHECK constraint failed: t3.x<25}} 27906f6541eSdrh 28006f6541eSdrhdo_test check-4.1 { 28106f6541eSdrh execsql { 28206f6541eSdrh CREATE TABLE t4(x, y, 28306f6541eSdrh CHECK ( 28406f6541eSdrh x+y==11 28506f6541eSdrh OR x*y==12 28606f6541eSdrh OR x/y BETWEEN 5 AND 8 28706f6541eSdrh OR -x==y+10 28806f6541eSdrh ) 28906f6541eSdrh ); 29006f6541eSdrh } 29106f6541eSdrh} {} 29206f6541eSdrhdo_test check-4.2 { 29306f6541eSdrh execsql { 29406f6541eSdrh INSERT INTO t4 VALUES(1,10); 29506f6541eSdrh SELECT * FROM t4 29606f6541eSdrh } 29706f6541eSdrh} {1 10} 29806f6541eSdrhdo_test check-4.3 { 29906f6541eSdrh execsql { 30006f6541eSdrh UPDATE t4 SET x=4, y=3; 30106f6541eSdrh SELECT * FROM t4 30206f6541eSdrh } 30306f6541eSdrh} {4 3} 304f33a7a8cSshanehdo_test check-4.4 { 30506f6541eSdrh execsql { 30606f6541eSdrh UPDATE t4 SET x=12, y=2; 30706f6541eSdrh SELECT * FROM t4 30806f6541eSdrh } 30906f6541eSdrh} {12 2} 310f33a7a8cSshanehdo_test check-4.5 { 31106f6541eSdrh execsql { 31206f6541eSdrh UPDATE t4 SET x=12, y=-22; 31306f6541eSdrh SELECT * FROM t4 31406f6541eSdrh } 31506f6541eSdrh} {12 -22} 316f33a7a8cSshanehdo_test check-4.6 { 31706f6541eSdrh catchsql { 31806f6541eSdrh UPDATE t4 SET x=0, y=1; 31906f6541eSdrh } 32092e21ef0Sdrh} {1 {CHECK constraint failed: x+y==11 32192e21ef0Sdrh OR x*y==12 32292e21ef0Sdrh OR x/y BETWEEN 5 AND 8 32392e21ef0Sdrh OR -x==y+10}} 324f33a7a8cSshanehdo_test check-4.7 { 32506f6541eSdrh execsql { 32606f6541eSdrh SELECT * FROM t4; 32706f6541eSdrh } 32806f6541eSdrh} {12 -22} 329f33a7a8cSshanehdo_test check-4.8 { 3300cd2d4c9Sdrh execsql { 3310cd2d4c9Sdrh PRAGMA ignore_check_constraints=ON; 3320cd2d4c9Sdrh UPDATE t4 SET x=0, y=1; 3330cd2d4c9Sdrh SELECT * FROM t4; 3348a284dceSdrh PRAGMA integrity_check; 3350cd2d4c9Sdrh } 3368a284dceSdrh} {0 1 ok} 3378a284dceSdrhdo_execsql_test check-4.8.1 { 3388a284dceSdrh PRAGMA ignore_check_constraints=OFF; 3398a284dceSdrh PRAGMA integrity_check; 3408a284dceSdrh} {{CHECK constraint failed in t4}} 341f33a7a8cSshanehdo_test check-4.9 { 3420cd2d4c9Sdrh catchsql { 3430cd2d4c9Sdrh UPDATE t4 SET x=0, y=2; 3440cd2d4c9Sdrh } 34592e21ef0Sdrh} {1 {CHECK constraint failed: x+y==11 34692e21ef0Sdrh OR x*y==12 34792e21ef0Sdrh OR x/y BETWEEN 5 AND 8 34892e21ef0Sdrh OR -x==y+10}} 3493bdca9c9Sdanielk1977ifcapable vacuum { 350f33a7a8cSshaneh do_test check_4.10 { 3510cd2d4c9Sdrh catchsql { 3520cd2d4c9Sdrh VACUUM 3530cd2d4c9Sdrh } 3540cd2d4c9Sdrh } {0 {}} 3553bdca9c9Sdanielk1977} 3560cd2d4c9Sdrh 3574284fb07Sdrhdo_test check-5.1 { 3584284fb07Sdrh catchsql { 3594284fb07Sdrh CREATE TABLE t5(x, y, 3604284fb07Sdrh CHECK( x*y<:abc ) 3614284fb07Sdrh ); 3624284fb07Sdrh } 3634284fb07Sdrh} {1 {parameters prohibited in CHECK constraints}} 3644284fb07Sdrhdo_test check-5.2 { 3654284fb07Sdrh catchsql { 3664284fb07Sdrh CREATE TABLE t5(x, y, 3674284fb07Sdrh CHECK( x*y<? ) 3684284fb07Sdrh ); 3694284fb07Sdrh } 3704284fb07Sdrh} {1 {parameters prohibited in CHECK constraints}} 3714284fb07Sdrh 3724b2688abSdanielk1977ifcapable conflict { 3734b2688abSdanielk1977 374aa01c7e2Sdrhdo_test check-6.1 { 375aa01c7e2Sdrh execsql {SELECT * FROM t1} 376aa01c7e2Sdrh} {4 11.0} 377aa01c7e2Sdrhdo_test check-6.2 { 378aa01c7e2Sdrh execsql { 379aa01c7e2Sdrh UPDATE OR IGNORE t1 SET x=5; 380aa01c7e2Sdrh SELECT * FROM t1; 381aa01c7e2Sdrh } 382aa01c7e2Sdrh} {4 11.0} 383aa01c7e2Sdrhdo_test check-6.3 { 384aa01c7e2Sdrh execsql { 385aa01c7e2Sdrh INSERT OR IGNORE INTO t1 VALUES(5,4.0); 386aa01c7e2Sdrh SELECT * FROM t1; 387aa01c7e2Sdrh } 388aa01c7e2Sdrh} {4 11.0} 389aa01c7e2Sdrhdo_test check-6.4 { 390aa01c7e2Sdrh execsql { 391aa01c7e2Sdrh INSERT OR IGNORE INTO t1 VALUES(2,20.0); 392aa01c7e2Sdrh SELECT * FROM t1; 393aa01c7e2Sdrh } 394aa01c7e2Sdrh} {4 11.0 2 20.0} 395aa01c7e2Sdrhdo_test check-6.5 { 396aa01c7e2Sdrh catchsql { 397aa01c7e2Sdrh UPDATE OR FAIL t1 SET x=7-x, y=y+1; 398aa01c7e2Sdrh } 39992e21ef0Sdrh} {1 {CHECK constraint failed: x<5}} 400aa01c7e2Sdrhdo_test check-6.6 { 401aa01c7e2Sdrh execsql { 402aa01c7e2Sdrh SELECT * FROM t1; 403aa01c7e2Sdrh } 404aa01c7e2Sdrh} {3 12.0 2 20.0} 405aa01c7e2Sdrhdo_test check-6.7 { 406aa01c7e2Sdrh catchsql { 407aa01c7e2Sdrh BEGIN; 408aa01c7e2Sdrh INSERT INTO t1 VALUES(1,30.0); 409aa01c7e2Sdrh INSERT OR ROLLBACK INTO t1 VALUES(8,40.0); 410aa01c7e2Sdrh } 41192e21ef0Sdrh} {1 {CHECK constraint failed: x<5}} 412aa01c7e2Sdrhdo_test check-6.8 { 413aa01c7e2Sdrh catchsql { 414aa01c7e2Sdrh COMMIT; 415aa01c7e2Sdrh } 416aa01c7e2Sdrh} {1 {cannot commit - no transaction is active}} 417aa01c7e2Sdrhdo_test check-6.9 { 418aa01c7e2Sdrh execsql { 419aa01c7e2Sdrh SELECT * FROM t1 420aa01c7e2Sdrh } 421aa01c7e2Sdrh} {3 12.0 2 20.0} 422aa01c7e2Sdrh 4232e06c67cSdrhdo_test check-6.11 { 4242e06c67cSdrh execsql {SELECT * FROM t1} 4252e06c67cSdrh} {3 12.0 2 20.0} 4262e06c67cSdrhdo_test check-6.12 { 4272e06c67cSdrh catchsql { 4282e06c67cSdrh REPLACE INTO t1 VALUES(6,7); 4292e06c67cSdrh } 43092e21ef0Sdrh} {1 {CHECK constraint failed: x<5}} 4312e06c67cSdrhdo_test check-6.13 { 4322e06c67cSdrh execsql {SELECT * FROM t1} 4332e06c67cSdrh} {3 12.0 2 20.0} 4342e06c67cSdrhdo_test check-6.14 { 4352e06c67cSdrh catchsql { 4362e06c67cSdrh INSERT OR IGNORE INTO t1 VALUES(6,7); 4372e06c67cSdrh } 4382e06c67cSdrh} {0 {}} 4392e06c67cSdrhdo_test check-6.15 { 4402e06c67cSdrh execsql {SELECT * FROM t1} 4412e06c67cSdrh} {3 12.0 2 20.0} 4422e06c67cSdrh 4432e06c67cSdrh 4444b2688abSdanielk1977} 44506f6541eSdrh 446ddd1fc72Sdrh#-------------------------------------------------------------------------- 447ddd1fc72Sdrh# If a connection opens a database that contains a CHECK constraint that 448ddd1fc72Sdrh# uses an unknown UDF, the schema should not be considered malformed. 449ddd1fc72Sdrh# Attempting to modify the table should fail (since the CHECK constraint 450ddd1fc72Sdrh# cannot be tested). 451ddd1fc72Sdrh# 452ddd1fc72Sdrhreset_db 453ddd1fc72Sdrhproc myfunc {x} {expr $x < 10} 45420cee7d0Sdrhdb func myfunc -deterministic myfunc 455ddd1fc72Sdrh 456ddd1fc72Sdrhdo_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) } 457ddd1fc72Sdrhdo_execsql_test 7.2 { INSERT INTO t6 VALUES(9) } 458f9c8ce3cSdrhdo_catchsql_test 7.3 { INSERT INTO t6 VALUES(11) } \ 45992e21ef0Sdrh {1 {CHECK constraint failed: myfunc(a)}} 460ddd1fc72Sdrh 461ddd1fc72Sdrhdo_test 7.4 { 462ddd1fc72Sdrh sqlite3 db2 test.db 463ddd1fc72Sdrh execsql { SELECT * FROM t6 } db2 464ddd1fc72Sdrh} {9} 465ddd1fc72Sdrh 466ddd1fc72Sdrhdo_test 7.5 { 467ddd1fc72Sdrh catchsql { INSERT INTO t6 VALUES(8) } db2 468ddd1fc72Sdrh} {1 {unknown function: myfunc()}} 469ddd1fc72Sdrh 470ddd1fc72Sdrhdo_test 7.6 { 471ddd1fc72Sdrh catchsql { CREATE TABLE t7(a CHECK (myfunc(a))) } db2 472ddd1fc72Sdrh} {1 {no such function: myfunc}} 473ddd1fc72Sdrh 474ddd1fc72Sdrhdo_test 7.7 { 475ddd1fc72Sdrh db2 func myfunc myfunc 476ddd1fc72Sdrh execsql { INSERT INTO t6 VALUES(8) } db2 477ddd1fc72Sdrh} {} 478ddd1fc72Sdrh 479ddd1fc72Sdrhdo_test 7.8 { 480ddd1fc72Sdrh db2 func myfunc myfunc 481ddd1fc72Sdrh catchsql { INSERT INTO t6 VALUES(12) } db2 48292e21ef0Sdrh} {1 {CHECK constraint failed: myfunc(a)}} 483ddd1fc72Sdrh 4841e7d43c9Sdrh# 2013-08-02: Silently ignore database name qualifiers in CHECK constraints. 4851e7d43c9Sdrh# 4861e7d43c9Sdrhdo_execsql_test 8.1 { 4871e7d43c9Sdrh CREATE TABLE t810(a, CHECK( main.t810.a>0 )); 4881e7d43c9Sdrh CREATE TABLE t811(b, CHECK( xyzzy.t811.b BETWEEN 5 AND 10 )); 4891e7d43c9Sdrh} {} 490ddd1fc72Sdrh 49198bfa16dSdrh# Make sure check constraints involving the ROWID are not ignored 49298bfa16dSdrh# 49398bfa16dSdrhdo_execsql_test 9.1 { 49498bfa16dSdrh CREATE TABLE t1( 49598bfa16dSdrh a INTEGER PRIMARY KEY, 49698bfa16dSdrh b INTEGER NOT NULL CONSTRAINT 'b-check' CHECK( b>a ), 49798bfa16dSdrh c INTEGER NOT NULL CONSTRAINT 'c-check' CHECK( c>rowid*2 ), 49898bfa16dSdrh d INTEGER NOT NULL CONSTRAINT 'd-check' CHECK( d BETWEEN b AND c ) 49998bfa16dSdrh ); 50098bfa16dSdrh INSERT INTO t1(a,b,c,d) VALUES(1,2,4,3),(2,4,6,5),(3,10,30,20); 50198bfa16dSdrh} {} 50298bfa16dSdrhdo_catchsql_test 9.2 { 50398bfa16dSdrh UPDATE t1 SET b=0 WHERE a=1; 50498bfa16dSdrh} {1 {CHECK constraint failed: b-check}} 50598bfa16dSdrhdo_catchsql_test 9.3 { 50698bfa16dSdrh UPDATE t1 SET c=a*2 WHERE a=1; 50798bfa16dSdrh} {1 {CHECK constraint failed: c-check}} 50898bfa16dSdrh 509a3b2da98Sdrh# Integrity check on a VIEW with columns. 510a3b2da98Sdrh# 511a3b2da98Sdrhdb close 512978896e0Sdrhdb2 close 513a3b2da98Sdrhforcedelete test.db 514a3b2da98Sdrhsqlite3 db test.db 515a3b2da98Sdrhdo_execsql_test 10.1 { 516a3b2da98Sdrh CREATE TABLE t1(x); 517a3b2da98Sdrh CREATE VIEW v1(y) AS SELECT x FROM t1; 518a3b2da98Sdrh PRAGMA integrity_check; 519a3b2da98Sdrh} {ok} 52098bfa16dSdrh 5218b65e591Sdan#------------------------------------------------------------------------- 5228b65e591Sdanreset_db 5238b65e591Sdando_execsql_test 11.0 { 5248b65e591Sdan CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ; 5258b65e591Sdan} 5268b65e591Sdando_execsql_test 11.1 { 5278b65e591Sdan INSERT INTO t1 VALUES (NULL); 5288b65e591Sdan} 5298b65e591Sdando_execsql_test 11.2 { 5308b65e591Sdan INSERT INTO t1 VALUES (NULL); 5318b65e591Sdan} 5328b65e591Sdan 5338b65e591Sdando_execsql_test 11.3 { 5348b65e591Sdan CREATE TABLE t2(b, a CHECK( 5358b65e591Sdan CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END) 5368b65e591Sdan ); 5378b65e591Sdan} 5388b65e591Sdando_execsql_test 11.4 { 5398b65e591Sdan INSERT INTO t2(a) VALUES('abc'); 5408b65e591Sdan} 5418b65e591Sdando_execsql_test 11.5 { 5428b65e591Sdan INSERT INTO t2(b, a) VALUES(1, 'abc'||''); 5438b65e591Sdan} 5448b65e591Sdando_execsql_test 11.6 { 5458b65e591Sdan INSERT INTO t2(b, a) VALUES(2, 'abc'); 5468b65e591Sdan} 5478b65e591Sdan 54822c04f81Sdrh# 2019-12-24 ticket b383b90278186263 54922c04f81Sdrh# 55022c04f81Sdrhreset_db 55122c04f81Sdrhdo_execsql_test 12.10 { 55222c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(a=+a)); 55322c04f81Sdrh INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75); 55422c04f81Sdrh SELECT quote(a) FROM t1 ORDER BY rowid; 55522c04f81Sdrh} {NULL 'xyz' '5' X'303132' '4.75'} 55622c04f81Sdrhdo_execsql_test 12.20 { 55722c04f81Sdrh DROP TABLE t1; 55822c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(a<>+a)); 55922c04f81Sdrh INSERT INTO t1(a) VALUES(NULL); 56022c04f81Sdrh} {} 56122c04f81Sdrhdo_catchsql_test 12.21 { 56222c04f81Sdrh INSERT INTO t1(a) VALUES('xyz'); 56392e21ef0Sdrh} {1 {CHECK constraint failed: a<>+a}} 56422c04f81Sdrhdo_catchsql_test 12.22 { 56522c04f81Sdrh INSERT INTO t1(a) VALUES(123); 56692e21ef0Sdrh} {1 {CHECK constraint failed: a<>+a}} 56722c04f81Sdrhdo_execsql_test 12.30 { 56822c04f81Sdrh DROP TABLE t1; 56922c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(NOT(a=+a))); 57022c04f81Sdrh INSERT INTO t1(a) VALUES(NULL); 57122c04f81Sdrh} {} 57222c04f81Sdrhdo_catchsql_test 12.31 { 57322c04f81Sdrh INSERT INTO t1(a) VALUES('xyz'); 57492e21ef0Sdrh} {1 {CHECK constraint failed: NOT(a=+a)}} 57522c04f81Sdrhdo_catchsql_test 12.32 { 57622c04f81Sdrh INSERT INTO t1(a) VALUES(123); 57792e21ef0Sdrh} {1 {CHECK constraint failed: NOT(a=+a)}} 57822c04f81Sdrhdo_execsql_test 12.40 { 57922c04f81Sdrh DROP TABLE t1; 58022c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(NOT(a<>+a))); 58122c04f81Sdrh INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75); 58222c04f81Sdrh SELECT quote(a) FROM t1 ORDER BY rowid; 58322c04f81Sdrh} {NULL 'xyz' '5' X'303132' '4.75'} 58422c04f81Sdrhdo_execsql_test 12.50 { 58522c04f81Sdrh DROP TABLE t1; 58622c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(a BETWEEN 0 AND +a)); 58722c04f81Sdrh INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75); 58822c04f81Sdrh SELECT quote(a) FROM t1 ORDER BY rowid; 58922c04f81Sdrh} {NULL 'xyz' '5' X'303132' '4.75'} 59022c04f81Sdrhdo_execsql_test 12.60 { 59122c04f81Sdrh DROP TABLE t1; 59222c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN 0 AND +a)); 59322c04f81Sdrh INSERT INTO t1(a) VALUES(NULL); 59422c04f81Sdrh SELECT quote(a) FROM t1 ORDER BY rowid; 59522c04f81Sdrh} {NULL} 59622c04f81Sdrhdo_catchsql_test 12.61 { 59722c04f81Sdrh INSERT INTO t1(a) VALUES(456); 59892e21ef0Sdrh} {1 {CHECK constraint failed: a NOT BETWEEN 0 AND +a}} 59922c04f81Sdrhdo_execsql_test 12.70 { 60022c04f81Sdrh DROP TABLE t1; 60122c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(a BETWEEN +a AND 999999)); 60222c04f81Sdrh INSERT INTO t1(a) VALUES(NULL),(5); 60322c04f81Sdrh SELECT quote(a) FROM t1 ORDER BY rowid; 60422c04f81Sdrh} {NULL '5'} 60522c04f81Sdrhdo_execsql_test 12.80 { 60622c04f81Sdrh DROP TABLE t1; 60722c04f81Sdrh CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN +a AND 999999)); 60822c04f81Sdrh INSERT INTO t1(a) VALUES(NULL); 60922c04f81Sdrh SELECT quote(a) FROM t1 ORDER BY rowid; 61022c04f81Sdrh} {NULL} 61122c04f81Sdrhdo_catchsql_test 12.81 { 61222c04f81Sdrh INSERT INTO t1(a) VALUES(456); 61392e21ef0Sdrh} {1 {CHECK constraint failed: a NOT BETWEEN +a AND 999999}} 6148b65e591Sdan 615ffe07b2dSdrhfinish_test 616