Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Additional commands and another procedure name changes for clarity of presentation. No logic changes. (CVS 6323) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 91d9d51e03657e7492dd7b93e66c82b1 |
User & Date: | drh 2009-02-24 19:21:41 |
Context
2009-02-25
| ||
08:56 | Minor changes and coverge tests for "SELECT count(*)" optimization. (CVS 6324) check-in: a3695b98 user: danielk1977 tags: trunk | |
2009-02-24
| ||
19:21 | Additional commands and another procedure name changes for clarity of presentation. No logic changes. (CVS 6323) check-in: 91d9d51e user: drh tags: trunk | |
18:57 | Changes to comments and functions/procedure names for clarification. No changes to logic. (CVS 6322) check-in: b99c1815 user: drh tags: trunk | |
Changes
Changes to src/btree.c.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 .... 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 .... 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 .... 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 .... 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 .... 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 .... 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 .... 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 |
** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.569 2009/02/24 18:57:32 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" ................................................................................ } #endif /* ** Forward declaration */ static int checkReadLocks(Btree*, Pgno, BtCursor*, i64); #ifdef SQLITE_OMIT_SHARED_CACHE /* ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), ** and clearAllSharedCacheTableLocks() ** manipulate entries in the BtShared.pLock linked list used to store ................................................................................ assert( sqlite3BtreeHoldsMutex(p) ); assert( wrFlag==0 || wrFlag==1 ); if( wrFlag ){ assert( !pBt->readOnly ); if( NEVER(pBt->readOnly) ){ return SQLITE_READONLY; } if( checkReadLocks(p, iTable, 0, 0) ){ return SQLITE_LOCKED; } } if( pBt->pPage1==0 ){ rc = lockBtreeWithRetry(p); if( rc!=SQLITE_OK ){ ................................................................................ ** This routine checks all cursors that point to table pgnoRoot. ** If any of those cursors were opened with wrFlag==0 in a different ** database connection (a database connection that shares the pager ** cache with the current connection) and that other connection ** is not in the ReadUncommmitted state, then this routine returns ** SQLITE_LOCKED. ** ** As well as cursors with wrFlag==0, cursors with wrFlag==1 and ** isIncrblobHandle==1 are also considered 'read' cursors. Incremental ** blob cursors are used for both reading and writing. ** ** When pgnoRoot is the root page of an intkey table, this function is also ** responsible for invalidating incremental blob cursors when the table row ** on which they are opened is deleted or modified. Cursors are invalidated ** according to the following rules: ** ** 1) When BtreeClearTable() is called to completely delete the contents ................................................................................ ** to the integer row id of the B-Tree entry being modified. Unless ** pExclude is itself an incremental blob cursor, then all incremental ** blob cursors open on row iRow of the B-Tree are invalidated. ** ** 3) If both pExclude and iRow are set to zero, no incremental blob ** cursors are invalidated. */ static int checkReadLocks( Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude, i64 iRow ){ BtCursor *p; BtShared *pBt = pBtree->pBt; sqlite3 *db = pBtree->db; assert( sqlite3BtreeHoldsMutex(pBtree) ); for(p=pBt->pCursor; p; p=p->pNext){ if( p==pExclude ) continue; ................................................................................ unsigned char *oldCell; unsigned char *newCell = 0; assert( cursorHoldsMutex(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); assert( !pBt->readOnly ); assert( pCur->wrFlag ); if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur, nKey) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } /* Save the positions of any other cursors open on this table */ ................................................................................ if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } if( NEVER(pCur->aiIdx[pCur->iPage]>=pPage->nCell) ){ return SQLITE_ERROR; /* The cursor is not pointing to anything */ } assert( pCur->wrFlag ); if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur, pCur->info.nKey) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } /* Restore the current cursor position (a no-op if the cursor is not in ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors ** open on the same table. Then call sqlite3PagerWrite() on the page ** that the entry will be deleted from. ................................................................................ */ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); pBt->db = p->db; assert( p->inTrans==TRANS_WRITE ); if( (rc = checkReadLocks(p, iTable, 0, 1))!=SQLITE_OK ){ /* nothing to do */ }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){ /* nothing to do */ }else{ rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); ................................................................................ ** (c) the cursor points at a valid row of an intKey table. */ if( !pCsr->wrFlag ){ return SQLITE_READONLY; } assert( !pCsr->pBt->readOnly && pCsr->pBt->inTransaction==TRANS_WRITE ); if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } if( pCsr->eState==CURSOR_INVALID || !pCsr->apPage[pCsr->iPage]->intKey ){ return SQLITE_ERROR; } return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1); |
| | | | | | | | | | | | | > > | | |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 .... 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 .... 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 .... 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 .... 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 .... 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 .... 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 .... 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 |
** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.570 2009/02/24 19:21:41 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" ................................................................................ } #endif /* ** Forward declaration */ static int checkForReadConflicts(Btree*, Pgno, BtCursor*, i64); #ifdef SQLITE_OMIT_SHARED_CACHE /* ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), ** and clearAllSharedCacheTableLocks() ** manipulate entries in the BtShared.pLock linked list used to store ................................................................................ assert( sqlite3BtreeHoldsMutex(p) ); assert( wrFlag==0 || wrFlag==1 ); if( wrFlag ){ assert( !pBt->readOnly ); if( NEVER(pBt->readOnly) ){ return SQLITE_READONLY; } if( checkForReadConflicts(p, iTable, 0, 0) ){ return SQLITE_LOCKED; } } if( pBt->pPage1==0 ){ rc = lockBtreeWithRetry(p); if( rc!=SQLITE_OK ){ ................................................................................ ** This routine checks all cursors that point to table pgnoRoot. ** If any of those cursors were opened with wrFlag==0 in a different ** database connection (a database connection that shares the pager ** cache with the current connection) and that other connection ** is not in the ReadUncommmitted state, then this routine returns ** SQLITE_LOCKED. ** ** As well as cursors with wrFlag==0, cursors with ** isIncrblobHandle==1 are also considered 'read' cursors because ** incremental blob cursors are used for both reading and writing. ** ** When pgnoRoot is the root page of an intkey table, this function is also ** responsible for invalidating incremental blob cursors when the table row ** on which they are opened is deleted or modified. Cursors are invalidated ** according to the following rules: ** ** 1) When BtreeClearTable() is called to completely delete the contents ................................................................................ ** to the integer row id of the B-Tree entry being modified. Unless ** pExclude is itself an incremental blob cursor, then all incremental ** blob cursors open on row iRow of the B-Tree are invalidated. ** ** 3) If both pExclude and iRow are set to zero, no incremental blob ** cursors are invalidated. */ static int checkForReadConflicts( Btree *pBtree, /* The database file to check */ Pgno pgnoRoot, /* Look for read cursors on this btree */ BtCursor *pExclude, /* Ignore this cursor */ i64 iRow /* The rowid that might be changing */ ){ BtCursor *p; BtShared *pBt = pBtree->pBt; sqlite3 *db = pBtree->db; assert( sqlite3BtreeHoldsMutex(pBtree) ); for(p=pBt->pCursor; p; p=p->pNext){ if( p==pExclude ) continue; ................................................................................ unsigned char *oldCell; unsigned char *newCell = 0; assert( cursorHoldsMutex(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); assert( !pBt->readOnly ); assert( pCur->wrFlag ); if( checkForReadConflicts(pCur->pBtree, pCur->pgnoRoot, pCur, nKey) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } /* Save the positions of any other cursors open on this table */ ................................................................................ if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } if( NEVER(pCur->aiIdx[pCur->iPage]>=pPage->nCell) ){ return SQLITE_ERROR; /* The cursor is not pointing to anything */ } assert( pCur->wrFlag ); if( checkForReadConflicts(pCur->pBtree, pCur->pgnoRoot, pCur, pCur->info.nKey) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } /* Restore the current cursor position (a no-op if the cursor is not in ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors ** open on the same table. Then call sqlite3PagerWrite() on the page ** that the entry will be deleted from. ................................................................................ */ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); pBt->db = p->db; assert( p->inTrans==TRANS_WRITE ); if( (rc = checkForReadConflicts(p, iTable, 0, 1))!=SQLITE_OK ){ /* nothing to do */ }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){ /* nothing to do */ }else{ rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); ................................................................................ ** (c) the cursor points at a valid row of an intKey table. */ if( !pCsr->wrFlag ){ return SQLITE_READONLY; } assert( !pCsr->pBt->readOnly && pCsr->pBt->inTransaction==TRANS_WRITE ); if( checkForReadConflicts(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } if( pCsr->eState==CURSOR_INVALID || !pCsr->apPage[pCsr->iPage]->intKey ){ return SQLITE_ERROR; } return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1); |