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 { 2166518ca7Sdrh # 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; 3166518ca7Sdrh PRAGMA integrity_check; 321fe0537eSdrh } 3366518ca7Sdrh} {14 20 ok} 341fe0537eSdrh 3566518ca7Sdrh# Error conditions during parsing... 3666518ca7Sdrh# 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 7166518ca7Sdrh# STAT1 shows the partial indices have a reduced number of 7266518ca7Sdrh# rows. 7366518ca7Sdrh# 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 13066518ca7Sdrh# Queries use partial indices as appropriate times. 13166518ca7Sdrh# 13266518ca7Sdrhdo_test index6-2.1 { 13366518ca7Sdrh execsql { 13466518ca7Sdrh CREATE TABLE t2(a,b); 13566518ca7Sdrh INSERT INTO t2(a,b) SELECT value, value FROM nums WHERE value<1000; 13666518ca7Sdrh UPDATE t2 SET a=NULL WHERE b%5==0; 13766518ca7Sdrh CREATE INDEX t2a1 ON t2(a) WHERE a IS NOT NULL; 13866518ca7Sdrh SELECT count(*) FROM t2 WHERE a IS NOT NULL; 13966518ca7Sdrh } 14066518ca7Sdrh} {800} 14166518ca7Sdrhdo_test index6-2.2 { 14266518ca7Sdrh execsql { 14366518ca7Sdrh EXPLAIN QUERY PLAN 14466518ca7Sdrh SELECT * FROM t2 WHERE a=5; 14566518ca7Sdrh } 14666518ca7Sdrh} {/.* TABLE t2 USING INDEX t2a1 .*/} 14766518ca7Sdrhdo_test index6-2.3 { 14866518ca7Sdrh execsql { 14966518ca7Sdrh EXPLAIN QUERY PLAN 15066518ca7Sdrh SELECT * FROM t2 WHERE a IS NOT NULL; 15166518ca7Sdrh } 15266518ca7Sdrh} {/.* TABLE t2 USING INDEX t2a1 .*/} 15366518ca7Sdrhdo_test index6-2.4 { 15466518ca7Sdrh execsql { 15566518ca7Sdrh EXPLAIN QUERY PLAN 15666518ca7Sdrh SELECT * FROM t2 WHERE a IS NULL; 15766518ca7Sdrh } 15866518ca7Sdrh} {~/.*INDEX t2a1.*/} 15966518ca7Sdrh 16066518ca7Sdrhdo_execsql_test index6-2.101 { 16166518ca7Sdrh DROP INDEX t2a1; 16266518ca7Sdrh UPDATE t2 SET a=b, b=b+10000; 16366518ca7Sdrh SELECT b FROM t2 WHERE a=15; 16466518ca7Sdrh} {10015} 16566518ca7Sdrhdo_execsql_test index6-2.102 { 16666518ca7Sdrh CREATE INDEX t2a2 ON t2(a) WHERE a<100 OR a>200; 16766518ca7Sdrh SELECT b FROM t2 WHERE a=15; 16866518ca7Sdrh PRAGMA integrity_check; 16966518ca7Sdrh} {10015 ok} 17066518ca7Sdrhdo_execsql_test index6-2.102eqp { 17166518ca7Sdrh EXPLAIN QUERY PLAN 17266518ca7Sdrh SELECT b FROM t2 WHERE a=15; 17366518ca7Sdrh} {~/.*INDEX t2a2.*/} 17466518ca7Sdrhdo_execsql_test index6-2.103 { 17566518ca7Sdrh SELECT b FROM t2 WHERE a=15 AND a<100; 17666518ca7Sdrh} {10015} 17766518ca7Sdrhdo_execsql_test index6-2.103eqp { 17866518ca7Sdrh EXPLAIN QUERY PLAN 17966518ca7Sdrh SELECT b FROM t2 WHERE a=15 AND a<100; 18066518ca7Sdrh} {/.*INDEX t2a2.*/} 18166518ca7Sdrhdo_execsql_test index6-2.104 { 18266518ca7Sdrh SELECT b FROM t2 WHERE a=515 AND a>200; 18366518ca7Sdrh} {10515} 18466518ca7Sdrhdo_execsql_test index6-2.104eqp { 18566518ca7Sdrh EXPLAIN QUERY PLAN 18666518ca7Sdrh SELECT b FROM t2 WHERE a=515 AND a>200; 18766518ca7Sdrh} {/.*INDEX t2a2.*/} 18866518ca7Sdrh 18966518ca7Sdrh# Partial UNIQUE indices 19066518ca7Sdrh# 19166518ca7Sdrhdo_execsql_test index6-3.1 { 19266518ca7Sdrh CREATE TABLE t3(a,b); 19366518ca7Sdrh INSERT INTO t3 SELECT value, value FROM nums WHERE value<200; 19466518ca7Sdrh UPDATE t3 SET a=999 WHERE b%5!=0; 19566518ca7Sdrh CREATE UNIQUE INDEX t3a ON t3(a) WHERE a<>999; 19666518ca7Sdrh} {} 19766518ca7Sdrhdo_test index6-3.2 { 19866518ca7Sdrh # unable to insert a duplicate row a-value that is not 999. 19966518ca7Sdrh catchsql { 20066518ca7Sdrh INSERT INTO t3(a,b) VALUES(150, 'test1'); 20166518ca7Sdrh } 20266518ca7Sdrh} {1 {column a is not unique}} 20366518ca7Sdrhdo_test index6-3.3 { 20466518ca7Sdrh # can insert multiple rows with a==999 because such rows are not 20566518ca7Sdrh # part of the unique index. 20666518ca7Sdrh catchsql { 20766518ca7Sdrh INSERT INTO t3(a,b) VALUES(999, 'test1'), (999, 'test2'); 20866518ca7Sdrh } 20966518ca7Sdrh} {0 {}} 21066518ca7Sdrhdo_execsql_test index6-3.4 { 21166518ca7Sdrh SELECT count(*) FROM t3 WHERE a=999; 21266518ca7Sdrh} {162} 21366518ca7Sdrhintegrity_check index6-3.5 21466518ca7Sdrh 215*3bf0ac17Sdrhdo_execsql_test index6-4.0 { 216*3bf0ac17Sdrh VACUUM; 217*3bf0ac17Sdrh PRAGMA integrity_check; 218*3bf0ac17Sdrh} {ok} 219*3bf0ac17Sdrh 2201fe0537eSdrhfinish_test 221