1# 2001 September 27 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 the CREATE UNIQUE INDEX statement, 13# and primary keys, and the UNIQUE constraint on table columns 14# 15# $Id: unique.test,v 1.9 2009/05/02 15:46:47 drh Exp $ 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# Try to create a table with two primary keys. 21# (This is allowed in SQLite even that it is not valid SQL) 22# 23do_test unique-1.1 { 24 catchsql { 25 CREATE TABLE t1( 26 a int PRIMARY KEY, 27 b int PRIMARY KEY, 28 c text 29 ); 30 } 31} {1 {table "t1" has more than one primary key}} 32do_test unique-1.1b { 33 catchsql { 34 CREATE TABLE t1( 35 a int PRIMARY KEY, 36 b int UNIQUE, 37 c text 38 ); 39 } 40} {0 {}} 41do_test unique-1.2 { 42 catchsql { 43 INSERT INTO t1(a,b,c) VALUES(1,2,3) 44 } 45} {0 {}} 46do_test unique-1.3 { 47 catchsql { 48 INSERT INTO t1(a,b,c) VALUES(1,3,4) 49 } 50} {1 {UNIQUE constraint failed: t1.a}} 51verify_ex_errcode unique-1.3b SQLITE_CONSTRAINT_PRIMARYKEY 52do_test unique-1.4 { 53 execsql { 54 SELECT * FROM t1 ORDER BY a; 55 } 56} {1 2 3} 57do_test unique-1.5 { 58 catchsql { 59 INSERT INTO t1(a,b,c) VALUES(3,2,4) 60 } 61} {1 {UNIQUE constraint failed: t1.b}} 62verify_ex_errcode unique-1.5b SQLITE_CONSTRAINT_UNIQUE 63do_test unique-1.6 { 64 execsql { 65 SELECT * FROM t1 ORDER BY a; 66 } 67} {1 2 3} 68do_test unique-1.7 { 69 catchsql { 70 INSERT INTO t1(a,b,c) VALUES(3,4,5) 71 } 72} {0 {}} 73do_test unique-1.8 { 74 execsql { 75 SELECT * FROM t1 ORDER BY a; 76 } 77} {1 2 3 3 4 5} 78integrity_check unique-1.9 79 80do_test unique-2.0 { 81 execsql { 82 DROP TABLE t1; 83 CREATE TABLE t2(a int, b int); 84 INSERT INTO t2(a,b) VALUES(1,2); 85 INSERT INTO t2(a,b) VALUES(3,4); 86 SELECT * FROM t2 ORDER BY a; 87 } 88} {1 2 3 4} 89do_test unique-2.1 { 90 catchsql { 91 CREATE UNIQUE INDEX i2 ON t2(a) 92 } 93} {0 {}} 94do_test unique-2.2 { 95 catchsql { 96 SELECT * FROM t2 ORDER BY a 97 } 98} {0 {1 2 3 4}} 99do_test unique-2.3 { 100 catchsql { 101 INSERT INTO t2 VALUES(1,5); 102 } 103} {1 {UNIQUE constraint failed: t2.a}} 104verify_ex_errcode unique-2.3b SQLITE_CONSTRAINT_UNIQUE 105do_test unique-2.4 { 106 catchsql { 107 SELECT * FROM t2 ORDER BY a 108 } 109} {0 {1 2 3 4}} 110do_test unique-2.5 { 111 catchsql { 112 DROP INDEX i2; 113 SELECT * FROM t2 ORDER BY a; 114 } 115} {0 {1 2 3 4}} 116do_test unique-2.6 { 117 catchsql { 118 INSERT INTO t2 VALUES(1,5) 119 } 120} {0 {}} 121do_test unique-2.7 { 122 catchsql { 123 SELECT * FROM t2 ORDER BY a, b; 124 } 125} {0 {1 2 1 5 3 4}} 126do_test unique-2.8 { 127 catchsql { 128 CREATE UNIQUE INDEX i2 ON t2(a); 129 } 130} {1 {UNIQUE constraint failed: t2.a}} 131verify_ex_errcode unique-2.8b SQLITE_CONSTRAINT_UNIQUE 132do_test unique-2.9 { 133 catchsql { 134 CREATE INDEX i2 ON t2(a); 135 } 136} {0 {}} 137integrity_check unique-2.10 138 139# Test the UNIQUE keyword as used on two or more fields. 140# 141do_test unique-3.1 { 142 catchsql { 143 CREATE TABLE t3( 144 a int, 145 b int, 146 c int, 147 d int, 148 unique(a,c,d) 149 ); 150 } 151} {0 {}} 152do_test unique-3.2 { 153 catchsql { 154 INSERT INTO t3(a,b,c,d) VALUES(1,2,3,4); 155 SELECT * FROM t3 ORDER BY a,b,c,d; 156 } 157} {0 {1 2 3 4}} 158do_test unique-3.3 { 159 catchsql { 160 INSERT INTO t3(a,b,c,d) VALUES(1,2,3,5); 161 SELECT * FROM t3 ORDER BY a,b,c,d; 162 } 163} {0 {1 2 3 4 1 2 3 5}} 164do_test unique-3.4 { 165 catchsql { 166 INSERT INTO t3(a,b,c,d) VALUES(1,4,3,5); 167 SELECT * FROM t3 ORDER BY a,b,c,d; 168 } 169} {1 {UNIQUE constraint failed: t3.a, t3.c, t3.d}} 170verify_ex_errcode unique-3.4b SQLITE_CONSTRAINT_UNIQUE 171integrity_check unique-3.5 172 173# Make sure NULLs are distinct as far as the UNIQUE tests are 174# concerned. 175# 176do_test unique-4.1 { 177 execsql { 178 CREATE TABLE t4(a UNIQUE, b, c, UNIQUE(b,c)); 179 INSERT INTO t4 VALUES(1,2,3); 180 INSERT INTO t4 VALUES(NULL, 2, NULL); 181 SELECT * FROM t4; 182 } 183} {1 2 3 {} 2 {}} 184do_test unique-4.2 { 185 catchsql { 186 INSERT INTO t4 VALUES(NULL, 3, 4); 187 } 188} {0 {}} 189do_test unique-4.3 { 190 execsql { 191 SELECT * FROM t4 192 } 193} {1 2 3 {} 2 {} {} 3 4} 194do_test unique-4.4 { 195 catchsql { 196 INSERT INTO t4 VALUES(2, 2, NULL); 197 } 198} {0 {}} 199do_test unique-4.5 { 200 execsql { 201 SELECT * FROM t4 202 } 203} {1 2 3 {} 2 {} {} 3 4 2 2 {}} 204 205# Ticket #1301. Any NULL value in a set of unique columns should 206# cause the rows to be distinct. 207# 208do_test unique-4.6 { 209 catchsql { 210 INSERT INTO t4 VALUES(NULL, 2, NULL); 211 } 212} {0 {}} 213do_test unique-4.7 { 214 execsql {SELECT * FROM t4} 215} {1 2 3 {} 2 {} {} 3 4 2 2 {} {} 2 {}} 216do_test unique-4.8 { 217 catchsql {CREATE UNIQUE INDEX i4a ON t4(a,b)} 218} {0 {}} 219do_test unique-4.9 { 220 catchsql {CREATE UNIQUE INDEX i4b ON t4(a,b,c)} 221} {0 {}} 222do_test unique-4.10 { 223 catchsql {CREATE UNIQUE INDEX i4c ON t4(b)} 224} {1 {UNIQUE constraint failed: t4.b}} 225verify_ex_errcode unique-4.10b SQLITE_CONSTRAINT_UNIQUE 226integrity_check unique-4.99 227 228# Test the error message generation logic. In particular, make sure we 229# do not overflow the static buffer used to generate the error message. 230# 231do_test unique-5.1 { 232 execsql { 233 CREATE TABLE t5( 234 first_column_with_long_name, 235 second_column_with_long_name, 236 third_column_with_long_name, 237 fourth_column_with_long_name, 238 fifth_column_with_long_name, 239 sixth_column_with_long_name, 240 UNIQUE( 241 first_column_with_long_name, 242 second_column_with_long_name, 243 third_column_with_long_name, 244 fourth_column_with_long_name, 245 fifth_column_with_long_name, 246 sixth_column_with_long_name 247 ) 248 ); 249 INSERT INTO t5 VALUES(1,2,3,4,5,6); 250 SELECT * FROM t5; 251 } 252} {1 2 3 4 5 6} 253do_test unique-5.2 { 254 catchsql { 255 INSERT INTO t5 VALUES(1,2,3,4,5,6); 256 } 257} {1 {UNIQUE constraint failed: t5.first_column_with_long_name, t5.second_column_with_long_name, t5.third_column_with_long_name, t5.fourth_column_with_long_name, t5.fifth_column_with_long_name, t5.sixth_column_with_long_name}} 258verify_ex_errcode unique-5.2b SQLITE_CONSTRAINT_UNIQUE 259 260 261finish_test 262