Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: third_party/sqlite/src/src/delete.c

Issue 1610963002: Import SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/src/dbstat.c ('k') | third_party/sqlite/src/src/expr.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2001 September 15 2 ** 2001 September 15
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 int iDb = sqlite3SchemaToIndex(db, pView->pSchema); 99 int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
100 pWhere = sqlite3ExprDup(db, pWhere, 0); 100 pWhere = sqlite3ExprDup(db, pWhere, 0);
101 pFrom = sqlite3SrcListAppend(db, 0, 0, 0); 101 pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
102 if( pFrom ){ 102 if( pFrom ){
103 assert( pFrom->nSrc==1 ); 103 assert( pFrom->nSrc==1 );
104 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); 104 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
105 pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName); 105 pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
106 assert( pFrom->a[0].pOn==0 ); 106 assert( pFrom->a[0].pOn==0 );
107 assert( pFrom->a[0].pUsing==0 ); 107 assert( pFrom->a[0].pUsing==0 );
108 } 108 }
109 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); 109 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
110 SF_IncludeHidden, 0, 0);
110 sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); 111 sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
111 sqlite3Select(pParse, pSel, &dest); 112 sqlite3Select(pParse, pSel, &dest);
112 sqlite3SelectDelete(db, pSel); 113 sqlite3SelectDelete(db, pSel);
113 } 114 }
114 #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ 115 #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
115 116
116 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) 117 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
117 /* 118 /*
118 ** Generate an expression tree to implement the WHERE, ORDER BY, 119 ** Generate an expression tree to implement the WHERE, ORDER BY,
119 ** and LIMIT/OFFSET portion of DELETE and UPDATE statements. 120 ** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 if( pSelect == 0 ) return 0; 183 if( pSelect == 0 ) return 0;
183 184
184 /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ 185 /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
185 pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); 186 pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
186 if( pWhereRowid == 0 ) goto limit_where_cleanup_1; 187 if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
187 pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); 188 pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
188 if( pInClause == 0 ) goto limit_where_cleanup_1; 189 if( pInClause == 0 ) goto limit_where_cleanup_1;
189 190
190 pInClause->x.pSelect = pSelect; 191 pInClause->x.pSelect = pSelect;
191 pInClause->flags |= EP_xIsSelect; 192 pInClause->flags |= EP_xIsSelect;
192 sqlite3ExprSetHeight(pParse, pInClause); 193 sqlite3ExprSetHeightAndFlags(pParse, pInClause);
193 return pInClause; 194 return pInClause;
194 195
195 /* something went wrong. clean up anything allocated. */ 196 /* something went wrong. clean up anything allocated. */
196 limit_where_cleanup_1: 197 limit_where_cleanup_1:
197 sqlite3SelectDelete(pParse->db, pSelect); 198 sqlite3SelectDelete(pParse->db, pSelect);
198 return 0; 199 return 0;
199 200
200 limit_where_cleanup_2: 201 limit_where_cleanup_2:
201 sqlite3ExprDelete(pParse->db, pWhere); 202 sqlite3ExprDelete(pParse->db, pWhere);
202 sqlite3ExprListDelete(pParse->db, pOrderBy); 203 sqlite3ExprListDelete(pParse->db, pOrderBy);
(...skipping 16 matching lines...) Expand all
219 SrcList *pTabList, /* The table from which we should delete things */ 220 SrcList *pTabList, /* The table from which we should delete things */
220 Expr *pWhere /* The WHERE clause. May be null */ 221 Expr *pWhere /* The WHERE clause. May be null */
221 ){ 222 ){
222 Vdbe *v; /* The virtual database engine */ 223 Vdbe *v; /* The virtual database engine */
223 Table *pTab; /* The table from which records will be deleted */ 224 Table *pTab; /* The table from which records will be deleted */
224 const char *zDb; /* Name of database holding pTab */ 225 const char *zDb; /* Name of database holding pTab */
225 int i; /* Loop counter */ 226 int i; /* Loop counter */
226 WhereInfo *pWInfo; /* Information about the WHERE clause */ 227 WhereInfo *pWInfo; /* Information about the WHERE clause */
227 Index *pIdx; /* For looping over indices of the table */ 228 Index *pIdx; /* For looping over indices of the table */
228 int iTabCur; /* Cursor number for the table */ 229 int iTabCur; /* Cursor number for the table */
229 int iDataCur; /* VDBE cursor for the canonical data source */ 230 int iDataCur = 0; /* VDBE cursor for the canonical data source */
230 int iIdxCur; /* Cursor number of the first index */ 231 int iIdxCur = 0; /* Cursor number of the first index */
231 int nIdx; /* Number of indices */ 232 int nIdx; /* Number of indices */
232 sqlite3 *db; /* Main database structure */ 233 sqlite3 *db; /* Main database structure */
233 AuthContext sContext; /* Authorization context */ 234 AuthContext sContext; /* Authorization context */
234 NameContext sNC; /* Name context to resolve expressions in */ 235 NameContext sNC; /* Name context to resolve expressions in */
235 int iDb; /* Database number */ 236 int iDb; /* Database number */
236 int memCnt = -1; /* Memory cell used for change counting */ 237 int memCnt = -1; /* Memory cell used for change counting */
237 int rcauth; /* Value returned by authorization callback */ 238 int rcauth; /* Value returned by authorization callback */
238 int okOnePass; /* True for one-pass algorithm without the FIFO */ 239 int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
239 int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ 240 int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
240 u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ 241 u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
241 Index *pPk; /* The PRIMARY KEY index on the table */ 242 Index *pPk; /* The PRIMARY KEY index on the table */
242 int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ 243 int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */
243 i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ 244 i16 nPk = 1; /* Number of columns in the PRIMARY KEY */
244 int iKey; /* Memory cell holding key of row to be deleted */ 245 int iKey; /* Memory cell holding key of row to be deleted */
245 i16 nKey; /* Number of memory cells in the row key */ 246 i16 nKey; /* Number of memory cells in the row key */
246 int iEphCur = 0; /* Ephemeral table holding all primary key values */ 247 int iEphCur = 0; /* Ephemeral table holding all primary key values */
247 int iRowSet = 0; /* Register for rowset of rows to delete */ 248 int iRowSet = 0; /* Register for rowset of rows to delete */
248 int addrBypass = 0; /* Address of jump over the delete logic */ 249 int addrBypass = 0; /* Address of jump over the delete logic */
249 int addrLoop = 0; /* Top of the delete loop */ 250 int addrLoop = 0; /* Top of the delete loop */
250 int addrDelete = 0; /* Jump directly to the delete logic */
251 int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ 251 int addrEphOpen = 0; /* Instruction to open the Ephemeral table */
252 252
253 #ifndef SQLITE_OMIT_TRIGGER 253 #ifndef SQLITE_OMIT_TRIGGER
254 int isView; /* True if attempting to delete from a view */ 254 int isView; /* True if attempting to delete from a view */
255 Trigger *pTrigger; /* List of table triggers, if required */ 255 Trigger *pTrigger; /* List of table triggers, if required */
256 int bComplex; /* True if there are either triggers or FKs */
256 #endif 257 #endif
257 258
258 memset(&sContext, 0, sizeof(sContext)); 259 memset(&sContext, 0, sizeof(sContext));
259 db = pParse->db; 260 db = pParse->db;
260 if( pParse->nErr || db->mallocFailed ){ 261 if( pParse->nErr || db->mallocFailed ){
261 goto delete_from_cleanup; 262 goto delete_from_cleanup;
262 } 263 }
263 assert( pTabList->nSrc==1 ); 264 assert( pTabList->nSrc==1 );
264 265
265 /* Locate the table which we want to delete. This table has to be 266 /* Locate the table which we want to delete. This table has to be
266 ** put in an SrcList structure because some of the subroutines we 267 ** put in an SrcList structure because some of the subroutines we
267 ** will be calling are designed to work with multiple tables and expect 268 ** will be calling are designed to work with multiple tables and expect
268 ** an SrcList* parameter instead of just a Table* parameter. 269 ** an SrcList* parameter instead of just a Table* parameter.
269 */ 270 */
270 pTab = sqlite3SrcListLookup(pParse, pTabList); 271 pTab = sqlite3SrcListLookup(pParse, pTabList);
271 if( pTab==0 ) goto delete_from_cleanup; 272 if( pTab==0 ) goto delete_from_cleanup;
272 273
273 /* Figure out if we have any triggers and if the table being 274 /* Figure out if we have any triggers and if the table being
274 ** deleted from is a view 275 ** deleted from is a view
275 */ 276 */
276 #ifndef SQLITE_OMIT_TRIGGER 277 #ifndef SQLITE_OMIT_TRIGGER
277 pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); 278 pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
278 isView = pTab->pSelect!=0; 279 isView = pTab->pSelect!=0;
280 bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
279 #else 281 #else
280 # define pTrigger 0 282 # define pTrigger 0
281 # define isView 0 283 # define isView 0
284 # define bComplex 0
282 #endif 285 #endif
283 #ifdef SQLITE_OMIT_VIEW 286 #ifdef SQLITE_OMIT_VIEW
284 # undef isView 287 # undef isView
285 # define isView 0 288 # define isView 0
286 #endif 289 #endif
287 290
288 /* If pTab is really a view, make sure it has been initialized. 291 /* If pTab is really a view, make sure it has been initialized.
289 */ 292 */
290 if( sqlite3ViewGetColumnNames(pParse, pTab) ){ 293 if( sqlite3ViewGetColumnNames(pParse, pTab) ){
291 goto delete_from_cleanup; 294 goto delete_from_cleanup;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 if( db->flags & SQLITE_CountRows ){ 355 if( db->flags & SQLITE_CountRows ){
353 memCnt = ++pParse->nMem; 356 memCnt = ++pParse->nMem;
354 sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); 357 sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
355 } 358 }
356 359
357 #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION 360 #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
358 /* Special case: A DELETE without a WHERE clause deletes everything. 361 /* Special case: A DELETE without a WHERE clause deletes everything.
359 ** It is easier just to erase the whole table. Prior to version 3.6.5, 362 ** It is easier just to erase the whole table. Prior to version 3.6.5,
360 ** this optimization caused the row change count (the value returned by 363 ** this optimization caused the row change count (the value returned by
361 ** API function sqlite3_count_changes) to be set incorrectly. */ 364 ** API function sqlite3_count_changes) to be set incorrectly. */
362 if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) 365 if( rcauth==SQLITE_OK
363 && 0==sqlite3FkRequired(pParse, pTab, 0, 0) 366 && pWhere==0
367 && !bComplex
368 && !IsVirtual(pTab)
364 ){ 369 ){
365 assert( !isView ); 370 assert( !isView );
366 sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); 371 sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
367 if( HasRowid(pTab) ){ 372 if( HasRowid(pTab) ){
368 sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, 373 sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
369 pTab->zName, P4_STATIC); 374 pTab->zName, P4_STATIC);
370 } 375 }
371 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ 376 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
372 assert( pIdx->pSchema==pTab->pSchema ); 377 assert( pIdx->pSchema==pTab->pSchema );
373 sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); 378 sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
374 } 379 }
375 }else 380 }else
376 #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ 381 #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
377 { 382 {
383 u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
384 wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
378 if( HasRowid(pTab) ){ 385 if( HasRowid(pTab) ){
379 /* For a rowid table, initialize the RowSet to an empty set */ 386 /* For a rowid table, initialize the RowSet to an empty set */
380 pPk = 0; 387 pPk = 0;
381 nPk = 1; 388 nPk = 1;
382 iRowSet = ++pParse->nMem; 389 iRowSet = ++pParse->nMem;
383 sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); 390 sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
384 }else{ 391 }else{
385 /* For a WITHOUT ROWID table, create an ephemeral table used to 392 /* For a WITHOUT ROWID table, create an ephemeral table used to
386 ** hold all primary keys for rows to be deleted. */ 393 ** hold all primary keys for rows to be deleted. */
387 pPk = sqlite3PrimaryKeyIndex(pTab); 394 pPk = sqlite3PrimaryKeyIndex(pTab);
388 assert( pPk!=0 ); 395 assert( pPk!=0 );
389 nPk = pPk->nKeyCol; 396 nPk = pPk->nKeyCol;
390 iPk = pParse->nMem+1; 397 iPk = pParse->nMem+1;
391 pParse->nMem += nPk; 398 pParse->nMem += nPk;
392 iEphCur = pParse->nTab++; 399 iEphCur = pParse->nTab++;
393 addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); 400 addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk);
394 sqlite3VdbeSetP4KeyInfo(pParse, pPk); 401 sqlite3VdbeSetP4KeyInfo(pParse, pPk);
395 } 402 }
396 403
397 /* Construct a query to find the rowid or primary key for every row 404 /* Construct a query to find the rowid or primary key for every row
398 ** to be deleted, based on the WHERE clause. 405 ** to be deleted, based on the WHERE clause. Set variable eOnePass
406 ** to indicate the strategy used to implement this delete:
407 **
408 ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
409 ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
410 ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
399 */ 411 */
400 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 412 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
401 WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK,
402 iTabCur+1);
403 if( pWInfo==0 ) goto delete_from_cleanup; 413 if( pWInfo==0 ) goto delete_from_cleanup;
404 okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); 414 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
415 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
416 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
405 417
406 /* Keep track of the number of rows to be deleted */ 418 /* Keep track of the number of rows to be deleted */
407 if( db->flags & SQLITE_CountRows ){ 419 if( db->flags & SQLITE_CountRows ){
408 sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); 420 sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
409 } 421 }
410 422
411 /* Extract the rowid or primary key for the current row */ 423 /* Extract the rowid or primary key for the current row */
412 if( pPk ){ 424 if( pPk ){
413 for(i=0; i<nPk; i++){ 425 for(i=0; i<nPk; i++){
426 assert( pPk->aiColumn[i]>=0 );
414 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, 427 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
415 pPk->aiColumn[i], iPk+i); 428 pPk->aiColumn[i], iPk+i);
416 } 429 }
417 iKey = iPk; 430 iKey = iPk;
418 }else{ 431 }else{
419 iKey = pParse->nMem + 1; 432 iKey = pParse->nMem + 1;
420 iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); 433 iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
421 if( iKey>pParse->nMem ) pParse->nMem = iKey; 434 if( iKey>pParse->nMem ) pParse->nMem = iKey;
422 } 435 }
423 436
424 if( okOnePass ){ 437 if( eOnePass!=ONEPASS_OFF ){
425 /* For ONEPASS, no need to store the rowid/primary-key. There is only 438 /* For ONEPASS, no need to store the rowid/primary-key. There is only
426 ** one, so just keep it in its register(s) and fall through to the 439 ** one, so just keep it in its register(s) and fall through to the
427 ** delete code. 440 ** delete code. */
428 */
429 nKey = nPk; /* OP_Found will use an unpacked key */ 441 nKey = nPk; /* OP_Found will use an unpacked key */
430 aToOpen = sqlite3DbMallocRaw(db, nIdx+2); 442 aToOpen = sqlite3DbMallocRaw(db, nIdx+2);
431 if( aToOpen==0 ){ 443 if( aToOpen==0 ){
432 sqlite3WhereEnd(pWInfo); 444 sqlite3WhereEnd(pWInfo);
433 goto delete_from_cleanup; 445 goto delete_from_cleanup;
434 } 446 }
435 memset(aToOpen, 1, nIdx+1); 447 memset(aToOpen, 1, nIdx+1);
436 aToOpen[nIdx+1] = 0; 448 aToOpen[nIdx+1] = 0;
437 if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; 449 if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
438 if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; 450 if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
439 if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); 451 if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
440 addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */
441 }else if( pPk ){
442 /* Construct a composite key for the row to be deleted and remember it */
443 iKey = ++pParse->nMem;
444 nKey = 0; /* Zero tells OP_Found to use a composite key */
445 sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
446 sqlite3IndexAffinityStr(v, pPk), nPk);
447 sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
448 }else{ 452 }else{
449 /* Get the rowid of the row to be deleted and remember it in the RowSet */ 453 if( pPk ){
450 nKey = 1; /* OP_Seek always uses a single rowid */ 454 /* Add the PK key for this row to the temporary table */
451 sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); 455 iKey = ++pParse->nMem;
456 nKey = 0; /* Zero tells OP_Found to use a composite key */
457 sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
458 sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
459 sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
460 }else{
461 /* Add the rowid of the row to be deleted to the RowSet */
462 nKey = 1; /* OP_Seek always uses a single rowid */
463 sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
464 }
452 } 465 }
453 466
454 /* End of the WHERE loop */ 467 /* If this DELETE cannot use the ONEPASS strategy, this is the
455 sqlite3WhereEnd(pWInfo); 468 ** end of the WHERE loop */
456 if( okOnePass ){ 469 if( eOnePass!=ONEPASS_OFF ){
457 /* Bypass the delete logic below if the WHERE loop found zero rows */
458 addrBypass = sqlite3VdbeMakeLabel(v); 470 addrBypass = sqlite3VdbeMakeLabel(v);
459 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass); 471 }else{
460 sqlite3VdbeJumpHere(v, addrDelete); 472 sqlite3WhereEnd(pWInfo);
461 } 473 }
462 474
463 /* Unless this is a view, open cursors for the table we are 475 /* Unless this is a view, open cursors for the table we are
464 ** deleting from and all its indices. If this is a view, then the 476 ** deleting from and all its indices. If this is a view, then the
465 ** only effect this statement has is to fire the INSTEAD OF 477 ** only effect this statement has is to fire the INSTEAD OF
466 ** triggers. 478 ** triggers.
467 */ 479 */
468 if( !isView ){ 480 if( !isView ){
481 int iAddrOnce = 0;
482 u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE);
483 if( eOnePass==ONEPASS_MULTI ){
484 iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
485 }
469 testcase( IsVirtual(pTab) ); 486 testcase( IsVirtual(pTab) );
470 sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, 487 sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur,
471 &iDataCur, &iIdxCur); 488 aToOpen, &iDataCur, &iIdxCur);
472 assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); 489 assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
473 assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); 490 assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
491 if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
474 } 492 }
475 493
476 /* Set up a loop over the rowids/primary-keys that were found in the 494 /* Set up a loop over the rowids/primary-keys that were found in the
477 ** where-clause loop above. 495 ** where-clause loop above.
478 */ 496 */
479 if( okOnePass ){ 497 if( eOnePass!=ONEPASS_OFF ){
480 /* Just one row. Hence the top-of-loop is a no-op */
481 assert( nKey==nPk ); /* OP_Found will use an unpacked key */ 498 assert( nKey==nPk ); /* OP_Found will use an unpacked key */
482 assert( !IsVirtual(pTab) ); 499 if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
483 if( aToOpen[iDataCur-iTabCur] ){
484 assert( pPk!=0 || pTab->pSelect!=0 ); 500 assert( pPk!=0 || pTab->pSelect!=0 );
485 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); 501 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
486 VdbeCoverage(v); 502 VdbeCoverage(v);
487 } 503 }
488 }else if( pPk ){ 504 }else if( pPk ){
489 addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); 505 addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
490 sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); 506 sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
491 assert( nKey==0 ); /* OP_Found will use a composite key */ 507 assert( nKey==0 ); /* OP_Found will use a composite key */
492 }else{ 508 }else{
493 addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); 509 addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
494 VdbeCoverage(v); 510 VdbeCoverage(v);
495 assert( nKey==1 ); 511 assert( nKey==1 );
496 } 512 }
497 513
498 /* Delete the row */ 514 /* Delete the row */
499 #ifndef SQLITE_OMIT_VIRTUALTABLE 515 #ifndef SQLITE_OMIT_VIRTUALTABLE
500 if( IsVirtual(pTab) ){ 516 if( IsVirtual(pTab) ){
501 const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); 517 const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
502 sqlite3VtabMakeWritable(pParse, pTab); 518 sqlite3VtabMakeWritable(pParse, pTab);
503 sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); 519 sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
504 sqlite3VdbeChangeP5(v, OE_Abort); 520 sqlite3VdbeChangeP5(v, OE_Abort);
521 assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
505 sqlite3MayAbort(pParse); 522 sqlite3MayAbort(pParse);
523 if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
524 pParse->isMultiWrite = 0;
525 }
506 }else 526 }else
507 #endif 527 #endif
508 { 528 {
509 int count = (pParse->nested==0); /* True to count changes */ 529 int count = (pParse->nested==0); /* True to count changes */
530 int iIdxNoSeek = -1;
531 if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){
532 iIdxNoSeek = aiCurOnePass[1];
533 }
510 sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, 534 sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
511 iKey, nKey, count, OE_Default, okOnePass); 535 iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek);
512 } 536 }
513 537
514 /* End of the loop over all rowids/primary-keys. */ 538 /* End of the loop over all rowids/primary-keys. */
515 if( okOnePass ){ 539 if( eOnePass!=ONEPASS_OFF ){
516 sqlite3VdbeResolveLabel(v, addrBypass); 540 sqlite3VdbeResolveLabel(v, addrBypass);
541 sqlite3WhereEnd(pWInfo);
517 }else if( pPk ){ 542 }else if( pPk ){
518 sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); 543 sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
519 sqlite3VdbeJumpHere(v, addrLoop); 544 sqlite3VdbeJumpHere(v, addrLoop);
520 }else{ 545 }else{
521 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); 546 sqlite3VdbeGoto(v, addrLoop);
522 sqlite3VdbeJumpHere(v, addrLoop); 547 sqlite3VdbeJumpHere(v, addrLoop);
523 } 548 }
524 549
525 /* Close the cursors open on the table and its indexes. */ 550 /* Close the cursors open on the table and its indexes. */
526 if( !isView && !IsVirtual(pTab) ){ 551 if( !isView && !IsVirtual(pTab) ){
527 if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur); 552 if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
528 for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ 553 for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
529 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i); 554 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i);
530 } 555 }
531 } 556 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 ** in the case of a rowid table, or the PRIMARY KEY index in the case 603 ** in the case of a rowid table, or the PRIMARY KEY index in the case
579 ** of a WITHOUT ROWID table.) 604 ** of a WITHOUT ROWID table.)
580 ** 605 **
581 ** 2. Read/write cursors for all indices of pTab must be open as 606 ** 2. Read/write cursors for all indices of pTab must be open as
582 ** cursor number iIdxCur+i for the i-th index. 607 ** cursor number iIdxCur+i for the i-th index.
583 ** 608 **
584 ** 3. The primary key for the row to be deleted must be stored in a 609 ** 3. The primary key for the row to be deleted must be stored in a
585 ** sequence of nPk memory cells starting at iPk. If nPk==0 that means 610 ** sequence of nPk memory cells starting at iPk. If nPk==0 that means
586 ** that a search record formed from OP_MakeRecord is contained in the 611 ** that a search record formed from OP_MakeRecord is contained in the
587 ** single memory location iPk. 612 ** single memory location iPk.
613 **
614 ** eMode:
615 ** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
616 ** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
617 ** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
618 ** then this function must seek iDataCur to the entry identified by iPk
619 ** and nPk before reading from it.
620 **
621 ** If eMode is ONEPASS_MULTI, then this call is being made as part
622 ** of a ONEPASS delete that affects multiple rows. In this case, if
623 ** iIdxNoSeek is a valid cursor number (>=0), then its position should
624 ** be preserved following the delete operation. Or, if iIdxNoSeek is not
625 ** a valid cursor number, the position of iDataCur should be preserved
626 ** instead.
627 **
628 ** iIdxNoSeek:
629 ** If iIdxNoSeek is a valid cursor number (>=0), then it identifies an
630 ** index cursor (from within array of cursors starting at iIdxCur) that
631 ** already points to the index entry to be deleted.
588 */ 632 */
589 void sqlite3GenerateRowDelete( 633 void sqlite3GenerateRowDelete(
590 Parse *pParse, /* Parsing context */ 634 Parse *pParse, /* Parsing context */
591 Table *pTab, /* Table containing the row to be deleted */ 635 Table *pTab, /* Table containing the row to be deleted */
592 Trigger *pTrigger, /* List of triggers to (potentially) fire */ 636 Trigger *pTrigger, /* List of triggers to (potentially) fire */
593 int iDataCur, /* Cursor from which column data is extracted */ 637 int iDataCur, /* Cursor from which column data is extracted */
594 int iIdxCur, /* First index cursor */ 638 int iIdxCur, /* First index cursor */
595 int iPk, /* First memory cell containing the PRIMARY KEY */ 639 int iPk, /* First memory cell containing the PRIMARY KEY */
596 i16 nPk, /* Number of PRIMARY KEY memory cells */ 640 i16 nPk, /* Number of PRIMARY KEY memory cells */
597 u8 count, /* If non-zero, increment the row change counter */ 641 u8 count, /* If non-zero, increment the row change counter */
598 u8 onconf, /* Default ON CONFLICT policy for triggers */ 642 u8 onconf, /* Default ON CONFLICT policy for triggers */
599 u8 bNoSeek /* iDataCur is already pointing to the row to delete */ 643 u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
644 int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
600 ){ 645 ){
601 Vdbe *v = pParse->pVdbe; /* Vdbe */ 646 Vdbe *v = pParse->pVdbe; /* Vdbe */
602 int iOld = 0; /* First register in OLD.* array */ 647 int iOld = 0; /* First register in OLD.* array */
603 int iLabel; /* Label resolved to end of generated code */ 648 int iLabel; /* Label resolved to end of generated code */
604 u8 opSeek; /* Seek opcode */ 649 u8 opSeek; /* Seek opcode */
605 650
606 /* Vdbe is guaranteed to have been allocated by this stage. */ 651 /* Vdbe is guaranteed to have been allocated by this stage. */
607 assert( v ); 652 assert( v );
608 VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)", 653 VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
609 iDataCur, iIdxCur, iPk, (int)nPk)); 654 iDataCur, iIdxCur, iPk, (int)nPk));
610 655
611 /* Seek cursor iCur to the row to delete. If this row no longer exists 656 /* Seek cursor iCur to the row to delete. If this row no longer exists
612 ** (this can happen if a trigger program has already deleted it), do 657 ** (this can happen if a trigger program has already deleted it), do
613 ** not attempt to delete it or fire any DELETE triggers. */ 658 ** not attempt to delete it or fire any DELETE triggers. */
614 iLabel = sqlite3VdbeMakeLabel(v); 659 iLabel = sqlite3VdbeMakeLabel(v);
615 opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; 660 opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
616 if( !bNoSeek ){ 661 if( eMode==ONEPASS_OFF ){
617 sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); 662 sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
618 VdbeCoverageIf(v, opSeek==OP_NotExists); 663 VdbeCoverageIf(v, opSeek==OP_NotExists);
619 VdbeCoverageIf(v, opSeek==OP_NotFound); 664 VdbeCoverageIf(v, opSeek==OP_NotFound);
620 } 665 }
621 666
622 /* If there are any triggers to fire, allocate a range of registers to 667 /* If there are any triggers to fire, allocate a range of registers to
623 ** use for the old.* references in the triggers. */ 668 ** use for the old.* references in the triggers. */
624 if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ 669 if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
625 u32 mask; /* Mask of OLD.* columns in use */ 670 u32 mask; /* Mask of OLD.* columns in use */
626 int iCol; /* Iterator used while populating OLD.* */ 671 int iCol; /* Iterator used while populating OLD.* */
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 /* Do FK processing. This call checks that any FK constraints that 711 /* Do FK processing. This call checks that any FK constraints that
667 ** refer to this table (i.e. constraints attached to other tables) 712 ** refer to this table (i.e. constraints attached to other tables)
668 ** are not violated by deleting this row. */ 713 ** are not violated by deleting this row. */
669 sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); 714 sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0);
670 } 715 }
671 716
672 /* Delete the index and table entries. Skip this step if pTab is really 717 /* Delete the index and table entries. Skip this step if pTab is really
673 ** a view (in which case the only effect of the DELETE statement is to 718 ** a view (in which case the only effect of the DELETE statement is to
674 ** fire the INSTEAD OF triggers). */ 719 ** fire the INSTEAD OF triggers). */
675 if( pTab->pSelect==0 ){ 720 if( pTab->pSelect==0 ){
676 sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0); 721 sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
677 sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); 722 sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
678 if( count ){ 723 if( count ){
679 sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); 724 sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
680 } 725 }
726 if( iIdxNoSeek>=0 ){
727 sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
728 }
729 sqlite3VdbeChangeP5(v, eMode==ONEPASS_MULTI);
681 } 730 }
682 731
683 /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to 732 /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
684 ** handle rows (possibly in other tables) that refer via a foreign key 733 ** handle rows (possibly in other tables) that refer via a foreign key
685 ** to the row just deleted. */ 734 ** to the row just deleted. */
686 sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); 735 sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0);
687 736
688 /* Invoke AFTER DELETE trigger programs. */ 737 /* Invoke AFTER DELETE trigger programs. */
689 sqlite3CodeRowTrigger(pParse, pTrigger, 738 sqlite3CodeRowTrigger(pParse, pTrigger,
690 TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel 739 TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
(...skipping 22 matching lines...) Expand all
713 ** index is the 0-th index.) 762 ** index is the 0-th index.)
714 ** 763 **
715 ** 3. The "iDataCur" cursor must be already be positioned on the row 764 ** 3. The "iDataCur" cursor must be already be positioned on the row
716 ** that is to be deleted. 765 ** that is to be deleted.
717 */ 766 */
718 void sqlite3GenerateRowIndexDelete( 767 void sqlite3GenerateRowIndexDelete(
719 Parse *pParse, /* Parsing and code generating context */ 768 Parse *pParse, /* Parsing and code generating context */
720 Table *pTab, /* Table containing the row to be deleted */ 769 Table *pTab, /* Table containing the row to be deleted */
721 int iDataCur, /* Cursor of table holding data. */ 770 int iDataCur, /* Cursor of table holding data. */
722 int iIdxCur, /* First index cursor */ 771 int iIdxCur, /* First index cursor */
723 int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ 772 int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
773 int iIdxNoSeek /* Do not delete from this cursor */
724 ){ 774 ){
725 int i; /* Index loop counter */ 775 int i; /* Index loop counter */
726 int r1 = -1; /* Register holding an index key */ 776 int r1 = -1; /* Register holding an index key */
727 int iPartIdxLabel; /* Jump destination for skipping partial index entries */ 777 int iPartIdxLabel; /* Jump destination for skipping partial index entries */
728 Index *pIdx; /* Current index */ 778 Index *pIdx; /* Current index */
729 Index *pPrior = 0; /* Prior index */ 779 Index *pPrior = 0; /* Prior index */
730 Vdbe *v; /* The prepared statement under construction */ 780 Vdbe *v; /* The prepared statement under construction */
731 Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ 781 Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
732 782
733 v = pParse->pVdbe; 783 v = pParse->pVdbe;
734 pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); 784 pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
735 for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ 785 for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
736 assert( iIdxCur+i!=iDataCur || pPk==pIdx ); 786 assert( iIdxCur+i!=iDataCur || pPk==pIdx );
737 if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; 787 if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
738 if( pIdx==pPk ) continue; 788 if( pIdx==pPk ) continue;
789 if( iIdxCur+i==iIdxNoSeek ) continue;
739 VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); 790 VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
740 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, 791 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
741 &iPartIdxLabel, pPrior, r1); 792 &iPartIdxLabel, pPrior, r1);
742 sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, 793 sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
743 pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); 794 pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
744 sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); 795 sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
745 pPrior = pIdx; 796 pPrior = pIdx;
746 } 797 }
747 } 798 }
748 799
749 /* 800 /*
750 ** Generate code that will assemble an index key and stores it in register 801 ** Generate code that will assemble an index key and stores it in register
751 ** regOut. The key with be for index pIdx which is an index on pTab. 802 ** regOut. The key with be for index pIdx which is an index on pTab.
752 ** iCur is the index of a cursor open on the pTab table and pointing to 803 ** iCur is the index of a cursor open on the pTab table and pointing to
753 ** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then 804 ** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then
(...skipping 28 matching lines...) Expand all
782 Index *pIdx, /* The index for which to generate a key */ 833 Index *pIdx, /* The index for which to generate a key */
783 int iDataCur, /* Cursor number from which to take column data */ 834 int iDataCur, /* Cursor number from which to take column data */
784 int regOut, /* Put the new key into this register if not 0 */ 835 int regOut, /* Put the new key into this register if not 0 */
785 int prefixOnly, /* Compute only a unique prefix of the key */ 836 int prefixOnly, /* Compute only a unique prefix of the key */
786 int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */ 837 int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */
787 Index *pPrior, /* Previously generated index key */ 838 Index *pPrior, /* Previously generated index key */
788 int regPrior /* Register holding previous generated key */ 839 int regPrior /* Register holding previous generated key */
789 ){ 840 ){
790 Vdbe *v = pParse->pVdbe; 841 Vdbe *v = pParse->pVdbe;
791 int j; 842 int j;
792 Table *pTab = pIdx->pTable;
793 int regBase; 843 int regBase;
794 int nCol; 844 int nCol;
795 845
796 if( piPartIdxLabel ){ 846 if( piPartIdxLabel ){
797 if( pIdx->pPartIdxWhere ){ 847 if( pIdx->pPartIdxWhere ){
798 *piPartIdxLabel = sqlite3VdbeMakeLabel(v); 848 *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
799 pParse->iPartIdxTab = iDataCur; 849 pParse->iSelfTab = iDataCur;
800 sqlite3ExprCachePush(pParse); 850 sqlite3ExprCachePush(pParse);
801 sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 851 sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
802 SQLITE_JUMPIFNULL); 852 SQLITE_JUMPIFNULL);
803 }else{ 853 }else{
804 *piPartIdxLabel = 0; 854 *piPartIdxLabel = 0;
805 } 855 }
806 } 856 }
807 nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; 857 nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
808 regBase = sqlite3GetTempRange(pParse, nCol); 858 regBase = sqlite3GetTempRange(pParse, nCol);
809 if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; 859 if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
810 for(j=0; j<nCol; j++){ 860 for(j=0; j<nCol; j++){
811 if( pPrior && pPrior->aiColumn[j]==pIdx->aiColumn[j] ) continue; 861 if( pPrior
812 sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j], 862 && pPrior->aiColumn[j]==pIdx->aiColumn[j]
813 regBase+j); 863 && pPrior->aiColumn[j]!=XN_EXPR
864 ){
865 /* This column was already computed by the previous index */
866 continue;
867 }
868 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
814 /* If the column affinity is REAL but the number is an integer, then it 869 /* If the column affinity is REAL but the number is an integer, then it
815 ** might be stored in the table as an integer (using a compact 870 ** might be stored in the table as an integer (using a compact
816 ** representation) then converted to REAL by an OP_RealAffinity opcode. 871 ** representation) then converted to REAL by an OP_RealAffinity opcode.
817 ** But we are getting ready to store this value back into an index, where 872 ** But we are getting ready to store this value back into an index, where
818 ** it should be converted by to INTEGER again. So omit the OP_RealAffinity 873 ** it should be converted by to INTEGER again. So omit the OP_RealAffinity
819 ** opcode if it is present */ 874 ** opcode if it is present */
820 sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); 875 sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
821 } 876 }
822 if( regOut ){ 877 if( regOut ){
823 sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); 878 sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
824 } 879 }
825 sqlite3ReleaseTempRange(pParse, regBase, nCol); 880 sqlite3ReleaseTempRange(pParse, regBase, nCol);
826 return regBase; 881 return regBase;
827 } 882 }
828 883
829 /* 884 /*
830 ** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label 885 ** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label
831 ** because it was a partial index, then this routine should be called to 886 ** because it was a partial index, then this routine should be called to
832 ** resolve that label. 887 ** resolve that label.
833 */ 888 */
834 void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ 889 void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
835 if( iLabel ){ 890 if( iLabel ){
836 sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); 891 sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
837 sqlite3ExprCachePop(pParse); 892 sqlite3ExprCachePop(pParse);
838 } 893 }
839 } 894 }
OLDNEW
« no previous file with comments | « third_party/sqlite/src/src/dbstat.c ('k') | third_party/sqlite/src/src/expr.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698