diff options
Diffstat (limited to '')
-rwxr-xr-x | libraries/sqlite/win32/update.c | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/libraries/sqlite/win32/update.c b/libraries/sqlite/win32/update.c new file mode 100755 index 0000000..6cf7f73 --- /dev/null +++ b/libraries/sqlite/win32/update.c | |||
@@ -0,0 +1,630 @@ | |||
1 | /* | ||
2 | ** 2001 September 15 | ||
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 C code routines that are called by the parser | ||
13 | ** to handle UPDATE statements. | ||
14 | ** | ||
15 | ** $Id: update.c,v 1.140 2007/08/16 10:09:03 danielk1977 Exp $ | ||
16 | */ | ||
17 | #include "sqliteInt.h" | ||
18 | |||
19 | #ifndef SQLITE_OMIT_VIRTUALTABLE | ||
20 | /* Forward declaration */ | ||
21 | static void updateVirtualTable( | ||
22 | Parse *pParse, /* The parsing context */ | ||
23 | SrcList *pSrc, /* The virtual table to be modified */ | ||
24 | Table *pTab, /* The virtual table */ | ||
25 | ExprList *pChanges, /* The columns to change in the UPDATE statement */ | ||
26 | Expr *pRowidExpr, /* Expression used to recompute the rowid */ | ||
27 | int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ | ||
28 | Expr *pWhere /* WHERE clause of the UPDATE statement */ | ||
29 | ); | ||
30 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ | ||
31 | |||
32 | /* | ||
33 | ** The most recently coded instruction was an OP_Column to retrieve the | ||
34 | ** i-th column of table pTab. This routine sets the P3 parameter of the | ||
35 | ** OP_Column to the default value, if any. | ||
36 | ** | ||
37 | ** The default value of a column is specified by a DEFAULT clause in the | ||
38 | ** column definition. This was either supplied by the user when the table | ||
39 | ** was created, or added later to the table definition by an ALTER TABLE | ||
40 | ** command. If the latter, then the row-records in the table btree on disk | ||
41 | ** may not contain a value for the column and the default value, taken | ||
42 | ** from the P3 parameter of the OP_Column instruction, is returned instead. | ||
43 | ** If the former, then all row-records are guaranteed to include a value | ||
44 | ** for the column and the P3 value is not required. | ||
45 | ** | ||
46 | ** Column definitions created by an ALTER TABLE command may only have | ||
47 | ** literal default values specified: a number, null or a string. (If a more | ||
48 | ** complicated default expression value was provided, it is evaluated | ||
49 | ** when the ALTER TABLE is executed and one of the literal values written | ||
50 | ** into the sqlite_master table.) | ||
51 | ** | ||
52 | ** Therefore, the P3 parameter is only required if the default value for | ||
53 | ** the column is a literal number, string or null. The sqlite3ValueFromExpr() | ||
54 | ** function is capable of transforming these types of expressions into | ||
55 | ** sqlite3_value objects. | ||
56 | */ | ||
57 | void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){ | ||
58 | if( pTab && !pTab->pSelect ){ | ||
59 | sqlite3_value *pValue; | ||
60 | u8 enc = ENC(sqlite3VdbeDb(v)); | ||
61 | Column *pCol = &pTab->aCol[i]; | ||
62 | assert( i<pTab->nCol ); | ||
63 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, pCol->affinity, &pValue); | ||
64 | if( pValue ){ | ||
65 | sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM); | ||
66 | }else{ | ||
67 | VdbeComment((v, "# %s.%s", pTab->zName, pCol->zName)); | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | ** Process an UPDATE statement. | ||
74 | ** | ||
75 | ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; | ||
76 | ** \_______/ \________/ \______/ \________________/ | ||
77 | * onError pTabList pChanges pWhere | ||
78 | */ | ||
79 | void sqlite3Update( | ||
80 | Parse *pParse, /* The parser context */ | ||
81 | SrcList *pTabList, /* The table in which we should change things */ | ||
82 | ExprList *pChanges, /* Things to be changed */ | ||
83 | Expr *pWhere, /* The WHERE clause. May be null */ | ||
84 | int onError /* How to handle constraint errors */ | ||
85 | ){ | ||
86 | int i, j; /* Loop counters */ | ||
87 | Table *pTab; /* The table to be updated */ | ||
88 | int addr = 0; /* VDBE instruction address of the start of the loop */ | ||
89 | WhereInfo *pWInfo; /* Information about the WHERE clause */ | ||
90 | Vdbe *v; /* The virtual database engine */ | ||
91 | Index *pIdx; /* For looping over indices */ | ||
92 | int nIdx; /* Number of indices that need updating */ | ||
93 | int nIdxTotal; /* Total number of indices */ | ||
94 | int iCur; /* VDBE Cursor number of pTab */ | ||
95 | sqlite3 *db; /* The database structure */ | ||
96 | Index **apIdx = 0; /* An array of indices that need updating too */ | ||
97 | char *aIdxUsed = 0; /* aIdxUsed[i]==1 if the i-th index is used */ | ||
98 | int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the | ||
99 | ** an expression for the i-th column of the table. | ||
100 | ** aXRef[i]==-1 if the i-th column is not changed. */ | ||
101 | int chngRowid; /* True if the record number is being changed */ | ||
102 | Expr *pRowidExpr = 0; /* Expression defining the new record number */ | ||
103 | int openAll = 0; /* True if all indices need to be opened */ | ||
104 | AuthContext sContext; /* The authorization context */ | ||
105 | NameContext sNC; /* The name-context to resolve expressions in */ | ||
106 | int iDb; /* Database containing the table being updated */ | ||
107 | int memCnt = 0; /* Memory cell used for counting rows changed */ | ||
108 | |||
109 | #ifndef SQLITE_OMIT_TRIGGER | ||
110 | int isView; /* Trying to update a view */ | ||
111 | int triggers_exist = 0; /* True if any row triggers exist */ | ||
112 | #endif | ||
113 | |||
114 | int newIdx = -1; /* index of trigger "new" temp table */ | ||
115 | int oldIdx = -1; /* index of trigger "old" temp table */ | ||
116 | |||
117 | sContext.pParse = 0; | ||
118 | db = pParse->db; | ||
119 | if( pParse->nErr || db->mallocFailed ){ | ||
120 | goto update_cleanup; | ||
121 | } | ||
122 | assert( pTabList->nSrc==1 ); | ||
123 | |||
124 | /* Locate the table which we want to update. | ||
125 | */ | ||
126 | pTab = sqlite3SrcListLookup(pParse, pTabList); | ||
127 | if( pTab==0 ) goto update_cleanup; | ||
128 | iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); | ||
129 | |||
130 | /* Figure out if we have any triggers and if the table being | ||
131 | ** updated is a view | ||
132 | */ | ||
133 | #ifndef SQLITE_OMIT_TRIGGER | ||
134 | triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges); | ||
135 | isView = pTab->pSelect!=0; | ||
136 | #else | ||
137 | # define triggers_exist 0 | ||
138 | # define isView 0 | ||
139 | #endif | ||
140 | #ifdef SQLITE_OMIT_VIEW | ||
141 | # undef isView | ||
142 | # define isView 0 | ||
143 | #endif | ||
144 | |||
145 | if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ | ||
146 | goto update_cleanup; | ||
147 | } | ||
148 | if( sqlite3ViewGetColumnNames(pParse, pTab) ){ | ||
149 | goto update_cleanup; | ||
150 | } | ||
151 | aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol ); | ||
152 | if( aXRef==0 ) goto update_cleanup; | ||
153 | for(i=0; i<pTab->nCol; i++) aXRef[i] = -1; | ||
154 | |||
155 | /* If there are FOR EACH ROW triggers, allocate cursors for the | ||
156 | ** special OLD and NEW tables | ||
157 | */ | ||
158 | if( triggers_exist ){ | ||
159 | newIdx = pParse->nTab++; | ||
160 | oldIdx = pParse->nTab++; | ||
161 | } | ||
162 | |||
163 | /* Allocate a cursors for the main database table and for all indices. | ||
164 | ** The index cursors might not be used, but if they are used they | ||
165 | ** need to occur right after the database cursor. So go ahead and | ||
166 | ** allocate enough space, just in case. | ||
167 | */ | ||
168 | pTabList->a[0].iCursor = iCur = pParse->nTab++; | ||
169 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | ||
170 | pParse->nTab++; | ||
171 | } | ||
172 | |||
173 | /* Initialize the name-context */ | ||
174 | memset(&sNC, 0, sizeof(sNC)); | ||
175 | sNC.pParse = pParse; | ||
176 | sNC.pSrcList = pTabList; | ||
177 | |||
178 | /* Resolve the column names in all the expressions of the | ||
179 | ** of the UPDATE statement. Also find the column index | ||
180 | ** for each column to be updated in the pChanges array. For each | ||
181 | ** column to be updated, make sure we have authorization to change | ||
182 | ** that column. | ||
183 | */ | ||
184 | chngRowid = 0; | ||
185 | for(i=0; i<pChanges->nExpr; i++){ | ||
186 | if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){ | ||
187 | goto update_cleanup; | ||
188 | } | ||
189 | for(j=0; j<pTab->nCol; j++){ | ||
190 | if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ | ||
191 | if( j==pTab->iPKey ){ | ||
192 | chngRowid = 1; | ||
193 | pRowidExpr = pChanges->a[i].pExpr; | ||
194 | } | ||
195 | aXRef[j] = i; | ||
196 | break; | ||
197 | } | ||
198 | } | ||
199 | if( j>=pTab->nCol ){ | ||
200 | if( sqlite3IsRowid(pChanges->a[i].zName) ){ | ||
201 | chngRowid = 1; | ||
202 | pRowidExpr = pChanges->a[i].pExpr; | ||
203 | }else{ | ||
204 | sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); | ||
205 | goto update_cleanup; | ||
206 | } | ||
207 | } | ||
208 | #ifndef SQLITE_OMIT_AUTHORIZATION | ||
209 | { | ||
210 | int rc; | ||
211 | rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, | ||
212 | pTab->aCol[j].zName, db->aDb[iDb].zName); | ||
213 | if( rc==SQLITE_DENY ){ | ||
214 | goto update_cleanup; | ||
215 | }else if( rc==SQLITE_IGNORE ){ | ||
216 | aXRef[j] = -1; | ||
217 | } | ||
218 | } | ||
219 | #endif | ||
220 | } | ||
221 | |||
222 | /* Allocate memory for the array apIdx[] and fill it with pointers to every | ||
223 | ** index that needs to be updated. Indices only need updating if their | ||
224 | ** key includes one of the columns named in pChanges or if the record | ||
225 | ** number of the original table entry is changing. | ||
226 | */ | ||
227 | for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){ | ||
228 | if( chngRowid ){ | ||
229 | i = 0; | ||
230 | }else { | ||
231 | for(i=0; i<pIdx->nColumn; i++){ | ||
232 | if( aXRef[pIdx->aiColumn[i]]>=0 ) break; | ||
233 | } | ||
234 | } | ||
235 | if( i<pIdx->nColumn ) nIdx++; | ||
236 | } | ||
237 | if( nIdxTotal>0 ){ | ||
238 | apIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx + nIdxTotal ); | ||
239 | if( apIdx==0 ) goto update_cleanup; | ||
240 | aIdxUsed = (char*)&apIdx[nIdx]; | ||
241 | } | ||
242 | for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | ||
243 | if( chngRowid ){ | ||
244 | i = 0; | ||
245 | }else{ | ||
246 | for(i=0; i<pIdx->nColumn; i++){ | ||
247 | if( aXRef[pIdx->aiColumn[i]]>=0 ) break; | ||
248 | } | ||
249 | } | ||
250 | if( i<pIdx->nColumn ){ | ||
251 | apIdx[nIdx++] = pIdx; | ||
252 | aIdxUsed[j] = 1; | ||
253 | }else{ | ||
254 | aIdxUsed[j] = 0; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /* Begin generating code. | ||
259 | */ | ||
260 | v = sqlite3GetVdbe(pParse); | ||
261 | if( v==0 ) goto update_cleanup; | ||
262 | if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); | ||
263 | sqlite3BeginWriteOperation(pParse, 1, iDb); | ||
264 | |||
265 | #ifndef SQLITE_OMIT_VIRTUALTABLE | ||
266 | /* Virtual tables must be handled separately */ | ||
267 | if( IsVirtual(pTab) ){ | ||
268 | updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, | ||
269 | pWhere); | ||
270 | pWhere = 0; | ||
271 | pTabList = 0; | ||
272 | goto update_cleanup; | ||
273 | } | ||
274 | #endif | ||
275 | |||
276 | /* Resolve the column names in all the expressions in the | ||
277 | ** WHERE clause. | ||
278 | */ | ||
279 | if( sqlite3ExprResolveNames(&sNC, pWhere) ){ | ||
280 | goto update_cleanup; | ||
281 | } | ||
282 | |||
283 | /* Start the view context | ||
284 | */ | ||
285 | if( isView ){ | ||
286 | sqlite3AuthContextPush(pParse, &sContext, pTab->zName); | ||
287 | } | ||
288 | |||
289 | /* If we are trying to update a view, realize that view into | ||
290 | ** a ephemeral table. | ||
291 | */ | ||
292 | if( isView ){ | ||
293 | Select *pView; | ||
294 | pView = sqlite3SelectDup(db, pTab->pSelect); | ||
295 | sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0); | ||
296 | sqlite3SelectDelete(pView); | ||
297 | } | ||
298 | |||
299 | /* Begin the database scan | ||
300 | */ | ||
301 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); | ||
302 | if( pWInfo==0 ) goto update_cleanup; | ||
303 | |||
304 | /* Remember the rowid of every item to be updated. | ||
305 | */ | ||
306 | sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0); | ||
307 | sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0); | ||
308 | |||
309 | /* End the database scan loop. | ||
310 | */ | ||
311 | sqlite3WhereEnd(pWInfo); | ||
312 | |||
313 | /* Initialize the count of updated rows | ||
314 | */ | ||
315 | if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ | ||
316 | memCnt = pParse->nMem++; | ||
317 | sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt); | ||
318 | } | ||
319 | |||
320 | if( triggers_exist ){ | ||
321 | /* Create pseudo-tables for NEW and OLD | ||
322 | */ | ||
323 | sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0); | ||
324 | sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol); | ||
325 | sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0); | ||
326 | sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol); | ||
327 | |||
328 | /* The top of the update loop for when there are triggers. | ||
329 | */ | ||
330 | addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); | ||
331 | |||
332 | if( !isView ){ | ||
333 | sqlite3VdbeAddOp(v, OP_Dup, 0, 0); | ||
334 | sqlite3VdbeAddOp(v, OP_Dup, 0, 0); | ||
335 | /* Open a cursor and make it point to the record that is | ||
336 | ** being updated. | ||
337 | */ | ||
338 | sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); | ||
339 | } | ||
340 | sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); | ||
341 | |||
342 | /* Generate the OLD table | ||
343 | */ | ||
344 | sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); | ||
345 | sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); | ||
346 | sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0); | ||
347 | |||
348 | /* Generate the NEW table | ||
349 | */ | ||
350 | if( chngRowid ){ | ||
351 | sqlite3ExprCodeAndCache(pParse, pRowidExpr); | ||
352 | }else{ | ||
353 | sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); | ||
354 | } | ||
355 | for(i=0; i<pTab->nCol; i++){ | ||
356 | if( i==pTab->iPKey ){ | ||
357 | sqlite3VdbeAddOp(v, OP_Null, 0, 0); | ||
358 | continue; | ||
359 | } | ||
360 | j = aXRef[i]; | ||
361 | if( j<0 ){ | ||
362 | sqlite3VdbeAddOp(v, OP_Column, iCur, i); | ||
363 | sqlite3ColumnDefault(v, pTab, i); | ||
364 | }else{ | ||
365 | sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr); | ||
366 | } | ||
367 | } | ||
368 | sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); | ||
369 | if( !isView ){ | ||
370 | sqlite3TableAffinityStr(v, pTab); | ||
371 | } | ||
372 | if( pParse->nErr ) goto update_cleanup; | ||
373 | sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); | ||
374 | if( !isView ){ | ||
375 | sqlite3VdbeAddOp(v, OP_Close, iCur, 0); | ||
376 | } | ||
377 | |||
378 | /* Fire the BEFORE and INSTEAD OF triggers | ||
379 | */ | ||
380 | if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab, | ||
381 | newIdx, oldIdx, onError, addr) ){ | ||
382 | goto update_cleanup; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | if( !isView && !IsVirtual(pTab) ){ | ||
387 | /* | ||
388 | ** Open every index that needs updating. Note that if any | ||
389 | ** index could potentially invoke a REPLACE conflict resolution | ||
390 | ** action, then we need to open all indices because we might need | ||
391 | ** to be deleting some records. | ||
392 | */ | ||
393 | sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); | ||
394 | if( onError==OE_Replace ){ | ||
395 | openAll = 1; | ||
396 | }else{ | ||
397 | openAll = 0; | ||
398 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | ||
399 | if( pIdx->onError==OE_Replace ){ | ||
400 | openAll = 1; | ||
401 | break; | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ | ||
406 | if( openAll || aIdxUsed[i] ){ | ||
407 | KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); | ||
408 | sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); | ||
409 | sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, | ||
410 | (char*)pKey, P3_KEYINFO_HANDOFF); | ||
411 | assert( pParse->nTab>iCur+i+1 ); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | /* Loop over every record that needs updating. We have to load | ||
416 | ** the old data for each record to be updated because some columns | ||
417 | ** might not change and we will need to copy the old value. | ||
418 | ** Also, the old data is needed to delete the old index entries. | ||
419 | ** So make the cursor point at the old record. | ||
420 | */ | ||
421 | if( !triggers_exist ){ | ||
422 | addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); | ||
423 | sqlite3VdbeAddOp(v, OP_Dup, 0, 0); | ||
424 | } | ||
425 | sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr); | ||
426 | |||
427 | /* If the record number will change, push the record number as it | ||
428 | ** will be after the update. (The old record number is currently | ||
429 | ** on top of the stack.) | ||
430 | */ | ||
431 | if( chngRowid ){ | ||
432 | sqlite3ExprCode(pParse, pRowidExpr); | ||
433 | sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); | ||
434 | } | ||
435 | |||
436 | /* Compute new data for this record. | ||
437 | */ | ||
438 | for(i=0; i<pTab->nCol; i++){ | ||
439 | if( i==pTab->iPKey ){ | ||
440 | sqlite3VdbeAddOp(v, OP_Null, 0, 0); | ||
441 | continue; | ||
442 | } | ||
443 | j = aXRef[i]; | ||
444 | if( j<0 ){ | ||
445 | sqlite3VdbeAddOp(v, OP_Column, iCur, i); | ||
446 | sqlite3ColumnDefault(v, pTab, i); | ||
447 | }else{ | ||
448 | sqlite3ExprCode(pParse, pChanges->a[j].pExpr); | ||
449 | } | ||
450 | } | ||
451 | |||
452 | /* Do constraint checks | ||
453 | */ | ||
454 | sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, | ||
455 | onError, addr); | ||
456 | |||
457 | /* Delete the old indices for the current record. | ||
458 | */ | ||
459 | sqlite3GenerateRowIndexDelete(v, pTab, iCur, aIdxUsed); | ||
460 | |||
461 | /* If changing the record number, delete the old record. | ||
462 | */ | ||
463 | if( chngRowid ){ | ||
464 | sqlite3VdbeAddOp(v, OP_Delete, iCur, 0); | ||
465 | } | ||
466 | |||
467 | /* Create the new index entries and the new record. | ||
468 | */ | ||
469 | sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1, 0); | ||
470 | } | ||
471 | |||
472 | /* Increment the row counter | ||
473 | */ | ||
474 | if( db->flags & SQLITE_CountRows && !pParse->trigStack){ | ||
475 | sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt); | ||
476 | } | ||
477 | |||
478 | /* If there are triggers, close all the cursors after each iteration | ||
479 | ** through the loop. The fire the after triggers. | ||
480 | */ | ||
481 | if( triggers_exist ){ | ||
482 | if( !isView ){ | ||
483 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ | ||
484 | if( openAll || aIdxUsed[i] ) | ||
485 | sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0); | ||
486 | } | ||
487 | sqlite3VdbeAddOp(v, OP_Close, iCur, 0); | ||
488 | } | ||
489 | if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, | ||
490 | newIdx, oldIdx, onError, addr) ){ | ||
491 | goto update_cleanup; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | /* Repeat the above with the next record to be updated, until | ||
496 | ** all record selected by the WHERE clause have been updated. | ||
497 | */ | ||
498 | sqlite3VdbeAddOp(v, OP_Goto, 0, addr); | ||
499 | sqlite3VdbeJumpHere(v, addr); | ||
500 | |||
501 | /* Close all tables if there were no FOR EACH ROW triggers */ | ||
502 | if( !triggers_exist ){ | ||
503 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ | ||
504 | if( openAll || aIdxUsed[i] ){ | ||
505 | sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0); | ||
506 | } | ||
507 | } | ||
508 | sqlite3VdbeAddOp(v, OP_Close, iCur, 0); | ||
509 | }else{ | ||
510 | sqlite3VdbeAddOp(v, OP_Close, newIdx, 0); | ||
511 | sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0); | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | ** Return the number of rows that were changed. If this routine is | ||
516 | ** generating code because of a call to sqlite3NestedParse(), do not | ||
517 | ** invoke the callback function. | ||
518 | */ | ||
519 | if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){ | ||
520 | sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0); | ||
521 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); | ||
522 | sqlite3VdbeSetNumCols(v, 1); | ||
523 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC); | ||
524 | } | ||
525 | |||
526 | update_cleanup: | ||
527 | sqlite3AuthContextPop(&sContext); | ||
528 | sqlite3_free(apIdx); | ||
529 | sqlite3_free(aXRef); | ||
530 | sqlite3SrcListDelete(pTabList); | ||
531 | sqlite3ExprListDelete(pChanges); | ||
532 | sqlite3ExprDelete(pWhere); | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | #ifndef SQLITE_OMIT_VIRTUALTABLE | ||
537 | /* | ||
538 | ** Generate code for an UPDATE of a virtual table. | ||
539 | ** | ||
540 | ** The strategy is that we create an ephemerial table that contains | ||
541 | ** for each row to be changed: | ||
542 | ** | ||
543 | ** (A) The original rowid of that row. | ||
544 | ** (B) The revised rowid for the row. (note1) | ||
545 | ** (C) The content of every column in the row. | ||
546 | ** | ||
547 | ** Then we loop over this ephemeral table and for each row in | ||
548 | ** the ephermeral table call VUpdate. | ||
549 | ** | ||
550 | ** When finished, drop the ephemeral table. | ||
551 | ** | ||
552 | ** (note1) Actually, if we know in advance that (A) is always the same | ||
553 | ** as (B) we only store (A), then duplicate (A) when pulling | ||
554 | ** it out of the ephemeral table before calling VUpdate. | ||
555 | */ | ||
556 | static void updateVirtualTable( | ||
557 | Parse *pParse, /* The parsing context */ | ||
558 | SrcList *pSrc, /* The virtual table to be modified */ | ||
559 | Table *pTab, /* The virtual table */ | ||
560 | ExprList *pChanges, /* The columns to change in the UPDATE statement */ | ||
561 | Expr *pRowid, /* Expression used to recompute the rowid */ | ||
562 | int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ | ||
563 | Expr *pWhere /* WHERE clause of the UPDATE statement */ | ||
564 | ){ | ||
565 | Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ | ||
566 | ExprList *pEList = 0; /* The result set of the SELECT statement */ | ||
567 | Select *pSelect = 0; /* The SELECT statement */ | ||
568 | Expr *pExpr; /* Temporary expression */ | ||
569 | int ephemTab; /* Table holding the result of the SELECT */ | ||
570 | int i; /* Loop counter */ | ||
571 | int addr; /* Address of top of loop */ | ||
572 | sqlite3 *db = pParse->db; /* Database connection */ | ||
573 | |||
574 | /* Construct the SELECT statement that will find the new values for | ||
575 | ** all updated rows. | ||
576 | */ | ||
577 | pEList = sqlite3ExprListAppend(pParse, 0, | ||
578 | sqlite3CreateIdExpr(pParse, "_rowid_"), 0); | ||
579 | if( pRowid ){ | ||
580 | pEList = sqlite3ExprListAppend(pParse, pEList, | ||
581 | sqlite3ExprDup(db, pRowid), 0); | ||
582 | } | ||
583 | assert( pTab->iPKey<0 ); | ||
584 | for(i=0; i<pTab->nCol; i++){ | ||
585 | if( aXRef[i]>=0 ){ | ||
586 | pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr); | ||
587 | }else{ | ||
588 | pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName); | ||
589 | } | ||
590 | pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0); | ||
591 | } | ||
592 | pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); | ||
593 | |||
594 | /* Create the ephemeral table into which the update results will | ||
595 | ** be stored. | ||
596 | */ | ||
597 | assert( v ); | ||
598 | ephemTab = pParse->nTab++; | ||
599 | sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); | ||
600 | |||
601 | /* fill the ephemeral table | ||
602 | */ | ||
603 | sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0); | ||
604 | |||
605 | /* | ||
606 | ** Generate code to scan the ephemeral table and call VDelete and | ||
607 | ** VInsert | ||
608 | */ | ||
609 | sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0); | ||
610 | addr = sqlite3VdbeCurrentAddr(v); | ||
611 | sqlite3VdbeAddOp(v, OP_Column, ephemTab, 0); | ||
612 | if( pRowid ){ | ||
613 | sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1); | ||
614 | }else{ | ||
615 | sqlite3VdbeAddOp(v, OP_Dup, 0, 0); | ||
616 | } | ||
617 | for(i=0; i<pTab->nCol; i++){ | ||
618 | sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0)); | ||
619 | } | ||
620 | pParse->pVirtualLock = pTab; | ||
621 | sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, | ||
622 | (const char*)pTab->pVtab, P3_VTAB); | ||
623 | sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr); | ||
624 | sqlite3VdbeJumpHere(v, addr-1); | ||
625 | sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0); | ||
626 | |||
627 | /* Cleanup */ | ||
628 | sqlite3SelectDelete(pSelect); | ||
629 | } | ||
630 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ | ||