From: drh Date: Mon, 29 May 2017 14:26:07 +0000 (+0000) Subject: Optimizations to the Walker object and its methods to make the code a little X-Git-Tag: version-3.20.0~240 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=979dd1be5710eb2ed38a46b1712cf5da74947c2a;p=thirdparty%2Fsqlite.git Optimizations to the Walker object and its methods to make the code a little smaller and to help it run a little faster. FossilOrigin-Name: 6854a34ed708259f2280f7ee56cec09f7fc99810dc739dc2814ddeae286aa2c4 --- diff --git a/manifest b/manifest index fcb8b8238e..36f2144283 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\sinitialize\sthe\siSelectId\sof\sFROM\sclause\sterms\sthat\sare\sa\sself\njoin\sof\sa\sreused\smaterialized\ssubquery.\s\sWithout\sthis,\sthe\sEXPLAIN\sQUERY\sPLAN\noutput\sfor\sthe\squery\swill\sidentify\sthe\ssubquery\susing\sthe\suninitialized\n(and\sarbitrary)\siSelectId. -D 2017-05-29T13:09:24.519 +C Optimizations\sto\sthe\sWalker\sobject\sand\sits\smethods\sto\smake\sthe\scode\sa\slittle\nsmaller\sand\sto\shelp\sit\srun\sa\slittle\sfaster. +D 2017-05-29T14:26:07.045 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc @@ -357,7 +357,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c cc42a41c7422389860d40419a5e3bce5eaf6e7835c3ba2677751dc653550a5c7 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c bc2bfc227002ebe091e7cc321f09a48e52f86e1cd5ff9b028009db0671556749 -F src/expr.c 30f61b7d8236def0e99485651e5d983a102afa4cbc8b1ef0ab19ccb1f3841f99 +F src/expr.c 82ccc704a2e5aa114f2a2c67610b87963add6d65336f352bb1782a2942356bcb F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c db65492ae549c3b548c9ef1f279ce1684f1c473b116e1c56a90878cd5dcf968d F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -402,14 +402,14 @@ F src/pragma.h 37a1311d0388db480388d7ec09054f7103045eff20d4971f8a433b77f40b9921 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 +F src/resolve.c ffb69e203f18a7c4013c0b37e657e19abd61379c92480dbbd582bd365c5876aa F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c ecdb34eb3393633ca98f5e1a4228d83da3fb838a37db7bb5a3e2f838b2e52658 +F src/select.c fd0a17fb78130fe840a33024888d41c77ed0bab0340b72cf71b1558d5f465e88 F src/shell.c 3f761fe604174b31aacd2ea2eacef5e6fe550111d60c0d71532cc008c68cf3f3 F src/sqlite.h.in 8dd468837a4f6d76713e3a4cc65bea48095009038593d41040ab46c1b351197f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 -F src/sqliteInt.h aea3aa1b81e0d07d5b1c39b8c5a54a1dc5e4f10136cb63da392aef9eb2a5108b +F src/sqliteInt.h 80c485ad08b1091a6148637c1b9c334be6ab39cb0d28b839bab96e6783b9d006 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -484,7 +484,7 @@ F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 -F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 +F src/walker.c d46044e7a5842560dfe7122d93ff5145dd4a96f4d0bf5ba5910a7731b8c01e79 F src/where.c 67f98714b07ec3c1d5e033a63d23c0fd70c24861b7b46b69b10700f22dca6ffe F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20 F src/wherecode.c 8ad48867660519e262a401720845dc76934f86f558ec9606335fafcd7a2554f8 @@ -1581,7 +1581,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cc940a97efc096ff3725710f526c06f52453bd923fb9e825ce6990275df747a -R 35dcf48f31a7a8cf76b469de7e6b34dc +P 43c9ae371f6250fee98a7c4011726eff8ad37f5a97add4f490ac3a2dd501a0d2 +R 453c4ffd0fd2d3ef84551e2d5c6aff9e U drh -Z 3804513f19d04eacb2ef4a093a6026f8 +Z 17a17047de4968bc6d150d2777390a09 diff --git a/manifest.uuid b/manifest.uuid index c803b5e6fc..61857b1385 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -43c9ae371f6250fee98a7c4011726eff8ad37f5a97add4f490ac3a2dd501a0d2 \ No newline at end of file +6854a34ed708259f2280f7ee56cec09f7fc99810dc739dc2814ddeae286aa2c4 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 201dedcc8a..707dfe4563 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1772,10 +1772,12 @@ static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){ } static int exprIsConst(Expr *p, int initFlag, int iCur){ Walker w; - memset(&w, 0, sizeof(w)); w.eCode = initFlag; w.xExprCallback = exprNodeIsConstant; w.xSelectCallback = selectNodeIsConstant; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif w.u.iCur = iCur; sqlite3WalkExpr(&w, p); return w.eCode; @@ -1863,9 +1865,9 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ */ int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ Walker w; - memset(&w, 0, sizeof(w)); w.eCode = 1; w.xExprCallback = exprNodeIsConstantOrGroupBy; + w.xSelectCallback = 0; w.u.pGroupBy = pGroupBy; w.pParse = pParse; sqlite3WalkExpr(&w, p); @@ -1893,10 +1895,12 @@ int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ */ int sqlite3ExprContainsSubquery(Expr *p){ Walker w; - memset(&w, 0, sizeof(w)); w.eCode = 1; w.xExprCallback = sqlite3ExprWalkNoop; w.xSelectCallback = selectNodeIsConstant; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif sqlite3WalkExpr(&w, p); return w.eCode==0; } @@ -4901,8 +4905,8 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ Walker w; struct SrcCount cnt; assert( pExpr->op==TK_AGG_FUNCTION ); - memset(&w, 0, sizeof(w)); w.xExprCallback = exprSrcCount; + w.xSelectCallback = 0; w.u.pSrcCount = &cnt; cnt.pSrc = pSrcList; cnt.nThis = 0; @@ -5074,10 +5078,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ - UNUSED_PARAMETER(pWalker); UNUSED_PARAMETER(pSelect); + pWalker->walkerDepth++; return WRC_Continue; } +static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){ + UNUSED_PARAMETER(pSelect); + pWalker->walkerDepth--; +} /* ** Analyze the pExpr expression looking for aggregate functions and @@ -5090,9 +5098,10 @@ static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ */ void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ Walker w; - memset(&w, 0, sizeof(w)); w.xExprCallback = analyzeAggregate; w.xSelectCallback = analyzeAggregatesInSelect; + w.xSelectCallback2 = analyzeAggregatesInSelectEnd; + w.walkerDepth = 0; w.u.pNC = pNC; assert( pNC->pSrcList!=0 ); sqlite3WalkExpr(&w, pExpr); diff --git a/src/resolve.c b/src/resolve.c index 6b3caa625a..aed48260ec 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1446,8 +1446,6 @@ int sqlite3ResolveExprNames( w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; w.xSelectCallback2 = 0; - w.walkerDepth = 0; - w.eCode = 0; w.u.pNC = pNC; sqlite3WalkExpr(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 @@ -1501,9 +1499,9 @@ void sqlite3ResolveSelectNames( Walker w; assert( p!=0 ); - memset(&w, 0, sizeof(w)); w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; + w.xSelectCallback2 = 0; w.pParse = pParse; w.u.pNC = pOuterNC; sqlite3WalkSelect(&w, p); diff --git a/src/select.c b/src/select.c index a8547f8112..9d4c159198 100644 --- a/src/select.c +++ b/src/select.c @@ -4610,6 +4610,25 @@ int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ return WRC_Continue; } +/* +** No-op routine for the parse-tree walker for SELECT statements. +** subquery in the parser tree. +*/ +int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +#if SQLITE_DEBUG +/* +** Always assert. This xSelectCallback2 implementation proves that the +** xSelectCallback2 is never invoked. +*/ +void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + assert( 0 ); +} +#endif /* ** This routine "expands" a SELECT statement and all of its subqueries. ** For additional information on what it means to "expand" a SELECT @@ -4625,11 +4644,11 @@ int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ */ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ Walker w; - memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; if( pParse->hasCompound ){ w.xSelectCallback = convertCompoundSelectToSubquery; + w.xSelectCallback2 = 0; sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; @@ -4689,7 +4708,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ #ifndef SQLITE_OMIT_SUBQUERY Walker w; - memset(&w, 0, sizeof(w)); + w.xSelectCallback = sqlite3SelectWalkNoop; w.xSelectCallback2 = selectAddSubqueryTypeInfo; w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fc24885e28..7c78fdb426 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3337,6 +3337,10 @@ int sqlite3WalkSelect(Walker*, Select*); int sqlite3WalkSelectExpr(Walker*, Select*); int sqlite3WalkSelectFrom(Walker*, Select*); int sqlite3ExprWalkNoop(Walker*, Expr*); +int sqlite3SelectWalkNoop(Walker*, Select*); +#ifdef SQLITE_DEBUG +void sqlite3SelectWalkAssert2(Walker*, Select*); +#endif /* ** Return code from the parse-tree walking primitives and their diff --git a/src/walker.c b/src/walker.c index a7123d8ab0..dc874a259d 100644 --- a/src/walker.c +++ b/src/walker.c @@ -124,8 +124,9 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ ** ** If it is not NULL, the xSelectCallback() callback is invoked before ** the walk of the expressions and FROM clause. The xSelectCallback2() -** method, if it is not NULL, is invoked following the walk of the -** expressions and FROM clause. +** method is invoked following the walk of the expressions and FROM clause, +** but only if both xSelectCallback and xSelectCallback2 are both non-NULL +** and if the expressions and FROM clause both return WRC_Continue; ** ** Return WRC_Continue under normal conditions. Return WRC_Abort if ** there is an abort request. @@ -135,27 +136,19 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ */ int sqlite3WalkSelect(Walker *pWalker, Select *p){ int rc; - if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){ - return WRC_Continue; - } - rc = WRC_Continue; - pWalker->walkerDepth++; - while( p ){ - if( pWalker->xSelectCallback ){ - rc = pWalker->xSelectCallback(pWalker, p); - if( rc ) break; - } + if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue; + do{ + rc = pWalker->xSelectCallback(pWalker, p); + if( rc ) return rc & WRC_Abort; if( sqlite3WalkSelectExpr(pWalker, p) || sqlite3WalkSelectFrom(pWalker, p) ){ - pWalker->walkerDepth--; return WRC_Abort; } if( pWalker->xSelectCallback2 ){ pWalker->xSelectCallback2(pWalker, p); } p = p->pPrior; - } - pWalker->walkerDepth--; - return rc & WRC_Abort; + }while( p!=0 ); + return WRC_Continue; }