Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Bring test coverage up to 99%. (CVS 5522) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2cd6bae80984126023bcf479e5f3db5e |
User & Date: | drh 2008-08-01 20:10:08 |
Context
2008-08-02
| ||
03:50 | Additional coverage testing. Fix a segfault following OOM in sqltie3_load_extension(). (CVS 5523) check-in: f1e44eb323 user: drh tags: trunk | |
2008-08-01
| ||
20:10 | Bring test coverage up to 99%. (CVS 5522) check-in: 2cd6bae809 user: drh tags: trunk | |
18:47 | Fix problems in test scripts. Add new test cases to improve test coverage. (CVS 5521) check-in: b65f493c75 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 .... 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 .... 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 .... 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 .... 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 .... 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 .... 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 |
** 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.492 2008/07/28 19:34:53 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" ................................................................................ sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); } if( zMsg1 ){ sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1); } sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); va_end(ap); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. ................................................................................ } /* Check for complete coverage of the page */ data = pPage->aData; hdr = pPage->hdrOffset; hit = sqlite3PageMalloc( pBt->pageSize ); if( hit ){ memset(hit, 0, usableSize ); memset(hit, 1, get2byte(&data[hdr+5])); nCell = get2byte(&data[hdr+3]); cellStart = hdr + 12 - 4*pPage->leaf; for(i=0; i<nCell; i++){ int pc = get2byte(&data[cellStart+i*2]); u16 size = cellSizePtr(pPage, &data[pc]); ................................................................................ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** This routine does a complete check of the given BTree file. aRoot[] is ** an array of pages numbers were each page number is the root page of ** a table. nRoot is the number of entries in aRoot. ** ** If everything checks out, this routine returns NULL. If something is ** amiss, an error message is written into memory obtained from malloc() ** and a pointer to that error message is returned. The calling function ** is responsible for freeing the error message when it is done. */ char *sqlite3BtreeIntegrityCheck( Btree *p, /* The btree to be checked */ int *aRoot, /* An array of root pages numbers for individual trees */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ int *pnErr /* Write number of errors seen to this variable */ ................................................................................ BtShared *pBt = p->pBt; char zErr[100]; sqlite3BtreeEnter(p); pBt->db = p->db; nRef = sqlite3PagerRefcount(pBt->pPager); if( lockBtreeWithRetry(p)!=SQLITE_OK ){ sqlite3BtreeLeave(p); return sqlite3DbStrDup(0, "Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = pagerPagecount(sCheck.pPager); sCheck.mxErr = mxErr; sCheck.nErr = 0; *pnErr = 0; #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->nTrunc!=0 ){ sCheck.nPage = pBt->nTrunc; } #endif if( sCheck.nPage==0 ){ ................................................................................ return 0; } sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ unlockBtreeIfUnused(pBt); *pnErr = 1; sqlite3BtreeLeave(p); return sqlite3MPrintf(p->db, "Unable to malloc %d bytes", (sCheck.nPage+1)*sizeof(sCheck.anRef[0])); } for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ){ sCheck.anRef[i] = 1; } sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000); ................................................................................ ); } /* Clean up and report errors. */ sqlite3BtreeLeave(p); sqlite3_free(sCheck.anRef); *pnErr = sCheck.nErr; if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* |
| > > > | > > | | | | > | > | < > > > > > |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .... 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 .... 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 .... 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 .... 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 .... 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 .... 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 |
** 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.493 2008/08/01 20:10:08 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" ................................................................................ sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); } if( zMsg1 ){ sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1); } sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); va_end(ap); if( pCheck->errMsg.mallocFailed ){ pCheck->mallocFailed = 1; } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. ................................................................................ } /* Check for complete coverage of the page */ data = pPage->aData; hdr = pPage->hdrOffset; hit = sqlite3PageMalloc( pBt->pageSize ); if( hit==0 ){ pCheck->mallocFailed = 1; }else{ memset(hit, 0, usableSize ); memset(hit, 1, get2byte(&data[hdr+5])); nCell = get2byte(&data[hdr+3]); cellStart = hdr + 12 - 4*pPage->leaf; for(i=0; i<nCell; i++){ int pc = get2byte(&data[cellStart+i*2]); u16 size = cellSizePtr(pPage, &data[pc]); ................................................................................ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** This routine does a complete check of the given BTree file. aRoot[] is ** an array of pages numbers were each page number is the root page of ** a table. nRoot is the number of entries in aRoot. ** ** Write the number of error seen in *pnErr. Except for some memory ** allocation errors, nn error message is held in memory obtained from ** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is ** returned. */ char *sqlite3BtreeIntegrityCheck( Btree *p, /* The btree to be checked */ int *aRoot, /* An array of root pages numbers for individual trees */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ int *pnErr /* Write number of errors seen to this variable */ ................................................................................ BtShared *pBt = p->pBt; char zErr[100]; sqlite3BtreeEnter(p); pBt->db = p->db; nRef = sqlite3PagerRefcount(pBt->pPager); if( lockBtreeWithRetry(p)!=SQLITE_OK ){ *pnErr = 1; sqlite3BtreeLeave(p); return sqlite3DbStrDup(0, "cannot acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = pagerPagecount(sCheck.pPager); sCheck.mxErr = mxErr; sCheck.nErr = 0; sCheck.mallocFailed = 0; *pnErr = 0; #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->nTrunc!=0 ){ sCheck.nPage = pBt->nTrunc; } #endif if( sCheck.nPage==0 ){ ................................................................................ return 0; } sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ unlockBtreeIfUnused(pBt); *pnErr = 1; sqlite3BtreeLeave(p); return 0; } for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ){ sCheck.anRef[i] = 1; } sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000); ................................................................................ ); } /* Clean up and report errors. */ sqlite3BtreeLeave(p); sqlite3_free(sCheck.anRef); if( sCheck.mallocFailed ){ sqlite3StrAccumReset(&sCheck.errMsg); *pnErr = sCheck.nErr+1; return 0; } *pnErr = sCheck.nErr; if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* |
Changes to src/btreeInt.h.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
597
598
599
600
601
602
603
604
605
606
607
608
609
610
|
** 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: btreeInt.h,v 1.29 2008/07/18 09:34:57 danielk1977 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. ................................................................................ struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ int nPage; /* Number of pages in the database */ int *anRef; /* Number of times each page is referenced */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ StrAccum errMsg; /* Accumulate the error message text here */ }; /* ** Read or write a two- and four-byte big-endian integer values. */ #define get2byte(x) ((x)[0]<<8 | (x)[1]) |
|
>
|
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
|
** 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: btreeInt.h,v 1.30 2008/08/01 20:10:08 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. ................................................................................ struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ int nPage; /* Number of pages in the database */ int *anRef; /* Number of times each page is referenced */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int mallocFailed; /* A memory allocation error has occurred */ StrAccum errMsg; /* Accumulate the error message text here */ }; /* ** Read or write a two- and four-byte big-endian integer values. */ #define get2byte(x) ((x)[0]<<8 | (x)[1]) |
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
|
** ** 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.770 2008/08/01 17:37:41 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor ................................................................................ aRoot[j] = sqlite3VdbeIntValue(&pIn1[j]); } aRoot[j] = 0; assert( pOp->p5<db->nDb ); assert( (p->btreeMask & (1<<pOp->p5))!=0 ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, pnErr->u.i, &nErr); pnErr->u.i -= nErr; sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); }else{ sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); sqlite3DbFree(db, aRoot); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: FifoWrite P1 * * * * ** ** Write the integer from register P1 into the Fifo. |
|
>
>
>
<
|
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
|
** ** 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.771 2008/08/01 20:10:08 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor ................................................................................ aRoot[j] = sqlite3VdbeIntValue(&pIn1[j]); } aRoot[j] = 0; assert( pOp->p5<db->nDb ); assert( (p->btreeMask & (1<<pOp->p5))!=0 ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, pnErr->u.i, &nErr); sqlite3DbFree(db, aRoot); pnErr->u.i -= nErr; sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); }else if( z==0 ){ goto no_mem; }else{ sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: FifoWrite P1 * * * * ** ** Write the integer from register P1 into the Fifo. |
Changes to src/vdbe.h.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.134 2008/06/25 00:12:41 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines ................................................................................ int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); int sqlite3VdbeReset(Vdbe*, int); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); void sqlite3VdbeSwap(Vdbe*,Vdbe*); |
|
|
|
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.135 2008/08/01 20:10:08 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines ................................................................................ int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); int sqlite3VdbeReset(Vdbe*); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); void sqlite3VdbeSwap(Vdbe*,Vdbe*); |
Changes to src/vdbeapi.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.136 2008/07/28 19:34:54 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** The following structure contains pointers to the end points of a ................................................................................ int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v, 1); stmtLruAdd(v); sqlite3VdbeMakeReady(v, -1, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); sqlite3_mutex_leave(v->db->mutex); } return rc; } |
|
|
|
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.137 2008/08/01 20:10:08 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** The following structure contains pointers to the end points of a ................................................................................ int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); stmtLruAdd(v); sqlite3VdbeMakeReady(v, -1, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); sqlite3_mutex_leave(v->db->mutex); } return rc; } |
Changes to src/vdbeaux.c.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 ... 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 .... 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 .... 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 .... 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 .... 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 .... 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 .... 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 |
** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** ** $Id: vdbeaux.c,v 1.403 2008/08/01 17:37:41 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" ................................................................................ fflush(pOut); } #endif /* ** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N, int freebuffers){ if( p && N ){ sqlite3 *db = p->db; int malloc_failed = db->mallocFailed; while( N-->0 ){ assert( N<2 || p[0].db==p[1].db ); if( freebuffers ){ sqlite3VdbeMemRelease(p); }else{ sqlite3VdbeMemReleaseExternal(p); } p->flags = MEM_Null; p++; } db->mallocFailed = malloc_failed; } } ................................................................................ assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); /* Even though this opcode does not use dynamic strings for ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, p->nMem, 1); do{ i = p->pc++; }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; ................................................................................ /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. It also deletes the values of ** variables in the aVar[] array. */ static void Cleanup(Vdbe *p, int freebuffers){ int i; sqlite3 *db = p->db; closeAllCursorsExceptActiveVtabs(p); for(i=1; i<=p->nMem; i++){ MemSetTypeFlag(&p->aMem[i], MEM_Null); } releaseMemArray(&p->aMem[1], p->nMem, freebuffers); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; i<p->contextStackTop; i++){ sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } sqlite3DbFree(db, p->contextStack); } ................................................................................ ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; sqlite3 *db = p->db; releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); sqlite3DbFree(db, p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; while( n-- > 0 ){ pColName->flags = MEM_Null; ................................................................................ ** After this routine is run, the VDBE should be ready to be executed ** again. ** ** To look at it another way, this routine resets the state of the ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p, int freebuffers){ sqlite3 *db; db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ ................................................................................ sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } /* Reclaim all memory used by the VDBE */ Cleanup(p, freebuffers); /* Save profiling information from this VDBE run. */ #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ ................................................................................ /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p, 1); assert( (rc & p->db->errMask)==rc ); }else if( p->magic!=VDBE_MAGIC_INIT ){ return SQLITE_MISUSE; } /* releaseMemArray(&p->aMem[1], p->nMem, 1); */ sqlite3VdbeDelete(p); return rc; } /* ** Call the destructor for each auxdata entry in pVdbeFunc for which ** the corresponding bit in mask is clear. Auxdata entries beyond 31 ................................................................................ freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_DEBUG sqlite3DbFree(db, pOp->zComment); #endif } sqlite3DbFree(db, p->aOp); } releaseMemArray(p->aVar, p->nVar, 1); sqlite3DbFree(db, p->aLabel); if( p->aMem ){ sqlite3DbFree(db, &p->aMem[1]); } releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); p->magic = VDBE_MAGIC_DEAD; sqlite3DbFree(db, p); } /* |
| | < | < < < | | | | | | | < | | |
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 ... 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 .... 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 .... 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 .... 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 .... 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 .... 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 .... 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 |
** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** ** $Id: vdbeaux.c,v 1.404 2008/08/01 20:10:08 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" ................................................................................ fflush(pOut); } #endif /* ** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N){ if( p && N ){ sqlite3 *db = p->db; int malloc_failed = db->mallocFailed; while( N-->0 ){ assert( N<2 || p[0].db==p[1].db ); sqlite3VdbeMemRelease(p); p->flags = MEM_Null; p++; } db->mallocFailed = malloc_failed; } } ................................................................................ assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); /* Even though this opcode does not use dynamic strings for ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, p->nMem); do{ i = p->pc++; }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; ................................................................................ /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. It also deletes the values of ** variables in the aVar[] array. */ static void Cleanup(Vdbe *p){ int i; sqlite3 *db = p->db; closeAllCursorsExceptActiveVtabs(p); for(i=1; i<=p->nMem; i++){ MemSetTypeFlag(&p->aMem[i], MEM_Null); } releaseMemArray(&p->aMem[1], p->nMem); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; i<p->contextStackTop; i++){ sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } sqlite3DbFree(db, p->contextStack); } ................................................................................ ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; sqlite3 *db = p->db; releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; while( n-- > 0 ){ pColName->flags = MEM_Null; ................................................................................ ** After this routine is run, the VDBE should be ready to be executed ** again. ** ** To look at it another way, this routine resets the state of the ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p){ sqlite3 *db; db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ ................................................................................ sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } /* Reclaim all memory used by the VDBE */ Cleanup(p); /* Save profiling information from this VDBE run. */ #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ ................................................................................ /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); }else if( p->magic!=VDBE_MAGIC_INIT ){ return SQLITE_MISUSE; } sqlite3VdbeDelete(p); return rc; } /* ** Call the destructor for each auxdata entry in pVdbeFunc for which ** the corresponding bit in mask is clear. Auxdata entries beyond 31 ................................................................................ freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_DEBUG sqlite3DbFree(db, pOp->zComment); #endif } sqlite3DbFree(db, p->aOp); } releaseMemArray(p->aVar, p->nVar); sqlite3DbFree(db, p->aLabel); if( p->aMem ){ sqlite3DbFree(db, &p->aMem[1]); } releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); p->magic = VDBE_MAGIC_DEAD; sqlite3DbFree(db, p); } /* |
Changes to src/vdbemem.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
|
************************************************************************* ** ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** ** $Id: vdbemem.c,v 1.120 2008/07/30 13:14:55 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ................................................................................ }else if( xDel==SQLITE_DYNAMIC ){ sqlite3VdbeMemRelease(pMem); pMem->zMalloc = pMem->z = (char *)z; pMem->xDel = 0; }else{ sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; if( xDel==SQLITE_DYNAMIC ){ pMem->zMalloc = pMem->z; pMem->xDel = 0; flags |= MEM_Dyn; }else{ pMem->xDel = xDel; flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); } } pMem->n = nByte; pMem->flags = flags; pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT); |
|
<
<
<
<
<
|
|
<
|
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
|
************************************************************************* ** ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** ** $Id: vdbemem.c,v 1.121 2008/08/01 20:10:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ................................................................................ }else if( xDel==SQLITE_DYNAMIC ){ sqlite3VdbeMemRelease(pMem); pMem->zMalloc = pMem->z = (char *)z; pMem->xDel = 0; }else{ sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; pMem->xDel = xDel; flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); } pMem->n = nByte; pMem->flags = flags; pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT); |
Changes to test/attachmalloc.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH statement and # specifically out-of-memory conditions within that command. # # $Id: attachmalloc.test,v 1.7 2007/10/09 08:29:32 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !memdebug||!attach { finish_test ................................................................................ file delete -force test$i.db file delete -force test$i.db-journal } } -tclbody { if {[catch {sqlite3 db test.db}]} { error "out of memory" } sqlite3_extended_result_codes db 1 } -sqlbody { ATTACH 'test2.db' AS two; CREATE TABLE two.t1(x); ATTACH 'test3.db' AS three; CREATE TABLE three.t1(x); ATTACH 'test4.db' AS four; CREATE TABLE four.t1(x); } finish_test |
|
>
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH statement and # specifically out-of-memory conditions within that command. # # $Id: attachmalloc.test,v 1.8 2008/08/01 20:10:09 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !memdebug||!attach { finish_test ................................................................................ file delete -force test$i.db file delete -force test$i.db-journal } } -tclbody { if {[catch {sqlite3 db test.db}]} { error "out of memory" } sqlite3_db_config_lookaside db 0 0 sqlite3_extended_result_codes db 1 } -sqlbody { ATTACH 'test2.db' AS two; CREATE TABLE two.t1(x); ATTACH 'test3.db' AS three; CREATE TABLE three.t1(x); ATTACH 'test4.db' AS four; CREATE TABLE four.t1(x); } finish_test |
Changes to test/mallocH.test.
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
43
44
45
46
47
48
49
50
51
|
# May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This test script checks malloc failures in various obscure operations. # # $Id: mallocH.test,v 1.1 2008/08/01 18:47:02 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl # Malloc failures in journaling of in-memory databases. # ................................................................................ } # Malloc failures within the replace() function. # do_malloc_test mallocH-3 -sqlbody { SELECT replace('ababa','a','xyzzy'); } finish_test |
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This test script checks malloc failures in various obscure operations. # # $Id: mallocH.test,v 1.2 2008/08/01 20:10:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl # Malloc failures in journaling of in-memory databases. # ................................................................................ } # Malloc failures within the replace() function. # do_malloc_test mallocH-3 -sqlbody { SELECT replace('ababa','a','xyzzy'); } # Malloc failures during EXPLAIN. # ifcapable explain { do_malloc_test mallocH-4 -sqlprep { CREATE TABLE abc(a PRIMARY KEY, b, c); } -sqlbody { EXPLAIN SELECT * FROM abc AS t2 WHERE rowid=1; EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid=1; } } # Malloc failure during integrity_check pragma. # do_malloc_test mallocH-5 -sqlprep { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); CREATE TABLE t2(x,y); INSERT INTO t1 VALUES(1,2); INSERT INTO t2 SELECT * FROM t1; } -sqlbody { PRAGMA integrity_check; } finish_test |