mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Overhaul of EXPLAIN QUERY PLAN. The output is now in the form of a tree.
More details of the query plan are shown, and what is shown is truer to what actually happens. FossilOrigin-Name: ff01bbdabc4b9db3db8b928979442c91b32d72082158e4f5fe62ae51a73649d2
This commit is contained in:
@@ -95,7 +95,7 @@ do_setup_rec_test $tn.1 { CREATE TABLE t1(a, b, c) } {
|
||||
SELECT * FROM t1
|
||||
} {
|
||||
(no new indexes)
|
||||
0|0|0|SCAN TABLE t1
|
||||
SCAN TABLE t1
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.2 {
|
||||
@@ -104,7 +104,7 @@ do_setup_rec_test $tn.2 {
|
||||
SELECT * FROM t1 WHERE b>?;
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b);
|
||||
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
|
||||
SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.3 {
|
||||
@@ -113,7 +113,7 @@ do_setup_rec_test $tn.3 {
|
||||
SELECT * FROM t1 WHERE b COLLATE nocase BETWEEN ? AND ?
|
||||
} {
|
||||
CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE);
|
||||
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
|
||||
SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.4 {
|
||||
@@ -122,7 +122,7 @@ do_setup_rec_test $tn.4 {
|
||||
SELECT a FROM t1 ORDER BY b;
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b);
|
||||
0|0|0|SCAN TABLE t1 USING INDEX t1_idx_00000062
|
||||
SCAN TABLE t1 USING INDEX t1_idx_00000062
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.5 {
|
||||
@@ -131,7 +131,7 @@ do_setup_rec_test $tn.5 {
|
||||
SELECT a FROM t1 WHERE a=? ORDER BY b;
|
||||
} {
|
||||
CREATE INDEX t1_idx_000123a7 ON t1(a, b);
|
||||
0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
|
||||
SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.6 {
|
||||
@@ -140,7 +140,7 @@ do_setup_rec_test $tn.6 {
|
||||
SELECT min(a) FROM t1
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a);
|
||||
0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
|
||||
SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.7 {
|
||||
@@ -149,7 +149,7 @@ do_setup_rec_test $tn.7 {
|
||||
SELECT * FROM t1 ORDER BY a, b, c;
|
||||
} {
|
||||
CREATE INDEX t1_idx_033e95fe ON t1(a, b, c);
|
||||
0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
|
||||
SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
|
||||
}
|
||||
|
||||
#do_setup_rec_test $tn.1.8 {
|
||||
@@ -167,7 +167,7 @@ do_setup_rec_test $tn.8.1 {
|
||||
SELECT * FROM t1 WHERE a=?
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a);
|
||||
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
|
||||
SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
|
||||
}
|
||||
do_setup_rec_test $tn.8.2 {
|
||||
CREATE TABLE t1(a, b COLLATE nocase, c);
|
||||
@@ -175,7 +175,7 @@ do_setup_rec_test $tn.8.2 {
|
||||
SELECT * FROM t1 ORDER BY a ASC, b DESC, c ASC;
|
||||
} {
|
||||
CREATE INDEX t1_idx_5cb97285 ON t1(a, b DESC, c);
|
||||
0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_5cb97285
|
||||
SCAN TABLE t1 USING COVERING INDEX t1_idx_5cb97285
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ do_setup_rec_test $tn.9.1 {
|
||||
SELECT * FROM "t t" WHERE a=?
|
||||
} {
|
||||
CREATE INDEX 't t_idx_00000061' ON 't t'(a);
|
||||
0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?)
|
||||
SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.9.2 {
|
||||
@@ -196,7 +196,7 @@ do_setup_rec_test $tn.9.2 {
|
||||
SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
|
||||
} {
|
||||
CREATE INDEX 't t_idx_00000062' ON 't t'(b);
|
||||
0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
|
||||
SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
|
||||
}
|
||||
|
||||
# Columns with names that require quotes.
|
||||
@@ -207,7 +207,7 @@ do_setup_rec_test $tn.10.1 {
|
||||
SELECT * FROM t3 WHERE "b b" = ?
|
||||
} {
|
||||
CREATE INDEX t3_idx_00050c52 ON t3('b b');
|
||||
0|0|0|SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
|
||||
SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.10.2 {
|
||||
@@ -216,7 +216,7 @@ do_setup_rec_test $tn.10.2 {
|
||||
SELECT * FROM t3 ORDER BY "b b"
|
||||
} {
|
||||
CREATE INDEX t3_idx_00050c52 ON t3('b b');
|
||||
0|0|0|SCAN TABLE t3 USING INDEX t3_idx_00050c52
|
||||
SCAN TABLE t3 USING INDEX t3_idx_00050c52
|
||||
}
|
||||
|
||||
# Transitive constraints
|
||||
@@ -229,8 +229,8 @@ do_setup_rec_test $tn.11.1 {
|
||||
} {
|
||||
CREATE INDEX t5_idx_000123a7 ON t5(a, b);
|
||||
CREATE INDEX t6_idx_00000063 ON t6(c);
|
||||
0|0|1|SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?)
|
||||
0|1|0|SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
|
||||
SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?)
|
||||
SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
|
||||
}
|
||||
|
||||
# OR terms.
|
||||
@@ -242,8 +242,8 @@ do_setup_rec_test $tn.12.1 {
|
||||
} {
|
||||
CREATE INDEX t7_idx_00000062 ON t7(b);
|
||||
CREATE INDEX t7_idx_00000061 ON t7(a);
|
||||
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
|
||||
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
|
||||
SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
|
||||
SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
|
||||
}
|
||||
|
||||
# rowid terms.
|
||||
@@ -254,7 +254,7 @@ do_setup_rec_test $tn.13.1 {
|
||||
SELECT * FROM t8 WHERE rowid=?
|
||||
} {
|
||||
(no new indexes)
|
||||
0|0|0|SEARCH TABLE t8 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH TABLE t8 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
do_setup_rec_test $tn.13.2 {
|
||||
CREATE TABLE t8(a, b);
|
||||
@@ -262,7 +262,7 @@ do_setup_rec_test $tn.13.2 {
|
||||
SELECT * FROM t8 ORDER BY rowid
|
||||
} {
|
||||
(no new indexes)
|
||||
0|0|0|SCAN TABLE t8
|
||||
SCAN TABLE t8
|
||||
}
|
||||
do_setup_rec_test $tn.13.3 {
|
||||
CREATE TABLE t8(a, b);
|
||||
@@ -270,7 +270,7 @@ do_setup_rec_test $tn.13.3 {
|
||||
SELECT * FROM t8 WHERE a=? ORDER BY rowid
|
||||
} {
|
||||
CREATE INDEX t8_idx_00000061 ON t8(a);
|
||||
0|0|0|SEARCH TABLE t8 USING INDEX t8_idx_00000061 (a=?)
|
||||
SEARCH TABLE t8 USING INDEX t8_idx_00000061 (a=?)
|
||||
}
|
||||
|
||||
# Triggers
|
||||
@@ -285,8 +285,8 @@ do_setup_rec_test $tn.14 {
|
||||
INSERT INTO t9 VALUES(?, ?, ?);
|
||||
} {
|
||||
CREATE INDEX t10_idx_00000062 ON t10(b);
|
||||
0|1|0|-- TRIGGER t9t
|
||||
0|0|0|SEARCH TABLE t10 USING INDEX t10_idx_00000062 (b=?)
|
||||
-- TRIGGER t9t
|
||||
SEARCH TABLE t10 USING INDEX t10_idx_00000062 (b=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.15 {
|
||||
@@ -302,8 +302,8 @@ do_setup_rec_test $tn.15 {
|
||||
SELECT * FROM t2, t1 WHERE b=? AND d=? AND t2.rowid=t1.rowid
|
||||
} {
|
||||
CREATE INDEX t2_idx_00000064 ON t2(d);
|
||||
0|0|0|SEARCH TABLE t2 USING INDEX t2_idx_00000064 (d=?)
|
||||
0|1|1|SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH TABLE t2 USING INDEX t2_idx_00000064 (d=?)
|
||||
SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.16 {
|
||||
@@ -312,7 +312,7 @@ do_setup_rec_test $tn.16 {
|
||||
SELECT * FROM t1 WHERE b IS NOT NULL;
|
||||
} {
|
||||
(no new indexes)
|
||||
0|0|0|SCAN TABLE t1
|
||||
SCAN TABLE t1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1123,9 +1123,9 @@ int idxFindIndexes(
|
||||
"EXPLAIN QUERY PLAN %s", pStmt->zSql
|
||||
);
|
||||
while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
|
||||
int iSelectid = sqlite3_column_int(pExplain, 0);
|
||||
int iOrder = sqlite3_column_int(pExplain, 1);
|
||||
int iFrom = sqlite3_column_int(pExplain, 2);
|
||||
/* int iId = sqlite3_column_int(pExplain, 0); */
|
||||
/* int iParent = sqlite3_column_int(pExplain, 1); */
|
||||
/* int iNotUsed = sqlite3_column_int(pExplain, 2); */
|
||||
const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
|
||||
int nDetail = STRLEN(zDetail);
|
||||
int i;
|
||||
@@ -1152,9 +1152,7 @@ int idxFindIndexes(
|
||||
}
|
||||
}
|
||||
|
||||
pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n",
|
||||
iSelectid, iOrder, iFrom, zDetail
|
||||
);
|
||||
pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
|
||||
}
|
||||
|
||||
for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
|
||||
|
||||
@@ -29,38 +29,37 @@ do_execsql_test 1.0 {
|
||||
do_eqp_test 1.1 {
|
||||
SELECT * FROM t1, f1 WHERE f1 MATCH t1.x
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
|
||||
}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM t1, f1 WHERE f1 > t1.x
|
||||
} {
|
||||
0 0 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:}
|
||||
0 1 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
|
||||
} {
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 1.4 {
|
||||
SELECT * FROM f1 ORDER BY rank
|
||||
} {
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 1.5 {
|
||||
SELECT * FROM f1 WHERE rank MATCH ?
|
||||
} {
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -74,42 +74,48 @@ do_test rtree6-1.5 {
|
||||
do_eqp_test rtree6.2.1 {
|
||||
SELECT * FROM t1,t2 WHERE k=+ii AND x1<10
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0}
|
||||
0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_eqp_test rtree6.2.2 {
|
||||
SELECT * FROM t1,t2 WHERE k=ii AND x1<10
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0}
|
||||
0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_eqp_test rtree6.2.3 {
|
||||
SELECT * FROM t1,t2 WHERE k=ii
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:}
|
||||
0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_eqp_test rtree6.2.4.1 {
|
||||
SELECT * FROM t1,t2 WHERE v=+ii and x1<10 and x2>10
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1}
|
||||
0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1
|
||||
`--SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)
|
||||
}
|
||||
do_eqp_test rtree6.2.4.2 {
|
||||
SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1}
|
||||
0 1 1 {SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1
|
||||
`--SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)
|
||||
}
|
||||
|
||||
do_eqp_test rtree6.2.5 {
|
||||
SELECT * FROM t1,t2 WHERE k=ii AND x1<v
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:}
|
||||
0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_execsql_test rtree6-3.1 {
|
||||
|
||||
@@ -29,31 +29,35 @@ do_eqp_test 1.1 {
|
||||
SELECT * FROM r_tree, t
|
||||
WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t}
|
||||
0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t
|
||||
`--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
|
||||
}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM t, r_tree
|
||||
WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t}
|
||||
0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t
|
||||
`--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
|
||||
}
|
||||
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM t, r_tree
|
||||
WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t}
|
||||
0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t
|
||||
`--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
|
||||
}
|
||||
|
||||
do_eqp_test 1.5 {
|
||||
SELECT * FROM t, r_tree
|
||||
} {
|
||||
0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:}
|
||||
0 1 0 {SCAN TABLE t}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:
|
||||
`--SCAN TABLE t
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
@@ -82,31 +86,35 @@ do_eqp_test 2.1 {
|
||||
SELECT * FROM r_tree, t
|
||||
WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t}
|
||||
0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t
|
||||
`--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
|
||||
}
|
||||
|
||||
do_eqp_test 2.2 {
|
||||
SELECT * FROM t, r_tree
|
||||
WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t}
|
||||
0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t
|
||||
`--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
|
||||
}
|
||||
|
||||
do_eqp_test 2.3 {
|
||||
SELECT * FROM t, r_tree
|
||||
WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t}
|
||||
0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t
|
||||
`--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
|
||||
}
|
||||
|
||||
do_eqp_test 2.5 {
|
||||
SELECT * FROM t, r_tree
|
||||
} {
|
||||
0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:}
|
||||
0 1 0 {SCAN TABLE t}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:
|
||||
`--SCAN TABLE t
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -119,20 +127,25 @@ do_execsql_test 3.1 {
|
||||
}
|
||||
|
||||
do_eqp_test 3.2.1 { SELECT * FROM t1 CROSS JOIN t2 } {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
do_eqp_test 3.2.2 { SELECT * FROM t2 CROSS JOIN t1 } {
|
||||
0 0 0 {SCAN TABLE t2} 0 1 1 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
do_eqp_test 3.3.1 { SELECT * FROM t1 CROSS JOIN t3 } {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE t3 VIRTUAL TABLE INDEX 2:
|
||||
}
|
||||
do_eqp_test 3.3.2 { SELECT * FROM t3 CROSS JOIN t1 } {
|
||||
0 0 0 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:}
|
||||
0 1 1 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t3 VIRTUAL TABLE INDEX 2:
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
@@ -189,8 +202,9 @@ do_rtree_integrity_test 5.1.1 rt
|
||||
do_eqp_test 5.2 {
|
||||
SELECT * FROM t1, rt WHERE x==id;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE rt VIRTUAL TABLE INDEX 1:
|
||||
}
|
||||
|
||||
# Now create enough ANALYZE data to tell SQLite that virtual table "rt"
|
||||
@@ -205,8 +219,9 @@ sqlite3 db test.db
|
||||
do_eqp_test 5.4 {
|
||||
SELECT * FROM t1, rt WHERE x==id;
|
||||
} {
|
||||
0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:}
|
||||
0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE rt VIRTUAL TABLE INDEX 2:
|
||||
`--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)
|
||||
}
|
||||
|
||||
# Delete the ANALYZE data. "t1" should be the outer loop again.
|
||||
@@ -217,8 +232,9 @@ sqlite3 db test.db
|
||||
do_eqp_test 5.6 {
|
||||
SELECT * FROM t1, rt WHERE x==id;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE rt VIRTUAL TABLE INDEX 1:
|
||||
}
|
||||
|
||||
# This time create and attach a database that contains ANALYZE data for
|
||||
@@ -241,8 +257,9 @@ do_test 5.7 {
|
||||
do_eqp_test 5.8 {
|
||||
SELECT * FROM t1, rt WHERE x==id;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE rt VIRTUAL TABLE INDEX 1:
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
@@ -299,9 +316,9 @@ do_execsql_test 7.0 {
|
||||
|
||||
}
|
||||
|
||||
proc do_eqp_execsql_test {tn sql res} {
|
||||
set query "EXPLAIN QUERY PLAN $sql ; $sql "
|
||||
uplevel [list do_execsql_test $tn $query $res]
|
||||
proc do_eqp_execsql_test {tn sql res1 res2} {
|
||||
do_eqp_test $tn.1 $sql $res1
|
||||
do_execsql_test $tn.2 $sql $res2
|
||||
}
|
||||
|
||||
do_eqp_execsql_test 7.1 {
|
||||
@@ -309,9 +326,11 @@ do_eqp_execsql_test 7.1 {
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE xdir}
|
||||
0 1 2 {SCAN TABLE ydir}
|
||||
0 2 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE xdir
|
||||
|--SCAN TABLE ydir
|
||||
`--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1
|
||||
} {
|
||||
2 4
|
||||
}
|
||||
|
||||
@@ -320,10 +339,11 @@ do_eqp_execsql_test 7.2 {
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE xdir}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
|
||||
0 2 2 {SCAN TABLE ydir}
|
||||
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE xdir
|
||||
|--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1
|
||||
`--SCAN TABLE ydir
|
||||
} {
|
||||
5 1 2 7 12 14 {}
|
||||
5 2 2 7 8 12 10
|
||||
5 4 5 5 10 10 10
|
||||
@@ -334,9 +354,11 @@ do_eqp_execsql_test 7.3 {
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE xdir}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
|
||||
0 2 2 {SCAN TABLE ydir}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE xdir
|
||||
|--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1
|
||||
`--SCAN TABLE ydir
|
||||
} {
|
||||
2 4
|
||||
}
|
||||
|
||||
@@ -345,9 +367,11 @@ do_eqp_execsql_test 7.4 {
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 1 {SCAN TABLE xdir}
|
||||
0 1 0 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
|
||||
0 2 2 {SCAN TABLE ydir}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE xdir
|
||||
|--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1
|
||||
`--SCAN TABLE ydir
|
||||
} {
|
||||
2 4
|
||||
}
|
||||
|
||||
|
||||
151
manifest
151
manifest
@@ -1,5 +1,5 @@
|
||||
C Prevent\sVACUUM\sfrom\srunning\sany\scommands\sin\ssqlite_master.sql\sother\sthan\nCREATE\sstatements.\s\sThat\sis\sall\sthat\sshould\sbe\sthere\sanyhow.\s\sThis\sfixes\na\sproblem\sdiscovered\sby\sOSSFuzz.\s\sTest\scases\sin\sTH3.
|
||||
D 2018-05-02T15:00:26.033
|
||||
C Overhaul\sof\sEXPLAIN\sQUERY\sPLAN.\sThe\soutput\sis\snow\sin\sthe\sform\sof\sa\stree.\nMore\sdetails\sof\sthe\squery\splan\sare\sshown,\sand\swhat\sis\sshown\sis\struer\sto\swhat\nactually\shappens.
|
||||
D 2018-05-03T19:56:50.453
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
|
||||
@@ -44,8 +44,8 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 00fb67256755a5194dab3d462f8ed3ad4640b4731fe465e5e28cea42c59ce05e
|
||||
F ext/expert/sqlite3expert.c 1dfa561e64dc0f89d56b96e6afda87468c34b43604c2df50c47e3f4362778fb2
|
||||
F ext/expert/expert1.test 81c8834822181d009c08b18d2afb3b0fce8167a8bbbf23496a0e598d2b21623d
|
||||
F ext/expert/sqlite3expert.c 95fdee74be2912d962951d984f1123e55d3f44bd643da7a48ff6ea9426a47f69
|
||||
F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
@@ -187,7 +187,7 @@ F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c27
|
||||
F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da
|
||||
F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1
|
||||
F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b
|
||||
F ext/fts5/test/fts5plan.test e30e8378441114ef6977a3dc24ecd203caa670d782124dfc9a6e9af09f7abc4d
|
||||
F ext/fts5/test/fts5plan.test 00dc4c974938b509db7cb3680407f068ee6e9cc824f492f68cb741a7b679fe41
|
||||
F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15
|
||||
F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457
|
||||
F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056
|
||||
@@ -362,13 +362,13 @@ F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e5
|
||||
F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482
|
||||
F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
|
||||
F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142
|
||||
F ext/rtree/rtree6.test 916a641d2beac01b9880871ff07612d56c1e466190a27c82ab36ffd58be03b9f
|
||||
F ext/rtree/rtree6.test 593e0d36510d5ac1d1fb39b018274ff17604fe8fdca8cf1f8e16559cea1477f4
|
||||
F ext/rtree/rtree7.test c8fb2e555b128dd0f0bdb520c61380014f497f8a23c40f2e820acc9f9e4fdce5
|
||||
F ext/rtree/rtree8.test 649f5a37ec656028a4a32674b9b1183104285a7625a09d2a8f52a1cef72c93f2
|
||||
F ext/rtree/rtree9.test c646f12c8c1c68ef015c6c043d86a0c42488e2e68ed1bb1b0771a7ca246cbabf
|
||||
F ext/rtree/rtreeA.test 20623ca337ca3bd7e008cc9fb49e44dbe97f1a80b238e10a12bb4afcd0da3776
|
||||
F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9
|
||||
F ext/rtree/rtreeC.test d9d06dda1aee68b4dc227dfcc899f335f8b621e9d1920ee3d4e5dab8ccd71db7
|
||||
F ext/rtree/rtreeC.test 55e40c4bd9735d9944280f0e664f39374e71bcd9cd3fe4e82786d20b48017fb5
|
||||
F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc
|
||||
F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9
|
||||
F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331
|
||||
@@ -445,7 +445,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
|
||||
F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
|
||||
F src/delete.c b0f90749e22d5e41a12dbf940f4811138cf97da54b46b737089b93eb64a2896f
|
||||
F src/expr.c 5c9a6dc7f56d245d7bb82ba36fdba2ca3bdd1881b61ee60293dd98c766742cd9
|
||||
F src/expr.c af4a81a385277510bfc56df87c25d76fc365f98c33bc8797c4a8d84b88e31013
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
|
||||
F src/func.c 94f42cba2cc1c34aeaa441022ba0170ec3fec4bba54db4e0ded085c6dc0fdc51
|
||||
@@ -488,17 +488,17 @@ F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
|
||||
F src/pragma.c bea56df3ae0637768c0da4fbbb8f2492f780980d95000034a105ff291bf7ca69
|
||||
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
|
||||
F src/prepare.c 1492a2bed7bc5770c5850404f09bf887a67d4580985b8cee37bdab2ea809f479
|
||||
F src/prepare.c 95a9dba7a5d032039a77775188cb3b6fb17f2fa1a0b7cd915b30b4b823383ffa
|
||||
F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c daf07d8defce3311f9e69f1280a874d78bc1d16c305f6aa689640f7afa02842f
|
||||
F src/shell.c.in 54b902ab7d840f60ddfabc13124c85d4980342c88aff7679f2cc25f67c21ade7
|
||||
F src/select.c 75ae3000bef42ea6a7271cf49f6bc5e94bdbf73026ddea251f2a8b6cf14960fd
|
||||
F src/shell.c.in 29309f2ab656c8817fbc3b7910b9af8464557b91cba75277a03669399c8e2730
|
||||
F src/sqlite.h.in 469aed42e75193b7f5d88d812befa961c04746869475f96fcf434c9f67079f66
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
|
||||
F src/sqliteInt.h 8ac0138eae10337b745b03dad0124fd63ae911c0503e795729503e7fc6234d57
|
||||
F src/sqliteInt.h 7fbd839f07d873a877375138f2681453232e2e2de8f48be65888e295cd05ced3
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -556,7 +556,7 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c bbde32eac9eb1280f5292bcdfef66f5a57e43176cbf9347e0efab9f75e133f97
|
||||
F src/treeview.c 6cea286ca9af8b126dae9714799265353387244eba0d451c3cc2cd60946cc4c7
|
||||
F src/treeview.c 06dd506b1dcef01c5882a4189bc79afe2660dd992702f81cd7d003425a99cfbc
|
||||
F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995
|
||||
F src/update.c 5be2f501ddc704fc04183bdb28b25eab930bb8553d973429a089ec94fa85cf2b
|
||||
F src/upsert.c ae4a4823b45c4daf87e8aea8c0f582a8844763271f5ed54ee5956c4c612734f4
|
||||
@@ -564,10 +564,10 @@ F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 593498d6d1f1f3c5561c1476132d3b03af33881ff9f27ce4e48d4ba60be3615d
|
||||
F src/vdbe.c 066a4e1de2ed83e253adfd2e97a684cf562eaa41d31ee7f3d3e4c8aea4485a55
|
||||
F src/vdbe.h 574ce9a0d57b026fc93ac379a339b8d391977f335ab4176a7e21ba902e9184bd
|
||||
F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2
|
||||
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
|
||||
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
|
||||
F src/vdbeaux.c 944bae5207bbce456c466d01dcf2aac3ad49c957325d35c0ba7de882d3e5c25c
|
||||
F src/vdbeaux.c 58129ae46be079613df5c2c3714d80a78605415bfa10c9528634c7c2d2147727
|
||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||
F src/vdbemem.c 0cbe9b9560e42b72983cf9e1bceba48f297e51142bfb6b57f3747cf60106b92d
|
||||
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
|
||||
@@ -577,9 +577,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
|
||||
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
||||
F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
|
||||
F src/where.c 7a1c5555c00bcf49c677472ae83bb49bf24c8d8e9a060d475e86dee39be2fb3a
|
||||
F src/where.c aa94ef44ef36763817ca952e68c03db7eee5e2d4f1f0c3a98823a58c074157bd
|
||||
F src/whereInt.h 2610cb87dd95509995b63decc674c60f2757697a206cfe0c085ee53d9c43cfff
|
||||
F src/wherecode.c 3cb591fe7323e1bfd49059d75fcab75e383dfcf16a51c0e4f9368ac1b93e291b
|
||||
F src/wherecode.c 3368f0797a4b166e0773a4137d270d92ddcbce91618b11d1e9f11f7c39f33068
|
||||
F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@@ -595,19 +595,19 @@ F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df
|
||||
F test/analyze3.test 8b3ef8ba6d1096b76c40e0925c0fe51e700d2b779cdda40914580de3f9b9d80f
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8
|
||||
F test/analyze4.test cdf88f3f72b0f0643a1ff6c730fc5af1e42464d47478d9fbac84c333f72c014e
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
||||
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
|
||||
F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82
|
||||
F test/analyze9.test dac0bdc7eab965b9ad639ca83564d98717aaf13ce5a776f23d9a3680238cecd8
|
||||
F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a
|
||||
F test/analyze6.test 7b2667b879976ac4b90d8df80d5456328684f1f6f6fdef9469d6e53401f2f469
|
||||
F test/analyze7.test a37f4d9cb699a8af068ae02df1bb08bf844df8e98a92a8126cbff89e226879d8
|
||||
F test/analyze8.test e32a970564271114786703750e6939cf81dea4b8580874e38e9213ee092f6936
|
||||
F test/analyze9.test 9fbf0e0101eef4f5dc149769aa14e10b76ee06e7c28598264b32173cd1999a54
|
||||
F test/analyzeA.test 22a892d67bd2223126335b99774cce56ba91122cfe82446d2927afc43ad667dc
|
||||
F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70
|
||||
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||
F test/analyzeD.test 42af58de25a6436502e43006e9e59e2d71bcb0cf
|
||||
F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c
|
||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||
F test/analyzeF.test f423125b557f11ad71bb29765ef9c34b6dcf4ab7
|
||||
F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb
|
||||
F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49
|
||||
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
||||
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
@@ -626,11 +626,11 @@ F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
|
||||
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
|
||||
F test/autoinc.test 83aad64411583aac9ff0b629159ab4662029ab4e3f47090fce4efd132b304484
|
||||
F test/autoindex1.test 788d0894aa3aee1220036d20696e98733fb7ca02265cb1e801700177120c1aeb
|
||||
F test/autoindex1.test a09958fa756129af10b6582bcbf3cbdf11e305e027b393f393caef801159dee0
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990
|
||||
F test/autoindex5.test 5f0135dc3b266277b8c1904624439097d8e8020dd7197eda13fda23c35c21a05
|
||||
F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
|
||||
@@ -644,15 +644,15 @@ F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
|
||||
F test/bestindex1.test a9b831613b46baae213798cd3a71257833d5d3d2692e0e50c7ff0c3fbaeb0200
|
||||
F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060
|
||||
F test/bestindex3.test 578b6a52dab819e63f28e3640e04b32c85aed320
|
||||
F test/bestindex1.test 852170bddbb21daa121fabcc274640ff83d7d8705912e8b5fe7ed2c5a9a9224a
|
||||
F test/bestindex2.test 9a0ccd320b6525eec3a706aae6cdab7e1b7b5abca75027e39f39f755e76e5928
|
||||
F test/bestindex3.test 92a34c82f1ae245ef71f8c999f50a9dccd097a310cb070244c7b5cd0d2e07d73
|
||||
F test/bestindex4.test 4cb5ff7dbaebadb87d366f51969271778423b455
|
||||
F test/bestindex5.test 412b42f8036b28d8b2f3534d89389ad946a4b1a65a12263f51936f7424296f1b
|
||||
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
F test/bigmmap.test abe819e6e1ac1db0c3bfe364ff58889d96e7896b2bbc8bdf1afc77cdeb7d7a9b
|
||||
F test/bigmmap.test 31dad31573638bd32de866cdefd11843f75685be4ba6aec1a47918f098f1899b
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2
|
||||
F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483
|
||||
@@ -723,9 +723,9 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
||||
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
|
||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||
F test/corruptK.test 91550557849244a9904f4e090052e3f2c1c3f1106840d58b00ffaa3a8c2d3fc0
|
||||
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
|
||||
F test/cost.test dadd9905a9f34631a1821ff3d1b3e571ebad8afcd14ba0dca6d0818d9fd91237
|
||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
|
||||
F test/coveridxscan.test 5ec98719a2e2914e8908dc75f7247d9b54a26df04625f846ac7900d5483f7296
|
||||
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
|
||||
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
|
||||
@@ -766,7 +766,7 @@ F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145
|
||||
F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14
|
||||
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
|
||||
F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844
|
||||
F test/e_createtable.test ef30054d1e4cec4d1da2ffcebcc15f1ded3ed7ae80f009019485be973f449917
|
||||
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
|
||||
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
|
||||
F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5
|
||||
@@ -791,7 +791,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
||||
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
|
||||
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2
|
||||
F test/eqp.test 2ac18a1d6aa0a0a8f0eea1cc0ba7d63391e2f968a47f59643f889c7c87d238a4
|
||||
F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9
|
||||
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
|
||||
F test/exclusive.test 1206b87e192497d78c7f35552e86a9d05421498da300fb1cce5ca5351ccde3c3
|
||||
@@ -869,7 +869,7 @@ F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18
|
||||
F test/fts3ao.test c416d50c4fdb6f32a15205b3d0a49eb74fcea92feb66b531a83c904770de5ff1
|
||||
F test/fts3atoken.test 4b4c16fdcfc972f2cdbba212375a060a86ccf5f1
|
||||
F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9
|
||||
F test/fts3aux1.test 24b8a69e342a6684e3929408b245cdf5de0d45f8094108fa0a57cd007228963d
|
||||
F test/fts3aux1.test 7a170e172afdbceb67f5baa05941fd4fbf56af42f61daa3d140f4b4bf4cb68f6
|
||||
F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba
|
||||
F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd491
|
||||
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
|
||||
@@ -893,7 +893,7 @@ F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
|
||||
F test/fts3fault.test 9fb7d6266a38806de841f7244bac1b0fe3a1477184bbb10b172d19d2ca6ad692
|
||||
F test/fts3fault2.test 6a17a11d8034b1c4eca9f3091649273d56c49ff049e2173df8060f94341e9da0
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
F test/fts3join.test 69aeb460d0ea17527a2b1b8d24ce18f29c7f207a7261867a2618f639c8020459
|
||||
F test/fts3join.test 949b4f5ae3ae9cc2423cb865d711e32476bdb205ab2be923fdf48246e4a44166
|
||||
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
||||
F test/fts3matchinfo.test ce864e0bd92429df8008f31cf557269ba172482a
|
||||
F test/fts3misc.test ba03a83b831555cfd18c6c862b24b70a53ce7497fe55077f7c4b7c9ce83c2eed
|
||||
@@ -901,7 +901,7 @@ F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
|
||||
F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c
|
||||
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
|
||||
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
|
||||
F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170
|
||||
F test/fts3query.test ca5dffabdfe9aef2ebcc89e02ce515898f86f8c30a365283831c53e0e08e5821
|
||||
F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||
@@ -980,13 +980,13 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7
|
||||
F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
|
||||
F test/index6.test d07ea75b8c21f125c6f325522e8df8c05c91e9251ec923a31d0582b2ba4a617d
|
||||
F test/index7.test 72b59b8ddc5c13f4962886b4011eb9975014317d17ef36c6297921362fb7dd98
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
F test/indexedby.test faa585e315e868f09bce0eb39c41d6134649b13d2801638294d3ae616edf1609
|
||||
F test/indexedby.test 5a4a451412e3723b36214f2f98acc4ecbb7fd67fd11bbe9fa46ffb6e18cfd987
|
||||
F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e
|
||||
F test/indexexpr2.test 13247bac49143196556eb3f65e97ef301bd3e993f4511558b5db322ddc370ea6
|
||||
F test/indexexpr2.test 08551aa8956a91582979e17b6d369f321a5cb6ed6d3e952925a3e54e9e7de216
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
@@ -1009,10 +1009,10 @@ F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/istrue.test 62372ad3ddcc5d0eb8ff9097dcb0aad8961bf1b9cb45ba634f6e284695126f9a
|
||||
F test/join.test 2ad9d7fe10e0cc06bc7803c22e5533be11cdadbc592f5f95d789a873b57a5a66
|
||||
F test/join2.test f5ea0fd3b0a441c8e439706339dcd17cec63a896a755c04a30bfd442ecce1190
|
||||
F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test 000a18e9ccc9fc716e550eb2337729d3aee99031d0ddd9682f6b7d73aa99b924
|
||||
F test/join5.test 196e0cbb552dd91815a43b5a26b64d40bdf9ff881c7a8413821dbd5f7154e3f8
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
@@ -1065,7 +1065,7 @@ F test/mallocG.test 0ff91b65c50bdaba680fb75d87fe4ad35bb7934f
|
||||
F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
|
||||
F test/mallocI.test 6c23a71df077fa5d387be90e7e669c5b368ca38a
|
||||
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
|
||||
F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e
|
||||
F test/mallocK.test 1f4b5efbf61715ab79b20b38739ff4b3d110ceb53f54e5db6da1f01c083707ab
|
||||
F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc
|
||||
F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134
|
||||
F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
|
||||
@@ -1118,7 +1118,7 @@ F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/optfuzz-db01.c a0c256905c8ac79f9a5de2f374a3d9f757bef0dca2a238dc7c10cc8a38031834
|
||||
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
|
||||
F test/optfuzz.c 50e330304eb1992e15ddd11f3daaad9bcc0d9aaad09cb2bcc77f9515df2e88b1
|
||||
F test/orderby1.test 4d22a7c75f6a83fc1f188cc7bb5192285fdf2552
|
||||
F test/orderby1.test bb8535f52c42e91cfa110622ccff70597e531198bb4b033185ad84c11522ab1b
|
||||
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
|
||||
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
|
||||
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
|
||||
@@ -1173,15 +1173,15 @@ F test/releasetest.tcl 5f15ab8056799e9a6e26a310d49236d2e774d6a30d0ec74601e18d4ce
|
||||
F test/resetdb.test 7fda92e443233208ec5e1825b176a9df63fb5bf962248e08b76eb4296c630cdf
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5
|
||||
F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6
|
||||
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
|
||||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
|
||||
F test/rowvalue.test 32861d6a933ded868035f2ec79aeb993a2a46eb7a6d282ae13415a4c2e369463
|
||||
F test/rowvalue.test ef851a80f7e6de93b51caca9e4b6b7d2dcd540bbcca7d51860e80435b8b4c0de
|
||||
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
|
||||
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
|
||||
F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea
|
||||
F test/rowvalue4.test cbd1cead27a797d11ec93301fd801c89e97eb1809b3d984b7f16a3876e362eac
|
||||
F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6
|
||||
F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087
|
||||
F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8
|
||||
@@ -1197,7 +1197,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test 1ba0e2ee25dcd1d55ec770803b19832cffaecbf0b15d376807759ebeed3669b0
|
||||
F test/scanstatus.test d14842d0a2757ee059bcffa365746453d60952ba1077980c9a348a9fefbd232a
|
||||
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
||||
@@ -1215,10 +1215,10 @@ F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test f659f231489349e8c5734e610803d7654207318f
|
||||
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
|
||||
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
|
||||
F test/selectA.test 101e722370ac6e84978c2958b8931c78b10a1709
|
||||
F test/selectA.test b8a590f6493cad5b0bb4dfe1709bf7dcda0b6c40bb4caf32d1e36a89eebc8fc5
|
||||
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
|
||||
F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3
|
||||
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
|
||||
F test/selectD.test cfa9f27dbdbeaf2d021d26c79b6c790d8f26e5506d50117c7696d3e136d6d9e7
|
||||
F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
|
||||
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840
|
||||
@@ -1251,10 +1251,10 @@ F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test 8ab5d2c7c5cd3fe7f172d366e6e74e887cb33cb4
|
||||
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
F test/skipscan2.test ef143c6e4a5ba4f19c1d1e3f517811f7942bdf2142736cc568feb34e0b5fb763
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
|
||||
F test/skipscan6.test 0b4cd1b4ac9f84d91454df513c99a4932fa07e8f27b8049bea605068b3e34ac7
|
||||
F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f
|
||||
F test/snapshot2.test 925e42427e923262db63c9d7155183f889e3e99feaedec4075f659e51608344f
|
||||
F test/snapshot3.test 9719443594a04778861bd20d12596c5f880af177d6cd62f111da3198cafc6096
|
||||
@@ -1316,7 +1316,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl 94901a4625d9a2229666dd5c44120ddf7f0fb639470710ef74a4cefc7b039e07
|
||||
F test/tester.tcl aa7558f20fcf7dd9151325f849d9103bd450235093bc078073bf0f080991e3c4
|
||||
F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1337,7 +1337,7 @@ F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
|
||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
|
||||
F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
|
||||
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
|
||||
F test/tkt-385a5b56b9.test 5204a7cba0e28c99df0acbf95af5e1af4d32965a7a14de6eccebf949607618b1
|
||||
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
||||
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||
F test/tkt-3a77c9714e.test b08bca26de1140bdf004a37716582a43d7bd8be8
|
||||
@@ -1352,7 +1352,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
|
||||
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
|
||||
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
|
||||
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
|
||||
F test/tkt-78e04e52ea.test 1b2e6bf4f1d9887b216b6da774e5f25915ec8118
|
||||
F test/tkt-78e04e52ea.test 1b5be1bac961833a9fd70fe50738cb4064822c61f82c54f7d488435ec806ea62
|
||||
F test/tkt-7a31705a7e6.test 9e9c057b6a9497c8f7ba7b16871029414ccf6550e7345d9085d6d71c9a56bb6f
|
||||
F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
|
||||
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
|
||||
@@ -1370,7 +1370,7 @@ F test/tkt-a8a0d2996a.test 76662ff0622c90e7ce7bbcb4d9e1129acddf877d17c3489f2da7f
|
||||
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
|
||||
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
|
||||
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
|
||||
F test/tkt-b75a9ca6b0.test 97cc2d5eeaf82799eb42138c0a1ff64370238ce4
|
||||
F test/tkt-b75a9ca6b0.test 1bc0381538fd21f96a10dbabc10ffc51b5b2e5f412d34bae571273ca784003d7
|
||||
F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877
|
||||
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
|
||||
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
|
||||
@@ -1435,7 +1435,7 @@ F test/tkt3346.test 6f67c3ed7db94dfc5df4f5f0b63809a1f611e01a
|
||||
F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed
|
||||
F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b
|
||||
F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812
|
||||
F test/tkt3442.test 53840ec5325bb94544792aad4c20476f81dc26b1
|
||||
F test/tkt3442.test a1fc47c669e651d16494de3ff349bcb53281456f2ca02c8bc14220b6044bbfe8
|
||||
F test/tkt3457.test 5651e2cbb94645b677ec663160b9e192b87b7d365aecdfb24e19f749575a6fc2
|
||||
F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
|
||||
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
|
||||
@@ -1471,7 +1471,7 @@ F test/tkt3992.test f3e7d548ac26f763b47bc0f750da3d03c81071da
|
||||
F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd
|
||||
F test/tkt4018.test 18dbc6617f7a4b90e938d1bd6d26ad18daafaf08
|
||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
|
||||
F test/tpch01.test 7c4eb8cdd79c568f46d344b3e789c9fdb8a766d112871352704861f3fca32a2a
|
||||
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144
|
||||
@@ -1508,7 +1508,7 @@ F test/unionvtabfault.test 26b6854d5aef9005cd630513025690bff1b7378ae9c97b81e2a3c
|
||||
F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
|
||||
F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2
|
||||
F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
|
||||
F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8
|
||||
F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981
|
||||
F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60
|
||||
F test/update2.test 5e67667e1c54017d964e626db765cf8bedcf87483c184f4c575bdb8c1dd2313e
|
||||
F test/upsert1.test d587db593f131e112a98a05685c418e0eacc28df5905403e4ca04cd74c39a3fc
|
||||
@@ -1584,23 +1584,23 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
F test/where.test f19ea3fa31c425b04af42c8b192a5b595ee84498df8d27dcd79ec043b25fbbfb
|
||||
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
|
||||
F test/where3.test 54cdeb02157acc979de41530b804ae7b09552bf1
|
||||
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
F test/where7.test f520bcec2c3d12dc4615623b06b2aec7c2d67e94
|
||||
F test/where7.test 9bfbfdf0ee238f15a6eea29060f4bb22e8b43b724efe67fd8bf6febfbe54429d
|
||||
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
|
||||
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
|
||||
F test/where9.test 74f9dfddb42016d13b6ab0f6c943d7b993da9b2f7303faa2d465e02e340c2b5e
|
||||
F test/whereA.test 6c6a420ca7d313242f9b1bd471dc80e4d0f8323700ba9c78df0bb843d4daa3b4
|
||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
|
||||
F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89
|
||||
F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501
|
||||
F test/whereG.test 0158783235a6dd82fc0e37652b8522b186b9510594ac0a4bff0c4101b4396a52
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7
|
||||
F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767
|
||||
F test/whereI.test 0f30efab13000309f340cada83f5cf888814de0d056431fb2f0251a91c58becf
|
||||
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
|
||||
F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b
|
||||
F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864
|
||||
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
|
||||
@@ -1611,12 +1611,12 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/with1.test ca08e291249a810a2ec9b72ceef5575e07d5925b360fcf6652ae6fe06ac4dced
|
||||
F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
|
||||
F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 1cb47a1a5ba5b2946f18703fabf9fb2a237b0a8180538793ecbaed834d0df765
|
||||
F test/without_rowid1.test 533add9100255e4cc430d371b3ecfb79f11f956b86c3a1b9d34413bf8e482d8f
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
@@ -1727,7 +1727,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 0c67150749cb3d067e14b2dcac9c3489e0f14bd18c0387f1d9bc93d21fc96fe5
|
||||
R 05ae73916277803fcebbb023b759986c
|
||||
P ab0d99d0b5edece4c639baa47ce1ca2c02774cb2515e5b7f36d9bd312ccd3310 956fef361a795bd081d8e23ce4075dc8aafcee63ab7275d13b657b529d185b30
|
||||
R 067c5aa8ed93f027a9f18eeeee2f55ff
|
||||
T +closed 956fef361a795bd081d8e23ce4075dc8aafcee63ab7275d13b657b529d185b30
|
||||
U drh
|
||||
Z 0a57dfa0969cac36c6f9349555316be2
|
||||
Z b328f3a1ea4d4f9e8fb3fe9715c4ed00
|
||||
|
||||
@@ -1 +1 @@
|
||||
ab0d99d0b5edece4c639baa47ce1ca2c02774cb2515e5b7f36d9bd312ccd3310
|
||||
ff01bbdabc4b9db3db8b928979442c91b32d72082158e4f5fe62ae51a73649d2
|
||||
34
src/expr.c
34
src/expr.c
@@ -2410,11 +2410,8 @@ int sqlite3FindInIndex(
|
||||
if( colUsed==(MASKBIT(nExpr)-1) ){
|
||||
/* If we reach this point, that means the index pIdx is usable */
|
||||
int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
|
||||
sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
|
||||
P4_DYNAMIC);
|
||||
#endif
|
||||
ExplainQueryPlan((pParse, 0,
|
||||
"USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
|
||||
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
||||
VdbeComment((v, "%s", pIdx->zName));
|
||||
@@ -2646,17 +2643,9 @@ int sqlite3CodeSubselect(
|
||||
Select *pSelect = pExpr->x.pSelect;
|
||||
ExprList *pEList = pSelect->pEList;
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
if( pParse->explain==2 ){
|
||||
char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %sLIST SUBQUERY %d",
|
||||
jmpIfDynamic>=0?"":"CORRELATED ",
|
||||
pParse->iNextSelectId
|
||||
);
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg,
|
||||
P4_DYNAMIC);
|
||||
}
|
||||
#endif
|
||||
|
||||
ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
|
||||
jmpIfDynamic>=0?"":"CORRELATED "
|
||||
));
|
||||
assert( !isRowid );
|
||||
/* If the LHS and RHS of the IN operator do not match, that
|
||||
** error will have been caught long before we reach this point. */
|
||||
@@ -2777,18 +2766,9 @@ int sqlite3CodeSubselect(
|
||||
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
|
||||
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
if( pParse->explain==2 ){
|
||||
char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %sSCALAR SUBQUERY %d",
|
||||
jmpIfDynamic>=0?"":"CORRELATED ",
|
||||
pParse->iNextSelectId
|
||||
);
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg,
|
||||
P4_DYNAMIC);
|
||||
}
|
||||
#endif
|
||||
|
||||
pSel = pExpr->x.pSelect;
|
||||
ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
|
||||
jmpIfDynamic>=0?"":"CORRELATED "));
|
||||
nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
|
||||
sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
|
||||
pParse->nMem += nReg;
|
||||
|
||||
@@ -616,7 +616,7 @@ static int sqlite3Prepare(
|
||||
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
||||
static const char * const azColName[] = {
|
||||
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
|
||||
"selectid", "order", "from", "detail"
|
||||
"id", "parent", "notused", "detail"
|
||||
};
|
||||
int iFirst, mx;
|
||||
if( sParse.explain==2 ){
|
||||
|
||||
503
src/select.c
503
src/select.c
@@ -21,7 +21,7 @@
|
||||
/***/ int sqlite3SelectTrace = 0;
|
||||
# define SELECTTRACE(K,P,S,X) \
|
||||
if(sqlite3SelectTrace&(K)) \
|
||||
sqlite3DebugPrintf("%s/%d/%p: ",(S)->zSelName,(P)->iSelectId,(S)),\
|
||||
sqlite3DebugPrintf("%s/%d/%p: ",(S)->zSelName,(P)->addrExplain,(S)),\
|
||||
sqlite3DebugPrintf X
|
||||
#else
|
||||
# define SELECTTRACE(K,P,S,X)
|
||||
@@ -1293,11 +1293,7 @@ static const char *selectOpName(int id){
|
||||
** is determined by the zUsage argument.
|
||||
*/
|
||||
static void explainTempTable(Parse *pParse, const char *zUsage){
|
||||
if( pParse->explain==2 ){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
|
||||
}
|
||||
ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1315,42 +1311,6 @@ static void explainTempTable(Parse *pParse, const char *zUsage){
|
||||
# define explainSetInteger(y,z)
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
|
||||
/*
|
||||
** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
|
||||
** is a no-op. Otherwise, it adds a single row of output to the EQP result,
|
||||
** where the caption is of one of the two forms:
|
||||
**
|
||||
** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
|
||||
** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
|
||||
**
|
||||
** where iSub1 and iSub2 are the integers passed as the corresponding
|
||||
** function parameters, and op is the text representation of the parameter
|
||||
** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
|
||||
** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is
|
||||
** false, or the second form if it is true.
|
||||
*/
|
||||
static void explainComposite(
|
||||
Parse *pParse, /* Parse context */
|
||||
int op, /* One of TK_UNION, TK_EXCEPT etc. */
|
||||
int iSub1, /* Subquery id 1 */
|
||||
int iSub2, /* Subquery id 2 */
|
||||
int bUseTmp /* True if a temp table was used */
|
||||
){
|
||||
assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
|
||||
if( pParse->explain==2 ){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
char *zMsg = sqlite3MPrintf(
|
||||
pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
|
||||
bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
|
||||
);
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* No-op versions of the explainXXX() functions and macros. */
|
||||
# define explainComposite(v,w,x,y,z)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If the inner loop was generated using a non-null pOrderBy argument,
|
||||
@@ -2327,6 +2287,7 @@ static void generateWithRecursiveQuery(
|
||||
|
||||
/* Store the results of the setup-query in Queue. */
|
||||
pSetup->pNext = 0;
|
||||
ExplainQueryPlan((pParse, 1, "SETUP"));
|
||||
rc = sqlite3Select(pParse, pSetup, &destQueue);
|
||||
pSetup->pNext = p;
|
||||
if( rc ) goto end_of_recursive_query;
|
||||
@@ -2361,6 +2322,7 @@ static void generateWithRecursiveQuery(
|
||||
sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
|
||||
}else{
|
||||
p->pPrior = 0;
|
||||
ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
|
||||
sqlite3Select(pParse, p, &destQueue);
|
||||
assert( p->pPrior==0 );
|
||||
p->pPrior = pSetup;
|
||||
@@ -2406,10 +2368,9 @@ static int multiSelectValues(
|
||||
Select *p, /* The right-most of SELECTs to be coded */
|
||||
SelectDest *pDest /* What to do with query results */
|
||||
){
|
||||
Select *pPrior;
|
||||
Select *pRightmost = p;
|
||||
int nRow = 1;
|
||||
int rc = 0;
|
||||
int bShowAll = p->pLimit==0;
|
||||
assert( p->selFlags & SF_MultiValue );
|
||||
do{
|
||||
assert( p->selFlags & SF_Values );
|
||||
@@ -2418,14 +2379,13 @@ static int multiSelectValues(
|
||||
if( p->pPrior==0 ) break;
|
||||
assert( p->pPrior->pNext==p );
|
||||
p = p->pPrior;
|
||||
nRow++;
|
||||
nRow += bShowAll;
|
||||
}while(1);
|
||||
ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow,
|
||||
nRow==1 ? "" : "S"));
|
||||
while( p ){
|
||||
pPrior = p->pPrior;
|
||||
p->pPrior = 0;
|
||||
rc = sqlite3Select(pParse, p, pDest);
|
||||
p->pPrior = pPrior;
|
||||
if( rc || pRightmost->pLimit ) break;
|
||||
selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1);
|
||||
if( !bShowAll ) break;
|
||||
p->nSelectRow = nRow;
|
||||
p = p->pNext;
|
||||
}
|
||||
@@ -2474,10 +2434,6 @@ static int multiSelect(
|
||||
SelectDest dest; /* Alternative data destination */
|
||||
Select *pDelete = 0; /* Chain of simple selects to delete */
|
||||
sqlite3 *db; /* Database connection */
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
int iSub1 = 0; /* EQP id of left-hand query */
|
||||
int iSub2 = 0; /* EQP id of right-hand query */
|
||||
#endif
|
||||
|
||||
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
|
||||
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
|
||||
@@ -2528,217 +2484,231 @@ static int multiSelect(
|
||||
*/
|
||||
if( p->pOrderBy ){
|
||||
return multiSelectOrderBy(pParse, p, pDest);
|
||||
}else
|
||||
}else{
|
||||
|
||||
/* Generate code for the left and right SELECT statements.
|
||||
*/
|
||||
switch( p->op ){
|
||||
case TK_ALL: {
|
||||
int addr = 0;
|
||||
int nLimit;
|
||||
assert( !pPrior->pLimit );
|
||||
pPrior->iLimit = p->iLimit;
|
||||
pPrior->iOffset = p->iOffset;
|
||||
pPrior->pLimit = p->pLimit;
|
||||
explainSetInteger(iSub1, pParse->iNextSelectId);
|
||||
rc = sqlite3Select(pParse, pPrior, &dest);
|
||||
p->pLimit = 0;
|
||||
if( rc ){
|
||||
goto multi_select_end;
|
||||
}
|
||||
p->pPrior = 0;
|
||||
p->iLimit = pPrior->iLimit;
|
||||
p->iOffset = pPrior->iOffset;
|
||||
if( p->iLimit ){
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
|
||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||
if( p->iOffset ){
|
||||
sqlite3VdbeAddOp3(v, OP_OffsetLimit,
|
||||
p->iLimit, p->iOffset+1, p->iOffset);
|
||||
}
|
||||
}
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
rc = sqlite3Select(pParse, p, &dest);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
pDelete = p->pPrior;
|
||||
p->pPrior = pPrior;
|
||||
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
|
||||
if( pPrior->pLimit
|
||||
&& sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
|
||||
&& nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
|
||||
){
|
||||
p->nSelectRow = sqlite3LogEst((u64)nLimit);
|
||||
}
|
||||
if( addr ){
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
break;
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
if( pPrior->pPrior==0 ){
|
||||
ExplainQueryPlan((pParse, 1, "COMPOUND QUERY"));
|
||||
ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
|
||||
}
|
||||
case TK_EXCEPT:
|
||||
case TK_UNION: {
|
||||
int unionTab; /* Cursor number of the temporary table holding result */
|
||||
u8 op = 0; /* One of the SRT_ operations to apply to self */
|
||||
int priorOp; /* The SRT_ operation to apply to prior selects */
|
||||
Expr *pLimit; /* Saved values of p->nLimit */
|
||||
int addr;
|
||||
SelectDest uniondest;
|
||||
#endif
|
||||
|
||||
testcase( p->op==TK_EXCEPT );
|
||||
testcase( p->op==TK_UNION );
|
||||
priorOp = SRT_Union;
|
||||
if( dest.eDest==priorOp ){
|
||||
/* We can reuse a temporary table generated by a SELECT to our
|
||||
** right.
|
||||
/* Generate code for the left and right SELECT statements.
|
||||
*/
|
||||
switch( p->op ){
|
||||
case TK_ALL: {
|
||||
int addr = 0;
|
||||
int nLimit;
|
||||
assert( !pPrior->pLimit );
|
||||
pPrior->iLimit = p->iLimit;
|
||||
pPrior->iOffset = p->iOffset;
|
||||
pPrior->pLimit = p->pLimit;
|
||||
rc = sqlite3Select(pParse, pPrior, &dest);
|
||||
p->pLimit = 0;
|
||||
if( rc ){
|
||||
goto multi_select_end;
|
||||
}
|
||||
p->pPrior = 0;
|
||||
p->iLimit = pPrior->iLimit;
|
||||
p->iOffset = pPrior->iOffset;
|
||||
if( p->iLimit ){
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
|
||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||
if( p->iOffset ){
|
||||
sqlite3VdbeAddOp3(v, OP_OffsetLimit,
|
||||
p->iLimit, p->iOffset+1, p->iOffset);
|
||||
}
|
||||
}
|
||||
ExplainQueryPlan((pParse, 1, "UNION ALL"));
|
||||
rc = sqlite3Select(pParse, p, &dest);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
pDelete = p->pPrior;
|
||||
p->pPrior = pPrior;
|
||||
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
|
||||
if( pPrior->pLimit
|
||||
&& sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
|
||||
&& nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
|
||||
){
|
||||
p->nSelectRow = sqlite3LogEst((u64)nLimit);
|
||||
}
|
||||
if( addr ){
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_EXCEPT:
|
||||
case TK_UNION: {
|
||||
int unionTab; /* Cursor number of the temp table holding result */
|
||||
u8 op = 0; /* One of the SRT_ operations to apply to self */
|
||||
int priorOp; /* The SRT_ operation to apply to prior selects */
|
||||
Expr *pLimit; /* Saved values of p->nLimit */
|
||||
int addr;
|
||||
SelectDest uniondest;
|
||||
|
||||
testcase( p->op==TK_EXCEPT );
|
||||
testcase( p->op==TK_UNION );
|
||||
priorOp = SRT_Union;
|
||||
if( dest.eDest==priorOp ){
|
||||
/* We can reuse a temporary table generated by a SELECT to our
|
||||
** right.
|
||||
*/
|
||||
assert( p->pLimit==0 ); /* Not allowed on leftward elements */
|
||||
unionTab = dest.iSDParm;
|
||||
}else{
|
||||
/* We will need to create our own temporary table to hold the
|
||||
** intermediate results.
|
||||
*/
|
||||
unionTab = pParse->nTab++;
|
||||
assert( p->pOrderBy==0 );
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
|
||||
assert( p->addrOpenEphm[0] == -1 );
|
||||
p->addrOpenEphm[0] = addr;
|
||||
findRightmost(p)->selFlags |= SF_UsesEphemeral;
|
||||
assert( p->pEList );
|
||||
}
|
||||
|
||||
/* Code the SELECT statements to our left
|
||||
*/
|
||||
assert( p->pLimit==0 ); /* Not allowed on leftward elements */
|
||||
unionTab = dest.iSDParm;
|
||||
}else{
|
||||
/* We will need to create our own temporary table to hold the
|
||||
** intermediate results.
|
||||
assert( !pPrior->pOrderBy );
|
||||
sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
|
||||
rc = sqlite3Select(pParse, pPrior, &uniondest);
|
||||
if( rc ){
|
||||
goto multi_select_end;
|
||||
}
|
||||
|
||||
/* Code the current SELECT statement
|
||||
*/
|
||||
unionTab = pParse->nTab++;
|
||||
if( p->op==TK_EXCEPT ){
|
||||
op = SRT_Except;
|
||||
}else{
|
||||
assert( p->op==TK_UNION );
|
||||
op = SRT_Union;
|
||||
}
|
||||
p->pPrior = 0;
|
||||
pLimit = p->pLimit;
|
||||
p->pLimit = 0;
|
||||
uniondest.eDest = op;
|
||||
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
|
||||
selectOpName(p->op)));
|
||||
rc = sqlite3Select(pParse, p, &uniondest);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
|
||||
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
pDelete = p->pPrior;
|
||||
p->pPrior = pPrior;
|
||||
p->pOrderBy = 0;
|
||||
if( p->op==TK_UNION ){
|
||||
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
|
||||
}
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
p->pLimit = pLimit;
|
||||
p->iLimit = 0;
|
||||
p->iOffset = 0;
|
||||
|
||||
/* Convert the data in the temporary table into whatever form
|
||||
** it is that we currently need.
|
||||
*/
|
||||
assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
|
||||
if( dest.eDest!=priorOp ){
|
||||
int iCont, iBreak, iStart;
|
||||
assert( p->pEList );
|
||||
iBreak = sqlite3VdbeMakeLabel(v);
|
||||
iCont = sqlite3VdbeMakeLabel(v);
|
||||
computeLimitRegisters(pParse, p, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
|
||||
iStart = sqlite3VdbeCurrentAddr(v);
|
||||
selectInnerLoop(pParse, p, unionTab,
|
||||
0, 0, &dest, iCont, iBreak);
|
||||
sqlite3VdbeResolveLabel(v, iCont);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
|
||||
sqlite3VdbeResolveLabel(v, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert( p->op==TK_INTERSECT ); {
|
||||
int tab1, tab2;
|
||||
int iCont, iBreak, iStart;
|
||||
Expr *pLimit;
|
||||
int addr;
|
||||
SelectDest intersectdest;
|
||||
int r1;
|
||||
|
||||
/* INTERSECT is different from the others since it requires
|
||||
** two temporary tables. Hence it has its own case. Begin
|
||||
** by allocating the tables we will need.
|
||||
*/
|
||||
tab1 = pParse->nTab++;
|
||||
tab2 = pParse->nTab++;
|
||||
assert( p->pOrderBy==0 );
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
|
||||
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
|
||||
assert( p->addrOpenEphm[0] == -1 );
|
||||
p->addrOpenEphm[0] = addr;
|
||||
findRightmost(p)->selFlags |= SF_UsesEphemeral;
|
||||
assert( p->pEList );
|
||||
}
|
||||
|
||||
/* Code the SELECT statements to our left
|
||||
*/
|
||||
assert( !pPrior->pOrderBy );
|
||||
sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
|
||||
explainSetInteger(iSub1, pParse->iNextSelectId);
|
||||
rc = sqlite3Select(pParse, pPrior, &uniondest);
|
||||
if( rc ){
|
||||
goto multi_select_end;
|
||||
}
|
||||
|
||||
/* Code the current SELECT statement
|
||||
*/
|
||||
if( p->op==TK_EXCEPT ){
|
||||
op = SRT_Except;
|
||||
}else{
|
||||
assert( p->op==TK_UNION );
|
||||
op = SRT_Union;
|
||||
}
|
||||
p->pPrior = 0;
|
||||
pLimit = p->pLimit;
|
||||
p->pLimit = 0;
|
||||
uniondest.eDest = op;
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
rc = sqlite3Select(pParse, p, &uniondest);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
|
||||
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
pDelete = p->pPrior;
|
||||
p->pPrior = pPrior;
|
||||
p->pOrderBy = 0;
|
||||
if( p->op==TK_UNION ){
|
||||
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
|
||||
}
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
p->pLimit = pLimit;
|
||||
p->iLimit = 0;
|
||||
p->iOffset = 0;
|
||||
|
||||
/* Convert the data in the temporary table into whatever form
|
||||
** it is that we currently need.
|
||||
*/
|
||||
assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
|
||||
if( dest.eDest!=priorOp ){
|
||||
int iCont, iBreak, iStart;
|
||||
|
||||
/* Code the SELECTs to our left into temporary table "tab1".
|
||||
*/
|
||||
sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
|
||||
rc = sqlite3Select(pParse, pPrior, &intersectdest);
|
||||
if( rc ){
|
||||
goto multi_select_end;
|
||||
}
|
||||
|
||||
/* Code the current SELECT into temporary table "tab2"
|
||||
*/
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
|
||||
assert( p->addrOpenEphm[1] == -1 );
|
||||
p->addrOpenEphm[1] = addr;
|
||||
p->pPrior = 0;
|
||||
pLimit = p->pLimit;
|
||||
p->pLimit = 0;
|
||||
intersectdest.iSDParm = tab2;
|
||||
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
|
||||
selectOpName(p->op)));
|
||||
rc = sqlite3Select(pParse, p, &intersectdest);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
pDelete = p->pPrior;
|
||||
p->pPrior = pPrior;
|
||||
if( p->nSelectRow>pPrior->nSelectRow ){
|
||||
p->nSelectRow = pPrior->nSelectRow;
|
||||
}
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
p->pLimit = pLimit;
|
||||
|
||||
/* Generate code to take the intersection of the two temporary
|
||||
** tables.
|
||||
*/
|
||||
assert( p->pEList );
|
||||
iBreak = sqlite3VdbeMakeLabel(v);
|
||||
iCont = sqlite3VdbeMakeLabel(v);
|
||||
computeLimitRegisters(pParse, p, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
|
||||
iStart = sqlite3VdbeCurrentAddr(v);
|
||||
selectInnerLoop(pParse, p, unionTab,
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
|
||||
r1 = sqlite3GetTempReg(pParse);
|
||||
iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
|
||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
|
||||
VdbeCoverage(v);
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
selectInnerLoop(pParse, p, tab1,
|
||||
0, 0, &dest, iCont, iBreak);
|
||||
sqlite3VdbeResolveLabel(v, iCont);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
|
||||
sqlite3VdbeResolveLabel(v, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert( p->op==TK_INTERSECT ); {
|
||||
int tab1, tab2;
|
||||
int iCont, iBreak, iStart;
|
||||
Expr *pLimit;
|
||||
int addr;
|
||||
SelectDest intersectdest;
|
||||
int r1;
|
||||
|
||||
/* INTERSECT is different from the others since it requires
|
||||
** two temporary tables. Hence it has its own case. Begin
|
||||
** by allocating the tables we will need.
|
||||
*/
|
||||
tab1 = pParse->nTab++;
|
||||
tab2 = pParse->nTab++;
|
||||
assert( p->pOrderBy==0 );
|
||||
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
|
||||
assert( p->addrOpenEphm[0] == -1 );
|
||||
p->addrOpenEphm[0] = addr;
|
||||
findRightmost(p)->selFlags |= SF_UsesEphemeral;
|
||||
assert( p->pEList );
|
||||
|
||||
/* Code the SELECTs to our left into temporary table "tab1".
|
||||
*/
|
||||
sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
|
||||
explainSetInteger(iSub1, pParse->iNextSelectId);
|
||||
rc = sqlite3Select(pParse, pPrior, &intersectdest);
|
||||
if( rc ){
|
||||
goto multi_select_end;
|
||||
}
|
||||
|
||||
/* Code the current SELECT into temporary table "tab2"
|
||||
*/
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
|
||||
assert( p->addrOpenEphm[1] == -1 );
|
||||
p->addrOpenEphm[1] = addr;
|
||||
p->pPrior = 0;
|
||||
pLimit = p->pLimit;
|
||||
p->pLimit = 0;
|
||||
intersectdest.iSDParm = tab2;
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
rc = sqlite3Select(pParse, p, &intersectdest);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
pDelete = p->pPrior;
|
||||
p->pPrior = pPrior;
|
||||
if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
p->pLimit = pLimit;
|
||||
|
||||
/* Generate code to take the intersection of the two temporary
|
||||
** tables.
|
||||
*/
|
||||
assert( p->pEList );
|
||||
iBreak = sqlite3VdbeMakeLabel(v);
|
||||
iCont = sqlite3VdbeMakeLabel(v);
|
||||
computeLimitRegisters(pParse, p, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
|
||||
r1 = sqlite3GetTempReg(pParse);
|
||||
iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
|
||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
selectInnerLoop(pParse, p, tab1,
|
||||
0, 0, &dest, iCont, iBreak);
|
||||
sqlite3VdbeResolveLabel(v, iCont);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
|
||||
sqlite3VdbeResolveLabel(v, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
|
||||
break;
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
if( p->pNext==0 ){
|
||||
ExplainQueryPlanPop(pParse);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
|
||||
|
||||
|
||||
/* Compute collating sequences used by
|
||||
** temporary tables needed to implement the compound select.
|
||||
** Attach the KeyInfo structure to all temporary tables.
|
||||
@@ -3076,10 +3046,6 @@ static int multiSelectOrderBy(
|
||||
ExprList *pOrderBy; /* The ORDER BY clause */
|
||||
int nOrderBy; /* Number of terms in the ORDER BY clause */
|
||||
int *aPermute; /* Mapping from ORDER BY terms to result set columns */
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
int iSub1; /* EQP id of left-hand query */
|
||||
int iSub2; /* EQP id of right-hand query */
|
||||
#endif
|
||||
|
||||
assert( p->pOrderBy!=0 );
|
||||
assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
|
||||
@@ -3199,6 +3165,8 @@ static int multiSelectOrderBy(
|
||||
sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
|
||||
sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
|
||||
|
||||
ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));
|
||||
|
||||
/* Generate a coroutine to evaluate the SELECT statement to the
|
||||
** left of the compound operator - the "A" select.
|
||||
*/
|
||||
@@ -3206,7 +3174,7 @@ static int multiSelectOrderBy(
|
||||
addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
|
||||
VdbeComment((v, "left SELECT"));
|
||||
pPrior->iLimit = regLimitA;
|
||||
explainSetInteger(iSub1, pParse->iNextSelectId);
|
||||
ExplainQueryPlan((pParse, 1, "LEFT"));
|
||||
sqlite3Select(pParse, pPrior, &destA);
|
||||
sqlite3VdbeEndCoroutine(v, regAddrA);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
@@ -3221,7 +3189,7 @@ static int multiSelectOrderBy(
|
||||
savedOffset = p->iOffset;
|
||||
p->iLimit = regLimitB;
|
||||
p->iOffset = 0;
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
ExplainQueryPlan((pParse, 1, "RIGHT"));
|
||||
sqlite3Select(pParse, p, &destB);
|
||||
p->iLimit = savedLimit;
|
||||
p->iOffset = savedOffset;
|
||||
@@ -3333,7 +3301,7 @@ static int multiSelectOrderBy(
|
||||
|
||||
/*** TBD: Insert subroutine calls to close cursors on incomplete
|
||||
**** subqueries ****/
|
||||
explainComposite(pParse, p->op, iSub1, iSub2, 0);
|
||||
ExplainQueryPlanPop(pParse);
|
||||
return pParse->nErr!=0;
|
||||
}
|
||||
#endif
|
||||
@@ -5121,14 +5089,11 @@ static void explainSimpleCount(
|
||||
){
|
||||
if( pParse->explain==2 ){
|
||||
int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
|
||||
char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
|
||||
sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
|
||||
pTab->zName,
|
||||
bCover ? " USING COVERING INDEX " : "",
|
||||
bCover ? pIdx->zName : ""
|
||||
);
|
||||
sqlite3VdbeAddOp4(
|
||||
pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
|
||||
);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -5341,22 +5306,15 @@ int sqlite3Select(
|
||||
ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
|
||||
u8 minMaxFlag; /* Flag for min/max queries */
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
int iRestoreSelectId = pParse->iSelectId;
|
||||
pParse->iSelectId = pParse->iNextSelectId++;
|
||||
#endif
|
||||
|
||||
db = pParse->db;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( p==0 || db->mallocFailed || pParse->nErr ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||
memset(&sAggInfo, 0, sizeof(sAggInfo));
|
||||
#if SELECTTRACE_ENABLED
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
p->iSelectId = pParse->iSelectId;
|
||||
#endif
|
||||
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->iSelectId));
|
||||
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
|
||||
if( sqlite3SelectTrace & 0x100 ){
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
@@ -5393,10 +5351,6 @@ int sqlite3Select(
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get a pointer the VDBE under construction, allocating a new VDBE if one
|
||||
** does not already exist */
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) goto select_end;
|
||||
if( pDest->eDest==SRT_Output ){
|
||||
generateColumnNames(pParse, p);
|
||||
}
|
||||
@@ -5491,11 +5445,11 @@ int sqlite3Select(
|
||||
rc = multiSelect(pParse, p, pDest);
|
||||
#if SELECTTRACE_ENABLED
|
||||
SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
|
||||
if( pParse->iSelectId==0 && (sqlite3SelectTrace & 0x2000)!=0 ){
|
||||
if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
|
||||
if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
@@ -5607,7 +5561,7 @@ int sqlite3Select(
|
||||
VdbeComment((v, "%s", pItem->pTab->zName));
|
||||
pItem->addrFillSub = addrTop;
|
||||
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
|
||||
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
|
||||
ExplainQueryPlan((pParse, 1, "CO-ROUTINE 0x%p", pSub));
|
||||
sqlite3Select(pParse, pSub, &dest);
|
||||
pItem->pTab->nRowLogEst = pSub->nSelectRow;
|
||||
pItem->fg.viaCoroutine = 1;
|
||||
@@ -5642,12 +5596,11 @@ int sqlite3Select(
|
||||
pPrior = isSelfJoinView(pTabList, pItem);
|
||||
if( pPrior ){
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
|
||||
explainSetInteger(pItem->iSelectId, pPrior->iSelectId);
|
||||
assert( pPrior->pSelect!=0 );
|
||||
pSub->nSelectRow = pPrior->pSelect->nSelectRow;
|
||||
}else{
|
||||
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
|
||||
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
|
||||
ExplainQueryPlan((pParse, 1, "MATERIALIZE 0x%p", pSub));
|
||||
sqlite3Select(pParse, pSub, &dest);
|
||||
}
|
||||
pItem->pTab->nRowLogEst = pSub->nSelectRow;
|
||||
@@ -6285,10 +6238,10 @@ select_end:
|
||||
sqlite3DbFree(db, sAggInfo.aFunc);
|
||||
#if SELECTTRACE_ENABLED
|
||||
SELECTTRACE(0x1,pParse,p,("end processing\n"));
|
||||
if( pParse->iSelectId==0 && (sqlite3SelectTrace & 0x2000)!=0 ){
|
||||
if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
|
||||
ExplainQueryPlanPop(pParse);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -981,7 +981,8 @@ struct ExpertInfo {
|
||||
/* A single line in the EQP output */
|
||||
typedef struct EQPGraphRow EQPGraphRow;
|
||||
struct EQPGraphRow {
|
||||
int iSelectId; /* The SelectID for this row */
|
||||
int iEqpId; /* ID for this row */
|
||||
int iParentId; /* ID of the parent row */
|
||||
EQPGraphRow *pNext; /* Next row in sequence */
|
||||
char zText[1]; /* Text to display for this row */
|
||||
};
|
||||
@@ -1003,6 +1004,7 @@ struct ShellState {
|
||||
sqlite3 *db; /* The database */
|
||||
u8 autoExplain; /* Automatically turn on .explain mode */
|
||||
u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
|
||||
u8 autoEQPtest; /* autoEQP is in test mode */
|
||||
u8 statsOn; /* True to display memory stats before each finalize */
|
||||
u8 scanstatsOn; /* True to display scan stats before each finalize */
|
||||
u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
|
||||
@@ -1053,10 +1055,10 @@ struct ShellState {
|
||||
|
||||
/* Allowed values for ShellState.autoEQP
|
||||
*/
|
||||
#define AUTOEQP_off 0
|
||||
#define AUTOEQP_on 1
|
||||
#define AUTOEQP_trigger 2
|
||||
#define AUTOEQP_full 3
|
||||
#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
|
||||
#define AUTOEQP_on 1 /* Automatic EQP is on */
|
||||
#define AUTOEQP_trigger 2 /* On and also show plans for triggers */
|
||||
#define AUTOEQP_full 3 /* Show full EXPLAIN */
|
||||
|
||||
/* Allowed values for ShellState.openMode
|
||||
*/
|
||||
@@ -1667,12 +1669,16 @@ static int wsToEol(const char *z){
|
||||
/*
|
||||
** Add a new entry to the EXPLAIN QUERY PLAN data
|
||||
*/
|
||||
static void eqp_append(ShellState *p, int iSelectId, const char *zText){
|
||||
static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
|
||||
EQPGraphRow *pNew;
|
||||
int nText = strlen30(zText);
|
||||
if( p->autoEQPtest ){
|
||||
utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
|
||||
}
|
||||
pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
|
||||
if( pNew==0 ) shell_out_of_memory();
|
||||
pNew->iSelectId = iSelectId;
|
||||
pNew->iEqpId = iEqpId;
|
||||
pNew->iParentId = p2;
|
||||
memcpy(pNew->zText, zText, nText+1);
|
||||
pNew->pNext = 0;
|
||||
if( p->sGraph.pLast ){
|
||||
@@ -1696,46 +1702,29 @@ static void eqp_reset(ShellState *p){
|
||||
memset(&p->sGraph, 0, sizeof(p->sGraph));
|
||||
}
|
||||
|
||||
/* Return the next EXPLAIN QUERY PLAN line with iSelectId that occurs after
|
||||
/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
|
||||
** pOld, or return the first such line if pOld is NULL
|
||||
*/
|
||||
static EQPGraphRow *eqp_next_row(ShellState *p, int iSelectId, EQPGraphRow *pOld){
|
||||
static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
|
||||
EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
|
||||
while( pRow && pRow->iSelectId!=iSelectId ) pRow = pRow->pNext;
|
||||
while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
|
||||
return pRow;
|
||||
}
|
||||
|
||||
/* Render a single level of the graph shell having iSelectId. Called
|
||||
/* Render a single level of the graph that has iEqpId as its parent. Called
|
||||
** recursively to render sublevels.
|
||||
*/
|
||||
static void eqp_render_level(ShellState *p, int iSelectId){
|
||||
static void eqp_render_level(ShellState *p, int iEqpId){
|
||||
EQPGraphRow *pRow, *pNext;
|
||||
int i;
|
||||
int n = strlen30(p->sGraph.zPrefix);
|
||||
char *z;
|
||||
for(pRow = eqp_next_row(p, iSelectId, 0); pRow; pRow = pNext){
|
||||
pNext = eqp_next_row(p, iSelectId, pRow);
|
||||
for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
|
||||
pNext = eqp_next_row(p, iEqpId, pRow);
|
||||
z = pRow->zText;
|
||||
utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
|
||||
if( n<sizeof(p->sGraph.zPrefix)-7 && (z = strstr(z, " SUBQUER"))!=0 ){
|
||||
if( n<sizeof(p->sGraph.zPrefix)-7 ){
|
||||
memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
|
||||
if( strncmp(z, " SUBQUERY ", 9)==0 && (i = atoi(z+10))>iSelectId ){
|
||||
eqp_render_level(p, i);
|
||||
}else if( strncmp(z, " SUBQUERIES ", 12)==0 ){
|
||||
i = atoi(z+12);
|
||||
if( i>iSelectId ){
|
||||
utf8_printf(p->out, "%s|--SUBQUERY %d\n", p->sGraph.zPrefix, i);
|
||||
memcpy(&p->sGraph.zPrefix[n+3],"| ",4);
|
||||
eqp_render_level(p, i);
|
||||
}
|
||||
z = strstr(z, " AND ");
|
||||
if( z && (i = atoi(z+5))>iSelectId ){
|
||||
p->sGraph.zPrefix[n+3] = 0;
|
||||
utf8_printf(p->out, "%s`--SUBQUERY %d\n", p->sGraph.zPrefix, i);
|
||||
memcpy(&p->sGraph.zPrefix[n+3]," ",4);
|
||||
eqp_render_level(p, i);
|
||||
}
|
||||
}
|
||||
eqp_render_level(p, pRow->iEqpId);
|
||||
p->sGraph.zPrefix[n] = 0;
|
||||
}
|
||||
}
|
||||
@@ -2114,7 +2103,7 @@ static int shell_callback(
|
||||
break;
|
||||
}
|
||||
case MODE_EQP: {
|
||||
eqp_append(p, atoi(azArg[0]), azArg[3]);
|
||||
eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2956,9 +2945,10 @@ static int shell_exec(
|
||||
if( rc==SQLITE_OK ){
|
||||
while( sqlite3_step(pExplain)==SQLITE_ROW ){
|
||||
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
|
||||
int iSelectId = sqlite3_column_int(pExplain, 0);
|
||||
int iEqpId = sqlite3_column_int(pExplain, 0);
|
||||
int iParentId = sqlite3_column_int(pExplain, 1);
|
||||
if( zEQPLine[0]=='-' ) eqp_render(pArg);
|
||||
eqp_append(pArg, iSelectId, zEQPLine);
|
||||
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
|
||||
}
|
||||
eqp_render(pArg);
|
||||
}
|
||||
@@ -5914,10 +5904,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
p->autoEQPtest = 0;
|
||||
if( strcmp(azArg[1],"full")==0 ){
|
||||
p->autoEQP = AUTOEQP_full;
|
||||
}else if( strcmp(azArg[1],"trigger")==0 ){
|
||||
p->autoEQP = AUTOEQP_trigger;
|
||||
}else if( strcmp(azArg[1],"test")==0 ){
|
||||
p->autoEQP = AUTOEQP_on;
|
||||
p->autoEQPtest = 1;
|
||||
}else{
|
||||
p->autoEQP = (u8)booleanValue(azArg[1]);
|
||||
}
|
||||
|
||||
@@ -2609,9 +2609,6 @@ struct SrcList {
|
||||
unsigned viaCoroutine :1; /* Implemented as a co-routine */
|
||||
unsigned isRecursive :1; /* True for recursive reference in WITH */
|
||||
} fg;
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
|
||||
#endif
|
||||
int iCursor; /* The VDBE cursor number used to access this table */
|
||||
Expr *pOn; /* The ON clause of a join */
|
||||
IdList *pUsing; /* The USING clause of a join */
|
||||
@@ -2783,7 +2780,6 @@ struct Select {
|
||||
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
|
||||
#if SELECTTRACE_ENABLED
|
||||
char zSelName[12]; /* Symbolic name of this SELECT use for debugging */
|
||||
u32 iSelectId; /* EXPLAIN QUERY PLAN select ID */
|
||||
#endif
|
||||
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
|
||||
SrcList *pSrc; /* The FROM clause */
|
||||
@@ -2824,8 +2820,7 @@ struct Select {
|
||||
#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
|
||||
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
|
||||
#define SF_ComplexResult 0x40000 /* Result set contains subquery or function */
|
||||
|
||||
#define SF_ComplexResult 0x40000 /* Result contains subquery or function */
|
||||
|
||||
/*
|
||||
** The results of a SELECT can be distributed in several ways, as defined
|
||||
@@ -3095,8 +3090,7 @@ struct Parse {
|
||||
#endif
|
||||
int nHeight; /* Expression tree height of current sub-select */
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
int iSelectId; /* ID of current select for EXPLAIN output */
|
||||
int iNextSelectId; /* Next available select ID for EXPLAIN output */
|
||||
int addrExplain; /* Address of current OP_Explain opcode */
|
||||
#endif
|
||||
VList *pVList; /* Mapping between variable names and numbers */
|
||||
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
|
||||
|
||||
@@ -141,10 +141,10 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
do{
|
||||
#if SELECTTRACE_ENABLED
|
||||
sqlite3TreeViewLine(pView,
|
||||
"SELECT%s%s (%s/%d/%p) selFlags=0x%x nSelectRow=%d",
|
||||
"SELECT%s%s (%s/%p) selFlags=0x%x nSelectRow=%d",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
|
||||
p->zSelName, p->iSelectId, p, p->selFlags,
|
||||
p->zSelName, p, p->selFlags,
|
||||
(int)p->nSelectRow
|
||||
);
|
||||
#else
|
||||
|
||||
14
src/vdbe.h
14
src/vdbe.h
@@ -197,7 +197,19 @@ void sqlite3VdbeEndCoroutine(Vdbe*,int);
|
||||
# define sqlite3VdbeVerifyNoMallocRequired(A,B)
|
||||
# define sqlite3VdbeVerifyNoResultRow(A)
|
||||
#endif
|
||||
VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
|
||||
VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
void sqlite3VdbeExplain(Parse*,u8,const char*,...);
|
||||
void sqlite3VdbeExplainPop(Parse*);
|
||||
int sqlite3VdbeExplainParent(Parse*);
|
||||
# define ExplainQueryPlan(P) sqlite3VdbeExplain P
|
||||
# define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P)
|
||||
# define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P)
|
||||
#else
|
||||
# define ExplainQueryPlan(P)
|
||||
# define ExplainQueryPlanPop(P)
|
||||
# define ExplainQueryPlanParent(P) 0
|
||||
#endif
|
||||
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
|
||||
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
|
||||
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
|
||||
|
||||
@@ -303,6 +303,49 @@ int sqlite3VdbeAddOp4Dup8(
|
||||
return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
/*
|
||||
** Return the address of the current EXPLAIN QUERY PLAN baseline.
|
||||
** 0 means "none".
|
||||
*/
|
||||
int sqlite3VdbeExplainParent(Parse *pParse){
|
||||
VdbeOp *pOp;
|
||||
if( pParse->addrExplain==0 ) return 0;
|
||||
pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
|
||||
return pOp->p2;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add a new OP_Explain opcode.
|
||||
**
|
||||
** If the bPush flag is true, then make this opcode the parent for
|
||||
** subsequent Explains until sqlite3VdbeExplainPop() is called.
|
||||
*/
|
||||
void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
|
||||
if( pParse->explain==2 ){
|
||||
char *zMsg;
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
va_list ap;
|
||||
int iThis;
|
||||
va_start(ap, zFmt);
|
||||
zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
|
||||
va_end(ap);
|
||||
v = pParse->pVdbe;
|
||||
iThis = v->nOp;
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
|
||||
zMsg, P4_DYNAMIC);
|
||||
if( bPush) pParse->addrExplain = iThis;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Pop the EXPLAIN QUERY PLAN stack one level.
|
||||
*/
|
||||
void sqlite3VdbeExplainPop(Parse *pParse){
|
||||
pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_EXPLAIN */
|
||||
|
||||
/*
|
||||
** Add an OP_ParseSchema opcode. This routine is broken out from
|
||||
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
|
||||
|
||||
@@ -4592,6 +4592,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( wctrlFlags & WHERE_WANT_DISTINCT ){
|
||||
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
|
||||
}
|
||||
ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
|
||||
}else{
|
||||
/* Assign a bit from the bitmask to every term in the FROM clause.
|
||||
**
|
||||
|
||||
@@ -134,7 +134,6 @@ int sqlite3WhereExplainOneScan(
|
||||
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
|
||||
Vdbe *v = pParse->pVdbe; /* VM being constructed */
|
||||
sqlite3 *db = pParse->db; /* Database handle */
|
||||
int iId = pParse->iSelectId; /* Select id (left-most output column) */
|
||||
int isSearch; /* True for a SEARCH. False for SCAN. */
|
||||
WhereLoop *pLoop; /* The controlling WhereLoop object */
|
||||
u32 flags; /* Flags that describe this loop */
|
||||
@@ -153,7 +152,7 @@ int sqlite3WhereExplainOneScan(
|
||||
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
|
||||
if( pItem->pSelect ){
|
||||
sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
|
||||
sqlite3XPrintf(&str, " SUBQUERY 0x%p", pItem->pSelect);
|
||||
}else{
|
||||
sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
|
||||
}
|
||||
@@ -214,7 +213,8 @@ int sqlite3WhereExplainOneScan(
|
||||
}
|
||||
#endif
|
||||
zMsg = sqlite3StrAccumFinish(&str);
|
||||
ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
|
||||
ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
|
||||
pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -118,10 +118,10 @@ do_execsql_test analyze3-1.1.x {
|
||||
#
|
||||
do_eqp_test analyze3-1.1.2 {
|
||||
SELECT sum(y) FROM t1 WHERE x>200 AND x<300
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
|
||||
do_eqp_test analyze3-1.1.3 {
|
||||
SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
# 2017-06-26: Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
|
||||
# the use of bound parameters by STAT4
|
||||
@@ -131,27 +131,27 @@ unset -nocomplain l
|
||||
unset -nocomplain u
|
||||
do_eqp_test analyze3-1.1.3.100 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
|
||||
set l 200
|
||||
set u 300
|
||||
do_eqp_test analyze3-1.1.3.101 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
|
||||
set l 0
|
||||
set u 1100
|
||||
do_eqp_test analyze3-1.1.3.102 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
db cache flush
|
||||
sqlite3_db_config db ENABLE_QPSG 1
|
||||
do_eqp_test analyze3-1.1.3.103 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
|
||||
db cache flush
|
||||
sqlite3_db_config db ENABLE_QPSG 0
|
||||
do_eqp_test analyze3-1.1.3.104 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
do_test analyze3-1.1.4 {
|
||||
sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
|
||||
@@ -201,10 +201,10 @@ do_execsql_test analyze3-2.1.x {
|
||||
} {200 990}
|
||||
do_eqp_test analyze3-1.2.2 {
|
||||
SELECT sum(y) FROM t2 WHERE x>1 AND x<2
|
||||
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
|
||||
} {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}
|
||||
do_eqp_test analyze3-1.2.3 {
|
||||
SELECT sum(y) FROM t2 WHERE x>0 AND x<99
|
||||
} {0 0 0 {SCAN TABLE t2}}
|
||||
} {SCAN TABLE t2}
|
||||
|
||||
do_test analyze3-1.2.4 {
|
||||
sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
|
||||
@@ -253,10 +253,10 @@ do_execsql_test analyze3-1.3.x {
|
||||
} {99 1000}
|
||||
do_eqp_test analyze3-1.3.2 {
|
||||
SELECT sum(y) FROM t3 WHERE x>200 AND x<300
|
||||
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}
|
||||
} {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}
|
||||
do_eqp_test analyze3-1.3.3 {
|
||||
SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
|
||||
} {0 0 0 {SCAN TABLE t3}}
|
||||
} {SCAN TABLE t3}
|
||||
|
||||
do_test analyze3-1.3.4 {
|
||||
sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
|
||||
@@ -308,10 +308,10 @@ do_test analyze3-2.1 {
|
||||
} {}
|
||||
do_eqp_test analyze3-2.2 {
|
||||
SELECT count(a) FROM t1 WHERE b LIKE 'a%'
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}
|
||||
do_eqp_test analyze3-2.3 {
|
||||
SELECT count(a) FROM t1 WHERE b LIKE '%a'
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
# Return the first argument if like_match_blobs is true (the default)
|
||||
# or the second argument if not
|
||||
@@ -698,11 +698,11 @@ do_test analyze3-6.1 {
|
||||
|
||||
do_eqp_test analyze3-6-3 {
|
||||
SELECT * FROM t1 WHERE a = 5 AND c = 13;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (c=?)}
|
||||
|
||||
do_eqp_test analyze3-6-2 {
|
||||
SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (c=?)}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 2015-04-20.
|
||||
|
||||
@@ -38,7 +38,7 @@ do_test analyze4-1.0 {
|
||||
|
||||
# Should choose the t1a index since it is more specific than t1b.
|
||||
db eval {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=5 AND b IS NULL}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
|
||||
# Verify that the t1b index shows that it does not narrow down the
|
||||
# search any at all.
|
||||
|
||||
@@ -61,14 +61,18 @@ do_test analyze6-1.0 {
|
||||
#
|
||||
do_test analyze6-1.1 {
|
||||
eqp {SELECT count(*) FROM ev, cat WHERE x=y}
|
||||
} {0 0 1 {SCAN TABLE cat USING COVERING INDEX catx} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?)}}
|
||||
} {/*SCAN TABLE cat USING COVERING INDEX catx*SEARCH TABLE ev USING COVERING INDEX evy (y=?)*/}
|
||||
|
||||
# The same plan is chosen regardless of the order of the tables in the
|
||||
# FROM clause.
|
||||
#
|
||||
do_test analyze6-1.2 {
|
||||
eqp {SELECT count(*) FROM cat, ev WHERE x=y}
|
||||
} {0 0 0 {SCAN TABLE cat USING COVERING INDEX catx} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?)}}
|
||||
do_eqp_test analyze6-1.2 {
|
||||
SELECT count(*) FROM cat, ev WHERE x=y
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE cat USING COVERING INDEX catx
|
||||
`--SEARCH TABLE ev USING COVERING INDEX evy (y=?)
|
||||
}
|
||||
|
||||
|
||||
# Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30
|
||||
@@ -82,26 +86,26 @@ do_test analyze6-2.1 {
|
||||
ANALYZE;
|
||||
}
|
||||
eqp {SELECT * FROM t201 WHERE z=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/}
|
||||
do_test analyze6-2.2 {
|
||||
eqp {SELECT * FROM t201 WHERE y=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/}
|
||||
do_test analyze6-2.3 {
|
||||
eqp {SELECT * FROM t201 WHERE x=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/}
|
||||
do_test analyze6-2.4 {
|
||||
execsql {
|
||||
INSERT INTO t201 VALUES(1,2,3),(2,3,4),(3,4,5);
|
||||
ANALYZE t201;
|
||||
}
|
||||
eqp {SELECT * FROM t201 WHERE z=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/}
|
||||
do_test analyze6-2.5 {
|
||||
eqp {SELECT * FROM t201 WHERE y=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/}
|
||||
do_test analyze6-2.6 {
|
||||
eqp {SELECT * FROM t201 WHERE x=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/}
|
||||
do_test analyze6-2.7 {
|
||||
execsql {
|
||||
INSERT INTO t201 VALUES(4,5,7);
|
||||
@@ -111,12 +115,12 @@ do_test analyze6-2.7 {
|
||||
ANALYZE t201;
|
||||
}
|
||||
eqp {SELECT * FROM t201 WHERE z=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/}
|
||||
do_test analyze6-2.8 {
|
||||
eqp {SELECT * FROM t201 WHERE y=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/}
|
||||
do_test analyze6-2.9 {
|
||||
eqp {SELECT * FROM t201 WHERE x=5}
|
||||
} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
|
||||
} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -37,13 +37,13 @@ do_test analyze7-1.0 {
|
||||
WHERE value BETWEEN 1 AND 256;
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;
|
||||
}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test analyze7-1.1 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
do_test analyze7-1.2 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
|
||||
|
||||
# Run an analyze on one of the three indices. Verify that this
|
||||
# effects the row-count estimate on the one query that uses that
|
||||
@@ -53,20 +53,20 @@ do_test analyze7-2.0 {
|
||||
execsql {ANALYZE t1a;}
|
||||
db cache flush
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test analyze7-2.1 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
do_test analyze7-2.2 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
|
||||
|
||||
# Verify that since the query planner now things that t1a is more
|
||||
# selective than t1b, it prefers to use t1a.
|
||||
#
|
||||
do_test analyze7-2.3 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
|
||||
# Run an analysis on another of the three indices. Verify that this
|
||||
# new analysis works and does not disrupt the previous analysis.
|
||||
@@ -75,40 +75,40 @@ do_test analyze7-3.0 {
|
||||
execsql {ANALYZE t1cd;}
|
||||
db cache flush;
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test analyze7-3.1 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
do_test analyze7-3.2.1 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
|
||||
ifcapable stat4||stat3 {
|
||||
# If ENABLE_STAT4 is defined, SQLite comes up with a different estimated
|
||||
# row count for (c=2) than it does for (c=?).
|
||||
do_test analyze7-3.2.2 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
|
||||
} else {
|
||||
# If ENABLE_STAT4 is not defined, the expected row count for (c=2) is the
|
||||
# same as that for (c=?).
|
||||
do_test analyze7-3.2.3 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
|
||||
}
|
||||
do_test analyze7-3.3 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
|
||||
ifcapable {!stat4 && !stat3} {
|
||||
do_test analyze7-3.4 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
do_test analyze7-3.5 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
}
|
||||
do_test analyze7-3.6 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)*/}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -61,25 +61,25 @@ do_test 1.0 {
|
||||
#
|
||||
do_test 1.1 {
|
||||
eqp {SELECT * FROM t1 WHERE a=100 AND b=55}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
do_test 1.2 {
|
||||
eqp {SELECT * FROM t1 WHERE a=99 AND b=55}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test 1.3 {
|
||||
eqp {SELECT * FROM t1 WHERE a=101 AND b=55}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test 1.4 {
|
||||
eqp {SELECT * FROM t1 WHERE a=100 AND b=56}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
do_test 1.5 {
|
||||
eqp {SELECT * FROM t1 WHERE a=99 AND b=56}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test 1.6 {
|
||||
eqp {SELECT * FROM t1 WHERE a=101 AND b=56}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test 2.1 {
|
||||
eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)*/}
|
||||
|
||||
# There are many more values of c between 0 and 100000 than there are
|
||||
# between 800000 and 900000. So t1c is more selective for the latter
|
||||
@@ -99,17 +99,17 @@ do_execsql_test 3.0 {
|
||||
} {50 376 32}
|
||||
do_test 3.1 {
|
||||
eqp {SELECT * FROM t1 WHERE b BETWEEN 30 AND 34 AND c BETWEEN 0 AND 100000}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)*/}
|
||||
do_test 3.2 {
|
||||
eqp {SELECT * FROM t1
|
||||
WHERE b BETWEEN 30 AND 34 AND c BETWEEN 800000 AND 900000}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)*/}
|
||||
do_test 3.3 {
|
||||
eqp {SELECT * FROM t1 WHERE a=100 AND c BETWEEN 0 AND 100000}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
do_test 3.4 {
|
||||
eqp {SELECT * FROM t1
|
||||
WHERE a=100 AND c BETWEEN 800000 AND 900000}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)*/}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -987,7 +987,8 @@ do_eqp_test 21.3 {
|
||||
reset_db
|
||||
do_execsql_test 22.0 {
|
||||
CREATE TABLE t3(a, b, c, d, PRIMARY KEY(a, b)) WITHOUT ROWID;
|
||||
}
|
||||
SELECT * FROM t3;
|
||||
} {}
|
||||
do_execsql_test 22.1 {
|
||||
WITH r(x) AS (
|
||||
SELECT 1
|
||||
@@ -1055,15 +1056,11 @@ do_eqp_test 23.1 {
|
||||
-- Formerly used index i41. But i41 is not a covering index whereas
|
||||
-- the PRIMARY KEY is a covering index, and so as of 2017-10-15, the
|
||||
-- PRIMARY KEY is preferred.
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t4 USING PRIMARY KEY (c=? AND b=? AND a<?)}
|
||||
}
|
||||
} {SEARCH TABLE t4 USING PRIMARY KEY (c=? AND b=? AND a<?)}
|
||||
do_eqp_test 23.2 {
|
||||
SELECT * FROM t4 WHERE
|
||||
(e=1 AND b='xyz' AND c='zyx' AND a<'JJJ') AND f<300
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t4 USING INDEX i42 (f<?)}
|
||||
}
|
||||
} {SEARCH TABLE t4 USING INDEX i42 (f<?)}
|
||||
|
||||
do_execsql_test 24.0 {
|
||||
CREATE TABLE t5(c, d, b, e, a, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
|
||||
@@ -1108,33 +1105,26 @@ ifcapable stat4&&cte {
|
||||
|
||||
# Term (b<?) is estimated at 25%. Better than (a<30) but not as
|
||||
# good as (a<20).
|
||||
do_eqp_test 25.2.1 { SELECT * FROM t6 WHERE a<30 AND b<? } {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX bb (b<?)}
|
||||
}
|
||||
do_eqp_test 25.2.2 { SELECT * FROM t6 WHERE a<20 AND b<? } {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX aa (a<?)}
|
||||
}
|
||||
do_eqp_test 25.2.1 { SELECT * FROM t6 WHERE a<30 AND b<? } \
|
||||
{SEARCH TABLE t6 USING INDEX bb (b<?)}
|
||||
do_eqp_test 25.2.2 { SELECT * FROM t6 WHERE a<20 AND b<? } \
|
||||
{SEARCH TABLE t6 USING INDEX aa (a<?)}
|
||||
|
||||
# Term (b BETWEEN ? AND ?) is estimated at 1/64.
|
||||
do_eqp_test 25.3.1 {
|
||||
SELECT * FROM t6 WHERE a BETWEEN 5 AND 10 AND b BETWEEN ? AND ?
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
|
||||
|
||||
# Term (b BETWEEN ? AND 60) is estimated to return roughly 15 rows -
|
||||
# 60 from (b<=60) multiplied by 0.25 for the b>=? term. Better than
|
||||
# (a<20) but not as good as (a<10).
|
||||
do_eqp_test 25.4.1 {
|
||||
SELECT * FROM t6 WHERE a < 10 AND (b BETWEEN ? AND 60)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX aa (a<?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX aa (a<?)}
|
||||
|
||||
do_eqp_test 25.4.2 {
|
||||
SELECT * FROM t6 WHERE a < 20 AND (b BETWEEN ? AND 60)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -1190,9 +1180,7 @@ do_execsql_test 26.1.3 {
|
||||
#
|
||||
do_eqp_test 26.1.4 {
|
||||
SELECT * FROM t1 WHERE x = 10000 AND y < 50 AND z = 444;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z=?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX t1z (z=?)}
|
||||
|
||||
|
||||
# This test - 26.2.* - tests that another manifestation of the same problem
|
||||
@@ -1241,9 +1229,7 @@ do_execsql_test 26.2.1 {
|
||||
|
||||
do_eqp_test 26.2.2 {
|
||||
SELECT * FROM t1 WHERE x='B' AND y>25 AND z=?;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -136,10 +136,10 @@ foreach {tn analyze_cmd} {
|
||||
|
||||
do_eqp_test 1.$tn.2.5 {
|
||||
SELECT * FROM t1 WHERE b = 31 AND c = 0;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b=?)}
|
||||
do_eqp_test 1.$tn.2.6 {
|
||||
SELECT * FROM t1 WHERE b = 125 AND c = 16;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c=?)}
|
||||
|
||||
do_execsql_test 1.$tn.3.1 {
|
||||
SELECT count(*) FROM t1 WHERE b BETWEEN 0 AND 50
|
||||
@@ -156,31 +156,31 @@ foreach {tn analyze_cmd} {
|
||||
|
||||
do_eqp_test 1.$tn.3.5 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN 0 AND 50 AND c BETWEEN 0 AND 50
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.6 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN 75 AND 125 AND c BETWEEN 75 AND 125
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.7 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN +0 AND +50 AND c BETWEEN +0 AND +50
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.8 {
|
||||
SELECT * FROM t1
|
||||
WHERE b BETWEEN cast('0' AS int) AND cast('50.0' AS real)
|
||||
AND c BETWEEN cast('0' AS numeric) AND cast('50.0' AS real)
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.9 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN +75 AND +125 AND c BETWEEN +75 AND +125
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.10 {
|
||||
SELECT * FROM t1
|
||||
WHERE b BETWEEN cast('75' AS int) AND cast('125.0' AS real)
|
||||
AND c BETWEEN cast('75' AS numeric) AND cast('125.0' AS real)
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -63,9 +63,7 @@ do_test 1.1 {
|
||||
#
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM t1 WHERE a=3001 AND c=150;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
|
||||
|
||||
do_test 1.3 {
|
||||
execsql { DELETE FROM sqlite_stat1 }
|
||||
@@ -80,9 +78,7 @@ do_test 1.3 {
|
||||
#
|
||||
do_eqp_test 1.4 {
|
||||
SELECT * FROM t1 WHERE a=3001 AND c=150;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1_ab (a=?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX t1_ab (a=?)}
|
||||
|
||||
do_test 1.5 {
|
||||
execsql {
|
||||
@@ -93,9 +89,7 @@ do_test 1.5 {
|
||||
|
||||
do_eqp_test 1.6 {
|
||||
SELECT * FROM t1 WHERE a=13 AND c=150;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
|
||||
|
||||
do_test 1.7 {
|
||||
execsql { DELETE FROM sqlite_stat1 }
|
||||
@@ -108,8 +102,6 @@ do_test 1.7 {
|
||||
# gets this right, even without stat1 data.
|
||||
do_eqp_test 1.8 {
|
||||
SELECT * FROM t1 WHERE a=13 AND c=150;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -62,7 +62,7 @@ foreach {tn where idx} {
|
||||
11 "x = nullif('19', 0) AND y = nullif('4', 0)" {t1y (y=?)}
|
||||
12 "x = nullif('4', 0) AND y = nullif('19', 0)" {t1y (y=?)}
|
||||
} {
|
||||
set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
|
||||
set res "SEARCH TABLE t1 USING INDEX $idx"
|
||||
do_eqp_test 1.$tn "SELECT * FROM t1 WHERE $where" $res
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ foreach {tn where idx} {
|
||||
3 "x = nondet4() AND y = nondet19()" {t1y (y=?)}
|
||||
4 "x = nondet19() AND y = nondet4()" {t1y (y=?)}
|
||||
} {
|
||||
set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
|
||||
set res "SEARCH TABLE t1 USING INDEX $idx"
|
||||
do_eqp_test 3.$tn "SELECT * FROM t1 WHERE $where" $res
|
||||
}
|
||||
|
||||
|
||||
@@ -177,35 +177,36 @@ do_execsql_test autoindex1-500 {
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t501',null,'1000000');
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t502',null,'1000');
|
||||
ANALYZE sqlite_master;
|
||||
EXPLAIN QUERY PLAN
|
||||
}
|
||||
do_eqp_test autoindex1-500.1 {
|
||||
SELECT b FROM t501
|
||||
WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {EXECUTE LIST SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t502}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--LIST SUBQUERY
|
||||
`--SCAN TABLE t502
|
||||
}
|
||||
do_execsql_test autoindex1-501 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test autoindex1-501 {
|
||||
SELECT b FROM t501
|
||||
WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t501}
|
||||
0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1}
|
||||
1 0 0 {SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t501
|
||||
`--CORRELATED LIST SUBQUERY
|
||||
`--SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)
|
||||
}
|
||||
do_execsql_test autoindex1-502 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test autoindex1-502 {
|
||||
SELECT b FROM t501
|
||||
WHERE t501.a=123
|
||||
AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t502}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--CORRELATED LIST SUBQUERY
|
||||
`--SCAN TABLE t502
|
||||
}
|
||||
|
||||
|
||||
# The following code checks a performance regression reported on the
|
||||
# mailing list on 2010-10-19. The problem is that the nRowEst field
|
||||
# of ephermeral tables was not being initialized correctly and so no
|
||||
@@ -257,7 +258,8 @@ do_execsql_test autoindex1-600 {
|
||||
ON sheep (originating_flock);
|
||||
CREATE INDEX sheep_reg_flock_index
|
||||
ON sheep (registering_flock);
|
||||
EXPLAIN QUERY PLAN
|
||||
}
|
||||
do_eqp_test autoindex1-600a {
|
||||
SELECT x.sheep_no, x.registering_flock, x.date_of_registration
|
||||
FROM sheep x LEFT JOIN
|
||||
(SELECT s.sheep_no, prev.flock_no, prev.owner_person_id,
|
||||
@@ -274,21 +276,26 @@ do_execsql_test autoindex1-600 {
|
||||
WHERE y.sheep_no IS NULL
|
||||
ORDER BY x.registering_flock;
|
||||
} {
|
||||
1 0 0 {SCAN TABLE sheep AS s}
|
||||
1 1 1 {SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?)}
|
||||
1 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
|
||||
2 0 0 {SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?)}
|
||||
0 0 0 {SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index}
|
||||
0 1 1 {SEARCH SUBQUERY 1 AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| |--SCAN TABLE sheep AS s
|
||||
| |--SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?)
|
||||
| `--CORRELATED SCALAR SUBQUERY
|
||||
| `--SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?)
|
||||
|--SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index
|
||||
`--SEARCH SUBQUERY xxxxxx AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)
|
||||
}
|
||||
|
||||
|
||||
do_execsql_test autoindex1-700 {
|
||||
CREATE TABLE t5(a, b, c);
|
||||
EXPLAIN QUERY PLAN SELECT a FROM t5 WHERE b=10 ORDER BY c;
|
||||
}
|
||||
do_eqp_test autoindex1-700a {
|
||||
SELECT a FROM t5 WHERE b=10 ORDER BY c;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t5}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t5
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
# The following checks a performance issue reported on the sqlite-dev
|
||||
|
||||
@@ -84,8 +84,9 @@ do_execsql_test 210 {
|
||||
do_eqp_test 220 {
|
||||
select count(*) from u, v where u.b = v.b and v.e > 34;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE v USING INDEX ve (e>?)}
|
||||
0 1 0 {SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE v USING INDEX ve (e>?)
|
||||
`--SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ do_execsql_test autoindex5-1.0 {
|
||||
# The following query should use an automatic index for the view
|
||||
# in FROM clause of the subquery of the second result column.
|
||||
#
|
||||
do_execsql_test autoindex5-1.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test autoindex5-1.1 {
|
||||
SELECT
|
||||
st.bug_name,
|
||||
(SELECT ALL debian_cve.bug FROM debian_cve
|
||||
@@ -103,7 +102,7 @@ do_execsql_test autoindex5-1.1 {
|
||||
AND ( sp.release = 'sid' OR sp.release = 'stretch' OR sp.release = 'jessie'
|
||||
OR sp.release = 'wheezy' OR sp.release = 'squeeze' )
|
||||
ORDER BY sp.name, st.bug_name, sp.release, sp.subrelease;
|
||||
} {/SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX .bug_name=/}
|
||||
} {SEARCH SUBQUERY * USING AUTOMATIC COVERING INDEX (bug_name=?)}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that ticket [8a2adec1] has been fixed.
|
||||
|
||||
@@ -51,15 +51,11 @@ do_execsql_test 1.0 {
|
||||
|
||||
do_eqp_test 1.1 {
|
||||
SELECT * FROM x1 WHERE a = 'abc'
|
||||
} {
|
||||
0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
|
||||
}
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM x1 WHERE a IN ('abc', 'def');
|
||||
} {
|
||||
0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
|
||||
}
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -144,21 +140,24 @@ foreach {tn mode} {
|
||||
} {1 4}
|
||||
|
||||
set plan(use) {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
set plan(omit) {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
set plan(use2) {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 2.2.$mode.6 {
|
||||
SELECT rowid FROM t1 WHERE a IN ('one', 'four') ORDER BY +rowid
|
||||
} $plan($mode)
|
||||
} [string map {"\n " "\n"} $plan($mode)]
|
||||
}
|
||||
|
||||
# 2016-04-09.
|
||||
|
||||
@@ -89,40 +89,40 @@ do_execsql_test 1.0 {
|
||||
|
||||
do_eqp_test 1.1 {
|
||||
SELECT * FROM t1 WHERE a='abc'
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
|
||||
}
|
||||
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM t1 WHERE a='abc' AND b='def'
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=? AND b=?)}
|
||||
}
|
||||
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=? AND b=?)}
|
||||
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM t1 WHERE a='abc' AND a='def'
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
|
||||
}
|
||||
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
|
||||
|
||||
do_eqp_test 1.4 {
|
||||
SELECT * FROM t1,t2 WHERE c=a
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:}
|
||||
0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
|
||||
`--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
|
||||
}
|
||||
|
||||
do_eqp_test 1.5 {
|
||||
SELECT * FROM t1, t2 CROSS JOIN t3 WHERE t2.c = +t1.b AND t3.e=t2.d
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:}
|
||||
0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)}
|
||||
0 2 2 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
|
||||
|--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
|
||||
`--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)
|
||||
}
|
||||
|
||||
do_eqp_test 1.6 {
|
||||
SELECT * FROM t1, t2, t3 WHERE t2.c = +t1.b AND t3.e = t2.d
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:}
|
||||
0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)}
|
||||
0 2 2 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
|
||||
|--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
|
||||
`--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)
|
||||
}
|
||||
|
||||
do_execsql_test 1.7.1 {
|
||||
@@ -132,10 +132,11 @@ do_eqp_test 1.7.2 {
|
||||
SELECT * FROM x1 CROSS JOIN t1, t2, t3
|
||||
WHERE t1.a = t2.c AND t1.b = t3.e
|
||||
} {
|
||||
0 0 0 {SCAN TABLE x1}
|
||||
0 1 1 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:}
|
||||
0 2 2 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)}
|
||||
0 3 3 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE x1
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
|
||||
|--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
|
||||
`--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -79,28 +79,26 @@ do_execsql_test 1.0 {
|
||||
|
||||
do_eqp_test 1.1 {
|
||||
SELECT * FROM t1 WHERE a LIKE 'abc';
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
|
||||
}
|
||||
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM t1 WHERE a = 'abc';
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
|
||||
}
|
||||
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
|
||||
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM t1 WHERE a = 'abc' OR b = 'def';
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?
|
||||
`--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
|
||||
}
|
||||
|
||||
do_eqp_test 1.4 {
|
||||
SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def';
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?
|
||||
`--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
|
||||
}
|
||||
|
||||
do_execsql_test 1.5 {
|
||||
@@ -147,10 +145,11 @@ ifcapable !icu {
|
||||
|
||||
do_eqp_test 2.2 {
|
||||
SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)}
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)
|
||||
`--SEARCH TABLE t2 USING INDEX t2y (y=?)
|
||||
}]
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -92,13 +92,13 @@ for {set i 0} {$i < 9} {incr i} {
|
||||
SELECT * FROM t$t AS o WHERE
|
||||
NOT EXISTS( SELECT * FROM t$t AS i WHERE a=o.a AND +b=o.b AND +c=o.c )
|
||||
ORDER BY b, c;
|
||||
" "
|
||||
0 0 0 {SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1}
|
||||
0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1}
|
||||
1 0 0 {SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
"
|
||||
" [string map {"\n " "\n"} "
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1
|
||||
`--CORRELATED SCALAR SUBQUERY
|
||||
`--SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)
|
||||
"]
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ do_execsql_test 1.1 {
|
||||
do_eqp_test 1.2 {
|
||||
SELECT e FROM t3, t4 WHERE b=c ORDER BY b, d;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t3 USING COVERING INDEX i3}
|
||||
0 1 1 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t3 USING COVERING INDEX i3
|
||||
`--SEARCH TABLE t4 USING INDEX i4 (c=?)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +39,7 @@ do_execsql_test 2.1 {
|
||||
# if the index is a non-covering index.
|
||||
do_eqp_test 2.2 {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING INDEX i1}
|
||||
}
|
||||
} {SCAN TABLE t1 USING INDEX i1}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
CREATE TABLE t5(a INTEGER PRIMARY KEY,b,c,d,e,f,g);
|
||||
@@ -57,10 +56,11 @@ do_eqp_test 3.2 {
|
||||
WHERE b IS NULL OR c IS NULL OR d IS NULL
|
||||
ORDER BY a;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t5 USING INDEX t5b (b=?)}
|
||||
0 0 0 {SEARCH TABLE t5 USING INDEX t5c (c=?)}
|
||||
0 0 0 {SEARCH TABLE t5 USING INDEX t5d (d=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t5 USING INDEX t5b (b=?)
|
||||
|--SEARCH TABLE t5 USING INDEX t5c (c=?)
|
||||
|--SEARCH TABLE t5 USING INDEX t5d (d=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -79,14 +79,11 @@ do_execsql_test 4.1 {
|
||||
}
|
||||
do_eqp_test 4.2 {
|
||||
SELECT * FROM t1 WHERE likelihood(a=?, 0.014) AND b BETWEEN ? AND ?;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
|
||||
do_eqp_test 4.3 {
|
||||
SELECT * FROM t1 WHERE likelihood(a=?, 0.016) AND b BETWEEN ? AND ?;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b>? AND b<?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (b>? AND b<?)}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -100,15 +97,17 @@ do_execsql_test 5.1 {
|
||||
do_eqp_test 5.2 {
|
||||
SELECT * FROM t2 ORDER BY x, y;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t2 USING INDEX t2i1}
|
||||
0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2 USING INDEX t2i1
|
||||
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 5.3 {
|
||||
SELECT * FROM t2 WHERE x BETWEEN ? AND ? ORDER BY rowid;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2i1 (x>? AND x<?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t2 USING INDEX t2i1 (x>? AND x<?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
# where7.test, where8.test:
|
||||
@@ -122,9 +121,10 @@ do_execsql_test 6.1 {
|
||||
do_eqp_test 6.2 {
|
||||
SELECT a FROM t3 WHERE (b BETWEEN 2 AND 4) OR c=100 ORDER BY a
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)}
|
||||
0 0 0 {SEARCH TABLE t3 USING INDEX t3i2 (c=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)
|
||||
|--SEARCH TABLE t3 USING INDEX t3i2 (c=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -145,9 +145,10 @@ do_eqp_test 7.2 {
|
||||
WHERE (b>=950 AND b<=1010) OR (b IS NULL AND c NOT NULL)
|
||||
ORDER BY a
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)
|
||||
|--SEARCH TABLE t1 USING INDEX t1b (b=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 7.3 {
|
||||
@@ -155,15 +156,11 @@ do_eqp_test 7.3 {
|
||||
WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
|
||||
OR (b NOT NULL AND c IS NULL AND d NOT NULL)
|
||||
OR (b NOT NULL AND c NOT NULL AND d IS NULL)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
do_eqp_test 7.4 {
|
||||
SELECT rowid FROM t1 WHERE (+b IS NULL AND c NOT NULL) OR c IS NULL
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -194,10 +191,11 @@ do_eqp_test 8.2 {
|
||||
AND unlikely(composer.cid=track.cid)
|
||||
AND unlikely(album.aid=track.aid);
|
||||
} {
|
||||
0 0 2 {SCAN TABLE track}
|
||||
0 1 0 {SEARCH TABLE album USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 2 1 {SEARCH TABLE composer USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE track
|
||||
|--SEARCH TABLE album USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|--SEARCH TABLE composer USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--USE TEMP B-TREE FOR DISTINCT
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -263,27 +261,19 @@ ifcapable stat4 {
|
||||
|
||||
do_eqp_test 10.3 {
|
||||
SELECT rowid FROM t6 WHERE a=0 AND c=0
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
|
||||
|
||||
do_eqp_test 10.4 {
|
||||
SELECT rowid FROM t6 WHERE a=0 AND b='xyz' AND c=0
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
|
||||
|
||||
do_eqp_test 10.5 {
|
||||
SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND c=0
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX t6i1 (a=?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX t6i1 (a=?)}
|
||||
|
||||
do_eqp_test 10.6 {
|
||||
SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND b='xyz' AND c=0
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t6 USING INDEX t6i1 (a=? AND b=?)}
|
||||
}
|
||||
} {SEARCH TABLE t6 USING INDEX t6i1 (a=? AND b=?)}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -109,16 +109,11 @@ do_execsql_test 5.1.0 "
|
||||
|
||||
do_eqp_test 5.1.1 {
|
||||
SELECT * FROM t1 ORDER BY c1, c2;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
}
|
||||
} {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
|
||||
do_eqp_test 5.1.2 {
|
||||
SELECT * FROM t2 ORDER BY c1, c2;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX i2}
|
||||
}
|
||||
|
||||
} {SCAN TABLE t2 USING COVERING INDEX i2}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1385,13 +1385,13 @@ do_execsql_test 4.10.0 {
|
||||
}
|
||||
do_createtable_tests 4.10 {
|
||||
1 "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 5"
|
||||
{0 0 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?)}}
|
||||
{/*SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?)*/}
|
||||
|
||||
2 "EXPLAIN QUERY PLAN SELECT * FROM t2 ORDER BY b, c"
|
||||
{0 0 0 {SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1}}
|
||||
{/*SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1*/}
|
||||
|
||||
3 "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE b=10 AND c>10"
|
||||
{0 0 0 {SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?)}}
|
||||
{/*SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?)*/}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-45493-35653 A CHECK constraint may be attached to a
|
||||
|
||||
434
test/eqp.test
434
test/eqp.test
@@ -43,78 +43,108 @@ do_execsql_test 1.1 {
|
||||
do_eqp_test 1.2 {
|
||||
SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
0 0 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)}
|
||||
0 1 0 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t1 USING INDEX i1 (a=?)
|
||||
|--SEARCH TABLE t1 USING INDEX i2 (b=?)
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t2}
|
||||
0 1 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
0 1 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2
|
||||
|--SEARCH TABLE t1 USING INDEX i1 (a=?)
|
||||
`--SEARCH TABLE t1 USING INDEX i2 (b=?)
|
||||
}
|
||||
do_eqp_test 1.3 {
|
||||
SELECT a FROM t1 ORDER BY a
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t1 USING COVERING INDEX i1
|
||||
}
|
||||
do_eqp_test 1.4 {
|
||||
SELECT a FROM t1 ORDER BY +a
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING COVERING INDEX i1
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_eqp_test 1.5 {
|
||||
SELECT a FROM t1 WHERE a=4
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)
|
||||
}
|
||||
do_eqp_test 1.6 {
|
||||
SELECT DISTINCT count(*) FROM t3 GROUP BY a;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t3}
|
||||
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t3
|
||||
|--USE TEMP B-TREE FOR GROUP BY
|
||||
`--USE TEMP B-TREE FOR DISTINCT
|
||||
}
|
||||
|
||||
do_eqp_test 1.7 {
|
||||
SELECT * FROM t3 JOIN (SELECT 1)
|
||||
} {
|
||||
0 0 1 {SCAN SUBQUERY 1}
|
||||
0 1 0 {SCAN TABLE t3}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--SCAN CONSTANT ROW
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SCAN TABLE t3
|
||||
}
|
||||
do_eqp_test 1.8 {
|
||||
SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2)
|
||||
} {
|
||||
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
|
||||
0 0 1 {SCAN SUBQUERY 1}
|
||||
0 1 0 {SCAN TABLE t3}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | `--SCAN CONSTANT ROW
|
||||
| `--UNION USING TEMP B-TREE
|
||||
| `--SCAN CONSTANT ROW
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SCAN TABLE t3
|
||||
}
|
||||
do_eqp_test 1.9 {
|
||||
SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17)
|
||||
} {
|
||||
3 0 0 {SCAN TABLE t3}
|
||||
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)}
|
||||
0 0 1 {SCAN SUBQUERY 1}
|
||||
0 1 0 {SCAN TABLE t3}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | `--SCAN CONSTANT ROW
|
||||
| `--EXCEPT USING TEMP B-TREE
|
||||
| `--SCAN TABLE t3
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SCAN TABLE t3
|
||||
}
|
||||
do_eqp_test 1.10 {
|
||||
SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17)
|
||||
} {
|
||||
3 0 0 {SCAN TABLE t3}
|
||||
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)}
|
||||
0 0 1 {SCAN SUBQUERY 1}
|
||||
0 1 0 {SCAN TABLE t3}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | `--SCAN CONSTANT ROW
|
||||
| `--INTERSECT USING TEMP B-TREE
|
||||
| `--SCAN TABLE t3
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SCAN TABLE t3
|
||||
}
|
||||
|
||||
do_eqp_test 1.11 {
|
||||
SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17)
|
||||
} {
|
||||
3 0 0 {SCAN TABLE t3}
|
||||
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)}
|
||||
0 0 1 {SCAN SUBQUERY 1}
|
||||
0 1 0 {SCAN TABLE t3}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | `--SCAN CONSTANT ROW
|
||||
| `--UNION ALL
|
||||
| `--SCAN TABLE t3
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SCAN TABLE t3
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -129,48 +159,58 @@ do_execsql_test 2.1 {
|
||||
}
|
||||
|
||||
det 2.2.1 "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
|--USE TEMP B-TREE FOR GROUP BY
|
||||
|--USE TEMP B-TREE FOR DISTINCT
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
det 2.2.2 "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1" {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
|--USE TEMP B-TREE FOR DISTINCT
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
det 2.2.3 "SELECT DISTINCT * FROM t1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--USE TEMP B-TREE FOR DISTINCT
|
||||
}
|
||||
det 2.2.4 "SELECT DISTINCT * FROM t1, t2" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE t2}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
|--SCAN TABLE t2
|
||||
`--USE TEMP B-TREE FOR DISTINCT
|
||||
}
|
||||
det 2.2.5 "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE t2}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
|--SCAN TABLE t2
|
||||
|--USE TEMP B-TREE FOR DISTINCT
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
det 2.2.6 "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x" {
|
||||
0 0 1 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
0 1 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
det 2.3.1 "SELECT max(x) FROM t2" {
|
||||
0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t2 USING COVERING INDEX t2i1
|
||||
}
|
||||
det 2.3.2 "SELECT min(x) FROM t2" {
|
||||
0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t2 USING COVERING INDEX t2i1
|
||||
}
|
||||
det 2.3.3 "SELECT min(x), max(x) FROM t2" {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
}
|
||||
|
||||
det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
|
||||
0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
|
||||
@@ -181,40 +221,46 @@ det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
|
||||
do_eqp_test 3.1.1 {
|
||||
SELECT (SELECT x FROM t1 AS sub) FROM t1;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE SCALAR SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t1 AS sub}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCALAR SUBQUERY
|
||||
`--SCAN TABLE t1 AS sub
|
||||
}
|
||||
do_eqp_test 3.1.2 {
|
||||
SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE SCALAR SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t1 AS sub}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCALAR SUBQUERY
|
||||
`--SCAN TABLE t1 AS sub
|
||||
}
|
||||
do_eqp_test 3.1.3 {
|
||||
SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE SCALAR SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t1 AS sub}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCALAR SUBQUERY
|
||||
|--SCAN TABLE t1 AS sub
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_eqp_test 3.1.4 {
|
||||
SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE SCALAR SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCALAR SUBQUERY
|
||||
`--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
}
|
||||
|
||||
det 3.2.1 {
|
||||
SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
0 0 0 {SCAN SUBQUERY 1}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--CO-ROUTINE xxxxxx
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
det 3.2.2 {
|
||||
SELECT * FROM
|
||||
@@ -222,34 +268,40 @@ det 3.2.2 {
|
||||
(SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2
|
||||
ORDER BY x2.y LIMIT 5
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
|
||||
0 0 0 {SCAN SUBQUERY 1 AS x1}
|
||||
0 1 1 {SCAN SUBQUERY 2 AS x2}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--SCAN TABLE t2 USING INDEX t2i1
|
||||
|--SCAN SUBQUERY xxxxxx AS x1
|
||||
|--SCAN SUBQUERY xxxxxx AS x2
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
det 3.3.1 {
|
||||
SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE LIST SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--LIST SUBQUERY
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
det 3.3.2 {
|
||||
SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--CORRELATED LIST SUBQUERY
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
det 3.3.3 {
|
||||
SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--CORRELATED SCALAR SUBQUERY
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -258,119 +310,158 @@ det 3.3.3 {
|
||||
do_eqp_test 4.1.1 {
|
||||
SELECT * FROM t1 UNION ALL SELECT * FROM t2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
2 0 0 {SCAN TABLE t2}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
|
||||
QUERY PLAN
|
||||
`--COMPOUND QUERY
|
||||
|--LEFT-MOST SUBQUERY
|
||||
| `--SCAN TABLE t1
|
||||
`--UNION ALL
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
do_eqp_test 4.1.2 {
|
||||
SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2}
|
||||
2 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION ALL)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_eqp_test 4.1.3 {
|
||||
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2}
|
||||
2 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)}
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_eqp_test 4.1.4 {
|
||||
SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2}
|
||||
2 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)}
|
||||
QUERY PLAN
|
||||
`--MERGE (INTERSECT)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_eqp_test 4.1.5 {
|
||||
SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2}
|
||||
2 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
|
||||
QUERY PLAN
|
||||
`--MERGE (EXCEPT)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 4.2.2 {
|
||||
SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 1
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION ALL)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
`--SCAN TABLE t2 USING INDEX t2i1
|
||||
}
|
||||
do_eqp_test 4.2.3 {
|
||||
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 1
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
|
||||
2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)}
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2 USING INDEX t2i1
|
||||
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
}
|
||||
do_eqp_test 4.2.4 {
|
||||
SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
|
||||
2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)}
|
||||
QUERY PLAN
|
||||
`--MERGE (INTERSECT)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2 USING INDEX t2i1
|
||||
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
}
|
||||
do_eqp_test 4.2.5 {
|
||||
SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
1 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
|
||||
2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
|
||||
QUERY PLAN
|
||||
`--MERGE (EXCEPT)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t1
|
||||
| `--USE TEMP B-TREE FOR ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t2 USING INDEX t2i1
|
||||
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
}
|
||||
|
||||
do_eqp_test 4.3.1 {
|
||||
SELECT x FROM t1 UNION SELECT x FROM t2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t1}
|
||||
2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
|
||||
QUERY PLAN
|
||||
`--COMPOUND QUERY
|
||||
|--LEFT-MOST SUBQUERY
|
||||
| `--SCAN TABLE t1
|
||||
`--UNION USING TEMP B-TREE
|
||||
`--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
}
|
||||
|
||||
do_eqp_test 4.3.2 {
|
||||
SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1
|
||||
} {
|
||||
2 0 0 {SCAN TABLE t1}
|
||||
3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
|
||||
4 0 0 {SCAN TABLE t1}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)}
|
||||
QUERY PLAN
|
||||
`--COMPOUND QUERY
|
||||
|--LEFT-MOST SUBQUERY
|
||||
| `--SCAN TABLE t1
|
||||
|--UNION USING TEMP B-TREE
|
||||
| `--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
`--UNION USING TEMP B-TREE
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
do_eqp_test 4.3.3 {
|
||||
SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1
|
||||
} {
|
||||
2 0 0 {SCAN TABLE t1}
|
||||
2 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
|
||||
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION)}
|
||||
4 0 0 {SCAN TABLE t1}
|
||||
4 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 4 (UNION)}
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION)
|
||||
|--LEFT
|
||||
| `--MERGE (UNION)
|
||||
| |--LEFT
|
||||
| | |--SCAN TABLE t1
|
||||
| | `--USE TEMP B-TREE FOR ORDER BY
|
||||
| `--RIGHT
|
||||
| `--SCAN TABLE t2 USING COVERING INDEX t2i1
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t1
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
if 0 {
|
||||
#-------------------------------------------------------------------------
|
||||
# This next block of tests verifies that the examples on the
|
||||
# lang_explain.html page are correct.
|
||||
#
|
||||
drop_all_tables
|
||||
|
||||
# EVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
|
||||
# XVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
|
||||
# FROM t1 WHERE a=1;
|
||||
# 0|0|0|SCAN TABLE t1
|
||||
#
|
||||
@@ -379,7 +470,7 @@ det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
|
||||
# XVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
|
||||
# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
|
||||
# 0|0|0|SEARCH TABLE t1 USING INDEX i1
|
||||
#
|
||||
@@ -388,7 +479,7 @@ det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
|
||||
# XVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
|
||||
# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
|
||||
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
||||
#
|
||||
@@ -397,7 +488,7 @@ det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" {
|
||||
0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2;
|
||||
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
|
||||
# 0|1|1|SCAN TABLE t2
|
||||
@@ -408,7 +499,7 @@ det 5.4.1 "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
|
||||
0 1 1 {SCAN TABLE t2}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2;
|
||||
# 0|0|1|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
|
||||
# 0|1|0|SCAN TABLE t2
|
||||
@@ -418,7 +509,7 @@ det 5.5 "SELECT t1.a, t2.c FROM t2, t1 WHERE t1.a=1 AND t1.b>2" {
|
||||
0 1 0 {SCAN TABLE t2}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
|
||||
# XVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
|
||||
# sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
|
||||
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
||||
# 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
|
||||
@@ -429,7 +520,7 @@ det 5.6.1 "SELECT a, b FROM t1 WHERE a=1 OR b=2" {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT c, d FROM t2 ORDER BY c;
|
||||
# 0|0|0|SCAN TABLE t2
|
||||
# 0|0|0|USE TEMP B-TREE FOR ORDER BY
|
||||
@@ -439,7 +530,7 @@ det 5.7 "SELECT c, d FROM t2 ORDER BY c" {
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
|
||||
# XVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
|
||||
# sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
|
||||
# 0|0|0|SCAN TABLE t2 USING INDEX i4
|
||||
#
|
||||
@@ -448,7 +539,7 @@ det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
|
||||
0 0 0 {SCAN TABLE t2 USING INDEX i4}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
|
||||
# XVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
|
||||
# (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
|
||||
# 0|0|0|SCAN TABLE t2
|
||||
# 0|0|0|EXECUTE SCALAR SUBQUERY 1
|
||||
@@ -466,7 +557,7 @@ det 5.9 {
|
||||
2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
|
||||
# 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
|
||||
# 0|0|0|SCAN SUBQUERY 1
|
||||
@@ -480,7 +571,7 @@ det 5.10 {
|
||||
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
|
||||
# 0|0|0|SEARCH TABLE t2 USING INDEX i4 (c=?)
|
||||
# 0|1|1|SCAN TABLE t1
|
||||
@@ -490,7 +581,7 @@ det 5.11 "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1" {
|
||||
0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT a FROM t1 UNION SELECT c FROM t2;
|
||||
# 1|0|0|SCAN TABLE t1
|
||||
# 2|0|0|SCAN TABLE t2
|
||||
@@ -502,7 +593,7 @@ det 5.12 "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2" {
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
|
||||
# XVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
|
||||
# SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1;
|
||||
# 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
|
||||
# 2|0|0|SCAN TABLE t2 2|0|0|USE TEMP B-TREE FOR ORDER BY
|
||||
@@ -515,7 +606,6 @@ det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
|
||||
}
|
||||
|
||||
|
||||
if {![nonzero_reserved_bytes]} {
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests - eqp-6.* - test that the example C code on
|
||||
@@ -557,6 +647,7 @@ if {![nonzero_reserved_bytes]} {
|
||||
0 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests - eqp-7.* - test that queries that use the OP_Count
|
||||
@@ -571,11 +662,13 @@ do_execsql_test 7.0 {
|
||||
}
|
||||
|
||||
det 7.1 "SELECT count(*) FROM t1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
det 7.2 "SELECT count(*) FROM t2" {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t2 USING COVERING INDEX i1
|
||||
}
|
||||
|
||||
do_execsql_test 7.3 {
|
||||
@@ -593,11 +686,13 @@ db close
|
||||
sqlite3 db test.db
|
||||
|
||||
det 7.4 "SELECT count(*) FROM t1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
det 7.5 "SELECT count(*) FROM t2" {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t2 USING COVERING INDEX i1
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -612,31 +707,38 @@ do_execsql_test 8.0 {
|
||||
}
|
||||
|
||||
det 8.1.1 "SELECT * FROM t2" {
|
||||
0 0 0 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
|
||||
det 8.1.2 "SELECT * FROM t2 WHERE rowid=?" {
|
||||
0 0 0 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
det 8.1.3 "SELECT count(*) FROM t2" {
|
||||
0 0 0 {SCAN TABLE t2}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t2
|
||||
}
|
||||
|
||||
det 8.2.1 "SELECT * FROM t1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
det 8.2.2 "SELECT * FROM t1 WHERE b=?" {
|
||||
0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=?)}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t1 USING PRIMARY KEY (b=?)
|
||||
}
|
||||
|
||||
det 8.2.3 "SELECT * FROM t1 WHERE b=? AND c=?" {
|
||||
0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=? AND c=?)}
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t1 USING PRIMARY KEY (b=? AND c=?)
|
||||
}
|
||||
|
||||
det 8.2.4 "SELECT count(*) FROM t1" {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -105,10 +105,10 @@ db func rec rec
|
||||
#
|
||||
do_execsql_test 2.1.1.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term='braid'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 1:*/}
|
||||
do_execsql_test 2.1.1.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term='braid'
|
||||
} {0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}}
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
|
||||
|
||||
# Now show that using "term='braid'" means the virtual table returns
|
||||
# only 1 row to SQLite, but "+term='braid'" means all 19 are returned.
|
||||
@@ -154,24 +154,24 @@ do_execsql_test 2.1.5 { SELECT * FROM terms WHERE term=NULL } {}
|
||||
|
||||
do_execsql_test 2.2.1.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term>'brain'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 2:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 2:*/}
|
||||
do_execsql_test 2.2.1.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term>'brain'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
|
||||
|
||||
do_execsql_test 2.2.1.3 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term<'brain'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 4:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 4:*/}
|
||||
do_execsql_test 2.2.1.4 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term<'brain'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
|
||||
|
||||
do_execsql_test 2.2.1.5 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term BETWEEN 'brags' AND 'brain'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 6:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 6:*/}
|
||||
do_execsql_test 2.2.1.6 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term BETWEEN 'brags' AND 'brain'
|
||||
} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} }
|
||||
} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
|
||||
|
||||
do_test 2.2.2.1 {
|
||||
set cnt 0
|
||||
@@ -335,8 +335,9 @@ foreach {tn sort orderby} {
|
||||
9 1 "ORDER BY occurrences DESC"
|
||||
} {
|
||||
|
||||
set res [list 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}]
|
||||
if {$sort} { lappend res 0 0 0 {USE TEMP B-TREE FOR ORDER BY} }
|
||||
set res {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}
|
||||
if {$sort} { append res {*USE TEMP B-TREE FOR ORDER BY} }
|
||||
set res "/*$res*/"
|
||||
|
||||
set sql "SELECT * FROM terms $orderby"
|
||||
do_execsql_test 2.3.1.$tn "EXPLAIN QUERY PLAN $sql" $res
|
||||
@@ -403,39 +404,48 @@ do_execsql_test 4.1 {
|
||||
INSERT INTO x3 SELECT term FROM terms WHERE col = '*';
|
||||
}
|
||||
|
||||
proc do_plansql_test {tn sql r} {
|
||||
uplevel do_execsql_test $tn [list "EXPLAIN QUERY PLAN $sql ; $sql"] [list $r]
|
||||
proc do_plansql_test {tn sql r1 r2} {
|
||||
do_eqp_test $tn.eqp $sql $r1
|
||||
do_execsql_test $tn $sql $r2
|
||||
}
|
||||
|
||||
do_plansql_test 4.2 {
|
||||
SELECT y FROM x2, terms WHERE y = term AND col = '*'
|
||||
} {
|
||||
0 0 0 {SCAN TABLE x2}
|
||||
0 1 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE x2
|
||||
`--SCAN TABLE terms VIRTUAL TABLE INDEX 1:
|
||||
} {
|
||||
a b c d e f g h i j k l
|
||||
}
|
||||
|
||||
do_plansql_test 4.3 {
|
||||
SELECT y FROM terms, x2 WHERE y = term AND col = '*'
|
||||
} {
|
||||
0 0 1 {SCAN TABLE x2}
|
||||
0 1 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE x2
|
||||
`--SCAN TABLE terms VIRTUAL TABLE INDEX 1:
|
||||
} {
|
||||
a b c d e f g h i j k l
|
||||
}
|
||||
|
||||
do_plansql_test 4.4 {
|
||||
SELECT y FROM x3, terms WHERE y = term AND col = '*'
|
||||
} {
|
||||
0 0 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}
|
||||
0 1 0 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE terms VIRTUAL TABLE INDEX 0:
|
||||
`--SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)
|
||||
} {
|
||||
a b c d e f g h i j k l
|
||||
}
|
||||
|
||||
do_plansql_test 4.5 {
|
||||
SELECT y FROM terms, x3 WHERE y = term AND occurrences>1 AND col = '*'
|
||||
} {
|
||||
0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}
|
||||
0 1 1 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE terms VIRTUAL TABLE INDEX 0:
|
||||
`--SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)
|
||||
} {
|
||||
a k l
|
||||
}
|
||||
|
||||
|
||||
@@ -96,9 +96,11 @@ do_eqp_test 4.2 {
|
||||
) AS rr ON t4.rowid=rr.docid
|
||||
WHERE t4.y = ?;
|
||||
} {
|
||||
1 0 0 {SCAN TABLE ft4 VIRTUAL TABLE INDEX 3:}
|
||||
0 0 0 {SCAN TABLE t4}
|
||||
0 1 1 {SEARCH SUBQUERY 1 AS rr USING AUTOMATIC COVERING INDEX (docid=?)}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--SCAN TABLE ft4 VIRTUAL TABLE INDEX 3:
|
||||
|--SCAN TABLE t4
|
||||
`--SEARCH SUBQUERY xxxxxx AS rr USING AUTOMATIC COVERING INDEX (docid=?)
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -118,26 +118,30 @@ do_test fts3query-4.1 {
|
||||
do_eqp_test fts3query-4.2 {
|
||||
SELECT t1.number FROM t1, ft WHERE t1.number=ft.rowid ORDER BY t1.date
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
0 1 1 {SCAN TABLE ft VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING COVERING INDEX i1
|
||||
`--SCAN TABLE ft VIRTUAL TABLE INDEX 1:
|
||||
}
|
||||
do_eqp_test fts3query-4.3 {
|
||||
SELECT t1.number FROM ft, t1 WHERE t1.number=ft.rowid ORDER BY t1.date
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
0 1 0 {SCAN TABLE ft VIRTUAL TABLE INDEX 1:}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING COVERING INDEX i1
|
||||
`--SCAN TABLE ft VIRTUAL TABLE INDEX 1:
|
||||
}
|
||||
do_eqp_test fts3query-4.4 {
|
||||
SELECT t1.number FROM t1, bt WHERE t1.number=bt.rowid ORDER BY t1.date
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
0 1 1 {SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING COVERING INDEX i1
|
||||
`--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
do_eqp_test fts3query-4.5 {
|
||||
SELECT t1.number FROM bt, t1 WHERE t1.number=bt.rowid ORDER BY t1.date
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
0 1 0 {SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING COVERING INDEX i1
|
||||
`--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -318,8 +318,9 @@ do_execsql_test index6-8.0 {
|
||||
do_eqp_test index6-8.1 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t8a}
|
||||
0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t8a
|
||||
`--SEARCH TABLE t8b USING INDEX i8c (y=?)
|
||||
}
|
||||
|
||||
do_execsql_test index6-8.2 {
|
||||
|
||||
@@ -321,9 +321,8 @@ do_execsql_test index7-6.3 {
|
||||
}
|
||||
do_eqp_test index7-6.4 {
|
||||
SELECT * FROM v4 WHERE d='xyz' AND c='def'
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
|
||||
}
|
||||
} {SEARCH TABLE t4 USING INDEX i4 (c=?)}
|
||||
|
||||
do_catchsql_test index7-6.5 {
|
||||
CREATE INDEX t5a ON t5(a) WHERE a=#1;
|
||||
} {1 {near "#1": syntax error}}
|
||||
|
||||
@@ -40,17 +40,18 @@ proc EQP {sql} {
|
||||
|
||||
# These tests are to check that "EXPLAIN QUERY PLAN" is working as expected.
|
||||
#
|
||||
do_execsql_test indexedby-1.2 {
|
||||
EXPLAIN QUERY PLAN select * from t1 WHERE a = 10;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-1.3 {
|
||||
EXPLAIN QUERY PLAN select * from t1 ;
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
do_execsql_test indexedby-1.4 {
|
||||
EXPLAIN QUERY PLAN select * from t1, t2 WHERE c = 10;
|
||||
do_eqp_test indexedby-1.2 {
|
||||
select * from t1 WHERE a = 10;
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-1.3 {
|
||||
select * from t1 ;
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test indexedby-1.4 {
|
||||
select * from t1, t2 WHERE c = 10;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE t2 USING INDEX i3 (c=?)}
|
||||
0 1 0 {SCAN TABLE t1}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t2 USING INDEX i3 (c=?)
|
||||
`--SCAN TABLE t1
|
||||
}
|
||||
|
||||
# Parser tests. Test that an INDEXED BY or NOT INDEX clause can be
|
||||
@@ -115,25 +116,23 @@ do_test indexedby-2.7 {
|
||||
# the rowid can still be used to look up entries even when "NOT INDEXED"
|
||||
# is specified.
|
||||
#
|
||||
do_execsql_test indexedby-3.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a = 'one' AND b = 'two'
|
||||
do_eqp_test indexedby-3.1 {
|
||||
SELECT * FROM t1 WHERE a = 'one' AND b = 'two'
|
||||
} {/SEARCH TABLE t1 USING INDEX/}
|
||||
do_execsql_test indexedby-3.1.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
do_execsql_test indexedby-3.1.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE rowid=1
|
||||
do_eqp_test indexedby-3.1.1 {
|
||||
SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test indexedby-3.1.2 {
|
||||
SELECT * FROM t1 NOT INDEXED WHERE rowid=1
|
||||
} {/SEARCH TABLE t1 USING INTEGER PRIMARY KEY .rowid=/}
|
||||
|
||||
|
||||
do_execsql_test indexedby-3.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test indexedby-3.2 {
|
||||
SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-3.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-3.3 {
|
||||
SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
|
||||
do_test indexedby-3.4 {
|
||||
catchsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' }
|
||||
} {1 {no query solution}}
|
||||
@@ -147,14 +146,12 @@ do_test indexedby-3.7 {
|
||||
catchsql { SELECT * FROM t1 INDEXED BY i1 ORDER BY a }
|
||||
} {0 {}}
|
||||
|
||||
do_execsql_test indexedby-3.8 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test indexedby-3.8 {
|
||||
SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 ORDER BY e
|
||||
} {0 0 0 {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1}}
|
||||
do_execsql_test indexedby-3.9 {
|
||||
EXPLAIN QUERY PLAN
|
||||
} {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1}
|
||||
do_eqp_test indexedby-3.9 {
|
||||
SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE e = 10
|
||||
} {0 0 0 {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)}}
|
||||
} {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)}
|
||||
do_test indexedby-3.10 {
|
||||
catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE f = 10 }
|
||||
} {1 {no query solution}}
|
||||
@@ -164,17 +161,19 @@ do_test indexedby-3.11 {
|
||||
|
||||
# Tests for multiple table cases.
|
||||
#
|
||||
do_execsql_test indexedby-4.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE a = c
|
||||
do_eqp_test indexedby-4.1 {
|
||||
SELECT * FROM t1, t2 WHERE a = c
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SEARCH TABLE t2 USING INDEX i3 (c=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SEARCH TABLE t2 USING INDEX i3 (c=?)
|
||||
}
|
||||
do_execsql_test indexedby-4.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c
|
||||
do_eqp_test indexedby-4.2 {
|
||||
SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t2}
|
||||
0 1 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2
|
||||
`--SEARCH TABLE t1 USING INDEX i1 (a=?)
|
||||
}
|
||||
do_test indexedby-4.3 {
|
||||
catchsql {
|
||||
@@ -194,10 +193,10 @@ do_test indexedby-4.4 {
|
||||
do_execsql_test indexedby-5.1 {
|
||||
CREATE VIEW v2 AS SELECT * FROM t1 INDEXED BY i1 WHERE a > 5;
|
||||
EXPLAIN QUERY PLAN SELECT * FROM v2
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/}
|
||||
do_execsql_test indexedby-5.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM v2 WHERE b = 10
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
|
||||
} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/}
|
||||
do_test indexedby-5.3 {
|
||||
execsql { DROP INDEX i1 }
|
||||
catchsql { SELECT * FROM v2 }
|
||||
@@ -216,12 +215,12 @@ do_test indexedby-5.5 {
|
||||
|
||||
# Test that "NOT INDEXED" may use the rowid index, but not others.
|
||||
#
|
||||
do_execsql_test indexedby-6.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 10 ORDER BY rowid
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
|
||||
do_execsql_test indexedby-6.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
do_eqp_test indexedby-6.1 {
|
||||
SELECT * FROM t1 WHERE b = 10 ORDER BY rowid
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
|
||||
do_eqp_test indexedby-6.2 {
|
||||
SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
# EVIDENCE-OF: R-40297-14464 The INDEXED BY phrase forces the SQLite
|
||||
# query planner to use a particular named index on a DELETE, SELECT, or
|
||||
@@ -229,44 +228,42 @@ do_execsql_test indexedby-6.2 {
|
||||
#
|
||||
# Test that "INDEXED BY" can be used in a DELETE statement.
|
||||
#
|
||||
do_execsql_test indexedby-7.1 {
|
||||
EXPLAIN QUERY PLAN DELETE FROM t1 WHERE a = 5
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-7.2 {
|
||||
EXPLAIN QUERY PLAN DELETE FROM t1 NOT INDEXED WHERE a = 5
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
do_execsql_test indexedby-7.3 {
|
||||
EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-7.4 {
|
||||
EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-7.5 {
|
||||
EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
|
||||
do_eqp_test indexedby-7.1 {
|
||||
DELETE FROM t1 WHERE a = 5
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-7.2 {
|
||||
DELETE FROM t1 NOT INDEXED WHERE a = 5
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test indexedby-7.3 {
|
||||
DELETE FROM t1 INDEXED BY i1 WHERE a = 5
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-7.4 {
|
||||
DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-7.5 {
|
||||
DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
|
||||
do_test indexedby-7.6 {
|
||||
catchsql { DELETE FROM t1 INDEXED BY i2 WHERE a = 5}
|
||||
} {1 {no query solution}}
|
||||
|
||||
# Test that "INDEXED BY" can be used in an UPDATE statement.
|
||||
#
|
||||
do_execsql_test indexedby-8.1 {
|
||||
EXPLAIN QUERY PLAN UPDATE t1 SET rowid=rowid+1 WHERE a = 5
|
||||
} {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-8.2 {
|
||||
EXPLAIN QUERY PLAN UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
do_execsql_test indexedby-8.3 {
|
||||
EXPLAIN QUERY PLAN UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5
|
||||
} {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-8.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test indexedby-8.1 {
|
||||
UPDATE t1 SET rowid=rowid+1 WHERE a = 5
|
||||
} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-8.2 {
|
||||
UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test indexedby-8.3 {
|
||||
UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5
|
||||
} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-8.4 {
|
||||
UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 AND b = 10
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
do_execsql_test indexedby-8.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test indexedby-8.5 {
|
||||
UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5 AND b = 10
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
|
||||
do_test indexedby-8.6 {
|
||||
catchsql { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5}
|
||||
} {1 {no query solution}}
|
||||
@@ -341,7 +338,7 @@ do_execsql_test 11.4 {
|
||||
} {1 1 3}
|
||||
do_eqp_test 11.5 {
|
||||
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
|
||||
} {0 0 0 {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}}
|
||||
} {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}
|
||||
|
||||
do_execsql_test 11.6 {
|
||||
CREATE TABLE x2(c INTEGER PRIMARY KEY, a, b TEXT);
|
||||
@@ -362,7 +359,7 @@ do_execsql_test 11.9 {
|
||||
} {1 1 3}
|
||||
do_eqp_test 11.10 {
|
||||
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
|
||||
} {0 0 0 {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}}
|
||||
} {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check INDEXED BY works (throws an exception) with partial indexes that
|
||||
|
||||
@@ -91,10 +91,11 @@ ifcapable json1 {
|
||||
WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL
|
||||
GROUP BY json_extract(x, '$.b') COLLATE nocase
|
||||
ORDER BY json_extract(x, '$.b') COLLATE nocase;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t2}
|
||||
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t2
|
||||
`--USE TEMP B-TREE FOR GROUP BY
|
||||
}]
|
||||
|
||||
do_execsql_test 3.3.2 {
|
||||
CREATE INDEX i3 ON t3(json_extract(x, '$.a'), json_extract(x, '$.b'));
|
||||
@@ -105,10 +106,11 @@ ifcapable json1 {
|
||||
WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL
|
||||
GROUP BY json_extract(x, '$.b') COLLATE nocase
|
||||
ORDER BY json_extract(x, '$.b') COLLATE nocase;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t3 USING INDEX i3 (<expr>=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t3 USING INDEX i3 (<expr>=?)
|
||||
`--USE TEMP B-TREE FOR GROUP BY
|
||||
}]
|
||||
}
|
||||
|
||||
do_execsql_test 3.4.0 {
|
||||
|
||||
@@ -112,15 +112,17 @@ do_execsql_test 3.0 {
|
||||
do_eqp_test 3.1 {
|
||||
SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_1 USING (k3);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_eqp_test 3.2 {
|
||||
SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_2 USING (k3);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -158,15 +160,17 @@ do_execsql_test 4.1.4 {
|
||||
do_eqp_test 4.1.5 {
|
||||
SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE c1}
|
||||
0 1 1 {SEARCH TABLE c2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 2 2 {SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE c1
|
||||
|--SEARCH TABLE c2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
do_eqp_test 4.1.6 {
|
||||
SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE c1}
|
||||
0 1 2 {SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE c1
|
||||
`--SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_execsql_test 4.2.0 {
|
||||
@@ -203,15 +207,17 @@ do_execsql_test 4.2.4 {
|
||||
do_eqp_test 4.2.5 {
|
||||
SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE c1}
|
||||
0 1 1 {SEARCH TABLE c2 USING INDEX sqlite_autoindex_c2_1 (k=?)}
|
||||
0 2 2 {SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE c1
|
||||
|--SEARCH TABLE c2 USING INDEX sqlite_autoindex_c2_1 (k=?)
|
||||
`--SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)
|
||||
}
|
||||
do_eqp_test 4.2.6 {
|
||||
SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE c1}
|
||||
0 1 2 {SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE c1
|
||||
`--SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)
|
||||
}
|
||||
|
||||
# 2017-11-23 (Thanksgiving day)
|
||||
@@ -245,14 +251,11 @@ do_execsql_test 5.0 {
|
||||
}
|
||||
do_eqp_test 5.1 {
|
||||
SELECT s1.a FROM s1 left join s2 using (a);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE s1}
|
||||
}
|
||||
} {SCAN TABLE s1}
|
||||
|
||||
do_eqp_test 5.2 {
|
||||
SELECT s1.a FROM s1 left join s3 using (a);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE s1}
|
||||
}
|
||||
} {SCAN TABLE s1}
|
||||
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE u1(a INTEGER PRIMARY KEY, b, c);
|
||||
@@ -261,9 +264,7 @@ do_execsql_test 6.0 {
|
||||
}
|
||||
do_eqp_test 6.1 {
|
||||
SELECT u2.* FROM u2 LEFT JOIN u1 ON( u1.a=u2.a AND u1.b=u2.b AND u1.c=u2.c );
|
||||
} {
|
||||
0 0 0 {SCAN TABLE u2}
|
||||
}
|
||||
} {SCAN TABLE u2}
|
||||
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
|
||||
@@ -264,9 +264,10 @@ do_eqp_test 7.2 {
|
||||
t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL))
|
||||
);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)}
|
||||
0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
|--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
|
||||
`--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
|
||||
}
|
||||
|
||||
do_execsql_test 7.3 {
|
||||
@@ -285,9 +286,9 @@ do_execsql_test 7.3 {
|
||||
do_eqp_test 7.4 {
|
||||
SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t3}
|
||||
0 1 1 {SEARCH TABLE t4 USING INDEX t4xz (x=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t3
|
||||
`--SEARCH TABLE t4 USING INDEX t4xz (x=?)
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -121,10 +121,11 @@ do_execsql_test 6.0 {
|
||||
ifcapable stat4 {
|
||||
do_eqp_test 6.1 {
|
||||
SELECT DISTINCT c FROM t3 WHERE b BETWEEN '.xx..' AND '.xxxx';
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t3 USING INDEX i3 (ANY(a) AND b>? AND b<?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR DISTINCT}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t3 USING INDEX i3 (ANY(a) AND b>? AND b<?)
|
||||
`--USE TEMP B-TREE FOR DISTINCT
|
||||
}]
|
||||
}
|
||||
|
||||
do_faultsim_test 6 -faults oom* -body {
|
||||
|
||||
@@ -454,9 +454,12 @@ do_test 4.0 {
|
||||
|
||||
# No sorting of queries that omit the FROM clause.
|
||||
#
|
||||
do_execsql_test 5.0 {
|
||||
EXPLAIN QUERY PLAN SELECT 5 ORDER BY 1
|
||||
} {}
|
||||
do_eqp_test 5.0 {
|
||||
SELECT 5 ORDER BY 1
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SCAN CONSTANT ROW
|
||||
}
|
||||
do_execsql_test 5.1 {
|
||||
EXPLAIN QUERY PLAN SELECT 5 UNION ALL SELECT 3 ORDER BY 1
|
||||
} {~/B-TREE/}
|
||||
@@ -512,8 +515,9 @@ do_execsql_test 8.0 {
|
||||
do_eqp_test 8.1 {
|
||||
SELECT * FROM t1 ORDER BY a, b;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING INDEX i1}
|
||||
0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING INDEX i1
|
||||
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
}
|
||||
|
||||
do_execsql_test 8.2 {
|
||||
|
||||
@@ -101,7 +101,7 @@ do_rollback_test 2.2 -setup {
|
||||
#
|
||||
do_eqp_test 3.1 {
|
||||
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC;
|
||||
} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
|
||||
} {SCAN TABLE t1 USING INDEX i1}
|
||||
do_rollback_test 3.2 -setup {
|
||||
BEGIN;
|
||||
DELETE FROM t1 WHERE (i%2)==1;
|
||||
@@ -131,7 +131,7 @@ do_execsql_test 4.1 { UPDATE t1 SET h = $leader || h; }
|
||||
|
||||
do_eqp_test 4.2 {
|
||||
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC;
|
||||
} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
|
||||
} {SCAN TABLE t1 USING INDEX i1}
|
||||
do_rollback_test 4.3 -setup {
|
||||
BEGIN;
|
||||
DELETE FROM t1 WHERE (i%2)==1;
|
||||
|
||||
@@ -175,19 +175,19 @@ do_execsql_test 7.0 {
|
||||
|
||||
foreach {tn sql res eqp} {
|
||||
1 "SELECT * FROM xy WHERE (i, j) IS (2, 2)" {2 2 2}
|
||||
"0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)}"
|
||||
"SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)"
|
||||
|
||||
2 "SELECT * FROM xy WHERE (k, j) < (2, 3)" {1 1 1 2 2 2}
|
||||
"0 0 0 {SCAN TABLE xy}"
|
||||
"SCAN TABLE xy"
|
||||
|
||||
3 "SELECT * FROM xy WHERE (i, j) < (2, 3)" {1 1 1 2 2 2}
|
||||
"0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid<?)}"
|
||||
"SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid<?)"
|
||||
|
||||
4 "SELECT * FROM xy WHERE (i, j) > (2, 1)" {2 2 2 3 3 3 4 4 4}
|
||||
"0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}"
|
||||
"SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)"
|
||||
|
||||
5 "SELECT * FROM xy WHERE (i, j) > ('2', 1)" {2 2 2 3 3 3 4 4 4}
|
||||
"0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}"
|
||||
"SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)"
|
||||
|
||||
} {
|
||||
do_eqp_test 7.$tn.1 $sql $eqp
|
||||
|
||||
@@ -184,34 +184,33 @@ ifcapable stat4 {
|
||||
ANALYZE;
|
||||
}
|
||||
|
||||
do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)}
|
||||
}
|
||||
do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)}
|
||||
}
|
||||
do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)}
|
||||
}
|
||||
do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } \
|
||||
{SEARCH TABLE c1 USING INDEX c1cd (c=?)}
|
||||
|
||||
do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } \
|
||||
{SEARCH TABLE c1 USING INDEX c1cd (c=?)}
|
||||
|
||||
do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } \
|
||||
{SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)}
|
||||
|
||||
do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } \
|
||||
{SEARCH TABLE c1 USING INDEX c1cd (c>?)}
|
||||
|
||||
do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } \
|
||||
{SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
|
||||
do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } \
|
||||
{SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
|
||||
do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } \
|
||||
{SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
|
||||
do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } \
|
||||
{SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))}
|
||||
|
||||
do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } \
|
||||
{SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
|
||||
do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c>?)}
|
||||
}
|
||||
do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
}
|
||||
do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
}
|
||||
do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
}
|
||||
do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))}
|
||||
}
|
||||
do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } {
|
||||
0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
|
||||
}
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@@ -234,11 +233,12 @@ do_eqp_test 5.1 {
|
||||
(a, b) IN (SELECT x, y FROM d1) AND
|
||||
(c) IN (SELECT y FROM d1)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)}
|
||||
0 0 0 {EXECUTE LIST SUBQUERY 1}
|
||||
1 0 0 {SCAN TABLE d1}
|
||||
0 0 0 {EXECUTE LIST SUBQUERY 2}
|
||||
2 0 0 {SCAN TABLE d1}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)
|
||||
|--LIST SUBQUERY
|
||||
| `--SCAN TABLE d1
|
||||
`--LIST SUBQUERY
|
||||
`--SCAN TABLE d1
|
||||
}
|
||||
|
||||
do_execsql_test 6.0 {
|
||||
@@ -249,31 +249,23 @@ do_execsql_test 6.0 {
|
||||
|
||||
do_eqp_test 6.1 {
|
||||
SELECT * FROM e1 WHERE (a, b) > (?, ?)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))}
|
||||
}
|
||||
} {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))}
|
||||
|
||||
do_eqp_test 6.2 {
|
||||
SELECT * FROM e1 WHERE (a, b) < (?, ?)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))}
|
||||
}
|
||||
} {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))}
|
||||
|
||||
do_eqp_test 6.3 {
|
||||
SELECT * FROM e1 WHERE c = ? AND (d, e) > (?, ?)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))}
|
||||
}
|
||||
} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))}
|
||||
|
||||
do_eqp_test 6.4 {
|
||||
SELECT * FROM e1 WHERE c = ? AND (d, e) < (?, ?)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))}
|
||||
}
|
||||
} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))}
|
||||
|
||||
do_eqp_test 6.5 {
|
||||
SELECT * FROM e1 WHERE (d, e) BETWEEN (?, ?) AND (?, ?) AND c = ?
|
||||
} {
|
||||
0 0 0
|
||||
{SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))}
|
||||
}
|
||||
} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ do_scanstatus_test 5.2.2 {
|
||||
|
||||
do_eqp_test 5.3.1 {
|
||||
SELECT count(*) FROM t2 WHERE y = 'j';
|
||||
} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}}
|
||||
} {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
|
||||
do_execsql_test 5.3.2 {
|
||||
SELECT count(*) FROM t2 WHERE y = 'j';
|
||||
} {19}
|
||||
@@ -340,8 +340,9 @@ do_scanstatus_test 5.3.3 {
|
||||
do_eqp_test 5.4.1 {
|
||||
SELECT count(*) FROM t1, t2 WHERE y = c;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 USING COVERING INDEX t1bc}
|
||||
0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1 USING COVERING INDEX t1bc
|
||||
`--SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)
|
||||
}
|
||||
do_execsql_test 5.4.2 {
|
||||
SELECT count(*) FROM t1, t2 WHERE y = c;
|
||||
@@ -356,8 +357,9 @@ do_scanstatus_test 5.4.3 {
|
||||
do_eqp_test 5.5.1 {
|
||||
SELECT count(*) FROM t1, t3 WHERE y = c;
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t3}
|
||||
0 1 0 {SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t3
|
||||
`--SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)
|
||||
}
|
||||
do_execsql_test 5.5.2 {
|
||||
SELECT count(*) FROM t1, t3 WHERE y = c;
|
||||
|
||||
@@ -1336,11 +1336,14 @@ do_eqp_test 4.1.2 {
|
||||
SELECT a, b FROM t4 WHERE f()==f()
|
||||
ORDER BY 1,2
|
||||
} {
|
||||
1 0 0 {SCAN TABLE t5 USING INDEX i2}
|
||||
1 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
2 0 0 {SCAN TABLE t4 USING INDEX i1}
|
||||
2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
|
||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION ALL)
|
||||
|--LEFT
|
||||
| |--SCAN TABLE t5 USING INDEX i2
|
||||
| `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
`--RIGHT
|
||||
|--SCAN TABLE t4 USING INDEX i1
|
||||
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
|
||||
}
|
||||
|
||||
do_execsql_test 4.1.3 {
|
||||
|
||||
@@ -169,6 +169,6 @@ do_execsql_test selectD-4.1 {
|
||||
WHERE x1.d>5
|
||||
GROUP BY x1.d) AS x2
|
||||
ON t41.b=x2.d;
|
||||
} {/.*SEARCH SUBQUERY 1 AS x2 USING AUTOMATIC.*/}
|
||||
} {/*SEARCH SUBQUERY 0x* AS x2 USING AUTOMATIC*/}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -199,7 +199,7 @@ do_test skipscan2-3.2 {
|
||||
} {}
|
||||
do_eqp_test skipscan2-3.3eqp {
|
||||
SELECT * FROM t3 WHERE b=42;
|
||||
} {0 0 0 {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)}}
|
||||
} {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -179,22 +179,13 @@ do_execsql_test 3.0 {
|
||||
#
|
||||
do_eqp_test 3.1 {
|
||||
SELECT * FROM t3 WHERE a = ? AND c = ?
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t3 USING INDEX t3_a (a=?)}
|
||||
}
|
||||
} {SEARCH TABLE t3 USING INDEX t3_a (a=?)}
|
||||
|
||||
# The same query on table t2. This should use index "t2_a", for the
|
||||
# same reason. At one point though, it was mistakenly using a skip-scan.
|
||||
#
|
||||
do_eqp_test 3.2 {
|
||||
SELECT * FROM t2 WHERE a = ? AND c = ?
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2_a (a=?)}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
} {SEARCH TABLE t2 USING INDEX t2_a (a=?)}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -959,10 +959,81 @@ proc do_timed_execsql_test {testname sql {result {}}} {
|
||||
uplevel do_test [list $testname] [list "execsql_timed {$sql}"]\
|
||||
[list [list {*}$result]]
|
||||
}
|
||||
proc do_eqp_test {name sql res} {
|
||||
uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res]
|
||||
|
||||
# Run an EXPLAIN QUERY PLAN $sql in database "db". Then rewrite the output
|
||||
# as an ASCII-art graph and return a string that is that graph.
|
||||
#
|
||||
# Hexadecimal literals in the output text are converted into "xxxxxx" since those
|
||||
# literals are pointer values that might very from one run of the test to the
|
||||
# next, yet we want the output to be consistent.
|
||||
#
|
||||
proc query_plan_graph {sql} {
|
||||
db eval "EXPLAIN QUERY PLAN $sql" {
|
||||
set dx($id) $detail
|
||||
lappend cx($parent) $id
|
||||
}
|
||||
set a "\n QUERY PLAN\n"
|
||||
append a [append_graph " " dx cx 0]
|
||||
return [regsub -all { 0x[A-F0-9]+\y} $a { xxxxxx}]
|
||||
}
|
||||
|
||||
# Helper routine for [query_plan_graph SQL]:
|
||||
#
|
||||
# Output rows of the graph that are children of $level.
|
||||
#
|
||||
# prefix: Prepend to every output line
|
||||
#
|
||||
# dxname: Name of an array variable that stores text describe
|
||||
# The description for $id is $dx($id)
|
||||
#
|
||||
# cxname: Name of an array variable holding children of item.
|
||||
# Children of $id are $cx($id)
|
||||
#
|
||||
# level: Render all lines that are children of $level
|
||||
#
|
||||
proc append_graph {prefix dxname cxname level} {
|
||||
upvar $dxname dx $cxname cx
|
||||
set a ""
|
||||
set x $cx($level)
|
||||
set n [llength $x]
|
||||
for {set i 0} {$i<$n} {incr i} {
|
||||
set id [lindex $x $i]
|
||||
if {$i==$n-1} {
|
||||
set p1 "`--"
|
||||
set p2 " "
|
||||
} else {
|
||||
set p1 "|--"
|
||||
set p2 "| "
|
||||
}
|
||||
append a $prefix$p1$dx($id)\n
|
||||
if {[info exists cx($id)]} {
|
||||
append a [append_graph "$prefix$p2" dx cx $id]
|
||||
}
|
||||
}
|
||||
return $a
|
||||
}
|
||||
|
||||
# Do an EXPLAIN QUERY PLAN test on input $sql with expected results $res
|
||||
#
|
||||
# If $res begins with a "\s+QUERY PLAN\n" then it is assumed to be the
|
||||
# complete graph which must match the output of [query_plan_graph $sql]
|
||||
# exactly.
|
||||
#
|
||||
# If $res does not begin with "\s+QUERY PLAN\n" then take it is a string
|
||||
# that must be found somewhere in the query plan output.
|
||||
#
|
||||
proc do_eqp_test {name sql res} {
|
||||
if {[regexp {^\s+QUERY PLAN\n} $res]} {
|
||||
uplevel do_test $name [list [list query_plan_graph $sql]] [list $res]
|
||||
} else {
|
||||
if {[string index $res 0]!="/"} {
|
||||
set res "/*$res*/"
|
||||
}
|
||||
uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Usage: do_select_tests PREFIX ?SWITCHES? TESTLIST
|
||||
#
|
||||
|
||||
@@ -34,20 +34,17 @@ do_execsql_test 2.0 {
|
||||
CREATE UNIQUE INDEX t2y ON t2(y);
|
||||
}
|
||||
|
||||
do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2x}
|
||||
}
|
||||
do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } \
|
||||
{SCAN TABLE t2 USING COVERING INDEX t2x}
|
||||
|
||||
do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } {
|
||||
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2y}
|
||||
}
|
||||
do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } \
|
||||
{SCAN TABLE t2 USING COVERING INDEX t2y}
|
||||
|
||||
do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
|
||||
}
|
||||
do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } \
|
||||
{SEARCH TABLE t2 USING INDEX t2y (y=?)}
|
||||
|
||||
do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } \
|
||||
{SEARCH TABLE t2 USING INDEX t2x (x=?)}
|
||||
|
||||
do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x=?)}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -41,10 +41,8 @@ do_test tkt-78e04-1.3 {
|
||||
}
|
||||
} {}
|
||||
do_test tkt-78e04-1.4 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';
|
||||
}
|
||||
} {0 0 0 {SCAN TABLE USING COVERING INDEX i1}}
|
||||
db eval {EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';}
|
||||
} {/*SCAN TABLE USING COVERING INDEX i1*/}
|
||||
do_test tkt-78e04-1.5 {
|
||||
execsql {
|
||||
DROP TABLE "";
|
||||
@@ -57,12 +55,12 @@ do_test tkt-78e04-2.1 {
|
||||
CREATE INDEX "" ON t2(x);
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=5;
|
||||
}
|
||||
} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX (x=?)}}
|
||||
} {/*SEARCH TABLE t2 USING COVERING INDEX (x=?)*/}
|
||||
do_test tkt-78e04-2.2 {
|
||||
execsql {
|
||||
DROP INDEX "";
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=2;
|
||||
}
|
||||
} {0 0 0 {SCAN TABLE t2}}
|
||||
} {/*SCAN TABLE t2*/}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -32,41 +32,41 @@ do_execsql_test 1.1 {
|
||||
CREATE INDEX i1 ON t1(x, y);
|
||||
}
|
||||
|
||||
set idxscan {0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}}
|
||||
set tblscan {0 0 0 {SCAN TABLE t1}}
|
||||
set grpsort {0 0 0 {USE TEMP B-TREE FOR GROUP BY}}
|
||||
set sort {0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
|
||||
set idxscan {SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
set tblscan {SCAN TABLE t1}
|
||||
set grpsort {USE TEMP B-TREE FOR GROUP BY}
|
||||
set sort {USE TEMP B-TREE FOR ORDER BY}
|
||||
|
||||
foreach {tn q res eqp} [subst -nocommands {
|
||||
1 "SELECT * FROM t1 GROUP BY x, y ORDER BY x,y"
|
||||
{1 3 2 2 3 1} {$idxscan}
|
||||
|
||||
2 "SELECT * FROM t1 GROUP BY x, y ORDER BY x"
|
||||
{1 3 2 2 3 1} {$idxscan $sort}
|
||||
{1 3 2 2 3 1} {$idxscan*$sort}
|
||||
|
||||
3 "SELECT * FROM t1 GROUP BY y, x ORDER BY y, x"
|
||||
{3 1 2 2 1 3} {$idxscan $sort}
|
||||
{3 1 2 2 1 3} {$idxscan*$sort}
|
||||
|
||||
4 "SELECT * FROM t1 GROUP BY x ORDER BY x"
|
||||
{1 3 2 2 3 1} {$idxscan}
|
||||
|
||||
5 "SELECT * FROM t1 GROUP BY y ORDER BY y"
|
||||
{3 1 2 2 1 3} {$tblscan $grpsort}
|
||||
{3 1 2 2 1 3} {$tblscan*$grpsort}
|
||||
|
||||
6 "SELECT * FROM t1 GROUP BY y ORDER BY x"
|
||||
{1 3 2 2 3 1} {$tblscan $grpsort $sort}
|
||||
{1 3 2 2 3 1} {$tblscan*$grpsort*$sort}
|
||||
|
||||
7 "SELECT * FROM t1 GROUP BY x, y ORDER BY x, y DESC"
|
||||
{1 3 2 2 3 1} {$idxscan $sort}
|
||||
{1 3 2 2 3 1} {$idxscan*$sort}
|
||||
|
||||
8 "SELECT * FROM t1 GROUP BY x, y ORDER BY x DESC, y DESC"
|
||||
{3 1 2 2 1 3} {$idxscan $sort}
|
||||
{3 1 2 2 1 3} {$idxscan*$sort}
|
||||
|
||||
9 "SELECT * FROM t1 GROUP BY x, y ORDER BY x ASC, y ASC"
|
||||
{1 3 2 2 3 1} {$idxscan}
|
||||
|
||||
10 "SELECT * FROM t1 GROUP BY x, y ORDER BY x COLLATE nocase, y"
|
||||
{1 3 2 2 3 1} {$idxscan $sort}
|
||||
{1 3 2 2 3 1} {$idxscan*$sort}
|
||||
|
||||
}] {
|
||||
do_execsql_test 1.$tn.1 $q $res
|
||||
|
||||
@@ -34,35 +34,24 @@ do_test tkt3442-1.1 {
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
# Explain Query Plan
|
||||
#
|
||||
proc EQP {sql} {
|
||||
uplevel "execsql {EXPLAIN QUERY PLAN $sql}"
|
||||
}
|
||||
|
||||
|
||||
# These tests perform an EXPLAIN QUERY PLAN on both versions of the
|
||||
# SELECT referenced in ticket #3442 (both '5000' and "5000")
|
||||
# and verify that the query plan is the same.
|
||||
#
|
||||
ifcapable explain {
|
||||
do_test tkt3442-1.2 {
|
||||
EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; }
|
||||
} {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
|
||||
do_test tkt3442-1.3 {
|
||||
EQP { SELECT node FROM listhash WHERE id="5000" LIMIT 1; }
|
||||
} {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
|
||||
}
|
||||
do_eqp_test tkt3442-1.2 {
|
||||
SELECT node FROM listhash WHERE id='5000' LIMIT 1;
|
||||
} {SEARCH TABLE listhash USING INDEX ididx (id=?)}
|
||||
do_eqp_test tkt3442-1.3 {
|
||||
SELECT node FROM listhash WHERE id="5000" LIMIT 1;
|
||||
} {SEARCH TABLE listhash USING INDEX ididx (id=?)}
|
||||
|
||||
|
||||
# Some extra tests testing other permutations of 5000.
|
||||
#
|
||||
ifcapable explain {
|
||||
do_test tkt3442-1.4 {
|
||||
EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; }
|
||||
} {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
|
||||
}
|
||||
do_eqp_test tkt3442-1.4 {
|
||||
SELECT node FROM listhash WHERE id=5000 LIMIT 1;
|
||||
} {SEARCH TABLE listhash USING INDEX ididx (id=?)}
|
||||
|
||||
do_test tkt3442-1.5 {
|
||||
catchsql {
|
||||
SELECT node FROM listhash WHERE id=[5000] LIMIT 1;
|
||||
|
||||
@@ -165,7 +165,7 @@ do_test tpch01-1.1 {
|
||||
order by
|
||||
o_year;}]
|
||||
set ::eqpres
|
||||
} {/0 0 0 {SEARCH TABLE part USING INDEX bootleg_pti .P_TYPE=..} 0 1 2 {SEARCH TABLE lineitem USING INDEX lpki2 .L_PARTKEY=..}.*/}
|
||||
} {/*SEARCH TABLE part USING INDEX bootleg_pti *SEARCH TABLE lineitem USING INDEX lpki2*/}
|
||||
do_test tpch01-1.1b {
|
||||
set ::eqpres
|
||||
} {/.* customer .* nation AS n1 .*/}
|
||||
@@ -187,6 +187,14 @@ group by
|
||||
c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment
|
||||
order by
|
||||
revenue desc;
|
||||
} {0 0 1 {SEARCH TABLE orders USING INDEX odi (O_ORDERDATE>? AND O_ORDERDATE<?)} 0 1 0 {SEARCH TABLE customer USING INDEX cpki (C_CUSTKEY=?)} 0 2 3 {SEARCH TABLE nation USING INDEX npki (N_NATIONKEY=?)} 0 3 2 {SEARCH TABLE lineitem USING INDEX lpki (L_ORDERKEY=?)} 0 0 0 {USE TEMP B-TREE FOR GROUP BY} 0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE orders USING INDEX odi (O_ORDERDATE>? AND O_ORDERDATE<?)
|
||||
|--SEARCH TABLE customer USING INDEX cpki (C_CUSTKEY=?)
|
||||
|--SEARCH TABLE nation USING INDEX npki (N_NATIONKEY=?)
|
||||
|--SEARCH TABLE lineitem USING INDEX lpki (L_ORDERKEY=?)
|
||||
|--USE TEMP B-TREE FOR GROUP BY
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -40,28 +40,27 @@ foreach idxmode {ordered unordered} {
|
||||
sqlite3 db test.db
|
||||
foreach {tn sql r(ordered) r(unordered)} {
|
||||
1 "SELECT * FROM t1 ORDER BY a"
|
||||
{0 0 0 {SCAN TABLE t1 USING INDEX i1}}
|
||||
{0 0 0 {SCAN TABLE t1} 0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
|
||||
{SCAN TABLE t1 USING INDEX i1}
|
||||
{SCAN TABLE t1*USE TEMP B-TREE FOR ORDER BY}
|
||||
2 "SELECT * FROM t1 WHERE a > 100"
|
||||
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
|
||||
{0 0 0 {SCAN TABLE t1}}
|
||||
{SEARCH TABLE t1 USING INDEX i1 (a>?)}
|
||||
{SCAN TABLE t1}
|
||||
3 "SELECT * FROM t1 WHERE a = ? ORDER BY rowid"
|
||||
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
|
||||
{SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
{SEARCH TABLE t1 USING INDEX i1 (a=?)*USE TEMP B-TREE FOR ORDER BY}
|
||||
4 "SELECT max(a) FROM t1"
|
||||
{0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1}}
|
||||
{0 0 0 {SEARCH TABLE t1}}
|
||||
{SEARCH TABLE t1 USING COVERING INDEX i1}
|
||||
{SEARCH TABLE t1}
|
||||
5 "SELECT group_concat(b) FROM t1 GROUP BY a"
|
||||
{0 0 0 {SCAN TABLE t1 USING INDEX i1}}
|
||||
{0 0 0 {SCAN TABLE t1} 0 0 0 {USE TEMP B-TREE FOR GROUP BY}}
|
||||
{SCAN TABLE t1 USING INDEX i1}
|
||||
{SCAN TABLE t1*USE TEMP B-TREE FOR GROUP BY}
|
||||
|
||||
6 "SELECT * FROM t1 WHERE a = ?"
|
||||
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
{SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
{SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
7 "SELECT count(*) FROM t1"
|
||||
{0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}}
|
||||
{0 0 0 {SCAN TABLE t1}}
|
||||
{SCAN TABLE t1 USING COVERING INDEX i1}
|
||||
{SCAN TABLE t1}
|
||||
} {
|
||||
do_eqp_test 1.$idxmode.$tn $sql $r($idxmode)
|
||||
}
|
||||
|
||||
@@ -235,17 +235,20 @@ do_execsql_test where3-3.0 {
|
||||
CREATE TABLE t302(x, y);
|
||||
INSERT INTO t302 VALUES(4,5);
|
||||
ANALYZE;
|
||||
explain query plan SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t302}
|
||||
0 1 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
}
|
||||
do_execsql_test where3-3.1 {
|
||||
explain query plan
|
||||
do_eqp_test where3-3.0a {
|
||||
SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t302
|
||||
`--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
do_eqp_test where3-3.1 {
|
||||
SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y;
|
||||
} {
|
||||
0 0 1 {SCAN TABLE t302}
|
||||
0 1 0 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t302
|
||||
`--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
do_execsql_test where3-3.2 {
|
||||
SELECT * FROM t301 WHERE c=3 AND a IS NULL;
|
||||
@@ -308,8 +311,8 @@ do_execsql_test where3-5.0 {
|
||||
CREATE INDEX bbb_111 ON bbb (fk, type);
|
||||
CREATE INDEX bbb_222 ON bbb (parent, position);
|
||||
CREATE INDEX bbb_333 ON bbb (fk, lastModified);
|
||||
|
||||
EXPLAIN QUERY PLAN
|
||||
}
|
||||
do_eqp_test where3-5.0a {
|
||||
SELECT bbb.title AS tag_title
|
||||
FROM aaa JOIN bbb ON bbb.id = aaa.parent
|
||||
WHERE aaa.fk = 'constant'
|
||||
@@ -317,12 +320,12 @@ do_execsql_test where3-5.0 {
|
||||
AND bbb.parent = 4
|
||||
ORDER BY bbb.title COLLATE NOCASE ASC;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)}
|
||||
0 1 1 {SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
|
||||
|--SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_execsql_test where3-5.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test where3-5.1 {
|
||||
SELECT bbb.title AS tag_title
|
||||
FROM aaa JOIN aaa AS bbb ON bbb.id = aaa.parent
|
||||
WHERE aaa.fk = 'constant'
|
||||
@@ -330,12 +333,12 @@ do_execsql_test where3-5.1 {
|
||||
AND bbb.parent = 4
|
||||
ORDER BY bbb.title COLLATE NOCASE ASC;
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)}
|
||||
0 1 1 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
|
||||
|--SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_execsql_test where3-5.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test where3-5.2 {
|
||||
SELECT bbb.title AS tag_title
|
||||
FROM bbb JOIN aaa ON bbb.id = aaa.parent
|
||||
WHERE aaa.fk = 'constant'
|
||||
@@ -343,12 +346,12 @@ do_execsql_test where3-5.2 {
|
||||
AND bbb.parent = 4
|
||||
ORDER BY bbb.title COLLATE NOCASE ASC;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)}
|
||||
0 1 0 {SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
|
||||
|--SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_execsql_test where3-5.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test where3-5.3 {
|
||||
SELECT bbb.title AS tag_title
|
||||
FROM aaa AS bbb JOIN aaa ON bbb.id = aaa.parent
|
||||
WHERE aaa.fk = 'constant'
|
||||
@@ -356,9 +359,10 @@ do_execsql_test where3-5.3 {
|
||||
AND bbb.parent = 4
|
||||
ORDER BY bbb.title COLLATE NOCASE ASC;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)}
|
||||
0 1 0 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
|
||||
|--SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
# Name resolution with NATURAL JOIN and USING
|
||||
|
||||
@@ -23341,8 +23341,8 @@ do_execsql_test where7-3.1 {
|
||||
CREATE INDEX t302_c3 on t302(c3);
|
||||
CREATE INDEX t302_c8_c3 on t302(c8, c3);
|
||||
CREATE INDEX t302_c5 on t302(c5);
|
||||
|
||||
EXPLAIN QUERY PLAN
|
||||
}
|
||||
do_eqp_test where7-3.2 {
|
||||
SELECT t302.c1
|
||||
FROM t302 JOIN t301 ON t302.c8 = +t301.c8
|
||||
WHERE t302.c2 = 19571
|
||||
@@ -23351,10 +23351,11 @@ do_execsql_test where7-3.1 {
|
||||
OR t301.c8 = 1407424651264000)
|
||||
ORDER BY t302.c5 LIMIT 200;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)}
|
||||
0 0 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 1 0 {SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)
|
||||
|--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|--SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -357,25 +357,25 @@ do_test where9-2.8 {
|
||||
|
||||
|
||||
ifcapable explain {
|
||||
do_execsql_test where9-3.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
do_eqp_test where9-3.1 {
|
||||
SELECT t2.a FROM t1, t2
|
||||
WHERE t1.a=80 AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?)}
|
||||
0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)}
|
||||
}
|
||||
do_execsql_test where9-3.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|--SEARCH TABLE t2 USING INDEX t2d (d=?)
|
||||
`--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
|
||||
}]
|
||||
do_eqp_test where9-3.2 {
|
||||
SELECT coalesce(t2.a,9999)
|
||||
FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f
|
||||
WHERE t1.a=80
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?)}
|
||||
0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|--SEARCH TABLE t2 USING INDEX t2d (d=?)
|
||||
`--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
|
||||
}]
|
||||
}
|
||||
|
||||
# Make sure that INDEXED BY and multi-index OR clauses play well with
|
||||
@@ -446,35 +446,30 @@ do_test where9-4.8 {
|
||||
}
|
||||
} {1 {no query solution}}
|
||||
|
||||
ifcapable explain {
|
||||
# The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
|
||||
# the former is an equality test which is expected to return fewer rows.
|
||||
#
|
||||
do_execsql_test where9-5.1 {
|
||||
EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?)}
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1d (d=?)}
|
||||
}
|
||||
|
||||
# In contrast, b=1000 is preferred over any OR-clause.
|
||||
#
|
||||
do_execsql_test where9-5.2 {
|
||||
EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}
|
||||
}
|
||||
|
||||
# Likewise, inequalities in an AND are preferred over inequalities in
|
||||
# an OR.
|
||||
#
|
||||
do_execsql_test where9-5.3 {
|
||||
EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL)
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>?)}
|
||||
}
|
||||
# The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
|
||||
# the former is an equality test which is expected to return fewer rows.
|
||||
#
|
||||
do_eqp_test where9-5.1 {
|
||||
SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t1 USING INDEX t1c (c=?)
|
||||
`--SEARCH TABLE t1 USING INDEX t1d (d=?)
|
||||
}
|
||||
|
||||
# In contrast, b=1000 is preferred over any OR-clause.
|
||||
#
|
||||
do_eqp_test where9-5.2 {
|
||||
SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b=?)}
|
||||
|
||||
# Likewise, inequalities in an AND are preferred over inequalities in
|
||||
# an OR.
|
||||
#
|
||||
do_eqp_test where9-5.3 {
|
||||
SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL)
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>?)}
|
||||
|
||||
############################################################################
|
||||
# Make sure OR-clauses work correctly on UPDATE and DELETE statements.
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ do_eqp_test whereG-1.1 {
|
||||
WHERE unlikely(cname LIKE '%bach%')
|
||||
AND composer.cid=track.cid
|
||||
AND album.aid=track.aid;
|
||||
} {/.*composer.*track.*album.*/}
|
||||
} {composer*track*album}
|
||||
do_execsql_test whereG-1.2 {
|
||||
SELECT DISTINCT aname
|
||||
FROM album, composer, track
|
||||
@@ -195,13 +195,13 @@ do_execsql_test 5.1 {
|
||||
}
|
||||
do_eqp_test 5.1.2 {
|
||||
SELECT * FROM t1 WHERE a>?
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a>?)}
|
||||
do_eqp_test 5.1.3 {
|
||||
SELECT * FROM t1 WHERE likelihood(a>?, 0.9)
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test 5.1.4 {
|
||||
SELECT * FROM t1 WHERE likely(a>?)
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
do_test 5.2 {
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
@@ -212,23 +212,23 @@ do_test 5.2 {
|
||||
} {}
|
||||
do_eqp_test 5.2.2 {
|
||||
SELECT * FROM t1 WHERE likelihood(b>?, 0.01)
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (ANY(a) AND b>?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (ANY(a) AND b>?)}
|
||||
do_eqp_test 5.2.3 {
|
||||
SELECT * FROM t1 WHERE likelihood(b>?, 0.9)
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test 5.2.4 {
|
||||
SELECT * FROM t1 WHERE likely(b>?)
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
do_eqp_test 5.3.1 {
|
||||
SELECT * FROM t1 WHERE a=?
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
|
||||
} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||
do_eqp_test 5.3.2 {
|
||||
SELECT * FROM t1 WHERE likelihood(a=?, 0.9)
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
do_eqp_test 5.3.3 {
|
||||
SELECT * FROM t1 WHERE likely(a=?)
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
} {SCAN TABLE t1}
|
||||
|
||||
# 2015-06-18
|
||||
# Ticket [https://www.sqlite.org/see/tktview/472f0742a1868fb58862bc588ed70]
|
||||
|
||||
@@ -29,8 +29,9 @@ do_execsql_test 1.0 {
|
||||
do_eqp_test 1.1 {
|
||||
SELECT a FROM t1 WHERE b='b' OR c='x'
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b=?)}
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t1 USING INDEX i1 (b=?)
|
||||
`--SEARCH TABLE t1 USING INDEX i2 (c=?)
|
||||
}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
@@ -57,8 +58,9 @@ do_execsql_test 2.0 {
|
||||
do_eqp_test 2.1 {
|
||||
SELECT a FROM t2 WHERE b='b' OR c='x'
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX i3 (b=?)}
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)}
|
||||
QUERY PLAN
|
||||
|--SEARCH TABLE t2 USING INDEX i3 (b=?)
|
||||
`--SEARCH TABLE t2 USING INDEX i4 (c=?)
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
|
||||
@@ -402,9 +402,7 @@ do_eqp_test 3.4 {
|
||||
a = 4 AND b BETWEEN 20 AND 80 -- Matches 80 rows
|
||||
AND
|
||||
c BETWEEN 150 AND 160 -- Matches 10 rows
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX idx_c (c>? AND c<?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX idx_c (c>? AND c<?)}
|
||||
|
||||
# This one should use index "idx_ab".
|
||||
do_eqp_test 3.5 {
|
||||
@@ -412,9 +410,7 @@ do_eqp_test 3.5 {
|
||||
a = 5 AND b BETWEEN 20 AND 80 -- Matches 1 row
|
||||
AND
|
||||
c BETWEEN 150 AND 160 -- Matches 10 rows
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t1 USING INDEX idx_ab (a=? AND b>? AND b<?)}
|
||||
}
|
||||
} {SEARCH TABLE t1 USING INDEX idx_ab (a=? AND b>? AND b<?)}
|
||||
|
||||
###########################################################################################
|
||||
|
||||
|
||||
@@ -992,16 +992,23 @@ do_execsql_test 18.2 {
|
||||
|
||||
# EXPLAIN QUERY PLAN on a self-join of a CTE
|
||||
#
|
||||
do_execsql_test 19.1 {
|
||||
do_execsql_test 19.1a {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
EXPLAIN QUERY PLAN
|
||||
}
|
||||
do_eqp_test 19.1b {
|
||||
WITH
|
||||
x1(a) AS (values(100))
|
||||
INSERT INTO t1(x)
|
||||
SELECT * FROM (WITH x2(y) AS (SELECT * FROM x1) SELECT y+a FROM x1, x2);
|
||||
SELECT * FROM t1;
|
||||
} {0 0 0 {SCAN SUBQUERY 1} 0 1 1 {SCAN SUBQUERY 1}}
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| `--SCAN CONSTANT ROW
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SCAN SUBQUERY xxxxxx
|
||||
}
|
||||
|
||||
# 2017-10-28.
|
||||
# See check-in https://sqlite.org/src/info/0926df095faf72c2
|
||||
|
||||
@@ -79,22 +79,30 @@ ifcapable analyze {
|
||||
do_eqp_test 3.1.2 {
|
||||
WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1)
|
||||
SELECT * FROM cnt, y1 WHERE i=a
|
||||
} {
|
||||
3 0 0 {SCAN TABLE cnt}
|
||||
1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)}
|
||||
0 0 0 {SCAN SUBQUERY 1}
|
||||
0 1 1 {SEARCH TABLE y1 USING INDEX y1a (a=?)}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| |--SETUP
|
||||
| | `--SCAN CONSTANT ROW
|
||||
| `--RECURSIVE STEP
|
||||
| `--SCAN TABLE cnt
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
`--SEARCH TABLE y1 USING INDEX y1a (a=?)
|
||||
}]
|
||||
|
||||
do_eqp_test 3.1.3 {
|
||||
WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1000000)
|
||||
SELECT * FROM cnt, y1 WHERE i=a
|
||||
} {
|
||||
3 0 0 {SCAN TABLE cnt}
|
||||
1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)}
|
||||
0 0 1 {SCAN TABLE y1}
|
||||
0 1 0 {SEARCH SUBQUERY 1 USING AUTOMATIC COVERING INDEX (i=?)}
|
||||
}
|
||||
} [string map {"\n " \n} {
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| |--SETUP
|
||||
| | `--SCAN CONSTANT ROW
|
||||
| `--RECURSIVE STEP
|
||||
| `--SCAN TABLE cnt
|
||||
|--SCAN TABLE y1
|
||||
`--SEARCH SUBQUERY xxxxxx USING AUTOMATIC COVERING INDEX (i=?)
|
||||
}]
|
||||
}
|
||||
|
||||
do_execsql_test 3.2.1 {
|
||||
@@ -108,13 +116,18 @@ do_eqp_test 3.2.2 {
|
||||
SELECT * FROM c, w2, w1
|
||||
WHERE c.id=w2.pk AND c.id=w1.pk;
|
||||
} {
|
||||
2 0 0 {EXECUTE SCALAR SUBQUERY 3}
|
||||
3 0 0 {SCAN TABLE w2}
|
||||
4 0 0 {SCAN TABLE w1}
|
||||
4 1 1 {SCAN TABLE c}
|
||||
1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} 0 0 0 {SCAN SUBQUERY 1}
|
||||
0 1 1 {SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
0 2 2 {SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
QUERY PLAN
|
||||
|--MATERIALIZE xxxxxx
|
||||
| |--SETUP
|
||||
| | |--SCAN CONSTANT ROW
|
||||
| | `--SCALAR SUBQUERY
|
||||
| | `--SCAN TABLE w2
|
||||
| `--RECURSIVE STEP
|
||||
| |--SCAN TABLE w1
|
||||
| `--SCAN TABLE c
|
||||
|--SCAN SUBQUERY xxxxxx
|
||||
|--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -238,7 +238,7 @@ do_execsql_test 5.0 {
|
||||
|
||||
do_eqp_test 5.1 {
|
||||
SELECT * FROM t45 WHERE b=? AND a>?
|
||||
} {/*USING INDEX i45 (b=? AND a>?)*/}
|
||||
} {USING INDEX i45 (b=? AND a>?)}
|
||||
|
||||
do_execsql_test 5.2 {
|
||||
SELECT * FROM t45 WHERE b='two' AND a>4
|
||||
@@ -257,11 +257,11 @@ do_execsql_test 5.4 {
|
||||
}
|
||||
|
||||
set queries {
|
||||
1 2 "c = 5 AND a = 1" {/*i46 (c=? AND a=?)*/}
|
||||
2 6 "c = 4 AND a < 3" {/*i46 (c=? AND a<?)*/}
|
||||
3 4 "c = 2 AND a >= 3" {/*i46 (c=? AND a>?)*/}
|
||||
4 1 "c = 2 AND a = 1 AND b<10" {/*i46 (c=? AND a=? AND b<?)*/}
|
||||
5 1 "c = 0 AND a = 0 AND b>5" {/*i46 (c=? AND a=? AND b>?)*/}
|
||||
1 2 "c = 5 AND a = 1" {i46 (c=? AND a=?)}
|
||||
2 6 "c = 4 AND a < 3" {i46 (c=? AND a<?)}
|
||||
3 4 "c = 2 AND a >= 3" {i46 (c=? AND a>?)}
|
||||
4 1 "c = 2 AND a = 1 AND b<10" {i46 (c=? AND a=? AND b<?)}
|
||||
5 1 "c = 0 AND a = 0 AND b>5" {i46 (c=? AND a=? AND b>?)}
|
||||
}
|
||||
|
||||
foreach {tn cnt where eqp} $queries {
|
||||
|
||||
Reference in New Issue
Block a user