monotone

monotone Mtn Source Tree

Root/sqlite/update.c

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.1 2003/08/05 23:03:07 graydon Exp $
16*/
17#include "sqliteInt.h"
18
19/*
20** Process an UPDATE statement.
21**
22** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
23** \_______/ \________/ \______/ \________________/
24* onError pTabList pChanges pWhere
25*/
26void sqliteUpdate(
27 Parse *pParse, /* The parser context */
28 SrcList *pTabList, /* The table in which we should change things */
29 ExprList *pChanges, /* Things to be changed */
30 Expr *pWhere, /* The WHERE clause. May be null */
31 int onError /* How to handle constraint errors */
32){
33 int i, j; /* Loop counters */
34 Table *pTab; /* The table to be updated */
35 int addr; /* VDBE instruction address of the start of the loop */
36 WhereInfo *pWInfo; /* Information about the WHERE clause */
37 Vdbe *v; /* The virtual database engine */
38 Index *pIdx; /* For looping over indices */
39 int nIdx; /* Number of indices that need updating */
40 int nIdxTotal; /* Total number of indices */
41 int iCur; /* VDBE Cursor number of pTab */
42 sqlite *db; /* The database structure */
43 Index **apIdx = 0; /* An array of indices that need updating too */
44 char *aIdxUsed = 0; /* aIdxUsed[i]==1 if the i-th index is used */
45 int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
46 ** an expression for the i-th column of the table.
47 ** aXRef[i]==-1 if the i-th column is not changed. */
48 int chngRecno; /* True if the record number is being changed */
49 Expr *pRecnoExpr; /* Expression defining the new record number */
50 int openAll; /* True if all indices need to be opened */
51 int isView; /* Trying to update a view */
52 AuthContext sContext; /* The authorization context */
53
54 int before_triggers; /* True if there are any BEFORE triggers */
55 int after_triggers; /* True if there are any AFTER triggers */
56 int row_triggers_exist = 0; /* True if any row triggers exist */
57
58 int newIdx = -1; /* index of trigger "new" temp table */
59 int oldIdx = -1; /* index of trigger "old" temp table */
60
61 sContext.pParse = 0;
62 if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
63 db = pParse->db;
64 assert( pTabList->nSrc==1 );
65
66 /* Locate the table which we want to update.
67 */
68 pTab = sqliteSrcListLookup(pParse, pTabList);
69 if( pTab==0 ) goto update_cleanup;
70 before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
71 TK_UPDATE, TK_BEFORE, TK_ROW, pChanges);
72 after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
73 TK_UPDATE, TK_AFTER, TK_ROW, pChanges);
74 row_triggers_exist = before_triggers || after_triggers;
75 isView = pTab->pSelect!=0;
76 if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
77 goto update_cleanup;
78 }
79 if( isView ){
80 if( sqliteViewGetColumnNames(pParse, pTab) ){
81 goto update_cleanup;
82 }
83 }
84 aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
85 if( aXRef==0 ) goto update_cleanup;
86 for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
87
88 /* If there are FOR EACH ROW triggers, allocate cursors for the
89 ** special OLD and NEW tables
90 */
91 if( row_triggers_exist ){
92 newIdx = pParse->nTab++;
93 oldIdx = pParse->nTab++;
94 }
95
96 /* Allocate a cursors for the main database table and for all indices.
97 ** The index cursors might not be used, but if they are used they
98 ** need to occur right after the database cursor. So go ahead and
99 ** allocate enough space, just in case.
100 */
101 pTabList->a[0].iCursor = iCur = pParse->nTab++;
102 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
103 pParse->nTab++;
104 }
105
106 /* Resolve the column names in all the expressions of the
107 ** of the UPDATE statement. Also find the column index
108 ** for each column to be updated in the pChanges array. For each
109 ** column to be updated, make sure we have authorization to change
110 ** that column.
111 */
112 chngRecno = 0;
113 for(i=0; i<pChanges->nExpr; i++){
114 if( sqliteExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
115 goto update_cleanup;
116 }
117 if( sqliteExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
118 goto update_cleanup;
119 }
120 for(j=0; j<pTab->nCol; j++){
121 if( sqliteStrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
122 if( j==pTab->iPKey ){
123 chngRecno = 1;
124 pRecnoExpr = pChanges->a[i].pExpr;
125 }
126 aXRef[j] = i;
127 break;
128 }
129 }
130 if( j>=pTab->nCol ){
131 if( sqliteIsRowid(pChanges->a[i].zName) ){
132 chngRecno = 1;
133 pRecnoExpr = pChanges->a[i].pExpr;
134 }else{
135 sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
136 goto update_cleanup;
137 }
138 }
139#ifndef SQLITE_OMIT_AUTHORIZATION
140 {
141 int rc;
142 rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
143 pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
144 if( rc==SQLITE_DENY ){
145 goto update_cleanup;
146 }else if( rc==SQLITE_IGNORE ){
147 aXRef[j] = -1;
148 }
149 }
150#endif
151 }
152
153 /* Allocate memory for the array apIdx[] and fill it with pointers to every
154 ** index that needs to be updated. Indices only need updating if their
155 ** key includes one of the columns named in pChanges or if the record
156 ** number of the original table entry is changing.
157 */
158 for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
159 if( chngRecno ){
160 i = 0;
161 }else {
162 for(i=0; i<pIdx->nColumn; i++){
163 if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
164 }
165 }
166 if( i<pIdx->nColumn ) nIdx++;
167 }
168 if( nIdxTotal>0 ){
169 apIdx = sqliteMalloc( sizeof(Index*) * nIdx + nIdxTotal );
170 if( apIdx==0 ) goto update_cleanup;
171 aIdxUsed = (char*)&apIdx[nIdx];
172 }
173 for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
174 if( chngRecno ){
175 i = 0;
176 }else{
177 for(i=0; i<pIdx->nColumn; i++){
178 if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
179 }
180 }
181 if( i<pIdx->nColumn ){
182 apIdx[nIdx++] = pIdx;
183 aIdxUsed[j] = 1;
184 }else{
185 aIdxUsed[j] = 0;
186 }
187 }
188
189 /* Resolve the column names in all the expressions in the
190 ** WHERE clause.
191 */
192 if( pWhere ){
193 if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
194 goto update_cleanup;
195 }
196 if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
197 goto update_cleanup;
198 }
199 }
200
201 /* Start the view context
202 */
203 if( isView ){
204 sqliteAuthContextPush(pParse, &sContext, pTab->zName);
205 }
206
207 /* Begin generating code.
208 */
209 v = sqliteGetVdbe(pParse);
210 if( v==0 ) goto update_cleanup;
211 sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
212
213 /* If we are trying to update a view, construct that view into
214 ** a temporary table.
215 */
216 if( isView ){
217 Select *pView;
218 pView = sqliteSelectDup(pTab->pSelect);
219 sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
220 sqliteSelectDelete(pView);
221 }
222
223 /* Begin the database scan
224 */
225 pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
226 if( pWInfo==0 ) goto update_cleanup;
227
228 /* Remember the index of every item to be updated.
229 */
230 sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
231
232 /* End the database scan loop.
233 */
234 sqliteWhereEnd(pWInfo);
235
236 /* Initialize the count of updated rows
237 */
238 if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
239 sqliteVdbeAddOp(v, OP_Integer, 0, 0);
240 }
241
242 if( row_triggers_exist ){
243 /* Create pseudo-tables for NEW and OLD
244 */
245 sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
246 sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
247
248 /* The top of the update loop for when there are triggers.
249 */
250 sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
251 addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
252 sqliteVdbeAddOp(v, OP_Dup, 0, 0);
253
254 /* Open a cursor and make it point to the record that is
255 ** being updated.
256 */
257 sqliteVdbeAddOp(v, OP_Dup, 0, 0);
258 if( !isView ){
259 sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
260 sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
261 }
262 sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
263
264 /* Generate the OLD table
265 */
266 sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
267 sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
268 sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
269
270 /* Generate the NEW table
271 */
272 if( chngRecno ){
273 sqliteExprCode(pParse, pRecnoExpr);
274 }else{
275 sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
276 }
277 for(i=0; i<pTab->nCol; i++){
278 if( i==pTab->iPKey ){
279 sqliteVdbeAddOp(v, OP_String, 0, 0);
280 continue;
281 }
282 j = aXRef[i];
283 if( j<0 ){
284 sqliteVdbeAddOp(v, OP_Column, iCur, i);
285 }else{
286 sqliteExprCode(pParse, pChanges->a[j].pExpr);
287 }
288 }
289 sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
290 sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
291 if( !isView ){
292 sqliteVdbeAddOp(v, OP_Close, iCur, 0);
293 }
294
295 /* Fire the BEFORE and INSTEAD OF triggers
296 */
297 if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
298 newIdx, oldIdx, onError, addr) ){
299 goto update_cleanup;
300 }
301 }
302
303 if( !isView ){
304 /*
305 ** Open every index that needs updating. Note that if any
306 ** index could potentially invoke a REPLACE conflict resolution
307 ** action, then we need to open all indices because we might need
308 ** to be deleting some records.
309 */
310 sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
311 sqliteVdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
312 if( onError==OE_Replace ){
313 openAll = 1;
314 }else{
315 openAll = 0;
316 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
317 if( pIdx->onError==OE_Replace ){
318 openAll = 1;
319 break;
320 }
321 }
322 }
323 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
324 if( openAll || aIdxUsed[i] ){
325 sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
326 sqliteVdbeAddOp(v, OP_OpenWrite, iCur+i+1, pIdx->tnum);
327 assert( pParse->nTab>iCur+i+1 );
328 }
329 }
330
331 /* Loop over every record that needs updating. We have to load
332 ** the old data for each record to be updated because some columns
333 ** might not change and we will need to copy the old value.
334 ** Also, the old data is needed to delete the old index entires.
335 ** So make the cursor point at the old record.
336 */
337 if( !row_triggers_exist ){
338 sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
339 addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
340 sqliteVdbeAddOp(v, OP_Dup, 0, 0);
341 }
342 sqliteVdbeAddOp(v, OP_NotExists, iCur, addr);
343
344 /* If the record number will change, push the record number as it
345 ** will be after the update. (The old record number is currently
346 ** on top of the stack.)
347 */
348 if( chngRecno ){
349 sqliteExprCode(pParse, pRecnoExpr);
350 sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
351 }
352
353 /* Compute new data for this record.
354 */
355 for(i=0; i<pTab->nCol; i++){
356 if( i==pTab->iPKey ){
357 sqliteVdbeAddOp(v, OP_String, 0, 0);
358 continue;
359 }
360 j = aXRef[i];
361 if( j<0 ){
362 sqliteVdbeAddOp(v, OP_Column, iCur, i);
363 }else{
364 sqliteExprCode(pParse, pChanges->a[j].pExpr);
365 }
366 }
367
368 /* Do constraint checks
369 */
370 sqliteGenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
371 onError, addr);
372
373 /* Delete the old indices for the current record.
374 */
375 sqliteGenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
376
377 /* If changing the record number, delete the old record.
378 */
379 if( chngRecno ){
380 sqliteVdbeAddOp(v, OP_Delete, iCur, 0);
381 }
382
383 /* Create the new index entries and the new record.
384 */
385 sqliteCompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
386 }
387
388 /* Increment the row counter
389 */
390 if( db->flags & SQLITE_CountRows && !pParse->trigStack){
391 sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
392 }
393
394 /* If there are triggers, close all the cursors after each iteration
395 ** through the loop. The fire the after triggers.
396 */
397 if( row_triggers_exist ){
398 if( !isView ){
399 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
400 if( openAll || aIdxUsed[i] )
401 sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
402 }
403 sqliteVdbeAddOp(v, OP_Close, iCur, 0);
404 pParse->nTab = iCur;
405 }
406 if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
407 newIdx, oldIdx, onError, addr) ){
408 goto update_cleanup;
409 }
410 }
411
412 /* Repeat the above with the next record to be updated, until
413 ** all record selected by the WHERE clause have been updated.
414 */
415 sqliteVdbeAddOp(v, OP_Goto, 0, addr);
416 sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
417 sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
418
419 /* Close all tables if there were no FOR EACH ROW triggers */
420 if( !row_triggers_exist ){
421 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
422 if( openAll || aIdxUsed[i] ){
423 sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
424 }
425 }
426 sqliteVdbeAddOp(v, OP_Close, iCur, 0);
427 pParse->nTab = iCur;
428 }else{
429 sqliteVdbeAddOp(v, OP_Close, newIdx, 0);
430 sqliteVdbeAddOp(v, OP_Close, oldIdx, 0);
431 }
432
433 sqliteEndWriteOperation(pParse);
434
435 /*
436 ** Return the number of rows that were changed.
437 */
438 if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
439 sqliteVdbeAddOp(v, OP_ColumnName, 0, 0);
440 sqliteVdbeChangeP3(v, -1, "rows updated", P3_STATIC);
441 sqliteVdbeAddOp(v, OP_Callback, 1, 0);
442 }
443
444update_cleanup:
445 sqliteAuthContextPop(&sContext);
446 sqliteFree(apIdx);
447 sqliteFree(aXRef);
448 sqliteSrcListDelete(pTabList);
449 sqliteExprListDelete(pChanges);
450 sqliteExprDelete(pWhere);
451 return;
452}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status