Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: third_party/sqlite/src/src/main.c

Issue 5626002: Update sqlite to 3.7.3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/third_party/sqlite/src
Patch Set: Remove misc change. Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/src/src/loadext.c ('k') | third_party/sqlite/src/src/malloc.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/src/src/main.c
diff --git a/third_party/sqlite/src/src/main.c b/third_party/sqlite/src/src/main.c
index 370462803ebb08fff75898b88d103eca100bdd11..3b1ddaf9cc35388978dd3af748e97390f325c476 100644
--- a/third_party/sqlite/src/src/main.c
+++ b/third_party/sqlite/src/src/main.c
@@ -17,7 +17,7 @@
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_FTS3
-# include "../../ext/fts3/fts3.h"
+# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE
# include "rtree.h"
@@ -26,15 +26,33 @@
# include "sqliteicu.h"
#endif
-/*
-** The version of the library
-*/
#ifndef SQLITE_AMALGAMATION
+/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
+** contains the text of SQLITE_VERSION macro.
+*/
const char sqlite3_version[] = SQLITE_VERSION;
#endif
+
+/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
+** a pointer to the to the sqlite3_version[] string constant.
+*/
const char *sqlite3_libversion(void){ return sqlite3_version; }
+
+/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
+** pointer to a string constant whose value is the same as the
+** SQLITE_SOURCE_ID C preprocessor macro.
+*/
const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+
+/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
+** returns an integer equal to SQLITE_VERSION_NUMBER.
+*/
int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+
+/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns
+** zero if and only if SQLite was compiled mutexing code omitted due to
+** the SQLITE_THREADSAFE compile-time option being set to 0.
+*/
int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
@@ -155,6 +173,13 @@ int sqlite3_initialize(void){
** sqlite3_initialize(). The recursive calls normally come through
** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
** recursive calls might also be possible.
+ **
+ ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls
+ ** to the xInit method, so the xInit method need not be threadsafe.
+ **
+ ** The following mutex is what serializes access to the appdef pcache xInit
+ ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the
+ ** call to sqlite3PcacheInitialize().
*/
sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
@@ -257,7 +282,7 @@ int sqlite3_config(int op, ...){
/* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
** the SQLite library is in use. */
- if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE;
+ if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;
va_start(ap, op);
switch( op ){
@@ -265,7 +290,7 @@ int sqlite3_config(int op, ...){
/* Mutex configuration options are only available in a threadsafe
** compile.
*/
-#if SQLITE_THREADSAFE
+#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
case SQLITE_CONFIG_SINGLETHREAD: {
/* Disable all mutexing */
sqlite3GlobalConfig.bCoreMutex = 0;
@@ -378,6 +403,21 @@ int sqlite3_config(int op, ...){
sqlite3GlobalConfig.nLookaside = va_arg(ap, int);
break;
}
+
+ /* Record a pointer to the logger funcction and its first argument.
+ ** The default is NULL. Logging is disabled if the function pointer is
+ ** NULL.
+ */
+ case SQLITE_CONFIG_LOG: {
+ /* MSVC is picky about pulling func ptrs from va lists.
+ ** http://support.microsoft.com/kb/47961
+ ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*));
+ */
+ typedef void(*LOGFUNC_t)(void*,int,const char*);
+ sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
+ sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
+ break;
+ }
default: {
rc = SQLITE_ERROR;
@@ -420,12 +460,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
sz = 0;
pStart = 0;
}else if( pBuf==0 ){
- sz = ROUND8(sz);
+ sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
sqlite3BeginBenignMalloc();
- pStart = sqlite3Malloc( sz*cnt );
+ pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */
sqlite3EndBenignMalloc();
}else{
- sz = ROUNDDOWN8(sz);
+ sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
pStart = pBuf;
}
db->lookaside.pStart = pStart;
@@ -468,14 +508,14 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
va_start(ap, op);
switch( op ){
case SQLITE_DBCONFIG_LOOKASIDE: {
- void *pBuf = va_arg(ap, void*);
- int sz = va_arg(ap, int);
- int cnt = va_arg(ap, int);
+ void *pBuf = va_arg(ap, void*); /* IMP: R-21112-12275 */
+ int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
+ int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
default: {
- rc = SQLITE_ERROR;
+ rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
break;
}
}
@@ -581,17 +621,34 @@ void sqlite3CloseSavepoints(sqlite3 *db){
}
/*
+** Invoke the destructor function associated with FuncDef p, if any. Except,
+** if this is not the last copy of the function, do not invoke it. Multiple
+** copies of a single function are created when create_function() is called
+** with SQLITE_ANY as the encoding.
+*/
+static void functionDestroy(sqlite3 *db, FuncDef *p){
+ FuncDestructor *pDestructor = p->pDestructor;
+ if( pDestructor ){
+ pDestructor->nRef--;
+ if( pDestructor->nRef==0 ){
+ pDestructor->xDestroy(pDestructor->pUserData);
+ sqlite3DbFree(db, pDestructor);
+ }
+ }
+}
+
+/*
** Close an existing SQLite database
*/
int sqlite3_close(sqlite3 *db){
- HashElem *i;
+ HashElem *i; /* Hash table iterator */
int j;
if( !db ){
return SQLITE_OK;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE;
+ return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
@@ -652,6 +709,7 @@ int sqlite3_close(sqlite3 *db){
for(p=db->aFunc.a[j]; p; p=pHash){
pHash = p->pHash;
while( p ){
+ functionDestroy(db, p);
pNext = p->pNext;
sqlite3DbFree(db, p);
p = pNext;
@@ -731,6 +789,9 @@ void sqlite3RollbackAll(sqlite3 *db){
sqlite3ResetInternalSchema(db, 0);
}
+ /* Any deferred constraint violations have now been resolved. */
+ db->nDeferredCons = 0;
+
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
db->xRollbackCallback(db->pRollbackArg);
@@ -758,7 +819,7 @@ const char *sqlite3ErrStr(int rc){
/* SQLITE_NOTFOUND */ 0,
/* SQLITE_FULL */ "database or disk is full",
/* SQLITE_CANTOPEN */ "unable to open database file",
- /* SQLITE_PROTOCOL */ 0,
+ /* SQLITE_PROTOCOL */ "locking protocol",
/* SQLITE_EMPTY */ "table contains no data",
/* SQLITE_SCHEMA */ "database schema has changed",
/* SQLITE_TOOBIG */ "string or blob too big",
@@ -923,7 +984,8 @@ int sqlite3CreateFunc(
void *pUserData,
void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*)
+ void (*xFinal)(sqlite3_context*),
+ FuncDestructor *pDestructor
){
FuncDef *p;
int nName;
@@ -935,7 +997,7 @@ int sqlite3CreateFunc(
(!xFunc && (!xFinal && xStep)) ||
(nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
(255<(nName = sqlite3Strlen30( zFunctionName))) ){
- return SQLITE_MISUSE;
+ return SQLITE_MISUSE_BKPT;
}
#ifndef SQLITE_OMIT_UTF16
@@ -951,10 +1013,10 @@ int sqlite3CreateFunc(
}else if( enc==SQLITE_ANY ){
int rc;
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
- pUserData, xFunc, xStep, xFinal);
+ pUserData, xFunc, xStep, xFinal, pDestructor);
if( rc==SQLITE_OK ){
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
- pUserData, xFunc, xStep, xFinal);
+ pUserData, xFunc, xStep, xFinal, pDestructor);
}
if( rc!=SQLITE_OK ){
return rc;
@@ -987,6 +1049,15 @@ int sqlite3CreateFunc(
if( !p ){
return SQLITE_NOMEM;
}
+
+ /* If an older version of the function with a configured destructor is
+ ** being replaced invoke the destructor function here. */
+ functionDestroy(db, p);
+
+ if( pDestructor ){
+ pDestructor->nRef++;
+ }
+ p->pDestructor = pDestructor;
p->flags = 0;
p->xFunc = xFunc;
p->xStep = xStep;
@@ -1001,7 +1072,7 @@ int sqlite3CreateFunc(
*/
int sqlite3_create_function(
sqlite3 *db,
- const char *zFunctionName,
+ const char *zFunc,
int nArg,
int enc,
void *p,
@@ -1009,9 +1080,41 @@ int sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value **),
void (*xFinal)(sqlite3_context*)
){
- int rc;
+ return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
+ xFinal, 0);
+}
+
+int sqlite3_create_function_v2(
+ sqlite3 *db,
+ const char *zFunc,
+ int nArg,
+ int enc,
+ void *p,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+ void (*xFinal)(sqlite3_context*),
+ void (*xDestroy)(void *)
+){
+ int rc = SQLITE_ERROR;
+ FuncDestructor *pArg = 0;
sqlite3_mutex_enter(db->mutex);
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal);
+ if( xDestroy ){
+ pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
+ if( !pArg ){
+ xDestroy(p);
+ goto out;
+ }
+ pArg->xDestroy = xDestroy;
+ pArg->pUserData = p;
+ }
+ rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg);
+ if( pArg && pArg->nRef==0 ){
+ assert( rc!=SQLITE_OK );
+ xDestroy(p);
+ sqlite3DbFree(db, pArg);
+ }
+
+ out:
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -1032,8 +1135,8 @@ int sqlite3_create_function16(
char *zFunc8;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
- zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
- rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
+ zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
+ rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
sqlite3DbFree(db, zFunc8);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -1064,7 +1167,7 @@ int sqlite3_overload_function(
sqlite3_mutex_enter(db->mutex);
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
- 0, sqlite3InvalidFunction, 0, 0);
+ 0, sqlite3InvalidFunction, 0, 0, 0);
}
rc = sqlite3ApiExit(db, SQLITE_OK);
sqlite3_mutex_leave(db->mutex);
@@ -1168,6 +1271,139 @@ void *sqlite3_rollback_hook(
return pRet;
}
+#ifndef SQLITE_OMIT_WAL
+/*
+** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
+** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
+** is greater than sqlite3.pWalArg cast to an integer (the value configured by
+** wal_autocheckpoint()).
+*/
+int sqlite3WalDefaultHook(
+ void *pClientData, /* Argument */
+ sqlite3 *db, /* Connection */
+ const char *zDb, /* Database */
+ int nFrame /* Size of WAL */
+){
+ if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){
+ sqlite3BeginBenignMalloc();
+ sqlite3_wal_checkpoint(db, zDb);
+ sqlite3EndBenignMalloc();
+ }
+ return SQLITE_OK;
+}
+#endif /* SQLITE_OMIT_WAL */
+
+/*
+** Configure an sqlite3_wal_hook() callback to automatically checkpoint
+** a database after committing a transaction if there are nFrame or
+** more frames in the log file. Passing zero or a negative value as the
+** nFrame parameter disables automatic checkpoints entirely.
+**
+** The callback registered by this function replaces any existing callback
+** registered using sqlite3_wal_hook(). Likewise, registering a callback
+** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
+** configured by this function.
+*/
+int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+#ifdef SQLITE_OMIT_WAL
+ UNUSED_PARAMETER(db);
+ UNUSED_PARAMETER(nFrame);
+#else
+ if( nFrame>0 ){
+ sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
+ }else{
+ sqlite3_wal_hook(db, 0, 0);
+ }
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** Register a callback to be invoked each time a transaction is written
+** into the write-ahead-log by this database connection.
+*/
+void *sqlite3_wal_hook(
+ sqlite3 *db, /* Attach the hook to this db handle */
+ int(*xCallback)(void *, sqlite3*, const char*, int),
+ void *pArg /* First argument passed to xCallback() */
+){
+#ifndef SQLITE_OMIT_WAL
+ void *pRet;
+ sqlite3_mutex_enter(db->mutex);
+ pRet = db->pWalArg;
+ db->xWalCallback = xCallback;
+ db->pWalArg = pArg;
+ sqlite3_mutex_leave(db->mutex);
+ return pRet;
+#else
+ return 0;
+#endif
+}
+
+
+/*
+** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
+** to contains a zero-length string, all attached databases are
+** checkpointed.
+*/
+int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+#ifdef SQLITE_OMIT_WAL
+ return SQLITE_OK;
+#else
+ int rc; /* Return code */
+ int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
+
+ sqlite3_mutex_enter(db->mutex);
+ if( zDb && zDb[0] ){
+ iDb = sqlite3FindDbName(db, zDb);
+ }
+ if( iDb<0 ){
+ rc = SQLITE_ERROR;
+ sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb);
+ }else{
+ rc = sqlite3Checkpoint(db, iDb);
+ sqlite3Error(db, rc, 0);
+ }
+ rc = sqlite3ApiExit(db, rc);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+#endif
+}
+
+#ifndef SQLITE_OMIT_WAL
+/*
+** Run a checkpoint on database iDb. This is a no-op if database iDb is
+** not currently open in WAL mode.
+**
+** If a transaction is open on the database being checkpointed, this
+** function returns SQLITE_LOCKED and a checkpoint is not attempted. If
+** an error occurs while running the checkpoint, an SQLite error code is
+** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK.
+**
+** The mutex on database handle db should be held by the caller. The mutex
+** associated with the specific b-tree being checkpointed is taken by
+** this function while the checkpoint is running.
+**
+** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are
+** checkpointed. If an error is encountered it is returned immediately -
+** no attempt is made to checkpoint any remaining databases.
+*/
+int sqlite3Checkpoint(sqlite3 *db, int iDb){
+ int rc = SQLITE_OK; /* Return code */
+ int i; /* Used to iterate through attached dbs */
+
+ assert( sqlite3_mutex_held(db->mutex) );
+
+ for(i=0; i<db->nDb && rc==SQLITE_OK; i++){
+ if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){
+ rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt);
+ }
+ }
+
+ return rc;
+}
+#endif /* SQLITE_OMIT_WAL */
+
/*
** This function returns true if main-memory should be used instead of
** a temporary file for transient pager files and statement journals.
@@ -1203,60 +1439,6 @@ int sqlite3TempInMemory(const sqlite3 *db){
}
/*
-** This routine is called to create a connection to a database BTree
-** driver. If zFilename is the name of a file, then that file is
-** opened and used. If zFilename is the magic name ":memory:" then
-** the database is stored in memory (and is thus forgotten as soon as
-** the connection is closed.) If zFilename is NULL then the database
-** is a "virtual" database for transient use only and is deleted as
-** soon as the connection is closed.
-**
-** A virtual database can be either a disk file (that is automatically
-** deleted when the file is closed) or it an be held entirely in memory.
-** The sqlite3TempInMemory() function is used to determine which.
-*/
-int sqlite3BtreeFactory(
- const sqlite3 *db, /* Main database when opening aux otherwise 0 */
- const char *zFilename, /* Name of the file containing the BTree database */
- int omitJournal, /* if TRUE then do not journal this file */
- int nCache, /* How many pages in the page cache */
- int vfsFlags, /* Flags passed through to vfsOpen */
- Btree **ppBtree /* Pointer to new Btree object written here */
-){
- int btFlags = 0;
- int rc;
-
- assert( sqlite3_mutex_held(db->mutex) );
- assert( ppBtree != 0);
- if( omitJournal ){
- btFlags |= BTREE_OMIT_JOURNAL;
- }
- if( db->flags & SQLITE_NoReadlock ){
- btFlags |= BTREE_NO_READLOCK;
- }
-#ifndef SQLITE_OMIT_MEMORYDB
- if( zFilename==0 && sqlite3TempInMemory(db) ){
- zFilename = ":memory:";
- }
-#endif
-
- if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (zFilename==0 || *zFilename==0) ){
- vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
- }
- rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
-
- /* If the B-Tree was successfully opened, set the pager-cache size to the
- ** default value. Except, if the call to BtreeOpen() returned a handle
- ** open on an existing shared pager-cache, do not change the pager-cache
- ** size.
- */
- if( rc==SQLITE_OK && 0==sqlite3BtreeSchema(*ppBtree, 0, 0) ){
- sqlite3BtreeSetCacheSize(*ppBtree, nCache);
- }
- return rc;
-}
-
-/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
@@ -1266,7 +1448,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
return sqlite3ErrStr(SQLITE_NOMEM);
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
- return sqlite3ErrStr(SQLITE_MISUSE);
+ return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
}
sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
@@ -1335,7 +1517,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
*/
int sqlite3_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE;
+ return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
return SQLITE_NOMEM;
@@ -1344,7 +1526,7 @@ int sqlite3_errcode(sqlite3 *db){
}
int sqlite3_extended_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE;
+ return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
return SQLITE_NOMEM;
@@ -1382,7 +1564,7 @@ static int createCollation(
enc2 = SQLITE_UTF16NATIVE;
}
if( enc2<SQLITE_UTF8 || enc2>SQLITE_UTF16BE ){
- return SQLITE_MISUSE;
+ return SQLITE_MISUSE_BKPT;
}
/* Check if this call is removing or replacing an existing collation
@@ -1478,9 +1660,6 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
#endif
-#if SQLITE_MAX_VARIABLE_NUMBER<1
-# error SQLITE_MAX_VARIABLE_NUMBER must be at least 1
-#endif
#if SQLITE_MAX_COLUMN>32767
# error SQLITE_MAX_COLUMN must not exceed 32767
#endif
@@ -1501,17 +1680,39 @@ static const int aHardLimit[] = {
*/
int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
+
+
+ /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
+ ** there is a hard upper bound set at compile-time by a C preprocessor
+ ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
+ ** "_MAX_".)
+ */
+ assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
+ assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
+ assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
+ assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
+ assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
+ assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
+ assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
+ assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
+ assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
+ SQLITE_MAX_LIKE_PATTERN_LENGTH );
+ assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
+ assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
+ assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) );
+
+
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
return -1;
}
oldLimit = db->aLimit[limitId];
- if( newLimit>=0 ){
+ if( newLimit>=0 ){ /* IMP: R-52476-28732 */
if( newLimit>aHardLimit[limitId] ){
- newLimit = aHardLimit[limitId];
+ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
}
db->aLimit[limitId] = newLimit;
}
- return oldLimit;
+ return oldLimit; /* IMP: R-53341-35419 */
}
/*
@@ -1535,6 +1736,24 @@ static int openDatabase(
if( rc ) return rc;
#endif
+ /* Only allow sensible combinations of bits in the flags argument.
+ ** Throw an error if any non-sense combination is used. If we
+ ** do not block illegal combinations here, it could trigger
+ ** assert() statements in deeper layers. Sensible combinations
+ ** are:
+ **
+ ** 1: SQLITE_OPEN_READONLY
+ ** 2: SQLITE_OPEN_READWRITE
+ ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
+ */
+ assert( SQLITE_OPEN_READONLY == 0x01 );
+ assert( SQLITE_OPEN_READWRITE == 0x02 );
+ assert( SQLITE_OPEN_CREATE == 0x04 );
+ testcase( (1<<(flags&7))==0x02 ); /* READONLY */
+ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
+ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
+ if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE;
+
if( sqlite3GlobalConfig.bCoreMutex==0 ){
isThreadsafe = 0;
}else if( flags & SQLITE_OPEN_NOMUTEX ){
@@ -1568,7 +1787,8 @@ static int openDatabase(
SQLITE_OPEN_SUBJOURNAL |
SQLITE_OPEN_MASTER_JOURNAL |
SQLITE_OPEN_NOMUTEX |
- SQLITE_OPEN_FULLMUTEX
+ SQLITE_OPEN_FULLMUTEX |
+ SQLITE_OPEN_WAL
);
/* Allocate the sqlite data structure */
@@ -1593,7 +1813,7 @@ static int openDatabase(
db->autoCommit = 1;
db->nextAutovac = -1;
db->nextPagesize = 0;
- db->flags |= SQLITE_ShortColNames
+ db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
@@ -1640,9 +1860,8 @@ static int openDatabase(
/* Open the backend database driver */
db->openFlags = flags;
- rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE,
- flags | SQLITE_OPEN_MAIN_DB,
- &db->aDb[0].pBt);
+ rc = sqlite3BtreeOpen(zFilename, db, &db->aDb[0].pBt, 0,
+ flags | SQLITE_OPEN_MAIN_DB);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_IOERR_NOMEM ){
rc = SQLITE_NOMEM;
@@ -1731,6 +1950,8 @@ static int openDatabase(
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
+ sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
+
opendb_out:
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
@@ -1858,7 +2079,7 @@ int sqlite3_create_collation16(
char *zName8;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
- zName8 = sqlite3Utf16to8(db, zName, -1);
+ zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
if( zName8 ){
rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
sqlite3DbFree(db, zName8);
@@ -1905,7 +2126,6 @@ int sqlite3_collation_needed16(
}
#endif /* SQLITE_OMIT_UTF16 */
-#ifndef SQLITE_OMIT_GLOBALRECOVER
#ifndef SQLITE_OMIT_DEPRECATED
/*
** This function is now an anachronism. It used to be used to recover from a
@@ -1915,7 +2135,6 @@ int sqlite3_global_recover(void){
return SQLITE_OK;
}
#endif
-#endif
/*
** Test to see whether or not the database connection is in autocommit
@@ -1929,16 +2148,39 @@ 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.
+** The following routines are subtitutes for constants SQLITE_CORRUPT,
+** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
+** constants. They server two purposes:
+**
+** 1. Serve as a convenient place to set a breakpoint in a debugger
+** to detect when version error conditions occurs.
+**
+** 2. Invoke sqlite3_log() to provide the source code location where
+** a low-level error is first detected.
*/
-int sqlite3Corrupt(void){
+int sqlite3CorruptError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ sqlite3_log(SQLITE_CORRUPT,
+ "database corruption at line %d of [%.10s]",
+ lineno, 20+sqlite3_sourceid());
return SQLITE_CORRUPT;
}
-#endif
+int sqlite3MisuseError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ sqlite3_log(SQLITE_MISUSE,
+ "misuse at line %d of [%.10s]",
+ lineno, 20+sqlite3_sourceid());
+ return SQLITE_MISUSE;
+}
+int sqlite3CantopenError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ sqlite3_log(SQLITE_CANTOPEN,
+ "cannot open file at line %d of [%.10s]",
+ lineno, 20+sqlite3_sourceid());
+ return SQLITE_CANTOPEN;
+}
+
#ifndef SQLITE_OMIT_DEPRECATED
/*
@@ -1982,7 +2224,6 @@ int sqlite3_table_column_metadata(
/* Ensure the database schema has been loaded */
sqlite3_mutex_enter(db->mutex);
- (void)sqlite3SafetyOn(db);
sqlite3BtreeEnterAll(db);
rc = sqlite3Init(db, &zErrMsg);
if( SQLITE_OK!=rc ){
@@ -2041,7 +2282,6 @@ int sqlite3_table_column_metadata(
error_out:
sqlite3BtreeLeaveAll(db);
- (void)sqlite3SafetyOff(db);
/* Whether the function call succeeded or failed, set the output parameters
** to whatever their local counterparts contain. If an error did occur,
@@ -2209,9 +2449,13 @@ int sqlite3_test_control(int op, ...){
** dileterious behavior.
*/
case SQLITE_TESTCTRL_PENDING_BYTE: {
- unsigned int newVal = va_arg(ap, unsigned int);
- rc = sqlite3PendingByte;
- if( newVal ) sqlite3PendingByte = newVal;
+ rc = PENDING_BYTE;
+#ifndef SQLITE_OMIT_WSD
+ {
+ unsigned int newVal = va_arg(ap, unsigned int);
+ if( newVal ) sqlite3PendingByte = newVal;
+ }
+#endif
break;
}
@@ -2281,6 +2525,65 @@ int sqlite3_test_control(int op, ...){
break;
}
+ /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
+ **
+ ** Enable or disable various optimizations for testing purposes. The
+ ** argument N is a bitmask of optimizations to be disabled. For normal
+ ** operation N should be 0. The idea is that a test program (like the
+ ** SQL Logic Test or SLT test module) can run the same SQL multiple times
+ ** with various optimizations disabled to verify that the same answer
+ ** is obtained in every case.
+ */
+ case SQLITE_TESTCTRL_OPTIMIZATIONS: {
+ sqlite3 *db = va_arg(ap, sqlite3*);
+ int x = va_arg(ap,int);
+ db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
+ break;
+ }
+
+#ifdef SQLITE_N_KEYWORD
+ /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
+ **
+ ** If zWord is a keyword recognized by the parser, then return the
+ ** number of keywords. Or if zWord is not a keyword, return 0.
+ **
+ ** This test feature is only available in the amalgamation since
+ ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite
+ ** is built using separate source files.
+ */
+ case SQLITE_TESTCTRL_ISKEYWORD: {
+ const char *zWord = va_arg(ap, const char*);
+ int n = sqlite3Strlen30(zWord);
+ rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0;
+ break;
+ }
+#endif
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_PGHDRSZ)
+ **
+ ** Return the size of a pcache header in bytes.
+ */
+ case SQLITE_TESTCTRL_PGHDRSZ: {
+ rc = sizeof(PgHdr);
+ break;
+ }
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree);
+ **
+ ** Pass pFree into sqlite3ScratchFree().
+ ** If sz>0 then allocate a scratch buffer into pNew.
+ */
+ case SQLITE_TESTCTRL_SCRATCHMALLOC: {
+ void *pFree, **ppNew;
+ int sz;
+ sz = va_arg(ap, int);
+ ppNew = va_arg(ap, void**);
+ pFree = va_arg(ap, void*);
+ if( sz ) *ppNew = sqlite3ScratchMalloc(sz);
+ sqlite3ScratchFree(pFree);
+ break;
+ }
+
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
« no previous file with comments | « third_party/sqlite/src/src/loadext.c ('k') | third_party/sqlite/src/src/malloc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698