|
1 /* |
|
2 ** 2008 August 16 |
|
3 ** |
|
4 ** The author disclaims copyright to this source code. In place of |
|
5 ** a legal notice, here is a blessing: |
|
6 ** |
|
7 ** May you do good and not evil. |
|
8 ** May you find forgiveness for yourself and forgive others. |
|
9 ** May you share freely, never taking more than you give. |
|
10 ** |
|
11 ************************************************************************* |
|
12 ** This file contains routines used for walking the parser tree for |
|
13 ** an SQL statement. |
|
14 ** |
|
15 ** $Id: walker.c,v 1.1 2008/08/20 16:35:10 drh Exp $ |
|
16 */ |
|
17 #include "sqliteInt.h" |
|
18 #include <stdlib.h> |
|
19 #include <string.h> |
|
20 |
|
21 |
|
22 /* |
|
23 ** Walk an expression tree. Invoke the callback once for each node |
|
24 ** of the expression, while decending. (In other words, the callback |
|
25 ** is invoked before visiting children.) |
|
26 ** |
|
27 ** The return value from the callback should be one of the WRC_* |
|
28 ** constants to specify how to proceed with the walk. |
|
29 ** |
|
30 ** WRC_Continue Continue descending down the tree. |
|
31 ** |
|
32 ** WRC_Prune Do not descend into child nodes. But allow |
|
33 ** the walk to continue with sibling nodes. |
|
34 ** |
|
35 ** WRC_Abort Do no more callbacks. Unwind the stack and |
|
36 ** return the top-level walk call. |
|
37 ** |
|
38 ** The return value from this routine is WRC_Abort to abandon the tree walk |
|
39 ** and WRC_Continue to continue. |
|
40 */ |
|
41 int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ |
|
42 int rc; |
|
43 if( pExpr==0 ) return WRC_Continue; |
|
44 rc = pWalker->xExprCallback(pWalker, pExpr); |
|
45 if( rc==WRC_Continue ){ |
|
46 if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; |
|
47 if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; |
|
48 if( sqlite3WalkExprList(pWalker, pExpr->pList) ) return WRC_Abort; |
|
49 if( sqlite3WalkSelect(pWalker, pExpr->pSelect) ){ |
|
50 return WRC_Abort; |
|
51 } |
|
52 } |
|
53 return rc & WRC_Abort; |
|
54 } |
|
55 |
|
56 /* |
|
57 ** Call sqlite3WalkExpr() for every expression in list p or until |
|
58 ** an abort request is seen. |
|
59 */ |
|
60 int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ |
|
61 int i, rc = WRC_Continue; |
|
62 struct ExprList_item *pItem; |
|
63 if( p ){ |
|
64 for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ |
|
65 if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; |
|
66 } |
|
67 } |
|
68 return rc & WRC_Continue; |
|
69 } |
|
70 |
|
71 /* |
|
72 ** Walk all expressions associated with SELECT statement p. Do |
|
73 ** not invoke the SELECT callback on p, but do (of course) invoke |
|
74 ** any expr callbacks and SELECT callbacks that come from subqueries. |
|
75 ** Return WRC_Abort or WRC_Continue. |
|
76 */ |
|
77 int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ |
|
78 if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; |
|
79 if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; |
|
80 if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; |
|
81 if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; |
|
82 if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; |
|
83 if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; |
|
84 if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; |
|
85 return WRC_Continue; |
|
86 } |
|
87 |
|
88 /* |
|
89 ** Walk the parse trees associated with all subqueries in the |
|
90 ** FROM clause of SELECT statement p. Do not invoke the select |
|
91 ** callback on p, but do invoke it on each FROM clause subquery |
|
92 ** and on any subqueries further down in the tree. Return |
|
93 ** WRC_Abort or WRC_Continue; |
|
94 */ |
|
95 int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ |
|
96 SrcList *pSrc; |
|
97 int i; |
|
98 struct SrcList_item *pItem; |
|
99 |
|
100 pSrc = p->pSrc; |
|
101 if( pSrc ){ |
|
102 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ |
|
103 if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ |
|
104 return WRC_Abort; |
|
105 } |
|
106 } |
|
107 } |
|
108 return WRC_Continue; |
|
109 } |
|
110 |
|
111 /* |
|
112 ** Call sqlite3WalkExpr() for every expression in Select statement p. |
|
113 ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and |
|
114 ** on the compound select chain, p->pPrior. |
|
115 ** |
|
116 ** Return WRC_Continue under normal conditions. Return WRC_Abort if |
|
117 ** there is an abort request. |
|
118 ** |
|
119 ** If the Walker does not have an xSelectCallback() then this routine |
|
120 ** is a no-op returning WRC_Continue. |
|
121 */ |
|
122 int sqlite3WalkSelect(Walker *pWalker, Select *p){ |
|
123 int rc; |
|
124 if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue; |
|
125 rc = WRC_Continue; |
|
126 while( p ){ |
|
127 rc = pWalker->xSelectCallback(pWalker, p); |
|
128 if( rc ) break; |
|
129 if( sqlite3WalkSelectExpr(pWalker, p) ) return WRC_Abort; |
|
130 if( sqlite3WalkSelectFrom(pWalker, p) ) return WRC_Abort; |
|
131 p = p->pPrior; |
|
132 } |
|
133 return rc & WRC_Abort; |
|
134 } |