11fe0537eSdrh# 2013-07-31 21fe0537eSdrh# 31fe0537eSdrh# The author disclaims copyright to this source code. In place of 41fe0537eSdrh# a legal notice, here is a blessing: 51fe0537eSdrh# 61fe0537eSdrh# May you do good and not evil. 71fe0537eSdrh# May you find forgiveness for yourself and forgive others. 81fe0537eSdrh# May you share freely, never taking more than you give. 91fe0537eSdrh# 101fe0537eSdrh#*********************************************************************** 111fe0537eSdrh# 121fe0537eSdrh# Test cases for partial indices 131fe0537eSdrh# 141fe0537eSdrh 151fe0537eSdrh 161fe0537eSdrhset testdir [file dirname $argv0] 171fe0537eSdrhsource $testdir/tester.tcl 181fe0537eSdrh 191fe0537eSdrhload_static_extension db wholenumber; 201fe0537eSdrhdo_test index6-1.1 { 21*66518ca7Sdrh # Able to parse and manage partial indices 221fe0537eSdrh execsql { 23721dfcf5Sdrh CREATE TABLE t1(a,b,c); 241fe0537eSdrh CREATE INDEX t1a ON t1(a) WHERE a IS NOT NULL; 251fe0537eSdrh CREATE INDEX t1b ON t1(b) WHERE b>10; 261fe0537eSdrh CREATE VIRTUAL TABLE nums USING wholenumber; 27721dfcf5Sdrh INSERT INTO t1(a,b,c) 28721dfcf5Sdrh SELECT CASE WHEN value%3!=0 THEN value END, value, value 291fe0537eSdrh FROM nums WHERE value<=20; 301fe0537eSdrh SELECT count(a), count(b) FROM t1; 31*66518ca7Sdrh PRAGMA integrity_check; 321fe0537eSdrh } 33*66518ca7Sdrh} {14 20 ok} 341fe0537eSdrh 35*66518ca7Sdrh# Error conditions during parsing... 36*66518ca7Sdrh# 373780be11Sdrhdo_test index6-1.2 { 383780be11Sdrh catchsql { 39721dfcf5Sdrh CREATE INDEX bad1 ON t1(a,b) WHERE x IS NOT NULL; 403780be11Sdrh } 41721dfcf5Sdrh} {1 {no such column: x}} 423780be11Sdrhdo_test index6-1.3 { 433780be11Sdrh catchsql { 443780be11Sdrh CREATE INDEX bad1 ON t1(a,b) WHERE EXISTS(SELECT * FROM t1); 453780be11Sdrh } 463780be11Sdrh} {1 {subqueries prohibited in partial index WHERE clauses}} 473780be11Sdrhdo_test index6-1.4 { 483780be11Sdrh catchsql { 493780be11Sdrh CREATE INDEX bad1 ON t1(a,b) WHERE a!=?1; 503780be11Sdrh } 513780be11Sdrh} {1 {parameters prohibited in partial index WHERE clauses}} 523780be11Sdrhdo_test index6-1.5 { 533780be11Sdrh catchsql { 543780be11Sdrh CREATE INDEX bad1 ON t1(a,b) WHERE a!=random(); 553780be11Sdrh } 563780be11Sdrh} {1 {functions prohibited in partial index WHERE clauses}} 573780be11Sdrhdo_test index6-1.6 { 583780be11Sdrh catchsql { 593780be11Sdrh CREATE INDEX bad1 ON t1(a,b) WHERE a NOT LIKE 'abc%'; 603780be11Sdrh } 613780be11Sdrh} {1 {functions prohibited in partial index WHERE clauses}} 623780be11Sdrh 638a9789b6Sdrhdo_test index6-1.10 { 648a9789b6Sdrh execsql { 658a9789b6Sdrh ANALYZE; 668a9789b6Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 678a9789b6Sdrh PRAGMA integrity_check; 688a9789b6Sdrh } 69721dfcf5Sdrh} {{} 20 t1a {14 1} t1b {10 1} ok} 708a9789b6Sdrh 71*66518ca7Sdrh# STAT1 shows the partial indices have a reduced number of 72*66518ca7Sdrh# rows. 73*66518ca7Sdrh# 748a9789b6Sdrhdo_test index6-1.11 { 758a9789b6Sdrh execsql { 768a9789b6Sdrh UPDATE t1 SET a=b; 778a9789b6Sdrh ANALYZE; 788a9789b6Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 798a9789b6Sdrh PRAGMA integrity_check; 808a9789b6Sdrh } 81721dfcf5Sdrh} {{} 20 t1a {20 1} t1b {10 1} ok} 828a9789b6Sdrh 838a9789b6Sdrhdo_test index6-1.11 { 848a9789b6Sdrh execsql { 858a9789b6Sdrh UPDATE t1 SET a=NULL WHERE b%3!=0; 868a9789b6Sdrh UPDATE t1 SET b=b+100; 878a9789b6Sdrh ANALYZE; 888a9789b6Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 898a9789b6Sdrh PRAGMA integrity_check; 908a9789b6Sdrh } 91721dfcf5Sdrh} {{} 20 t1a {6 1} t1b {20 1} ok} 928a9789b6Sdrh 938a9789b6Sdrhdo_test index6-1.12 { 948a9789b6Sdrh execsql { 958a9789b6Sdrh UPDATE t1 SET a=CASE WHEN b%3!=0 THEN b END; 968a9789b6Sdrh UPDATE t1 SET b=b-100; 978a9789b6Sdrh ANALYZE; 988a9789b6Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 998a9789b6Sdrh PRAGMA integrity_check; 1008a9789b6Sdrh } 101721dfcf5Sdrh} {{} 20 t1a {13 1} t1b {10 1} ok} 1028a9789b6Sdrh 1038a9789b6Sdrhdo_test index6-1.13 { 1048a9789b6Sdrh execsql { 1058a9789b6Sdrh DELETE FROM t1 WHERE b BETWEEN 8 AND 12; 1068a9789b6Sdrh ANALYZE; 1078a9789b6Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 1088a9789b6Sdrh PRAGMA integrity_check; 1098a9789b6Sdrh } 110721dfcf5Sdrh} {{} 15 t1a {10 1} t1b {8 1} ok} 1118a9789b6Sdrh 1128a9789b6Sdrhdo_test index6-1.14 { 1138a9789b6Sdrh execsql { 1148a9789b6Sdrh REINDEX; 1158a9789b6Sdrh ANALYZE; 1168a9789b6Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 1178a9789b6Sdrh PRAGMA integrity_check; 1188a9789b6Sdrh } 119721dfcf5Sdrh} {{} 15 t1a {10 1} t1b {8 1} ok} 120721dfcf5Sdrh 121721dfcf5Sdrhdo_test index6-1.15 { 122721dfcf5Sdrh execsql { 123721dfcf5Sdrh CREATE INDEX t1c ON t1(c); 124721dfcf5Sdrh ANALYZE; 125721dfcf5Sdrh SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; 126721dfcf5Sdrh PRAGMA integrity_check; 127721dfcf5Sdrh } 128721dfcf5Sdrh} {t1a {10 1} t1b {8 1} t1c {15 1} ok} 1293780be11Sdrh 130*66518ca7Sdrh# Queries use partial indices as appropriate times. 131*66518ca7Sdrh# 132*66518ca7Sdrhdo_test index6-2.1 { 133*66518ca7Sdrh execsql { 134*66518ca7Sdrh CREATE TABLE t2(a,b); 135*66518ca7Sdrh INSERT INTO t2(a,b) SELECT value, value FROM nums WHERE value<1000; 136*66518ca7Sdrh UPDATE t2 SET a=NULL WHERE b%5==0; 137*66518ca7Sdrh CREATE INDEX t2a1 ON t2(a) WHERE a IS NOT NULL; 138*66518ca7Sdrh SELECT count(*) FROM t2 WHERE a IS NOT NULL; 139*66518ca7Sdrh } 140*66518ca7Sdrh} {800} 141*66518ca7Sdrhdo_test index6-2.2 { 142*66518ca7Sdrh execsql { 143*66518ca7Sdrh EXPLAIN QUERY PLAN 144*66518ca7Sdrh SELECT * FROM t2 WHERE a=5; 145*66518ca7Sdrh } 146*66518ca7Sdrh} {/.* TABLE t2 USING INDEX t2a1 .*/} 147*66518ca7Sdrhdo_test index6-2.3 { 148*66518ca7Sdrh execsql { 149*66518ca7Sdrh EXPLAIN QUERY PLAN 150*66518ca7Sdrh SELECT * FROM t2 WHERE a IS NOT NULL; 151*66518ca7Sdrh } 152*66518ca7Sdrh} {/.* TABLE t2 USING INDEX t2a1 .*/} 153*66518ca7Sdrhdo_test index6-2.4 { 154*66518ca7Sdrh execsql { 155*66518ca7Sdrh EXPLAIN QUERY PLAN 156*66518ca7Sdrh SELECT * FROM t2 WHERE a IS NULL; 157*66518ca7Sdrh } 158*66518ca7Sdrh} {~/.*INDEX t2a1.*/} 159*66518ca7Sdrh 160*66518ca7Sdrhdo_execsql_test index6-2.101 { 161*66518ca7Sdrh DROP INDEX t2a1; 162*66518ca7Sdrh UPDATE t2 SET a=b, b=b+10000; 163*66518ca7Sdrh SELECT b FROM t2 WHERE a=15; 164*66518ca7Sdrh} {10015} 165*66518ca7Sdrhdo_execsql_test index6-2.102 { 166*66518ca7Sdrh CREATE INDEX t2a2 ON t2(a) WHERE a<100 OR a>200; 167*66518ca7Sdrh SELECT b FROM t2 WHERE a=15; 168*66518ca7Sdrh PRAGMA integrity_check; 169*66518ca7Sdrh} {10015 ok} 170*66518ca7Sdrhdo_execsql_test index6-2.102eqp { 171*66518ca7Sdrh EXPLAIN QUERY PLAN 172*66518ca7Sdrh SELECT b FROM t2 WHERE a=15; 173*66518ca7Sdrh} {~/.*INDEX t2a2.*/} 174*66518ca7Sdrhdo_execsql_test index6-2.103 { 175*66518ca7Sdrh SELECT b FROM t2 WHERE a=15 AND a<100; 176*66518ca7Sdrh} {10015} 177*66518ca7Sdrhdo_execsql_test index6-2.103eqp { 178*66518ca7Sdrh EXPLAIN QUERY PLAN 179*66518ca7Sdrh SELECT b FROM t2 WHERE a=15 AND a<100; 180*66518ca7Sdrh} {/.*INDEX t2a2.*/} 181*66518ca7Sdrhdo_execsql_test index6-2.104 { 182*66518ca7Sdrh SELECT b FROM t2 WHERE a=515 AND a>200; 183*66518ca7Sdrh} {10515} 184*66518ca7Sdrhdo_execsql_test index6-2.104eqp { 185*66518ca7Sdrh EXPLAIN QUERY PLAN 186*66518ca7Sdrh SELECT b FROM t2 WHERE a=515 AND a>200; 187*66518ca7Sdrh} {/.*INDEX t2a2.*/} 188*66518ca7Sdrh 189*66518ca7Sdrh# Partial UNIQUE indices 190*66518ca7Sdrh# 191*66518ca7Sdrhdo_execsql_test index6-3.1 { 192*66518ca7Sdrh CREATE TABLE t3(a,b); 193*66518ca7Sdrh INSERT INTO t3 SELECT value, value FROM nums WHERE value<200; 194*66518ca7Sdrh UPDATE t3 SET a=999 WHERE b%5!=0; 195*66518ca7Sdrh CREATE UNIQUE INDEX t3a ON t3(a) WHERE a<>999; 196*66518ca7Sdrh} {} 197*66518ca7Sdrhdo_test index6-3.2 { 198*66518ca7Sdrh # unable to insert a duplicate row a-value that is not 999. 199*66518ca7Sdrh catchsql { 200*66518ca7Sdrh INSERT INTO t3(a,b) VALUES(150, 'test1'); 201*66518ca7Sdrh } 202*66518ca7Sdrh} {1 {column a is not unique}} 203*66518ca7Sdrhdo_test index6-3.3 { 204*66518ca7Sdrh # can insert multiple rows with a==999 because such rows are not 205*66518ca7Sdrh # part of the unique index. 206*66518ca7Sdrh catchsql { 207*66518ca7Sdrh INSERT INTO t3(a,b) VALUES(999, 'test1'), (999, 'test2'); 208*66518ca7Sdrh } 209*66518ca7Sdrh} {0 {}} 210*66518ca7Sdrhdo_execsql_test index6-3.4 { 211*66518ca7Sdrh SELECT count(*) FROM t3 WHERE a=999; 212*66518ca7Sdrh} {162} 213*66518ca7Sdrhintegrity_check index6-3.5 214*66518ca7Sdrh 2151fe0537eSdrhfinish_test 216