summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c210
1 files changed, 167 insertions, 43 deletions
diff --git a/src/main.c b/src/main.c
index 39f6042..cea7282 100644
--- a/src/main.c
+++ b/src/main.c
@@ -117,6 +117,9 @@ char *sqlite3_data_directory = 0;
int sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
+#ifdef SQLITE_EXTRA_INIT
+ int bRunExtraInit = 0; /* Extra initialization needed */
+#endif
#ifdef SQLITE_OMIT_WSD
rc = sqlite3_wsd_init(4096, 24);
@@ -132,13 +135,6 @@ int sqlite3_initialize(void){
*/
if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
-#ifdef SQLITE_ENABLE_SQLLOG
- {
- extern void sqlite3_init_sqllog(void);
- sqlite3_init_sqllog();
- }
-#endif
-
/* Make sure the mutex subsystem is initialized. If unable to
** initialize the mutex subsystem, return early with the error.
** If the system is so sick that we are unable to allocate a mutex,
@@ -214,6 +210,9 @@ int sqlite3_initialize(void){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
sqlite3GlobalConfig.isInit = 1;
+#ifdef SQLITE_EXTRA_INIT
+ bRunExtraInit = 1;
+#endif
}
sqlite3GlobalConfig.inProgress = 0;
}
@@ -254,7 +253,7 @@ int sqlite3_initialize(void){
** compile-time option.
*/
#ifdef SQLITE_EXTRA_INIT
- if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
+ if( bRunExtraInit ){
int SQLITE_EXTRA_INIT(const char*);
rc = SQLITE_EXTRA_INIT(0);
}
@@ -442,8 +441,8 @@ int sqlite3_config(int op, ...){
memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
}else{
/* The heap pointer is not NULL, then install one of the
- ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
- ** ENABLE_MEMSYS5 is defined, return an error.
+ ** mem5.c/mem3.c methods. The enclosing #if guarantees at
+ ** least one of these methods is currently enabled.
*/
#ifdef SQLITE_ENABLE_MEMSYS3
sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
@@ -462,7 +461,7 @@ int sqlite3_config(int op, ...){
break;
}
- /* Record a pointer to the logger funcction and its first argument.
+ /* Record a pointer to the logger function and its first argument.
** The default is NULL. Logging is disabled if the function pointer is
** NULL.
*/
@@ -509,6 +508,13 @@ int sqlite3_config(int op, ...){
break;
}
+#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
+ case SQLITE_CONFIG_WIN32_HEAPSIZE: {
+ sqlite3GlobalConfig.nHeap = va_arg(ap, int);
+ break;
+ }
+#endif
+
default: {
rc = SQLITE_ERROR;
break;
@@ -575,7 +581,8 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
db->lookaside.bEnabled = 1;
db->lookaside.bMalloced = pBuf==0 ?1:0;
}else{
- db->lookaside.pEnd = 0;
+ db->lookaside.pStart = db;
+ db->lookaside.pEnd = db;
db->lookaside.bEnabled = 0;
db->lookaside.bMalloced = 0;
}
@@ -701,7 +708,7 @@ static int binCollFunc(
/*
** Another built-in collating sequence: NOCASE.
**
-** This collating sequence is intended to be used for "case independant
+** This collating sequence is intended to be used for "case independent
** comparison". SQLite's knowledge of upper and lower case equivalents
** extends only to the 26 characters used in the English language.
**
@@ -793,6 +800,7 @@ static void disconnectAllVtab(sqlite3 *db){
}
}
}
+ sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
@@ -819,6 +827,8 @@ static int connectionIsBusy(sqlite3 *db){
*/
static int sqlite3Close(sqlite3 *db, int forceZombie){
if( !db ){
+ /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or
+ ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */
return SQLITE_OK;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
@@ -973,9 +983,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
#endif
sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
- if( db->pErr ){
- sqlite3ValueFree(db->pErr);
- }
+ sqlite3ValueFree(db->pErr);
sqlite3CloseExtensions(db);
db->magic = SQLITE_MAGIC_ERROR;
@@ -1024,7 +1032,6 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
inTrans = 1;
}
sqlite3BtreeRollback(p, tripCode);
- db->aDb[i].inTrans = 0;
}
}
sqlite3VtabRollback(db);
@@ -1038,6 +1045,8 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
+ db->nDeferredImmCons = 0;
+ db->flags &= ~SQLITE_DeferFKs;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -1049,8 +1058,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
- defined(SQLITE_DEBUG_OS_TRACE)
+#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST)
const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
@@ -1064,6 +1072,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break;
+ case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
@@ -1071,6 +1080,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
+ case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
@@ -1083,7 +1093,6 @@ const char *sqlite3ErrName(int rc){
case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
- case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break;
case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
case SQLITE_IOERR_CHECKRESERVEDLOCK:
@@ -1098,6 +1107,8 @@ const char *sqlite3ErrName(int rc){
case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
+ case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break;
+ case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
@@ -1106,6 +1117,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break;
case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break;
+ case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
@@ -1124,6 +1136,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
case SQLITE_CONSTRAINT_FUNCTION:
zName = "SQLITE_CONSTRAINT_FUNCTION"; break;
+ case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
@@ -1137,6 +1150,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_NOTICE_RECOVER_ROLLBACK:
zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
+ case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
}
}
@@ -1297,7 +1311,7 @@ void sqlite3_progress_handler(
sqlite3_mutex_enter(db->mutex);
if( nOps>0 ){
db->xProgress = xProgress;
- db->nProgressOps = nOps;
+ db->nProgressOps = (unsigned)nOps;
db->pProgressArg = pArg;
}else{
db->xProgress = 0;
@@ -1350,6 +1364,7 @@ int sqlite3CreateFunc(
){
FuncDef *p;
int nName;
+ int extraFlags;
assert( sqlite3_mutex_held(db->mutex) );
if( zFunctionName==0 ||
@@ -1360,6 +1375,10 @@ int sqlite3CreateFunc(
(255<(nName = sqlite3Strlen30( zFunctionName))) ){
return SQLITE_MISUSE_BKPT;
}
+
+ assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
+ extraFlags = enc & SQLITE_DETERMINISTIC;
+ enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
#ifndef SQLITE_OMIT_UTF16
/* If SQLITE_UTF16 is specified as the encoding type, transform this
@@ -1373,10 +1392,10 @@ int sqlite3CreateFunc(
enc = SQLITE_UTF16NATIVE;
}else if( enc==SQLITE_ANY ){
int rc;
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
pUserData, xFunc, xStep, xFinal, pDestructor);
if( rc==SQLITE_OK ){
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
pUserData, xFunc, xStep, xFinal, pDestructor);
}
if( rc!=SQLITE_OK ){
@@ -1394,8 +1413,8 @@ int sqlite3CreateFunc(
** operation to continue but invalidate all precompiled statements.
*/
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
- if( p && p->iPrefEnc==enc && p->nArg==nArg ){
- if( db->activeVdbeCnt ){
+ if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
+ if( db->nVdbeActive ){
sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
@@ -1419,7 +1438,8 @@ int sqlite3CreateFunc(
pDestructor->nRef++;
}
p->pDestructor = pDestructor;
- p->flags = 0;
+ p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
+ testcase( p->funcFlags & SQLITE_DETERMINISTIC );
p->xFunc = xFunc;
p->xStep = xStep;
p->xFinalize = xFinal;
@@ -1849,6 +1869,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
if( db->mallocFailed ){
z = sqlite3ErrStr(SQLITE_NOMEM);
}else{
+ testcase( db->pErr==0 );
z = (char*)sqlite3_value_text(db->pErr);
assert( !db->mallocFailed );
if( z==0 ){
@@ -1890,8 +1911,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
}else{
z = sqlite3_value_text16(db->pErr);
if( z==0 ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3Error(db, db->errCode, sqlite3ErrStr(db->errCode));
z = sqlite3_value_text16(db->pErr);
}
/* A malloc() may have failed within the call to sqlite3_value_text16()
@@ -1939,6 +1959,32 @@ const char *sqlite3_errstr(int rc){
}
/*
+** Invalidate all cached KeyInfo objects for database connection "db"
+*/
+static void invalidateCachedKeyInfo(sqlite3 *db){
+ Db *pDb; /* A single database */
+ int iDb; /* The database index number */
+ HashElem *k; /* For looping over tables in pDb */
+ Table *pTab; /* A table in the database */
+ Index *pIdx; /* Each index */
+
+ for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
+ if( pDb->pBt==0 ) continue;
+ sqlite3BtreeEnter(pDb->pBt);
+ for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->pKeyInfo && pIdx->pKeyInfo->db==db ){
+ sqlite3KeyInfoUnref(pIdx->pKeyInfo);
+ pIdx->pKeyInfo = 0;
+ }
+ }
+ }
+ sqlite3BtreeLeave(pDb->pBt);
+ }
+}
+
+/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
*/
@@ -1976,12 +2022,13 @@ static int createCollation(
*/
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
- if( db->activeVdbeCnt ){
+ if( db->nVdbeActive ){
sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
sqlite3ExpirePreparedStatements(db);
+ invalidateCachedKeyInfo(db);
/* If collation sequence pColl was created directly by a call to
** sqlite3_create_collation, and not generated by synthCollSeq(),
@@ -2030,7 +2077,7 @@ static const int aHardLimit[] = {
SQLITE_MAX_FUNCTION_ARG,
SQLITE_MAX_ATTACHED,
SQLITE_MAX_LIKE_PATTERN_LENGTH,
- SQLITE_MAX_VARIABLE_NUMBER,
+ SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
SQLITE_MAX_TRIGGER_DEPTH,
};
@@ -2055,8 +2102,8 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
#endif
-#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62
-# error SQLITE_MAX_ATTACHED must be between 0 and 62
+#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
+# error SQLITE_MAX_ATTACHED must be between 0 and 125
#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
@@ -2174,20 +2221,20 @@ int sqlite3ParseUri(
zFile = sqlite3_malloc(nByte);
if( !zFile ) return SQLITE_NOMEM;
+ iIn = 5;
+#ifndef SQLITE_ALLOW_URI_AUTHORITY
/* Discard the scheme and authority segments of the URI. */
if( zUri[5]=='/' && zUri[6]=='/' ){
iIn = 7;
while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;
-
if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
*pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s",
iIn-7, &zUri[7]);
rc = SQLITE_ERROR;
goto parse_uri_out;
}
- }else{
- iIn = 5;
}
+#endif
/* Copy the filename and any query parameters into the zFile buffer.
** Decode %HH escape codes along the way.
@@ -2451,7 +2498,10 @@ static int openDatabase(
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
- db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
+ db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
+ | SQLITE_AutoIndex
+#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
@@ -2575,8 +2625,6 @@ static int openDatabase(
}
#endif
- sqlite3Error(db, rc, 0);
-
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
@@ -2587,6 +2635,8 @@ static int openDatabase(
SQLITE_DEFAULT_LOCKING_MODE);
#endif
+ if( rc ) sqlite3Error(db, rc, 0);
+
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
@@ -2791,8 +2841,6 @@ int sqlite3_global_recover(void){
** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** 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;
@@ -3048,7 +3096,7 @@ int sqlite3_test_control(int op, ...){
** to the xRandomness method of the default VFS.
*/
case SQLITE_TESTCTRL_PRNG_RESET: {
- sqlite3PrngResetState();
+ sqlite3_randomness(0,0);
break;
}
@@ -3068,6 +3116,28 @@ int sqlite3_test_control(int op, ...){
}
/*
+ ** sqlite3_test_control(FAULT_INSTALL, xCallback)
+ **
+ ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called,
+ ** if xCallback is not NULL.
+ **
+ ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0)
+ ** is called immediately after installing the new callback and the return
+ ** value from sqlite3FaultSim(0) becomes the return from
+ ** sqlite3_test_control().
+ */
+ case SQLITE_TESTCTRL_FAULT_INSTALL: {
+ /* MSVC is picky about pulling func ptrs from va lists.
+ ** http://support.microsoft.com/kb/47961
+ ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
+ */
+ typedef int(*TESTCALLBACKFUNC_t)(int);
+ sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
+ rc = sqlite3FaultSim(0);
+ break;
+ }
+
+ /*
** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
**
** Register hooks to call to indicate which malloc() failures
@@ -3158,6 +3228,22 @@ int sqlite3_test_control(int op, ...){
break;
}
+ /*
+ ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER);
+ **
+ ** The integer returned reveals the byte-order of the computer on which
+ ** SQLite is running:
+ **
+ ** 1 big-endian, determined at run-time
+ ** 10 little-endian, determined at run-time
+ ** 432101 big-endian, determined at compile-time
+ ** 123410 little-endian, determined at compile-time
+ */
+ case SQLITE_TESTCTRL_BYTEORDER: {
+ rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN;
+ break;
+ }
+
/* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
**
** Set the nReserve size to N for the main database on the database
@@ -3248,6 +3334,44 @@ int sqlite3_test_control(int op, ...){
}
#endif
+ /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
+ **
+ ** Set or clear a flag that indicates that the database file is always well-
+ ** formed and never corrupt. This flag is clear by default, indicating that
+ ** database files might have arbitrary corruption. Setting the flag during
+ ** testing causes certain assert() statements in the code to be activated
+ ** that demonstrat invariants on well-formed database files.
+ */
+ case SQLITE_TESTCTRL_NEVER_CORRUPT: {
+ sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
+ break;
+ }
+
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
+ **
+ ** Set the VDBE coverage callback function to xCallback with context
+ ** pointer ptr.
+ */
+ case SQLITE_TESTCTRL_VDBE_COVERAGE: {
+#ifdef SQLITE_VDBE_COVERAGE
+ typedef void (*branch_callback)(void*,int,u8,u8);
+ sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
+ sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
+#endif
+ break;
+ }
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);
+ **
+ ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if
+ ** not.
+ */
+ case SQLITE_TESTCTRL_ISINIT: {
+ if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
+ break;
+ }
+
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
@@ -3296,7 +3420,7 @@ sqlite3_int64 sqlite3_uri_int64(
){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
sqlite3_int64 v;
- if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){
+ if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){
bDflt = v;
}
return bDflt;
@@ -3332,5 +3456,5 @@ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
*/
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
- return pBt ? sqlite3PagerIsreadonly(sqlite3BtreePager(pBt)) : -1;
+ return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}