-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
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
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
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
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
-43c9ae371f6250fee98a7c4011726eff8ad37f5a97add4f490ac3a2dd501a0d2
\ No newline at end of file
+6854a34ed708259f2280f7ee56cec09f7fc99810dc739dc2814ddeae286aa2c4
\ No newline at end of file
}
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;
*/
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);
*/
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;
}
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;
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
*/
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);
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
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);
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
*/
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;
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;
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
**
** 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.
*/
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;
}