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