Add a new ORDER BY optimization that bypasses ORDER BY terms that are
constrained by == and IS NULL terms of the WHERE clause. FossilOrigin-Name: b920bb70bb009b7c54e7667544c9810c5ee25e19
This commit is contained in:
parent
6d38147c19
commit
b8916be945
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
||||
C An\sindex\smight\sbe\suseful\sfor\sORDER\sBY\sif\sany\sindexed\scolumn\sis\sin\sthe\nORDER\sBY\sclause,\snot\sjust\sthe\sfirst\sindexed\scolumn.
|
||||
D 2013-06-13T17:58:08.642
|
||||
C Add\sa\snew\sORDER\sBY\soptimization\sthat\sbypasses\sORDER\sBY\sterms\sthat\sare\nconstrained\sby\s==\sand\sIS\sNULL\sterms\sof\sthe\sWHERE\sclause.
|
||||
D 2013-06-14T02:51:48.285
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -289,7 +289,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
|
||||
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||
F src/where.c ba5f6766cfc7fcee945d45120cbb6e39a881b8e0
|
||||
F src/where.c 7d406cca2f60afbbfb57470f0d4981798bccf6e8
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
@ -695,6 +695,7 @@ F test/orderby1.test 9b524aff9147288da43a6d7ddfdcff47fa2303c6
|
||||
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
|
||||
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
|
||||
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
|
||||
F test/orderby5.test 02eca502a0f97c77ce383b0dfa17e99c6a107b8d
|
||||
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
|
||||
F test/pager1.test 16b649c8f0b38d446acbcff8a7bf055a9be43276
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
@ -1095,7 +1096,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P e8b7ea8202c443bfc8a978588c7d2cfaa14a8fea
|
||||
R 20475a52b4ff0eaa6499f9e0ae4a1e9c
|
||||
P ade473b5ae3fe2162b0ec29731d8e864a9301e07
|
||||
R eae0305c76446978c9d6694aa033807b
|
||||
U drh
|
||||
Z f8930bf04903145489a941260cbef3e2
|
||||
Z 288ef6a3a068d55d460d1b487a44477a
|
||||
|
@ -1 +1 @@
|
||||
ade473b5ae3fe2162b0ec29731d8e864a9301e07
|
||||
b920bb70bb009b7c54e7667544c9810c5ee25e19
|
33
src/where.c
33
src/where.c
@ -4891,7 +4891,7 @@ static int wherePathSatisfiesOrderBy(
|
||||
Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */
|
||||
Bitmask obDone; /* Mask of all ORDER BY terms */
|
||||
Bitmask orderDistinctMask; /* Mask of all well-ordered loops */
|
||||
|
||||
Bitmask ready; /* Mask of inner loops */
|
||||
|
||||
/*
|
||||
** We say the WhereLoop is "one-row" if it generates no more than one
|
||||
@ -4931,10 +4931,39 @@ static int wherePathSatisfiesOrderBy(
|
||||
isOrderDistinct = 1;
|
||||
obDone = MASKBIT(nOrderBy)-1;
|
||||
orderDistinctMask = 0;
|
||||
ready = 0;
|
||||
for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
|
||||
if( iLoop>0 ) ready |= pLoop->maskSelf;
|
||||
pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast;
|
||||
assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
|
||||
iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
|
||||
|
||||
/* Mark off any ORDER BY term X that is a column in the table of
|
||||
** the current loop for which there is term in the WHERE
|
||||
** clause of the form X IS NULL or X=? that reference only outer
|
||||
** loops.
|
||||
*/
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
if( MASKBIT(i) & obSat ) continue;
|
||||
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
|
||||
if( pOBExpr->op!=TK_COLUMN ) continue;
|
||||
if( pOBExpr->iTable!=iCur ) continue;
|
||||
pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
|
||||
~ready, WO_EQ|WO_ISNULL, 0);
|
||||
if( pTerm==0 ) continue;
|
||||
if( pOBExpr->iColumn>=0 ){
|
||||
const char *z1, *z2;
|
||||
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
|
||||
if( !pColl ) pColl = db->pDfltColl;
|
||||
z1 = pColl->zName;
|
||||
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
|
||||
if( !pColl ) pColl = db->pDfltColl;
|
||||
z2 = pColl->zName;
|
||||
if( sqlite3StrICmp(z1, z2)!=0 ) continue;
|
||||
}
|
||||
obSat |= MASKBIT(i);
|
||||
}
|
||||
|
||||
if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
|
||||
if( pLoop->wsFlags & WHERE_IPK ){
|
||||
pIndex = 0;
|
||||
@ -5066,7 +5095,7 @@ static int wherePathSatisfiesOrderBy(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* End the loop over all WhereLoops from outer-most down to inner-most */
|
||||
if( obSat==obDone ) return 1;
|
||||
if( !isOrderDistinct ) return 0;
|
||||
if( isLastLoop ) return 1;
|
||||
|
97
test/orderby5.test
Normal file
97
test/orderby5.test
Normal file
@ -0,0 +1,97 @@
|
||||
# 2013-06-14
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing that the optimizations that disable
|
||||
# ORDER BY clauses work correctly
|
||||
#
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix orderby5
|
||||
|
||||
# Generate test data for a join. Verify that the join gets the
|
||||
# correct answer.
|
||||
#
|
||||
do_execsql_test 1.1 {
|
||||
CREATE TABLE t1(a,b,c);
|
||||
CREATE INDEX t1bc ON t1(b,c);
|
||||
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT a, b, c FROM t1 WHERE a=0;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.2.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT a, c, b FROM t1 WHERE a=0;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.2.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT a, c, b FROM t1 WHERE a='xyz' COLLATE nocase;
|
||||
} {/B-TREE/}
|
||||
do_execsql_test 1.2.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT a COLLATE nocase, c, b FROM t1 WHERE a='xyz';
|
||||
} {/B-TREE/}
|
||||
do_execsql_test 1.2.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT a COLLATE nocase, c, b FROM t1 WHERE a='xyz' COLLATE nocase;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT b, a, c FROM t1 WHERE a=0;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT b, c, a FROM t1 WHERE a=0;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT c, a, b FROM t1 WHERE a=0;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.6 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT c, b, a FROM t1 WHERE a=0;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 1.7 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT DISTINCT c, b, a FROM t1 WHERE +a=0;
|
||||
} {/B-TREE/}
|
||||
do_execsql_test 2.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a=0 ORDER BY a, b, c;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 2.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE +a=0 ORDER BY a, b, c;
|
||||
} {/B-TREE/}
|
||||
do_execsql_test 2.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a=0 ORDER BY b, a, c;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 2.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a=0 ORDER BY b, c, a;
|
||||
} {~/B-TREE/}
|
||||
do_execsql_test 2.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a=0 ORDER BY a, c, b;
|
||||
} {/B-TREE/}
|
||||
do_execsql_test 2.6 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a=0 ORDER BY c, a, b;
|
||||
} {/B-TREE/}
|
||||
do_execsql_test 2.7 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a=0 ORDER BY c, b, a;
|
||||
} {/B-TREE/}
|
||||
|
||||
|
||||
finish_test
|
Loading…
x
Reference in New Issue
Block a user