OLD | NEW |
| (Empty) |
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 sher
man 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 she
rman 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 she
rman 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 sher
man 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 pho
ne 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 s
herman 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 sher
man 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 sher
man 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 finish_test | |
OLD | NEW |