modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/without_rowid1.test (about) 1 # 2013-10-30 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 # 12 # This file implements regression tests for SQLite library. The 13 # focus of this file is testing WITHOUT ROWID tables. 14 # 15 16 set testdir [file dirname $argv0] 17 source $testdir/tester.tcl 18 set testprefix without_rowid1 19 20 # Create and query a WITHOUT ROWID table. 21 # 22 do_execsql_test without_rowid1-1.0 { 23 CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID; 24 CREATE INDEX t1bd ON t1(b, d); 25 INSERT INTO t1 VALUES('journal','sherman','ammonia','helena'); 26 INSERT INTO t1 VALUES('dynamic','juliet','flipper','command'); 27 INSERT INTO t1 VALUES('journal','sherman','gamma','patriot'); 28 INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena'); 29 SELECT *, '|' FROM t1 ORDER BY c, a; 30 } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} 31 32 integrity_check without_rowid1-1.0ic 33 34 do_execsql_test without_rowid1-1.1 { 35 SELECT *, '|' FROM t1 ORDER BY +c, a; 36 } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} 37 38 do_execsql_test without_rowid1-1.2 { 39 SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC; 40 } {journal sherman gamma patriot | dynamic juliet flipper command | journal sherman ammonia helena | arctic sleep ammonia helena |} 41 42 do_execsql_test without_rowid1-1.11 { 43 SELECT *, '|' FROM t1 ORDER BY b, d; 44 } {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |} 45 46 do_execsql_test without_rowid1-1.12 { 47 SELECT *, '|' FROM t1 ORDER BY +b, d; 48 } {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |} 49 50 # Trying to insert a duplicate PRIMARY KEY fails. 51 # 52 do_test without_rowid1-1.21 { 53 catchsql { 54 INSERT INTO t1 VALUES('dynamic','phone','flipper','harvard'); 55 } 56 } {1 {UNIQUE constraint failed: t1.c, t1.a}} 57 58 # REPLACE INTO works, however. 59 # 60 do_execsql_test without_rowid1-1.22 { 61 REPLACE INTO t1 VALUES('dynamic','phone','flipper','harvard'); 62 SELECT *, '|' FROM t1 ORDER BY c, a; 63 } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic phone flipper harvard | journal sherman gamma patriot |} 64 65 do_execsql_test without_rowid1-1.23 { 66 SELECT *, '|' FROM t1 ORDER BY b, d; 67 } {dynamic phone flipper harvard | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |} 68 69 # UPDATE statements. 70 # 71 do_execsql_test without_rowid1-1.31 { 72 UPDATE t1 SET d=3.1415926 WHERE a='journal'; 73 SELECT *, '|' FROM t1 ORDER BY c, a; 74 } {arctic sleep ammonia helena | journal sherman ammonia 3.1415926 | dynamic phone flipper harvard | journal sherman gamma 3.1415926 |} 75 do_execsql_test without_rowid1-1.32 { 76 SELECT *, '|' FROM t1 ORDER BY b, d; 77 } {dynamic phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |} 78 79 do_execsql_test without_rowid1-1.35 { 80 UPDATE t1 SET a=1250 WHERE b='phone'; 81 SELECT *, '|' FROM t1 ORDER BY c, a; 82 } {arctic sleep ammonia helena | journal sherman ammonia 3.1415926 | 1250 phone flipper harvard | journal sherman gamma 3.1415926 |} 83 integrity_check without_rowid1-1.36 84 85 do_execsql_test without_rowid1-1.37 { 86 SELECT *, '|' FROM t1 ORDER BY b, d; 87 } {1250 phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |} 88 89 do_execsql_test without_rowid1-1.40 { 90 VACUUM; 91 SELECT *, '|' FROM t1 ORDER BY b, d; 92 } {1250 phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |} 93 integrity_check without_rowid1-1.41 94 95 # Verify that ANALYZE works 96 # 97 do_execsql_test without_rowid1-1.50 { 98 ANALYZE; 99 SELECT * FROM sqlite_stat1 ORDER BY idx; 100 } {t1 t1 {4 2 1} t1 t1bd {4 2 2}} 101 ifcapable stat3 { 102 do_execsql_test without_rowid1-1.51 { 103 SELECT DISTINCT tbl, idx FROM sqlite_stat3 ORDER BY idx; 104 } {t1 t1 t1 t1bd} 105 } 106 ifcapable stat4 { 107 do_execsql_test without_rowid1-1.52 { 108 SELECT DISTINCT tbl, idx FROM sqlite_stat4 ORDER BY idx; 109 } {t1 t1 t1 t1bd} 110 } 111 112 #---------- 113 114 do_execsql_test 2.1.1 { 115 CREATE TABLE t4 (a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID; 116 INSERT INTO t4 VALUES('abc', 'def'); 117 SELECT * FROM t4; 118 } {abc def} 119 do_execsql_test 2.1.2 { 120 UPDATE t4 SET a = 'ABC'; 121 SELECT * FROM t4; 122 } {ABC def} 123 124 do_execsql_test 2.2.1 { 125 DROP TABLE t4; 126 CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID; 127 INSERT INTO t4(a, b) VALUES('abc', 'def'); 128 SELECT * FROM t4; 129 } {def abc} 130 131 do_execsql_test 2.2.2 { 132 UPDATE t4 SET a = 'ABC', b = 'xyz'; 133 SELECT * FROM t4; 134 } {xyz ABC} 135 136 do_execsql_test 2.3.1 { 137 CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID; 138 INSERT INTO t5(a, b) VALUES('abc', 'def'); 139 UPDATE t5 SET a='abc', b='def'; 140 } {} 141 142 do_execsql_test 2.4.1 { 143 CREATE TABLE t6 ( 144 a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a) 145 ) WITHOUT ROWID; 146 147 INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi'); 148 UPDATE t6 SET a='ABC', c='ghi'; 149 } {} 150 151 do_execsql_test 2.4.2 { 152 SELECT * FROM t6 ORDER BY b, a; 153 SELECT * FROM t6 ORDER BY c; 154 } {ABC def ghi ABC def ghi} 155 156 #------------------------------------------------------------------------- 157 # Unless the destination table is completely empty, the xfer optimization 158 # is disabled for WITHOUT ROWID tables. The following tests check for 159 # some problems that might occur if this were not the case. 160 # 161 reset_db 162 do_execsql_test 3.1.1 { 163 CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID; 164 CREATE UNIQUE INDEX i1 ON t1(b); 165 166 CREATE TABLE t2(a, b, PRIMARY KEY(a)) WITHOUT ROWID; 167 CREATE UNIQUE INDEX i2 ON t2(b); 168 169 INSERT INTO t1 VALUES('one', 'two'); 170 INSERT INTO t2 VALUES('three', 'two'); 171 } 172 173 do_execsql_test 3.1.2 { 174 INSERT OR REPLACE INTO t1 SELECT * FROM t2; 175 SELECT * FROM t1; 176 } {three two} 177 178 do_execsql_test 3.1.3 { 179 DELETE FROM t1; 180 INSERT INTO t1 SELECT * FROM t2; 181 SELECT * FROM t1; 182 } {three two} 183 184 do_catchsql_test 3.1.4 { 185 INSERT INTO t2 VALUES('four', 'four'); 186 INSERT INTO t2 VALUES('six', 'two'); 187 INSERT INTO t1 SELECT * FROM t2; 188 } {1 {UNIQUE constraint failed: t2.b}} 189 190 do_execsql_test 3.1.5 { 191 CREATE TABLE t3(a PRIMARY KEY); 192 CREATE TABLE t4(a PRIMARY KEY); 193 194 INSERT INTO t4 VALUES('i'); 195 INSERT INTO t4 VALUES('ii'); 196 INSERT INTO t4 VALUES('iii'); 197 198 INSERT INTO t3 SELECT * FROM t4; 199 SELECT * FROM t3; 200 } {i ii iii} 201 202 ############################################################################ 203 # Ticket [c34d0557f740c450709d6e33df72d4f3f651a3cc] 204 # Name resolution issue with WITHOUT ROWID 205 # 206 do_execsql_test 4.1 { 207 CREATE TABLE t41(a PRIMARY KEY) WITHOUT ROWID; 208 INSERT INTO t41 VALUES('abc'); 209 CREATE TABLE t42(x); 210 INSERT INTO t42 VALUES('xyz'); 211 SELECT t42.rowid FROM t41, t42; 212 } {1} 213 do_execsql_test 4.2 { 214 SELECT t42.rowid FROM t42, t41; 215 } {1} 216 217 218 #-------------------------------------------------------------------------- 219 # The following tests verify that the trailing PK fields added to each 220 # entry in an index on a WITHOUT ROWID table are used correctly. 221 # 222 do_execsql_test 5.0 { 223 CREATE TABLE t45(a PRIMARY KEY, b, c) WITHOUT ROWID; 224 CREATE INDEX i45 ON t45(b); 225 226 INSERT INTO t45 VALUES(2, 'one', 'x'); 227 INSERT INTO t45 VALUES(4, 'one', 'x'); 228 INSERT INTO t45 VALUES(6, 'one', 'x'); 229 INSERT INTO t45 VALUES(8, 'one', 'x'); 230 INSERT INTO t45 VALUES(10, 'one', 'x'); 231 232 INSERT INTO t45 VALUES(1, 'two', 'x'); 233 INSERT INTO t45 VALUES(3, 'two', 'x'); 234 INSERT INTO t45 VALUES(5, 'two', 'x'); 235 INSERT INTO t45 VALUES(7, 'two', 'x'); 236 INSERT INTO t45 VALUES(9, 'two', 'x'); 237 } 238 239 do_eqp_test 5.1 { 240 SELECT * FROM t45 WHERE b=? AND a>? 241 } {/*USING INDEX i45 (b=? AND a>?)*/} 242 243 do_execsql_test 5.2 { 244 SELECT * FROM t45 WHERE b='two' AND a>4 245 } {5 two x 7 two x 9 two x} 246 247 do_execsql_test 5.3 { 248 SELECT * FROM t45 WHERE b='one' AND a<8 249 } { 2 one x 4 one x 6 one x } 250 251 do_execsql_test 5.4 { 252 CREATE TABLE t46(a, b, c, d, PRIMARY KEY(a, b)) WITHOUT ROWID; 253 WITH r(x) AS ( 254 SELECT 1 UNION ALL SELECT x+1 FROM r WHERE x<100 255 ) 256 INSERT INTO t46 SELECT x / 20, x % 20, x % 10, x FROM r; 257 } 258 259 set queries { 260 1 2 "c = 5 AND a = 1" {/*i46 (c=? AND a=?)*/} 261 2 6 "c = 4 AND a < 3" {/*i46 (c=? AND a<?)*/} 262 3 4 "c = 2 AND a >= 3" {/*i46 (c=? AND a>?)*/} 263 4 1 "c = 2 AND a = 1 AND b<10" {/*i46 (c=? AND a=? AND b<?)*/} 264 5 1 "c = 0 AND a = 0 AND b>5" {/*i46 (c=? AND a=? AND b>?)*/} 265 } 266 267 foreach {tn cnt where eqp} $queries { 268 do_execsql_test 5.5.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt 269 } 270 271 do_execsql_test 5.6 { 272 CREATE INDEX i46 ON t46(c); 273 } 274 275 foreach {tn cnt where eqp} $queries { 276 do_execsql_test 5.7.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt 277 do_eqp_test 5.7.$tn.2 "SELECT count(*) FROM t46 WHERE $where" $eqp 278 } 279 280 #------------------------------------------------------------------------- 281 # Check that redundant UNIQUE constraints do not cause a problem. 282 # 283 do_execsql_test 6.0 { 284 CREATE TABLE t47(a, b UNIQUE PRIMARY KEY) WITHOUT ROWID; 285 CREATE INDEX i47 ON t47(a); 286 INSERT INTO t47 VALUES(1, 2); 287 INSERT INTO t47 VALUES(2, 4); 288 INSERT INTO t47 VALUES(3, 6); 289 INSERT INTO t47 VALUES(4, 8); 290 291 VACUUM; 292 PRAGMA integrity_check; 293 SELECT name FROM sqlite_master WHERE tbl_name = 't47'; 294 } {ok t47 i47} 295 296 do_execsql_test 6.1 { 297 CREATE TABLE t48( 298 a UNIQUE UNIQUE, 299 b UNIQUE, 300 PRIMARY KEY(a), 301 UNIQUE(a) 302 ) WITHOUT ROWID; 303 INSERT INTO t48 VALUES('a', 'b'), ('c', 'd'), ('e', 'f'); 304 VACUUM; 305 PRAGMA integrity_check; 306 SELECT name FROM sqlite_master WHERE tbl_name = 't48'; 307 } { 308 ok t48 sqlite_autoindex_t48_2 309 } 310 311 # 2015-05-28: CHECK constraints can refer to the rowid in a 312 # rowid table, but not in a WITHOUT ROWID table. 313 # 314 do_execsql_test 7.1 { 315 CREATE TABLE t70a( 316 a INT CHECK( rowid!=33 ), 317 b TEXT PRIMARY KEY 318 ); 319 INSERT INTO t70a(a,b) VALUES(99,'hello'); 320 } {} 321 do_catchsql_test 7.2 { 322 INSERT INTO t70a(rowid,a,b) VALUES(33,99,'xyzzy'); 323 } {1 {CHECK constraint failed: t70a}} 324 do_catchsql_test 7.3 { 325 CREATE TABLE t70b( 326 a INT CHECK( rowid!=33 ), 327 b TEXT PRIMARY KEY 328 ) WITHOUT ROWID; 329 } {1 {no such column: rowid}} 330 331 # 2017-07-30: OSSFuzz discovered that an extra entry was being 332 # added in the sqlite_master table for an "INTEGER PRIMARY KEY UNIQUE" 333 # WITHOUT ROWID table. Make sure this has now been fixed. 334 # 335 db close 336 sqlite3 db :memory: 337 do_execsql_test 8.1 { 338 CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID; 339 CREATE INDEX t1x ON t1(x); 340 INSERT INTO t1(x,b) VALUES('funny','buffalo'); 341 SELECT type, name, '|' FROM sqlite_master; 342 } {table t1 | index t1x |} 343 344 345 346 finish_test