blob: 042132b81d59db4a30fe7df00a8c948f40a15c33 [file] [log] [blame]
drh47991422015-08-31 15:58:06 +00001# 2015-08-31
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 file is testing indexes on expressions.
13#
14
15set testdir [file dirname $argv0]
16source $testdir/tester.tcl
17
18do_execsql_test indexexpr1-100 {
19 CREATE TABLE t1(a,b,c);
20 INSERT INTO t1(a,b,c)
drh390b88a2015-08-31 18:13:01 +000021 /* 123456789 123456789 123456789 123456789 123456789 123456789 */
drh1d85e402015-08-31 17:34:41 +000022 VALUES('In_the_beginning_was_the_Word',1,1),
23 ('and_the_Word_was_with_God',1,2),
24 ('and_the_Word_was_God',1,3),
25 ('The_same_was_in_the_beginning_with_God',2,1),
26 ('All_things_were_made_by_him',3,1),
27 ('and_without_him_was_not_any_thing_made_that_was_made',3,2);
drh47991422015-08-31 15:58:06 +000028 CREATE INDEX t1a1 ON t1(substr(a,1,12));
29} {}
30do_execsql_test indexexpr1-110 {
drh1d85e402015-08-31 17:34:41 +000031 SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;
drh47991422015-08-31 15:58:06 +000032} {1 2 | 1 3 |}
33do_execsql_test indexexpr1-110eqp {
34 EXPLAIN QUERY PLAN
drh1d85e402015-08-31 17:34:41 +000035 SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;
drh47991422015-08-31 15:58:06 +000036} {/USING INDEX t1a1/}
37do_execsql_test indexexpr1-120 {
drh1d85e402015-08-31 17:34:41 +000038 SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;
drh47991422015-08-31 15:58:06 +000039} {1 2 | 1 3 |}
40do_execsql_test indexexpr1-120eqp {
41 EXPLAIN QUERY PLAN
drh1d85e402015-08-31 17:34:41 +000042 SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;
drh47991422015-08-31 15:58:06 +000043} {/USING INDEX t1a1/}
44
drh1d85e402015-08-31 17:34:41 +000045do_execsql_test indexexpr1-130 {
46 CREATE INDEX t1ba ON t1(b,substr(a,2,3),c);
47 SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c;
48} {2 3}
49do_execsql_test indexexpr1-130eqp {
50 EXPLAIN QUERY PLAN
51 SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c;
52} {/USING INDEX t1ba/}
53
54do_execsql_test indexexpr1-140 {
55 SELECT rowid, substr(a,b,3), '|' FROM t1 ORDER BY 2;
56} {1 In_ | 2 and | 3 and | 6 d_w | 4 he_ | 5 l_t |}
57do_execsql_test indexexpr1-141 {
58 CREATE INDEX t1abx ON t1(substr(a,b,3));
59 SELECT rowid FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +rowid;
60} {1 2 3}
61do_execsql_test indexexpr1-141eqp {
62 EXPLAIN QUERY PLAN
63 SELECT rowid FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +rowid;
64} {/USING INDEX t1abx/}
65do_execsql_test indexexpr1-142 {
66 SELECT rowid FROM t1 WHERE +substr(a,b,3)<='and' ORDER BY +rowid;
67} {1 2 3}
68do_execsql_test indexexpr1-150 {
69 SELECT rowid FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
70 ORDER BY +rowid;
71} {2 3 5}
72do_execsql_test indexexpr1-150eqp {
73 EXPLAIN QUERY PLAN
74 SELECT rowid FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
75 ORDER BY +rowid;
76} {/USING INDEX t1abx/}
77
dan37f3ac82021-10-01 20:39:50 +000078ifcapable altertable {
79 do_execsql_test indexexpr1-160 {
80 ALTER TABLE t1 ADD COLUMN d;
81 UPDATE t1 SET d=length(a);
82 CREATE INDEX t1a2 ON t1(SUBSTR(a, 27, 3)) WHERE d>=29;
83 SELECT rowid, b, c FROM t1
84 WHERE substr(a,27,3)=='ord' AND d>=29;
85 } {1 1 1}
86 do_execsql_test indexexpr1-160eqp {
87 EXPLAIN QUERY PLAN
88 SELECT rowid, b, c FROM t1
89 WHERE substr(a,27,3)=='ord' AND d>=29;
90 } {/USING INDEX t1a2/}
91}
drh390b88a2015-08-31 18:13:01 +000092
drhdae26fe2015-09-24 18:47:59 +000093# ORDER BY using an indexed expression
94#
95do_execsql_test indexexpr1-170 {
96 CREATE INDEX t1alen ON t1(length(a));
97 SELECT length(a) FROM t1 ORDER BY length(a);
98} {20 25 27 29 38 52}
99do_execsql_test indexexpr1-170eqp {
100 EXPLAIN QUERY PLAN
101 SELECT length(a) FROM t1 ORDER BY length(a);
drh82102332021-03-20 15:11:29 +0000102} {/SCAN t1 USING INDEX t1alen/}
drhdae26fe2015-09-24 18:47:59 +0000103do_execsql_test indexexpr1-171 {
104 SELECT length(a) FROM t1 ORDER BY length(a) DESC;
105} {52 38 29 27 25 20}
106do_execsql_test indexexpr1-171eqp {
107 EXPLAIN QUERY PLAN
108 SELECT length(a) FROM t1 ORDER BY length(a) DESC;
drh82102332021-03-20 15:11:29 +0000109} {/SCAN t1 USING INDEX t1alen/}
drh390b88a2015-08-31 18:13:01 +0000110
drh1d85e402015-08-31 17:34:41 +0000111do_execsql_test indexexpr1-200 {
112 DROP TABLE t1;
113 CREATE TABLE t1(id ANY PRIMARY KEY, a,b,c) WITHOUT ROWID;
114 INSERT INTO t1(id,a,b,c)
115 VALUES(1,'In_the_beginning_was_the_Word',1,1),
116 (2,'and_the_Word_was_with_God',1,2),
117 (3,'and_the_Word_was_God',1,3),
118 (4,'The_same_was_in_the_beginning_with_God',2,1),
119 (5,'All_things_were_made_by_him',3,1),
120 (6,'and_without_him_was_not_any_thing_made_that_was_made',3,2);
121 CREATE INDEX t1a1 ON t1(substr(a,1,12));
122} {}
123do_execsql_test indexexpr1-210 {
124 SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;
125} {1 2 | 1 3 |}
126do_execsql_test indexexpr1-210eqp {
127 EXPLAIN QUERY PLAN
128 SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;
129} {/USING INDEX t1a1/}
130do_execsql_test indexexpr1-220 {
131 SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;
132} {1 2 | 1 3 |}
133do_execsql_test indexexpr1-220eqp {
134 EXPLAIN QUERY PLAN
135 SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;
136} {/USING INDEX t1a1/}
137
138do_execsql_test indexexpr1-230 {
139 CREATE INDEX t1ba ON t1(b,substr(a,2,3),c);
140 SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c;
141} {2 3}
142do_execsql_test indexexpr1-230eqp {
143 EXPLAIN QUERY PLAN
144 SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c;
145} {/USING INDEX t1ba/}
146
147do_execsql_test indexexpr1-240 {
148 SELECT id, substr(a,b,3), '|' FROM t1 ORDER BY 2;
149} {1 In_ | 2 and | 3 and | 6 d_w | 4 he_ | 5 l_t |}
150do_execsql_test indexexpr1-241 {
151 CREATE INDEX t1abx ON t1(substr(a,b,3));
152 SELECT id FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +id;
153} {1 2 3}
154do_execsql_test indexexpr1-241eqp {
155 EXPLAIN QUERY PLAN
156 SELECT id FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +id;
157} {/USING INDEX t1abx/}
158do_execsql_test indexexpr1-242 {
159 SELECT id FROM t1 WHERE +substr(a,b,3)<='and' ORDER BY +id;
160} {1 2 3}
161do_execsql_test indexexpr1-250 {
162 SELECT id FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
163 ORDER BY +id;
164} {2 3 5}
165do_execsql_test indexexpr1-250eqp {
166 EXPLAIN QUERY PLAN
167 SELECT id FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
168 ORDER BY +id;
169} {/USING INDEX t1abx/}
170
dan37f3ac82021-10-01 20:39:50 +0000171ifcapable altertable {
172 do_execsql_test indexexpr1-260 {
173 ALTER TABLE t1 ADD COLUMN d;
174 UPDATE t1 SET d=length(a);
175 CREATE INDEX t1a2 ON t1(SUBSTR(a, 27, 3)) WHERE d>=29;
176 SELECT id, b, c FROM t1
177 WHERE substr(a,27,3)=='ord' AND d>=29;
178 } {1 1 1}
179 do_execsql_test indexexpr1-260eqp {
180 EXPLAIN QUERY PLAN
181 SELECT id, b, c FROM t1
182 WHERE substr(a,27,3)=='ord' AND d>=29;
183 } {/USING INDEX t1a2/}
184}
drh390b88a2015-08-31 18:13:01 +0000185
186
drh1d85e402015-08-31 17:34:41 +0000187do_catchsql_test indexexpr1-300 {
drh3e34eab2017-07-19 19:48:40 +0000188 CREATE TABLE t2(a,b,c); INSERT INTO t2 VALUES(1,2,3);
drh1d85e402015-08-31 17:34:41 +0000189 CREATE INDEX t2x1 ON t2(a,b+random());
190} {1 {non-deterministic functions prohibited in index expressions}}
191do_catchsql_test indexexpr1-301 {
drh3e34eab2017-07-19 19:48:40 +0000192 CREATE INDEX t2x1 ON t2(julianday('now',a));
drh20cee7d2019-10-30 18:50:08 +0000193} {1 {non-deterministic use of julianday() in an index}}
drh1d85e402015-08-31 17:34:41 +0000194do_catchsql_test indexexpr1-310 {
195 CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));
196} {1 {subqueries prohibited in index expressions}}
drh390b88a2015-08-31 18:13:01 +0000197do_catchsql_test indexexpr1-320 {
198 CREATE TABLE e1(x,y,UNIQUE(y,substr(x,1,5)));
199} {1 {expressions prohibited in PRIMARY KEY and UNIQUE constraints}}
200do_catchsql_test indexexpr1-330 {
201 CREATE TABLE e1(x,y,PRIMARY KEY(y,substr(x,1,5)));
202} {1 {expressions prohibited in PRIMARY KEY and UNIQUE constraints}}
203do_catchsql_test indexexpr1-331 {
204 CREATE TABLE e1(x,y,PRIMARY KEY(y,substr(x,1,5))) WITHOUT ROWID;
205} {1 {expressions prohibited in PRIMARY KEY and UNIQUE constraints}}
206do_catchsql_test indexexpr1-340 {
207 CREATE TABLE e1(x,y,FOREIGN KEY(substr(y,1,5)) REFERENCES t1);
208} {1 {near "(": syntax error}}
drh47991422015-08-31 15:58:06 +0000209
drh8b576422015-08-31 23:09:42 +0000210do_execsql_test indexexpr1-400 {
211 CREATE TABLE t3(a,b,c);
212 WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<30)
213 INSERT INTO t3(a,b,c)
214 SELECT x, printf('ab%04xyz',x), random() FROM c;
215 CREATE UNIQUE INDEX t3abc ON t3(CAST(a AS text), b, substr(c,1,3));
216 SELECT a FROM t3 WHERE CAST(a AS text)<='10' ORDER BY +a;
drh68391ac2015-09-25 20:49:16 +0000217 PRAGMA integrity_check;
218} {1 10 ok}
drh8b576422015-08-31 23:09:42 +0000219do_catchsql_test indexexpr1-410 {
220 INSERT INTO t3 SELECT * FROM t3 WHERE rowid=10;
221} {1 {UNIQUE constraint failed: index 't3abc'}}
222
drh0b8d2552015-09-05 22:36:07 +0000223do_execsql_test indexexpr1-500 {
224 CREATE TABLE t5(a);
225 CREATE TABLE cnt(x);
226 WITH RECURSIVE
227 c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
228 INSERT INTO cnt(x) SELECT x FROM c;
229 INSERT INTO t5(a) SELECT printf('abc%03dxyz',x) FROM cnt;
230 CREATE INDEX t5ax ON t5( substr(a,4,3) );
231} {}
232do_execsql_test indexexpr1-510 {
233 -- The use of the "k" alias in the WHERE clause is technically
234 -- illegal, but SQLite allows it for historical reasons. In this
235 -- test and the next, verify that "k" can be used by the t5ax index
236 SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x);
237} {001 002 003 004 005}
238do_execsql_test indexexpr1-510eqp {
239 EXPLAIN QUERY PLAN
240 SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x);
241} {/USING INDEX t5ax/}
242
drhe63e8a62015-09-18 18:09:28 +0000243# Skip-scan on an indexed expression
244#
245do_execsql_test indexexpr1-600 {
246 DROP TABLE IF EXISTS t4;
247 CREATE TABLE t4(a,b,c,d,e,f,g,h,i);
248 CREATE INDEX t4all ON t4(a,b,c<d,e,f,i,h);
249 INSERT INTO t4 VALUES(1,2,3,4,5,6,7,8,9);
250 ANALYZE;
251 DELETE FROM sqlite_stat1;
252 INSERT INTO sqlite_stat1
253 VALUES('t4','t4all','600000 160000 40000 10000 2000 600 100 40 10');
254 ANALYZE sqlite_master;
255 SELECT i FROM t4 WHERE e=5;
256} {9}
257
drhc5de2d02015-09-24 12:19:17 +0000258# Indexed expressions on both sides of an == in a WHERE clause.
259#
drh72694432015-09-24 11:26:45 +0000260do_execsql_test indexexpr1-700 {
261 DROP TABLE IF EXISTS t7;
262 CREATE TABLE t7(a,b,c);
263 INSERT INTO t7(a,b,c) VALUES(1,2,2),('abc','def','def'),(4,5,6);
264 CREATE INDEX t7b ON t7(+b);
265 CREATE INDEX t7c ON t7(+c);
266 SELECT *, '|' FROM t7 WHERE +b=+c ORDER BY +a;
267} {1 2 2 | abc def def |}
drhc5de2d02015-09-24 12:19:17 +0000268do_execsql_test indexexpr1-710 {
269 CREATE TABLE t71(a,b,c);
270 CREATE INDEX t71bc ON t71(b+c);
271 CREATE TABLE t72(x,y,z);
272 CREATE INDEX t72yz ON t72(y+z);
273 INSERT INTO t71(a,b,c) VALUES(1,11,2),(2,7,15),(3,5,4);
274 INSERT INTO t72(x,y,z) VALUES(1,10,3),(2,8,14),(3,9,9);
275 SELECT a, x, '|' FROM t71, t72
276 WHERE b+c=y+z
277 ORDER BY +a, +x;
278} {1 1 | 2 2 |}
drh0b8d2552015-09-05 22:36:07 +0000279
drhdae26fe2015-09-24 18:47:59 +0000280# Collating sequences on indexes of expressions
281#
282do_execsql_test indexexpr1-800 {
283 DROP TABLE IF EXISTS t8;
284 CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT);
285 CREATE UNIQUE INDEX t8bx ON t8(substr(b,2,4) COLLATE nocase);
286 INSERT INTO t8(a,b) VALUES(1,'Alice'),(2,'Bartholemew'),(3,'Cynthia');
287 SELECT * FROM t8 WHERE substr(b,2,4)='ARTH' COLLATE nocase;
288} {2 Bartholemew}
289do_catchsql_test indexexpr1-810 {
290 INSERT INTO t8(a,b) VALUES(4,'BARTHMERE');
291} {1 {UNIQUE constraint failed: index 't8bx'}}
292do_catchsql_test indexexpr1-820 {
293 DROP INDEX t8bx;
294 CREATE UNIQUE INDEX t8bx ON t8(substr(b,2,4) COLLATE rtrim);
295 INSERT INTO t8(a,b) VALUES(4,'BARTHMERE');
296} {0 {}}
297
drh68391ac2015-09-25 20:49:16 +0000298# Check that PRAGMA integrity_check works correctly on a
299# UNIQUE index that includes rowid and expression terms.
300#
301do_execsql_test indexexpr1-900 {
302 CREATE TABLE t9(a,b,c,d);
303 CREATE UNIQUE INDEX t9x1 ON t9(c,abs(d),b);
304 INSERT INTO t9(rowid,a,b,c,d) VALUES(1,2,3,4,5);
305 INSERT INTO t9(rowid,a,b,c,d) VALUES(2,NULL,NULL,NULL,NULL);
306 INSERT INTO t9(rowid,a,b,c,d) VALUES(3,NULL,NULL,NULL,NULL);
307 INSERT INTO t9(rowid,a,b,c,d) VALUES(4,5,6,7,8);
308 PRAGMA integrity_check;
309} {ok}
310do_catchsql_test indexexpr1-910 {
311 INSERT INTO t9(a,b,c,d) VALUES(5,6,7,-8);
312} {1 {UNIQUE constraint failed: index 't9x1'}}
drhdae26fe2015-09-24 18:47:59 +0000313
drh1c75c9d2015-12-21 15:22:13 +0000314# Test cases derived from a NEVER() maro failure discovered by
315# Jonathan Metzman using AFL
316#
317do_execsql_test indexexpr1-1000 {
318 DROP TABLE IF EXISTS t0;
319 CREATE TABLE t0(a,b,t);
320 CREATE INDEX i ON t0(a in(0,1));
321 INSERT INTO t0 VALUES(0,1,2),(2,3,4),(5,6,7);
322 UPDATE t0 SET b=99 WHERE (a in(0,1))=0;
323 SELECT *, '|' FROM t0 ORDER BY +a;
324} {0 1 2 | 2 99 4 | 5 99 7 |}
325do_execsql_test indexexpr1-1010 {
326 UPDATE t0 SET b=88 WHERE (a in(0,1))=1;
327 SELECT *, '|' FROM t0 ORDER BY +a;
328} {0 88 2 | 2 99 4 | 5 99 7 |}
329
drh48590fc2016-10-10 13:29:15 +0000330# 2016-10-10
331# Make sure indexes on expressions skip over initial NULL values in the
332# index as they are suppose to do.
333# Ticket https://www.sqlite.org/src/tktview/4baa46491212947
334#
335do_execsql_test indexexpr1-1100 {
336 DROP TABLE IF EXISTS t1;
337 CREATE TABLE t1(a);
338 INSERT INTO t1 VALUES(NULL),(1);
339 SELECT '1:', typeof(a), a FROM t1 WHERE a<10;
340 SELECT '2:', typeof(a), a FROM t1 WHERE a+0<10;
341 CREATE INDEX t1x1 ON t1(a);
342 CREATE INDEX t1x2 ON t1(a+0);
343 SELECT '3:', typeof(a), a FROM t1 WHERE a<10;
344 SELECT '4:', typeof(a), a FROM t1 WHERE a+0<10;
345} {1: integer 1 2: integer 1 3: integer 1 4: integer 1}
drhdae26fe2015-09-24 18:47:59 +0000346
dan90b2fe62016-10-10 14:34:00 +0000347do_execsql_test indexexpr1-1200 {
348 CREATE TABLE t10(a int, b int, c int, d int);
349 INSERT INTO t10(a, b, c, d) VALUES(0, 0, 2, 2);
350 INSERT INTO t10(a, b, c, d) VALUES(0, 0, 0, 0);
351 INSERT INTO t10(a, b, c, d) VALUES(0, 0, 1, 1);
352 INSERT INTO t10(a, b, c, d) VALUES(1, 1, 1, 1);
353 INSERT INTO t10(a, b, c, d) VALUES(1, 1, 0, 0);
354 INSERT INTO t10(a, b, c, d) VALUES(2, 2, 0, 0);
355
356 SELECT a+b, c+d FROM t10 ORDER BY a+b, c+d;
357} {
358 0 0 0 2 0 4 2 0 2 2 4 0
359}
360do_execsql_test indexexpr1-1200.1 {
361 CREATE INDEX t10_ab ON t10(a+b);
362}
363do_execsql_test indexexpr1-1200.2 {
364 SELECT a+b, c+d FROM t10 ORDER BY a+b, c+d;
365} {
366 0 0 0 2 0 4 2 0 2 2 4 0
367}
368do_execsql_test indexexpr1-1200.3 {
369 CREATE INDEX t10_abcd ON t10(a+b,c+d);
370}
371do_execsql_test indexexpr1-1200.4 {
372 SELECT a+b, c+d FROM t10 ORDER BY a+b, c+d;
373} {
374 0 0 0 2 0 4 2 0 2 2 4 0
375}
376
drh13ac46e2017-02-11 13:51:23 +0000377# Ticket https://www.sqlite.org/src/tktview/eb703ba7b50c1a
378# Incorrect result using an index on an expression with a collating function
379#
380do_execsql_test indexexpr1-1300.1 {
381 CREATE TABLE t1300(a INTEGER PRIMARY KEY, b);
382 INSERT INTO t1300 VALUES(1,'coffee'),(2,'COFFEE'),(3,'stress'),(4,'STRESS');
383 CREATE INDEX t1300bexpr ON t1300( substr(b,4) );
384 SELECT a FROM t1300 WHERE substr(b,4)='ess' COLLATE nocase ORDER BY +a;
385} {3 4}
386
drh4dd89d52017-08-14 14:53:24 +0000387# Ticket https://sqlite.org/src/tktview/aa98619a
388# Assertion fault using an index on a constant
389#
390do_execsql_test indexexpr1-1400 {
391 CREATE TABLE t1400(x TEXT);
392 CREATE INDEX t1400x ON t1400(1); -- Index on a constant
393 SELECT 1 IN (SELECT 2) FROM t1400;
394} {}
395do_execsql_test indexexpr1-1410 {
396 INSERT INTO t1400 VALUES('a'),('b');
397 SELECT 1 IN (SELECT 2) FROM t1400;
398} {0 0}
399do_execsql_test indexexpr1-1420 {
400 SELECT 1 IN (SELECT 2 UNION ALL SELECT 1) FROM t1400;
401} {1 1}
402do_execsql_test indexexpr1-1430 {
403 DROP INDEX t1400x;
404 CREATE INDEX t1400x ON t1400(abs(15+3));
405 SELECT abs(15+3) IN (SELECT 17 UNION ALL SELECT 18) FROM t1;
406} {1 1}
407
drh4d795ef2018-01-02 18:11:11 +0000408# 2018-01-02 ticket https://sqlite.org/src/info/dc3f932f5a147771
409# A REPLACE into a table that uses an index on an expression causes
410# an assertion fault. Problem discovered by OSSFuzz.
411#
412do_execsql_test indexexpr1-1500 {
413 CREATE TABLE t1500(a INT PRIMARY KEY, b INT UNIQUE);
414 CREATE INDEX t1500ab ON t1500(a*b);
415 INSERT INTO t1500(a,b) VALUES(1,2);
416 REPLACE INTO t1500(a,b) VALUES(1,3); -- formerly caused assertion fault
417 SELECT * FROM t1500;
418} {1 3}
drh4dd89d52017-08-14 14:53:24 +0000419
drh9eb8dba2018-01-03 01:47:30 +0000420# 2018-01-03 OSSFuzz discovers another test case for the same problem
421# above.
422#
423do_execsql_test indexexpr-1510 {
424 DROP TABLE IF EXISTS t1;
425 CREATE TABLE t1(a PRIMARY KEY,b UNIQUE);
426 REPLACE INTO t1 VALUES(2, 1);
427 REPLACE INTO t1 SELECT 6,1;
428 CREATE INDEX t1aa ON t1(a-a);
429 REPLACE INTO t1 SELECT a, randomblob(a) FROM t1
430} {}
431
drh06b3bd52018-02-01 01:13:33 +0000432# 2018-01-31 https://www.sqlite.org/src/tktview/343634942dd54ab57b702411
433# When an index on an expression depends on the string representation of
434# a numeric table column, trouble can arise since there are multiple
435# string that can map to the same numeric value. (Ex: 123, 0123, 000123).
436#
437do_execsql_test indexexpr-1600 {
438 DROP TABLE IF EXISTS t1;
439 CREATE TABLE t1 (a INTEGER, b);
440 CREATE INDEX idx1 ON t1 (lower(a));
441 INSERT INTO t1 VALUES('0001234',3);
442 PRAGMA integrity_check;
443} {ok}
444do_execsql_test indexexpr-1610 {
445 INSERT INTO t1 VALUES('1234',0),('001234',2),('01234',1);
446 SELECT b FROM t1 WHERE lower(a)='1234' ORDER BY +b;
447} {0 1 2 3}
448do_execsql_test indexexpr-1620 {
449 SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b;
450} {}
451
drh14c865e2019-08-10 15:06:03 +0000452# 2019-08-09 https://www.sqlite.org/src/info/9080b6227fabb466
453# ExprImpliesExpr theorem prover bug:
454# "(NULL IS FALSE) IS FALSE" does not imply "NULL IS NULL"
455#
456do_execsql_test indexexpr-1700 {
457 DROP TABLE IF EXISTS t0;
458 CREATE TABLE t0(c0);
459 INSERT INTO t0(c0) VALUES (0);
460 CREATE INDEX i0 ON t0(NULL > c0) WHERE (NULL NOT NULL);
461 SELECT * FROM t0 WHERE ((NULL IS FALSE) IS FALSE);
462} {0}
drh06b3bd52018-02-01 01:13:33 +0000463
drhbffdd632019-09-02 00:58:44 +0000464# 2019-09-02 https://www.sqlite.org/src/tktview/57af00b6642ecd6848
465# When the expression of an an index-on-expression references a
466# table column of type REAL that is actually holding an MEM_IntReal
467# value, be sure to use the REAL value and not the INT value when
468# computing the expression.
469#
dan9d30c8f2019-09-26 19:53:26 +0000470ifcapable like_match_blobs {
471 do_execsql_test indexexpr-1800 {
472 DROP TABLE IF EXISTS t0;
473 CREATE TABLE t0(c0 REAL, c1 TEXT);
474 CREATE INDEX i0 ON t0(+c0, c0);
475 INSERT INTO t0(c0) VALUES(0);
476 SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0;
477 } {0}
478 do_execsql_test indexexpr-1810 {
479 SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0;
480 } {1}
481 do_execsql_test indexexpr-1820 {
482 DROP TABLE IF EXISTS t1;
483 CREATE TABLE t1(x REAL);
484 CREATE INDEX t1x ON t1(x, +x);
485 INSERT INTO t1(x) VALUES(2);
486 SELECT +x FROM t1 WHERE x=2;
487 } {2.0}
488}
drhbffdd632019-09-02 00:58:44 +0000489
drh2aa10862022-04-30 12:35:51 +0000490# 2022-04-30 https://sqlite.org/forum/info/7efabf4b03328e57
491# Assertion fault during a DELETE INDEXED BY.
492#
493reset_db
494do_execsql_test indexexpr-1900 {
495 CREATE TABLE t1(x TEXT PRIMARY KEY, y TEXT, z INT);
496 INSERT INTO t1(x,y,z) VALUES('alpha','ALPHA',1),('bravo','charlie',1);
497 CREATE INDEX i1 ON t1(+y COLLATE NOCASE);
498 SELECT * FROM t1;
499} {alpha ALPHA 1 bravo charlie 1}
500do_execsql_test indexexpr-1910 {
501 DELETE FROM t1 INDEXED BY i1
502 WHERE x IS +y COLLATE NOCASE IN (SELECT z FROM t1)
503 RETURNING *;
504} {alpha ALPHA 1}
505do_execsql_test indexexpr-1920 {
506 SELECT * FROM t1;
507} {bravo charlie 1}
508
drh47991422015-08-31 15:58:06 +0000509finish_test