From: danielk1977 Date: Fri, 4 Jan 2008 13:24:28 +0000 (+0000) Subject: Modify the code generated for a DELETE to use registers instead of the vdbe stack... X-Git-Tag: version-3.6.10~1502 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=96cb76fc7a99b9738e31a9a8f3efe47a6de2646d;p=thirdparty%2Fsqlite.git Modify the code generated for a DELETE to use registers instead of the vdbe stack. (CVS 4675) FossilOrigin-Name: 173f281334d340290e1978abea5d1ea804141910 --- diff --git a/manifest b/manifest index a2d4c83915..0756bd2efd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sOP_MemSet,\sfor\ssetting\sa\smemory\scell\sto\sa\sstring\svalue.\s(CVS\s4674) -D 2008-01-04T11:01:04 +C Modify\sthe\scode\sgenerated\sfor\sa\sDELETE\sto\suse\sregisters\sinstead\sof\sthe\svdbe\sstack.\s(CVS\s4675) +D 2008-01-04T13:24:29 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -90,13 +90,13 @@ F src/build.c b7874b45716fa56e6fd1291ffb0b97a55e470728 F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6 -F src/delete.c b5f77d88cc35367cfafc2e4edcf9327d19428615 +F src/delete.c 36193a3a10e636d3ee4fe1fdfac57982d5471623 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/expr.c e60ee4f48194469bf7b101fb7a14e56abea3daa4 F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 -F src/insert.c ecffad8ecc5dc69d6dc05d8dc136f872864af84e +F src/insert.c 7a8c825953ab6435fef1823e83cbe627860dd6d5 F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2 F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 @@ -136,7 +136,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb -F src/sqliteInt.h 2cae3a7556208c68987752b6d8f9212a8a2327a7 +F src/sqliteInt.h df036b69e3c5c6a87354a10668f165b22994f264 F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4 F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf @@ -168,7 +168,7 @@ F src/update.c a68e11e766376bf0fbec93d70c9389c4c502dd55 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736 F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0 -F src/vdbe.c 09caf5753f176603ad4965d92c7ff32786c1cc2b +F src/vdbe.c 55e1a0541f87e2c73fa4c4d73649c3d6cd39b9a3 F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5 F src/vdbeInt.h 869d0f550354c1364dde1d3611d770bd1c767505 F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c @@ -603,7 +603,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 61bfb77c4267b99ac8a8ef49355bcbc395a1a37b -R edd05b654f5ed425ebc77621c6cc523e +P 8bb9f970dd71cbf19e45774fc822aa1efebc1724 +R 991771337c0268b312b29969927e9c60 U danielk1977 -Z 55c192a0d96eb126863103cbe98ffaaa +Z 58a58785d108e95cb589bb5d4ad7f5cb diff --git a/manifest.uuid b/manifest.uuid index ffa3958f0f..24b4471c49 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bb9f970dd71cbf19e45774fc822aa1efebc1724 \ No newline at end of file +173f281334d340290e1978abea5d1ea804141910 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index a2c4da292c..88a6ef58a8 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** 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.144 2008/01/03 18:03:09 drh Exp $ +** $Id: delete.c,v 1.145 2008/01/04 13:24:29 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -299,6 +299,8 @@ void sqlite3DeleteFrom( ** the table and pick which records to delete. */ else{ + int iRowid = ++pParse->nMem; /* Used for storing value read from fifo */ + /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); @@ -342,44 +344,41 @@ void sqlite3DeleteFrom( if( triggers_exist ){ sqlite3VdbeResolveLabel(v, addr); } - addr = sqlite3VdbeAddOp2(v, OP_FifoRead, 0, end); + addr = sqlite3VdbeAddOp2(v, OP_FifoRead, iRowid, end); sqlite3VdbeAddOp1(v, OP_StackDepth, -1); if( triggers_exist ){ - int mem1 = ++pParse->nMem; - if( !isView ){ - sqlite3VdbeAddOp1(v, OP_MemStore, mem1); - } - sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr); - sqlite3VdbeAddOp1(v, OP_Rowid, iCur); + int iData = ++pParse->nMem; /* For storing row data of OLD table */ + + /* If the record is no longer present in the table, jump to the + ** next iteration of the loop through the contents of the fifo. + */ + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); + + /* Populate the OLD.* pseudo-table */ if( old_col_mask ){ - sqlite3VdbeAddOp1(v, OP_RowData, iCur); + sqlite3VdbeAddOp3(v, OP_RowData, iCur, 0, iData); }else{ - sqlite3VdbeAddOp0(v, OP_Null); + sqlite3VdbeAddOp2(v, OP_MemNull, 0, iData); } - sqlite3CodeInsert(pParse, oldIdx, 0); + sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid); /* Jump back and run the BEFORE triggers */ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); sqlite3VdbeJumpHere(v, iEndBeforeTrigger); - - if( !isView ){ - sqlite3VdbeAddOp1(v, OP_MemLoad, mem1); - } } if( !isView ){ /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ - int iReg = sqlite3StackToReg(pParse, 1); + const char *pVtab = (const char *)pTab->pVtab; pParse->pVirtualLock = pTab; - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iReg, - (const char*)pTab->pVtab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVtab, P4_VTAB); }else #endif { - sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); + sqlite3GenerateRowDelete(db, v, pTab, iCur, iRowid, pParse->nested==0); } } @@ -436,8 +435,8 @@ delete_from_cleanup: ** 2. Read/write cursors for all indices of pTab must be open as ** cursor number base+i for the i-th index. ** -** 3. The record number of the row to be deleted must be on the top -** of the stack. +** 3. The record number of the row to be deleted must be stored in +** memory cell iRowid. ** ** This routine pops the top of the stack to remove the record number ** and then generates code to remove both the table record and all index @@ -448,10 +447,11 @@ void sqlite3GenerateRowDelete( Vdbe *v, /* Generate code into this VDBE */ Table *pTab, /* Table containing the row to be deleted */ int iCur, /* Cursor number for the table */ + int iRowid, /* Memory cell that contains the rowid to delete */ int count /* Increment the row change counter */ ){ int addr; - addr = sqlite3VdbeAddOp1(v, OP_NotExists, iCur); + addr = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowid); sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0); sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); if( count ){ diff --git a/src/insert.c b/src/insert.c index de74736b71..710175bc06 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.208 2008/01/03 23:44:53 drh Exp $ +** $Id: insert.c,v 1.209 2008/01/04 13:24:29 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -1176,7 +1176,8 @@ void sqlite3GenerateConstraintChecks( break; } case OE_Replace: { - sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0); + int iRowid = sqlite3StackToReg(pParse, 1); + sqlite3GenerateRowDelete(pParse->db, v, pTab, base, iRowid, 0); if( isUpdate ){ sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1); sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3e75f1f53a..a59aeb85ad 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.636 2008/01/03 23:44:53 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.637 2008/01/04 13:24:29 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1768,7 +1768,7 @@ int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3IsRowid(const char*); -void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int); +void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int, int); void sqlite3GenerateRowIndexDelete(Vdbe*, Table*, int, char*); void sqlite3GenerateIndexKey(Vdbe*, Index*, int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int); diff --git a/src/vdbe.c b/src/vdbe.c index 736d7819a9..9c258f04d5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** 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.674 2008/01/04 11:01:04 danielk1977 Exp $ +** $Id: vdbe.c,v 1.675 2008/01/04 13:24:29 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -3344,12 +3344,14 @@ case OP_IsUnique: { /* no-push */ break; } -/* Opcode: NotExists P1 P2 * +/* Opcode: NotExists P1 P2 P3 ** -** Use the top of the stack as a integer key. If a record with that key -** does not exist in table of P1, then jump to P2. If the record -** does exist, then fall thru. The cursor is left pointing to the -** record if it exists. The integer key is popped from the stack. +** Use the top of the stack as a integer key. Or, if P3 is non-zero, +** use the contents of memory cell P3 as an integer key. If a record +** with that key does not exist in table of P1, then jump to P2. +** If the record does exist, then fall thru. The cursor is left +** pointing to the record if it exists. The integer key is popped +** from the stack (unless it was read from a memory cell). ** ** The difference between this operation and NotFound is that this ** operation assumes the key is an integer and that P1 is a table whereas @@ -3362,17 +3364,24 @@ case OP_NotExists: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; - assert( pTos>=p->aStack ); + Mem *pKey; + if( pOp->p3 ){ + assert( pOp->p3<=p->nMem ); + pKey = &p->aMem[pOp->p3]; + }else{ + pKey = pTos; + assert( pTos>=p->aStack ); + } assert( i>=0 && inCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res; u64 iKey; - assert( pTos->flags & MEM_Int ); + assert( pKey->flags & MEM_Int ); assert( p->apCsr[i]->isTable ); - iKey = intToKey(pTos->u.i); + iKey = intToKey(pKey->u.i); rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, 0,&res); - pC->lastRowid = pTos->u.i; + pC->lastRowid = pKey->u.i; pC->rowidIsValid = res==0; pC->nullRow = 0; pC->cacheStatus = CACHE_STALE; @@ -3386,8 +3395,10 @@ case OP_NotExists: { /* no-push */ pC->rowidIsValid = 0; } } - Release(pTos); - pTos--; + if( pOp->p3==0 ){ + Release(pTos); + pTos--; + } break; } @@ -3727,20 +3738,24 @@ case OP_ResetCount: { /* no-push */ break; } -/* Opcode: RowData P1 * * +/* Opcode: RowData P1 * P3 ** -** Push onto the stack the complete row data for cursor P1. -** There is no interpretation of the data. It is just copied -** onto the stack exactly as it is found in the database file. +** Push onto the stack the complete row data for cursor P1. Or if P3 +** is a positive non-zero integer register number, then the value +** is written into that register. There is no interpretation of the data. +** It is just copied onto the stack or into the memory cell exactly as +** it is found in the database file. ** -** If the cursor is not pointing to a valid row, a NULL is pushed -** onto the stack. +** If the cursor is not pointing to a valid row, a NULL value is +** pushed/inserted instead. */ -/* Opcode: RowKey P1 * * +/* Opcode: RowKey P1 * P3 ** -** Push onto the stack the complete row key for cursor P1. -** There is no interpretation of the key. It is just copied -** onto the stack exactly as it is found in the database file. +** Push onto the stack the complete row key for cursor P1. Or if P3 +** is a positive non-zero integer register number, then the value +** is written into that register. There is no interpretation of the data. +** It is just copied onto the stack or into the memory cell exactly as +** it is found in the database file. ** ** If the cursor is not pointing to a valid row, a NULL is pushed ** onto the stack. @@ -3750,22 +3765,27 @@ case OP_RowData: { int i = pOp->p1; Cursor *pC; u32 n; + Mem *pOut; /* Note that RowKey and RowData are really exactly the same instruction */ - pTos++; + if( pOp->p3 ){ + pOut = &p->aMem[pOp->p3]; + }else{ + pOut = ++pTos; + } assert( i>=0 && inCursor ); pC = p->apCsr[i]; assert( pC->isTable || pOp->opcode==OP_RowKey ); assert( pC->isIndex || pOp->opcode==OP_RowData ); assert( pC!=0 ); if( pC->nullRow ){ - pTos->flags = MEM_Null; + pOut->flags = MEM_Null; }else if( pC->pCursor!=0 ){ BtCursor *pCrsr = pC->pCursor; rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; if( pC->nullRow ){ - pTos->flags = MEM_Null; + pOut->flags = MEM_Null; break; }else if( pC->isIndex ){ i64 n64; @@ -3781,31 +3801,31 @@ case OP_RowData: { if( n>SQLITE_MAX_LENGTH ){ goto too_big; } - pTos->n = n; + pOut->n = n; if( n<=NBFS ){ - pTos->flags = MEM_Blob | MEM_Short; - pTos->z = pTos->zShort; + pOut->flags = MEM_Blob | MEM_Short; + pOut->z = pOut->zShort; }else{ char *z = sqlite3_malloc( n ); if( z==0 ) goto no_mem; - pTos->flags = MEM_Blob | MEM_Dyn; - pTos->xDel = 0; - pTos->z = z; + pOut->flags = MEM_Blob | MEM_Dyn; + pOut->xDel = 0; + pOut->z = z; } if( pC->isIndex ){ - rc = sqlite3BtreeKey(pCrsr, 0, n, pTos->z); + rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); }else{ - rc = sqlite3BtreeData(pCrsr, 0, n, pTos->z); + rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); } }else if( pC->pseudoTable ){ - pTos->n = pC->nData; + pOut->n = pC->nData; assert( pC->nData<=SQLITE_MAX_LENGTH ); - pTos->z = pC->pData; - pTos->flags = MEM_Blob|MEM_Ephem; + pOut->z = pC->pData; + pOut->flags = MEM_Blob|MEM_Ephem; }else{ - pTos->flags = MEM_Null; + pOut->flags = MEM_Null; } - pTos->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ + pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ break; } @@ -4505,8 +4525,7 @@ case OP_IntegrityCk: { /* Opcode: FifoWrite * * * ** -** Write the integer on the top of the stack -** into the Fifo. +** Write the integer on the top of the stack into the Fifo. */ case OP_FifoWrite: { /* no-push */ assert( pTos>=p->aStack ); @@ -4519,11 +4538,14 @@ case OP_FifoWrite: { /* no-push */ break; } -/* Opcode: FifoRead * P2 * +/* Opcode: FifoRead P1 P2 * ** -** Attempt to read a single integer from the Fifo -** and push it onto the stack. If the Fifo is empty -** push nothing but instead jump to 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; @@ -4531,9 +4553,13 @@ case OP_FifoRead: { if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){ pc = pOp->p2 - 1; }else{ - pTos++; - pTos->u.i = v; - pTos->flags = MEM_Int; + Mem *pOut; + if( pOp->p1 ){ + pOut = &p->aMem[pOp->p1]; + }else{ + pOut = ++pTos; + } + sqlite3VdbeMemSetInt64(pOut, v); } break; }