gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/indexexpr1.test (about)

     1  # 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  
    15  set testdir [file dirname $argv0]
    16  source $testdir/tester.tcl
    17  
    18  do_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  } {}
    30  do_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 |}
    33  do_execsql_test indexexpr1-110eqp {
    34    EXPLAIN QUERY PLAN
    35    SELECT b, c, '|' FROM t1 WHERE substr(a,1,12)=='and_the_Word' ORDER BY b, c;
    36  } {/USING INDEX t1a1/}
    37  do_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 |}
    40  do_execsql_test indexexpr1-120eqp {
    41    EXPLAIN QUERY PLAN
    42    SELECT b, c, '|' FROM t1 WHERE 'and_the_Word'==substr(a,1,12) ORDER BY b, c;
    43  } {/USING INDEX t1a1/}
    44  
    45  do_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}
    49  do_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  
    54  do_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 |}
    57  do_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}
    61  do_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/}
    65  do_execsql_test indexexpr1-142 {
    66    SELECT rowid FROM t1 WHERE +substr(a,b,3)<='and' ORDER BY +rowid;
    67  } {1 2 3}
    68  do_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}
    72  do_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  
    78  ifcapable 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  }
    92  
    93  # ORDER BY using an indexed expression
    94  #
    95  do_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}
    99  do_execsql_test indexexpr1-170eqp {
   100    EXPLAIN QUERY PLAN
   101    SELECT length(a) FROM t1 ORDER BY length(a);
   102  } {/SCAN t1 USING INDEX t1alen/}
   103  do_execsql_test indexexpr1-171 {
   104    SELECT length(a) FROM t1 ORDER BY length(a) DESC;
   105  } {52 38 29 27 25 20}
   106  do_execsql_test indexexpr1-171eqp {
   107    EXPLAIN QUERY PLAN
   108    SELECT length(a) FROM t1 ORDER BY length(a) DESC;
   109  } {/SCAN t1 USING INDEX t1alen/}
   110  
   111  do_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  } {}
   123  do_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 |}
   126  do_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/}
   130  do_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 |}
   133  do_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  
   138  do_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}
   142  do_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  
   147  do_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 |}
   150  do_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}
   154  do_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/}
   158  do_execsql_test indexexpr1-242 {
   159    SELECT id FROM t1 WHERE +substr(a,b,3)<='and' ORDER BY +id;
   160  } {1 2 3}
   161  do_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}
   165  do_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  
   171  ifcapable 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  }
   185  
   186  
   187  do_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}}
   191  do_catchsql_test indexexpr1-301 {
   192    CREATE INDEX t2x1 ON t2(julianday('now',a));
   193  } {1 {non-deterministic use of julianday() in an index}}
   194  do_catchsql_test indexexpr1-310 {
   195    CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));
   196  } {1 {subqueries prohibited in index expressions}}
   197  do_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}}
   200  do_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}}
   203  do_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}}
   206  do_catchsql_test indexexpr1-340 {
   207    CREATE TABLE e1(x,y,FOREIGN KEY(substr(y,1,5)) REFERENCES t1);
   208  } {1 {near "(": syntax error}}
   209  
   210  do_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}
   219  do_catchsql_test indexexpr1-410 {
   220    INSERT INTO t3 SELECT * FROM t3 WHERE rowid=10;
   221  } {1 {UNIQUE constraint failed: index 't3abc'}}
   222  
   223  do_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  } {}
   232  do_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}
   238  do_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  
   243  # Skip-scan on an indexed expression
   244  #
   245  do_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  
   258  # Indexed expressions on both sides of an == in a WHERE clause.
   259  #
   260  do_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 |}
   268  do_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 |}
   279  
   280  # Collating sequences on indexes of expressions
   281  #
   282  do_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}
   289  do_catchsql_test indexexpr1-810 {
   290    INSERT INTO t8(a,b) VALUES(4,'BARTHMERE');
   291  } {1 {UNIQUE constraint failed: index 't8bx'}}
   292  do_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 a
   299  # UNIQUE index that includes rowid and expression terms.
   300  #
   301  do_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}
   310  do_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 by
   315  # Jonathan Metzman using AFL
   316  #
   317  do_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 |}
   325  do_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-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  #
   335  do_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  
   347  do_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  }
   360  do_execsql_test indexexpr1-1200.1 {
   361    CREATE INDEX t10_ab ON t10(a+b);
   362  }
   363  do_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  }
   368  do_execsql_test indexexpr1-1200.3 {
   369    CREATE INDEX t10_abcd ON t10(a+b,c+d);
   370  }
   371  do_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  
   377  # Ticket https://www.sqlite.org/src/tktview/eb703ba7b50c1a
   378  # Incorrect result using an index on an expression with a collating function
   379  #
   380  do_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/aa98619a
   388  # Assertion fault using an index on a constant
   389  #
   390  do_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  } {}
   395  do_execsql_test indexexpr1-1410 {
   396    INSERT INTO t1400 VALUES('a'),('b');
   397    SELECT 1 IN (SELECT 2) FROM t1400;
   398  } {0 0}
   399  do_execsql_test indexexpr1-1420 {
   400    SELECT 1 IN (SELECT 2 UNION ALL SELECT 1) FROM t1400;
   401  } {1 1}
   402  do_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/dc3f932f5a147771
   409  # A REPLACE into a table that uses an index on an expression causes
   410  # an assertion fault.  Problem discovered by OSSFuzz.
   411  #
   412  do_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}
   419  
   420  # 2018-01-03 OSSFuzz discovers another test case for the same problem
   421  # above.
   422  #
   423  do_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  
   432  # 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  #
   437  do_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}
   444  do_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}
   448  do_execsql_test indexexpr-1620 {
   449    SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b;
   450  } {}
   451  
   452  # 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  #
   456  do_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}
   463  
   464  # 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  #
   470  ifcapable 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  }
   489  
   490  # 2022-04-30 https://sqlite.org/forum/info/7efabf4b03328e57
   491  # Assertion fault during a DELETE INDEXED BY.
   492  #
   493  reset_db
   494  do_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}
   500  do_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}
   505  do_execsql_test indexexpr-1920 {
   506    SELECT * FROM t1;
   507  } {bravo charlie 1}
   508  
   509  finish_test