Improved handling of constants and especially constant functions in the

ORDER BY clause of a query.  Do not optimize out "ORDER BY random()".
Fix for ticket [65bdeb9739605cc2296].

FossilOrigin-Name: dca1945aeb3fb005263f9be00ee8e72b966ae303
This commit is contained in:
drh 2014-02-26 02:26:09 +00:00
parent 0baa035a1e
commit 434a93147c
4 changed files with 48 additions and 25 deletions

View File

@ -1,5 +1,5 @@
C Do\snot\sallow\stemporary\sregisters\sto\sbe\sin\suse\sacross\san\sOP_Yield\swithin\sa\nco-routine.\s\sFix\sfor\sticket\s[8c63ff0eca81a9132d8].
D 2014-02-25T21:55:16.402
C Improved\shandling\sof\sconstants\sand\sespecially\sconstant\sfunctions\sin\sthe\nORDER\sBY\sclause\sof\sa\squery.\s\sDo\snot\soptimize\sout\s"ORDER\sBY\srandom()".\nFix\sfor\sticket\s[65bdeb9739605cc2296].
D 2014-02-26T02:26:09.921
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c 0b5a4d45fdf05ad541893d986abd2f660f6e0094
F src/where.c 6042e1a377cf7dc72c10493269ed75e276275cd8
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -1070,7 +1070,7 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b
F test/where2.test ed6baa9420a109d8be683dbef5d153d186f3690b
F test/where2.test 455a2eb2666e66c1e84e2cb5815173a85e6237db
F test/where3.test d28c51f257e60be30f74308fa385ceeddfb54a6e
F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
@ -1152,7 +1152,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 23001a85cd334090cf6c70d4d7e722a01f4f6899
R 53d871612a374a058c13125cf02ae108
P 97a8c9733cba97c78e979dfd5c66610c23e90288
R a3177866e2afe2abf843086af2a9a3a2
U drh
Z 196bbfe69fc9298304e0610559f3cd1e
Z c50f86b62c93dcd00c53d2ca75883787

View File

@ -1 +1 @@
97a8c9733cba97c78e979dfd5c66610c23e90288
dca1945aeb3fb005263f9be00ee8e72b966ae303

View File

@ -4901,9 +4901,12 @@ static int wherePathSatisfiesOrderBy(
orderDistinctMask |= pLoop->maskSelf;
for(i=0; i<nOrderBy; i++){
Expr *p;
Bitmask mTerm;
if( MASKBIT(i) & obSat ) continue;
p = pOrderBy->a[i].pExpr;
if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
mTerm = exprTableUsage(&pWInfo->sMaskSet,p);
if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
if( (mTerm&~orderDistinctMask)==0 ){
obSat |= MASKBIT(i);
}
}
@ -5526,22 +5529,6 @@ WhereInfo *sqlite3WhereBegin(
goto whereBeginError;
}
/* If the ORDER BY (or GROUP BY) clause contains references to general
** expressions, then we won't be able to satisfy it using indices, so
** go ahead and disable it now.
*/
if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
for(ii=0; ii<pOrderBy->nExpr; ii++){
Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr);
if( pExpr->op!=TK_COLUMN ){
pWInfo->pOrderBy = pOrderBy = 0;
break;
}else if( pExpr->iColumn<0 ){
break;
}
}
}
if( wctrlFlags & WHERE_WANT_DISTINCT ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
/* The DISTINCT marking is pointless. Ignore it. */

View File

@ -121,6 +121,42 @@ do_test where2-2.3 {
}
} {85 6 7396 7402 nosort t1 *}
# Ticket [65bdeb9739605cc22966f49208452996ff29a640] 2014-02-26
# Make sure "ORDER BY random" does not gets optimized out.
#
do_test where2-2.4 {
db eval {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b DEFAULT 1);
WITH RECURSIVE
cnt(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM cnt WHERE x<50)
INSERT INTO x1 SELECT x, 1 FROM cnt;
CREATE TABLE x2(x INTEGER PRIMARY KEY);
INSERT INTO x2 VALUES(1);
}
set sql {SELECT * FROM x1, x2 WHERE x=1 ORDER BY random()}
set out1 [db eval $sql]
set out2 [db eval $sql]
set out3 [db eval $sql]
expr {$out1!=$out2 && $out2!=$out3}
} {1}
do_execsql_test where2-2.5 {
-- random() is not optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY random();
} {/ random/}
do_execsql_test where2-2.5b {
-- random() is not optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY random();
} {/ SorterOpen /}
do_execsql_test where2-2.6 {
-- other constant functions are optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY abs(5);
} {~/ abs/}
do_execsql_test where2-2.6b {
-- other constant functions are optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY abs(5);
} {~/ SorterOpen /}
# Efficient handling of forward and reverse table scans.
#