1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Improvements to the HAVING-to-WHERE optimization. The code uses less space

and less CPU, and there is now ".selecttrace" output.

FossilOrigin-Name: 5ad668d4339397fe66fe085e0527e37a1930917da88d462a8d89a465faa15e28
This commit is contained in:
drh
2018-03-20 18:08:33 +00:00
parent de8113c31e
commit cd0abc24d1
4 changed files with 28 additions and 38 deletions

View File

@@ -1,5 +1,5 @@
C For\s'zipfile',\sdetect\sattempts\sto\scause\sa\sduplicate\sentry\svia\sUPDATE.\s\sAlso,\sfix\shandling\sof\s'UPDATE\sOR\sREPLACE'\sstatements\srun\son\szipfile\svirtual\stables.\s\sWin32\sportability\sfixes\sto\sthe\s'fileio'\sextension.\s\sMiscellaneous\stest\sfixes. C Improvements\sto\sthe\sHAVING-to-WHERE\soptimization.\s\sThe\scode\suses\sless\sspace\nand\sless\sCPU,\sand\sthere\sis\snow\s".selecttrace"\soutput.
D 2018-03-20T16:56:12.064 D 2018-03-20T18:08:33.634
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3 F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3
@@ -489,12 +489,12 @@ F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 66c73fcb7719b8ff0e841b58338f13604ff3e2b50a723f9b8f383595735262f6 F src/resolve.c 66c73fcb7719b8ff0e841b58338f13604ff3e2b50a723f9b8f383595735262f6
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 97a2131f02c605c52a6d5deac5b2ae6604db8c346829eb6b185bc38512a9b49a F src/select.c 69ed6ca9d1bf4adb41472b0740b7b90868438dedcdd5ab2fd608070eca30d073
F src/shell.c.in 911b9e3bce40413c78fdba28efa28363e98183819bd4b300780bf57bacfc4b84 F src/shell.c.in 911b9e3bce40413c78fdba28efa28363e98183819bd4b300780bf57bacfc4b84
F src/sqlite.h.in 19762b57baa1ade67531f254de94374428fb9c82452ef305017847945f9c2911 F src/sqlite.h.in 19762b57baa1ade67531f254de94374428fb9c82452ef305017847945f9c2911
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
F src/sqliteInt.h 5c07bbc55d9eb3389a10536bd008e2d6f20f586871972610431d943595b40ca4 F src/sqliteInt.h 7e9deb145c110289f50fcf72a8742d030834885676482391fe83c3cee75f97d4
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1712,8 +1712,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P ec7addc87f97bcff3c3694b14a680453b52de3f8c106436f0708a1cc04b90faa 9a5ef341de2bd2fc4657a510f48159f7876f58d340b457b4272a71d389f88da3 P b36caeca91647616ac2ccdb281200c1a8bcd15d1f30dda0c1d89440d54607196
R 1e4df846035bbcb340ca288f329df6a5 R 8c8ba3697adfaee222e4b3bf5fcfea0c
T +closed 9a5ef341de2bd2fc4657a510f48159f7876f58d340b457b4272a71d389f88da3 U drh
U mistachkin Z 2c3bb9ba5e9ef9c236ac01dacb11a7b0
Z 2140b1494b49e09f4697bfddad075bea

View File

@@ -1 +1 @@
b36caeca91647616ac2ccdb281200c1a8bcd15d1f30dda0c1d89440d54607196 5ad668d4339397fe66fe085e0527e37a1930917da88d462a8d89a465faa15e28

View File

@@ -4912,14 +4912,6 @@ static void explainSimpleCount(
# define explainSimpleCount(a,b,c) # define explainSimpleCount(a,b,c)
#endif #endif
/*
** Context object for havingToWhereExprCb().
*/
struct HavingToWhereCtx {
Expr **ppWhere;
ExprList *pGroupBy;
};
/* /*
** sqlite3WalkExpr() callback used by havingToWhere(). ** sqlite3WalkExpr() callback used by havingToWhere().
** **
@@ -4933,15 +4925,16 @@ struct HavingToWhereCtx {
*/ */
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
if( pExpr->op!=TK_AND ){ if( pExpr->op!=TK_AND ){
struct HavingToWhereCtx *p = pWalker->u.pHavingCtx; Select *pS = pWalker->u.pSelect;
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){ if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
sqlite3 *db = pWalker->pParse->db; sqlite3 *db = pWalker->pParse->db;
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0); Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
if( pNew ){ if( pNew ){
Expr *pWhere = *(p->ppWhere); Expr *pWhere = pS->pWhere;
SWAP(Expr, *pNew, *pExpr); SWAP(Expr, *pNew, *pExpr);
pNew = sqlite3ExprAnd(db, pWhere, pNew); pNew = sqlite3ExprAnd(db, pWhere, pNew);
*(p->ppWhere) = pNew; pS->pWhere = pNew;
pWalker->eCode = 1;
} }
} }
return WRC_Prune; return WRC_Prune;
@@ -4964,23 +4957,19 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
** entirely of constants and expressions that are also GROUP BY terms that ** entirely of constants and expressions that are also GROUP BY terms that
** use the "BINARY" collation sequence. ** use the "BINARY" collation sequence.
*/ */
static void havingToWhere( static void havingToWhere(Parse *pParse, Select *p){
Parse *pParse,
ExprList *pGroupBy,
Expr *pHaving,
Expr **ppWhere
){
struct HavingToWhereCtx sCtx;
Walker sWalker; Walker sWalker;
sCtx.ppWhere = ppWhere;
sCtx.pGroupBy = pGroupBy;
memset(&sWalker, 0, sizeof(sWalker)); memset(&sWalker, 0, sizeof(sWalker));
sWalker.pParse = pParse; sWalker.pParse = pParse;
sWalker.xExprCallback = havingToWhereExprCb; sWalker.xExprCallback = havingToWhereExprCb;
sWalker.u.pHavingCtx = &sCtx; sWalker.u.pSelect = p;
sqlite3WalkExpr(&sWalker, pHaving); sqlite3WalkExpr(&sWalker, p->pHaving);
#if SELECTTRACE_ENABLED
if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
} }
/* /*
@@ -5649,7 +5638,9 @@ int sqlite3Select(
if( pHaving ){ if( pHaving ){
if( pGroupBy ){ if( pGroupBy ){
assert( pWhere==p->pWhere ); assert( pWhere==p->pWhere );
havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere); assert( pHaving==p->pHaving );
assert( pGroupBy==p->pGroupBy );
havingToWhere(pParse, p);
pWhere = p->pWhere; pWhere = p->pWhere;
} }
sqlite3ExprAnalyzeAggregates(&sNC, pHaving); sqlite3ExprAnalyzeAggregates(&sNC, pHaving);

View File

@@ -3357,9 +3357,9 @@ struct Walker {
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
int *aiCol; /* array of column indexes */ int *aiCol; /* array of column indexes */
struct IdxCover *pIdxCover; /* Check for index coverage */ struct IdxCover *pIdxCover; /* Check for index coverage */
struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */ struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
ExprList *pGroupBy; /* GROUP BY clause */ ExprList *pGroupBy; /* GROUP BY clause */
struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */ Select *pSelect; /* HAVING to WHERE clause ctx */
} u; } u;
}; };