1# 2004 November 12 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 script is testing the AUTOINCREMENT features. 13# 14# $Id: autoinc.test,v 1.9 2006/01/03 00:33:50 drh Exp $ 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# If the library is not compiled with autoincrement support then 21# skip all tests in this file. 22# 23ifcapable {!autoinc} { 24 finish_test 25 return 26} 27 28# The database is initially empty. 29# 30do_test autoinc-1.1 { 31 execsql { 32 SELECT name FROM sqlite_master WHERE type='table'; 33 } 34} {} 35 36# Add a table with the AUTOINCREMENT feature. Verify that the 37# SQLITE_SEQUENCE table gets created. 38# 39do_test autoinc-1.2 { 40 execsql { 41 CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y); 42 SELECT name FROM sqlite_master WHERE type='table'; 43 } 44} {t1 sqlite_sequence} 45 46# The SQLITE_SEQUENCE table is initially empty 47# 48do_test autoinc-1.3 { 49 execsql { 50 SELECT * FROM sqlite_sequence; 51 } 52} {} 53 54# Close and reopen the database. Verify that everything is still there. 55# 56do_test autoinc-1.4 { 57 db close 58 sqlite3 db test.db 59 execsql { 60 SELECT * FROM sqlite_sequence; 61 } 62} {} 63 64# We are not allowed to drop the sqlite_sequence table. 65# 66do_test autoinc-1.5 { 67 catchsql {DROP TABLE sqlite_sequence} 68} {1 {table sqlite_sequence may not be dropped}} 69do_test autoinc-1.6 { 70 execsql {SELECT name FROM sqlite_master WHERE type='table'} 71} {t1 sqlite_sequence} 72 73# Insert an entries into the t1 table and make sure the largest key 74# is always recorded in the sqlite_sequence table. 75# 76do_test autoinc-2.1 { 77 execsql { 78 SELECT * FROM sqlite_sequence 79 } 80} {} 81do_test autoinc-2.2 { 82 execsql { 83 INSERT INTO t1 VALUES(12,34); 84 SELECT * FROM sqlite_sequence; 85 } 86} {t1 12} 87do_test autoinc-2.3 { 88 execsql { 89 INSERT INTO t1 VALUES(1,23); 90 SELECT * FROM sqlite_sequence; 91 } 92} {t1 12} 93do_test autoinc-2.4 { 94 execsql { 95 INSERT INTO t1 VALUES(123,456); 96 SELECT * FROM sqlite_sequence; 97 } 98} {t1 123} 99do_test autoinc-2.5 { 100 execsql { 101 INSERT INTO t1 VALUES(NULL,567); 102 SELECT * FROM sqlite_sequence; 103 } 104} {t1 124} 105do_test autoinc-2.6 { 106 execsql { 107 DELETE FROM t1 WHERE y=567; 108 SELECT * FROM sqlite_sequence; 109 } 110} {t1 124} 111do_test autoinc-2.7 { 112 execsql { 113 INSERT INTO t1 VALUES(NULL,567); 114 SELECT * FROM sqlite_sequence; 115 } 116} {t1 125} 117do_test autoinc-2.8 { 118 execsql { 119 DELETE FROM t1; 120 SELECT * FROM sqlite_sequence; 121 } 122} {t1 125} 123do_test autoinc-2.9 { 124 execsql { 125 INSERT INTO t1 VALUES(12,34); 126 SELECT * FROM sqlite_sequence; 127 } 128} {t1 125} 129do_test autoinc-2.10 { 130 execsql { 131 INSERT INTO t1 VALUES(125,456); 132 SELECT * FROM sqlite_sequence; 133 } 134} {t1 125} 135do_test autoinc-2.11 { 136 execsql { 137 INSERT INTO t1 VALUES(-1234567,-1); 138 SELECT * FROM sqlite_sequence; 139 } 140} {t1 125} 141do_test autoinc-2.12 { 142 execsql { 143 INSERT INTO t1 VALUES(234,5678); 144 SELECT * FROM sqlite_sequence; 145 } 146} {t1 234} 147do_test autoinc-2.13 { 148 execsql { 149 DELETE FROM t1; 150 INSERT INTO t1 VALUES(NULL,1); 151 SELECT * FROM sqlite_sequence; 152 } 153} {t1 235} 154do_test autoinc-2.14 { 155 execsql { 156 SELECT * FROM t1; 157 } 158} {235 1} 159 160# Manually change the autoincrement values in sqlite_sequence. 161# 162do_test autoinc-2.20 { 163 execsql { 164 UPDATE sqlite_sequence SET seq=1234 WHERE name='t1'; 165 INSERT INTO t1 VALUES(NULL,2); 166 SELECT * FROM t1; 167 } 168} {235 1 1235 2} 169do_test autoinc-2.21 { 170 execsql { 171 SELECT * FROM sqlite_sequence; 172 } 173} {t1 1235} 174do_test autoinc-2.22 { 175 execsql { 176 UPDATE sqlite_sequence SET seq=NULL WHERE name='t1'; 177 INSERT INTO t1 VALUES(NULL,3); 178 SELECT * FROM t1; 179 } 180} {235 1 1235 2 1236 3} 181do_test autoinc-2.23 { 182 execsql { 183 SELECT * FROM sqlite_sequence; 184 } 185} {t1 1236} 186do_test autoinc-2.24 { 187 execsql { 188 UPDATE sqlite_sequence SET seq='a-string' WHERE name='t1'; 189 INSERT INTO t1 VALUES(NULL,4); 190 SELECT * FROM t1; 191 } 192} {235 1 1235 2 1236 3 1237 4} 193do_test autoinc-2.25 { 194 execsql { 195 SELECT * FROM sqlite_sequence; 196 } 197} {t1 1237} 198do_test autoinc-2.26 { 199 execsql { 200 DELETE FROM sqlite_sequence WHERE name='t1'; 201 INSERT INTO t1 VALUES(NULL,5); 202 SELECT * FROM t1; 203 } 204} {235 1 1235 2 1236 3 1237 4 1238 5} 205do_test autoinc-2.27 { 206 execsql { 207 SELECT * FROM sqlite_sequence; 208 } 209} {t1 1238} 210do_test autoinc-2.28 { 211 execsql { 212 UPDATE sqlite_sequence SET seq='12345678901234567890' 213 WHERE name='t1'; 214 INSERT INTO t1 VALUES(NULL,6); 215 SELECT * FROM t1; 216 } 217} {235 1 1235 2 1236 3 1237 4 1238 5 1239 6} 218do_test autoinc-2.29 { 219 execsql { 220 SELECT * FROM sqlite_sequence; 221 } 222} {t1 1239} 223 224# Test multi-row inserts 225# 226do_test autoinc-2.50 { 227 execsql { 228 DELETE FROM t1 WHERE y>=3; 229 INSERT INTO t1 SELECT NULL, y+2 FROM t1; 230 SELECT * FROM t1; 231 } 232} {235 1 1235 2 1240 3 1241 4} 233do_test autoinc-2.51 { 234 execsql { 235 SELECT * FROM sqlite_sequence 236 } 237} {t1 1241} 238 239ifcapable tempdb { 240 do_test autoinc-2.52 { 241 execsql { 242 CREATE TEMP TABLE t2 AS SELECT y FROM t1; 243 INSERT INTO t1 SELECT NULL, y+4 FROM t2; 244 SELECT * FROM t1; 245 } 246 } {235 1 1235 2 1240 3 1241 4 1242 5 1243 6 1244 7 1245 8} 247 do_test autoinc-2.53 { 248 execsql { 249 SELECT * FROM sqlite_sequence 250 } 251 } {t1 1245} 252 do_test autoinc-2.54 { 253 execsql { 254 DELETE FROM t1; 255 INSERT INTO t1 SELECT NULL, y FROM t2; 256 SELECT * FROM t1; 257 } 258 } {1246 1 1247 2 1248 3 1249 4} 259 do_test autoinc-2.55 { 260 execsql { 261 SELECT * FROM sqlite_sequence 262 } 263 } {t1 1249} 264} 265 266# Create multiple AUTOINCREMENT tables. Make sure all sequences are 267# tracked separately and do not interfere with one another. 268# 269do_test autoinc-2.70 { 270 catchsql { 271 DROP TABLE t2; 272 } 273 execsql { 274 CREATE TABLE t2(d, e INTEGER PRIMARY KEY AUTOINCREMENT, f); 275 INSERT INTO t2(d) VALUES(1); 276 SELECT * FROM sqlite_sequence; 277 } 278} [ifcapable tempdb {list t1 1249 t2 1} else {list t1 1241 t2 1}] 279do_test autoinc-2.71 { 280 execsql { 281 INSERT INTO t2(d) VALUES(2); 282 SELECT * FROM sqlite_sequence; 283 } 284} [ifcapable tempdb {list t1 1249 t2 2} else {list t1 1241 t2 2}] 285do_test autoinc-2.72 { 286 execsql { 287 INSERT INTO t1(x) VALUES(10000); 288 SELECT * FROM sqlite_sequence; 289 } 290} {t1 10000 t2 2} 291do_test autoinc-2.73 { 292 execsql { 293 CREATE TABLE t3(g INTEGER PRIMARY KEY AUTOINCREMENT, h); 294 INSERT INTO t3(h) VALUES(1); 295 SELECT * FROM sqlite_sequence; 296 } 297} {t1 10000 t2 2 t3 1} 298do_test autoinc-2.74 { 299 execsql { 300 INSERT INTO t2(d,e) VALUES(3,100); 301 SELECT * FROM sqlite_sequence; 302 } 303} {t1 10000 t2 100 t3 1} 304 305 306# When a table with an AUTOINCREMENT is deleted, the corresponding entry 307# in the SQLITE_SEQUENCE table should also be deleted. But the SQLITE_SEQUENCE 308# table itself should remain behind. 309# 310do_test autoinc-3.1 { 311 execsql {SELECT name FROM sqlite_sequence} 312} {t1 t2 t3} 313do_test autoinc-3.2 { 314 execsql { 315 DROP TABLE t1; 316 SELECT name FROM sqlite_sequence; 317 } 318} {t2 t3} 319do_test autoinc-3.3 { 320 execsql { 321 DROP TABLE t3; 322 SELECT name FROM sqlite_sequence; 323 } 324} {t2} 325do_test autoinc-3.4 { 326 execsql { 327 DROP TABLE t2; 328 SELECT name FROM sqlite_sequence; 329 } 330} {} 331 332# AUTOINCREMENT on TEMP tables. 333# 334ifcapable tempdb { 335 do_test autoinc-4.1 { 336 execsql { 337 SELECT 1, name FROM sqlite_master WHERE type='table'; 338 SELECT 2, name FROM sqlite_temp_master WHERE type='table'; 339 } 340 } {1 sqlite_sequence} 341 do_test autoinc-4.2 { 342 execsql { 343 CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y); 344 CREATE TEMP TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b); 345 SELECT 1, name FROM sqlite_master WHERE type='table'; 346 SELECT 2, name FROM sqlite_temp_master WHERE type='table'; 347 } 348 } {1 sqlite_sequence 1 t1 2 t3 2 sqlite_sequence} 349 do_test autoinc-4.3 { 350 execsql { 351 SELECT 1, * FROM main.sqlite_sequence; 352 SELECT 2, * FROM temp.sqlite_sequence; 353 } 354 } {} 355 do_test autoinc-4.4 { 356 execsql { 357 INSERT INTO t1 VALUES(10,1); 358 INSERT INTO t3 VALUES(20,2); 359 INSERT INTO t1 VALUES(NULL,3); 360 INSERT INTO t3 VALUES(NULL,4); 361 } 362 } {} 363 364 ifcapable compound { 365 do_test autoinc-4.4.1 { 366 execsql { 367 SELECT * FROM t1 UNION ALL SELECT * FROM t3; 368 } 369 } {10 1 11 3 20 2 21 4} 370 } ;# ifcapable compound 371 372 do_test autoinc-4.5 { 373 execsql { 374 SELECT 1, * FROM main.sqlite_sequence; 375 SELECT 2, * FROM temp.sqlite_sequence; 376 } 377 } {1 t1 11 2 t3 21} 378 do_test autoinc-4.6 { 379 execsql { 380 INSERT INTO t1 SELECT * FROM t3; 381 SELECT 1, * FROM main.sqlite_sequence; 382 SELECT 2, * FROM temp.sqlite_sequence; 383 } 384 } {1 t1 21 2 t3 21} 385 do_test autoinc-4.7 { 386 execsql { 387 INSERT INTO t3 SELECT x+100, y FROM t1; 388 SELECT 1, * FROM main.sqlite_sequence; 389 SELECT 2, * FROM temp.sqlite_sequence; 390 } 391 } {1 t1 21 2 t3 121} 392 do_test autoinc-4.8 { 393 execsql { 394 DROP TABLE t3; 395 SELECT 1, * FROM main.sqlite_sequence; 396 SELECT 2, * FROM temp.sqlite_sequence; 397 } 398 } {1 t1 21} 399 do_test autoinc-4.9 { 400 execsql { 401 CREATE TEMP TABLE t2(p INTEGER PRIMARY KEY AUTOINCREMENT, q); 402 INSERT INTO t2 SELECT * FROM t1; 403 DROP TABLE t1; 404 SELECT 1, * FROM main.sqlite_sequence; 405 SELECT 2, * FROM temp.sqlite_sequence; 406 } 407 } {2 t2 21} 408 do_test autoinc-4.10 { 409 execsql { 410 DROP TABLE t2; 411 SELECT 1, * FROM main.sqlite_sequence; 412 SELECT 2, * FROM temp.sqlite_sequence; 413 } 414 } {} 415} 416 417# Make sure AUTOINCREMENT works on ATTACH-ed tables. 418# 419ifcapable tempdb { 420 do_test autoinc-5.1 { 421 file delete -force test2.db 422 file delete -force test2.db-journal 423 sqlite3 db2 test2.db 424 execsql { 425 CREATE TABLE t4(m INTEGER PRIMARY KEY AUTOINCREMENT, n); 426 CREATE TABLE t5(o, p INTEGER PRIMARY KEY AUTOINCREMENT); 427 } db2; 428 execsql { 429 ATTACH 'test2.db' as aux; 430 SELECT 1, * FROM main.sqlite_sequence; 431 SELECT 2, * FROM temp.sqlite_sequence; 432 SELECT 3, * FROM aux.sqlite_sequence; 433 } 434 } {} 435 do_test autoinc-5.2 { 436 execsql { 437 INSERT INTO t4 VALUES(NULL,1); 438 SELECT 1, * FROM main.sqlite_sequence; 439 SELECT 2, * FROM temp.sqlite_sequence; 440 SELECT 3, * FROM aux.sqlite_sequence; 441 } 442 } {3 t4 1} 443 do_test autoinc-5.3 { 444 execsql { 445 INSERT INTO t5 VALUES(100,200); 446 SELECT * FROM sqlite_sequence 447 } db2 448 } {t4 1 t5 200} 449 do_test autoinc-5.4 { 450 execsql { 451 SELECT 1, * FROM main.sqlite_sequence; 452 SELECT 2, * FROM temp.sqlite_sequence; 453 SELECT 3, * FROM aux.sqlite_sequence; 454 } 455 } {3 t4 1 3 t5 200} 456} 457 458# Requirement REQ00310: Make sure an insert fails if the sequence is 459# already at its maximum value. 460# 461ifcapable {rowid32} { 462 do_test autoinc-6.1 { 463 execsql { 464 CREATE TABLE t6(v INTEGER PRIMARY KEY AUTOINCREMENT, w); 465 INSERT INTO t6 VALUES(2147483647,1); 466 SELECT seq FROM main.sqlite_sequence WHERE name='t6'; 467 } 468 } 2147483647 469} 470ifcapable {!rowid32} { 471 do_test autoinc-6.1 { 472 execsql { 473 CREATE TABLE t6(v INTEGER PRIMARY KEY AUTOINCREMENT, w); 474 INSERT INTO t6 VALUES(9223372036854775807,1); 475 SELECT seq FROM main.sqlite_sequence WHERE name='t6'; 476 } 477 } 9223372036854775807 478} 479do_test autoinc-6.2 { 480 catchsql { 481 INSERT INTO t6 VALUES(NULL,1); 482 } 483} {1 {database or disk is full}} 484 485# Allow the AUTOINCREMENT keyword inside the parentheses 486# on a separate PRIMARY KEY designation. 487# 488do_test autoinc-7.1 { 489 execsql { 490 CREATE TABLE t7(x INTEGER, y REAL, PRIMARY KEY(x AUTOINCREMENT)); 491 INSERT INTO t7(y) VALUES(123); 492 INSERT INTO t7(y) VALUES(234); 493 DELETE FROM t7; 494 INSERT INTO t7(y) VALUES(345); 495 SELECT * FROM t7; 496 } 497} {3 345.0} 498 499# Test that if the AUTOINCREMENT is applied to a non integer primary key 500# the error message is sensible. 501do_test autoinc-7.2 { 502 catchsql { 503 CREATE TABLE t8(x TEXT PRIMARY KEY AUTOINCREMENT); 504 } 505} {1 {AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY}} 506 507 508# Ticket #1283. Make sure that preparing but never running a statement 509# that creates the sqlite_sequence table does not mess up the database. 510# 511do_test autoinc-8.1 { 512 catch {db2 close} 513 catch {db close} 514 file delete -force test.db 515 sqlite3 db test.db 516 set DB [sqlite3_connection_pointer db] 517 set STMT [sqlite3_prepare $DB { 518 CREATE TABLE t1( 519 x INTEGER PRIMARY KEY AUTOINCREMENT 520 ) 521 } -1 TAIL] 522 sqlite3_finalize $STMT 523 set STMT [sqlite3_prepare $DB { 524 CREATE TABLE t1( 525 x INTEGER PRIMARY KEY AUTOINCREMENT 526 ) 527 } -1 TAIL] 528 sqlite3_step $STMT 529 sqlite3_finalize $STMT 530 execsql { 531 INSERT INTO t1 VALUES(NULL); 532 SELECT * FROM t1; 533 } 534} {1} 535 536finish_test 537