wasCSharpSQLite – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Text; |
||
4 | |||
5 | using Bitmask = System.UInt64; |
||
6 | using u32 = System.UInt32; |
||
7 | |||
8 | namespace Community.CsharpSqlite |
||
9 | { |
||
10 | public partial class Sqlite3 |
||
11 | { |
||
12 | /* |
||
13 | ** 2008 August 16 |
||
14 | ** |
||
15 | ** The author disclaims copyright to this source code. In place of |
||
16 | ** a legal notice, here is a blessing: |
||
17 | ** |
||
18 | ** May you do good and not evil. |
||
19 | ** May you find forgiveness for yourself and forgive others. |
||
20 | ** May you share freely, never taking more than you give. |
||
21 | ** |
||
22 | ************************************************************************* |
||
23 | ** This file contains routines used for walking the parser tree for |
||
24 | ** an SQL statement. |
||
25 | ************************************************************************* |
||
26 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
27 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
28 | ** |
||
29 | ** SQLITE_SOURCE_ID: 2010-08-23 18:52:01 42537b60566f288167f1b5864a5435986838e3a3 |
||
30 | ** |
||
31 | ************************************************************************* |
||
32 | */ |
||
33 | //#include "sqliteInt.h" |
||
34 | //#include <stdlib.h> |
||
35 | //#include <string.h> |
||
36 | |||
37 | |||
38 | /* |
||
39 | ** Walk an expression tree. Invoke the callback once for each node |
||
40 | ** of the expression, while decending. (In other words, the callback |
||
41 | ** is invoked before visiting children.) |
||
42 | ** |
||
43 | ** The return value from the callback should be one of the WRC_* |
||
44 | ** constants to specify how to proceed with the walk. |
||
45 | ** |
||
46 | ** WRC_Continue Continue descending down the tree. |
||
47 | ** |
||
48 | ** WRC_Prune Do not descend into child nodes. But allow |
||
49 | ** the walk to continue with sibling nodes. |
||
50 | ** |
||
51 | ** WRC_Abort Do no more callbacks. Unwind the stack and |
||
52 | ** return the top-level walk call. |
||
53 | ** |
||
54 | ** The return value from this routine is WRC_Abort to abandon the tree walk |
||
55 | ** and WRC_Continue to continue. |
||
56 | */ |
||
57 | static int sqlite3WalkExpr( Walker pWalker, ref Expr pExpr ) |
||
58 | { |
||
59 | int rc; |
||
60 | if ( pExpr == null ) |
||
61 | return WRC_Continue; |
||
62 | testcase( ExprHasProperty( pExpr, EP_TokenOnly ) ); |
||
63 | testcase( ExprHasProperty( pExpr, EP_Reduced ) ); |
||
64 | rc = pWalker.xExprCallback( pWalker, ref pExpr ); |
||
65 | if ( rc == WRC_Continue |
||
66 | && !ExprHasAnyProperty( pExpr, EP_TokenOnly ) ) |
||
67 | { |
||
68 | if ( sqlite3WalkExpr( pWalker, ref pExpr.pLeft ) != 0 ) |
||
69 | return WRC_Abort; |
||
70 | if ( sqlite3WalkExpr( pWalker, ref pExpr.pRight ) != 0 ) |
||
71 | return WRC_Abort; |
||
72 | if ( ExprHasProperty( pExpr, EP_xIsSelect ) ) |
||
73 | { |
||
74 | if ( sqlite3WalkSelect( pWalker, pExpr.x.pSelect ) != 0 ) |
||
75 | return WRC_Abort; |
||
76 | } |
||
77 | else |
||
78 | { |
||
79 | if ( sqlite3WalkExprList( pWalker, pExpr.x.pList ) != 0 ) |
||
80 | return WRC_Abort; |
||
81 | } |
||
82 | } |
||
83 | return rc & WRC_Abort; |
||
84 | } |
||
85 | |||
86 | /* |
||
87 | ** Call sqlite3WalkExpr() for every expression in list p or until |
||
88 | ** an abort request is seen. |
||
89 | */ |
||
90 | static int sqlite3WalkExprList( Walker pWalker, ExprList p ) |
||
91 | { |
||
92 | int i; |
||
93 | ExprList_item pItem; |
||
94 | if ( p != null ) |
||
95 | { |
||
96 | for ( i = p.nExpr; i > 0; i-- ) |
||
97 | {//, pItem++){ |
||
98 | pItem = p.a[p.nExpr - i]; |
||
99 | if ( sqlite3WalkExpr( pWalker, ref pItem.pExpr ) != 0 ) |
||
100 | return WRC_Abort; |
||
101 | } |
||
102 | } |
||
103 | return WRC_Continue; |
||
104 | } |
||
105 | |||
106 | /* |
||
107 | ** Walk all expressions associated with SELECT statement p. Do |
||
108 | ** not invoke the SELECT callback on p, but do (of course) invoke |
||
109 | ** any expr callbacks and SELECT callbacks that come from subqueries. |
||
110 | ** Return WRC_Abort or WRC_Continue. |
||
111 | */ |
||
112 | static int sqlite3WalkSelectExpr( Walker pWalker, Select p ) |
||
113 | { |
||
114 | if ( sqlite3WalkExprList( pWalker, p.pEList ) != 0 ) |
||
115 | return WRC_Abort; |
||
116 | if ( sqlite3WalkExpr( pWalker, ref p.pWhere ) != 0 ) |
||
117 | return WRC_Abort; |
||
118 | if ( sqlite3WalkExprList( pWalker, p.pGroupBy ) != 0 ) |
||
119 | return WRC_Abort; |
||
120 | if ( sqlite3WalkExpr( pWalker, ref p.pHaving ) != 0 ) |
||
121 | return WRC_Abort; |
||
122 | if ( sqlite3WalkExprList( pWalker, p.pOrderBy ) != 0 ) |
||
123 | return WRC_Abort; |
||
124 | if ( sqlite3WalkExpr( pWalker, ref p.pLimit ) != 0 ) |
||
125 | return WRC_Abort; |
||
126 | if ( sqlite3WalkExpr( pWalker, ref p.pOffset ) != 0 ) |
||
127 | return WRC_Abort; |
||
128 | return WRC_Continue; |
||
129 | } |
||
130 | |||
131 | /* |
||
132 | ** Walk the parse trees associated with all subqueries in the |
||
133 | ** FROM clause of SELECT statement p. Do not invoke the select |
||
134 | ** callback on p, but do invoke it on each FROM clause subquery |
||
135 | ** and on any subqueries further down in the tree. Return |
||
136 | ** WRC_Abort or WRC_Continue; |
||
137 | */ |
||
138 | static int sqlite3WalkSelectFrom( Walker pWalker, Select p ) |
||
139 | { |
||
140 | SrcList pSrc; |
||
141 | int i; |
||
142 | SrcList_item pItem; |
||
143 | |||
144 | pSrc = p.pSrc; |
||
145 | if ( ALWAYS( pSrc ) ) |
||
146 | { |
||
147 | for ( i = pSrc.nSrc; i > 0; i-- )// pItem++ ) |
||
148 | { |
||
149 | pItem = pSrc.a[pSrc.nSrc - i]; |
||
150 | if ( sqlite3WalkSelect( pWalker, pItem.pSelect ) != 0 ) |
||
151 | { |
||
152 | return WRC_Abort; |
||
153 | } |
||
154 | } |
||
155 | } |
||
156 | return WRC_Continue; |
||
157 | } |
||
158 | |||
159 | /* |
||
160 | ** Call sqlite3WalkExpr() for every expression in Select statement p. |
||
161 | ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and |
||
162 | ** on the compound select chain, p.pPrior. |
||
163 | ** |
||
164 | ** Return WRC_Continue under normal conditions. Return WRC_Abort if |
||
165 | ** there is an abort request. |
||
166 | ** |
||
167 | ** If the Walker does not have an xSelectCallback() then this routine |
||
168 | ** is a no-op returning WRC_Continue. |
||
169 | */ |
||
170 | static int sqlite3WalkSelect( Walker pWalker, Select p ) |
||
171 | { |
||
172 | int rc; |
||
173 | if ( p == null || pWalker.xSelectCallback == null ) |
||
174 | return WRC_Continue; |
||
175 | rc = WRC_Continue; |
||
176 | while ( p != null ) |
||
177 | { |
||
178 | rc = pWalker.xSelectCallback( pWalker, p ); |
||
179 | if ( rc != 0 ) |
||
180 | break; |
||
181 | if ( sqlite3WalkSelectExpr( pWalker, p ) != 0 ) |
||
182 | return WRC_Abort; |
||
183 | if ( sqlite3WalkSelectFrom( pWalker, p ) != 0 ) |
||
184 | return WRC_Abort; |
||
185 | p = p.pPrior; |
||
186 | } |
||
187 | return rc & WRC_Abort; |
||
188 | } |
||
189 | } |
||
190 | } |