Optimization: Convert an ORDER BY clause into a no-op if the query also
contains a GROUP BY clause that will force the same output order. FossilOrigin-Name: ca9d86baf70f210d331ce93102177c8005c494cb
This commit is contained in:
parent
93791ea0ba
commit
8c6f666b26
22
manifest
22
manifest
@ -1,8 +1,8 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
C Change\sthe\sdefault_cache_size\spragma\sto\salways\sstore\sa\spositive\svalue.
|
||||
D 2010-04-26T17:36:35
|
||||
C Optimization:\sConvert\san\sORDER\sBY\sclause\sinto\sa\sno-op\sif\sthe\squery\salso\ncontains\sa\sGROUP\sBY\sclause\sthat\swill\sforce\sthe\ssame\soutput\sorder.
|
||||
D 2010-04-26T19:17:27
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -121,7 +121,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c 51553a859994d01d8bf3500747f66a890c459774
|
||||
F src/date.c 485a4409a384310e6d93fd1104a9d0a8658becd9
|
||||
F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581
|
||||
F src/expr.c 6baed2a0448d494233d9c0a610eea018ab386a32
|
||||
F src/expr.c 286f62b24217ade1c14ba56de413ffdd607b6a41
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0
|
||||
F src/func.c 0c28599430856631216b6c0131c51c89bf516026
|
||||
@ -167,11 +167,11 @@ F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c ac5f1a713cd1ae77f08b83cc69581e11bf5ae6f9
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c b7c9a40bc1567bceff52ad4b73108734ee4bf268
|
||||
F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b
|
||||
F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4
|
||||
F src/sqlite.h.in dc98616304e3e776008655671d81e3ad3028ada7
|
||||
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
||||
F src/sqliteInt.h 15339730eeeb571ed515d125e3446ae80ec3b4ef
|
||||
F src/sqliteInt.h 4303fdad2e96c56f510cc8e31a647b1b8c5a5254
|
||||
F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
|
||||
F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 245d934b72cbc6e897193e7892195b6561995939
|
||||
R 1a721a7e3d8403e75d36dd22925eaa62
|
||||
P 36fb2cae75b5dfe1fe818895f03c0b4f4190a722
|
||||
R 39601da2973f0d22788b2e5833832c44
|
||||
U drh
|
||||
Z d3141c0d53e4f0054b2b5670e084ebf2
|
||||
Z 9d6faae1537324b0ce24766e774d3c1e
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFL1c8noxKgR168RlERAk2fAJwIn4ScLPQ6cD+9QSCdisImYXuM8QCfTXNt
|
||||
XvbQVdO+MSVbonYnIw7jvtU=
|
||||
=Dgm7
|
||||
iD8DBQFL1ebKoxKgR168RlERAixaAJ9MtsB9+gfG3m3Uh9CtO8GjRZH+fgCghDsR
|
||||
Xx+FaS5+UH9uAeCG9zc761s=
|
||||
=CIW0
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -1 +1 @@
|
||||
36fb2cae75b5dfe1fe818895f03c0b4f4190a722
|
||||
ca9d86baf70f210d331ce93102177c8005c494cb
|
39
src/expr.c
39
src/expr.c
@ -3440,7 +3440,6 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
** an incorrect 0 or 1 could lead to a malfunction.
|
||||
*/
|
||||
int sqlite3ExprCompare(Expr *pA, Expr *pB){
|
||||
int i;
|
||||
if( pA==0||pB==0 ){
|
||||
return pB==pA ? 0 : 2;
|
||||
}
|
||||
@ -3453,18 +3452,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
|
||||
if( pA->op!=pB->op ) return 2;
|
||||
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
|
||||
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
|
||||
|
||||
if( pA->x.pList && pB->x.pList ){
|
||||
if( pA->x.pList->nExpr!=pB->x.pList->nExpr ) return 2;
|
||||
for(i=0; i<pA->x.pList->nExpr; i++){
|
||||
Expr *pExprA = pA->x.pList->a[i].pExpr;
|
||||
Expr *pExprB = pB->x.pList->a[i].pExpr;
|
||||
if( sqlite3ExprCompare(pExprA, pExprB) ) return 2;
|
||||
}
|
||||
}else if( pA->x.pList || pB->x.pList ){
|
||||
return 2;
|
||||
}
|
||||
|
||||
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
|
||||
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
|
||||
if( ExprHasProperty(pA, EP_IntValue) ){
|
||||
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
|
||||
@ -3481,6 +3469,31 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Compare two ExprList objects. Return 0 if they are identical and
|
||||
** non-zero if they differ in any way.
|
||||
**
|
||||
** This routine might return non-zero for equivalent ExprLists. The
|
||||
** only consequence will be disabled optimizations. But this routine
|
||||
** must never return 0 if the two ExprList objects are different, or
|
||||
** a malfunction will result.
|
||||
**
|
||||
** Two NULL pointers are considered to be the same. But a NULL pointer
|
||||
** always differs from a non-NULL pointer.
|
||||
*/
|
||||
int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
|
||||
int i;
|
||||
if( pA==0 && pB==0 ) return 0;
|
||||
if( pA==0 || pB==0 ) return 1;
|
||||
if( pA->nExpr!=pB->nExpr ) return 1;
|
||||
for(i=0; i<pA->nExpr; i++){
|
||||
Expr *pExprA = pA->a[i].pExpr;
|
||||
Expr *pExprB = pB->a[i].pExpr;
|
||||
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
|
||||
if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add a new element to the pAggInfo->aCol[] array. Return the index of
|
||||
|
12
src/select.c
12
src/select.c
@ -3718,6 +3718,18 @@ int sqlite3Select(
|
||||
isDistinct = 0;
|
||||
}
|
||||
|
||||
/* If there is both a GROUP BY and an ORDER BY clause and they are
|
||||
** identical, then disable the ORDER BY clause since the GROUP BY
|
||||
** will cause elements to come out in the correct order. This is
|
||||
** an optimization - the correct answer should result regardless.
|
||||
** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
|
||||
** to disable this optimization for testing purposes.
|
||||
*/
|
||||
if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
|
||||
&& (db->flags & SQLITE_GroupByOrder)==0 ){
|
||||
pOrderBy = 0;
|
||||
}
|
||||
|
||||
/* If there is an ORDER BY clause, then this sorting
|
||||
** index might end up being unused if the data can be
|
||||
** extracted in pre-sorted order. If that is the case, then the
|
||||
|
@ -925,7 +925,8 @@ struct sqlite3 {
|
||||
#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */
|
||||
#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */
|
||||
#define SQLITE_IndexCover 0x10 /* Disable index covering table */
|
||||
#define SQLITE_OptMask 0x1f /* Mask of all disablable opts */
|
||||
#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */
|
||||
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
|
||||
|
||||
/*
|
||||
** Possible values for the sqlite.magic field.
|
||||
@ -2689,6 +2690,7 @@ void sqlite3Vacuum(Parse*);
|
||||
int sqlite3RunVacuum(char**, sqlite3*);
|
||||
char *sqlite3NameFromToken(sqlite3*, Token*);
|
||||
int sqlite3ExprCompare(Expr*, Expr*);
|
||||
int sqlite3ExprListCompare(ExprList*, ExprList*);
|
||||
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
||||
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
|
||||
Vdbe *sqlite3GetVdbe(Parse*);
|
||||
|
Loading…
x
Reference in New Issue
Block a user