| 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 301808cdcec2cb8b50b64abecf74ab6b392d56d8..03e4f1b928457ba34dacc3ec5bdcae523e86f03d 100644
|
| --- a/third_party/sqlite/src/src/main.c
|
| +++ b/third_party/sqlite/src/src/main.c
|
| @@ -187,7 +187,7 @@ int sqlite3_initialize(void){
|
| sqlite3GlobalConfig.pInitMutex =
|
| sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
|
| if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
|
| - rc = SQLITE_NOMEM;
|
| + rc = SQLITE_NOMEM_BKPT;
|
| }
|
| }
|
| }
|
| @@ -218,7 +218,6 @@ int sqlite3_initialize(void){
|
| */
|
| sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
|
| if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
|
| - FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
| sqlite3GlobalConfig.inProgress = 1;
|
| #ifdef SQLITE_ENABLE_SQLLOG
|
| {
|
| @@ -226,8 +225,8 @@ int sqlite3_initialize(void){
|
| sqlite3_init_sqllog();
|
| }
|
| #endif
|
| - memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
|
| - sqlite3RegisterGlobalFunctions();
|
| + memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
|
| + sqlite3RegisterBuiltinFunctions();
|
| if( sqlite3GlobalConfig.isPCacheInit==0 ){
|
| rc = sqlite3PcacheInitialize();
|
| }
|
| @@ -634,6 +633,11 @@ int sqlite3_config(int op, ...){
|
| break;
|
| }
|
|
|
| + case SQLITE_CONFIG_STMTJRNL_SPILL: {
|
| + sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int);
|
| + break;
|
| + }
|
| +
|
| default: {
|
| rc = SQLITE_ERROR;
|
| break;
|
| @@ -698,12 +702,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
| p = (LookasideSlot*)&((u8*)p)[sz];
|
| }
|
| db->lookaside.pEnd = p;
|
| - db->lookaside.bEnabled = 1;
|
| + db->lookaside.bDisable = 0;
|
| db->lookaside.bMalloced = pBuf==0 ?1:0;
|
| }else{
|
| db->lookaside.pStart = db;
|
| db->lookaside.pEnd = db;
|
| - db->lookaside.bEnabled = 0;
|
| + db->lookaside.bDisable = 1;
|
| db->lookaside.bMalloced = 0;
|
| }
|
| #endif /* SQLITE_OMIT_LOOKASIDE */
|
| @@ -785,6 +789,11 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
| int rc;
|
| va_start(ap, op);
|
| switch( op ){
|
| + case SQLITE_DBCONFIG_MAINDBNAME: {
|
| + db->aDb[0].zDbSName = va_arg(ap,char*);
|
| + rc = SQLITE_OK;
|
| + break;
|
| + }
|
| case SQLITE_DBCONFIG_LOOKASIDE: {
|
| void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
|
| int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
|
| @@ -797,8 +806,11 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
| int op; /* The opcode */
|
| u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */
|
| } aFlagOp[] = {
|
| - { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
| - { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
| + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
| + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
| + { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
| + { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
|
| + { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
|
| };
|
| unsigned int i;
|
| rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
| @@ -958,7 +970,7 @@ void sqlite3CloseSavepoints(sqlite3 *db){
|
| ** with SQLITE_ANY as the encoding.
|
| */
|
| static void functionDestroy(sqlite3 *db, FuncDef *p){
|
| - FuncDestructor *pDestructor = p->pDestructor;
|
| + FuncDestructor *pDestructor = p->u.pDestructor;
|
| if( pDestructor ){
|
| pDestructor->nRef--;
|
| if( pDestructor->nRef==0 ){
|
| @@ -1027,6 +1039,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
|
| return SQLITE_MISUSE_BKPT;
|
| }
|
| sqlite3_mutex_enter(db->mutex);
|
| + if( db->mTrace & SQLITE_TRACE_CLOSE ){
|
| + db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
|
| + }
|
|
|
| /* Force xDisconnect calls on all virtual tables */
|
| disconnectAllVtab(db);
|
| @@ -1140,18 +1155,17 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
| */
|
| sqlite3ConnectionClosed(db);
|
|
|
| - for(j=0; j<ArraySize(db->aFunc.a); j++){
|
| - FuncDef *pNext, *pHash, *p;
|
| - 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;
|
| - }
|
| - }
|
| - }
|
| + for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
|
| + FuncDef *pNext, *p;
|
| + p = sqliteHashData(i);
|
| + do{
|
| + functionDestroy(db, p);
|
| + pNext = p->pNext;
|
| + sqlite3DbFree(db, p);
|
| + p = pNext;
|
| + }while( p );
|
| + }
|
| + sqlite3HashClear(&db->aFunc);
|
| for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
|
| CollSeq *pColl = (CollSeq *)sqliteHashData(i);
|
| /* Invoke any destructors registered for collation sequence user data. */
|
| @@ -1554,7 +1568,7 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
| */
|
| void sqlite3_interrupt(sqlite3 *db){
|
| #ifdef SQLITE_ENABLE_API_ARMOR
|
| - if( !sqlite3SafetyCheckOk(db) ){
|
| + if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){
|
| (void)SQLITE_MISUSE_BKPT;
|
| return;
|
| }
|
| @@ -1575,7 +1589,7 @@ int sqlite3CreateFunc(
|
| int nArg,
|
| int enc,
|
| void *pUserData,
|
| - void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
|
| + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
|
| void (*xStep)(sqlite3_context*,int,sqlite3_value **),
|
| void (*xFinal)(sqlite3_context*),
|
| FuncDestructor *pDestructor
|
| @@ -1586,9 +1600,9 @@ int sqlite3CreateFunc(
|
|
|
| assert( sqlite3_mutex_held(db->mutex) );
|
| if( zFunctionName==0 ||
|
| - (xFunc && (xFinal || xStep)) ||
|
| - (!xFunc && (xFinal && !xStep)) ||
|
| - (!xFunc && (!xFinal && xStep)) ||
|
| + (xSFunc && (xFinal || xStep)) ||
|
| + (!xSFunc && (xFinal && !xStep)) ||
|
| + (!xSFunc && (!xFinal && xStep)) ||
|
| (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
|
| (255<(nName = sqlite3Strlen30( zFunctionName))) ){
|
| return SQLITE_MISUSE_BKPT;
|
| @@ -1611,10 +1625,10 @@ int sqlite3CreateFunc(
|
| }else if( enc==SQLITE_ANY ){
|
| int rc;
|
| rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
|
| - pUserData, xFunc, xStep, xFinal, pDestructor);
|
| + pUserData, xSFunc, xStep, xFinal, pDestructor);
|
| if( rc==SQLITE_OK ){
|
| rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
|
| - pUserData, xFunc, xStep, xFinal, pDestructor);
|
| + pUserData, xSFunc, xStep, xFinal, pDestructor);
|
| }
|
| if( rc!=SQLITE_OK ){
|
| return rc;
|
| @@ -1630,7 +1644,7 @@ int sqlite3CreateFunc(
|
| ** is being overridden/deleted but there are no active VMs, allow the
|
| ** operation to continue but invalidate all precompiled statements.
|
| */
|
| - p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
|
| + p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
|
| if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
|
| if( db->nVdbeActive ){
|
| sqlite3ErrorWithMsg(db, SQLITE_BUSY,
|
| @@ -1642,10 +1656,10 @@ int sqlite3CreateFunc(
|
| }
|
| }
|
|
|
| - p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
|
| + p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
|
| assert(p || db->mallocFailed);
|
| if( !p ){
|
| - return SQLITE_NOMEM;
|
| + return SQLITE_NOMEM_BKPT;
|
| }
|
|
|
| /* If an older version of the function with a configured destructor is
|
| @@ -1655,11 +1669,10 @@ int sqlite3CreateFunc(
|
| if( pDestructor ){
|
| pDestructor->nRef++;
|
| }
|
| - p->pDestructor = pDestructor;
|
| + p->u.pDestructor = pDestructor;
|
| p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
|
| testcase( p->funcFlags & SQLITE_DETERMINISTIC );
|
| - p->xFunc = xFunc;
|
| - p->xStep = xStep;
|
| + p->xSFunc = xSFunc ? xSFunc : xStep;
|
| p->xFinalize = xFinal;
|
| p->pUserData = pUserData;
|
| p->nArg = (u16)nArg;
|
| @@ -1675,11 +1688,11 @@ int sqlite3_create_function(
|
| int nArg,
|
| int enc,
|
| void *p,
|
| - void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
|
| + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
|
| void (*xStep)(sqlite3_context*,int,sqlite3_value **),
|
| void (*xFinal)(sqlite3_context*)
|
| ){
|
| - return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
|
| + return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep,
|
| xFinal, 0);
|
| }
|
|
|
| @@ -1689,7 +1702,7 @@ int sqlite3_create_function_v2(
|
| int nArg,
|
| int enc,
|
| void *p,
|
| - void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
|
| + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
|
| void (*xStep)(sqlite3_context*,int,sqlite3_value **),
|
| void (*xFinal)(sqlite3_context*),
|
| void (*xDestroy)(void *)
|
| @@ -1712,7 +1725,7 @@ int sqlite3_create_function_v2(
|
| pArg->xDestroy = xDestroy;
|
| pArg->pUserData = p;
|
| }
|
| - rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg);
|
| + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg);
|
| if( pArg && pArg->nRef==0 ){
|
| assert( rc!=SQLITE_OK );
|
| xDestroy(p);
|
| @@ -1732,7 +1745,7 @@ int sqlite3_create_function16(
|
| int nArg,
|
| int eTextRep,
|
| void *p,
|
| - void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
| + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
|
| void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
| void (*xFinal)(sqlite3_context*)
|
| ){
|
| @@ -1745,7 +1758,7 @@ int sqlite3_create_function16(
|
| sqlite3_mutex_enter(db->mutex);
|
| assert( !db->mallocFailed );
|
| zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
|
| - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
|
| + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0);
|
| sqlite3DbFree(db, zFunc8);
|
| rc = sqlite3ApiExit(db, rc);
|
| sqlite3_mutex_leave(db->mutex);
|
| @@ -1771,7 +1784,6 @@ int sqlite3_overload_function(
|
| const char *zName,
|
| int nArg
|
| ){
|
| - int nName = sqlite3Strlen30(zName);
|
| int rc = SQLITE_OK;
|
|
|
| #ifdef SQLITE_ENABLE_API_ARMOR
|
| @@ -1780,7 +1792,7 @@ int sqlite3_overload_function(
|
| }
|
| #endif
|
| sqlite3_mutex_enter(db->mutex);
|
| - if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
|
| + if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
|
| rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
|
| 0, sqlite3InvalidFunction, 0, 0, 0);
|
| }
|
| @@ -1798,7 +1810,8 @@ int sqlite3_overload_function(
|
| ** trace is a pointer to a function that is invoked at the start of each
|
| ** SQL statement.
|
| */
|
| -void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
|
| +#ifndef SQLITE_OMIT_DEPRECATED
|
| +void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
|
| void *pOld;
|
|
|
| #ifdef SQLITE_ENABLE_API_ARMOR
|
| @@ -1809,11 +1822,38 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
|
| #endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pOld = db->pTraceArg;
|
| - db->xTrace = xTrace;
|
| + db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
|
| + db->xTrace = (int(*)(u32,void*,void*,void*))xTrace;
|
| db->pTraceArg = pArg;
|
| sqlite3_mutex_leave(db->mutex);
|
| return pOld;
|
| }
|
| +#endif /* SQLITE_OMIT_DEPRECATED */
|
| +
|
| +/* Register a trace callback using the version-2 interface.
|
| +*/
|
| +int sqlite3_trace_v2(
|
| + sqlite3 *db, /* Trace this connection */
|
| + unsigned mTrace, /* Mask of events to be traced */
|
| + int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */
|
| + void *pArg /* Context */
|
| +){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| + sqlite3_mutex_enter(db->mutex);
|
| + if( mTrace==0 ) xTrace = 0;
|
| + if( xTrace==0 ) mTrace = 0;
|
| + db->mTrace = mTrace;
|
| + db->xTrace = xTrace;
|
| + db->pTraceArg = pArg;
|
| + sqlite3_mutex_leave(db->mutex);
|
| + return SQLITE_OK;
|
| +}
|
| +
|
| +#ifndef SQLITE_OMIT_DEPRECATED
|
| /*
|
| ** Register a profile function. The pArg from the previously registered
|
| ** profile function is returned.
|
| @@ -1842,6 +1882,7 @@ void *sqlite3_profile(
|
| sqlite3_mutex_leave(db->mutex);
|
| return pOld;
|
| }
|
| +#endif /* SQLITE_OMIT_DEPRECATED */
|
| #endif /* SQLITE_OMIT_TRACE */
|
|
|
| /*
|
| @@ -1920,6 +1961,27 @@ void *sqlite3_rollback_hook(
|
| return pRet;
|
| }
|
|
|
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
| +/*
|
| +** Register a callback to be invoked each time a row is updated,
|
| +** inserted or deleted using this database connection.
|
| +*/
|
| +void *sqlite3_preupdate_hook(
|
| + sqlite3 *db, /* Attach the hook to this database */
|
| + void(*xCallback)( /* Callback function */
|
| + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64),
|
| + void *pArg /* First callback argument */
|
| +){
|
| + void *pRet;
|
| + sqlite3_mutex_enter(db->mutex);
|
| + pRet = db->pPreUpdateArg;
|
| + db->xPreUpdateCallback = xCallback;
|
| + db->pPreUpdateArg = pArg;
|
| + sqlite3_mutex_leave(db->mutex);
|
| + return pRet;
|
| +}
|
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
| +
|
| #ifndef SQLITE_OMIT_WAL
|
| /*
|
| ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
|
| @@ -2045,6 +2107,13 @@ int sqlite3_wal_checkpoint_v2(
|
| sqlite3Error(db, rc);
|
| }
|
| rc = sqlite3ApiExit(db, rc);
|
| +
|
| + /* If there are no active statements, clear the interrupt flag at this
|
| + ** point. */
|
| + if( db->nVdbeActive==0 ){
|
| + db->u1.isInterrupted = 0;
|
| + }
|
| +
|
| sqlite3_mutex_leave(db->mutex);
|
| return rc;
|
| #endif
|
| @@ -2150,14 +2219,14 @@ int sqlite3TempInMemory(const sqlite3 *db){
|
| const char *sqlite3_errmsg(sqlite3 *db){
|
| const char *z;
|
| if( !db ){
|
| - return sqlite3ErrStr(SQLITE_NOMEM);
|
| + return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
|
| }
|
| if( !sqlite3SafetyCheckSickOrOk(db) ){
|
| return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
|
| }
|
| sqlite3_mutex_enter(db->mutex);
|
| if( db->mallocFailed ){
|
| - z = sqlite3ErrStr(SQLITE_NOMEM);
|
| + z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
|
| }else{
|
| testcase( db->pErr==0 );
|
| z = (char*)sqlite3_value_text(db->pErr);
|
| @@ -2209,7 +2278,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
|
| ** be cleared before returning. Do this directly, instead of via
|
| ** sqlite3ApiExit(), to avoid setting the database handle error message.
|
| */
|
| - db->mallocFailed = 0;
|
| + sqlite3OomClear(db);
|
| }
|
| sqlite3_mutex_leave(db->mutex);
|
| return z;
|
| @@ -2225,7 +2294,7 @@ int sqlite3_errcode(sqlite3 *db){
|
| return SQLITE_MISUSE_BKPT;
|
| }
|
| if( !db || db->mallocFailed ){
|
| - return SQLITE_NOMEM;
|
| + return SQLITE_NOMEM_BKPT;
|
| }
|
| return db->errCode & db->errMask;
|
| }
|
| @@ -2234,10 +2303,13 @@ int sqlite3_extended_errcode(sqlite3 *db){
|
| return SQLITE_MISUSE_BKPT;
|
| }
|
| if( !db || db->mallocFailed ){
|
| - return SQLITE_NOMEM;
|
| + return SQLITE_NOMEM_BKPT;
|
| }
|
| return db->errCode;
|
| }
|
| +int sqlite3_system_errno(sqlite3 *db){
|
| + return db ? db->iSysErrno : 0;
|
| +}
|
|
|
| /*
|
| ** Return a string that describes the kind of error specified in the
|
| @@ -2314,7 +2386,7 @@ static int createCollation(
|
| }
|
|
|
| pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
|
| - if( pColl==0 ) return SQLITE_NOMEM;
|
| + if( pColl==0 ) return SQLITE_NOMEM_BKPT;
|
| pColl->xCmp = xCompare;
|
| pColl->pUser = pCtx;
|
| pColl->xDel = xDel;
|
| @@ -2362,8 +2434,8 @@ static const int aHardLimit[] = {
|
| #if SQLITE_MAX_VDBE_OP<40
|
| # error SQLITE_MAX_VDBE_OP must be at least 40
|
| #endif
|
| -#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
|
| -# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
|
| +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
|
| +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
|
| #endif
|
| #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
|
| # error SQLITE_MAX_ATTACHED must be between 0 and 125
|
| @@ -2493,7 +2565,7 @@ int sqlite3ParseUri(
|
|
|
| for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
|
| zFile = sqlite3_malloc64(nByte);
|
| - if( !zFile ) return SQLITE_NOMEM;
|
| + if( !zFile ) return SQLITE_NOMEM_BKPT;
|
|
|
| iIn = 5;
|
| #ifdef SQLITE_ALLOW_URI_AUTHORITY
|
| @@ -2544,6 +2616,7 @@ int sqlite3ParseUri(
|
|
|
| assert( octet>=0 && octet<256 );
|
| if( octet==0 ){
|
| +#ifndef SQLITE_ENABLE_URI_00_ERROR
|
| /* This branch is taken when "%00" appears within the URI. In this
|
| ** case we ignore all text in the remainder of the path, name or
|
| ** value currently being parsed. So ignore the current character
|
| @@ -2556,6 +2629,12 @@ int sqlite3ParseUri(
|
| iIn++;
|
| }
|
| continue;
|
| +#else
|
| + /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
|
| + *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
|
| + rc = SQLITE_ERROR;
|
| + goto parse_uri_out;
|
| +#endif
|
| }
|
| c = octet;
|
| }else if( eState==1 && (c=='&' || c=='=') ){
|
| @@ -2659,8 +2738,10 @@ int sqlite3ParseUri(
|
|
|
| }else{
|
| zFile = sqlite3_malloc64(nUri+2);
|
| - if( !zFile ) return SQLITE_NOMEM;
|
| - memcpy(zFile, zUri, nUri);
|
| + if( !zFile ) return SQLITE_NOMEM_BKPT;
|
| + if( nUri ){
|
| + memcpy(zFile, zUri, nUri);
|
| + }
|
| zFile[nUri] = '\0';
|
| zFile[nUri+1] = '\0';
|
| flags &= ~SQLITE_OPEN_URI;
|
| @@ -2816,6 +2897,9 @@ static int openDatabase(
|
| #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
|
| | SQLITE_CellSizeCk
|
| #endif
|
| +#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
|
| + | SQLITE_Fts3Tokenizer
|
| +#endif
|
| ;
|
| sqlite3HashInit(&db->aCollSeq);
|
| #ifndef SQLITE_OMIT_VIRTUALTABLE
|
| @@ -2847,7 +2931,7 @@ static int openDatabase(
|
| db->openFlags = flags;
|
| rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
|
| if( rc!=SQLITE_OK ){
|
| - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
|
| + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
|
| sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
|
| sqlite3_free(zErrMsg);
|
| goto opendb_out;
|
| @@ -2858,7 +2942,7 @@ static int openDatabase(
|
| flags | SQLITE_OPEN_MAIN_DB);
|
| if( rc!=SQLITE_OK ){
|
| if( rc==SQLITE_IOERR_NOMEM ){
|
| - rc = SQLITE_NOMEM;
|
| + rc = SQLITE_NOMEM_BKPT;
|
| }
|
| sqlite3Error(db, rc);
|
| goto opendb_out;
|
| @@ -2869,13 +2953,13 @@ static int openDatabase(
|
| sqlite3BtreeLeave(db->aDb[0].pBt);
|
| db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
|
|
|
| - /* The default safety_level for the main database is 'full'; for the temp
|
| - ** database it is 'NONE'. This matches the pager layer defaults.
|
| + /* The default safety_level for the main database is FULL; for the temp
|
| + ** database it is OFF. This matches the pager layer defaults.
|
| */
|
| - db->aDb[0].zName = "main";
|
| - db->aDb[0].safety_level = 3;
|
| - db->aDb[1].zName = "temp";
|
| - db->aDb[1].safety_level = 1;
|
| + db->aDb[0].zDbSName = "main";
|
| + db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
|
| + db->aDb[1].zDbSName = "temp";
|
| + db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
|
|
|
| db->magic = SQLITE_MAGIC_OPEN;
|
| if( db->mallocFailed ){
|
| @@ -2887,12 +2971,21 @@ static int openDatabase(
|
| ** is accessed.
|
| */
|
| sqlite3Error(db, SQLITE_OK);
|
| - sqlite3RegisterBuiltinFunctions(db);
|
| + sqlite3RegisterPerConnectionBuiltinFunctions(db);
|
| + rc = sqlite3_errcode(db);
|
| +
|
| +#ifdef SQLITE_ENABLE_FTS5
|
| + /* Register any built-in FTS5 module before loading the automatic
|
| + ** extensions. This allows automatic extensions to register FTS5
|
| + ** tokenizers and auxiliary functions. */
|
| + if( !db->mallocFailed && rc==SQLITE_OK ){
|
| + rc = sqlite3Fts5Init(db);
|
| + }
|
| +#endif
|
|
|
| /* Load automatic extensions - extensions that have been registered
|
| ** using the sqlite3_automatic_extension() API.
|
| */
|
| - rc = sqlite3_errcode(db);
|
| if( rc==SQLITE_OK ){
|
| sqlite3AutoLoadExtensions(db);
|
| rc = sqlite3_errcode(db);
|
| @@ -2921,12 +3014,6 @@ static int openDatabase(
|
| }
|
| #endif
|
|
|
| -#ifdef SQLITE_ENABLE_FTS5
|
| - if( !db->mallocFailed && rc==SQLITE_OK ){
|
| - rc = sqlite3Fts5Init(db);
|
| - }
|
| -#endif
|
| -
|
| #ifdef DEFAULT_ENABLE_RECOVER
|
| /* Initialize recover virtual table for testing. */
|
| extern int recoverVtableInit(sqlite3 *db);
|
| @@ -3069,7 +3156,7 @@ int sqlite3_open16(
|
| SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
|
| }
|
| }else{
|
| - rc = SQLITE_NOMEM;
|
| + rc = SQLITE_NOMEM_BKPT;
|
| }
|
| sqlite3ValueFree(pVal);
|
|
|
| @@ -3214,7 +3301,7 @@ int sqlite3_get_autocommit(sqlite3 *db){
|
|
|
| /*
|
| ** The following routines are substitutes for constants SQLITE_CORRUPT,
|
| -** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
|
| +** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
|
| ** constants. They serve two purposes:
|
| **
|
| ** 1. Serve as a convenient place to set a breakpoint in a debugger
|
| @@ -3223,28 +3310,33 @@ int sqlite3_get_autocommit(sqlite3 *db){
|
| ** 2. Invoke sqlite3_log() to provide the source code location where
|
| ** a low-level error is first detected.
|
| */
|
| +static int reportError(int iErr, int lineno, const char *zType){
|
| + sqlite3_log(iErr, "%s at line %d of [%.10s]",
|
| + zType, lineno, 20+sqlite3_sourceid());
|
| + return iErr;
|
| +}
|
| 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;
|
| + return reportError(SQLITE_CORRUPT, lineno, "database corruption");
|
| }
|
| 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;
|
| + return reportError(SQLITE_MISUSE, lineno, "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;
|
| + return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
|
| }
|
| -
|
| +#ifdef SQLITE_DEBUG
|
| +int sqlite3NomemError(int lineno){
|
| + testcase( sqlite3GlobalConfig.xLog!=0 );
|
| + return reportError(SQLITE_NOMEM, lineno, "OOM");
|
| +}
|
| +int sqlite3IoerrnomemError(int lineno){
|
| + testcase( sqlite3GlobalConfig.xLog!=0 );
|
| + return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
|
| +}
|
| +#endif
|
|
|
| #ifndef SQLITE_OMIT_DEPRECATED
|
| /*
|
| @@ -3338,7 +3430,7 @@ int sqlite3_table_column_metadata(
|
| ** explicitly declared column. Copy meta information from *pCol.
|
| */
|
| if( pCol ){
|
| - zDataType = pCol->zType;
|
| + zDataType = sqlite3ColumnType(pCol,0);
|
| zCollSeq = pCol->zColl;
|
| notnull = pCol->notNull!=0;
|
| primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
|
| @@ -3451,7 +3543,7 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
| */
|
| int sqlite3_test_control(int op, ...){
|
| int rc = 0;
|
| -#ifdef SQLITE_OMIT_BUILTIN_TEST
|
| +#ifdef SQLITE_UNTESTABLE
|
| UNUSED_PARAMETER(op);
|
| #else
|
| va_list ap;
|
| @@ -3575,7 +3667,7 @@ int sqlite3_test_control(int op, ...){
|
| */
|
| case SQLITE_TESTCTRL_ASSERT: {
|
| volatile int x = 0;
|
| - assert( (x = va_arg(ap,int))!=0 );
|
| + assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
|
| rc = x;
|
| break;
|
| }
|
| @@ -3717,6 +3809,15 @@ int sqlite3_test_control(int op, ...){
|
| break;
|
| }
|
|
|
| + /* Set the threshold at which OP_Once counters reset back to zero.
|
| + ** By default this is 0x7ffffffe (over 2 billion), but that value is
|
| + ** too big to test in a reasonable amount of time, so this control is
|
| + ** provided to set a small and easily reachable reset value.
|
| + */
|
| + case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: {
|
| + sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int);
|
| + break;
|
| + }
|
|
|
| /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
|
| **
|
| @@ -3779,7 +3880,7 @@ int sqlite3_test_control(int op, ...){
|
| }
|
| }
|
| va_end(ap);
|
| -#endif /* SQLITE_OMIT_BUILTIN_TEST */
|
| +#endif /* SQLITE_UNTESTABLE */
|
| return rc;
|
| }
|
|
|
| @@ -3835,15 +3936,8 @@ sqlite3_int64 sqlite3_uri_int64(
|
| ** Return the Btree pointer identified by zDbName. Return NULL if not found.
|
| */
|
| Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
|
| - int i;
|
| - for(i=0; i<db->nDb; i++){
|
| - if( db->aDb[i].pBt
|
| - && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0)
|
| - ){
|
| - return db->aDb[i].pBt;
|
| - }
|
| - }
|
| - return 0;
|
| + int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
|
| + return iDb<0 ? 0 : db->aDb[iDb].pBt;
|
| }
|
|
|
| /*
|
| @@ -3890,7 +3984,6 @@ int sqlite3_snapshot_get(
|
| ){
|
| int rc = SQLITE_ERROR;
|
| #ifndef SQLITE_OMIT_WAL
|
| - int iDb;
|
|
|
| #ifdef SQLITE_ENABLE_API_ARMOR
|
| if( !sqlite3SafetyCheckOk(db) ){
|
| @@ -3899,13 +3992,15 @@ int sqlite3_snapshot_get(
|
| #endif
|
| sqlite3_mutex_enter(db->mutex);
|
|
|
| - iDb = sqlite3FindDbName(db, zDb);
|
| - if( iDb==0 || iDb>1 ){
|
| - Btree *pBt = db->aDb[iDb].pBt;
|
| - if( 0==sqlite3BtreeIsInTrans(pBt) ){
|
| - rc = sqlite3BtreeBeginTrans(pBt, 0);
|
| - if( rc==SQLITE_OK ){
|
| - rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
|
| + if( db->autoCommit==0 ){
|
| + int iDb = sqlite3FindDbName(db, zDb);
|
| + if( iDb==0 || iDb>1 ){
|
| + Btree *pBt = db->aDb[iDb].pBt;
|
| + if( 0==sqlite3BtreeIsInTrans(pBt) ){
|
| + rc = sqlite3BtreeBeginTrans(pBt, 0);
|
| + if( rc==SQLITE_OK ){
|
| + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
|
| + }
|
| }
|
| }
|
| }
|
| @@ -3953,6 +4048,38 @@ int sqlite3_snapshot_open(
|
| }
|
|
|
| /*
|
| +** Recover as many snapshots as possible from the wal file associated with
|
| +** schema zDb of database db.
|
| +*/
|
| +int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
|
| + int rc = SQLITE_ERROR;
|
| + int iDb;
|
| +#ifndef SQLITE_OMIT_WAL
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| +
|
| + sqlite3_mutex_enter(db->mutex);
|
| + iDb = sqlite3FindDbName(db, zDb);
|
| + if( iDb==0 || iDb>1 ){
|
| + Btree *pBt = db->aDb[iDb].pBt;
|
| + if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
|
| + rc = sqlite3BtreeBeginTrans(pBt, 0);
|
| + if( rc==SQLITE_OK ){
|
| + rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
|
| + sqlite3BtreeCommit(pBt);
|
| + }
|
| + }
|
| + }
|
| + sqlite3_mutex_leave(db->mutex);
|
| +#endif /* SQLITE_OMIT_WAL */
|
| + return rc;
|
| +}
|
| +
|
| +/*
|
| ** Free a snapshot handle obtained from sqlite3_snapshot_get().
|
| */
|
| void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
|
|
|