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 i16 = System.Int16; |
||
7 | using u8 = System.Byte; |
||
8 | using u16 = System.UInt16; |
||
9 | using u32 = System.UInt32; |
||
10 | |||
11 | #if !SQLITE_MAX_VARIABLE_NUMBER |
||
12 | using ynVar = System.Int16; |
||
13 | #else |
||
14 | using ynVar = System.Int32; |
||
15 | #endif |
||
16 | |||
17 | namespace Community.CsharpSqlite |
||
18 | { |
||
19 | using sqlite3_value = Sqlite3.Mem; |
||
20 | |||
21 | public partial class Sqlite3 |
||
22 | { |
||
23 | /* |
||
24 | ** 2008 August 18 |
||
25 | ** |
||
26 | ** The author disclaims copyright to this source code. In place of |
||
27 | ** a legal notice, here is a blessing: |
||
28 | ** |
||
29 | ** May you do good and not evil. |
||
30 | ** May you find forgiveness for yourself and forgive others. |
||
31 | ** May you share freely, never taking more than you give. |
||
32 | ** |
||
33 | ************************************************************************* |
||
34 | ** |
||
35 | ** This file contains routines used for walking the parser tree and |
||
36 | ** resolve all identifiers by associating them with a particular |
||
37 | ** table and column. |
||
38 | ************************************************************************* |
||
39 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
40 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
41 | ** |
||
42 | ** SQLITE_SOURCE_ID: 2010-08-23 18:52:01 42537b60566f288167f1b5864a5435986838e3a3 |
||
43 | ** |
||
44 | ************************************************************************* |
||
45 | */ |
||
46 | //#include "sqliteInt.h" |
||
47 | //#include <stdlib.h> |
||
48 | //#include <string.h> |
||
49 | |||
50 | /* |
||
51 | ** Turn the pExpr expression into an alias for the iCol-th column of the |
||
52 | ** result set in pEList. |
||
53 | ** |
||
54 | ** If the result set column is a simple column reference, then this routine |
||
55 | ** makes an exact copy. But for any other kind of expression, this |
||
56 | ** routine make a copy of the result set column as the argument to the |
||
57 | ** TK_AS operator. The TK_AS operator causes the expression to be |
||
58 | ** evaluated just once and then reused for each alias. |
||
59 | ** |
||
60 | ** The reason for suppressing the TK_AS term when the expression is a simple |
||
61 | ** column reference is so that the column reference will be recognized as |
||
62 | ** usable by indices within the WHERE clause processing logic. |
||
63 | ** |
||
64 | ** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means |
||
65 | ** that in a GROUP BY clause, the expression is evaluated twice. Hence: |
||
66 | ** |
||
67 | ** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x |
||
68 | ** |
||
69 | ** Is equivalent to: |
||
70 | ** |
||
71 | ** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5 |
||
72 | ** |
||
73 | ** The result of random()%5 in the GROUP BY clause is probably different |
||
74 | ** from the result in the result-set. We might fix this someday. Or |
||
75 | ** then again, we might not... |
||
76 | */ |
||
77 | static void resolveAlias( |
||
78 | Parse pParse, /* Parsing context */ |
||
79 | ExprList pEList, /* A result set */ |
||
80 | int iCol, /* A column in the result set. 0..pEList.nExpr-1 */ |
||
81 | Expr pExpr, /* Transform this into an alias to the result set */ |
||
82 | string zType /* "GROUP" or "ORDER" or "" */ |
||
83 | ) |
||
84 | { |
||
85 | Expr pOrig; /* The iCol-th column of the result set */ |
||
86 | Expr pDup; /* Copy of pOrig */ |
||
87 | sqlite3 db; /* The database connection */ |
||
88 | |||
89 | Debug.Assert( iCol >= 0 && iCol < pEList.nExpr ); |
||
90 | pOrig = pEList.a[iCol].pExpr; |
||
91 | Debug.Assert( pOrig != null ); |
||
92 | Debug.Assert( ( pOrig.flags & EP_Resolved ) != 0 ); |
||
93 | db = pParse.db; |
||
94 | if ( pOrig.op != TK_COLUMN && ( zType.Length == 0 || zType[0] != 'G' ) ) |
||
95 | { |
||
96 | pDup = sqlite3ExprDup( db, pOrig, 0 ); |
||
97 | pDup = sqlite3PExpr( pParse, TK_AS, pDup, null, null ); |
||
98 | if ( pDup == null ) |
||
99 | return; |
||
100 | if ( pEList.a[iCol].iAlias == 0 ) |
||
101 | { |
||
102 | pEList.a[iCol].iAlias = (u16)( ++pParse.nAlias ); |
||
103 | } |
||
104 | pDup.iTable = pEList.a[iCol].iAlias; |
||
105 | } |
||
106 | else if ( ExprHasProperty( pOrig, EP_IntValue ) || pOrig.u.zToken == null ) |
||
107 | { |
||
108 | pDup = sqlite3ExprDup( db, pOrig, 0 ); |
||
109 | if ( pDup == null ) |
||
110 | return; |
||
111 | } |
||
112 | else |
||
113 | { |
||
114 | string zToken = pOrig.u.zToken; |
||
115 | Debug.Assert( zToken != null ); |
||
116 | pOrig.u.zToken = null; |
||
117 | pDup = sqlite3ExprDup( db, pOrig, 0 ); |
||
118 | pOrig.u.zToken = zToken; |
||
119 | if ( pDup == null ) |
||
120 | return; |
||
121 | Debug.Assert( ( pDup.flags & ( EP_Reduced | EP_TokenOnly ) ) == 0 ); |
||
122 | pDup.flags2 |= EP2_MallocedToken; |
||
123 | pDup.u.zToken = zToken;// sqlite3DbStrDup( db, zToken ); |
||
124 | } |
||
125 | if ( ( pExpr.flags & EP_ExpCollate ) != 0 ) |
||
126 | { |
||
127 | pDup.pColl = pExpr.pColl; |
||
128 | pDup.flags |= EP_ExpCollate; |
||
129 | } |
||
130 | |||
131 | /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This |
||
132 | ** prevents ExprDelete() from deleting the Expr structure itself, |
||
133 | ** allowing it to be repopulated by the memcpy() on the following line. |
||
134 | */ |
||
135 | ExprSetProperty( pExpr, EP_Static ); |
||
136 | sqlite3ExprDelete( db, ref pExpr ); |
||
137 | pExpr.CopyFrom( pDup ); //memcpy(pExpr, pDup, sizeof(*pExpr)); |
||
138 | sqlite3DbFree( db, ref pDup ); |
||
139 | } |
||
140 | |||
141 | /* |
||
142 | ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up |
||
143 | ** that name in the set of source tables in pSrcList and make the pExpr |
||
144 | ** expression node refer back to that source column. The following changes |
||
145 | ** are made to pExpr: |
||
146 | ** |
||
147 | ** pExpr->iDb Set the index in db->aDb[] of the database X |
||
148 | ** (even if X is implied). |
||
149 | ** pExpr->iTable Set to the cursor number for the table obtained |
||
150 | ** from pSrcList. |
||
151 | ** pExpr->pTab Points to the Table structure of X.Y (even if |
||
152 | ** X and/or Y are implied.) |
||
153 | ** pExpr->iColumn Set to the column number within the table. |
||
154 | ** pExpr->op Set to TK_COLUMN. |
||
155 | ** pExpr->pLeft Any expression this points to is deleted |
||
156 | ** pExpr->pRight Any expression this points to is deleted. |
||
157 | ** |
||
158 | ** The zDb variable is the name of the database (the "X"). This value may be |
||
159 | ** NULL meaning that name is of the form Y.Z or Z. Any available database |
||
160 | ** can be used. The zTable variable is the name of the table (the "Y"). This |
||
161 | ** value can be NULL if zDb is also NULL. If zTable is NULL it |
||
162 | ** means that the form of the name is Z and that columns from any table |
||
163 | ** can be used. |
||
164 | ** |
||
165 | ** If the name cannot be resolved unambiguously, leave an error message |
||
166 | ** in pParse and return WRC_Abort. Return WRC_Prune on success. |
||
167 | */ |
||
168 | static int lookupName( |
||
169 | Parse pParse, /* The parsing context */ |
||
170 | string zDb, /* Name of the database containing table, or NULL */ |
||
171 | string zTab, /* Name of table containing column, or NULL */ |
||
172 | string zCol, /* Name of the column. */ |
||
173 | NameContext pNC, /* The name context used to resolve the name */ |
||
174 | Expr pExpr /* Make this EXPR node point to the selected column */ |
||
175 | ) |
||
176 | { |
||
177 | int i, j; /* Loop counters */ |
||
178 | int cnt = 0; /* Number of matching column names */ |
||
179 | int cntTab = 0; /* Number of matching table names */ |
||
180 | sqlite3 db = pParse.db; /* The database connection */ |
||
181 | SrcList_item pItem; /* Use for looping over pSrcList items */ |
||
182 | SrcList_item pMatch = null; /* The matching pSrcList item */ |
||
183 | NameContext pTopNC = pNC; /* First namecontext in the list */ |
||
184 | Schema pSchema = null; /* Schema of the expression */ |
||
185 | int isTrigger = 0; |
||
186 | |||
187 | Debug.Assert( pNC != null ); /* the name context cannot be NULL. */ |
||
188 | Debug.Assert( zCol != null ); /* The Z in X.Y.Z cannot be NULL */ |
||
189 | Debug.Assert( !ExprHasAnyProperty( pExpr, EP_TokenOnly | EP_Reduced ) ); |
||
190 | |||
191 | /* Initialize the node to no-match */ |
||
192 | pExpr.iTable = -1; |
||
193 | pExpr.pTab = null; |
||
194 | ExprSetIrreducible( pExpr ); |
||
195 | |||
196 | /* Start at the inner-most context and move outward until a match is found */ |
||
197 | while ( pNC != null && cnt == 0 ) |
||
198 | { |
||
199 | ExprList pEList; |
||
200 | SrcList pSrcList = pNC.pSrcList; |
||
201 | |||
202 | if ( pSrcList != null ) |
||
203 | { |
||
204 | for ( i = 0; i < pSrcList.nSrc; i++ )//, pItem++ ) |
||
205 | { |
||
206 | pItem = pSrcList.a[i]; |
||
207 | Table pTab; |
||
208 | int iDb; |
||
209 | Column pCol; |
||
210 | |||
211 | pTab = pItem.pTab; |
||
212 | Debug.Assert( pTab != null && pTab.zName != null ); |
||
213 | iDb = sqlite3SchemaToIndex( db, pTab.pSchema ); |
||
214 | Debug.Assert( pTab.nCol > 0 ); |
||
215 | if ( zTab != null ) |
||
216 | { |
||
217 | if ( pItem.zAlias != null ) |
||
218 | { |
||
219 | string zTabName = pItem.zAlias; |
||
220 | if ( !zTabName.Equals( zTab, StringComparison.OrdinalIgnoreCase ) ) |
||
221 | continue; |
||
222 | } |
||
223 | else |
||
224 | { |
||
225 | string zTabName = pTab.zName; |
||
226 | if ( NEVER( zTabName == null ) || !zTabName.Equals( zTab ,StringComparison.OrdinalIgnoreCase ) ) |
||
227 | { |
||
228 | continue; |
||
229 | } |
||
230 | if ( zDb != null && !db.aDb[iDb].zName.Equals( zDb ,StringComparison.OrdinalIgnoreCase ) ) |
||
231 | { |
||
232 | continue; |
||
233 | } |
||
234 | } |
||
235 | } |
||
236 | if ( 0 == ( cntTab++ ) ) |
||
237 | { |
||
238 | pExpr.iTable = pItem.iCursor; |
||
239 | pExpr.pTab = pTab; |
||
240 | pSchema = pTab.pSchema; |
||
241 | pMatch = pItem; |
||
242 | } |
||
243 | for ( j = 0; j < pTab.nCol; j++ )//, pCol++ ) |
||
244 | { |
||
245 | pCol = pTab.aCol[j]; |
||
246 | if ( pCol.zName.Equals( zCol, StringComparison.OrdinalIgnoreCase ) ) |
||
247 | { |
||
248 | IdList pUsing; |
||
249 | cnt++; |
||
250 | pExpr.iTable = pItem.iCursor; |
||
251 | pExpr.pTab = pTab; |
||
252 | pMatch = pItem; |
||
253 | pSchema = pTab.pSchema; |
||
254 | /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ |
||
255 | pExpr.iColumn = (short)( j == pTab.iPKey ? -1 : j ); |
||
256 | if ( i < pSrcList.nSrc - 1 ) |
||
257 | { |
||
258 | if ( ( pSrcList.a[i + 1].jointype & JT_NATURAL ) != 0 )// pItem[1].jointype |
||
259 | { |
||
260 | /* If this match occurred in the left table of a natural join, |
||
261 | ** then skip the right table to avoid a duplicate match */ |
||
262 | //pItem++; |
||
263 | i++; |
||
264 | } |
||
265 | else if ( ( pUsing = pSrcList.a[i + 1].pUsing ) != null )//pItem[1].pUsing |
||
266 | { |
||
267 | /* If this match occurs on a column that is in the USING clause |
||
268 | ** of a join, skip the search of the right table of the join |
||
269 | ** to avoid a duplicate match there. */ |
||
270 | int k; |
||
271 | for ( k = 0; k < pUsing.nId; k++ ) |
||
272 | { |
||
273 | if ( pUsing.a[k].zName.Equals( zCol ,StringComparison.OrdinalIgnoreCase ) ) |
||
274 | { |
||
275 | //pItem++; |
||
276 | i++; |
||
277 | break; |
||
278 | } |
||
279 | } |
||
280 | } |
||
281 | } |
||
282 | break; |
||
283 | } |
||
284 | } |
||
285 | } |
||
286 | } |
||
287 | |||
288 | #if !SQLITE_OMIT_TRIGGER |
||
289 | /* If we have not already resolved the name, then maybe |
||
290 | ** it is a new.* or old.* trigger argument reference |
||
291 | */ |
||
292 | if ( zDb == null && zTab != null && cnt == 0 && pParse.pTriggerTab != null ) |
||
293 | { |
||
294 | int op = pParse.eTriggerOp; |
||
295 | Table pTab = null; |
||
296 | Debug.Assert( op == TK_DELETE || op == TK_UPDATE || op == TK_INSERT ); |
||
297 | if ( op != TK_DELETE && "new".Equals( zTab ,StringComparison.OrdinalIgnoreCase ) ) |
||
298 | { |
||
299 | pExpr.iTable = 1; |
||
300 | pTab = pParse.pTriggerTab; |
||
301 | } |
||
302 | else if ( op != TK_INSERT && "old".Equals( zTab ,StringComparison.OrdinalIgnoreCase ) ) |
||
303 | { |
||
304 | pExpr.iTable = 0; |
||
305 | pTab = pParse.pTriggerTab; |
||
306 | } |
||
307 | |||
308 | if ( pTab != null ) |
||
309 | { |
||
310 | int iCol; |
||
311 | pSchema = pTab.pSchema; |
||
312 | cntTab++; |
||
313 | for ( iCol = 0; iCol < pTab.nCol; iCol++ ) |
||
314 | { |
||
315 | Column pCol = pTab.aCol[iCol]; |
||
316 | if ( pCol.zName.Equals( zCol ,StringComparison.OrdinalIgnoreCase ) ) |
||
317 | { |
||
318 | if ( iCol == pTab.iPKey ) |
||
319 | { |
||
320 | iCol = -1; |
||
321 | } |
||
322 | break; |
||
323 | } |
||
324 | } |
||
325 | if ( iCol >= pTab.nCol && sqlite3IsRowid( zCol ) ) |
||
326 | { |
||
327 | iCol = -1; /* IMP: R-44911-55124 */ |
||
328 | } |
||
329 | if ( iCol < pTab.nCol ) |
||
330 | { |
||
331 | cnt++; |
||
332 | if ( iCol < 0 ) |
||
333 | { |
||
334 | pExpr.affinity = SQLITE_AFF_INTEGER; |
||
335 | } |
||
336 | else if ( pExpr.iTable == 0 ) |
||
337 | { |
||
338 | testcase( iCol == 31 ); |
||
339 | testcase( iCol == 32 ); |
||
340 | pParse.oldmask |= ( iCol >= 32 ? 0xffffffff : ( ( (u32)1 ) << iCol ) ); |
||
341 | } |
||
342 | else |
||
343 | { |
||
344 | testcase( iCol == 31 ); |
||
345 | testcase( iCol == 32 ); |
||
346 | pParse.newmask |= ( iCol >= 32 ? 0xffffffff : ( ( (u32)1 ) << iCol ) ); |
||
347 | } |
||
348 | pExpr.iColumn = (i16)iCol; |
||
349 | pExpr.pTab = pTab; |
||
350 | isTrigger = 1; |
||
351 | } |
||
352 | } |
||
353 | } |
||
354 | #endif //* !SQLITE_OMIT_TRIGGER) */ |
||
355 | |||
356 | /* |
||
357 | ** Perhaps the name is a reference to the ROWID |
||
358 | */ |
||
359 | if ( cnt == 0 && cntTab == 1 && sqlite3IsRowid( zCol ) ) |
||
360 | { |
||
361 | cnt = 1; |
||
362 | pExpr.iColumn = -1; /* IMP: R-44911-55124 */ |
||
363 | pExpr.affinity = SQLITE_AFF_INTEGER; |
||
364 | } |
||
365 | |||
366 | /* |
||
367 | ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z |
||
368 | ** might refer to an result-set alias. This happens, for example, when |
||
369 | ** we are resolving names in the WHERE clause of the following command: |
||
370 | ** |
||
371 | ** SELECT a+b AS x FROM table WHERE x<10; |
||
372 | ** |
||
373 | ** In cases like this, replace pExpr with a copy of the expression that |
||
374 | ** forms the result set entry ("a+b" in the example) and return immediately. |
||
375 | ** Note that the expression in the result set should have already been |
||
376 | ** resolved by the time the WHERE clause is resolved. |
||
377 | */ |
||
378 | if ( cnt == 0 && ( pEList = pNC.pEList ) != null && zTab == null ) |
||
379 | { |
||
380 | for ( j = 0; j < pEList.nExpr; j++ ) |
||
381 | { |
||
382 | string zAs = pEList.a[j].zName; |
||
383 | if ( zAs != null && zAs.Equals( zCol ,StringComparison.OrdinalIgnoreCase ) ) |
||
384 | { |
||
385 | Expr pOrig; |
||
386 | Debug.Assert( pExpr.pLeft == null && pExpr.pRight == null ); |
||
387 | Debug.Assert( pExpr.x.pList == null ); |
||
388 | Debug.Assert( pExpr.x.pSelect == null ); |
||
389 | pOrig = pEList.a[j].pExpr; |
||
390 | if ( 0 == pNC.allowAgg && ExprHasProperty( pOrig, EP_Agg ) ) |
||
391 | { |
||
392 | sqlite3ErrorMsg( pParse, "misuse of aliased aggregate %s", zAs ); |
||
393 | return WRC_Abort; |
||
394 | } |
||
395 | resolveAlias( pParse, pEList, j, pExpr, string.Empty ); |
||
396 | cnt = 1; |
||
397 | pMatch = null; |
||
398 | Debug.Assert( zTab == null && zDb == null ); |
||
399 | goto lookupname_end; |
||
400 | } |
||
401 | } |
||
402 | } |
||
403 | |||
404 | /* Advance to the next name context. The loop will exit when either |
||
405 | ** we have a match (cnt>0) or when we run out of name contexts. |
||
406 | */ |
||
407 | if ( cnt == 0 ) |
||
408 | { |
||
409 | pNC = pNC.pNext; |
||
410 | } |
||
411 | } |
||
412 | |||
413 | /* |
||
414 | ** If X and Y are NULL (in other words if only the column name Z is |
||
415 | ** supplied) and the value of Z is enclosed in double-quotes, then |
||
416 | ** Z is a string literal if it doesn't match any column names. In that |
||
417 | ** case, we need to return right away and not make any changes to |
||
418 | ** pExpr. |
||
419 | ** |
||
420 | ** Because no reference was made to outer contexts, the pNC.nRef |
||
421 | ** fields are not changed in any context. |
||
422 | */ |
||
423 | if ( cnt == 0 && zTab == null && ExprHasProperty( pExpr, EP_DblQuoted ) ) |
||
424 | { |
||
425 | pExpr.op = TK_STRING; |
||
426 | pExpr.pTab = null; |
||
427 | return WRC_Prune; |
||
428 | } |
||
429 | |||
430 | /* |
||
431 | ** cnt==0 means there was not match. cnt>1 means there were two or |
||
432 | ** more matches. Either way, we have an error. |
||
433 | */ |
||
434 | if ( cnt != 1 ) |
||
435 | { |
||
436 | string zErr; |
||
437 | zErr = cnt == 0 ? "no such column" : "ambiguous column name"; |
||
438 | if ( zDb != null ) |
||
439 | { |
||
440 | sqlite3ErrorMsg( pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol ); |
||
441 | } |
||
442 | else if ( zTab != null ) |
||
443 | { |
||
444 | sqlite3ErrorMsg( pParse, "%s: %s.%s", zErr, zTab, zCol ); |
||
445 | } |
||
446 | else |
||
447 | { |
||
448 | sqlite3ErrorMsg( pParse, "%s: %s", zErr, zCol ); |
||
449 | } |
||
450 | pParse.checkSchema = 1; |
||
451 | pTopNC.nErr++; |
||
452 | } |
||
453 | |||
454 | /* If a column from a table in pSrcList is referenced, then record |
||
455 | ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes |
||
456 | ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the |
||
457 | ** column number is greater than the number of bits in the bitmask |
||
458 | ** then set the high-order bit of the bitmask. |
||
459 | */ |
||
460 | if ( pExpr.iColumn >= 0 && pMatch != null ) |
||
461 | { |
||
462 | int n = pExpr.iColumn; |
||
463 | testcase( n == BMS - 1 ); |
||
464 | if ( n >= BMS ) |
||
465 | { |
||
466 | n = BMS - 1; |
||
467 | } |
||
468 | Debug.Assert( pMatch.iCursor == pExpr.iTable ); |
||
469 | pMatch.colUsed |= ( (Bitmask)1 ) << n; |
||
470 | } |
||
471 | |||
472 | /* Clean up and return |
||
473 | */ |
||
474 | sqlite3ExprDelete( db, ref pExpr.pLeft ); |
||
475 | pExpr.pLeft = null; |
||
476 | sqlite3ExprDelete( db, ref pExpr.pRight ); |
||
477 | pExpr.pRight = null; |
||
478 | pExpr.op = (u8)( isTrigger != 0 ? TK_TRIGGER : TK_COLUMN ); |
||
479 | lookupname_end: |
||
480 | if ( cnt == 1 ) |
||
481 | { |
||
482 | Debug.Assert( pNC != null ); |
||
483 | sqlite3AuthRead( pParse, pExpr, pSchema, pNC.pSrcList ); |
||
484 | /* Increment the nRef value on all name contexts from TopNC up to |
||
485 | ** the point where the name matched. */ |
||
486 | for ( ; ; ) |
||
487 | { |
||
488 | Debug.Assert( pTopNC != null ); |
||
489 | pTopNC.nRef++; |
||
490 | if ( pTopNC == pNC ) |
||
491 | break; |
||
492 | pTopNC = pTopNC.pNext; |
||
493 | } |
||
494 | return WRC_Prune; |
||
495 | } |
||
496 | else |
||
497 | { |
||
498 | return WRC_Abort; |
||
499 | } |
||
500 | } |
||
501 | |||
502 | /* |
||
503 | ** Allocate and return a pointer to an expression to load the column iCol |
||
504 | ** from datasource iSrc in SrcList pSrc. |
||
505 | */ |
||
506 | static Expr sqlite3CreateColumnExpr( sqlite3 db, SrcList pSrc, int iSrc, int iCol ) |
||
507 | { |
||
508 | Expr p = sqlite3ExprAlloc( db, TK_COLUMN, null, 0 ); |
||
509 | if ( p != null ) |
||
510 | { |
||
511 | SrcList_item pItem = pSrc.a[iSrc]; |
||
512 | p.pTab = pItem.pTab; |
||
513 | p.iTable = pItem.iCursor; |
||
514 | if ( p.pTab.iPKey == iCol ) |
||
515 | { |
||
516 | p.iColumn = -1; |
||
517 | } |
||
518 | else |
||
519 | { |
||
520 | p.iColumn = (ynVar)iCol; |
||
521 | testcase( iCol == BMS ); |
||
522 | testcase( iCol == BMS - 1 ); |
||
523 | pItem.colUsed |= ( (Bitmask)1 ) << ( iCol >= BMS ? BMS - 1 : iCol ); |
||
524 | } |
||
525 | ExprSetProperty( p, EP_Resolved ); |
||
526 | } |
||
527 | return p; |
||
528 | } |
||
529 | |||
530 | /* |
||
531 | ** This routine is callback for sqlite3WalkExpr(). |
||
532 | ** |
||
533 | ** Resolve symbolic names into TK_COLUMN operators for the current |
||
534 | ** node in the expression tree. Return 0 to continue the search down |
||
535 | ** the tree or 2 to abort the tree walk. |
||
536 | ** |
||
537 | ** This routine also does error checking and name resolution for |
||
538 | ** function names. The operator for aggregate functions is changed |
||
539 | ** to TK_AGG_FUNCTION. |
||
540 | */ |
||
541 | static int resolveExprStep( Walker pWalker, ref Expr pExpr ) |
||
542 | { |
||
543 | NameContext pNC; |
||
544 | Parse pParse; |
||
545 | |||
546 | pNC = pWalker.u.pNC; |
||
547 | Debug.Assert( pNC != null ); |
||
548 | pParse = pNC.pParse; |
||
549 | Debug.Assert( pParse == pWalker.pParse ); |
||
550 | |||
551 | if ( ExprHasAnyProperty( pExpr, EP_Resolved ) ) |
||
552 | return WRC_Prune; |
||
553 | ExprSetProperty( pExpr, EP_Resolved ); |
||
554 | #if !NDEBUG |
||
555 | if ( pNC.pSrcList != null && pNC.pSrcList.nAlloc > 0 ) |
||
556 | { |
||
557 | SrcList pSrcList = pNC.pSrcList; |
||
558 | int i; |
||
559 | for ( i = 0; i < pNC.pSrcList.nSrc; i++ ) |
||
560 | { |
||
561 | Debug.Assert( pSrcList.a[i].iCursor >= 0 && pSrcList.a[i].iCursor < pParse.nTab ); |
||
562 | } |
||
563 | } |
||
564 | #endif |
||
565 | switch ( pExpr.op ) |
||
566 | { |
||
567 | |||
568 | #if (SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !(SQLITE_OMIT_SUBQUERY) |
||
569 | /* The special operator TK_ROW means use the rowid for the first |
||
570 | ** column in the FROM clause. This is used by the LIMIT and ORDER BY |
||
571 | ** clause processing on UPDATE and DELETE statements. |
||
572 | */ |
||
573 | case TK_ROW: { |
||
574 | SrcList pSrcList = pNC.pSrcList; |
||
575 | SrcList_item pItem; |
||
576 | Debug.Assert( pSrcList !=null && pSrcList.nSrc==1 ); |
||
577 | pItem = pSrcList.a[0]; |
||
578 | pExpr.op = TK_COLUMN; |
||
579 | pExpr.pTab = pItem.pTab; |
||
580 | pExpr.iTable = pItem.iCursor; |
||
581 | pExpr.iColumn = -1; |
||
582 | pExpr.affinity = SQLITE_AFF_INTEGER; |
||
583 | break; |
||
584 | } |
||
585 | #endif //* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) / |
||
586 | |||
587 | /* A lone identifier is the name of a column. |
||
588 | */ |
||
589 | case TK_ID: |
||
590 | { |
||
591 | return lookupName( pParse, null, null, pExpr.u.zToken, pNC, pExpr ); |
||
592 | } |
||
593 | |||
594 | /* A table name and column name: ID.ID |
||
595 | ** Or a database, table and column: ID.ID.ID |
||
596 | */ |
||
597 | case TK_DOT: |
||
598 | { |
||
599 | string zColumn; |
||
600 | string zTable; |
||
601 | string zDb; |
||
602 | Expr pRight; |
||
603 | |||
604 | /* if( pSrcList==0 ) break; */ |
||
605 | pRight = pExpr.pRight; |
||
606 | if ( pRight.op == TK_ID ) |
||
607 | { |
||
608 | zDb = null; |
||
609 | zTable = pExpr.pLeft.u.zToken; |
||
610 | zColumn = pRight.u.zToken; |
||
611 | } |
||
612 | else |
||
613 | { |
||
614 | Debug.Assert( pRight.op == TK_DOT ); |
||
615 | zDb = pExpr.pLeft.u.zToken; |
||
616 | zTable = pRight.pLeft.u.zToken; |
||
617 | zColumn = pRight.pRight.u.zToken; |
||
618 | } |
||
619 | return lookupName( pParse, zDb, zTable, zColumn, pNC, pExpr ); |
||
620 | } |
||
621 | |||
622 | /* Resolve function names |
||
623 | */ |
||
624 | case TK_CONST_FUNC: |
||
625 | case TK_FUNCTION: |
||
626 | { |
||
627 | ExprList pList = pExpr.x.pList; /* The argument list */ |
||
628 | int n = pList != null ? pList.nExpr : 0; /* Number of arguments */ |
||
629 | bool no_such_func = false; /* True if no such function exists */ |
||
630 | bool wrong_num_args = false; /* True if wrong number of arguments */ |
||
631 | bool is_agg = false; /* True if is an aggregate function */ |
||
632 | int auth; /* Authorization to use the function */ |
||
633 | int nId; /* Number of characters in function name */ |
||
634 | string zId; /* The function name. */ |
||
635 | FuncDef pDef; /* Information about the function */ |
||
636 | u8 enc = (u8)pParse.db.aDbStatic[0].pSchema.enc;// ENC( pParse.db ); /* The database encoding */ |
||
637 | |||
638 | testcase( pExpr.op == TK_CONST_FUNC ); |
||
639 | Debug.Assert( !ExprHasProperty( pExpr, EP_xIsSelect ) ); |
||
640 | zId = pExpr.u.zToken; |
||
641 | nId = sqlite3Strlen30( zId ); |
||
642 | pDef = sqlite3FindFunction( pParse.db, zId, nId, n, enc, 0 ); |
||
643 | if ( pDef == null ) |
||
644 | { |
||
645 | pDef = sqlite3FindFunction( pParse.db, zId, nId, -1, enc, 0 ); |
||
646 | if ( pDef == null ) |
||
647 | { |
||
648 | no_such_func = true; |
||
649 | } |
||
650 | else |
||
651 | { |
||
652 | wrong_num_args = true; |
||
653 | } |
||
654 | } |
||
655 | else |
||
656 | { |
||
657 | is_agg = pDef.xFunc == null; |
||
658 | } |
||
659 | #if !SQLITE_OMIT_AUTHORIZATION |
||
660 | if( pDef ){ |
||
661 | auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef.zName, 0); |
||
662 | if( auth!=SQLITE_OK ){ |
||
663 | if( auth==SQLITE_DENY ){ |
||
664 | sqlite3ErrorMsg(pParse, "not authorized to use function: %s", |
||
665 | pDef.zName); |
||
666 | pNC.nErr++; |
||
667 | } |
||
668 | pExpr.op = TK_NULL; |
||
669 | return WRC_Prune; |
||
670 | } |
||
671 | } |
||
672 | #endif |
||
673 | if ( is_agg && 0 == pNC.allowAgg ) |
||
674 | { |
||
675 | sqlite3ErrorMsg( pParse, "misuse of aggregate function %.*s()", nId, zId ); |
||
676 | pNC.nErr++; |
||
677 | is_agg = false; |
||
678 | } |
||
679 | else if ( no_such_func ) |
||
680 | { |
||
681 | sqlite3ErrorMsg( pParse, "no such function: %.*s", nId, zId ); |
||
682 | pNC.nErr++; |
||
683 | } |
||
684 | else if ( wrong_num_args ) |
||
685 | { |
||
686 | sqlite3ErrorMsg( pParse, "wrong number of arguments to function %.*s()", |
||
687 | nId, zId ); |
||
688 | pNC.nErr++; |
||
689 | } |
||
690 | if ( is_agg ) |
||
691 | { |
||
692 | pExpr.op = TK_AGG_FUNCTION; |
||
693 | pNC.hasAgg = 1; |
||
694 | } |
||
695 | if ( is_agg ) |
||
696 | pNC.allowAgg = 0; |
||
697 | sqlite3WalkExprList( pWalker, pList ); |
||
698 | if ( is_agg ) |
||
699 | pNC.allowAgg = 1; |
||
700 | /* FIX ME: Compute pExpr.affinity based on the expected return |
||
701 | ** type of the function |
||
702 | */ |
||
703 | return WRC_Prune; |
||
704 | } |
||
705 | #if !SQLITE_OMIT_SUBQUERY |
||
706 | case TK_SELECT: |
||
707 | case TK_EXISTS: |
||
708 | { |
||
709 | testcase( pExpr.op == TK_EXISTS ); |
||
710 | goto case TK_IN; |
||
711 | } |
||
712 | #endif |
||
713 | case TK_IN: |
||
714 | { |
||
715 | testcase( pExpr.op == TK_IN ); |
||
716 | if ( ExprHasProperty( pExpr, EP_xIsSelect ) ) |
||
717 | { |
||
718 | int nRef = pNC.nRef; |
||
719 | #if !SQLITE_OMIT_CHECK |
||
720 | if ( pNC.isCheck != 0 ) |
||
721 | { |
||
722 | sqlite3ErrorMsg( pParse, "subqueries prohibited in CHECK constraints" ); |
||
723 | } |
||
724 | #endif |
||
725 | sqlite3WalkSelect( pWalker, pExpr.x.pSelect ); |
||
726 | Debug.Assert( pNC.nRef >= nRef ); |
||
727 | if ( nRef != pNC.nRef ) |
||
728 | { |
||
729 | ExprSetProperty( pExpr, EP_VarSelect ); |
||
730 | } |
||
731 | } |
||
732 | break; |
||
733 | } |
||
734 | #if !SQLITE_OMIT_CHECK |
||
735 | case TK_VARIABLE: |
||
736 | { |
||
737 | if ( pNC.isCheck != 0 ) |
||
738 | { |
||
739 | sqlite3ErrorMsg( pParse, "parameters prohibited in CHECK constraints" ); |
||
740 | } |
||
741 | break; |
||
742 | } |
||
743 | #endif |
||
744 | } |
||
745 | return ( pParse.nErr != 0 /* || pParse.db.mallocFailed != 0 */ ) ? WRC_Abort : WRC_Continue; |
||
746 | } |
||
747 | |||
748 | /* |
||
749 | ** pEList is a list of expressions which are really the result set of the |
||
750 | ** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause. |
||
751 | ** This routine checks to see if pE is a simple identifier which corresponds |
||
752 | ** to the AS-name of one of the terms of the expression list. If it is, |
||
753 | ** this routine return an integer between 1 and N where N is the number of |
||
754 | ** elements in pEList, corresponding to the matching entry. If there is |
||
755 | ** no match, or if pE is not a simple identifier, then this routine |
||
756 | ** return 0. |
||
757 | ** |
||
758 | ** pEList has been resolved. pE has not. |
||
759 | */ |
||
760 | static int resolveAsName( |
||
761 | Parse pParse, /* Parsing context for error messages */ |
||
762 | ExprList pEList, /* List of expressions to scan */ |
||
763 | Expr pE /* Expression we are trying to match */ |
||
764 | ) |
||
765 | { |
||
766 | int i; /* Loop counter */ |
||
767 | |||
768 | UNUSED_PARAMETER( pParse ); |
||
769 | |||
770 | if ( pE.op == TK_ID ) |
||
771 | { |
||
772 | string zCol = pE.u.zToken; |
||
773 | |||
774 | for ( i = 0; i < pEList.nExpr; i++ ) |
||
775 | { |
||
776 | string zAs = pEList.a[i].zName; |
||
777 | if ( zAs != null && zAs.Equals( zCol ,StringComparison.OrdinalIgnoreCase ) ) |
||
778 | { |
||
779 | return i + 1; |
||
780 | } |
||
781 | } |
||
782 | } |
||
783 | return 0; |
||
784 | } |
||
785 | |||
786 | /* |
||
787 | ** pE is a pointer to an expression which is a single term in the |
||
788 | ** ORDER BY of a compound SELECT. The expression has not been |
||
789 | ** name resolved. |
||
790 | ** |
||
791 | ** At the point this routine is called, we already know that the |
||
792 | ** ORDER BY term is not an integer index into the result set. That |
||
793 | ** case is handled by the calling routine. |
||
794 | ** |
||
795 | ** Attempt to match pE against result set columns in the left-most |
||
796 | ** SELECT statement. Return the index i of the matching column, |
||
797 | ** as an indication to the caller that it should sort by the i-th column. |
||
798 | ** The left-most column is 1. In other words, the value returned is the |
||
799 | ** same integer value that would be used in the SQL statement to indicate |
||
800 | ** the column. |
||
801 | ** |
||
802 | ** If there is no match, return 0. Return -1 if an error occurs. |
||
803 | */ |
||
804 | static int resolveOrderByTermToExprList( |
||
805 | Parse pParse, /* Parsing context for error messages */ |
||
806 | Select pSelect, /* The SELECT statement with the ORDER BY clause */ |
||
807 | Expr pE /* The specific ORDER BY term */ |
||
808 | ) |
||
809 | { |
||
810 | int i = 0; /* Loop counter */ |
||
811 | ExprList pEList; /* The columns of the result set */ |
||
812 | NameContext nc; /* Name context for resolving pE */ |
||
813 | sqlite3 db; /* Database connection */ |
||
814 | int rc; /* Return code from subprocedures */ |
||
815 | u8 savedSuppErr; /* Saved value of db->suppressErr */ |
||
816 | |||
817 | Debug.Assert( sqlite3ExprIsInteger( pE, ref i ) == 0 ); |
||
818 | pEList = pSelect.pEList; |
||
819 | |||
820 | /* Resolve all names in the ORDER BY term expression |
||
821 | */ |
||
822 | nc = new NameContext();// memset( &nc, 0, sizeof( nc ) ); |
||
823 | nc.pParse = pParse; |
||
824 | nc.pSrcList = pSelect.pSrc; |
||
825 | nc.pEList = pEList; |
||
826 | nc.allowAgg = 1; |
||
827 | nc.nErr = 0; |
||
828 | db = pParse.db; |
||
829 | savedSuppErr = db.suppressErr; |
||
830 | db.suppressErr = 1; |
||
831 | rc = sqlite3ResolveExprNames( nc, ref pE ); |
||
832 | db.suppressErr = savedSuppErr; |
||
833 | if ( rc != 0 ) |
||
834 | return 0; |
||
835 | |||
836 | /* Try to match the ORDER BY expression against an expression |
||
837 | ** in the result set. Return an 1-based index of the matching |
||
838 | ** result-set entry. |
||
839 | */ |
||
840 | for ( i = 0; i < pEList.nExpr; i++ ) |
||
841 | { |
||
842 | if ( sqlite3ExprCompare( pEList.a[i].pExpr, pE ) < 2 ) |
||
843 | { |
||
844 | return i + 1; |
||
845 | } |
||
846 | } |
||
847 | |||
848 | /* If no match, return 0. */ |
||
849 | return 0; |
||
850 | } |
||
851 | |||
852 | /* |
||
853 | ** Generate an ORDER BY or GROUP BY term out-of-range error. |
||
854 | */ |
||
855 | static void resolveOutOfRangeError( |
||
856 | Parse pParse, /* The error context into which to write the error */ |
||
857 | string zType, /* "ORDER" or "GROUP" */ |
||
858 | int i, /* The index (1-based) of the term out of range */ |
||
859 | int mx /* Largest permissible value of i */ |
||
860 | ) |
||
861 | { |
||
862 | sqlite3ErrorMsg( pParse, |
||
863 | "%r %s BY term out of range - should be " + |
||
864 | "between 1 and %d", i, zType, mx ); |
||
865 | } |
||
866 | |||
867 | /* |
||
868 | ** Analyze the ORDER BY clause in a compound SELECT statement. Modify |
||
869 | ** each term of the ORDER BY clause is a constant integer between 1 |
||
870 | ** and N where N is the number of columns in the compound SELECT. |
||
871 | ** |
||
872 | ** ORDER BY terms that are already an integer between 1 and N are |
||
873 | ** unmodified. ORDER BY terms that are integers outside the range of |
||
874 | ** 1 through N generate an error. ORDER BY terms that are expressions |
||
875 | ** are matched against result set expressions of compound SELECT |
||
876 | ** beginning with the left-most SELECT and working toward the right. |
||
877 | ** At the first match, the ORDER BY expression is transformed into |
||
878 | ** the integer column number. |
||
879 | ** |
||
880 | ** Return the number of errors seen. |
||
881 | */ |
||
882 | static int resolveCompoundOrderBy( |
||
883 | Parse pParse, /* Parsing context. Leave error messages here */ |
||
884 | Select pSelect /* The SELECT statement containing the ORDER BY */ |
||
885 | ) |
||
886 | { |
||
887 | int i; |
||
888 | ExprList pOrderBy; |
||
889 | ExprList pEList; |
||
890 | sqlite3 db; |
||
891 | int moreToDo = 1; |
||
892 | |||
893 | pOrderBy = pSelect.pOrderBy; |
||
894 | if ( pOrderBy == null ) |
||
895 | return 0; |
||
896 | db = pParse.db; |
||
897 | //#if SQLITE_MAX_COLUMN |
||
898 | if ( pOrderBy.nExpr > db.aLimit[SQLITE_LIMIT_COLUMN] ) |
||
899 | { |
||
900 | sqlite3ErrorMsg( pParse, "too many terms in ORDER BY clause" ); |
||
901 | return 1; |
||
902 | } |
||
903 | //#endif |
||
904 | for ( i = 0; i < pOrderBy.nExpr; i++ ) |
||
905 | { |
||
906 | pOrderBy.a[i].done = 0; |
||
907 | } |
||
908 | pSelect.pNext = null; |
||
909 | while ( pSelect.pPrior != null ) |
||
910 | { |
||
911 | pSelect.pPrior.pNext = pSelect; |
||
912 | pSelect = pSelect.pPrior; |
||
913 | } |
||
914 | while ( pSelect != null && moreToDo != 0 ) |
||
915 | { |
||
916 | ExprList_item pItem; |
||
917 | moreToDo = 0; |
||
918 | pEList = pSelect.pEList; |
||
919 | Debug.Assert( pEList != null ); |
||
920 | for ( i = 0; i < pOrderBy.nExpr; i++ )//, pItem++) |
||
921 | { |
||
922 | pItem = pOrderBy.a[i]; |
||
923 | int iCol = -1; |
||
924 | Expr pE, pDup; |
||
925 | if ( pItem.done != 0 ) |
||
926 | continue; |
||
927 | pE = pItem.pExpr; |
||
928 | if ( sqlite3ExprIsInteger( pE, ref iCol ) != 0 ) |
||
929 | { |
||
930 | if ( iCol <= 0 || iCol > pEList.nExpr ) |
||
931 | { |
||
932 | resolveOutOfRangeError( pParse, "ORDER", i + 1, pEList.nExpr ); |
||
933 | return 1; |
||
934 | } |
||
935 | } |
||
936 | else |
||
937 | { |
||
938 | iCol = resolveAsName( pParse, pEList, pE ); |
||
939 | if ( iCol == 0 ) |
||
940 | { |
||
941 | pDup = sqlite3ExprDup( db, pE, 0 ); |
||
942 | ////if ( 0 == db.mallocFailed ) |
||
943 | { |
||
944 | Debug.Assert( pDup != null ); |
||
945 | iCol = resolveOrderByTermToExprList( pParse, pSelect, pDup ); |
||
946 | } |
||
947 | sqlite3ExprDelete( db, ref pDup ); |
||
948 | } |
||
949 | } |
||
950 | if ( iCol > 0 ) |
||
951 | { |
||
952 | CollSeq pColl = pE.pColl; |
||
953 | int flags = pE.flags & EP_ExpCollate; |
||
954 | sqlite3ExprDelete( db, ref pE ); |
||
955 | pItem.pExpr = pE = sqlite3Expr( db, TK_INTEGER, null ); |
||
956 | if ( pE == null ) |
||
957 | return 1; |
||
958 | pE.pColl = pColl; |
||
959 | pE.flags = (u16)( pE.flags | EP_IntValue | flags ); |
||
960 | pE.u.iValue = iCol; |
||
961 | pItem.iCol = (u16)iCol; |
||
962 | pItem.done = 1; |
||
963 | } |
||
964 | else |
||
965 | { |
||
966 | moreToDo = 1; |
||
967 | } |
||
968 | } |
||
969 | pSelect = pSelect.pNext; |
||
970 | } |
||
971 | for ( i = 0; i < pOrderBy.nExpr; i++ ) |
||
972 | { |
||
973 | if ( pOrderBy.a[i].done == 0 ) |
||
974 | { |
||
975 | sqlite3ErrorMsg( pParse, "%r ORDER BY term does not match any " + |
||
976 | "column in the result set", i + 1 ); |
||
977 | return 1; |
||
978 | } |
||
979 | } |
||
980 | return 0; |
||
981 | } |
||
982 | |||
983 | /* |
||
984 | ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of |
||
985 | ** the SELECT statement pSelect. If any term is reference to a |
||
986 | ** result set expression (as determined by the ExprList.a.iCol field) |
||
987 | ** then convert that term into a copy of the corresponding result set |
||
988 | ** column. |
||
989 | ** |
||
990 | ** If any errors are detected, add an error message to pParse and |
||
991 | ** return non-zero. Return zero if no errors are seen. |
||
992 | */ |
||
993 | static int sqlite3ResolveOrderGroupBy( |
||
994 | Parse pParse, /* Parsing context. Leave error messages here */ |
||
995 | Select pSelect, /* The SELECT statement containing the clause */ |
||
996 | ExprList pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ |
||
997 | string zType /* "ORDER" or "GROUP" */ |
||
998 | ) |
||
999 | { |
||
1000 | int i; |
||
1001 | sqlite3 db = pParse.db; |
||
1002 | ExprList pEList; |
||
1003 | ExprList_item pItem; |
||
1004 | |||
1005 | if ( pOrderBy == null /* || pParse.db.mallocFailed != 0 */ ) |
||
1006 | return 0; |
||
1007 | //#if SQLITE_MAX_COLUMN |
||
1008 | if ( pOrderBy.nExpr > db.aLimit[SQLITE_LIMIT_COLUMN] ) |
||
1009 | { |
||
1010 | sqlite3ErrorMsg( pParse, "too many terms in %s BY clause", zType ); |
||
1011 | return 1; |
||
1012 | } |
||
1013 | //#endif |
||
1014 | pEList = pSelect.pEList; |
||
1015 | Debug.Assert( pEList != null ); /* sqlite3SelectNew() guarantees this */ |
||
1016 | for ( i = 0; i < pOrderBy.nExpr; i++ )//, pItem++) |
||
1017 | { |
||
1018 | pItem = pOrderBy.a[i]; |
||
1019 | if ( pItem.iCol != 0 ) |
||
1020 | { |
||
1021 | if ( pItem.iCol > pEList.nExpr ) |
||
1022 | { |
||
1023 | resolveOutOfRangeError( pParse, zType, i + 1, pEList.nExpr ); |
||
1024 | return 1; |
||
1025 | } |
||
1026 | resolveAlias( pParse, pEList, pItem.iCol - 1, pItem.pExpr, zType ); |
||
1027 | } |
||
1028 | } |
||
1029 | return 0; |
||
1030 | } |
||
1031 | |||
1032 | /* |
||
1033 | ** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. |
||
1034 | ** The Name context of the SELECT statement is pNC. zType is either |
||
1035 | ** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. |
||
1036 | ** |
||
1037 | ** This routine resolves each term of the clause into an expression. |
||
1038 | ** If the order-by term is an integer I between 1 and N (where N is the |
||
1039 | ** number of columns in the result set of the SELECT) then the expression |
||
1040 | ** in the resolution is a copy of the I-th result-set expression. If |
||
1041 | ** the order-by term is an identify that corresponds to the AS-name of |
||
1042 | ** a result-set expression, then the term resolves to a copy of the |
||
1043 | ** result-set expression. Otherwise, the expression is resolved in |
||
1044 | ** the usual way - using sqlite3ResolveExprNames(). |
||
1045 | ** |
||
1046 | ** This routine returns the number of errors. If errors occur, then |
||
1047 | ** an appropriate error message might be left in pParse. (OOM errors |
||
1048 | ** excepted.) |
||
1049 | */ |
||
1050 | static int resolveOrderGroupBy( |
||
1051 | NameContext pNC, /* The name context of the SELECT statement */ |
||
1052 | Select pSelect, /* The SELECT statement holding pOrderBy */ |
||
1053 | ExprList pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ |
||
1054 | string zType /* Either "ORDER" or "GROUP", as appropriate */ |
||
1055 | ) |
||
1056 | { |
||
1057 | int i; /* Loop counter */ |
||
1058 | int iCol; /* Column number */ |
||
1059 | ExprList_item pItem; /* A term of the ORDER BY clause */ |
||
1060 | Parse pParse; /* Parsing context */ |
||
1061 | int nResult; /* Number of terms in the result set */ |
||
1062 | |||
1063 | if ( pOrderBy == null ) |
||
1064 | return 0; |
||
1065 | nResult = pSelect.pEList.nExpr; |
||
1066 | pParse = pNC.pParse; |
||
1067 | for ( i = 0; i < pOrderBy.nExpr; i++ )//, pItem++ ) |
||
1068 | { |
||
1069 | pItem = pOrderBy.a[i]; |
||
1070 | Expr pE = pItem.pExpr; |
||
1071 | iCol = resolveAsName( pParse, pSelect.pEList, pE ); |
||
1072 | if ( iCol > 0 ) |
||
1073 | { |
||
1074 | /* If an AS-name match is found, mark this ORDER BY column as being |
||
1075 | ** a copy of the iCol-th result-set column. The subsequent call to |
||
1076 | ** sqlite3ResolveOrderGroupBy() will convert the expression to a |
||
1077 | ** copy of the iCol-th result-set expression. */ |
||
1078 | pItem.iCol = (u16)iCol; |
||
1079 | continue; |
||
1080 | } |
||
1081 | if ( sqlite3ExprIsInteger( pE, ref iCol ) != 0 ) |
||
1082 | { |
||
1083 | /* The ORDER BY term is an integer constant. Again, set the column |
||
1084 | ** number so that sqlite3ResolveOrderGroupBy() will convert the |
||
1085 | ** order-by term to a copy of the result-set expression */ |
||
1086 | if ( iCol < 1 ) |
||
1087 | { |
||
1088 | resolveOutOfRangeError( pParse, zType, i + 1, nResult ); |
||
1089 | return 1; |
||
1090 | } |
||
1091 | pItem.iCol = (u16)iCol; |
||
1092 | continue; |
||
1093 | } |
||
1094 | |||
1095 | /* Otherwise, treat the ORDER BY term as an ordinary expression */ |
||
1096 | pItem.iCol = 0; |
||
1097 | if ( sqlite3ResolveExprNames( pNC, ref pE ) != 0 ) |
||
1098 | { |
||
1099 | return 1; |
||
1100 | } |
||
1101 | } |
||
1102 | return sqlite3ResolveOrderGroupBy( pParse, pSelect, pOrderBy, zType ); |
||
1103 | } |
||
1104 | |||
1105 | /* |
||
1106 | ** Resolve names in the SELECT statement p and all of its descendents. |
||
1107 | */ |
||
1108 | static int resolveSelectStep( Walker pWalker, Select p ) |
||
1109 | { |
||
1110 | NameContext pOuterNC; /* Context that contains this SELECT */ |
||
1111 | NameContext sNC; /* Name context of this SELECT */ |
||
1112 | bool isCompound; /* True if p is a compound select */ |
||
1113 | int nCompound; /* Number of compound terms processed so far */ |
||
1114 | Parse pParse; /* Parsing context */ |
||
1115 | ExprList pEList; /* Result set expression list */ |
||
1116 | int i; /* Loop counter */ |
||
1117 | ExprList pGroupBy; /* The GROUP BY clause */ |
||
1118 | Select pLeftmost; /* Left-most of SELECT of a compound */ |
||
1119 | ////sqlite3 db; /* Database connection */ |
||
1120 | |||
1121 | Debug.Assert( p != null ); |
||
1122 | if ( ( p.selFlags & SF_Resolved ) != 0 ) |
||
1123 | { |
||
1124 | return WRC_Prune; |
||
1125 | } |
||
1126 | pOuterNC = pWalker.u.pNC; |
||
1127 | pParse = pWalker.pParse; |
||
1128 | ////db = pParse.db; |
||
1129 | |||
1130 | /* Normally sqlite3SelectExpand() will be called first and will have |
||
1131 | ** already expanded this SELECT. However, if this is a subquery within |
||
1132 | ** an expression, sqlite3ResolveExprNames() will be called without a |
||
1133 | ** prior call to sqlite3SelectExpand(). When that happens, let |
||
1134 | ** sqlite3SelectPrep() do all of the processing for this SELECT. |
||
1135 | ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and |
||
1136 | ** this routine in the correct order. |
||
1137 | */ |
||
1138 | if ( ( p.selFlags & SF_Expanded ) == 0 ) |
||
1139 | { |
||
1140 | sqlite3SelectPrep( pParse, p, pOuterNC ); |
||
1141 | return ( pParse.nErr != 0 /*|| db.mallocFailed != 0 */ ) ? WRC_Abort : WRC_Prune; |
||
1142 | } |
||
1143 | |||
1144 | isCompound = p.pPrior != null; |
||
1145 | nCompound = 0; |
||
1146 | pLeftmost = p; |
||
1147 | while ( p != null ) |
||
1148 | { |
||
1149 | Debug.Assert( ( p.selFlags & SF_Expanded ) != 0 ); |
||
1150 | Debug.Assert( ( p.selFlags & SF_Resolved ) == 0 ); |
||
1151 | p.selFlags |= SF_Resolved; |
||
1152 | |||
1153 | /* Resolve the expressions in the LIMIT and OFFSET clauses. These |
||
1154 | ** are not allowed to refer to any names, so pass an empty NameContext. |
||
1155 | */ |
||
1156 | sNC = new NameContext();// memset( &sNC, 0, sizeof( sNC ) ); |
||
1157 | sNC.pParse = pParse; |
||
1158 | if ( sqlite3ResolveExprNames( sNC, ref p.pLimit ) != 0 || |
||
1159 | sqlite3ResolveExprNames( sNC, ref p.pOffset ) != 0 ) |
||
1160 | { |
||
1161 | return WRC_Abort; |
||
1162 | } |
||
1163 | |||
1164 | /* Set up the local name-context to pass to sqlite3ResolveExprNames() to |
||
1165 | ** resolve the result-set expression list. |
||
1166 | */ |
||
1167 | sNC.allowAgg = 1; |
||
1168 | sNC.pSrcList = p.pSrc; |
||
1169 | sNC.pNext = pOuterNC; |
||
1170 | |||
1171 | /* Resolve names in the result set. */ |
||
1172 | pEList = p.pEList; |
||
1173 | Debug.Assert( pEList != null ); |
||
1174 | for ( i = 0; i < pEList.nExpr; i++ ) |
||
1175 | { |
||
1176 | Expr pX = pEList.a[i].pExpr; |
||
1177 | if ( sqlite3ResolveExprNames( sNC, ref pX ) != 0 ) |
||
1178 | { |
||
1179 | return WRC_Abort; |
||
1180 | } |
||
1181 | } |
||
1182 | |||
1183 | /* Recursively resolve names in all subqueries |
||
1184 | */ |
||
1185 | for ( i = 0; i < p.pSrc.nSrc; i++ ) |
||
1186 | { |
||
1187 | SrcList_item pItem = p.pSrc.a[i]; |
||
1188 | if ( pItem.pSelect != null ) |
||
1189 | { |
||
1190 | string zSavedContext = pParse.zAuthContext; |
||
1191 | if ( pItem.zName != null ) |
||
1192 | pParse.zAuthContext = pItem.zName; |
||
1193 | sqlite3ResolveSelectNames( pParse, pItem.pSelect, pOuterNC ); |
||
1194 | pParse.zAuthContext = zSavedContext; |
||
1195 | if ( pParse.nErr != 0 /*|| db.mallocFailed != 0 */ ) |
||
1196 | return WRC_Abort; |
||
1197 | } |
||
1198 | } |
||
1199 | |||
1200 | /* If there are no aggregate functions in the result-set, and no GROUP BY |
||
1201 | ** expression, do not allow aggregates in any of the other expressions. |
||
1202 | */ |
||
1203 | Debug.Assert( ( p.selFlags & SF_Aggregate ) == 0 ); |
||
1204 | pGroupBy = p.pGroupBy; |
||
1205 | if ( pGroupBy != null || sNC.hasAgg != 0 ) |
||
1206 | { |
||
1207 | p.selFlags |= SF_Aggregate; |
||
1208 | } |
||
1209 | else |
||
1210 | { |
||
1211 | sNC.allowAgg = 0; |
||
1212 | } |
||
1213 | |||
1214 | /* If a HAVING clause is present, then there must be a GROUP BY clause. |
||
1215 | */ |
||
1216 | if ( p.pHaving != null && pGroupBy == null ) |
||
1217 | { |
||
1218 | sqlite3ErrorMsg( pParse, "a GROUP BY clause is required before HAVING" ); |
||
1219 | return WRC_Abort; |
||
1220 | } |
||
1221 | |||
1222 | /* Add the expression list to the name-context before parsing the |
||
1223 | ** other expressions in the SELECT statement. This is so that |
||
1224 | ** expressions in the WHERE clause (etc.) can refer to expressions by |
||
1225 | ** aliases in the result set. |
||
1226 | ** |
||
1227 | ** Minor point: If this is the case, then the expression will be |
||
1228 | ** re-evaluated for each reference to it. |
||
1229 | */ |
||
1230 | sNC.pEList = p.pEList; |
||
1231 | if ( sqlite3ResolveExprNames( sNC, ref p.pWhere ) != 0 || |
||
1232 | sqlite3ResolveExprNames( sNC, ref p.pHaving ) != 0 |
||
1233 | ) |
||
1234 | { |
||
1235 | return WRC_Abort; |
||
1236 | } |
||
1237 | |||
1238 | /* The ORDER BY and GROUP BY clauses may not refer to terms in |
||
1239 | ** outer queries |
||
1240 | */ |
||
1241 | sNC.pNext = null; |
||
1242 | sNC.allowAgg = 1; |
||
1243 | |||
1244 | /* Process the ORDER BY clause for singleton SELECT statements. |
||
1245 | ** The ORDER BY clause for compounds SELECT statements is handled |
||
1246 | ** below, after all of the result-sets for all of the elements of |
||
1247 | ** the compound have been resolved. |
||
1248 | */ |
||
1249 | if ( !isCompound && resolveOrderGroupBy( sNC, p, p.pOrderBy, "ORDER" ) != 0 ) |
||
1250 | { |
||
1251 | return WRC_Abort; |
||
1252 | } |
||
1253 | //if ( db.mallocFailed != 0 ) |
||
1254 | //{ |
||
1255 | // return WRC_Abort; |
||
1256 | //} |
||
1257 | |||
1258 | /* Resolve the GROUP BY clause. At the same time, make sure |
||
1259 | ** the GROUP BY clause does not contain aggregate functions. |
||
1260 | */ |
||
1261 | if ( pGroupBy != null ) |
||
1262 | { |
||
1263 | ExprList_item pItem; |
||
1264 | |||
1265 | if ( resolveOrderGroupBy( sNC, p, pGroupBy, "GROUP" ) != 0 /*|| db.mallocFailed != 0 */ ) |
||
1266 | { |
||
1267 | return WRC_Abort; |
||
1268 | } |
||
1269 | for ( i = 0; i < pGroupBy.nExpr; i++ )//, pItem++) |
||
1270 | { |
||
1271 | pItem = pGroupBy.a[i]; |
||
1272 | if ( ( pItem.pExpr.flags & EP_Agg ) != 0 )//HasProperty(pItem.pExpr, EP_Agg) ) |
||
1273 | { |
||
1274 | sqlite3ErrorMsg( pParse, "aggregate functions are not allowed in " + |
||
1275 | "the GROUP BY clause" ); |
||
1276 | return WRC_Abort; |
||
1277 | } |
||
1278 | } |
||
1279 | } |
||
1280 | |||
1281 | /* Advance to the next term of the compound |
||
1282 | */ |
||
1283 | p = p.pPrior; |
||
1284 | nCompound++; |
||
1285 | } |
||
1286 | |||
1287 | /* Resolve the ORDER BY on a compound SELECT after all terms of |
||
1288 | ** the compound have been resolved. |
||
1289 | */ |
||
1290 | if ( isCompound && resolveCompoundOrderBy( pParse, pLeftmost ) != 0 ) |
||
1291 | { |
||
1292 | return WRC_Abort; |
||
1293 | } |
||
1294 | |||
1295 | return WRC_Prune; |
||
1296 | } |
||
1297 | |||
1298 | /* |
||
1299 | ** This routine walks an expression tree and resolves references to |
||
1300 | ** table columns and result-set columns. At the same time, do error |
||
1301 | ** checking on function usage and set a flag if any aggregate functions |
||
1302 | ** are seen. |
||
1303 | ** |
||
1304 | ** To resolve table columns references we look for nodes (or subtrees) of the |
||
1305 | ** form X.Y.Z or Y.Z or just Z where |
||
1306 | ** |
||
1307 | ** X: The name of a database. Ex: "main" or "temp" or |
||
1308 | ** the symbolic name assigned to an ATTACH-ed database. |
||
1309 | ** |
||
1310 | ** Y: The name of a table in a FROM clause. Or in a trigger |
||
1311 | ** one of the special names "old" or "new". |
||
1312 | ** |
||
1313 | ** Z: The name of a column in table Y. |
||
1314 | ** |
||
1315 | ** The node at the root of the subtree is modified as follows: |
||
1316 | ** |
||
1317 | ** Expr.op Changed to TK_COLUMN |
||
1318 | ** Expr.pTab Points to the Table object for X.Y |
||
1319 | ** Expr.iColumn The column index in X.Y. -1 for the rowid. |
||
1320 | ** Expr.iTable The VDBE cursor number for X.Y |
||
1321 | ** |
||
1322 | ** |
||
1323 | ** To resolve result-set references, look for expression nodes of the |
||
1324 | ** form Z (with no X and Y prefix) where the Z matches the right-hand |
||
1325 | ** size of an AS clause in the result-set of a SELECT. The Z expression |
||
1326 | ** is replaced by a copy of the left-hand side of the result-set expression. |
||
1327 | ** Table-name and function resolution occurs on the substituted expression |
||
1328 | ** tree. For example, in: |
||
1329 | ** |
||
1330 | ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x; |
||
1331 | ** |
||
1332 | ** The "x" term of the order by is replaced by "a+b" to render: |
||
1333 | ** |
||
1334 | ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; |
||
1335 | ** |
||
1336 | ** Function calls are checked to make sure that the function is |
||
1337 | ** defined and that the correct number of arguments are specified. |
||
1338 | ** If the function is an aggregate function, then the pNC.hasAgg is |
||
1339 | ** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. |
||
1340 | ** If an expression contains aggregate functions then the EP_Agg |
||
1341 | ** property on the expression is set. |
||
1342 | ** |
||
1343 | ** An error message is left in pParse if anything is amiss. The number |
||
1344 | ** if errors is returned. |
||
1345 | */ |
||
1346 | static int sqlite3ResolveExprNames( |
||
1347 | NameContext pNC, /* Namespace to resolve expressions in. */ |
||
1348 | ref Expr pExpr /* The expression to be analyzed. */ |
||
1349 | ) |
||
1350 | { |
||
1351 | u8 savedHasAgg; |
||
1352 | Walker w = new Walker(); |
||
1353 | |||
1354 | if ( pExpr == null ) |
||
1355 | return 0; |
||
1356 | #if SQLITE_MAX_EXPR_DEPTH//>0 |
||
1357 | { |
||
1358 | Parse pParse = pNC.pParse; |
||
1359 | if( sqlite3ExprCheckHeight(pParse, pExpr.nHeight+pNC.pParse.nHeight) ){ |
||
1360 | return 1; |
||
1361 | } |
||
1362 | pParse.nHeight += pExpr.nHeight; |
||
1363 | } |
||
1364 | #endif |
||
1365 | savedHasAgg = pNC.hasAgg; |
||
1366 | pNC.hasAgg = 0; |
||
1367 | w.xExprCallback = resolveExprStep; |
||
1368 | w.xSelectCallback = resolveSelectStep; |
||
1369 | w.pParse = pNC.pParse; |
||
1370 | w.u.pNC = pNC; |
||
1371 | sqlite3WalkExpr( w, ref pExpr ); |
||
1372 | #if SQLITE_MAX_EXPR_DEPTH//>0 |
||
1373 | pNC.pParse.nHeight -= pExpr.nHeight; |
||
1374 | #endif |
||
1375 | if ( pNC.nErr > 0 || w.pParse.nErr > 0 ) |
||
1376 | { |
||
1377 | ExprSetProperty( pExpr, EP_Error ); |
||
1378 | } |
||
1379 | if ( pNC.hasAgg != 0 ) |
||
1380 | { |
||
1381 | ExprSetProperty( pExpr, EP_Agg ); |
||
1382 | } |
||
1383 | else if ( savedHasAgg != 0 ) |
||
1384 | { |
||
1385 | pNC.hasAgg = 1; |
||
1386 | } |
||
1387 | return ExprHasProperty( pExpr, EP_Error ) ? 1 : 0; |
||
1388 | } |
||
1389 | |||
1390 | |||
1391 | /* |
||
1392 | ** Resolve all names in all expressions of a SELECT and in all |
||
1393 | ** decendents of the SELECT, including compounds off of p.pPrior, |
||
1394 | ** subqueries in expressions, and subqueries used as FROM clause |
||
1395 | ** terms. |
||
1396 | ** |
||
1397 | ** See sqlite3ResolveExprNames() for a description of the kinds of |
||
1398 | ** transformations that occur. |
||
1399 | ** |
||
1400 | ** All SELECT statements should have been expanded using |
||
1401 | ** sqlite3SelectExpand() prior to invoking this routine. |
||
1402 | */ |
||
1403 | static void sqlite3ResolveSelectNames( |
||
1404 | Parse pParse, /* The parser context */ |
||
1405 | Select p, /* The SELECT statement being coded. */ |
||
1406 | NameContext pOuterNC /* Name context for parent SELECT statement */ |
||
1407 | ) |
||
1408 | { |
||
1409 | Walker w = new Walker(); |
||
1410 | |||
1411 | Debug.Assert( p != null ); |
||
1412 | w.xExprCallback = resolveExprStep; |
||
1413 | w.xSelectCallback = resolveSelectStep; |
||
1414 | w.pParse = pParse; |
||
1415 | w.u.pNC = pOuterNC; |
||
1416 | sqlite3WalkSelect( w, p ); |
||
1417 | } |
||
1418 | } |
||
1419 | } |