Fix a problem causing the planner to generate sub-optimal plans for some queries
that use recursive WITH sub-queries with LIMIT clauses. FossilOrigin-Name: 053a149cc8244a7f85137129cfcb8622efe90306
This commit is contained in:
parent
e0a04a36a6
commit
69b9383edf
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C All\stemp.sqlite_master\sto\sbe\sused\sas\san\salias\sfor\ssqlite_temp_master.
|
||||
D 2016-12-16T01:00:21.326
|
||||
C Fix\sa\sproblem\scausing\sthe\splanner\sto\sgenerate\ssub-optimal\splans\sfor\ssome\squeries\nthat\suse\srecursive\sWITH\ssub-queries\swith\sLIMIT\sclauses.
|
||||
D 2016-12-16T15:05:40.539
|
||||
F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
||||
@ -388,7 +388,7 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 204491a5e09a66380a067943d8651af8bda1d358
|
||||
F src/select.c e4c687333c5fa33b1ce05c37bfbea6e09d3dbee9
|
||||
F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65
|
||||
F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
@ -1436,7 +1436,7 @@ F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3
|
||||
F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87
|
||||
F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98
|
||||
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 4e3749127e7249f46e17bfabc614b0876f60565a
|
||||
R 27200c6ed9ee619c25ffbd7fc5b77433
|
||||
U drh
|
||||
Z dbd7760e0bb1a8efbcd514dce9f9a0ad
|
||||
P 8d646905b830d5bb29092e103ac5cb499b3c7e5a
|
||||
R 147fd014e993bf990284d024622f7825
|
||||
U dan
|
||||
Z ececc9941f2e958f0280d3f055b0e66d
|
||||
|
@ -1 +1 @@
|
||||
8d646905b830d5bb29092e103ac5cb499b3c7e5a
|
||||
053a149cc8244a7f85137129cfcb8622efe90306
|
@ -2037,6 +2037,7 @@ static void generateWithRecursiveQuery(
|
||||
|
||||
/* Process the LIMIT and OFFSET clauses, if they exist */
|
||||
addrBreak = sqlite3VdbeMakeLabel(v);
|
||||
p->nSelectRow = 320; /* 4 billion rows */
|
||||
computeLimitRegisters(pParse, p, addrBreak);
|
||||
pLimit = p->pLimit;
|
||||
pOffset = p->pOffset;
|
||||
@ -5170,7 +5171,9 @@ int sqlite3Select(
|
||||
/* Set the limiter.
|
||||
*/
|
||||
iEnd = sqlite3VdbeMakeLabel(v);
|
||||
p->nSelectRow = 320; /* 4 billion rows */
|
||||
if( (p->selFlags & SF_FixedLimit)==0 ){
|
||||
p->nSelectRow = 320; /* 4 billion rows */
|
||||
}
|
||||
computeLimitRegisters(pParse, p, iEnd);
|
||||
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
|
||||
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
|
||||
|
@ -61,4 +61,60 @@ do_execsql_test 2.1 {
|
||||
SELECT * FROM t1;
|
||||
} {200}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that the planner notices LIMIT clauses on recursive WITH queries.
|
||||
#
|
||||
|
||||
ifcapable analyze {
|
||||
do_execsql_test 3.1.1 {
|
||||
CREATE TABLE y1(a, b);
|
||||
CREATE INDEX y1a ON y1(a);
|
||||
|
||||
WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1000)
|
||||
INSERT INTO y1 SELECT i%10, i FROM cnt;
|
||||
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=?)}
|
||||
}
|
||||
|
||||
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=?)}
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test 3.2.1 {
|
||||
CREATE TABLE w1(pk INTEGER PRIMARY KEY, x INTEGER);
|
||||
CREATE TABLE w2(pk INTEGER PRIMARY KEY);
|
||||
}
|
||||
|
||||
do_eqp_test 3.2.2 {
|
||||
WITH RECURSIVE c(w,id) AS (SELECT 0, (SELECT pk FROM w2 LIMIT 1)
|
||||
UNION ALL SELECT c.w + 1, x FROM w1, c LIMIT 1)
|
||||
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=?)}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user