-C Add\sthe\sability\sto\suse\san\sindex\seven\sif\sthe\sleft-most\scolumns\sof\sthe\sindex\nare\sunconstrainted,\sprovided\sthat\sthe\sleft-most\scolumns\shave\sfew\sdistinct\nvalues.
-D 2013-11-13T12:27:25.442
+C Add\stest\scases\sfor\sskip-scan.\s\sEnhance\s"do_test"\sso\sthat\sif\sthe\sexpected\sresult\nis\sof\sthe\sform\s"/*..*/"\sor\s"~/*..*/"\sit\streats\sthe\sexpected\sresult\sas\sa\sglob\npattern\srather\sthan\sas\sa\sregular\sexpression.\s\sFix\sa\sbug\sin\sANALYZE\sresult\nloading\sassociated\swith\sWITHOUT\sROWID\stables.
+D 2013-11-13T15:32:15.331
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
-F src/analyze.c 27f0c132aa0679189837e0addf8762e7fd6831b6
+F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f
F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
+F test/skipscan1.test 63af32c300be545417410ea2ce44e78c5b2e34b1
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 0a48d94222d50e6e50d72ac103606c4f8e7cbb81
-F test/tester.tcl 3f675f00d22de3595be25dc2d2cba7ff623ef058
+F test/tester.tcl bce6b929932498383ce92431da6a96432c690bf7
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 5196000930600d0cd931b87e864507791b9dab08
-R d1d503c972952b4e29bfacf424d1532a
-T *branch * skip-scan
-T *sym-skip-scan *
-T -sym-trunk *
+P 27dd5993d1ae5625eb94bf406421eb390d001be9
+R 56958c69a5559324c31384471b37b6dc
U drh
-Z c64da1e6d225931e6198f9f21b69efb9
+Z 2ff45f7229fb8bf180b3b10c0362f0e0
--- /dev/null
+# 2013-11-13
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This file implements tests of the "skip-scan" query strategy.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_execsql_test skipscan1-1.1 {
+ CREATE TABLE t1(a TEXT, b INT, c INT, d INT);
+ CREATE INDEX t1abc ON t1(a,b,c);
+ INSERT INTO t1 VALUES('abc',123,4,5);
+ INSERT INTO t1 VALUES('abc',234,5,6);
+ INSERT INTO t1 VALUES('abc',234,6,7);
+ INSERT INTO t1 VALUES('abc',345,7,8);
+ INSERT INTO t1 VALUES('def',567,8,9);
+ INSERT INTO t1 VALUES('def',345,9,10);
+ INSERT INTO t1 VALUES('bcd',100,6,11);
+
+ /* Fake the sqlite_stat1 table so that the query planner believes
+ ** the table contains thousands of rows and that the first few
+ ** columns are not selective. */
+ ANALYZE;
+ DELETE FROM sqlite_stat1;
+ INSERT INTO sqlite_stat1 VALUES('t1','t1abc','10000 5000 2000 10');
+ ANALYZE sqlite_master;
+} {}
+
+# Simple queries that leave the first one or two columns of the
+# index unconstrainted.
+#
+do_execsql_test skipscan1-1.2 {
+ SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
+} {abc 345 7 8 | def 345 9 10 |}
+do_execsql_test skipscan1-1.2eqp {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
+} {/* USING INDEX t1abc (ANY(a) AND b=?)*/}
+do_execsql_test skipscan1-1.2sort {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
+} {~/*ORDER BY*/}
+
+do_execsql_test skipscan1-1.3 {
+ SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a DESC;
+} {def 345 9 10 | abc 345 7 8 |}
+do_execsql_test skipscan1-1.3eqp {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
+} {/* USING INDEX t1abc (ANY(a) AND b=?)*/}
+do_execsql_test skipscan1-1.3sort {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
+} {~/*ORDER BY*/}
+
+do_execsql_test skipscan1-1.4 {
+ SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
+} {abc 234 6 7 | bcd 100 6 11 |}
+do_execsql_test skipscan1-1.4eqp {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
+} {/* USING INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
+do_execsql_test skipscan1-1.4sort {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
+} {~/*ORDER BY*/}
+
+# Joins
+#
+do_execsql_test skipscan1-1.5 {
+ CREATE TABLE t1j(x TEXT, y INTEGER);
+ INSERT INTO t1j VALUES('one',1),('six',6),('ninty-nine',99);
+ SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
+} {six abc 234 6 7 | six bcd 100 6 11 |}
+do_execsql_test skipscan1-1.5eqp {
+ EXPLAIN QUERY PLAN
+ SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
+} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
+
+do_execsql_test skipscan1-1.6 {
+ SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
+} {one {} {} {} {} | six abc 234 6 7 | six bcd 100 6 11 | ninty-nine {} {} {} {} |}
+do_execsql_test skipscan1-1.6eqp {
+ EXPLAIN QUERY PLAN
+ SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
+} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
+
+do_execsql_test skipscan1-2.1 {
+ CREATE TABLE t2(a TEXT, b INT, c INT, d INT,
+ PRIMARY KEY(a,b,c));
+ INSERT INTO t2 SELECT * FROM t1;
+
+ /* Fake the sqlite_stat1 table so that the query planner believes
+ ** the table contains thousands of rows and that the first few
+ ** columns are not selective. */
+ ANALYZE;
+ UPDATE sqlite_stat1 SET stat='10000 5000 2000 10' WHERE idx NOT NULL;
+ ANALYZE sqlite_master;
+} {}
+
+do_execsql_test skipscan1-2.2 {
+ SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a;
+} {abc 345 7 8 | def 345 9 10 |}
+do_execsql_test skipscan1-2.2eqp {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a;
+} {/* USING INDEX sqlite_autoindex_t2_1 (ANY(a) AND b=?)*/}
+do_execsql_test skipscan1-2.2sort {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a;
+} {~/*ORDER BY*/}
+
+
+do_execsql_test skipscan1-3.1 {
+ CREATE TABLE t3(a TEXT, b INT, c INT, d INT,
+ PRIMARY KEY(a,b,c)) WITHOUT ROWID;
+ INSERT INTO t3 SELECT * FROM t1;
+
+ /* Fake the sqlite_stat1 table so that the query planner believes
+ ** the table contains thousands of rows and that the first few
+ ** columns are not selective. */
+ ANALYZE;
+ UPDATE sqlite_stat1 SET stat='10000 5000 2000 10' WHERE idx NOT NULL;
+ ANALYZE sqlite_master;
+} {}
+
+do_execsql_test skipscan1-3.2 {
+ SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
+} {abc 345 7 8 | def 345 9 10 |}
+do_execsql_test skipscan1-3.2eqp {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
+} {/* INDEX sqlite_autoindex_t3_1 (ANY(a) AND b=?)*/}
+do_execsql_test skipscan1-3.2sort {
+ EXPLAIN QUERY PLAN
+ SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
+} {~/*ORDER BY*/}
+
+finish_test