CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
indexexpr1.test686 linesDownload Raw Back to test
1# 2015-08-312#3# The author disclaims copyright to this source code.  In place of4# 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.  The12# focus of this file is testing indexes on expressions.13#14 15set testdir [file dirname $argv0]16source $testdir/tester.tcl17 18do_execsql_test indexexpr1-100 {19  CREATE TABLE t1(a,b,c);20  INSERT INTO t1(a,b,c)21      /*  123456789 123456789 123456789 123456789 123456789 123456789 */ 22  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);28  CREATE INDEX t1a1 ON t1(substr(a,1,12));29} {}30do_execsql_test indexexpr1-110 {31  SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;32} {1 2 | 1 3 |}33do_execsql_test indexexpr1-110eqp {34  EXPLAIN QUERY PLAN35  SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;36} {/USING INDEX t1a1/}37do_execsql_test indexexpr1-120 {38  SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;39} {1 2 | 1 3 |}40do_execsql_test indexexpr1-120eqp {41  EXPLAIN QUERY PLAN42  SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;43} {/USING INDEX t1a1/}44 45do_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 PLAN51  SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c;52} {/USING COVERING 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 PLAN63  SELECT rowid FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +rowid;64} {/USING COVERING 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 PLAN74  SELECT rowid FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')75   ORDER BY +rowid;76} {/USING COVERING INDEX t1abx/}77 78ifcapable 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 t184      WHERE substr(a,27,3)=='ord' AND d>=29;85  } {1 1 1}86  do_execsql_test indexexpr1-160eqp {87    EXPLAIN QUERY PLAN88      SELECT rowid, b, c FROM t189      WHERE substr(a,27,3)=='ord' AND d>=29;90  } {/USING INDEX t1a2/}91}92 93# ORDER BY using an indexed expression94#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 PLAN101  SELECT length(a) FROM t1 ORDER BY length(a);102} {/SCAN t1 USING COVERING INDEX t1alen/}103do_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 PLAN108  SELECT length(a) FROM t1 ORDER BY length(a) DESC;109} {/SCAN t1 USING COVERING INDEX t1alen/}110 111do_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 PLAN128  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 PLAN135  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 PLAN144  SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c;145} {/USING COVERING 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 PLAN156  SELECT id FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +id;157} {/USING COVERING 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 PLAN167  SELECT id FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')168   ORDER BY +id;169} {/USING COVERING INDEX t1abx/}170 171ifcapable 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 t1177      WHERE substr(a,27,3)=='ord' AND d>=29;178  } {1 1 1}179  do_execsql_test indexexpr1-260eqp {180    EXPLAIN QUERY PLAN181      SELECT id, b, c FROM t1182      WHERE substr(a,27,3)=='ord' AND d>=29;183  } {/USING INDEX t1a2/}184}185 186 187do_catchsql_test indexexpr1-300 {188  CREATE TABLE t2(a,b,c); INSERT INTO t2 VALUES(1,2,3);189  CREATE INDEX t2x1 ON t2(a,b+random());190} {1 {non-deterministic functions prohibited in index expressions}}191do_catchsql_test indexexpr1-301 {192  CREATE INDEX t2x1 ON t2(julianday('now',a));193} {1 {non-deterministic use of julianday() in an index}}194do_catchsql_test indexexpr1-310 {195  CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));196} {1 {subqueries prohibited in index expressions}}197do_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}}209 210do_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;217  PRAGMA integrity_check;218} {1 10 ok}219do_catchsql_test indexexpr1-410 {220  INSERT INTO t3 SELECT * FROM t3 WHERE rowid=10;221} {1 {UNIQUE constraint failed: index 't3abc'}}222 223do_execsql_test indexexpr1-500 {224  CREATE TABLE t5(a);225  CREATE TABLE cnt(x);226  WITH RECURSIVE227    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 technically234  -- illegal, but SQLite allows it for historical reasons.  In this235  -- test and the next, verify that "k" can be used by the t5ax index236  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 PLAN240  SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x);241} {/USING COVERING INDEX t5ax/}242 243# Skip-scan on an indexed expression244#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_stat1253    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 258# Indexed expressions on both sides of an == in a WHERE clause.259#260do_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 |}268do_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, t72276   WHERE b+c=y+z277  ORDER BY +a, +x;278} {1 1 | 2 2 |}279 280# Collating sequences on indexes of expressions281#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 298# Check that PRAGMA integrity_check works correctly on a299# 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'}}313 314# Test cases derived from a NEVER() maro failure discovered by315# Jonathan Metzman using AFL316#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 330# 2016-10-10331# Make sure indexes on expressions skip over initial NULL values in the332# index as they are suppose to do.333# Ticket https://sqlite.org/src/tktview/4baa46491212947334#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}346 347do_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 0359}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 0367}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 0375}376 377# Ticket https://sqlite.org/src/tktview/eb703ba7b50c1a378# Incorrect result using an index on an expression with a collating function379#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 387# Ticket https://sqlite.org/src/tktview/aa98619a388# Assertion fault using an index on a constant389#390do_execsql_test indexexpr1-1400 {391  CREATE TABLE t1400(x TEXT);392  CREATE INDEX t1400x ON t1400(1);  -- Index on a constant393  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 408# 2018-01-02 ticket https://sqlite.org/src/info/dc3f932f5a147771409# A REPLACE into a table that uses an index on an expression causes410# 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 fault417  SELECT * FROM t1500;418} {1 3}419 420# 2018-01-03 OSSFuzz discovers another test case for the same problem421# above.422#423do_execsql_test indexexpr1-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 t1430} {}431 432# 2018-01-31 https://sqlite.org/src/tktview/343634942dd54ab57b702411433# When an index on an expression depends on the string representation of434# a numeric table column, trouble can arise since there are multiple435# string that can map to the same numeric value.  (Ex: 123, 0123, 000123).436#437do_execsql_test indexexpr1-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 indexexpr1-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 indexexpr1-1620 {449  SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b;450} {}451 452# 2019-08-09 https://sqlite.org/src/info/9080b6227fabb466453# ExprImpliesExpr theorem prover bug:454# "(NULL IS FALSE) IS FALSE" does not imply "NULL IS NULL"455#456do_execsql_test indexexpr1-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}463 464# 2019-09-02 https://sqlite.org/src/tktview/57af00b6642ecd6848465# When the expression of an an index-on-expression references a466# table column of type REAL that is actually holding an MEM_IntReal467# value, be sure to use the REAL value and not the INT value when468# computing the expression.469#470ifcapable like_match_blobs {471  do_execsql_test indexexpr1-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 indexexpr1-1810 {479    SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0; 480  } {1}481  do_execsql_test indexexpr1-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}489 490# 2022-04-30 https://sqlite.org/forum/info/7efabf4b03328e57491# Assertion fault during a DELETE INDEXED BY.492#493reset_db494do_execsql_test indexexpr1-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 indexexpr1-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 indexexpr1-1920 {506  SELECT * FROM t1;507} {bravo charlie 1}508 509# 2022-11-28 Ticket 695a1a53de510# Improved ability to recognize that an index on an expression is a511# covering index.512#513reset_db514do_execsql_test indexexpr1-2000 {515  CREATE TABLE t1(a INT, b TEXT);516  INSERT INTO t1(a,b) VALUES517    (10, '{"one":5,"two":6}'),518    (10, '{"one":50,"two":60}'),519    (10, '{"three":99}'),520    (11, '{"one":100,"two":200}');521  CREATE INDEX t1_one ON t1(a, b->>'one');522  CREATE INDEX t1_two ON t1(a, b->>'two');523}524do_execsql_test indexexpr1-2010 {525  EXPLAIN QUERY PLAN526  SELECT sum(b->>'one') FROM t1 WHERE a=10; /* Query AA */527} {/.* t1_one .*/}528do_execsql_test indexexpr1-2011 {529  SELECT sum(b->>'one') FROM t1 WHERE a=10; /* Query AA */530} {55}531do_execsql_test indexexpr1-2020 {532  EXPLAIN QUERY PLAN533  SELECT sum(b->>'two') FROM t1 WHERE a=10; /* Query BB */534} {/.* t1_two .*/}535do_execsql_test indexexpr1-2021 {536  SELECT sum(b->>'two') FROM t1 WHERE a=10; /* Query BB */537} {66}538do_execsql_test indexexpr1-2030 {539  DROP TABLE t1;540  CREATE TABLE t1(a INT, b TEXT, c INT, d INT);541  INSERT INTO t1(a,b,c,d) VALUES542    (1, '{"x":1}', 12,  3),543    (1, '{"x":2}',  4,  5),544    (1, '{"x":1}',  6, 11),545    (2, '{"x":1}', 22,  3),546    (2, '{"x":2}',  4,  5),547    (3, '{"x":1}',  6,  7);548  CREATE INDEX t1x ON t1(d, a, b->>'x', c);549}550do_execsql_test indexexpr1-2040 {551  SELECT a,552       SUM(1)                              AS t1,553       SUM(CASE WHEN b->>'x'=1 THEN 1 END) AS t2,554       SUM(c)                              AS t3,555       SUM(CASE WHEN b->>'x'=1 THEN c END) AS t4556    FROM t1;557} {1 6 4 54 46}558do_execsql_test indexexpr1-2050 {559  explain query plan560  SELECT a,561       SUM(1)                              AS t1,562       SUM(CASE WHEN b->>'x'=1 THEN 1 END) AS t2,563       SUM(c)                              AS t3,564       SUM(CASE WHEN b->>'x'=1 THEN c END) AS t4565    FROM t1;566} {/.*SCAN t1 USING COVERING INDEX t1x.*/}567 568reset_db569do_execsql_test indexexpr1-2100 {570  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);571  INSERT INTO t1(a,b) VALUES(1,0);572  CREATE INDEX x1 ON t1( "y" );573  CREATE INDEX x2 ON t1( +"y" );574  CREATE INDEX x3 ON t1( +'y' );575  CREATE INDEX x4 ON t1( "y*" );576}577do_execsql_test indexexpr1-2110 {578  UPDATE t1 SET b=100 WHERE (SELECT 'y') GLOB "y";579  SELECT b FROM t1;580} 100581do_execsql_test indexexpr1-2120 {582  UPDATE t1 SET b=200 WHERE (SELECT 'y') GLOB +"y";583  SELECT b FROM t1;584} 200585do_execsql_test indexexpr1-2130 {586  UPDATE t1 SET b=300 WHERE (SELECT 'y') GLOB +'y';587  SELECT b FROM t1;588} 300589do_execsql_test indexexpr1-2140 {590  UPDATE t1 SET b=400 WHERE (SELECT 'y') GLOB "y*";591  SELECT b FROM t1;592} 400593 594# 2023-04-18 Forum post https://sqlite.org/forum/forumpost/f34e32d120 from595# Alexis King.596#597# This problem originates at check-in b9190d3da70c4171 (2022-11-25).598# A similar problem arose on 2023-03-04 at599# https://sqlite.org/forum/forumpost/a68313d054 and was fixed at600# check-in e06973876993926f.  See the test case tkt-99378-400.601# 602reset_db603do_execsql_test indexexpr1-2200 {604  CREATE TABLE t1(id INTEGER PRIMARY KEY, tag INT);605  INSERT INTO t1 VALUES (0, 7), (1, 8);606  CREATE TABLE t2(type INT, t1_id  INT, value  INT);607  INSERT INTO t2 VALUES (0, 0, 100), (0, 1, 101);608  CREATE INDEX t1x ON t1(-tag);609  SELECT u.tag, v.max_value610    FROM (SELECT tag FROM t1 GROUP BY -tag) u611    JOIN (SELECT t1.tag AS "tag", t2.type AS "type",612                 MAX(t2.value) AS "max_value"613            FROM t1614                 JOIN t2 ON t2.t1_id = t1.id615           GROUP BY t2.type, t1.tag616         ) v ON v.type = 0 AND v.tag = u.tag;617} {7 100 8 101}618do_execsql_test indexexpr1-2210 {619  DROP TABLE t1;620  CREATE TABLE t1(x INT, y TEXT);621  INSERT INTO t1(x,y) VALUES(1,'{b:5}');622  SELECT json_insert('{}', '$.a', coalesce(null,json(y)))->>'$.a.b' FROM t1;623} {5}624db null NULL625do_execsql_test indexexpr1-2211 {626  CREATE INDEX t1j ON t1(coalesce(null,json(y)));627  SELECT json_insert('{}', '$.a', coalesce(null,json(y)))->>'$.a.b' FROM t1;628} {5}629do_execsql_test indexexpr1-2220 {630  DROP INDEX t1j;631  SELECT json_insert('{}', '$.a', iif(1,json(y),123))->>'$.a.b' FROM t1;632} {5}633do_execsql_test indexexpr1-2221 {634  CREATE INDEX t1j ON t1(iif(1,json(y),123));635  SELECT json_insert('{}', '$.a', iif(1,json(y),123))->>'$.a.b' FROM t1;636} {5}637do_execsql_test indexexpr1-2230 {638  DROP INDEX t1j;639  SELECT json_insert('{}', '$.a', ifnull(NULL,json(y)))->>'$.a.b' FROM t1;640} {5}641do_execsql_test indexexpr1-2231 {642  CREATE INDEX t1j ON t1(ifnull(NULL,json(y)));643  SELECT json_insert('{}', '$.a', ifnull(NULL,json(y)))->>'$.a.b' FROM t1;644} {5}645do_execsql_test indexexpr1-2240 {646  DROP INDEX t1j;647  SELECT json_insert('{}', '$.a', nullif(json(y),8))->>'$.a.b' FROM t1;648} {5}649do_execsql_test indexexpr1-2241 {650  CREATE INDEX t1j ON t1(nullif(json(y),8));651  SELECT json_insert('{}', '$.a', nullif(json(y),8))->>'$.a.b' FROM t1;652} {5}653do_execsql_test indexexpr1-2250 {654  DROP INDEX t1j;655  SELECT json_insert('{}', '$.a', min('~',json(y)))->>'$.a.b' FROM t1;656} {5}657do_execsql_test indexexpr1-2251 {658  CREATE INDEX t1j ON t1(min('~',json(y)));659  SELECT json_insert('{}', '$.a', min('~',json(y)))->>'$.a.b' FROM t1;660} {5}661do_execsql_test indexexpr1-2260 {662  DROP INDEX t1j;663  SELECT json_insert('{}', '$.a', max('...',json(y)))->>'$.a.b' FROM t1;664} {5}665do_execsql_test indexexpr1-2261 {666  CREATE INDEX t1j ON t1(max('...',json(y)));667  SELECT json_insert('{}', '$.a', max('...',json(y)))->>'$.a.b' FROM t1;668} {5}669 670 671# 2023-11-08 Forum post https://sqlite.org/forum/forumpost/68d284c86b082c3e672#673# Functions that return subtypes and that are indexed cannot be used to674# cover function calls from the main table, since the indexed value does675# not know the subtype.676#677reset_db678do_execsql_test indexexpr1-2300 {679  CREATE TABLE t1(x INT, y TEXT);680  INSERT INTO t1(x,y) VALUES(1,'{b:5}');681  CREATE INDEX t1j ON t1(json(y));682  SELECT json_insert('{}', '$.a', json(y)) FROM t1;683} {{{"a":{"b":5}}}}684 685finish_test686