mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-02 02:32:27 +00:00
Upgrade SQLite to 3.40 (#699)
This commit is contained in:
parent
bcae817215
commit
0dc0758574
151 changed files with 27917 additions and 22169 deletions
372
third_party/sqlite3/main.c
vendored
372
third_party/sqlite3/main.c
vendored
|
@ -14,17 +14,16 @@
|
|||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
*/
|
||||
#include "third_party/sqlite3/sqliteInt.inc"
|
||||
/* clang-format off */
|
||||
#include "third_party/sqlite3/sqliteInt.h"
|
||||
|
||||
#ifdef SQLITE_ENABLE_FTS3
|
||||
#include "third_party/sqlite3/fts3.inc"
|
||||
# include "third_party/sqlite3/fts3.h"
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_RTREE
|
||||
#include "third_party/sqlite3/rtree.inc"
|
||||
# include "third_party/sqlite3/rtree.h"
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
|
||||
#include "third_party/sqlite3/sqliteicu.inc"
|
||||
# include "third_party/sqlite3/sqliteicu.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -51,9 +50,6 @@ int sqlite3Fts2Init(sqlite3*);
|
|||
#ifdef SQLITE_ENABLE_FTS5
|
||||
int sqlite3Fts5Init(sqlite3*);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_JSON1
|
||||
int sqlite3Json1Init(sqlite3*);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_STMTVTAB
|
||||
int sqlite3StmtVtabInit(sqlite3*);
|
||||
#endif
|
||||
|
@ -88,8 +84,8 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
|
|||
sqlite3DbstatRegister,
|
||||
#endif
|
||||
sqlite3TestExtInit,
|
||||
#ifdef SQLITE_ENABLE_JSON1
|
||||
sqlite3Json1Init,
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
|
||||
sqlite3JsonTableFunctions,
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_STMTVTAB
|
||||
sqlite3StmtVtabInit,
|
||||
|
@ -306,7 +302,7 @@ int sqlite3_initialize(void){
|
|||
sqlite3GlobalConfig.isPCacheInit = 1;
|
||||
rc = sqlite3OsInit();
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3MemdbInit();
|
||||
}
|
||||
|
@ -721,12 +717,12 @@ int sqlite3_config(int op, ...){
|
|||
}
|
||||
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
|
||||
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
case SQLITE_CONFIG_MEMDB_MAXSIZE: {
|
||||
sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64);
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_DESERIALIZE */
|
||||
#endif /* SQLITE_OMIT_DESERIALIZE */
|
||||
|
||||
default: {
|
||||
rc = SQLITE_ERROR;
|
||||
|
@ -828,18 +824,19 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
|||
db->lookaside.bMalloced = pBuf==0 ?1:0;
|
||||
db->lookaside.nSlot = nBig+nSm;
|
||||
}else{
|
||||
db->lookaside.pStart = db;
|
||||
db->lookaside.pStart = 0;
|
||||
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
|
||||
db->lookaside.pSmallInit = 0;
|
||||
db->lookaside.pSmallFree = 0;
|
||||
db->lookaside.pMiddle = db;
|
||||
db->lookaside.pMiddle = 0;
|
||||
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
|
||||
db->lookaside.pEnd = db;
|
||||
db->lookaside.pEnd = 0;
|
||||
db->lookaside.bDisable = 1;
|
||||
db->lookaside.sz = 0;
|
||||
db->lookaside.bMalloced = 0;
|
||||
db->lookaside.nSlot = 0;
|
||||
}
|
||||
db->lookaside.pTrueEnd = db->lookaside.pEnd;
|
||||
assert( sqlite3LookasideUsed(db,0)==0 );
|
||||
#endif /* SQLITE_OMIT_LOOKASIDE */
|
||||
return SQLITE_OK;
|
||||
|
@ -918,6 +915,7 @@ int sqlite3_db_cacheflush(sqlite3 *db){
|
|||
int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
va_list ap;
|
||||
int rc;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
va_start(ap, op);
|
||||
switch( op ){
|
||||
case SQLITE_DBCONFIG_MAINDBNAME: {
|
||||
|
@ -983,6 +981,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
|||
}
|
||||
}
|
||||
va_end(ap);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1087,7 +1086,7 @@ void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
|
|||
/*
|
||||
** Return the number of changes in the most recent call to sqlite3_exec().
|
||||
*/
|
||||
int sqlite3_changes(sqlite3 *db){
|
||||
sqlite3_int64 sqlite3_changes64(sqlite3 *db){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
|
@ -1096,11 +1095,14 @@ int sqlite3_changes(sqlite3 *db){
|
|||
#endif
|
||||
return db->nChange;
|
||||
}
|
||||
int sqlite3_changes(sqlite3 *db){
|
||||
return (int)sqlite3_changes64(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of changes since the database handle was opened.
|
||||
*/
|
||||
int sqlite3_total_changes(sqlite3 *db){
|
||||
sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
|
@ -1109,6 +1111,9 @@ int sqlite3_total_changes(sqlite3 *db){
|
|||
#endif
|
||||
return db->nTotalChange;
|
||||
}
|
||||
int sqlite3_total_changes(sqlite3 *db){
|
||||
return (int)sqlite3_total_changes64(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** Close all open savepoints. This function only manipulates fields of the
|
||||
|
@ -1133,7 +1138,9 @@ void sqlite3CloseSavepoints(sqlite3 *db){
|
|||
** with SQLITE_ANY as the encoding.
|
||||
*/
|
||||
static void functionDestroy(sqlite3 *db, FuncDef *p){
|
||||
FuncDestructor *pDestructor = p->u.pDestructor;
|
||||
FuncDestructor *pDestructor;
|
||||
assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 );
|
||||
pDestructor = p->u.pDestructor;
|
||||
if( pDestructor ){
|
||||
pDestructor->nRef--;
|
||||
if( pDestructor->nRef==0 ){
|
||||
|
@ -1237,7 +1244,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
|
|||
|
||||
/* Convert the connection into a zombie and then close it.
|
||||
*/
|
||||
db->magic = SQLITE_MAGIC_ZOMBIE;
|
||||
db->eOpenState = SQLITE_STATE_ZOMBIE;
|
||||
sqlite3LeaveMutexAndCloseZombie(db);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
@ -1275,7 +1282,7 @@ int sqlite3_txn_state(sqlite3 *db, const char *zSchema){
|
|||
/*
|
||||
** Two variations on the public interface for closing a database
|
||||
** connection. The sqlite3_close() version returns SQLITE_BUSY and
|
||||
** leaves the connection option if there are unfinalized prepared
|
||||
** leaves the connection open if there are unfinalized prepared
|
||||
** statements or unfinished sqlite3_backups. The sqlite3_close_v2()
|
||||
** version forces the connection to become a zombie if there are
|
||||
** unclosed resources, and arranges for deallocation when the last
|
||||
|
@ -1301,7 +1308,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
|||
** or if the connection has not yet been closed by sqlite3_close_v2(),
|
||||
** then just leave the mutex and return.
|
||||
*/
|
||||
if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
|
||||
if( db->eOpenState!=SQLITE_STATE_ZOMBIE || connectionIsBusy(db) ){
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return;
|
||||
}
|
||||
|
@ -1387,7 +1394,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
|||
sqlite3_free(db->auth.zAuthPW);
|
||||
#endif
|
||||
|
||||
db->magic = SQLITE_MAGIC_ERROR;
|
||||
db->eOpenState = SQLITE_STATE_ERROR;
|
||||
|
||||
/* The temp-database schema is allocated differently from the other schema
|
||||
** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
|
||||
|
@ -1396,8 +1403,11 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
|||
** structure?
|
||||
*/
|
||||
sqlite3DbFree(db, db->aDb[1].pSchema);
|
||||
if( db->xAutovacDestr ){
|
||||
db->xAutovacDestr(db->pAutovacPagesArg);
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
db->magic = SQLITE_MAGIC_CLOSED;
|
||||
db->eOpenState = SQLITE_STATE_CLOSED;
|
||||
sqlite3_mutex_free(db->mutex);
|
||||
assert( sqlite3LookasideUsed(db,0)==0 );
|
||||
if( db->lookaside.bMalloced ){
|
||||
|
@ -1450,7 +1460,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
|||
/* Any deferred constraint violations have now been resolved. */
|
||||
db->nDeferredCons = 0;
|
||||
db->nDeferredImmCons = 0;
|
||||
db->flags &= ~(u64)SQLITE_DeferFKs;
|
||||
db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
|
||||
|
||||
/* If one has been configured, invoke the rollback-hook callback */
|
||||
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
|
||||
|
@ -1785,7 +1795,7 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
|||
*/
|
||||
void sqlite3_interrupt(sqlite3 *db){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){
|
||||
if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return;
|
||||
}
|
||||
|
@ -1814,7 +1824,6 @@ int sqlite3CreateFunc(
|
|||
FuncDestructor *pDestructor
|
||||
){
|
||||
FuncDef *p;
|
||||
int nName;
|
||||
int extraFlags;
|
||||
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
@ -1824,7 +1833,7 @@ int sqlite3CreateFunc(
|
|||
|| ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */
|
||||
|| ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */
|
||||
|| (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
|
||||
|| (255<(nName = sqlite3Strlen30( zFunctionName)))
|
||||
|| (255<sqlite3Strlen30(zFunctionName))
|
||||
){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
|
@ -1849,22 +1858,33 @@ int sqlite3CreateFunc(
|
|||
** If SQLITE_ANY is specified, add three versions of the function
|
||||
** to the hash table.
|
||||
*/
|
||||
if( enc==SQLITE_UTF16 ){
|
||||
enc = SQLITE_UTF16NATIVE;
|
||||
}else if( enc==SQLITE_ANY ){
|
||||
int rc;
|
||||
rc = sqlite3CreateFunc(db, zFunctionName, nArg,
|
||||
(SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE,
|
||||
pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
|
||||
if( rc==SQLITE_OK ){
|
||||
switch( enc ){
|
||||
case SQLITE_UTF16:
|
||||
enc = SQLITE_UTF16NATIVE;
|
||||
break;
|
||||
case SQLITE_ANY: {
|
||||
int rc;
|
||||
rc = sqlite3CreateFunc(db, zFunctionName, nArg,
|
||||
(SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE,
|
||||
(SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE,
|
||||
pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3CreateFunc(db, zFunctionName, nArg,
|
||||
(SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE,
|
||||
pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
enc = SQLITE_UTF16BE;
|
||||
break;
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
enc = SQLITE_UTF16BE;
|
||||
case SQLITE_UTF8:
|
||||
case SQLITE_UTF16LE:
|
||||
case SQLITE_UTF16BE:
|
||||
break;
|
||||
default:
|
||||
enc = SQLITE_UTF8;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
enc = SQLITE_UTF8;
|
||||
|
@ -1885,6 +1905,10 @@ int sqlite3CreateFunc(
|
|||
}else{
|
||||
sqlite3ExpirePreparedStatements(db, 0);
|
||||
}
|
||||
}else if( xSFunc==0 && xFinal==0 ){
|
||||
/* Trying to delete a function that does not exist. This is a no-op.
|
||||
** https://sqlite.org/forum/forumpost/726219164b */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
|
||||
|
@ -1957,7 +1981,7 @@ static int createFunctionApi(
|
|||
xSFunc, xStep, xFinal, xValue, xInverse, pArg
|
||||
);
|
||||
if( pArg && pArg->nRef==0 ){
|
||||
assert( rc!=SQLITE_OK );
|
||||
assert( rc!=SQLITE_OK || (xStep==0 && xFinal==0) );
|
||||
xDestroy(p);
|
||||
sqlite3_free(pArg);
|
||||
}
|
||||
|
@ -2283,6 +2307,34 @@ void *sqlite3_preupdate_hook(
|
|||
}
|
||||
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
/*
|
||||
** Register a function to be invoked prior to each autovacuum that
|
||||
** determines the number of pages to vacuum.
|
||||
*/
|
||||
int sqlite3_autovacuum_pages(
|
||||
sqlite3 *db, /* Attach the hook to this database */
|
||||
unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
|
||||
void *pArg, /* Argument to the function */
|
||||
void (*xDestructor)(void*) /* Destructor for pArg */
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
if( xDestructor ) xDestructor(pArg);
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( db->xAutovacDestr ){
|
||||
db->xAutovacDestr(db->pAutovacPagesArg);
|
||||
}
|
||||
db->xAutovacPages = xCallback;
|
||||
db->pAutovacPagesArg = pArg;
|
||||
db->xAutovacDestr = xDestructor;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
|
||||
|
@ -2545,6 +2597,19 @@ const char *sqlite3_errmsg(sqlite3 *db){
|
|||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the byte offset of the most recent error
|
||||
*/
|
||||
int sqlite3_error_offset(sqlite3 *db){
|
||||
int iOffset = -1;
|
||||
if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
iOffset = db->errByteOffset;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
}
|
||||
return iOffset;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
/*
|
||||
** Return UTF-16 encoded English language explanation of the most recent
|
||||
|
@ -2805,6 +2870,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
|
|||
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
|
||||
if( newLimit>aHardLimit[limitId] ){
|
||||
newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
|
||||
}else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){
|
||||
newLimit = 1;
|
||||
}
|
||||
db->aLimit[limitId] = newLimit;
|
||||
}
|
||||
|
@ -3076,7 +3143,7 @@ int sqlite3ParseUri(
|
|||
*/
|
||||
static const char *uriParameter(const char *zFilename, const char *zParam){
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
while( zFilename[0] ){
|
||||
while( ALWAYS(zFilename!=0) && zFilename[0] ){
|
||||
int x = strcmp(zFilename, zParam);
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
if( x==0 ) return zFilename;
|
||||
|
@ -3136,8 +3203,8 @@ static int openDatabase(
|
|||
** dealt with in the previous code block. Besides these, the only
|
||||
** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
|
||||
** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
|
||||
** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
|
||||
** off all other flags.
|
||||
** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
|
||||
** bits. Silently mask off all other flags.
|
||||
*/
|
||||
flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
|
||||
SQLITE_OPEN_EXCLUSIVE |
|
||||
|
@ -3172,9 +3239,9 @@ static int openDatabase(
|
|||
}
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->errMask = 0xff;
|
||||
db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
|
||||
db->nDb = 2;
|
||||
db->magic = SQLITE_MAGIC_BUSY;
|
||||
db->eOpenState = SQLITE_STATE_BUSY;
|
||||
db->aDb = db->aDbStatic;
|
||||
db->lookaside.bDisable = 1;
|
||||
db->lookaside.sz = 0;
|
||||
|
@ -3186,7 +3253,15 @@ static int openDatabase(
|
|||
db->nextAutovac = -1;
|
||||
db->szMmap = sqlite3GlobalConfig.szMmap;
|
||||
db->nextPagesize = 0;
|
||||
db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */
|
||||
#ifdef SQLITE_ENABLE_SORTER_MMAP
|
||||
/* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map
|
||||
** the temporary files used to do external sorts (see code in vdbesort.c)
|
||||
** is disabled. It can still be used either by defining
|
||||
** SQLITE_ENABLE_SORTER_MMAP at compile time or by using the
|
||||
** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */
|
||||
db->nMaxSorterMmap = 0x7FFFFFFF;
|
||||
#endif
|
||||
db->flags |= SQLITE_ShortColNames
|
||||
| SQLITE_EnableTrigger
|
||||
| SQLITE_EnableView
|
||||
|
@ -3277,6 +3352,19 @@ static int openDatabase(
|
|||
goto opendb_out;
|
||||
}
|
||||
|
||||
#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)
|
||||
/* Process magic filenames ":localStorage:" and ":sessionStorage:" */
|
||||
if( zFilename && zFilename[0]==':' ){
|
||||
if( strcmp(zFilename, ":localStorage:")==0 ){
|
||||
zFilename = "file:local?vfs=kvvfs";
|
||||
flags |= SQLITE_OPEN_URI;
|
||||
}else if( strcmp(zFilename, ":sessionStorage:")==0 ){
|
||||
zFilename = "file:session?vfs=kvvfs";
|
||||
flags |= SQLITE_OPEN_URI;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) */
|
||||
|
||||
/* Parse the filename/URI argument
|
||||
**
|
||||
** Only allow sensible combinations of bits in the flags argument.
|
||||
|
@ -3307,6 +3395,12 @@ static int openDatabase(
|
|||
sqlite3_free(zErrMsg);
|
||||
goto opendb_out;
|
||||
}
|
||||
assert( db->pVfs!=0 );
|
||||
#if SQLITE_OS_KV || defined(SQLITE_OS_KV_OPTIONAL)
|
||||
if( sqlite3_stricmp(db->pVfs->zName, "kvvfs")==0 ){
|
||||
db->temp_store = 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Open the backend database driver */
|
||||
rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
|
||||
|
@ -3334,7 +3428,7 @@ static int openDatabase(
|
|||
db->aDb[1].zDbSName = "temp";
|
||||
db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
|
||||
|
||||
db->magic = SQLITE_MAGIC_OPEN;
|
||||
db->eOpenState = SQLITE_STATE_OPEN;
|
||||
if( db->mallocFailed ){
|
||||
goto opendb_out;
|
||||
}
|
||||
|
@ -3396,12 +3490,12 @@ opendb_out:
|
|||
sqlite3_mutex_leave(db->mutex);
|
||||
}
|
||||
rc = sqlite3_errcode(db);
|
||||
assert( db!=0 || rc==SQLITE_NOMEM );
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
assert( db!=0 || (rc&0xff)==SQLITE_NOMEM );
|
||||
if( (rc&0xff)==SQLITE_NOMEM ){
|
||||
sqlite3_close(db);
|
||||
db = 0;
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
db->magic = SQLITE_MAGIC_SICK;
|
||||
db->eOpenState = SQLITE_STATE_SICK;
|
||||
}
|
||||
*ppDb = db;
|
||||
#ifdef SQLITE_ENABLE_SQLLOG
|
||||
|
@ -3412,7 +3506,7 @@ opendb_out:
|
|||
}
|
||||
#endif
|
||||
sqlite3_free_filename(zOpen);
|
||||
return rc & 0xff;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3712,7 +3806,7 @@ int sqlite3_table_column_metadata(
|
|||
|
||||
/* Locate the table in question */
|
||||
pTab = sqlite3FindTable(db, zTableName, zDbName);
|
||||
if( !pTab || pTab->pSelect ){
|
||||
if( !pTab || IsView(pTab) ){
|
||||
pTab = 0;
|
||||
goto error_out;
|
||||
}
|
||||
|
@ -3723,7 +3817,7 @@ int sqlite3_table_column_metadata(
|
|||
}else{
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||
pCol = &pTab->aCol[iCol];
|
||||
if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
|
||||
if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3750,7 +3844,7 @@ int sqlite3_table_column_metadata(
|
|||
*/
|
||||
if( pCol ){
|
||||
zDataType = sqlite3ColumnType(pCol,0);
|
||||
zCollSeq = pCol->zColl;
|
||||
zCollSeq = sqlite3ColumnColl(pCol);
|
||||
notnull = pCol->notNull!=0;
|
||||
primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
|
||||
autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
|
||||
|
@ -3957,12 +4051,16 @@ int sqlite3_test_control(int op, ...){
|
|||
** sqlite3_test_control().
|
||||
*/
|
||||
case SQLITE_TESTCTRL_FAULT_INSTALL: {
|
||||
/* MSVC is picky about pulling func ptrs from va lists.
|
||||
** http://support.microsoft.com/kb/47961
|
||||
/* A bug in MSVC prevents it from understanding pointers to functions
|
||||
** types in the second argument to va_arg(). Work around the problem
|
||||
** using a typedef.
|
||||
** http://support.microsoft.com/kb/47961 <-- dead hyperlink
|
||||
** Search at http://web.archive.org/ to find the 2015-03-16 archive
|
||||
** of the link above to see the original text.
|
||||
** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
|
||||
*/
|
||||
typedef int(*TESTCALLBACKFUNC_t)(int);
|
||||
sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
|
||||
typedef int(*sqlite3FaultFuncType)(int);
|
||||
sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType);
|
||||
rc = sqlite3FaultSim(0);
|
||||
break;
|
||||
}
|
||||
|
@ -4021,6 +4119,28 @@ int sqlite3_test_control(int op, ...){
|
|||
volatile int x = 0;
|
||||
assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
|
||||
rc = x;
|
||||
#if defined(SQLITE_DEBUG)
|
||||
/* Invoke these debugging routines so that the compiler does not
|
||||
** issue "defined but not used" warnings. */
|
||||
if( x==9999 ){
|
||||
sqlite3ShowExpr(0);
|
||||
sqlite3ShowExpr(0);
|
||||
sqlite3ShowExprList(0);
|
||||
sqlite3ShowIdList(0);
|
||||
sqlite3ShowSrcList(0);
|
||||
sqlite3ShowWith(0);
|
||||
sqlite3ShowUpsert(0);
|
||||
sqlite3ShowTriggerStep(0);
|
||||
sqlite3ShowTriggerStepList(0);
|
||||
sqlite3ShowTrigger(0);
|
||||
sqlite3ShowTriggerList(0);
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
sqlite3ShowWindow(0);
|
||||
sqlite3ShowWinFunc(0);
|
||||
#endif
|
||||
sqlite3ShowSelect(0);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4089,13 +4209,27 @@ int sqlite3_test_control(int op, ...){
|
|||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
|
||||
**
|
||||
** If parameter onoff is non-zero, subsequent calls to localtime()
|
||||
** and its variants fail. If onoff is zero, undo this setting.
|
||||
** If parameter onoff is 1, subsequent calls to localtime() fail.
|
||||
** If 2, then invoke xAlt() instead of localtime(). If 0, normal
|
||||
** processing.
|
||||
**
|
||||
** xAlt arguments are void pointers, but they really want to be:
|
||||
**
|
||||
** int xAlt(const time_t*, struct tm*);
|
||||
**
|
||||
** xAlt should write results in to struct tm object of its 2nd argument
|
||||
** and return zero on success, or return non-zero on failure.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
|
||||
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
|
||||
typedef int(*sqlite3LocaltimeType)(const void*,void*);
|
||||
sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
|
||||
}else{
|
||||
sqlite3GlobalConfig.xAltLocaltime = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4200,12 +4334,16 @@ int sqlite3_test_control(int op, ...){
|
|||
*/
|
||||
case SQLITE_TESTCTRL_IMPOSTER: {
|
||||
sqlite3 *db = va_arg(ap, sqlite3*);
|
||||
int iDb;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
|
||||
db->init.busy = db->init.imposterTable = va_arg(ap,int);
|
||||
db->init.newTnum = va_arg(ap,int);
|
||||
if( db->init.busy==0 && db->init.newTnum>0 ){
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
|
||||
if( iDb>=0 ){
|
||||
db->init.iDb = iDb;
|
||||
db->init.busy = db->init.imposterTable = va_arg(ap,int);
|
||||
db->init.newTnum = va_arg(ap,int);
|
||||
if( db->init.busy==0 && db->init.newTnum>0 ){
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
break;
|
||||
|
@ -4264,8 +4402,8 @@ int sqlite3_test_control(int op, ...){
|
|||
**
|
||||
** "ptr" is a pointer to a u32.
|
||||
**
|
||||
** op==0 Store the current sqlite3SelectTrace in *ptr
|
||||
** op==1 Set sqlite3SelectTrace to the value *ptr
|
||||
** op==0 Store the current sqlite3TreeTrace in *ptr
|
||||
** op==1 Set sqlite3TreeTrace to the value *ptr
|
||||
** op==3 Store the current sqlite3WhereTrace in *ptr
|
||||
** op==3 Set sqlite3WhereTrace to the value *ptr
|
||||
*/
|
||||
|
@ -4273,13 +4411,65 @@ int sqlite3_test_control(int op, ...){
|
|||
int opTrace = va_arg(ap, int);
|
||||
u32 *ptr = va_arg(ap, u32*);
|
||||
switch( opTrace ){
|
||||
case 0: *ptr = sqlite3SelectTrace; break;
|
||||
case 1: sqlite3SelectTrace = *ptr; break;
|
||||
case 2: *ptr = sqlite3WhereTrace; break;
|
||||
case 3: sqlite3WhereTrace = *ptr; break;
|
||||
case 0: *ptr = sqlite3TreeTrace; break;
|
||||
case 1: sqlite3TreeTrace = *ptr; break;
|
||||
case 2: *ptr = sqlite3WhereTrace; break;
|
||||
case 3: sqlite3WhereTrace = *ptr; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
|
||||
** double fIn, // Input value
|
||||
** int *pLogEst, // sqlite3LogEstFromDouble(fIn)
|
||||
** u64 *pInt, // sqlite3LogEstToInt(*pLogEst)
|
||||
** int *pLogEst2 // sqlite3LogEst(*pInt)
|
||||
** );
|
||||
**
|
||||
** Test access for the LogEst conversion routines.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_LOGEST: {
|
||||
double rIn = va_arg(ap, double);
|
||||
LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
|
||||
int *pI1 = va_arg(ap,int*);
|
||||
u64 *pU64 = va_arg(ap,u64*);
|
||||
int *pI2 = va_arg(ap,int*);
|
||||
*pI1 = rLogEst;
|
||||
*pU64 = sqlite3LogEstToInt(rLogEst);
|
||||
*pI2 = sqlite3LogEst(*pU64);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue)
|
||||
**
|
||||
** If "id" is an integer between 1 and SQLITE_NTUNE then set the value
|
||||
** of the id-th tuning parameter to *piValue. If "id" is between -1
|
||||
** and -SQLITE_NTUNE, then write the current value of the (-id)-th
|
||||
** tuning parameter into *piValue.
|
||||
**
|
||||
** Tuning parameters are for use during transient development builds,
|
||||
** to help find the best values for constants in the query planner.
|
||||
** Access tuning parameters using the Tuning(ID) macro. Set the
|
||||
** parameters in the CLI using ".testctrl tune ID VALUE".
|
||||
**
|
||||
** Transient use only. Tuning parameters should not be used in
|
||||
** checked-in code.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_TUNE: {
|
||||
int id = va_arg(ap, int);
|
||||
int *piValue = va_arg(ap, int*);
|
||||
if( id>0 && id<=SQLITE_NTUNE ){
|
||||
Tuning(id) = *piValue;
|
||||
}else if( id<0 && id>=-SQLITE_NTUNE ){
|
||||
*piValue = Tuning(-id);
|
||||
}else{
|
||||
rc = SQLITE_NOTFOUND;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
va_end(ap);
|
||||
#endif /* SQLITE_UNTESTABLE */
|
||||
|
@ -4320,7 +4510,7 @@ static char *appendText(char *p, const char *z){
|
|||
** Memory layout must be compatible with that generated by the pager
|
||||
** and expected by sqlite3_uri_parameter() and databaseName().
|
||||
*/
|
||||
char *sqlite3_create_filename(
|
||||
const char *sqlite3_create_filename(
|
||||
const char *zDatabase,
|
||||
const char *zJournal,
|
||||
const char *zWal,
|
||||
|
@ -4356,10 +4546,10 @@ char *sqlite3_create_filename(
|
|||
** error to call this routine with any parameter other than a pointer
|
||||
** previously obtained from sqlite3_create_filename() or a NULL pointer.
|
||||
*/
|
||||
void sqlite3_free_filename(char *p){
|
||||
void sqlite3_free_filename(const char *p){
|
||||
if( p==0 ) return;
|
||||
p = (char*)databaseName(p);
|
||||
sqlite3_free(p - 4);
|
||||
p = databaseName(p);
|
||||
sqlite3_free((char*)p - 4);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4387,7 +4577,7 @@ const char *sqlite3_uri_key(const char *zFilename, int N){
|
|||
if( zFilename==0 || N<0 ) return 0;
|
||||
zFilename = databaseName(zFilename);
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
while( zFilename[0] && (N--)>0 ){
|
||||
while( ALWAYS(zFilename) && zFilename[0] && (N--)>0 ){
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
}
|
||||
|
@ -4430,12 +4620,14 @@ sqlite3_int64 sqlite3_uri_int64(
|
|||
** corruption.
|
||||
*/
|
||||
const char *sqlite3_filename_database(const char *zFilename){
|
||||
if( zFilename==0 ) return 0;
|
||||
return databaseName(zFilename);
|
||||
}
|
||||
const char *sqlite3_filename_journal(const char *zFilename){
|
||||
if( zFilename==0 ) return 0;
|
||||
zFilename = databaseName(zFilename);
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
while( zFilename[0] ){
|
||||
while( ALWAYS(zFilename) && zFilename[0] ){
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
}
|
||||
|
@ -4446,7 +4638,7 @@ const char *sqlite3_filename_wal(const char *zFilename){
|
|||
return 0;
|
||||
#else
|
||||
zFilename = sqlite3_filename_journal(zFilename);
|
||||
zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
|
||||
return zFilename;
|
||||
#endif
|
||||
}
|
||||
|
@ -4459,6 +4651,24 @@ Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
|
|||
return iDb<0 ? 0 : db->aDb[iDb].pBt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the name of the N-th database schema. Return NULL if N is out
|
||||
** of range.
|
||||
*/
|
||||
const char *sqlite3_db_name(sqlite3 *db, int N){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if( N<0 || N>=db->nDb ){
|
||||
return 0;
|
||||
}else{
|
||||
return db->aDb[N].zDbSName;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the filename of the database associated with a database
|
||||
** connection.
|
||||
|
@ -4590,8 +4800,8 @@ int sqlite3_snapshot_open(
|
|||
*/
|
||||
int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
|
||||
int rc = SQLITE_ERROR;
|
||||
int iDb;
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
int iDb;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue