aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-04-25 00:57:10 +0000
committerdrh <drh@noemail.net>2013-04-25 00:57:10 +0000
commitaa87f9a68b5ac0305699507574cb2ed074e722b8 (patch)
tree02f0a9ef2946b21e63b3173c9e4fbddc86a47e16 /src
parented17167e1dc966bfb871aea8297206991eac2794 (diff)
downloadsqlite-aa87f9a68b5ac0305699507574cb2ed074e722b8.tar.gz
sqlite-aa87f9a68b5ac0305699507574cb2ed074e722b8.zip
Make sure the affinity and datatype of sub-subqueries are initialized
prior to subqueries as the latter relies on the former. FossilOrigin-Name: 39b4e6ff9316cc78ea88349091e195b8104d1e9e
Diffstat (limited to 'src')
-rw-r--r--src/expr.c3
-rw-r--r--src/resolve.c2
-rw-r--r--src/select.c3
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/walker.c17
5 files changed, 22 insertions, 4 deletions
diff --git a/src/expr.c b/src/expr.c
index ae6a1dec1..a974c5a61 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1214,6 +1214,7 @@ static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
}
static int exprIsConst(Expr *p, int initFlag){
Walker w;
+ memset(&w, 0, sizeof(w));
w.u.i = initFlag;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = selectNodeIsConstant;
@@ -3428,8 +3429,8 @@ void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
Walker w;
if( pParse->cookieGoto ) return;
if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
+ memset(&w, 0, sizeof(w));
w.xExprCallback = evalConstExpr;
- w.xSelectCallback = 0;
w.pParse = pParse;
sqlite3WalkExpr(&w, pExpr);
}
diff --git a/src/resolve.c b/src/resolve.c
index 9b350caf8..a8e196926 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -1283,6 +1283,7 @@ int sqlite3ResolveExprNames(
#endif
savedHasAgg = pNC->ncFlags & NC_HasAgg;
pNC->ncFlags &= ~NC_HasAgg;
+ memset(&w, 0, sizeof(w));
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pNC->pParse;
@@ -1323,6 +1324,7 @@ void sqlite3ResolveSelectNames(
Walker w;
assert( p!=0 );
+ memset(&w, 0, sizeof(w));
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pParse;
diff --git a/src/select.c b/src/select.c
index 1daa5bed3..a745dc370 100644
--- a/src/select.c
+++ b/src/select.c
@@ -3576,6 +3576,7 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
*/
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
Walker w;
+ memset(&w, 0, sizeof(w));
w.xSelectCallback = selectExpander;
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
@@ -3634,9 +3635,11 @@ static int 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 = selectAddSubqueryTypeInfo;
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
+ w.bSelectDepthFirst = 1;
sqlite3WalkSelect(&w, pSelect);
#endif
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 3722041b0..876629a8c 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2588,6 +2588,7 @@ struct Walker {
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
Parse *pParse; /* Parser context. */
int walkerDepth; /* Number of subqueries */
+ u8 bSelectDepthFirst; /* Do subqueries first */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int i; /* Integer value */
diff --git a/src/walker.c b/src/walker.c
index eab96ea24..e71ed2ac4 100644
--- a/src/walker.c
+++ b/src/walker.c
@@ -113,7 +113,9 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
/*
** Call sqlite3WalkExpr() for every expression in Select statement p.
** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and
-** on the compound select chain, p->pPrior.
+** on the compound select chain, p->pPrior. Invoke the xSelectCallback()
+** either before or after the walk of expressions and FROM clause, depending
+** on whether pWalker->bSelectDepthFirst is false or true, respectively.
**
** Return WRC_Continue under normal conditions. Return WRC_Abort if
** there is an abort request.
@@ -127,14 +129,23 @@ int sqlite3WalkSelect(Walker *pWalker, Select *p){
rc = WRC_Continue;
pWalker->walkerDepth++;
while( p ){
- rc = pWalker->xSelectCallback(pWalker, p);
- if( rc ) break;
+ if( !pWalker->bSelectDepthFirst ){
+ rc = pWalker->xSelectCallback(pWalker, p);
+ if( rc ) break;
+ }
if( sqlite3WalkSelectExpr(pWalker, p)
|| sqlite3WalkSelectFrom(pWalker, p)
){
pWalker->walkerDepth--;
return WRC_Abort;
}
+ if( pWalker->bSelectDepthFirst ){
+ rc = pWalker->xSelectCallback(pWalker, p);
+ /* Depth-first search is currently only used for
+ ** selectAddSubqueryTypeInfo() and that routine always returns
+ ** WRC_Continue (0). So the following branch is never taken. */
+ if( NEVER(rc) ) break;
+ }
p = p->pPrior;
}
pWalker->walkerDepth--;