Snapshot of upstream SQLite 3.34.1
[sqlcipher.git] / test / without_rowid1.test
blob02a089610d4755752d2b4b7deda6a6c0d2cb21d2
1 # 2013-10-30
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # This file implements regression tests for SQLite library.  The
13 # focus of this file is testing WITHOUT ROWID tables.
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
18 set testprefix without_rowid1
20 proc do_execsql_test_if_vtab {tn sql {res {}}} {
21   ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
24 # Create and query a WITHOUT ROWID table.
26 do_execsql_test without_rowid1-1.0 {
27   CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID;
28   CREATE INDEX t1bd ON t1(b, d);
29   INSERT INTO t1 VALUES('journal','sherman','ammonia','helena');
30   INSERT INTO t1 VALUES('dynamic','juliet','flipper','command');
31   INSERT INTO t1 VALUES('journal','sherman','gamma','patriot');
32   INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena');
33   SELECT *, '|' FROM t1 ORDER BY c, a;
34 } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}
36 integrity_check without_rowid1-1.0ic
38 do_execsql_test_if_vtab without_rowid1-1.0ixi {
39   SELECT name, key FROM pragma_index_xinfo('t1');
40 } {c 1 a 1 b 0 d 0}
42 do_execsql_test without_rowid1-1.1 {
43   SELECT *, '|' FROM t1 ORDER BY +c, a;
44 } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}
46 do_execsql_test without_rowid1-1.2 {
47   SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC;
48 } {journal sherman gamma patriot | dynamic juliet flipper command | journal sherman ammonia helena | arctic sleep ammonia helena |}
50 do_execsql_test without_rowid1-1.11 {
51   SELECT *, '|' FROM t1 ORDER BY b, d;
52 } {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |}
54 do_execsql_test without_rowid1-1.12 {
55   SELECT *, '|' FROM t1 ORDER BY +b, d;
56 } {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |}
58 # Trying to insert a duplicate PRIMARY KEY fails.
60 do_test without_rowid1-1.21 {
61   catchsql {
62     INSERT INTO t1 VALUES('dynamic','phone','flipper','harvard');
63   }
64 } {1 {UNIQUE constraint failed: t1.c, t1.a}}
66 # REPLACE INTO works, however.
68 do_execsql_test without_rowid1-1.22 {
69   REPLACE INTO t1 VALUES('dynamic','phone','flipper','harvard');
70   SELECT *, '|' FROM t1 ORDER BY c, a;
71 } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic phone flipper harvard | journal sherman gamma patriot |}
73 do_execsql_test without_rowid1-1.23 {
74   SELECT *, '|' FROM t1 ORDER BY b, d;
75 } {dynamic phone flipper harvard | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |}
77 # UPDATE statements.
79 do_execsql_test without_rowid1-1.31 {
80   UPDATE t1 SET d=3.1415926 WHERE a='journal';
81   SELECT *, '|' FROM t1 ORDER BY c, a;
82 } {arctic sleep ammonia helena | journal sherman ammonia 3.1415926 | dynamic phone flipper harvard | journal sherman gamma 3.1415926 |}
83 do_execsql_test without_rowid1-1.32 {
84   SELECT *, '|' FROM t1 ORDER BY b, d;
85 } {dynamic phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |}
87 do_execsql_test without_rowid1-1.35 {
88   UPDATE t1 SET a=1250 WHERE b='phone';
89   SELECT *, '|' FROM t1 ORDER BY c, a;
90 } {arctic sleep ammonia helena | journal sherman ammonia 3.1415926 | 1250 phone flipper harvard | journal sherman gamma 3.1415926 |}
91 integrity_check without_rowid1-1.36
93 do_execsql_test without_rowid1-1.37 {
94   SELECT *, '|' FROM t1 ORDER BY b, d;
95 } {1250 phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |}
97 do_execsql_test without_rowid1-1.40 {
98   VACUUM;
99   SELECT *, '|' FROM t1 ORDER BY b, d;
100 } {1250 phone flipper harvard | journal sherman ammonia 3.1415926 | journal sherman gamma 3.1415926 | arctic sleep ammonia helena |}
101 integrity_check without_rowid1-1.41
103 # Verify that ANALYZE works
105 do_execsql_test without_rowid1-1.50 {
106   ANALYZE;
107   SELECT * FROM sqlite_stat1 ORDER BY idx;
108 } {t1 t1 {4 2 1} t1 t1bd {4 2 2}}
109 ifcapable stat4 {
110   do_execsql_test without_rowid1-1.52 {
111     SELECT DISTINCT tbl, idx FROM sqlite_stat4 ORDER BY idx;
112   } {t1 t1 t1 t1bd}
115 #----------
117 do_execsql_test 2.1.1 {
118   CREATE TABLE t4 (a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID;
119   INSERT INTO t4 VALUES('abc', 'def');
120   SELECT * FROM t4;
121 } {abc def}
122 do_execsql_test 2.1.2 {
123   UPDATE t4 SET a = 'ABC';
124   SELECT * FROM t4;
125 } {ABC def}
126 do_execsql_test_if_vtab 2.1.3 {
127   SELECT name, coll, key FROM pragma_index_xinfo('t4');
128 } {a nocase 1 b BINARY 0}
130 do_execsql_test 2.2.1 {
131   DROP TABLE t4;
132   CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID;
133   INSERT INTO t4(a, b) VALUES('abc', 'def');
134   SELECT * FROM t4;
135 } {def abc}
137 do_execsql_test 2.2.2 {
138   UPDATE t4 SET a = 'ABC', b = 'xyz';
139   SELECT * FROM t4;
140 } {xyz ABC}
142 do_execsql_test_if_vtab 2.2.3 {
143   SELECT name, coll, key FROM pragma_index_xinfo('t4');
144 } {a nocase 1 b BINARY 0}
147 do_execsql_test 2.3.1 {
148   CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID;
149   INSERT INTO t5(a, b) VALUES('abc', 'def');
150   UPDATE t5 SET a='abc', b='def';
151 } {}
153 do_execsql_test_if_vtab 2.3.2 {
154   SELECT name, coll, key FROM pragma_index_xinfo('t5');
155 } {b BINARY 1 a BINARY 1}
158 do_execsql_test 2.4.1 {
159   CREATE TABLE t6 (
160     a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a)
161   ) WITHOUT ROWID;
163   INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi');
164   UPDATE t6 SET a='ABC', c='ghi';
165 } {}
167 do_execsql_test 2.4.2 {
168   SELECT * FROM t6 ORDER BY b, a;
169   SELECT * FROM t6 ORDER BY c;
170 } {ABC def ghi ABC def ghi}
172 do_execsql_test_if_vtab 2.4.3 {
173   SELECT name, coll, key FROM pragma_index_xinfo('t6');
174 } {b BINARY 1 a nocase 1 c BINARY 0}
177 #-------------------------------------------------------------------------
178 # Unless the destination table is completely empty, the xfer optimization 
179 # is disabled for WITHOUT ROWID tables. The following tests check for
180 # some problems that might occur if this were not the case.
182 reset_db
183 do_execsql_test 3.1.1 {
184   CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID;
185   CREATE UNIQUE INDEX i1 ON t1(b);
187   CREATE TABLE t2(a, b, PRIMARY KEY(a)) WITHOUT ROWID;
188   CREATE UNIQUE INDEX i2 ON t2(b);
190   INSERT INTO t1 VALUES('one', 'two');
191   INSERT INTO t2 VALUES('three', 'two');
194 do_execsql_test 3.1.2 {
195   INSERT OR REPLACE INTO t1 SELECT * FROM t2;
196   SELECT * FROM t1;
197 } {three two}
199 do_execsql_test 3.1.3 {
200   DELETE FROM t1;
201   INSERT INTO t1 SELECT * FROM t2;
202   SELECT * FROM t1;
203 } {three two}
205 do_catchsql_test 3.1.4 {
206   INSERT INTO t2 VALUES('four', 'four');
207   INSERT INTO t2 VALUES('six', 'two');
208   INSERT INTO t1 SELECT * FROM t2;
209 } {1 {UNIQUE constraint failed: t2.b}}
211 do_execsql_test 3.1.5 {
212   CREATE TABLE t3(a PRIMARY KEY);
213   CREATE TABLE t4(a PRIMARY KEY);
215   INSERT INTO t4 VALUES('i');
216   INSERT INTO t4 VALUES('ii');
217   INSERT INTO t4 VALUES('iii');
219   INSERT INTO t3 SELECT * FROM t4;
220   SELECT * FROM t3;
221 } {i ii iii}
223 ############################################################################
224 # Ticket [c34d0557f740c450709d6e33df72d4f3f651a3cc]
225 # Name resolution issue with WITHOUT ROWID
227 do_execsql_test 4.1 {
228   CREATE TABLE t41(a PRIMARY KEY) WITHOUT ROWID;
229   INSERT INTO t41 VALUES('abc');
230   CREATE TABLE t42(x);
231   INSERT INTO t42 VALUES('xyz');
232   SELECT t42.rowid FROM t41, t42;
233 } {1}
234 do_execsql_test 4.2 {
235   SELECT t42.rowid FROM t42, t41;
236 } {1}
239 #--------------------------------------------------------------------------
240 # The following tests verify that the trailing PK fields added to each
241 # entry in an index on a WITHOUT ROWID table are used correctly.
243 do_execsql_test 5.0 {
244   CREATE TABLE t45(a PRIMARY KEY, b, c) WITHOUT ROWID;
245   CREATE INDEX i45 ON t45(b);
247   INSERT INTO t45 VALUES(2, 'one', 'x');
248   INSERT INTO t45 VALUES(4, 'one', 'x');
249   INSERT INTO t45 VALUES(6, 'one', 'x');
250   INSERT INTO t45 VALUES(8, 'one', 'x');
251   INSERT INTO t45 VALUES(10, 'one', 'x');
253   INSERT INTO t45 VALUES(1, 'two', 'x');
254   INSERT INTO t45 VALUES(3, 'two', 'x');
255   INSERT INTO t45 VALUES(5, 'two', 'x');
256   INSERT INTO t45 VALUES(7, 'two', 'x');
257   INSERT INTO t45 VALUES(9, 'two', 'x');
260 do_eqp_test 5.1 {
261   SELECT * FROM t45 WHERE b=? AND a>?
262 } {USING INDEX i45 (b=? AND a>?)}
264 do_execsql_test 5.2 {
265   SELECT * FROM t45 WHERE b='two' AND a>4
266 } {5 two x 7 two x 9 two x}
268 do_execsql_test 5.3 {
269   SELECT * FROM t45 WHERE b='one' AND a<8
270 } { 2 one x 4 one x 6 one x }
272 do_execsql_test 5.4 {
273   CREATE TABLE t46(a, b, c, d, PRIMARY KEY(a, b)) WITHOUT ROWID;
274   WITH r(x) AS (
275     SELECT 1 UNION ALL SELECT x+1 FROM r WHERE x<100
276   )
277   INSERT INTO t46 SELECT x / 20, x % 20, x % 10, x FROM r;
280 set queries {
281   1    2    "c = 5 AND a = 1"          {i46 (c=? AND a=?)}
282   2    6    "c = 4 AND a < 3"          {i46 (c=? AND a<?)}
283   3    4    "c = 2 AND a >= 3"         {i46 (c=? AND a>?)}
284   4    1    "c = 2 AND a = 1 AND b<10" {i46 (c=? AND a=? AND b<?)}
285   5    1    "c = 0 AND a = 0 AND b>5"  {i46 (c=? AND a=? AND b>?)}
288 foreach {tn cnt where eqp} $queries {
289   do_execsql_test 5.5.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt
292 do_execsql_test 5.6 {
293   CREATE INDEX i46 ON t46(c);
296 foreach {tn cnt where eqp} $queries {
297   do_execsql_test 5.7.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt
298   do_eqp_test 5.7.$tn.2  "SELECT count(*) FROM t46 WHERE $where" $eqp
301 #-------------------------------------------------------------------------
302 # Check that redundant UNIQUE constraints do not cause a problem.
304 do_execsql_test 6.0 {
305   CREATE TABLE t47(a, b UNIQUE PRIMARY KEY) WITHOUT ROWID;
306   CREATE INDEX i47 ON t47(a);
307   INSERT INTO t47 VALUES(1, 2);
308   INSERT INTO t47 VALUES(2, 4);
309   INSERT INTO t47 VALUES(3, 6);
310   INSERT INTO t47 VALUES(4, 8);
312   VACUUM;
313   PRAGMA integrity_check;
314   SELECT name FROM sqlite_master WHERE tbl_name = 't47';
315 } {ok t47 i47}
317 do_execsql_test 6.1 {
318   CREATE TABLE t48(
319     a UNIQUE UNIQUE, 
320     b UNIQUE, 
321     PRIMARY KEY(a), 
322     UNIQUE(a)
323   ) WITHOUT ROWID;
324   INSERT INTO t48 VALUES('a', 'b'), ('c', 'd'), ('e', 'f');
325   VACUUM;
326   PRAGMA integrity_check;
327   SELECT name FROM sqlite_master WHERE tbl_name = 't48';
328 } {
329   ok  t48   sqlite_autoindex_t48_2
332 # 2015-05-28: CHECK constraints can refer to the rowid in a
333 # rowid table, but not in a WITHOUT ROWID table.
335 do_execsql_test 7.1 {
336   CREATE TABLE t70a(
337      a INT CHECK( rowid!=33 ),
338      b TEXT PRIMARY KEY
339   );
340   INSERT INTO t70a(a,b) VALUES(99,'hello');
341 } {}
342 do_catchsql_test 7.2 {
343   INSERT INTO t70a(rowid,a,b) VALUES(33,99,'xyzzy');
344 } {1 {CHECK constraint failed: rowid!=33}}
345 do_catchsql_test 7.3 {
346   CREATE TABLE t70b(
347      a INT CHECK( rowid!=33 ),
348      b TEXT PRIMARY KEY
349   ) WITHOUT ROWID;
350 } {1 {no such column: rowid}}
352 # 2017-07-30: OSSFuzz discovered that an extra entry was being
353 # added in the sqlite_master table for an "INTEGER PRIMARY KEY UNIQUE"
354 # WITHOUT ROWID table.  Make sure this has now been fixed.
356 db close
357 sqlite3 db :memory:
358 do_execsql_test 8.1 {
359   CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID;
360   CREATE INDEX t1x ON t1(x);
361   INSERT INTO t1(x,b) VALUES('funny','buffalo');
362   SELECT type, name, '|' FROM sqlite_master;
363 } {table t1 | index t1x |}
365 # 2018-04-05: OSSFuzz found that the following was accessing an 
366 # unintialized memory cell. Which was not actually causing a 
367 # malfunction, but does cause an assert() to fail.
369 do_execsql_test 9.0 {
370   CREATE TABLE t2(b, c, PRIMARY KEY(b,c)) WITHOUT ROWID;
371   CREATE UNIQUE INDEX t2b ON t2(b);
372   UPDATE t2 SET b=1 WHERE b='';
375 do_execsql_test 10.1 {
376   DELETE FROM t2 WHERE b=1
379 #-------------------------------------------------------------------------
380 # UNIQUE constraint violation in an UPDATE with a multi-column PK.
382 reset_db
383 do_execsql_test 10.0 {
384   CREATE TABLE t1(a, b, c UNIQUE, PRIMARY KEY(a, b)) WITHOUT ROWID;
385   INSERT INTO t1 VALUES('a', 'a', 1);
386   INSERT INTO t1 VALUES('a', 'b', 2);
387   INSERT INTO t1 VALUES('b', 'a', 3);
388   INSERT INTO t1 VALUES('b', 'b', 4);
391 do_catchsql_test 10.1 {
392   UPDATE t1 SET c=1 WHERE (a, b) = ('a', 'a');
393 } {0 {}}
394 do_catchsql_test 10.2 {
395   UPDATE t1 SET c=1 WHERE (a, b) = ('a', 'b');
396 } {1 {UNIQUE constraint failed: t1.c}}
397 do_catchsql_test 10.3 {
398   UPDATE t1 SET c=1 WHERE (a, b) = ('b', 'a');
399 } {1 {UNIQUE constraint failed: t1.c}}
400 do_catchsql_test 10.4 {
401   UPDATE t1 SET c=1 WHERE (a, b) = ('b', 'b');
402 } {1 {UNIQUE constraint failed: t1.c}}
403 do_catchsql_test 10.5 {
404   UPDATE t1 SET c=1 WHERE (a, b) = ('c', 'c');
405 } {0 {}}
407 do_execsql_test 10.6 {
408   CREATE TRIGGER t1_tr BEFORE UPDATE ON t1 BEGIN
409     DELETE FROM t1 WHERE a = new.a;
410   END;
411   UPDATE t1 SET c = c+1 WHERE a = 'a';
412   SELECT * FROM t1;
413 } {b a 3  b b 4}
415 # 2019-04-29 ticket https://www.sqlite.org/src/info/3182d3879020ef3
416 do_execsql_test 11.1 {
417   CREATE TABLE t11(a TEXT PRIMARY KEY, b INT) WITHOUT ROWID;
418   CREATE INDEX t11a ON t11(a COLLATE NOCASE);
419   INSERT INTO t11(a,b) VALUES ('A',1),('a',2);
420   PRAGMA integrity_check;
421   SELECT a FROM t11 ORDER BY a COLLATE binary;
422 } {ok A a}
424 # 2019-05-13 ticket https://www.sqlite.org/src/info/bba7b69f9849b5b
425 do_execsql_test 12.1 {
426   DROP TABLE IF EXISTS t0;
427   CREATE TABLE t0 (c0 INTEGER PRIMARY KEY DESC, c1 UNIQUE DEFAULT NULL) WITHOUT ROWID;
428   INSERT INTO t0(c0) VALUES (1), (2), (3), (4), (5);
429   REINDEX;
430   PRAGMA integrity_check;
431 } {ok}
433 # 2019-11-07 ticket https://www.sqlite.org/src/info/302027baf1374498
434 # The xferCompatibleIndex() function confuses a PRIMARY KEY index
435 # with a UNIQUE index.
437 do_execsql_test 13.10 {
438   DROP TABLE IF EXISTS t0;
439   DROP TABLE IF EXISTS t1;
440   CREATE TABLE t0(
441     c0,
442     c1 UNIQUE,
443     PRIMARY KEY(c1, c1)
444   ) WITHOUT ROWID;
445   INSERT INTO t0(c0,c1) VALUES('abc','xyz');
446   CREATE TABLE t1(
447     c0,
448     c1 UNIQUE,
449     PRIMARY KEY(c1, c1)
450   ) WITHOUT ROWID;
451   INSERT INTO t1 SELECT * FROM t0;
452   PRAGMA integrity_check;
453   SELECT * FROM t0, t1;
454 } {ok abc xyz abc xyz}
455   
456 finish_test