Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Modify FifoRead and FifoWrite to work exclusively with memory cells. (CVS 4676) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2c913908a47e7ace7d964067e3566d23 |
User & Date: | danielk1977 2008-01-04 13:57:26.000 |
Context
2008-01-04
| ||
16:50 | Replace the NOPUSH_MASKs with a bit-vector mechanism that can contain several different properties about each opcode. (CVS 4677) (check-in: 042dcb9621 user: drh tags: trunk) | |
13:57 | Modify FifoRead and FifoWrite to work exclusively with memory cells. (CVS 4676) (check-in: 2c913908a4 user: danielk1977 tags: trunk) | |
13:24 | Modify the code generated for a DELETE to use registers instead of the vdbe stack. (CVS 4675) (check-in: 173f281334 user: danielk1977 tags: trunk) | |
Changes
Changes to src/delete.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.146 2008/01/04 13:57:26 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
228 229 230 231 232 233 234 235 236 237 238 | if( v==0 ){ goto delete_from_cleanup; } if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, triggers_exist, iDb); if( triggers_exist ){ int iGoto = sqlite3VdbeAddOp0(v, OP_Goto); addr = sqlite3VdbeMakeLabel(v); iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v); (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, | > > < | > < | > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | if( v==0 ){ goto delete_from_cleanup; } if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, triggers_exist, iDb); if( triggers_exist ){ int orconf = ((pParse->trigStack)?pParse->trigStack->orconf:OE_Default); int iGoto = sqlite3VdbeAddOp0(v, OP_Goto); addr = sqlite3VdbeMakeLabel(v); iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v); (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0); iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto); iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v); (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0); iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, iGoto); } /* If we are trying to delete from a view, realize that view into ** a ephemeral table. */ if( isView ){ |
︙ | ︙ | |||
295 296 297 298 299 300 301 | } } } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ else{ | | | | | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | } } } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ else{ int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the rowid of every item to be deleted. */ sqlite3VdbeAddOp2(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, iRowid); sqlite3VdbeAddOp1(v, OP_FifoWrite, iRowid); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp2(v, OP_MemIncr, 1, memCnt); } /* End the database scan loop. */ sqlite3WhereEnd(pWInfo); |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.156 2008/01/04 13:57:26 danielk1977 Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 112 113 114 115 | Expr *pRowidExpr = 0; /* Expression defining the new record number */ int openAll = 0; /* True if all indices need to be opened */ AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ int iDb; /* Database containing the table being updated */ int memCnt = 0; /* Memory cell used for counting rows changed */ int mem1; /* Memory address storing the rowid for next row to update */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* Trying to update a view */ int triggers_exist = 0; /* True if any row triggers exist */ #endif int iBeginAfterTrigger; /* Address of after trigger program */ int iEndAfterTrigger; /* Exit of after trigger program */ | > | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | Expr *pRowidExpr = 0; /* Expression defining the new record number */ int openAll = 0; /* True if all indices need to be opened */ AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ int iDb; /* Database containing the table being updated */ int memCnt = 0; /* Memory cell used for counting rows changed */ int mem1; /* Memory address storing the rowid for next row to update */ int iRowid; /* Memory address storing rowids */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* Trying to update a view */ int triggers_exist = 0; /* True if any row triggers exist */ #endif int iBeginAfterTrigger; /* Address of after trigger program */ int iEndAfterTrigger; /* Exit of after trigger program */ |
︙ | ︙ | |||
339 340 341 342 343 344 345 | /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto update_cleanup; /* Remember the rowid of every item to be updated. */ | > | | | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto update_cleanup; /* Remember the rowid of every item to be updated. */ iRowid = ++pParse->nMem; sqlite3VdbeAddOp2(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, iRowid); sqlite3VdbeAddOp2(v, OP_FifoWrite, iRowid, 0); /* End the database scan loop. */ sqlite3WhereEnd(pWInfo); /* Initialize the count of updated rows */ |
︙ | ︙ | |||
380 381 382 383 384 385 386 | if( openAll || aIdxUsed[i] ){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb, (char*)pKey, P4_KEYINFO_HANDOFF); assert( pParse->nTab>iCur+i+1 ); } } | < | < | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | if( openAll || aIdxUsed[i] ){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb, (char*)pKey, P4_KEYINFO_HANDOFF); assert( pParse->nTab>iCur+i+1 ); } } } /* Jump back to this point if a trigger encounters an IGNORE constraint. */ if( triggers_exist ){ sqlite3VdbeResolveLabel(v, addr); } /* Top of the update loop */ addr = sqlite3VdbeAddOp2(v, OP_FifoRead, iRowid, 0); sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0); if( triggers_exist ){ /* Make cursor iCur point to the record that is being updated. */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); /* Generate the OLD table */ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0); if( !old_col_mask ){ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); }else{ |
︙ | ︙ | |||
441 442 443 444 445 446 447 | sqlite3TableAffinityStr(v, pTab); } if( pParse->nErr ) goto update_cleanup; sqlite3CodeInsert(pParse, newIdx, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); sqlite3VdbeJumpHere(v, iEndBeforeTrigger); | < < < < | | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | sqlite3TableAffinityStr(v, pTab); } if( pParse->nErr ) goto update_cleanup; sqlite3CodeInsert(pParse, newIdx, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); sqlite3VdbeJumpHere(v, iEndBeforeTrigger); } if( !isView && !IsVirtual(pTab) ){ /* Loop over every record that needs updating. We have to load ** the old data for each record to be updated because some columns ** might not change and we will need to copy the old value. ** Also, the old data is needed to delete the old index entries. ** So make the cursor point at the old record. */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); sqlite3VdbeAddOp2(v, OP_MemLoad, iRowid, 0); /* If the record number will change, push the record number as it ** will be after the update. (The old record number is currently ** on top of the stack.) */ if( chngRowid ){ sqlite3ExprCode(pParse, pRowidExpr, 0); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.676 2008/01/04 13:57:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
4519 4520 4521 4522 4523 4524 4525 | pTos->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pTos, encoding); sqlite3_free(aRoot); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ | | | > | | | < < | | < < < < | 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 | pTos->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pTos, encoding); sqlite3_free(aRoot); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: FifoWrite P1 * * ** ** Write the integer from memory cell P1 into the Fifo. */ case OP_FifoWrite: { /* no-push */ Mem *pReg = &p->aMem[pOp->p1]; assert( pOp->p1>0 && pOp->p1<=p->nMem ); sqlite3VdbeMemIntegerify(pReg); if( sqlite3VdbeFifoPush(&p->sFifo, pReg->u.i)==SQLITE_NOMEM ){ goto no_mem; } break; } /* Opcode: FifoRead P1 P2 * ** ** Attempt to read a single integer from the Fifo. If P1 is zero, ** push the result onto the stack. Otherwise, store the read integer ** in register P1. ** ** If the Fifo is empty do not push an entry onto the stack or set ** a memory register but instead jump to P2. */ case OP_FifoRead: { i64 v; CHECK_FOR_INTERRUPT; if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){ pc = pOp->p2 - 1; }else{ Mem *pOut = &p->aMem[pOp->p1]; assert( pOp->p1>0 && pOp->p1<=p->nMem ); sqlite3VdbeMemSetInt64(pOut, v); } break; } #ifndef SQLITE_OMIT_TRIGGER /* Opcode: ContextPush * * * |
︙ | ︙ |