From 57f7f4b8159d67fb0eb0f09eaabf210aac91990b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 1 Oct 2010 19:04:37 +0000 Subject: [PATCH] Add tests for CHECK and UNIQUE constraints to e_createtable.test. FossilOrigin-Name: fb8db5581d884e5eb380480bc08d2106bfb6a9fc --- manifest | 26 ++----- manifest.uuid | 2 +- test/e_createtable.test | 162 +++++++++++++++++++++++++++++++++++++++- test/tester.tcl | 2 +- 4 files changed, 171 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 789d259600..f81ff04897 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Add\s#ifndef\sUSE_SYSTEM_SQLITE...#endif\saround\sthe\sbundled\sSQLite\slibrary\s\nfor\sthe\sTCL\sbindings. -D 2010-10-01T17:23:46 +C Add\stests\sfor\sCHECK\sand\sUNIQUE\sconstraints\sto\se_createtable.test. +D 2010-10-01T19:04:37 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -351,7 +348,7 @@ F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f F test/diskfull.test 0cede7ef9d8f415d9d3944005c76be7589bb5ebb F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_createtable.test 38ab5e010736c509d88fb1966c2aeb963b4ff9aa +F test/e_createtable.test 03597fda5181b67d18047d14da2a32f07afe95b4 F test/e_delete.test 55d868b647acc091c261a10b9b0cb0ab660a6acb F test/e_expr.test 164e87c1d7b40ceb47c57c3bffa384c81d009aa7 F test/e_fkey.test 6721a741c6499b3ab7e5385923233343c8f1ad05 @@ -647,7 +644,7 @@ F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05 -F test/tester.tcl 7ab20c411c0036004608de3377c9cdc508fde909 +F test/tester.tcl 6d862da591d5d5e4b2e22bb1e8a7c4ed95580b45 F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca @@ -875,14 +872,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P fa97d895463be6fd963c29b4525c2664193e36ec -R cee57623d0da94ad287120e52bf09dfd -U drh -Z 94aa2d05ef6169308b4b7ecdfc934a7a ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMphkmoxKgR168RlERAkoUAJ9D2EvLvDcG6vJ7CRGWxEjsFtif3QCgiTP1 -GWgaXFeonOK9mgFVngfb0pQ= -=GZN0 ------END PGP SIGNATURE----- +P 8d85584a4e0761afa0ff1e9e69036f1a66ab22dc +R 84df20d9e784695fdcd238229530bdad +U dan +Z f52298f78d95d5fe52db83131c12d5d8 diff --git a/manifest.uuid b/manifest.uuid index 33dd06bab8..a67f77cf41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d85584a4e0761afa0ff1e9e69036f1a66ab22dc \ No newline at end of file +fb8db5581d884e5eb380480bc08d2106bfb6a9fc \ No newline at end of file diff --git a/test/e_createtable.test b/test/e_createtable.test index 62fe89ed64..aa42c24893 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -1282,5 +1282,165 @@ do_catchsql_test 4.5.3 { UPDATE t3 SET u = NULL WHERE s = 2; } {1 {datatype mismatch}} -finish_test +# EVIDENCE-OF: R-00227-21080 A UNIQUE constraint is similar to a PRIMARY +# KEY constraint, except that a single table may have any number of +# UNIQUE constraints. +# +drop_all_tables +do_createtable_tests 4.6 { + 1 "CREATE TABLE t1(a UNIQUE, b UNIQUE)" {} + 2 "CREATE TABLE t2(a UNIQUE, b, c, UNIQUE(c, b))" {} + 3 "CREATE TABLE t3(a, b, c, UNIQUE(a), UNIQUE(b), UNIQUE(c))" {} + 4 "CREATE TABLE t4(a, b, c, UNIQUE(a, b, c))" {} +} +# EVIDENCE-OF: R-55240-58877 For each UNIQUE constraint on the table, +# each row must feature a unique combination of values in the columns +# identified by the UNIQUE constraint. +# +# EVIDENCE-OF: R-47733-51480 If an INSERT or UPDATE statement attempts +# to modify the table content so that two or more rows feature identical +# values in a set of columns that are subject to a UNIQUE constraint, it +# is a constraint violation. +# +do_execsql_test 4.7.0 { + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(4.3, 5.5); + INSERT INTO t1 VALUES('reveal', 'variableness'); + INSERT INTO t1 VALUES(X'123456', X'654321'); + + INSERT INTO t4 VALUES('xyx', 1, 1); + INSERT INTO t4 VALUES('xyx', 2, 1); + INSERT INTO t4 VALUES('uvw', 1, 1); +} +do_createtable_tests 4.7.1 -error { %s not unique } { + 1 "INSERT INTO t1 VALUES(1, 'one')" {{column a is}} + 2 "INSERT INTO t1 VALUES(4.3, 'two')" {{column a is}} + 3 "INSERT INTO t1 VALUES('reveal', 'three')" {{column a is}} + 4 "INSERT INTO t1 VALUES(X'123456', 'four')" {{column a is}} + + 5 "UPDATE t1 SET a = 1 WHERE rowid=2" {{column a is}} + 6 "UPDATE t1 SET a = 4.3 WHERE rowid=3" {{column a is}} + 7 "UPDATE t1 SET a = 'reveal' WHERE rowid=4" {{column a is}} + 8 "UPDATE t1 SET a = X'123456' WHERE rowid=1" {{column a is}} + + 9 "INSERT INTO t4 VALUES('xyx', 1, 1)" {{columns a, b, c are}} + 10 "INSERT INTO t4 VALUES('xyx', 2, 1)" {{columns a, b, c are}} + 11 "INSERT INTO t4 VALUES('uvw', 1, 1)" {{columns a, b, c are}} + + 12 "UPDATE t4 SET a='xyx' WHERE rowid=3" {{columns a, b, c are}} + 13 "UPDATE t4 SET b=1 WHERE rowid=2" {{columns a, b, c are}} + 14 "UPDATE t4 SET a=0, b=0, c=0" {{columns a, b, c are}} +} + +# EVIDENCE-OF: R-21289-11559 As with PRIMARY KEY constraints, for the +# purposes of UNIQUE constraints NULL values are considered distinct +# from all other values (including other NULLs). +# +do_createtable_tests 4.8 { + 1 "INSERT INTO t1 VALUES(NULL, NULL)" {} + 2 "INSERT INTO t1 VALUES(NULL, NULL)" {} + 3 "UPDATE t1 SET a = NULL" {} + 4 "UPDATE t1 SET b = NULL" {} + + 5 "INSERT INTO t4 VALUES(NULL, NULL, NULL)" {} + 6 "INSERT INTO t4 VALUES(NULL, NULL, NULL)" {} + 7 "UPDATE t4 SET a = NULL" {} + 8 "UPDATE t4 SET b = NULL" {} + 9 "UPDATE t4 SET c = NULL" {} +} + +# EVIDENCE-OF: R-26983-26377 INTEGER PRIMARY KEY columns aside, both +# UNIQUE and PRIMARY KEY constraints are implemented by creating an +# index in the database (in the same way as a "CREATE UNIQUE INDEX" +# statement would). +do_createtable_tests 4.9 -repair drop_all_tables -query { + SELECT count(*) FROM sqlite_master WHERE type='index' +} { + 1 "CREATE TABLE t1(a TEXT PRIMARY KEY, b)" 1 + 2 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b)" 0 + 3 "CREATE TABLE t1(a TEXT UNIQUE, b)" 1 + 4 "CREATE TABLE t1(a PRIMARY KEY, b TEXT UNIQUE)" 2 + 5 "CREATE TABLE t1(a PRIMARY KEY, b, c, UNIQUE(c, b))" 2 +} + +# EVIDENCE-OF: R-02252-33116 Such an index is used like any other index +# in the database to optimize queries. +# +do_execsql_test 4.10.0 { + CREATE TABLE t1(a, b PRIMARY KEY); + CREATE TABLE t2(a, b, c, UNIQUE(b, c)); +} +do_createtable_tests 4.10 { + 1 "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 5" + {0 0 {TABLE t1 WITH INDEX sqlite_autoindex_t1_1}} + + 2 "EXPLAIN QUERY PLAN SELECT * FROM t2 ORDER BY b, c" + {0 0 {TABLE t2 WITH INDEX sqlite_autoindex_t2_1 ORDER BY}} + + 3 "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE b=10 AND c>10" + {0 0 {TABLE t2 WITH INDEX sqlite_autoindex_t2_1}} +} + +# EVIDENCE-OF: R-45493-35653 A CHECK constraint may be attached to a +# column definition or specified as a table constraint. In practice it +# makes no difference. +# +# All the tests that deal with CHECK constraints below (4.11.* and +# 4.12.*) are run once for a table with the check constraint attached +# to a column definition, and once with a table where the check +# condition is specified as a table constraint. +# +# EVIDENCE-OF: R-55435-14303 Each time a new row is inserted into the +# table or an existing row is updated, the expression associated with +# each CHECK constraint is evaluated and cast to a NUMERIC value in the +# same way as a CAST expression. If the result is zero (integer value 0 +# or real value 0.0), then a constraint violation has occurred. +# +drop_all_tables +do_execsql_test 4.11 { + CREATE TABLE x1(a TEXT, b INTEGER CHECK( b>0 )); + CREATE TABLE t1(a TEXT, b INTEGER, CHECK( b>0 )); + INSERT INTO x1 VALUES('x', 'xx'); + INSERT INTO x1 VALUES('y', 'yy'); + INSERT INTO t1 SELECT * FROM x1; + + CREATE TABLE x2(a CHECK( a||b ), b); + CREATE TABLE t2(a, b, CHECK( a||b )); + INSERT INTO x2 VALUES(1, 'xx'); + INSERT INTO x2 VALUES(1, 'yy'); + INSERT INTO t2 SELECT * FROM x2; +} + +do_createtable_tests 4.11 -error {constraint failed} { + 1a "INSERT INTO x1 VALUES('one', 0)" {} + 1b "INSERT INTO t1 VALUES('one', -4.0)" {} + + 2a "INSERT INTO x2 VALUES('abc', 1)" {} + 2b "INSERT INTO t2 VALUES('abc', 1)" {} + + 3a "INSERT INTO x2 VALUES(0, 'abc')" {} + 3b "INSERT INTO t2 VALUES(0, 'abc')" {} + + 4a "UPDATE t1 SET b=-1 WHERE rowid=1" {} + 4b "UPDATE x1 SET b=-1 WHERE rowid=1" {} + + 4a "UPDATE x2 SET a='' WHERE rowid=1" {} + 4b "UPDATE t2 SET a='' WHERE rowid=1" {} +} + +# EVIDENCE-OF: R-34109-39108 If the CHECK expression evaluates to NULL, +# or any other non-zero value, it is not a constraint violation. +# +do_createtable_tests 4.12 { + 1a "INSERT INTO x1 VALUES('one', NULL)" {} + 1b "INSERT INTO t1 VALUES('one', NULL)" {} + + 2a "INSERT INTO x1 VALUES('one', 2)" {} + 2b "INSERT INTO t1 VALUES('one', 2)" {} + + 3a "INSERT INTO x2 VALUES(1, 'abc')" {} + 3b "INSERT INTO t2 VALUES(1, 'abc')" {} +} + +finish_test diff --git a/test/tester.tcl b/test/tester.tcl index ccf9084450..45f4c99eb3 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -345,7 +345,7 @@ proc fix_testname {varname} { } } -proc do_execsql_test {testname sql result} { +proc do_execsql_test {testname sql {result {}}} { fix_testname testname uplevel do_test $testname [list "execsql {$sql}"] [list $result] }