diff options
author | danielk1977 <danielk1977@noemail.net> | 2008-10-27 13:59:33 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2008-10-27 13:59:33 +0000 |
commit | c7af484b4b0a4f4db7e6f71b7e65cfde012e374e (patch) | |
tree | 572f74e759cd856f68f134cdc5e04a61428d4fe9 /src | |
parent | 9a02fb444c7c38360f4dafc91433ddeb13381a6f (diff) | |
download | sqlite-c7af484b4b0a4f4db7e6f71b7e65cfde012e374e.tar.gz sqlite-c7af484b4b0a4f4db7e6f71b7e65cfde012e374e.zip |
Make sqlite3_count_changes() and total_changes() work with "DELETE FROM <table-name>". (CVS 5844)
FossilOrigin-Name: e68e4282adb9003aa297d033aeb5d9cadee215cd
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 22 | ||||
-rw-r--r-- | src/btree.h | 4 | ||||
-rw-r--r-- | src/delete.c | 16 | ||||
-rw-r--r-- | src/test3.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 21 |
5 files changed, 40 insertions, 27 deletions
diff --git a/src/btree.c b/src/btree.c index 538a706d6..d94d9857a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.525 2008/10/08 17:58:49 danielk1977 Exp $ +** $Id: btree.c,v 1.526 2008/10/27 13:59:34 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -6187,7 +6187,8 @@ static int clearDatabasePage( BtShared *pBt, /* The BTree that contains the table */ Pgno pgno, /* Page number to clear */ MemPage *pParent, /* Parent page. NULL for the root */ - int freePageFlag /* Deallocate page if true */ + int freePageFlag, /* Deallocate page if true */ + int *pnChange ){ MemPage *pPage = 0; int rc; @@ -6204,15 +6205,18 @@ static int clearDatabasePage( for(i=0; i<pPage->nCell; i++){ pCell = findCell(pPage, i); if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(pCell), pPage, 1); + rc = clearDatabasePage(pBt, get4byte(pCell), pPage, 1, pnChange); if( rc ) goto cleardatabasepage_out; } rc = clearCell(pPage, pCell); if( rc ) goto cleardatabasepage_out; } if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage, 1); + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage, 1, pnChange); if( rc ) goto cleardatabasepage_out; + }else if( pnChange ){ + assert( pPage->intKey ); + *pnChange += pPage->nCell; } if( freePageFlag ){ rc = freePage(pPage); @@ -6233,8 +6237,12 @@ cleardatabasepage_out: ** This routine will fail with SQLITE_LOCKED if there are any open ** read cursors on the table. Open write cursors are moved to the ** root of the table. +** +** If pnChange is not NULL, then table iTable must be an intkey table. The +** integer value pointed to by pnChange is incremented by the number of +** entries in the table. */ -int sqlite3BtreeClearTable(Btree *p, int iTable){ +int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); @@ -6246,7 +6254,7 @@ int sqlite3BtreeClearTable(Btree *p, int iTable){ }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){ /* nothing to do */ }else{ - rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0); + rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0, pnChange); } sqlite3BtreeLeave(p); return rc; @@ -6294,7 +6302,7 @@ static int btreeDropTable(Btree *p, int iTable, int *piMoved){ rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0); if( rc ) return rc; - rc = sqlite3BtreeClearTable(p, iTable); + rc = sqlite3BtreeClearTable(p, iTable, 0); if( rc ){ releasePage(pPage); return rc; diff --git a/src/btree.h b/src/btree.h index 3f8c4ea4b..ba1673086 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.104 2008/10/08 17:58:49 danielk1977 Exp $ +** @(#) $Id: btree.h,v 1.105 2008/10/27 13:59:34 danielk1977 Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -117,7 +117,7 @@ int sqlite3BtreeIncrVacuum(Btree *); #define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */ int sqlite3BtreeDropTable(Btree*, int, int*); -int sqlite3BtreeClearTable(Btree*, int); +int sqlite3BtreeClearTable(Btree*, int, int*); int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); void sqlite3BtreeTripAllCursors(Btree*, int); diff --git a/src/delete.c b/src/delete.c index ef036cba9..382f1a67f 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.183 2008/10/27 08:24:38 danielk1977 Exp $ +** $Id: delete.c,v 1.184 2008/10/27 13:59:34 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -233,7 +233,7 @@ void sqlite3DeleteFrom( int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ NameContext sNC; /* Name context to resolve expressions in */ int iDb; /* Database number */ - int memCnt = 0; /* Memory cell used for change counting */ + int memCnt = -1; /* Memory cell used for change counting */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ @@ -372,17 +372,7 @@ void sqlite3DeleteFrom( */ if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){ assert( !isView ); - if( db->flags & SQLITE_CountRows ){ - /* If counting rows deleted, just count the total number of - ** entries in the table. */ - int addr2; - sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeAddOp2(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2); - addr2 = sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); - sqlite3VdbeAddOp2(v, OP_Next, iCur, addr2); - sqlite3VdbeAddOp1(v, OP_Close, iCur); - } - sqlite3VdbeAddOp2(v, OP_Clear, pTab->tnum, iDb); + sqlite3VdbeAddOp3(v, OP_Clear, pTab->tnum, iDb, memCnt); if( !pParse->nested ){ sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); } diff --git a/src/test3.c b/src/test3.c index 4b75690ff..0d915f3cb 100644 --- a/src/test3.c +++ b/src/test3.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.101 2008/08/13 19:11:48 drh Exp $ +** $Id: test3.c,v 1.102 2008/10/27 13:59:34 danielk1977 Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" @@ -389,7 +389,7 @@ static int btree_clear_table( pBt = sqlite3TestTextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; sqlite3BtreeEnter(pBt); - rc = sqlite3BtreeClearTable(pBt, iTable); + rc = sqlite3BtreeClearTable(pBt, iTable, 0); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); diff --git a/src/vdbe.c b/src/vdbe.c index 6ee22c1b6..a4a62b8bd 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.782 2008/10/08 17:58:49 danielk1977 Exp $ +** $Id: vdbe.c,v 1.783 2008/10/27 13:59:34 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -4042,7 +4042,7 @@ case OP_Destroy: { /* out2-prerelease */ break; } -/* Opcode: Clear P1 P2 * +/* Opcode: Clear P1 P2 P3 ** ** Delete all contents of the database table or index whose root page ** in the database file is given by P1. But, unlike Destroy, do not @@ -4052,11 +4052,26 @@ case OP_Destroy: { /* out2-prerelease */ ** P2==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** +** If the P3 value is non-zero, then the table refered to must be an +** intkey table (an SQL table, not an index). In this case the row change +** count is incremented by the number of rows in the table being cleared. +** If P3 is greater than zero, then the value stored in register P3 is +** also incremented by the number of rows in the table being cleared. +** ** See also: Destroy */ case OP_Clear: { + int nChange = 0; assert( (p->btreeMask & (1<<pOp->p2))!=0 ); - rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); + rc = sqlite3BtreeClearTable( + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) + ); + if( pOp->p3 ){ + p->nChange += nChange; + if( pOp->p3>0 ){ + p->aMem[pOp->p3].u.i += nChange; + } + } break; } |