mirror of https://github.com/sqlite/sqlite
Clarify error handling in pager code. No functional changes. (CVS 2956)
FossilOrigin-Name: 7b48836214ea3152f46e2dffb097ae7ea14901f4
This commit is contained in:
parent
45bfcfd3fc
commit
efaaf57974
20
manifest
20
manifest
|
@ -1,5 +1,5 @@
|
|||
C Version\s3.3.1\s(alpha)\s(CVS\s2953)
|
||||
D 2006-01-16T02:39:05
|
||||
C Clarify\serror\shandling\sin\spager\scode.\sNo\sfunctional\schanges.\s(CVS\s2956)
|
||||
D 2006-01-16T11:29:19
|
||||
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
|
@ -59,18 +59,18 @@ F src/os_unix.c 7daa1720d46bbc31c6138462b35876650eb1885e
|
|||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||
F src/os_win.c cd4ca2753aeaad11f5c9b9b6ef28752f45ed4529
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c 12da1f38d60a2c44925281d3a1bc2769fa36428b
|
||||
F src/pager.c 24d4b97c29a6a3d9f4437e6b56debb7e3f3183b2
|
||||
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
|
||||
F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
|
||||
F src/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3
|
||||
F src/prepare.c 1058dcb102005a880d757551d52a0a2830c05f27
|
||||
F src/prepare.c 368f5c04755f03dc04353513e6afcebb8ca8d53f
|
||||
F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812
|
||||
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
||||
F src/select.c 28d449c7762dd580aaba49a9c6c16e93ca951e49
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da
|
||||
F src/sqlite.h.in 492580f7e3ff71eb43193eb7bb98e2d549889ce3
|
||||
F src/sqliteInt.h ed482d6de58fa79000f9c3bb00d7740126fb55fb
|
||||
F src/sqliteInt.h 940bb605c7ac9240934f0b866f90be899f5261fc
|
||||
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
||||
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
|
||||
F src/test1.c d21e94ea95e76d8e838792806937332c5693dbf0
|
||||
|
@ -90,7 +90,7 @@ F src/vacuum.c 21a3c7f6f7be86bb1182fbc3df416ad702435b9e
|
|||
F src/vdbe.c 4db1a9000e238e068de56108f5a9708cd4124d55
|
||||
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
||||
F src/vdbeInt.h 5451cf71f229e366ac543607c0a17f36e5737ea9
|
||||
F src/vdbeapi.c afd3837cea0dec93dcb4724d073c84fa0da68e23
|
||||
F src/vdbeapi.c cac3f5bfb8ab9864ce5cea35eaae3d0d2efdc8ac
|
||||
F src/vdbeaux.c bfad18ca5d0372a34147ed98ac268b75ccb6858d
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c dd08a0eea4868ac4a2d91fdec32424308b1db772
|
||||
|
@ -341,7 +341,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 6591d365d4ba1263c3bc48f5ab47633fae2b2a3a
|
||||
R 7d7be83f73b610d0efb0d6e55a70818a
|
||||
U drh
|
||||
Z 95511deea1a74daa9ad5dc683e2d355c
|
||||
P bd7c5699939fda2bb792a0e2448df064a1171769
|
||||
R 24df549afc2503239ffb645fa43166ce
|
||||
U danielk1977
|
||||
Z c2d3eab392f302df5565749bb5c35c05
|
||||
|
|
|
@ -1 +1 @@
|
|||
bd7c5699939fda2bb792a0e2448df064a1171769
|
||||
7b48836214ea3152f46e2dffb097ae7ea14901f4
|
142
src/pager.c
142
src/pager.c
|
@ -18,7 +18,7 @@
|
|||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.237 2006/01/15 20:28:28 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.238 2006/01/16 11:29:19 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
|
@ -225,6 +225,14 @@ struct PgHistory {
|
|||
|
||||
/*
|
||||
** A open page cache is an instance of the following structure.
|
||||
**
|
||||
** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, SQLITE_PROTOCOL
|
||||
** or SQLITE_FULL. Once one of the first three errors occurs, it persists
|
||||
** and is returned as the result of every major pager API call. The
|
||||
** SQLITE_FULL return code is slightly different. It persists only until the
|
||||
** next successful rollback is performed on the pager cache. Also,
|
||||
** SQLITE_FULL does not affect the sqlite3pager_get() and sqlite3pager_lookup()
|
||||
** APIs, they may still be used successfully.
|
||||
*/
|
||||
struct Pager {
|
||||
u8 journalOpen; /* True if journal file descriptors is valid */
|
||||
|
@ -237,7 +245,7 @@ struct Pager {
|
|||
u8 noSync; /* Do not sync the journal if true */
|
||||
u8 fullSync; /* Do extra syncs of the journal for robustness */
|
||||
u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
|
||||
u8 errMask; /* One of several kinds of errors */
|
||||
u8 errCode; /* One of several kinds of errors */
|
||||
u8 tempFile; /* zFilename is a temporary file */
|
||||
u8 readOnly; /* True for a read-only database */
|
||||
u8 needSync; /* True if an fsync() is needed on the journal */
|
||||
|
@ -299,39 +307,6 @@ struct Pager {
|
|||
# define TEST_INCR(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** These are bits that can be set in Pager.errMask.
|
||||
**
|
||||
** TODO: Maybe we just want a variable - Pager.errCode. Can we really
|
||||
** have two simultaneous error conditions?
|
||||
**
|
||||
** Recovering from an SQLITE_FULL, SQLITE_LOCK, SQLITE_CORRUPT or
|
||||
** SQLITE_IOERR error is not a simple matter, particularly if the pager
|
||||
** cache is shared between multiple connections.
|
||||
**
|
||||
** SQLITE_FULL (PAGER_ERR_FULL):
|
||||
** Cleared when the transaction is rolled back.
|
||||
**
|
||||
** SQLITE_CORRUPT (PAGER_ERR_CORRUPT):
|
||||
** Cannot be cleared. The upper layer must close the current pager
|
||||
** and open a new one on the same file to continue.
|
||||
**
|
||||
** SQLITE_PROTOCOL (PAGER_ERR_LOCK):
|
||||
** This error only occurs if an internal error occurs or another process
|
||||
** is not following the sqlite locking protocol (i.e. someone is
|
||||
** manipulating the database file using something other than sqlite).
|
||||
** This is handled in the same way as database corruption - the error
|
||||
** cannot be cleared except by closing the current pager and opening
|
||||
** a brand new one on the same file.
|
||||
**
|
||||
** SQLITE_IOERR (PAGER_ERR_DISK):
|
||||
** Cleared when the transaction is rolled back.
|
||||
*/
|
||||
#define PAGER_ERR_FULL 0x01 /* a write() failed */
|
||||
#define PAGER_ERR_LOCK 0x02 /* error in the locking protocol */
|
||||
#define PAGER_ERR_CORRUPT 0x04 /* database or journal corruption */
|
||||
#define PAGER_ERR_DISK 0x08 /* general disk I/O error - bad hard drive? */
|
||||
|
||||
/*
|
||||
** Journal files begin with the following magic string. The data
|
||||
** was obtained from /dev/random. It is used only as a sanity check.
|
||||
|
@ -480,37 +455,19 @@ static u32 retrieve32bits(PgHdr *p, int offset){
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** Convert the bits in the pPager->errMask into an approprate
|
||||
** return code.
|
||||
*/
|
||||
static int pager_errcode(Pager *pPager){
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
|
||||
if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
|
||||
if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
|
||||
if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function should be called when an error occurs within the pager
|
||||
** code to set the appropriate bits in Pager.errMask.
|
||||
** code to set Pager.errCode.
|
||||
*/
|
||||
static int pager_error(Pager *pPager, int rc){
|
||||
switch( rc ){
|
||||
case SQLITE_PROTOCOL:
|
||||
pPager->errMask |= PAGER_ERR_LOCK;
|
||||
break;
|
||||
case SQLITE_IOERR:
|
||||
pPager->errMask |= PAGER_ERR_DISK;
|
||||
break;
|
||||
case SQLITE_FULL:
|
||||
pPager->errMask |= PAGER_ERR_FULL;
|
||||
break;
|
||||
case SQLITE_CORRUPT:
|
||||
pPager->errMask |= PAGER_ERR_CORRUPT;
|
||||
break;
|
||||
assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
|
||||
if(
|
||||
rc==SQLITE_FULL ||
|
||||
rc==SQLITE_IOERR ||
|
||||
rc==SQLITE_CORRUPT ||
|
||||
rc==SQLITE_PROTOCOL
|
||||
){
|
||||
pPager->errCode = rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -537,7 +494,7 @@ static u32 pager_pagehash(PgHdr *pPage){
|
|||
#define CHECK_PAGE(x) checkPage(x)
|
||||
static void checkPage(PgHdr *pPg){
|
||||
Pager *pPager = pPg->pPager;
|
||||
assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty ||
|
||||
assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty ||
|
||||
pPg->pageHash==pager_pagehash(pPg) );
|
||||
}
|
||||
|
||||
|
@ -879,7 +836,7 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
|
|||
*/
|
||||
static void pager_reset(Pager *pPager){
|
||||
PgHdr *pPg, *pNext;
|
||||
if( pPager->errMask ) return;
|
||||
if( pPager->errCode ) return;
|
||||
for(pPg=pPager->pAll; pPg; pPg=pNext){
|
||||
pNext = pPg->pNextAll;
|
||||
sqliteFree(pPg);
|
||||
|
@ -1500,8 +1457,7 @@ static int pager_stmt_playback(Pager *pPager){
|
|||
|
||||
end_stmt_playback:
|
||||
if( rc!=SQLITE_OK ){
|
||||
pPager->errMask |= PAGER_ERR_CORRUPT;
|
||||
rc = SQLITE_CORRUPT;
|
||||
rc = pager_error(pPager, SQLITE_CORRUPT);
|
||||
}else{
|
||||
pPager->journalOff = szJ;
|
||||
/* pager_reload_cache(pPager); */
|
||||
|
@ -1833,7 +1789,7 @@ int sqlite3pager_pagecount(Pager *pPager){
|
|||
n = pPager->dbSize;
|
||||
} else {
|
||||
if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
|
||||
pPager->errMask |= PAGER_ERR_DISK;
|
||||
pager_error(pPager, SQLITE_IOERR);
|
||||
return 0;
|
||||
}
|
||||
if( n>0 && n<pPager->pageSize ){
|
||||
|
@ -1979,8 +1935,8 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
|
|||
int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
|
||||
int rc;
|
||||
sqlite3pager_pagecount(pPager);
|
||||
if( pPager->errMask!=0 ){
|
||||
rc = pager_errcode(pPager);
|
||||
if( pPager->errCode ){
|
||||
rc = pPager->errCode;
|
||||
return rc;
|
||||
}
|
||||
if( nPage>=(unsigned)pPager->dbSize ){
|
||||
|
@ -2043,7 +1999,7 @@ int sqlite3pager_close(Pager *pPager){
|
|||
if( !MEMDB ){
|
||||
sqlite3OsUnlock(pPager->fd, NO_LOCK);
|
||||
}
|
||||
assert( pPager->errMask || pPager->journalOpen==0 );
|
||||
assert( pPager->errCode || pPager->journalOpen==0 );
|
||||
break;
|
||||
}
|
||||
case PAGER_SHARED: {
|
||||
|
@ -2070,7 +2026,7 @@ int sqlite3pager_close(Pager *pPager){
|
|||
sqliteFree(pPg);
|
||||
}
|
||||
TRACE2("CLOSE %d\n", PAGERID(pPager));
|
||||
assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
|
||||
assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
|
||||
if( pPager->journalOpen ){
|
||||
sqlite3OsClose(&pPager->jfd);
|
||||
}
|
||||
|
@ -2367,7 +2323,7 @@ static int hasHotJournal(Pager *pPager){
|
|||
** Try to find a page in the cache that can be recycled.
|
||||
**
|
||||
** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It
|
||||
** does not set the pPager->errMask variable.
|
||||
** does not set the pPager->errCode variable.
|
||||
*/
|
||||
static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
|
||||
PgHdr *pPg;
|
||||
|
@ -2512,7 +2468,7 @@ int sqlite3pager_release_memory(int nReq){
|
|||
if( rc!=SQLITE_OK ){
|
||||
/* An error occured whilst writing to the database file or
|
||||
** journal in pager_recycle(). The error is not returned to the
|
||||
** caller of this function. Instead, set the Pager.errMask variable.
|
||||
** caller of this function. Instead, set the Pager.errCode variable.
|
||||
** The error will be returned to the user (or users, in the case
|
||||
** of a shared pager cache) of the pager for which the error occured.
|
||||
*/
|
||||
|
@ -2565,8 +2521,8 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
*/
|
||||
assert( pPager!=0 );
|
||||
*ppPage = 0;
|
||||
if( pPager->errMask & ~(PAGER_ERR_FULL) ){
|
||||
return pager_errcode(pPager);
|
||||
if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
|
||||
return pPager->errCode;
|
||||
}
|
||||
|
||||
/* If this is the first page accessed, then get a SHARED lock
|
||||
|
@ -2702,9 +2658,9 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
if( pPager->nExtra>0 ){
|
||||
memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
|
||||
}
|
||||
if( pPager->errMask!=0 ){
|
||||
if( pPager->errCode ){
|
||||
sqlite3pager_unref(PGHDR_TO_DATA(pPg));
|
||||
rc = pager_errcode(pPager);
|
||||
rc = pPager->errCode;
|
||||
return rc;
|
||||
}
|
||||
if( sqlite3pager_pagecount(pPager)<(int)pgno ){
|
||||
|
@ -2761,7 +2717,7 @@ void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
|
|||
|
||||
assert( pPager!=0 );
|
||||
assert( pgno!=0 );
|
||||
if( pPager->errMask & ~(PAGER_ERR_FULL) ){
|
||||
if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
|
||||
return 0;
|
||||
}
|
||||
pPg = pager_lookup(pPager, pgno);
|
||||
|
@ -2859,8 +2815,8 @@ static int pager_open_journal(Pager *pPager){
|
|||
pPager->needSync = 0;
|
||||
pPager->alwaysRollback = 0;
|
||||
pPager->nRec = 0;
|
||||
if( pPager->errMask!=0 ){
|
||||
rc = pager_errcode(pPager);
|
||||
if( pPager->errCode ){
|
||||
rc = pPager->errCode;
|
||||
goto failed_to_open_journal;
|
||||
}
|
||||
pPager->origDbSize = pPager->dbSize;
|
||||
|
@ -2978,8 +2934,8 @@ int sqlite3pager_write(void *pData){
|
|||
|
||||
/* Check for errors
|
||||
*/
|
||||
if( pPager->errMask ){
|
||||
return pager_errcode(pPager);
|
||||
if( pPager->errCode ){
|
||||
return pPager->errCode;
|
||||
}
|
||||
if( pPager->readOnly ){
|
||||
return SQLITE_PERM;
|
||||
|
@ -3053,7 +3009,9 @@ int sqlite3pager_write(void *pData){
|
|||
*(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3pager_rollback(pPager);
|
||||
pPager->errMask |= PAGER_ERR_FULL;
|
||||
if( !pPager->errCode ){
|
||||
pager_error(pPager, SQLITE_FULL);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
pPager->nRec++;
|
||||
|
@ -3100,7 +3058,9 @@ int sqlite3pager_write(void *pData){
|
|||
CODEC(pPager, pData, pPg->pgno, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3pager_rollback(pPager);
|
||||
pPager->errMask |= PAGER_ERR_FULL;
|
||||
if( !pPager->errCode ){
|
||||
pager_error(pPager, SQLITE_FULL);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
pPager->stmtNRec++;
|
||||
|
@ -3260,15 +3220,15 @@ int sqlite3pager_commit(Pager *pPager){
|
|||
int rc;
|
||||
PgHdr *pPg;
|
||||
|
||||
if( pPager->errMask==PAGER_ERR_FULL ){
|
||||
if( pPager->errCode==SQLITE_FULL ){
|
||||
rc = sqlite3pager_rollback(pPager);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = SQLITE_FULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
if( pPager->errMask!=0 ){
|
||||
rc = pager_errcode(pPager);
|
||||
if( pPager->errCode ){
|
||||
rc = pPager->errCode;
|
||||
return rc;
|
||||
}
|
||||
if( pPager->state<PAGER_RESERVED ){
|
||||
|
@ -3379,11 +3339,11 @@ int sqlite3pager_rollback(Pager *pPager){
|
|||
return rc;
|
||||
}
|
||||
|
||||
if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
|
||||
if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
|
||||
if( pPager->state>=PAGER_EXCLUSIVE ){
|
||||
pager_playback(pPager);
|
||||
}
|
||||
return pager_errcode(pPager);
|
||||
return pPager->errCode;
|
||||
}
|
||||
if( pPager->state==PAGER_RESERVED ){
|
||||
int rc2;
|
||||
|
@ -3397,7 +3357,7 @@ int sqlite3pager_rollback(Pager *pPager){
|
|||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
pPager->errMask |= PAGER_ERR_CORRUPT;
|
||||
pager_error(pPager, SQLITE_CORRUPT);
|
||||
}
|
||||
pPager->dbSize = -1;
|
||||
return rc;
|
||||
|
@ -3421,7 +3381,7 @@ int *sqlite3pager_stats(Pager *pPager){
|
|||
a[2] = pPager->mxPage;
|
||||
a[3] = pPager->dbSize;
|
||||
a[4] = pPager->state;
|
||||
a[5] = pPager->errMask;
|
||||
a[5] = pPager->errCode;
|
||||
#ifdef SQLITE_TEST
|
||||
a[6] = pPager->nHit;
|
||||
a[7] = pPager->nMiss;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
** interface, and routines that contribute to loading the database schema
|
||||
** from disk.
|
||||
**
|
||||
** $Id: prepare.c,v 1.22 2006/01/13 06:33:24 danielk1977 Exp $
|
||||
** $Id: prepare.c,v 1.23 2006/01/16 11:29:20 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
|
@ -495,6 +495,7 @@ int sqlite3_prepare(
|
|||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
|
||||
/* Assert that malloc() has not failed */
|
||||
assert( !sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
|
||||
assert( ppStmt );
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.467 2006/01/13 06:33:24 danielk1977 Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.468 2006/01/16 11:29:20 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
|
@ -1754,7 +1754,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
|
|||
#endif
|
||||
|
||||
void sqlite3MallocClearFailed();
|
||||
#ifdef NDEBUG
|
||||
#ifndef SQLITE_MEMDEBUG
|
||||
#define sqlite3MallocDisallow()
|
||||
#define sqlite3MallocAllow()
|
||||
#else
|
||||
|
|
|
@ -156,7 +156,8 @@ int sqlite3_step(sqlite3_stmt *pStmt){
|
|||
sqlite3 *db;
|
||||
int rc;
|
||||
|
||||
assert(!sqlite3ThreadDataReadOnly()->mallocFailed);
|
||||
/* Assert that malloc() has not failed */
|
||||
assert( !sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
|
||||
if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_MISUSE;
|
||||
|
|
Loading…
Reference in New Issue