Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Changes to make corruption errors easier to track down. (CVS 2709) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c07330000b9427a77f412918078beffa |
User & Date: | drh 2005-09-17 15:20:27.000 |
Context
2005-09-17
| ||
16:36 | Fix a problem with the lock_status pragma and the UTF-16 encoding. (CVS 2710) (check-in: 1a737b457c user: drh tags: trunk) | |
15:20 | Changes to make corruption errors easier to track down. (CVS 2709) (check-in: c07330000b user: drh tags: trunk) | |
15:17 | Update the webpage description of 3.2.6 changes to talk about ticket #1432. (CVS 2708) (check-in: 0e23c28b25 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** 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.269 2005/09/17 15:20:27 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
490 491 492 493 494 495 496 | u8 *pPtrmap; /* The pointer map page */ Pgno iPtrmap; /* The pointer map page number */ int offset; /* Offset in pointer map page */ int rc; assert( pBt->autoVacuum ); if( key==0 ){ | | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | u8 *pPtrmap; /* The pointer map page */ Pgno iPtrmap; /* The pointer map page number */ int offset; /* Offset in pointer map page */ int rc; assert( pBt->autoVacuum ); if( key==0 ){ return SQLITE_CORRUPT_BKPT; } iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key); rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); if( rc!=SQLITE_OK ){ return rc; } offset = PTRMAP_PTROFFSET(pBt->usableSize, key); |
︙ | ︙ | |||
536 537 538 539 540 541 542 | } offset = PTRMAP_PTROFFSET(pBt->usableSize, key); if( pEType ) *pEType = pPtrmap[offset]; if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); sqlite3pager_unref(pPtrmap); | | | 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 | } offset = PTRMAP_PTROFFSET(pBt->usableSize, key); if( pEType ) *pEType = pPtrmap[offset]; if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); sqlite3pager_unref(pPtrmap); if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT; return SQLITE_OK; } #endif /* SQLITE_OMIT_AUTOVACUUM */ /* ** Given a btree page and a cell index (0 means the first cell on |
︙ | ︙ | |||
1026 1027 1028 1029 1030 1031 1032 | pBt = pPage->pBt; assert( pBt!=0 ); assert( pParent==0 || pParent->pBt==pBt ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] ); if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ /* The parent page should never change unless the file is corrupt */ | | | | | | | | 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | pBt = pPage->pBt; assert( pBt!=0 ); assert( pParent==0 || pParent->pBt==pBt ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] ); if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ /* The parent page should never change unless the file is corrupt */ return SQLITE_CORRUPT_BKPT; } if( pPage->isInit ) return SQLITE_OK; if( pPage->pParent==0 && pParent!=0 ){ pPage->pParent = pParent; sqlite3pager_ref(pParent->aData); } hdr = pPage->hdrOffset; data = pPage->aData; decodeFlags(pPage, data[hdr]); pPage->nOverflow = 0; pPage->idxShift = 0; usableSize = pBt->usableSize; pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; top = get2byte(&data[hdr+5]); pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ /* To many cells for a single page. The page must be corrupt */ return SQLITE_CORRUPT_BKPT; } if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){ /* All pages must have at least one cell, except for root pages */ return SQLITE_CORRUPT_BKPT; } /* Compute the total free space on the page */ pc = get2byte(&data[hdr+1]); nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell); while( pc>0 ){ int next, size; if( pc>usableSize-4 ){ /* Free block is off the page */ return SQLITE_CORRUPT_BKPT; } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); if( next>0 && next<=pc+size+3 ){ /* Free blocks must be in accending order */ return SQLITE_CORRUPT_BKPT; } nFree += size; pc = next; } pPage->nFree = nFree; if( nFree>=usableSize ){ /* Free space cannot exceed total page size */ return SQLITE_CORRUPT_BKPT; } pPage->isInit = 1; pageIntegrity(pPage); return SQLITE_OK; } |
︙ | ︙ | |||
1142 1143 1144 1145 1146 1147 1148 | Btree *pBt, /* The database file */ Pgno pgno, /* Number of the page to get */ MemPage **ppPage, /* Write the page pointer here */ MemPage *pParent /* Parent of the page */ ){ int rc; if( pgno==0 ){ | | | 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | Btree *pBt, /* The database file */ Pgno pgno, /* Number of the page to get */ MemPage **ppPage, /* Write the page pointer here */ MemPage *pParent /* Parent of the page */ ){ int rc; if( pgno==0 ){ return SQLITE_CORRUPT_BKPT; } rc = getPage(pBt, pgno, ppPage); if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){ rc = initPage(*ppPage, pParent); } return rc; } |
︙ | ︙ | |||
1710 1711 1712 1713 1714 1715 1716 | ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next ** overflow page in the list. */ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ | | | 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 | ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next ** overflow page in the list. */ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ return SQLITE_CORRUPT_BKPT; } put4byte(pPage->aData, iTo); }else{ int isInitOrig = pPage->isInit; int i; int nCell; |
︙ | ︙ | |||
1743 1744 1745 1746 1747 1748 1749 | } } } if( i==nCell ){ if( eType!=PTRMAP_BTREE || get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ | | | 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | } } } if( i==nCell ){ if( eType!=PTRMAP_BTREE || get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ return SQLITE_CORRUPT_BKPT; } put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); } pPage->isInit = isInitOrig; } return SQLITE_OK; |
︙ | ︙ | |||
1856 1857 1858 1859 1860 1861 1862 | #ifndef NDEBUG int nRef = *sqlite3pager_stats(pPager); #endif assert( pBt->autoVacuum ); if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){ | | | 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 | #ifndef NDEBUG int nRef = *sqlite3pager_stats(pPager); #endif assert( pBt->autoVacuum ); if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){ return SQLITE_CORRUPT_BKPT; } /* Figure out how many free-pages are in the database. If there are no ** free pages, then auto-vacuum is a no-op. */ nFreeList = get4byte(&pBt->pPage1->aData[36]); if( nFreeList==0 ){ |
︙ | ︙ | |||
1894 1895 1896 1897 1898 1899 1900 | if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){ continue; } rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage); if( rc!=SQLITE_OK ) goto autovacuum_out; if( eType==PTRMAP_ROOTPAGE ){ | | | 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 | if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){ continue; } rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage); if( rc!=SQLITE_OK ) goto autovacuum_out; if( eType==PTRMAP_ROOTPAGE ){ rc = SQLITE_CORRUPT_BKPT; goto autovacuum_out; } /* If iDbPage is free, do not swap it. */ if( eType==PTRMAP_FREEPAGE ){ continue; } |
︙ | ︙ | |||
2410 2411 2412 2413 2414 2415 2416 | offset -= ovflSize; } sqlite3pager_unref(aPayload); } } if( amt>0 ){ | | | | 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 | offset -= ovflSize; } sqlite3pager_unref(aPayload); } } if( amt>0 ){ return SQLITE_CORRUPT_BKPT; } return SQLITE_OK; } /* ** Read part of the key associated with cursor pCur. Exactly ** "amt" bytes will be transfered into pBuf[]. The transfer ** begins at "offset". ** ** Return SQLITE_OK on success or an error code if anything goes ** wrong. An error is returned if "offset+amt" is larger than ** the available payload. */ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( pCur->isValid ); assert( pCur->pPage!=0 ); if( pCur->pPage->intKey ){ return SQLITE_CORRUPT_BKPT; } assert( pCur->pPage->intKey==0 ); assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell ); return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } /* |
︙ | ︙ | |||
2548 2549 2550 2551 2552 2553 2554 | pOldPage = pCur->pPage; pOldPage->idxShift = 0; releasePage(pOldPage); pCur->pPage = pNewPage; pCur->idx = 0; pCur->info.nSize = 0; if( pNewPage->nCell<1 ){ | | | 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 | pOldPage = pCur->pPage; pOldPage->idxShift = 0; releasePage(pOldPage); pCur->pPage = pNewPage; pCur->idx = 0; pCur->info.nSize = 0; if( pNewPage->nCell<1 ){ return SQLITE_CORRUPT_BKPT; } return SQLITE_OK; } /* ** Return true if the page is the virtual root of its table. ** |
︙ | ︙ | |||
2757 2758 2759 2760 2761 2762 2763 | int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; if( !pPage->intKey && pKey==0 ){ | | | 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 | int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; if( !pPage->intKey && pKey==0 ){ return SQLITE_CORRUPT_BKPT; } pageIntegrity(pPage); while( lwr<=upr ){ void *pCellKey; i64 nCellKey; pCur->idx = (lwr+upr)/2; pCur->info.nSize = 0; |
︙ | ︙ | |||
3042 3043 3044 3045 3046 3047 3048 | *pPgno = iTrunk; memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); *ppPage = pTrunk; pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); }else if( k>pBt->usableSize/4 - 8 ){ /* Value of k is out of range. Database corruption */ | | | 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 | *pPgno = iTrunk; memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); *ppPage = pTrunk; pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); }else if( k>pBt->usableSize/4 - 8 ){ /* Value of k is out of range. Database corruption */ return SQLITE_CORRUPT_BKPT; #ifndef SQLITE_OMIT_AUTOVACUUM }else if( searchList && nearby==iTrunk ){ /* The list is being searched and this trunk page is the page ** to allocate, regardless of whether it has leaves. */ assert( *pPgno==iTrunk ); *ppPage = pTrunk; |
︙ | ︙ | |||
3117 3118 3119 3120 3121 3122 3123 | } iPage = get4byte(&aData[8+closest*4]); if( !searchList || iPage==nearby ){ *pPgno = iPage; if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){ /* Free page off the end of the file */ | | | 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 | } iPage = get4byte(&aData[8+closest*4]); if( !searchList || iPage==nearby ){ *pPgno = iPage; if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){ /* Free page off the end of the file */ return SQLITE_CORRUPT_BKPT; } TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" ": %d more free pages\n", *pPgno, closest+1, k, pTrunk->pgno, n-1)); if( closest<k-1 ){ memcpy(&aData[8+closest*4], &aData[4+k*4], 4); } |
︙ | ︙ | |||
3258 3259 3260 3261 3262 3263 3264 | if( info.iOverflow==0 ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } ovflPgno = get4byte(&pCell[info.iOverflow]); while( ovflPgno!=0 ){ MemPage *pOvfl; if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){ | | | 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 | if( info.iOverflow==0 ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } ovflPgno = get4byte(&pCell[info.iOverflow]); while( ovflPgno!=0 ){ MemPage *pOvfl; if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){ return SQLITE_CORRUPT_BKPT; } rc = getPage(pBt, ovflPgno, &pOvfl); if( rc ) return rc; ovflPgno = get4byte(pOvfl->aData); rc = freePage(pOvfl); sqlite3pager_unref(pOvfl->aData); if( rc ) return rc; |
︙ | ︙ | |||
4664 4665 4666 4667 4668 4669 4670 | int notUsed; unsigned char *tempCell = 0; assert( !pPage->leafData ); getTempCursor(pCur, &leafCur); rc = sqlite3BtreeNext(&leafCur, ¬Used); if( rc!=SQLITE_OK ){ if( rc!=SQLITE_NOMEM ){ | | | 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 | int notUsed; unsigned char *tempCell = 0; assert( !pPage->leafData ); getTempCursor(pCur, &leafCur); rc = sqlite3BtreeNext(&leafCur, ¬Used); if( rc!=SQLITE_OK ){ if( rc!=SQLITE_NOMEM ){ rc = SQLITE_CORRUPT_BKPT; } } if( rc==SQLITE_OK ){ rc = sqlite3pager_write(leafCur.pPage->aData); } if( rc==SQLITE_OK ){ TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", |
︙ | ︙ | |||
4850 4851 4852 4853 4854 4855 4856 | ){ MemPage *pPage = 0; int rc; unsigned char *pCell; int i; if( pgno>sqlite3pager_pagecount(pBt->pPager) ){ | | | 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 | ){ MemPage *pPage = 0; int rc; unsigned char *pCell; int i; if( pgno>sqlite3pager_pagecount(pBt->pPager) ){ return SQLITE_CORRUPT_BKPT; } rc = getAndInitPage(pBt, pgno, &pPage, pParent); if( rc ) goto cleardatabasepage_out; rc = sqlite3pager_write(pPage->aData); if( rc ) goto cleardatabasepage_out; for(i=0; i<pPage->nCell; i++){ |
︙ | ︙ | |||
5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 | if( rc ) break; rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage); if( rc ) break; sqlite3pager_unref(pPage); } for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){ void *pPage; rc = sqlite3pager_get(pBtTo->pPager, i, &pPage); if( rc ) break; rc = sqlite3pager_write(pPage); sqlite3pager_unref(pPage); sqlite3pager_dont_write(pBtTo->pPager, i); } if( !rc && nPage<nToPage ){ | > | 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 | if( rc ) break; rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage); if( rc ) break; sqlite3pager_unref(pPage); } for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){ void *pPage; if( i==iSkip ) continue; rc = sqlite3pager_get(pBtTo->pPager, i, &pPage); if( rc ) break; rc = sqlite3pager_write(pPage); sqlite3pager_unref(pPage); sqlite3pager_dont_write(pBtTo->pPager, i); } if( !rc && nPage<nToPage ){ |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.302 2005/09/17 15:20:27 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and |
︙ | ︙ | |||
1043 1044 1045 1046 1047 1048 1049 | ** by the next COMMIT or ROLLBACK. ** ******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite3_get_autocommit(sqlite3 *db){ return db->autoCommit; } | > > > > > > > > > > > | 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | ** by the next COMMIT or ROLLBACK. ** ******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite3_get_autocommit(sqlite3 *db){ return db->autoCommit; } #ifdef SQLITE_DEBUG /* ** The following routine is subtituted for constant SQLITE_CORRUPT in ** debugging builds. This provides a way to set a breakpoint for when ** corruption is first detected. */ int sqlite3Corrupt(void){ return SQLITE_CORRUPT; } #endif |
Changes to src/os.h.
︙ | ︙ | |||
160 161 162 163 164 165 166 | ** The default location of PENDING_BYTE is the first byte past the ** 1GB boundary. ** */ #ifndef SQLITE_TEST #define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ #else | < | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | ** The default location of PENDING_BYTE is the first byte past the ** 1GB boundary. ** */ #ifndef SQLITE_TEST #define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ #else extern unsigned int sqlite3_pending_byte; #define PENDING_BYTE sqlite3_pending_byte #endif #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 |
︙ | ︙ |
Changes to src/os_common.h.
︙ | ︙ | |||
29 30 31 32 33 34 35 | /* * When testing, this global variable stores the location of the * pending-byte in the database file. */ #ifdef SQLITE_TEST | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /* * When testing, this global variable stores the location of the * pending-byte in the database file. */ #ifdef SQLITE_TEST unsigned int sqlite3_pending_byte = 0x40000000; #endif int sqlite3_os_trace = 0; #ifdef SQLITE_DEBUG static int last_page = 0; #define SEEK(X) last_page=(X) #define TRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X) |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.215 2005/09/17 15:20:27 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 | } pPager->journalOff = szJ; end_stmt_playback: if( rc!=SQLITE_OK ){ pPager->errMask |= PAGER_ERR_CORRUPT; | | | 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 | } pPager->journalOff = szJ; end_stmt_playback: if( rc!=SQLITE_OK ){ pPager->errMask |= PAGER_ERR_CORRUPT; rc = SQLITE_CORRUPT; }else{ pPager->journalOff = szJ; /* pager_reload_cache(pPager); */ } return rc; } |
︙ | ︙ | |||
2304 2305 2306 2307 2308 2309 2310 | PgHdr *pPg; int rc; /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page ** number greater than this, or zero, is requested. */ if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ | | | 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 | PgHdr *pPg; int rc; /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page ** number greater than this, or zero, is requested. */ if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ return SQLITE_CORRUPT_BKPT; } /* Make sure we have not hit any critical errors. */ assert( pPager!=0 ); *ppPage = 0; if( pPager->errMask & ~(PAGER_ERR_FULL) ){ |
︙ | ︙ | |||
3189 3190 3191 3192 3193 3194 3195 | if( rc==SQLITE_OK ){ rc = rc2; } }else{ rc = pager_playback(pPager); } if( rc!=SQLITE_OK ){ | | | 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 | if( rc==SQLITE_OK ){ rc = rc2; } }else{ rc = pager_playback(pPager); } if( rc!=SQLITE_OK ){ rc = SQLITE_CORRUPT_BKPT; pPager->errMask |= PAGER_ERR_CORRUPT; } pPager->dbSize = -1; return rc; } /* |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.419 2005/09/17 15:20:27 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Many people are failing to set -DNDEBUG=1 when compiling SQLite. ** Setting NDEBUG makes the code smaller and run faster. So the following |
︙ | ︙ | |||
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 | /* * This global flag is set for performance testing of triggers. When it is set * SQLite will perform the overhead of building new and old trigger references * even when no triggers exist */ extern int sqlite3_always_code_trigger_setup; /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); int sqlite3HashNoCase(const char *, int); int sqlite3IsNumber(const char*, int*, u8); | > > > > > > > > > > > > > | 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 | /* * This global flag is set for performance testing of triggers. When it is set * SQLite will perform the overhead of building new and old trigger references * even when no triggers exist */ extern int sqlite3_always_code_trigger_setup; /* ** The SQLITE_CORRUPT_BKPT macro can be either a constant (for production ** builds) or a function call (for debugging). If it is a function call, ** it allows the operator to set a breakpoint at the spot where database ** corruption is first detected. */ #ifdef SQLITE_DEBUG extern int sqlite3Corrupt(void); # define SQLITE_CORRUPT_BKPT sqlite3Corrupt() #else # define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT #endif /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); int sqlite3HashNoCase(const char *, int); int sqlite3IsNumber(const char*, int*, u8); |
︙ | ︙ |
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.488 2005/09/17 15:20:28 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
1958 1959 1960 1961 1962 1963 1964 | } /* The header should end at the start of data and the data should ** end at last byte of the record. If this is not the case then ** we are dealing with a malformed record. */ if( idx!=szHdr || offset!=payloadSize ){ | | | 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 | } /* The header should end at the start of data and the data should ** end at last byte of the record. If this is not the case then ** we are dealing with a malformed record. */ if( idx!=szHdr || offset!=payloadSize ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } /* Remember all aType and aColumn information if we have a cursor ** to remember it in. */ if( pC ){ pC->payloadSize = payloadSize; |
︙ | ︙ | |||
2512 2513 2514 2515 2516 2517 2518 | /* Sanity checking. Only the lower four bits of the flags byte should ** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or ** 2 (zerodata for indices). If these conditions are not met it can ** only mean that we are dealing with a corrupt database file */ if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){ | | | | 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 | /* Sanity checking. Only the lower four bits of the flags byte should ** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or ** 2 (zerodata for indices). If these conditions are not met it can ** only mean that we are dealing with a corrupt database file */ if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){ rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } pCur->isTable = (flags & BTREE_INTKEY)!=0; pCur->isIndex = (flags & BTREE_ZERODATA)!=0; /* If P3==0 it means we are expected to open a table. If P3!=0 then ** we expect to be opening an index. If this is not what happened, ** then the database is corrupt */ if( (pCur->isTable && pOp->p3type==P3_KEYINFO) || (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){ rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } break; } case SQLITE_EMPTY: { pCur->isTable = pOp->p3type!=P3_KEYINFO; pCur->isIndex = !pCur->isTable; |
︙ | ︙ | |||
3052 3053 3054 3055 3056 3057 3058 | ** to double the speed of the COPY operation. */ int res, rx=SQLITE_OK, cnt; i64 x; cnt = 0; if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) != BTREE_INTKEY ){ | | | 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 | ** to double the speed of the COPY operation. */ int res, rx=SQLITE_OK, cnt; i64 x; cnt = 0; if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) != BTREE_INTKEY ){ rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 ); assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 ); #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1708 1709 1710 1711 1712 1713 1714 | u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ Mem m, v; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ | | | 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 | u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ Mem m, v; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ return SQLITE_CORRUPT_BKPT; } rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m); if( rc ){ return rc; } sqlite3GetVarint32(m.z, &szHdr); sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid); |
︙ | ︙ |
Changes to test/tester.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # 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. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # 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. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # # $Id: tester.tcl,v 1.50 2005/09/17 15:20:28 drh Exp $ # Make sure tclsqlite3 was compiled correctly. Abort now with an # error message if not. # if {[sqlite3 -tcl-uses-utf]} { if {"\u1234"=="u1234"} { puts stderr "***** BUILD PROBLEM *****" |
︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 | puts stderr "Recompile using a TCL library and header file that match" puts stderr "and try again.\n**************************" exit 1 } } set tcl_precision 15 # Use the pager codec if it is available # if {[sqlite3 -has-codec] && [info command sqlite_orig]==""} { rename sqlite3 sqlite_orig proc sqlite3 {args} { if {[llength $args]==2 && [string index [lindex $args 0] 0]!="-"} { | > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | puts stderr "Recompile using a TCL library and header file that match" puts stderr "and try again.\n**************************" exit 1 } } set tcl_precision 15 set sqlite_pending_byte 0x0010000 # Use the pager codec if it is available # if {[sqlite3 -has-codec] && [info command sqlite_orig]==""} { rename sqlite3 sqlite_orig proc sqlite3 {args} { if {[llength $args]==2 && [string index [lindex $args 0] 0]!="-"} { |
︙ | ︙ |