16fbe41acSdrh# 2013-10-30 26fbe41acSdrh# 36fbe41acSdrh# The author disclaims copyright to this source code. In place of 46fbe41acSdrh# a legal notice, here is a blessing: 56fbe41acSdrh# 66fbe41acSdrh# May you do good and not evil. 76fbe41acSdrh# May you find forgiveness for yourself and forgive others. 86fbe41acSdrh# May you share freely, never taking more than you give. 96fbe41acSdrh# 106fbe41acSdrh#*********************************************************************** 116fbe41acSdrh# 126fbe41acSdrh# This file implements regression tests for SQLite library. The 136fbe41acSdrh# focus of this file is testing WITHOUT ROWID tables. 146fbe41acSdrh# 156fbe41acSdrh 166fbe41acSdrhset testdir [file dirname $argv0] 176fbe41acSdrhsource $testdir/tester.tcl 18e83267daSdanset testprefix without_rowid1 196fbe41acSdrh 20b008e4d7Sdanproc do_execsql_test_if_vtab {tn sql {res {}}} { 21b008e4d7Sdan ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] } 22b008e4d7Sdan} 23b008e4d7Sdan 246fbe41acSdrh# Create and query a WITHOUT ROWID table. 256fbe41acSdrh# 266fbe41acSdrhdo_execsql_test without_rowid1-1.0 { 276fbe41acSdrh CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID; 286fbe41acSdrh CREATE INDEX t1bd ON t1(b, d); 296fbe41acSdrh INSERT INTO t1 VALUES('journal','sherman','ammonia','helena'); 306fbe41acSdrh INSERT INTO t1 VALUES('dynamic','juliet','flipper','command'); 316fbe41acSdrh INSERT INTO t1 VALUES('journal','sherman','gamma','patriot'); 326fbe41acSdrh INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena'); 336fbe41acSdrh SELECT *, '|' FROM t1 ORDER BY c, a; 346fbe41acSdrh} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} 356fbe41acSdrh 366fbe41acSdrhintegrity_check without_rowid1-1.0ic 376fbe41acSdrh 38b008e4d7Sdando_execsql_test_if_vtab without_rowid1-1.0ixi { 3919d9a3caSdrh SELECT name, key FROM pragma_index_xinfo('t1'); 4019d9a3caSdrh} {c 1 a 1 b 0 d 0} 412e50f670Sdrhdo_execsql_test_if_vtab without_rowid1-1.0tl { 422e50f670Sdrh SELECT wr FROM pragma_table_list('t1'); 432e50f670Sdrh} {1} 4419d9a3caSdrh 456fbe41acSdrhdo_execsql_test without_rowid1-1.1 { 466fbe41acSdrh SELECT *, '|' FROM t1 ORDER BY +c, a; 476fbe41acSdrh} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} 486fbe41acSdrh 496fbe41acSdrhdo_execsql_test without_rowid1-1.2 { 506fbe41acSdrh SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC; 516fbe41acSdrh} {journal sherman gamma patriot | dynamic juliet flipper command | journal sherman ammonia helena | arctic sleep ammonia helena |} 526fbe41acSdrh 536fbe41acSdrhdo_execsql_test without_rowid1-1.11 { 546fbe41acSdrh SELECT *, '|' FROM t1 ORDER BY b, d; 556fbe41acSdrh} {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |} 566fbe41acSdrh 576fbe41acSdrhdo_execsql_test without_rowid1-1.12 { 586fbe41acSdrh SELECT *, '|' FROM t1 ORDER BY +b, d; 596fbe41acSdrh} {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |} 606fbe41acSdrh 616fbe41acSdrh# Trying to insert a duplicate PRIMARY KEY fails. 626fbe41acSdrh# 636fbe41acSdrhdo_test without_rowid1-1.21 { 646fbe41acSdrh catchsql { 656fbe41acSdrh INSERT INTO t1 VALUES('dynamic','phone','flipper','harvard'); 666fbe41acSdrh } 67f9c8ce3cSdrh} {1 {UNIQUE constraint failed: t1.c, t1.a}} 686fbe41acSdrh 696fbe41acSdrh# REPLACE INTO works, however. 706fbe41acSdrh# 716fbe41acSdrhdo_execsql_test without_rowid1-1.22 { 726fbe41acSdrh REPLACE INTO t1 VALUES('dynamic','phone','flipper','harvard'); 736fbe41acSdrh SELECT *, '|' FROM t1 ORDER BY c, a; 746934fc7bSdrh} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic phone flipper harvard | journal sherman gamma patriot |} 756fbe41acSdrh 76f8ffb278Sdrhdo_execsql_test without_rowid1-1.23 { 77f8ffb278Sdrh SELECT *, '|' FROM t1 ORDER BY b, d; 78f8ffb278Sdrh} {dynamic phone flipper harvard | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |} 79f8ffb278Sdrh 80f8ffb278Sdrh# UPDATE statements. 81f8ffb278Sdrh# 82f8ffb278Sdrhdo_execsql_test without_rowid1-1.31 { 83f8ffb278Sdrh UPDATE t1 SET d=3.1415926 WHERE a='journal'; 84f8ffb278Sdrh SELECT *, '|' FROM t1 ORDER BY c, a; 85f8ffb278Sdrh} {arctic sleep ammonia helena | journal sherman ammonia 3.1415926 | dynamic phone flipper harvard | journal sherman gamma 3.1415926 |} 86bc43ae3dSdrhdo_execsql_test without_rowid1-1.32 { 87bc43ae3dSdrh SELECT *, '|' FROM t1 ORDER BY b, d; 88bc43ae3dSdrh} {dynamic phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |} 89bc43ae3dSdrh 90bc43ae3dSdrhdo_execsql_test without_rowid1-1.35 { 91bc43ae3dSdrh UPDATE t1 SET a=1250 WHERE b='phone'; 92bc43ae3dSdrh SELECT *, '|' FROM t1 ORDER BY c, a; 93bc43ae3dSdrh} {arctic sleep ammonia helena | journal sherman ammonia 3.1415926 | 1250 phone flipper harvard | journal sherman gamma 3.1415926 |} 94bc43ae3dSdrhintegrity_check without_rowid1-1.36 95bc43ae3dSdrh 96bc43ae3dSdrhdo_execsql_test without_rowid1-1.37 { 97bc43ae3dSdrh SELECT *, '|' FROM t1 ORDER BY b, d; 98bc43ae3dSdrh} {1250 phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |} 99bc43ae3dSdrh 100bc43ae3dSdrhdo_execsql_test without_rowid1-1.40 { 101bc43ae3dSdrh VACUUM; 102bc43ae3dSdrh SELECT *, '|' FROM t1 ORDER BY b, d; 103bc43ae3dSdrh} {1250 phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |} 104bc43ae3dSdrhintegrity_check without_rowid1-1.41 105bc43ae3dSdrh 10663f0eedfSdrh# Verify that ANALYZE works 10763f0eedfSdrh# 108ebe25af1Sdrhdo_execsql_test without_rowid1-1.50 { 109ebe25af1Sdrh ANALYZE; 110ebe25af1Sdrh SELECT * FROM sqlite_stat1 ORDER BY idx; 111ce95d119Sdrh} {t1 t1 {4 2 1} t1 t1bd {4 2 2}} 11263f0eedfSdrhifcapable stat4 { 11363f0eedfSdrh do_execsql_test without_rowid1-1.52 { 11463f0eedfSdrh SELECT DISTINCT tbl, idx FROM sqlite_stat4 ORDER BY idx; 11563f0eedfSdrh } {t1 t1 t1 t1bd} 11663f0eedfSdrh} 117f8ffb278Sdrh 118e83267daSdan#---------- 119e83267daSdan 120e83267daSdando_execsql_test 2.1.1 { 121e83267daSdan CREATE TABLE t4 (a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID; 122e83267daSdan INSERT INTO t4 VALUES('abc', 'def'); 123e83267daSdan SELECT * FROM t4; 124e83267daSdan} {abc def} 125e83267daSdando_execsql_test 2.1.2 { 126e83267daSdan UPDATE t4 SET a = 'ABC'; 127e83267daSdan SELECT * FROM t4; 128e83267daSdan} {ABC def} 129b008e4d7Sdando_execsql_test_if_vtab 2.1.3 { 13019d9a3caSdrh SELECT name, coll, key FROM pragma_index_xinfo('t4'); 13119d9a3caSdrh} {a nocase 1 b BINARY 0} 132e83267daSdan 133e83267daSdando_execsql_test 2.2.1 { 134e83267daSdan DROP TABLE t4; 135e83267daSdan CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID; 136e83267daSdan INSERT INTO t4(a, b) VALUES('abc', 'def'); 137e83267daSdan SELECT * FROM t4; 138e83267daSdan} {def abc} 139e83267daSdan 140e83267daSdando_execsql_test 2.2.2 { 141e83267daSdan UPDATE t4 SET a = 'ABC', b = 'xyz'; 142e83267daSdan SELECT * FROM t4; 143e83267daSdan} {xyz ABC} 144e83267daSdan 145b008e4d7Sdando_execsql_test_if_vtab 2.2.3 { 14619d9a3caSdrh SELECT name, coll, key FROM pragma_index_xinfo('t4'); 14719d9a3caSdrh} {a nocase 1 b BINARY 0} 14819d9a3caSdrh 14919d9a3caSdrh 150e83267daSdando_execsql_test 2.3.1 { 151e83267daSdan CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID; 152e83267daSdan INSERT INTO t5(a, b) VALUES('abc', 'def'); 153e83267daSdan UPDATE t5 SET a='abc', b='def'; 154e83267daSdan} {} 155e83267daSdan 156b008e4d7Sdando_execsql_test_if_vtab 2.3.2 { 15719d9a3caSdrh SELECT name, coll, key FROM pragma_index_xinfo('t5'); 15819d9a3caSdrh} {b BINARY 1 a BINARY 1} 15919d9a3caSdrh 16019d9a3caSdrh 161e83267daSdando_execsql_test 2.4.1 { 162e83267daSdan CREATE TABLE t6 ( 163e83267daSdan a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a) 164e83267daSdan ) WITHOUT ROWID; 165e83267daSdan 166e83267daSdan INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi'); 167e83267daSdan UPDATE t6 SET a='ABC', c='ghi'; 168e83267daSdan} {} 169e83267daSdan 170e83267daSdando_execsql_test 2.4.2 { 171e83267daSdan SELECT * FROM t6 ORDER BY b, a; 172e83267daSdan SELECT * FROM t6 ORDER BY c; 173e83267daSdan} {ABC def ghi ABC def ghi} 174e83267daSdan 175b008e4d7Sdando_execsql_test_if_vtab 2.4.3 { 17619d9a3caSdrh SELECT name, coll, key FROM pragma_index_xinfo('t6'); 17719d9a3caSdrh} {b BINARY 1 a nocase 1 c BINARY 0} 17819d9a3caSdrh 17919d9a3caSdrh 180427ebba1Sdan#------------------------------------------------------------------------- 181427ebba1Sdan# Unless the destination table is completely empty, the xfer optimization 182427ebba1Sdan# is disabled for WITHOUT ROWID tables. The following tests check for 183427ebba1Sdan# some problems that might occur if this were not the case. 184427ebba1Sdan# 185427ebba1Sdanreset_db 186427ebba1Sdando_execsql_test 3.1.1 { 187427ebba1Sdan CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID; 188427ebba1Sdan CREATE UNIQUE INDEX i1 ON t1(b); 189427ebba1Sdan 190427ebba1Sdan CREATE TABLE t2(a, b, PRIMARY KEY(a)) WITHOUT ROWID; 191427ebba1Sdan CREATE UNIQUE INDEX i2 ON t2(b); 192427ebba1Sdan 193427ebba1Sdan INSERT INTO t1 VALUES('one', 'two'); 194427ebba1Sdan INSERT INTO t2 VALUES('three', 'two'); 195427ebba1Sdan} 196427ebba1Sdan 197427ebba1Sdando_execsql_test 3.1.2 { 198427ebba1Sdan INSERT OR REPLACE INTO t1 SELECT * FROM t2; 199427ebba1Sdan SELECT * FROM t1; 200427ebba1Sdan} {three two} 201427ebba1Sdan 202427ebba1Sdando_execsql_test 3.1.3 { 203427ebba1Sdan DELETE FROM t1; 204427ebba1Sdan INSERT INTO t1 SELECT * FROM t2; 205427ebba1Sdan SELECT * FROM t1; 206427ebba1Sdan} {three two} 207427ebba1Sdan 208427ebba1Sdando_catchsql_test 3.1.4 { 209427ebba1Sdan INSERT INTO t2 VALUES('four', 'four'); 210427ebba1Sdan INSERT INTO t2 VALUES('six', 'two'); 211427ebba1Sdan INSERT INTO t1 SELECT * FROM t2; 212427ebba1Sdan} {1 {UNIQUE constraint failed: t2.b}} 213427ebba1Sdan 214427ebba1Sdando_execsql_test 3.1.5 { 215427ebba1Sdan CREATE TABLE t3(a PRIMARY KEY); 216427ebba1Sdan CREATE TABLE t4(a PRIMARY KEY); 217427ebba1Sdan 218427ebba1Sdan INSERT INTO t4 VALUES('i'); 219427ebba1Sdan INSERT INTO t4 VALUES('ii'); 220427ebba1Sdan INSERT INTO t4 VALUES('iii'); 221427ebba1Sdan 222427ebba1Sdan INSERT INTO t3 SELECT * FROM t4; 223427ebba1Sdan SELECT * FROM t3; 224427ebba1Sdan} {i ii iii} 225427ebba1Sdan 226784156f8Sdrh############################################################################ 227784156f8Sdrh# Ticket [c34d0557f740c450709d6e33df72d4f3f651a3cc] 228784156f8Sdrh# Name resolution issue with WITHOUT ROWID 229784156f8Sdrh# 230784156f8Sdrhdo_execsql_test 4.1 { 231784156f8Sdrh CREATE TABLE t41(a PRIMARY KEY) WITHOUT ROWID; 232784156f8Sdrh INSERT INTO t41 VALUES('abc'); 233784156f8Sdrh CREATE TABLE t42(x); 234784156f8Sdrh INSERT INTO t42 VALUES('xyz'); 235784156f8Sdrh SELECT t42.rowid FROM t41, t42; 236784156f8Sdrh} {1} 237784156f8Sdrhdo_execsql_test 4.2 { 238784156f8Sdrh SELECT t42.rowid FROM t42, t41; 239784156f8Sdrh} {1} 24039129ce8Sdan 24139129ce8Sdan 24239129ce8Sdan#-------------------------------------------------------------------------- 24339129ce8Sdan# The following tests verify that the trailing PK fields added to each 24439129ce8Sdan# entry in an index on a WITHOUT ROWID table are used correctly. 24539129ce8Sdan# 24639129ce8Sdando_execsql_test 5.0 { 24739129ce8Sdan CREATE TABLE t45(a PRIMARY KEY, b, c) WITHOUT ROWID; 24839129ce8Sdan CREATE INDEX i45 ON t45(b); 24939129ce8Sdan 25039129ce8Sdan INSERT INTO t45 VALUES(2, 'one', 'x'); 25139129ce8Sdan INSERT INTO t45 VALUES(4, 'one', 'x'); 25239129ce8Sdan INSERT INTO t45 VALUES(6, 'one', 'x'); 25339129ce8Sdan INSERT INTO t45 VALUES(8, 'one', 'x'); 25439129ce8Sdan INSERT INTO t45 VALUES(10, 'one', 'x'); 25539129ce8Sdan 25639129ce8Sdan INSERT INTO t45 VALUES(1, 'two', 'x'); 25739129ce8Sdan INSERT INTO t45 VALUES(3, 'two', 'x'); 25839129ce8Sdan INSERT INTO t45 VALUES(5, 'two', 'x'); 25939129ce8Sdan INSERT INTO t45 VALUES(7, 'two', 'x'); 26039129ce8Sdan INSERT INTO t45 VALUES(9, 'two', 'x'); 26139129ce8Sdan} 26239129ce8Sdan 26339129ce8Sdando_eqp_test 5.1 { 26439129ce8Sdan SELECT * FROM t45 WHERE b=? AND a>? 265b3f0276bSdrh} {USING INDEX i45 (b=? AND a>?)} 26639129ce8Sdan 26739129ce8Sdando_execsql_test 5.2 { 26839129ce8Sdan SELECT * FROM t45 WHERE b='two' AND a>4 26939129ce8Sdan} {5 two x 7 two x 9 two x} 27039129ce8Sdan 27139129ce8Sdando_execsql_test 5.3 { 27239129ce8Sdan SELECT * FROM t45 WHERE b='one' AND a<8 27339129ce8Sdan} { 2 one x 4 one x 6 one x } 27439129ce8Sdan 27539129ce8Sdando_execsql_test 5.4 { 27639129ce8Sdan CREATE TABLE t46(a, b, c, d, PRIMARY KEY(a, b)) WITHOUT ROWID; 27739129ce8Sdan WITH r(x) AS ( 27839129ce8Sdan SELECT 1 UNION ALL SELECT x+1 FROM r WHERE x<100 27939129ce8Sdan ) 28039129ce8Sdan INSERT INTO t46 SELECT x / 20, x % 20, x % 10, x FROM r; 28139129ce8Sdan} 28239129ce8Sdan 28339129ce8Sdanset queries { 284b3f0276bSdrh 1 2 "c = 5 AND a = 1" {i46 (c=? AND a=?)} 285b3f0276bSdrh 2 6 "c = 4 AND a < 3" {i46 (c=? AND a<?)} 286b3f0276bSdrh 3 4 "c = 2 AND a >= 3" {i46 (c=? AND a>?)} 287b3f0276bSdrh 4 1 "c = 2 AND a = 1 AND b<10" {i46 (c=? AND a=? AND b<?)} 288b3f0276bSdrh 5 1 "c = 0 AND a = 0 AND b>5" {i46 (c=? AND a=? AND b>?)} 28939129ce8Sdan} 29039129ce8Sdan 29139129ce8Sdanforeach {tn cnt where eqp} $queries { 29239129ce8Sdan do_execsql_test 5.5.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt 29339129ce8Sdan} 29439129ce8Sdan 29539129ce8Sdando_execsql_test 5.6 { 29639129ce8Sdan CREATE INDEX i46 ON t46(c); 29739129ce8Sdan} 29839129ce8Sdan 29939129ce8Sdanforeach {tn cnt where eqp} $queries { 30039129ce8Sdan do_execsql_test 5.7.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt 30139129ce8Sdan do_eqp_test 5.7.$tn.2 "SELECT count(*) FROM t46 WHERE $where" $eqp 30239129ce8Sdan} 30339129ce8Sdan 304c5b73585Sdan#------------------------------------------------------------------------- 305c5b73585Sdan# Check that redundant UNIQUE constraints do not cause a problem. 306c5b73585Sdan# 307c5b73585Sdando_execsql_test 6.0 { 308c5b73585Sdan CREATE TABLE t47(a, b UNIQUE PRIMARY KEY) WITHOUT ROWID; 309c5b73585Sdan CREATE INDEX i47 ON t47(a); 310c5b73585Sdan INSERT INTO t47 VALUES(1, 2); 311c5b73585Sdan INSERT INTO t47 VALUES(2, 4); 312c5b73585Sdan INSERT INTO t47 VALUES(3, 6); 313c5b73585Sdan INSERT INTO t47 VALUES(4, 8); 314c5b73585Sdan 315c5b73585Sdan VACUUM; 316c5b73585Sdan PRAGMA integrity_check; 317c5b73585Sdan SELECT name FROM sqlite_master WHERE tbl_name = 't47'; 318c5b73585Sdan} {ok t47 i47} 319c5b73585Sdan 320c5b73585Sdando_execsql_test 6.1 { 321c5b73585Sdan CREATE TABLE t48( 322c5b73585Sdan a UNIQUE UNIQUE, 323c5b73585Sdan b UNIQUE, 324c5b73585Sdan PRIMARY KEY(a), 325c5b73585Sdan UNIQUE(a) 326c5b73585Sdan ) WITHOUT ROWID; 327c5b73585Sdan INSERT INTO t48 VALUES('a', 'b'), ('c', 'd'), ('e', 'f'); 328c5b73585Sdan VACUUM; 329c5b73585Sdan PRAGMA integrity_check; 330c5b73585Sdan SELECT name FROM sqlite_master WHERE tbl_name = 't48'; 331c5b73585Sdan} { 332c5b73585Sdan ok t48 sqlite_autoindex_t48_2 333c5b73585Sdan} 334c5b73585Sdan 335fccda8a1Sdrh# 2015-05-28: CHECK constraints can refer to the rowid in a 336fccda8a1Sdrh# rowid table, but not in a WITHOUT ROWID table. 337fccda8a1Sdrh# 338fccda8a1Sdrhdo_execsql_test 7.1 { 339fccda8a1Sdrh CREATE TABLE t70a( 340fccda8a1Sdrh a INT CHECK( rowid!=33 ), 341fccda8a1Sdrh b TEXT PRIMARY KEY 342fccda8a1Sdrh ); 343fccda8a1Sdrh INSERT INTO t70a(a,b) VALUES(99,'hello'); 344fccda8a1Sdrh} {} 345fccda8a1Sdrhdo_catchsql_test 7.2 { 346fccda8a1Sdrh INSERT INTO t70a(rowid,a,b) VALUES(33,99,'xyzzy'); 34792e21ef0Sdrh} {1 {CHECK constraint failed: rowid!=33}} 348fccda8a1Sdrhdo_catchsql_test 7.3 { 349fccda8a1Sdrh CREATE TABLE t70b( 350fccda8a1Sdrh a INT CHECK( rowid!=33 ), 351fccda8a1Sdrh b TEXT PRIMARY KEY 352fccda8a1Sdrh ) WITHOUT ROWID; 353fccda8a1Sdrh} {1 {no such column: rowid}} 354c5b73585Sdan 355df94966cSdrh# 2017-07-30: OSSFuzz discovered that an extra entry was being 356df94966cSdrh# added in the sqlite_master table for an "INTEGER PRIMARY KEY UNIQUE" 357df94966cSdrh# WITHOUT ROWID table. Make sure this has now been fixed. 358df94966cSdrh# 359df94966cSdrhdb close 360df94966cSdrhsqlite3 db :memory: 361df94966cSdrhdo_execsql_test 8.1 { 362df94966cSdrh CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID; 363df94966cSdrh CREATE INDEX t1x ON t1(x); 364df94966cSdrh INSERT INTO t1(x,b) VALUES('funny','buffalo'); 365df94966cSdrh SELECT type, name, '|' FROM sqlite_master; 366df94966cSdrh} {table t1 | index t1x |} 367df94966cSdrh 3689a3c375fSdan# 2018-04-05: OSSFuzz found that the following was accessing an 3699a3c375fSdan# unintialized memory cell. Which was not actually causing a 3709a3c375fSdan# malfunction, but does cause an assert() to fail. 3719a3c375fSdan# 3729a3c375fSdando_execsql_test 9.0 { 3739a3c375fSdan CREATE TABLE t2(b, c, PRIMARY KEY(b,c)) WITHOUT ROWID; 3749a3c375fSdan CREATE UNIQUE INDEX t2b ON t2(b); 3759a3c375fSdan UPDATE t2 SET b=1 WHERE b=''; 3769a3c375fSdan} 3779a3c375fSdan 3789a3c375fSdando_execsql_test 10.1 { 3799a3c375fSdan DELETE FROM t2 WHERE b=1 3809a3c375fSdan} 381df94966cSdrh 382b84b38fdSdan#------------------------------------------------------------------------- 383b84b38fdSdan# UNIQUE constraint violation in an UPDATE with a multi-column PK. 384b84b38fdSdan# 385b84b38fdSdanreset_db 386b84b38fdSdando_execsql_test 10.0 { 387b84b38fdSdan CREATE TABLE t1(a, b, c UNIQUE, PRIMARY KEY(a, b)) WITHOUT ROWID; 388b84b38fdSdan INSERT INTO t1 VALUES('a', 'a', 1); 389b84b38fdSdan INSERT INTO t1 VALUES('a', 'b', 2); 390b84b38fdSdan INSERT INTO t1 VALUES('b', 'a', 3); 391b84b38fdSdan INSERT INTO t1 VALUES('b', 'b', 4); 392b84b38fdSdan} 393b84b38fdSdan 394b84b38fdSdando_catchsql_test 10.1 { 395b84b38fdSdan UPDATE t1 SET c=1 WHERE (a, b) = ('a', 'a'); 396b84b38fdSdan} {0 {}} 397b84b38fdSdando_catchsql_test 10.2 { 398b84b38fdSdan UPDATE t1 SET c=1 WHERE (a, b) = ('a', 'b'); 399b84b38fdSdan} {1 {UNIQUE constraint failed: t1.c}} 400b84b38fdSdando_catchsql_test 10.3 { 401b84b38fdSdan UPDATE t1 SET c=1 WHERE (a, b) = ('b', 'a'); 402b84b38fdSdan} {1 {UNIQUE constraint failed: t1.c}} 403b84b38fdSdando_catchsql_test 10.4 { 404b84b38fdSdan UPDATE t1 SET c=1 WHERE (a, b) = ('b', 'b'); 405b84b38fdSdan} {1 {UNIQUE constraint failed: t1.c}} 406d1f9932eSdando_catchsql_test 10.5 { 407d1f9932eSdan UPDATE t1 SET c=1 WHERE (a, b) = ('c', 'c'); 408d1f9932eSdan} {0 {}} 409d1f9932eSdan 410d1f9932eSdando_execsql_test 10.6 { 411d1f9932eSdan CREATE TRIGGER t1_tr BEFORE UPDATE ON t1 BEGIN 412d1f9932eSdan DELETE FROM t1 WHERE a = new.a; 413d1f9932eSdan END; 414d1f9932eSdan UPDATE t1 SET c = c+1 WHERE a = 'a'; 415d1f9932eSdan SELECT * FROM t1; 416d1f9932eSdan} {b a 3 b b 4} 417b84b38fdSdan 4184baa75b3Sdrh# 2019-04-29 ticket https://www.sqlite.org/src/info/3182d3879020ef3 4194baa75b3Sdrhdo_execsql_test 11.1 { 4204baa75b3Sdrh CREATE TABLE t11(a TEXT PRIMARY KEY, b INT) WITHOUT ROWID; 4214baa75b3Sdrh CREATE INDEX t11a ON t11(a COLLATE NOCASE); 4224baa75b3Sdrh INSERT INTO t11(a,b) VALUES ('A',1),('a',2); 4234baa75b3Sdrh PRAGMA integrity_check; 4244baa75b3Sdrh SELECT a FROM t11 ORDER BY a COLLATE binary; 4254baa75b3Sdrh} {ok A a} 426bf9ff256Sdrh 427bf9ff256Sdrh# 2019-05-13 ticket https://www.sqlite.org/src/info/bba7b69f9849b5b 428bf9ff256Sdrhdo_execsql_test 12.1 { 429bf9ff256Sdrh DROP TABLE IF EXISTS t0; 430bf9ff256Sdrh CREATE TABLE t0 (c0 INTEGER PRIMARY KEY DESC, c1 UNIQUE DEFAULT NULL) WITHOUT ROWID; 431bf9ff256Sdrh INSERT INTO t0(c0) VALUES (1), (2), (3), (4), (5); 432bf9ff256Sdrh REINDEX; 433bf9ff256Sdrh PRAGMA integrity_check; 434bf9ff256Sdrh} {ok} 435bf9ff256Sdrh 4361e7c00e6Sdrh# 2019-11-07 ticket https://www.sqlite.org/src/info/302027baf1374498 4371e7c00e6Sdrh# The xferCompatibleIndex() function confuses a PRIMARY KEY index 4381e7c00e6Sdrh# with a UNIQUE index. 4391e7c00e6Sdrh# 4401e7c00e6Sdrhdo_execsql_test 13.10 { 4411e7c00e6Sdrh DROP TABLE IF EXISTS t0; 4421e7c00e6Sdrh DROP TABLE IF EXISTS t1; 4431e7c00e6Sdrh CREATE TABLE t0( 4441e7c00e6Sdrh c0, 4451e7c00e6Sdrh c1 UNIQUE, 4461e7c00e6Sdrh PRIMARY KEY(c1, c1) 4471e7c00e6Sdrh ) WITHOUT ROWID; 4481e7c00e6Sdrh INSERT INTO t0(c0,c1) VALUES('abc','xyz'); 4491e7c00e6Sdrh CREATE TABLE t1( 4501e7c00e6Sdrh c0, 4511e7c00e6Sdrh c1 UNIQUE, 4521e7c00e6Sdrh PRIMARY KEY(c1, c1) 4531e7c00e6Sdrh ) WITHOUT ROWID; 4541e7c00e6Sdrh INSERT INTO t1 SELECT * FROM t0; 4551e7c00e6Sdrh PRAGMA integrity_check; 4561e7c00e6Sdrh SELECT * FROM t0, t1; 4571e7c00e6Sdrh} {ok abc xyz abc xyz} 458756748eaSdrh 459756748eaSdrh# 2021-05-13 https://sqlite.org/forum/forumpost/6c8960f545 460756748eaSdrhreset_db 46137f3ac8fSdanifcapable altertable { 462756748eaSdrh do_execsql_test 14.1 { 463756748eaSdrh CREATE TABLE t1(a INT PRIMARY KEY) WITHOUT ROWID; 464756748eaSdrh INSERT INTO t1(a) VALUES(10); 465756748eaSdrh ALTER TABLE t1 ADD COLUMN b INT; 466756748eaSdrh SELECT * FROM t1 WHERE a=20 OR (a=10 AND b=10); 467756748eaSdrh } {} 468756748eaSdrh do_execsql_test 14.2 { 469756748eaSdrh CREATE TABLE dual AS SELECT 'X' AS dummy; 470756748eaSdrh EXPLAIN QUERY PLAN SELECT * FROM dual, t1 WHERE a=10 AND b=10; 471756748eaSdrh } {~/b=/} 47237f3ac8fSdan} 473e83267daSdan 4743ea82384Sdrh# 2022-01-01 https://sqlite.org/forum/forumpost/b03d86f951 PoC #1 4753ea82384Sdrh# Omit an assert() from 2013 that no longer serves any purpose and 4763ea82384Sdrh# is no longer always true. 4773ea82384Sdrh# 478*f17f6075Sdrhifcapable altertable { 4793ea82384Sdrh reset_db 4803ea82384Sdrh do_execsql_test 15.1 { 4813ea82384Sdrh PRAGMA writable_schema=ON; 4823ea82384Sdrh CREATE TABLE sqlite_sequence (name PRIMARY KEY) WITHOUT ROWID; 4833ea82384Sdrh PRAGMA writable_schema=OFF; 4843ea82384Sdrh CREATE TABLE c1(x); 4853ea82384Sdrh INSERT INTO sqlite_sequence(name) VALUES('c0'),('c1'),('c2'); 4863ea82384Sdrh ALTER TABLE c1 RENAME TO a; 4873ea82384Sdrh SELECT name FROM sqlite_sequence ORDER BY +name; 4883ea82384Sdrh } {a c0 c2} 489*f17f6075Sdrh} 490784156f8Sdrhfinish_test 491