1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

More test cases an bug fixes for the ORDER BY optimization of joins. All

veryquick tests now pass.

FossilOrigin-Name: 0d573320057b0903a5589cabfb1b1ece1c57958e
This commit is contained in:
drh
2012-09-27 19:53:38 +00:00
parent 6b10a6a7ed
commit 5343b2d4a8
8 changed files with 315 additions and 39 deletions

View File

@ -1,5 +1,5 @@
C Test\scases\sand\sbug\sfixes\sapplied\sto\sthe\sORDER\sBY\soptimization\sfor\sjoins.\nSome\stest\scases\sfail,\sbut\sexcept\sfor\sthe\snew\sorderby1.test\sfailures,\sall\nfailures\sappear\sto\sbe\sissues\swith\sthe\stests,\snot\swith\sthe\score\scode. C More\stest\scases\san\sbug\sfixes\sfor\sthe\sORDER\sBY\soptimization\sof\sjoins.\s\sAll\nveryquick\stests\snow\spass.
D 2012-09-27T17:31:32.268 D 2012-09-27T19:53:38.142
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9
F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c a537824b2eec986c203a6a370090520b955f258b F src/where.c cd047c1223f6364f869d44b7d3941a687de7fcb6
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
@ -386,7 +386,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c
F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216 F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test 69013a64b469458820abb7f3281a7eaa6c1fda76 F test/e_select.test 07e8d81268ba1ffcaf1dc4bec48956af150c42f9
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3 F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3
@ -634,7 +634,7 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test 868a4f88c4f4565684bcc18e8ed61a990ece431b F test/orderby1.test 31c9865626046666e81cd22ecf8e1c24a4ea41b6
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
@ -740,7 +740,7 @@ F test/tclsqlite.test a3d2df21ee98957f5de4f9dc1db0eab68047ab5d
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
F test/tester.tcl ed47103d30a1a4b3c1d8de207606a407e55cc5c2 F test/tester.tcl 2f383e811010b05a83c0f00fc168cae1dd63a6d9
F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91 F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@ -784,7 +784,7 @@ F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408 F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408
F test/tkt-cbd054fa6b.test bd9fb546f63bc0c79d1776978d059fa51c5b1c63 F test/tkt-cbd054fa6b.test 9c27ed07b333eed458e5d4543f91ecdcf05aeb19
F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30 F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
@ -955,7 +955,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 59cf231e6edaf0f20b106a26d4294847e7c6eb25 F test/where.test ea9659ff6e31681d0cdaf964747139cb10808200
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@ -1017,7 +1017,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
P d2fcba1e143beca8c45724d2108870657c269e17 P 75cda864ededb6dc0f84bd52ed3311753a58e351
R 388197fbdd69fccc34c9d73c7bc9f9e7 R 2ac4d1c44b199e10f1d07ecdc3868045
U drh U drh
Z f07796285dcd213d3100411a37b9d38f Z 9df007fa9fa34b8089a8009c6ca9320b

View File

@ -1 +1 @@
75cda864ededb6dc0f84bd52ed3311753a58e351 0d573320057b0903a5589cabfb1b1ece1c57958e

View File

@ -1645,13 +1645,17 @@ static int isSortingIndex(
sqlite3 *db = pParse->db; /* Database connection */ sqlite3 *db = pParse->db; /* Database connection */
int nPriorSat; /* ORDER BY terms satisfied by outer loops */ int nPriorSat; /* ORDER BY terms satisfied by outer loops */
int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ int seenRowid = 0; /* True if an ORDER BY rowid term is seen */
int nEqOneRow; /* Idx columns that ref unique values */
if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0; if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0;
if( p->i==0 ){ if( p->i==0 ){
nPriorSat = 0; nPriorSat = 0;
nEqOneRow = nEqCol;
}else{ }else{
if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
nPriorSat = p->aLevel[p->i-1].plan.nOBSat; nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
sortOrder = bOuterRev;
nEqOneRow = 0;
} }
if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat; if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat;
pOrderBy = p->pOrderBy; pOrderBy = p->pOrderBy;
@ -1725,7 +1729,7 @@ static int isSortingIndex(
assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
assert( iSortOrder==0 || iSortOrder==1 ); assert( iSortOrder==0 || iSortOrder==1 );
termSortOrder = iSortOrder ^ pTerm->sortOrder; termSortOrder = iSortOrder ^ pTerm->sortOrder;
if( i>nEqCol ){ if( i>nEqOneRow ){
if( termSortOrder!=sortOrder ){ if( termSortOrder!=sortOrder ){
/* Indices can only be used if all ORDER BY terms past the /* Indices can only be used if all ORDER BY terms past the
** equality constraints are all either DESC or ASC. */ ** equality constraints are all either DESC or ASC. */
@ -1741,7 +1745,7 @@ static int isSortingIndex(
break; break;
} }
} }
*pbRev = bOuterRev ^ sortOrder; *pbRev = sortOrder;
/* If there was an "ORDER BY rowid" term that matched, or it is only /* If there was an "ORDER BY rowid" term that matched, or it is only
** possible for a single row from this table to match, then skip over ** possible for a single row from this table to match, then skip over
@ -3296,7 +3300,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
** So this computation assumes table records are about twice as big ** So this computation assumes table records are about twice as big
** as index records ** as index records
*/ */
if( wsFlags==WHERE_IDX_ONLY if( (wsFlags&~WHERE_REVERSE)==WHERE_IDX_ONLY
&& (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
&& sqlite3GlobalConfig.bUseCis && sqlite3GlobalConfig.bUseCis
&& OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan) && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
@ -3421,9 +3425,10 @@ static void bestBtreeIndex(WhereBestIdx *p){
WHERETRACE(( WHERETRACE((
"%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n" "%s(%s):\n"
" notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n"
" used=0x%llx nOrdered=%d nOBSat=%d\n", " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
" used=0x%llx nOrdered=%d nOBSat=%d\n",
pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"),
nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat
@ -5088,10 +5093,10 @@ WhereInfo *sqlite3WhereBegin(
} }
assert( bestJ>=0 ); assert( bestJ>=0 );
assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
WHERETRACE(("*** Optimizer selects table %d for loop %d" WHERETRACE(("*** Optimizer selects table %d for loop %d with:\n"
" with cost=%.1f, nRow=%.1f, nOBSat=%d\n", " cost=%.1f, nRow=%.1f, nOBSat=%d wsFlags=0x%08x\n",
bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow, bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow,
bestPlan.plan.nOBSat)); bestPlan.plan.nOBSat, bestPlan.plan.wsFlags));
if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
pWInfo->nOBSat = pOrderBy->nExpr; pWInfo->nOBSat = pOrderBy->nExpr;
} }

View File

@ -1023,7 +1023,7 @@ do_execsql_test e_select-4.9.0 {
# #
do_select_tests e_select-4.9 { do_select_tests e_select-4.9 {
1 "SELECT group_concat(one), two FROM b1 GROUP BY two" { 1 "SELECT group_concat(one), two FROM b1 GROUP BY two" {
4,5 f 1 o 7,6 s 3,2 t /#,# f 1 o #,# s #,# t/
} }
2 "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" { 2 "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" {
1,2,3,4 10 5,6,7 18 1,2,3,4 10 5,6,7 18
@ -1040,7 +1040,7 @@ do_select_tests e_select-4.9 {
# values are considered equal. # values are considered equal.
# #
do_select_tests e_select-4.10 { do_select_tests e_select-4.10 {
1 "SELECT group_concat(y) FROM b2 GROUP BY x" {0,1 3 2,4} 1 "SELECT group_concat(y) FROM b2 GROUP BY x" {/#,# 3 #,#/}
2 "SELECT count(*) FROM b2 GROUP BY CASE WHEN y<4 THEN NULL ELSE 0 END" {4 1} 2 "SELECT count(*) FROM b2 GROUP BY CASE WHEN y<4 THEN NULL ELSE 0 END" {4 1}
} }
@ -1745,12 +1745,12 @@ do_select_tests e_select-8.4 {
1 2 7 1 2 8 1 4 93 1 5 -1 1 2 7 1 2 8 1 4 93 1 5 -1
} }
8 "SELECT z, x FROM d1 ORDER BY 2" { 8 "SELECT z, x FROM d1 ORDER BY 2" {
3 1 8 1 7 1 -20 1 /# 1 # 1 # 1 # 1
93 1 -1 1 -1 2 93 2 # 1 # 1 # 2 # 2/
} }
9 "SELECT z, x FROM d1 ORDER BY 1" { 9 "SELECT z, x FROM d1 ORDER BY 1" {
-20 1 -1 2 -1 1 3 1 /-20 1 -1 # -1 # 3 1
7 1 8 1 93 2 93 1 7 1 8 1 93 # 93 #/
} }
} }
@ -1766,10 +1766,10 @@ do_select_tests e_select-8.5 {
94 94 9 8 4 0 0 -19 94 94 9 8 4 0 0 -19
} }
3 "SELECT z AS x, x AS z FROM d1 ORDER BY z" { 3 "SELECT z AS x, x AS z FROM d1 ORDER BY z" {
3 1 8 1 7 1 -20 1 93 1 -1 1 -1 2 93 2 /# 1 # 1 # 1 # 1 # 1 # 1 # 2 # 2/
} }
4 "SELECT z AS x, x AS z FROM d1 ORDER BY x" { 4 "SELECT z AS x, x AS z FROM d1 ORDER BY x" {
-20 1 -1 2 -1 1 3 1 7 1 8 1 93 2 93 1 /-20 1 -1 # -1 # 3 1 7 1 8 1 93 # 93 #/
} }
} }

View File

@ -114,7 +114,7 @@ do_test 1.4c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
} }
} {~/ORDER BY/} ;# ORDER BY optimized-out } {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
do_test 1.5a { do_test 1.5a {
@ -130,9 +130,9 @@ do_test 1.5b {
do_test 1.5c { do_test 1.5c {
db eval { db eval {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
} }
} {~/ORDER BY/} ;# ORDER BY optimized-out } {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
do_test 1.6a { do_test 1.6a {
db eval { db eval {
@ -152,4 +152,275 @@ do_test 1.6c {
} {~/ORDER BY/} ;# ORDER BY optimized-out } {~/ORDER BY/} ;# ORDER BY optimized-out
# Reconstruct the test data to use indices rather than integer primary keys.
#
do_test 2.0 {
db eval {
BEGIN;
DROP TABLE album;
DROP TABLE track;
CREATE TABLE album(
aid INT PRIMARY KEY,
title TEXT NOT NULL
);
CREATE INDEX album_i1 ON album(title, aid);
CREATE TABLE track(
aid INTEGER NOT NULL REFERENCES album,
tn INTEGER NOT NULL,
name TEXT,
UNIQUE(aid, tn)
);
INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
INSERT INTO track VALUES
(1, 1, 'one-a'),
(2, 2, 'two-b'),
(3, 3, 'three-c'),
(1, 3, 'one-c'),
(2, 1, 'two-a'),
(3, 1, 'three-a');
COMMIT;
}
} {}
do_test 2.1a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
# Verify that the ORDER BY clause is optimized out
#
do_test 2.1b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {~/ORDER BY/} ;# ORDER BY optimized out
# The same query with ORDER BY clause optimization disabled via + operators
# should give exactly the same answer.
#
do_test 2.2a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {one-a one-c two-a two-b three-a three-c}
# The output is sorted manually in this case.
#
do_test 2.2b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
# The same query with ORDER BY optimizations turned off via built-in test.
#
do_test 2.3a {
optimization_control db order-by-idx-join 0
db cache flush
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
do_test 2.3b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {/ORDER BY/} ;# separate sorting pass due to disabled optimization
optimization_control db all 1
db cache flush
# Reverse order sorts
#
do_test 2.4a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {three-a three-c two-a two-b one-a one-c}
do_test 2.4b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
}
} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
do_test 2.4c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
do_test 2.5a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
do_test 2.5b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
do_test 2.5c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC
do_test 2.6a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {three-c three-a two-b two-a one-c one-a}
do_test 2.6b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
}
} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
do_test 2.6c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {~/ORDER BY/} ;# ORDER BY optimized-out
# Generate another test dataset, but this time using mixed ASC/DESC indices.
#
do_test 3.0 {
db eval {
BEGIN;
DROP TABLE album;
DROP TABLE track;
CREATE TABLE album(
aid INTEGER PRIMARY KEY,
title TEXT UNIQUE NOT NULL
);
CREATE TABLE track(
tid INTEGER PRIMARY KEY,
aid INTEGER NOT NULL REFERENCES album,
tn INTEGER NOT NULL,
name TEXT,
UNIQUE(aid ASC, tn DESC)
);
INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
INSERT INTO track VALUES
(NULL, 1, 1, 'one-a'),
(NULL, 2, 2, 'two-b'),
(NULL, 3, 3, 'three-c'),
(NULL, 1, 3, 'one-c'),
(NULL, 2, 1, 'two-a'),
(NULL, 3, 1, 'three-a');
COMMIT;
}
} {}
do_test 3.1a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
# Verify that the ORDER BY clause is optimized out
#
do_test 3.1b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {~/ORDER BY/} ;# ORDER BY optimized out
# The same query with ORDER BY clause optimization disabled via + operators
# should give exactly the same answer.
#
do_test 3.2a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
# The output is sorted manually in this case.
#
do_test 3.2b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
# The same query with ORDER BY optimizations turned off via built-in test.
#
do_test 3.3a {
optimization_control db order-by-idx-join 0
db cache flush
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
do_test 3.3b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to disabled optimization
optimization_control db all 1
db cache flush
# Without the mixed ASC/DESC on ORDER BY
#
do_test 3.4a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
do_test 3.4b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting
do_test 3.4c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {/ORDER BY/} ;# separate sorting pass due to mismatched DESC/ASC
do_test 3.5a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {three-c three-a two-b two-a one-c one-a}
do_test 3.5b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
}
} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
do_test 3.5c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to mismatched ASC/DESC
do_test 3.6a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {three-a three-c two-a two-b one-a one-c}
do_test 3.6b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
}
} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
do_test 3.6c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {~/ORDER BY/} ;# inverted ASC/DESC is optimized out
finish_test finish_test

View File

@ -538,10 +538,10 @@ proc do_test {name cmd expected} {
} else { } else {
if {[regexp {^~?/.*/$} $expected]} { if {[regexp {^~?/.*/$} $expected]} {
if {[string index $expected 0]=="~"} { if {[string index $expected 0]=="~"} {
set re [string range $expected 2 end-1] set re [string map {# {[-0-9.]+}} [string range $expected 2 end-1]]
set ok [expr {![regexp $re $result]}] set ok [expr {![regexp $re $result]}]
} else { } else {
set re [string range $expected 1 end-1] set re [string map {# {[-0-9.]+}} [string range $expected 1 end-1]]
set ok [regexp $re $result] set ok [regexp $re $result]
} }
} else { } else {

View File

@ -50,7 +50,7 @@ do_test tkt-cbd05-1.3 {
WHERE idx = 't1_x' WHERE idx = 't1_x'
GROUP BY tbl,idx GROUP BY tbl,idx
} }
} {t1 t1_x { A B C D E F G H I}} } {/t1 t1_x .[ ABCDEFGHI]{10}./}
do_test tkt-cbd05-2.1 { do_test tkt-cbd05-2.1 {
db eval { db eval {
@ -82,6 +82,6 @@ do_test tkt-cbd05-2.3 {
WHERE idx = 't1_x' WHERE idx = 't1_x'
GROUP BY tbl,idx GROUP BY tbl,idx
} }
} {t1 t1_x { A B C D E F G H I}} } {/t1 t1_x .[ ABCDEFGHI]{10}./}
finish_test finish_test

View File

@ -383,7 +383,7 @@ ifcapable subquery {
count { count {
SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1; SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
} }
} {1 0 4 2 1 9 3 1 16 14} } {1 0 4 2 1 9 3 1 16 13}
do_test where-5.4 { do_test where-5.4 {
count { count {
SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1; SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
@ -1109,13 +1109,13 @@ do_test where-14.5 {
cksort { cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b
} }
} {4/4 4/1 1/4 1/1 sort} } {/4/[14] 4/[14] 1/[14] 1/[14] sort/}
do_test where-14.6 { do_test where-14.6 {
# This test case changed from "nosort" to "sort". See ticket 2a5629202f. # This test case changed from "nosort" to "sort". See ticket 2a5629202f.
cksort { cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC
} }
} {4/4 4/1 1/4 1/1 sort} } {/4/[14] 4/[14] 1/[14] 1/[14] sort/}
do_test where-14.7 { do_test where-14.7 {
cksort { cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b