Sqlite: Update Sqlite from 3.31.1 to 3.34 and adapt carray

You can now pass everything you can convert to a span directly and bind it
with a carray instead of using the pointer interface. This is working for
int, long long, double and null terminated C strings.

Change-Id: I274c218e2dec0f11e68576545bb78601f85462bd
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2020-12-21 17:23:34 +01:00
parent 9b4e2aa71d
commit b11d8aa92a
9 changed files with 16194 additions and 12448 deletions

View File

@@ -57,21 +57,32 @@ SQLITE_EXTENSION_INIT1
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
** Must exactly match the definitions in carray.h.
*/
#define CARRAY_INT32 0 /* Data is 32-bit signed integers */
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE 2 /* Data is doubles */
#define CARRAY_TEXT 3 /* Data is char* */
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
/* /*
** Allowed datatypes ** Names of allowed datatypes
*/
#define CARRAY_INT32 0
#define CARRAY_INT64 1
#define CARRAY_DOUBLE 2
#define CARRAY_TEXT 3
/*
** Names of types
*/ */
static const char *azType[] = { "int32", "int64", "double", "char*" }; static const char *azType[] = { "int32", "int64", "double", "char*" };
/*
** Structure used to hold the sqlite3_carray_bind() information
*/
typedef struct carray_bind carray_bind;
struct carray_bind {
void *aData; /* The data */
int nData; /* Number of elements */
int mFlags; /* Control flags */
void (*xDel)(void*); /* Destructor for aData */
};
/* carray_cursor is a subclass of sqlite3_vtab_cursor which will /* carray_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans ** serve as the underlying representation of a cursor that scans
@@ -136,13 +147,10 @@ static int carrayDisconnect(sqlite3_vtab *pVtab){
/* /*
** Constructor for a new carray_cursor object. ** Constructor for a new carray_cursor object.
*/ */
static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor) static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
{
carray_cursor *pCur; carray_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
pCur = sqlite3_malloc(sizeof(*pCur)); if( pCur==0 ) return SQLITE_NOMEM;
if (pCur == 0)
return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur)); memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base; *ppCursor = &pCur->base;
return SQLITE_OK; return SQLITE_OK;
@@ -242,7 +250,19 @@ static int carrayFilter(
int argc, sqlite3_value **argv int argc, sqlite3_value **argv
){ ){
carray_cursor *pCur = (carray_cursor *)pVtabCursor; carray_cursor *pCur = (carray_cursor *)pVtabCursor;
if( idxNum ){ pCur->pPtr = 0;
pCur->iCnt = 0;
switch( idxNum ){
case 1: {
carray_bind *pBind = sqlite3_value_pointer(argv[0], "carray-bind");
if( pBind==0 ) break;
pCur->pPtr = pBind->aData;
pCur->iCnt = pBind->nData;
pCur->eType = pBind->mFlags & 0x03;
break;
}
case 2:
case 3: {
pCur->pPtr = sqlite3_value_pointer(argv[0], "carray"); pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0; pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
if( idxNum<3 ){ if( idxNum<3 ){
@@ -261,9 +281,8 @@ static int carrayFilter(
pCur->eType = i; pCur->eType = i;
} }
} }
}else{ break;
pCur->pPtr = 0; }
pCur->iCnt = 0;
} }
pCur->iRowid = 1; pCur->iRowid = 1;
return SQLITE_OK; return SQLITE_OK;
@@ -278,9 +297,16 @@ static int carrayFilter(
** In this implementation idxNum is used to represent the ** In this implementation idxNum is used to represent the
** query plan. idxStr is unused. ** query plan. idxStr is unused.
** **
** idxNum is 2 if the pointer= and count= constraints exist, ** idxNum is:
** 3 if the ctype= constraint also exists, and is 0 otherwise. **
** If idxNum is 0, then carray becomes an empty table. ** 1 If only the pointer= constraint exists. In this case, the
** parameter must be bound using sqlite3_carray_bind().
**
** 2 if the pointer= and count= constraints exist.
**
** 3 if the ctype= constraint also exists.
**
** idxNum is 0 otherwise and carray becomes an empty table.
*/ */
static int carrayBestIndex( static int carrayBestIndex(
sqlite3_vtab *tab, sqlite3_vtab *tab,
@@ -308,19 +334,22 @@ static int carrayBestIndex(
break; break;
} }
} }
if( ptrIdx>=0 && cntIdx>=0 ){ if( ptrIdx>=0 ){
pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1; pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1;
pIdxInfo->aConstraintUsage[ptrIdx].omit = 1; pIdxInfo->aConstraintUsage[ptrIdx].omit = 1;
pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
pIdxInfo->estimatedCost = (double)1; pIdxInfo->estimatedCost = (double)1;
pIdxInfo->estimatedRows = 100; pIdxInfo->estimatedRows = 100;
pIdxInfo->idxNum = 1;
if( cntIdx>=0 ){
pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
pIdxInfo->idxNum = 2; pIdxInfo->idxNum = 2;
if( ctypeIdx>=0 ){ if( ctypeIdx>=0 ){
pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3; pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1; pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
pIdxInfo->idxNum = 3; pIdxInfo->idxNum = 3;
} }
}
}else{ }else{
pIdxInfo->estimatedCost = (double)2147483647; pIdxInfo->estimatedCost = (double)2147483647;
pIdxInfo->estimatedRows = 2147483647; pIdxInfo->estimatedRows = 2147483647;
@@ -356,6 +385,89 @@ static sqlite3_module carrayModule = {
0, /* xRename */ 0, /* xRename */
}; };
/*
** Destructor for the carray_bind object
*/
static void carrayBindDel(void *pPtr){
carray_bind *p = (carray_bind*)pPtr;
if( p->xDel!=SQLITE_STATIC ){
p->xDel(p->aData);
}
sqlite3_free(p);
}
/*
** Invoke this interface in order to bind to the single-argument
** version of CARRAY().
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_carray_bind(
sqlite3_stmt *pStmt,
int idx,
void *aData,
int nData,
int mFlags,
void (*xDestroy)(void*)
){
carray_bind *pNew;
int i;
pNew = sqlite3_malloc64(sizeof(*pNew));
if( pNew==0 ){
if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
xDestroy(aData);
}
return SQLITE_NOMEM;
}
pNew->nData = nData;
pNew->mFlags = mFlags;
if( xDestroy==SQLITE_TRANSIENT ){
sqlite3_int64 sz = nData;
switch( mFlags & 0x03 ){
case CARRAY_INT32: sz *= 4; break;
case CARRAY_INT64: sz *= 8; break;
case CARRAY_DOUBLE: sz *= 8; break;
case CARRAY_TEXT: sz *= sizeof(char*); break;
}
if( (mFlags & 0x03)==CARRAY_TEXT ){
for(i=0; i<nData; i++){
const char *z = ((char**)aData)[i];
if( z ) sz += strlen(z) + 1;
}
}
pNew->aData = sqlite3_malloc64( sz );
if( pNew->aData==0 ){
sqlite3_free(pNew);
return SQLITE_NOMEM;
}
if( (mFlags & 0x03)==CARRAY_TEXT ){
char **az = (char**)pNew->aData;
char *z = (char*)&az[nData];
for(i=0; i<nData; i++){
const char *zData = ((char**)aData)[i];
sqlite3_int64 n;
if( zData==0 ){
az[i] = 0;
continue;
}
az[i] = z;
n = strlen(zData);
memcpy(z, zData, n+1);
z += n+1;
}
}else{
memcpy(pNew->aData, aData, sz*nData);
}
pNew->xDel = sqlite3_free;
}else{
pNew->aData = aData;
pNew->xDel = xDestroy;
}
return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel);
}
/* /*
** For testing purpose in the TCL test harness, we need a method for ** For testing purpose in the TCL test harness, we need a method for
** setting the pointer value. The inttoptr(X) SQL function accomplishes ** setting the pointer value. The inttoptr(X) SQL function accomplishes
@@ -386,16 +498,22 @@ static void inttoptrFunc(
#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_VIRTUALTABLE */
int sqlite3_carray_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) #ifdef _WIN32
{ __declspec(dllexport)
#endif
int sqlite3_carray_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK; int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi); SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "carray", &carrayModule, 0); rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
if (rc == SQLITE_OK) { if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0, inttoptrFunc, 0, 0); rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,
inttoptrFunc, 0, 0);
} }
#endif /* SQLITE_TEST */ #endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_VIRTUALTABLE */

File diff suppressed because it is too large Load Diff

View File

@@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.31.1" #define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3031001 #define SQLITE_VERSION_NUMBER 3034000
#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6" #define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@@ -299,26 +299,22 @@ typedef sqlite_uint64 sqlite3_uint64;
** the [sqlite3] object is successfully destroyed and all associated ** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated. ** resources are deallocated.
** **
** ^If the database connection is associated with unfinalized prepared ** Ideally, applications should [sqlite3_finalize | finalize] all
** statements or unfinished sqlite3_backup objects then sqlite3_close() ** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
** will leave the database connection open and return [SQLITE_BUSY].
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
** and/or unfinished sqlite3_backups, then the database connection becomes
** an unusable "zombie" which will automatically be deallocated when the
** last prepared statement is finalized or the last sqlite3_backup is
** finished. The sqlite3_close_v2() interface is intended for use with
** host languages that are garbage collected, and where the order in which
** destructors are called is arbitrary.
**
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
** [sqlite3_blob_close | close] all [BLOB handles], and
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object. ^If ** with the [sqlite3] object prior to attempting to close the object.
** sqlite3_close_v2() is called on a [database connection] that still has ** ^If the database connection is associated with unfinalized prepared
** outstanding [prepared statements], [BLOB handles], and/or ** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation ** sqlite3_close() will leave the database connection open and return
** of resources is deferred until all [prepared statements], [BLOB handles], ** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
** and [sqlite3_backup] objects are also destroyed. ** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
** it returns [SQLITE_OK] regardless, but instead of deallocating the database
** connection immediately, it marks the database connection as an unusable
** "zombie" and makes arrangements to automatically deallocate the database
** connection after all prepared statements are finalized, all BLOB handles
** are closed, and all backups have finished. The sqlite3_close_v2() interface
** is intended for use with host languages that are garbage collected, and
** where the order in which destructors are called is arbitrary.
** **
** ^If an [sqlite3] object is destroyed while a transaction is open, ** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back. ** the transaction is automatically rolled back.
@@ -507,10 +503,13 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
@@ -519,6 +518,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
@@ -565,7 +565,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_SUPER_JOURNAL 0x00004000 /* VFS only */
#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
@@ -574,6 +574,9 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
/* Reserved: 0x00F00000 */ /* Reserved: 0x00F00000 */
/* Legacy compatibility: */
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
/* /*
** CAPI3REF: Device Characteristics ** CAPI3REF: Device Characteristics
@@ -871,7 +874,7 @@ struct sqlite3_io_methods {
** of the xSync method. In most cases, the pointer argument passed with ** of the xSync method. In most cases, the pointer argument passed with
** this file-control is NULL. However, if the database file is being synced ** this file-control is NULL. However, if the database file is being synced
** as part of a multi-database commit, the argument points to a nul-terminated ** as part of a multi-database commit, the argument points to a nul-terminated
** string containing the transactions master-journal file name. VFSes that ** string containing the transactions super-journal file name. VFSes that
** do not need this signal should silently ignore this opcode. Applications ** do not need this signal should silently ignore this opcode. Applications
** should not call [sqlite3_file_control()] with this opcode as doing so may ** should not call [sqlite3_file_control()] with this opcode as doing so may
** disrupt the operation of the specialized VFSes that do require it. ** disrupt the operation of the specialized VFSes that do require it.
@@ -1087,10 +1090,12 @@ struct sqlite3_io_methods {
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. ** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
** **
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]] ** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain ** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
** a file lock using the xLock or xShmLock methods of the VFS to wait ** to block for up to M milliseconds before failing when attempting to
** for up to M milliseconds before failing, where M is the single ** obtain a file lock using the xLock or xShmLock methods of the VFS.
** unsigned integer parameter. ** The parameter is a pointer to a 32-bit signed integer that contains
** the value that M is to be set to. Before returning, the 32-bit signed
** integer is overwritten with the previous value of M.
** **
** <li>[[SQLITE_FCNTL_DATA_VERSION]] ** <li>[[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
@@ -1112,6 +1117,11 @@ struct sqlite3_io_methods {
** happen either internally or externally and that are associated with ** happen either internally or externally and that are associated with
** a particular attached database. ** a particular attached database.
** **
** <li>[[SQLITE_FCNTL_CKPT_START]]
** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
** in wal mode before the client starts to copy pages from the wal
** file to the database file.
**
** <li>[[SQLITE_FCNTL_CKPT_DONE]] ** <li>[[SQLITE_FCNTL_CKPT_DONE]]
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
** in wal mode after the client has finished copying pages from the wal ** in wal mode after the client has finished copying pages from the wal
@@ -1155,6 +1165,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_DATA_VERSION 35 #define SQLITE_FCNTL_DATA_VERSION 35
#define SQLITE_FCNTL_SIZE_LIMIT 36 #define SQLITE_FCNTL_SIZE_LIMIT 36
#define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_CKPT_DONE 37
#define SQLITE_FCNTL_RESERVE_BYTES 38
#define SQLITE_FCNTL_CKPT_START 39
/* deprecated names */ /* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1259,7 +1271,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** <li> [SQLITE_OPEN_TEMP_JOURNAL] ** <li> [SQLITE_OPEN_TEMP_JOURNAL]
** <li> [SQLITE_OPEN_TRANSIENT_DB] ** <li> [SQLITE_OPEN_TRANSIENT_DB]
** <li> [SQLITE_OPEN_SUBJOURNAL] ** <li> [SQLITE_OPEN_SUBJOURNAL]
** <li> [SQLITE_OPEN_MASTER_JOURNAL] ** <li> [SQLITE_OPEN_SUPER_JOURNAL]
** <li> [SQLITE_OPEN_WAL] ** <li> [SQLITE_OPEN_WAL]
** </ul>)^ ** </ul>)^
** **
@@ -1637,7 +1649,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** by xInit. The pAppData pointer is used as the only parameter to ** by xInit. The pAppData pointer is used as the only parameter to
** xInit and xShutdown. ** xInit and xShutdown.
** **
** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes ** SQLite holds the [SQLITE_MUTEX_STATIC_MAIN] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe. The ** the xInit method, so the xInit method need not be threadsafe. The
** xShutdown method is only called from [sqlite3_shutdown()] so it does ** xShutdown method is only called from [sqlite3_shutdown()] so it does
** not need to be threadsafe either. For all other methods, SQLite ** not need to be threadsafe either. For all other methods, SQLite
@@ -2275,8 +2287,7 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td> ** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to ** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
** assume that database schemas (the contents of the [sqlite_master] tables) ** assume that database schemas are untainted by malicious content.
** are untainted by malicious content.
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
** takes additional defensive steps to protect the application from harm ** takes additional defensive steps to protect the application from harm
** including: ** including:
@@ -3533,8 +3544,19 @@ SQLITE_API int sqlite3_open_v2(
** that check if a database file was a URI that contained a specific query ** that check if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of that query parameter. ** parameter, and if so obtains the value of that query parameter.
** **
** If F is the database filename pointer passed into the xOpen() method of ** The first parameter to these interfaces (hereafter referred to
** a VFS implementation or it is the return value of [sqlite3_db_filename()] ** as F) must be one of:
** <ul>
** <li> A database filename pointer created by the SQLite core and
** passed into the xOpen() method of a VFS implemention, or
** <li> A filename obtained from [sqlite3_db_filename()], or
** <li> A new filename constructed using [sqlite3_create_filename()].
** </ul>
** If the F parameter is not one of the above, then the behavior is
** undefined and probably undesirable. Older versions of SQLite were
** more tolerant of invalid F parameters than newer versions.
**
** If F is a suitable filename (as described in the previous paragraph)
** and if P is the name of the query parameter, then ** and if P is the name of the query parameter, then
** sqlite3_uri_parameter(F,P) returns the value of the P ** sqlite3_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a ** parameter if it exists or a NULL pointer if P does not appear as a
@@ -3617,6 +3639,78 @@ SQLITE_API const char *sqlite3_filename_database(const char*);
SQLITE_API const char *sqlite3_filename_journal(const char*); SQLITE_API const char *sqlite3_filename_journal(const char*);
SQLITE_API const char *sqlite3_filename_wal(const char*); SQLITE_API const char *sqlite3_filename_wal(const char*);
/*
** CAPI3REF: Database File Corresponding To A Journal
**
** ^If X is the name of a rollback or WAL-mode journal file that is
** passed into the xOpen method of [sqlite3_vfs], then
** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
** object that represents the main database file.
**
** This routine is intended for use in custom [VFS] implementations
** only. It is not a general-purpose interface.
** The argument sqlite3_file_object(X) must be a filename pointer that
** has been passed into [sqlite3_vfs].xOpen method where the
** flags parameter to xOpen contains one of the bits
** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
** of this routine results in undefined and probably undesirable
** behavior.
*/
SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
/*
** CAPI3REF: Create and Destroy VFS Filenames
**
** These interfces are provided for use by [VFS shim] implementations and
** are not useful outside of that context.
**
** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
** database filename D with corresponding journal file J and WAL file W and
** with N URI parameters key/values pairs in the array P. The result from
** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
** is safe to pass to routines like:
** <ul>
** <li> [sqlite3_uri_parameter()],
** <li> [sqlite3_uri_boolean()],
** <li> [sqlite3_uri_int64()],
** <li> [sqlite3_uri_key()],
** <li> [sqlite3_filename_database()],
** <li> [sqlite3_filename_journal()], or
** <li> [sqlite3_filename_wal()].
** </ul>
** If a memory allocation error occurs, sqlite3_create_filename() might
** return a NULL pointer. The memory obtained from sqlite3_create_filename(X)
** must be released by a corresponding call to sqlite3_free_filename(Y).
**
** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
** of 2*N pointers to strings. Each pair of pointers in this array corresponds
** to a key and value for a query parameter. The P parameter may be a NULL
** pointer if N is zero. None of the 2*N pointers in the P array may be
** NULL pointers and key pointers should not be empty strings.
** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
** be NULL pointers, though they can be empty strings.
**
** The sqlite3_free_filename(Y) routine releases a memory allocation
** previously obtained from sqlite3_create_filename(). Invoking
** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
**
** If the Y parameter to sqlite3_free_filename(Y) is anything other
** than a NULL pointer or a pointer previously acquired from
** sqlite3_create_filename(), then bad things such as heap
** corruption or segfaults may occur. The value Y should be
** used again after sqlite3_free_filename(Y) has been called. This means
** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
** then the corresponding [sqlite3_module.xClose() method should also be
** invoked prior to calling sqlite3_free_filename(Y).
*/
SQLITE_API char *sqlite3_create_filename(
const char *zDatabase,
const char *zJournal,
const char *zWal,
int nParam,
const char **azParam
);
SQLITE_API void sqlite3_free_filename(char*);
/* /*
** CAPI3REF: Error Codes And Messages ** CAPI3REF: Error Codes And Messages
@@ -4199,12 +4293,30 @@ typedef struct sqlite3_context sqlite3_context;
** [sqlite3_bind_parameter_index()] API if desired. ^The index ** [sqlite3_bind_parameter_index()] API if desired. ^The index
** for "?NNN" parameters is the value of NNN. ** for "?NNN" parameters is the value of NNN.
** ^The NNN value must be between 1 and the [sqlite3_limit()] ** ^The NNN value must be between 1 and the [sqlite3_limit()]
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). ** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
** **
** ^The third argument is the value to bind to the parameter. ** ^The third argument is the value to bind to the parameter.
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() ** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter ** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
** is ignored and the end result is the same as sqlite3_bind_null(). ** is ignored and the end result is the same as sqlite3_bind_null().
** ^If the third parameter to sqlite3_bind_text() is not NULL, then
** it should be a pointer to well-formed UTF8 text.
** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
** it should be a pointer to well-formed UTF16 text.
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
** it should be a pointer to a well-formed unicode string that is
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
** otherwise.
**
** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
** found in first character, which is removed, or in the absence of a BOM
** the byte order is the native byte order of the host
** machine for sqlite3_bind_text16() or the byte order specified in
** the 6th parameter for sqlite3_bind_text64().)^
** ^If UTF16 input text contains invalid unicode
** characters, then SQLite might change those invalid characters
** into the unicode replacement character: U+FFFD.
** **
** ^(In those routines that have a fourth argument, its value is the ** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter. To be clear: the value is the ** number of bytes in the parameter. To be clear: the value is the
@@ -4218,7 +4330,7 @@ typedef struct sqlite3_context sqlite3_context;
** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset ** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL ** where the NUL terminator would occur assuming the string were NUL
** terminated. If any NUL characters occur at byte offsets less than ** terminated. If any NUL characters occurs at byte offsets less than
** the value of the fourth parameter then the resulting string value will ** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings ** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined. ** with embedded NULs is undefined.
@@ -5386,7 +5498,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
** **
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the ** determined by the N parameter on first successful call. Changing the
** value of N in any subsequents call to sqlite3_aggregate_context() within ** value of N in any subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory ** the same aggregate function instance will not resize the memory
** allocation.)^ Within the xFinal callback, it is customary to set ** allocation.)^ Within the xFinal callback, it is customary to set
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no ** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
@@ -5543,8 +5655,9 @@ typedef void (*sqlite3_destructor_type)(void*);
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() ** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
** as the text of an error message. ^SQLite interprets the error ** as the text of an error message. ^SQLite interprets the error
** message string from sqlite3_result_error() as UTF-8. ^SQLite ** message string from sqlite3_result_error() as UTF-8. ^SQLite
** interprets the string from sqlite3_result_error16() as UTF-16 in native ** interprets the string from sqlite3_result_error16() as UTF-16 using
** byte order. ^If the third parameter to sqlite3_result_error() ** the same [byte-order determination rules] as [sqlite3_bind_text16()].
** ^If the third parameter to sqlite3_result_error()
** or sqlite3_result_error16() is negative then SQLite takes as the error ** or sqlite3_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character. ** message all text up through the first zero character.
** ^If the third parameter to sqlite3_result_error() or ** ^If the third parameter to sqlite3_result_error() or
@@ -5612,6 +5725,25 @@ typedef void (*sqlite3_destructor_type)(void*);
** then SQLite makes a copy of the result into space obtained ** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns. ** from [sqlite3_malloc()] before it returns.
** **
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
** when the encoding is not UTF8, if the input UTF16 begins with a
** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
** string and the rest of the string is interpreted according to the
** byte-order specified by the BOM. ^The byte-order specified by
** the BOM at the beginning of the text overrides the byte-order
** specified by the interface procedure. ^So, for example, if
** sqlite3_result_text16le() is invoked with text that begins
** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
** first two bytes of input are skipped and the remaining input
** is interpreted as UTF16BE text.
**
** ^For UTF16 input text to the sqlite3_result_text16(),
** sqlite3_result_text16be(), sqlite3_result_text16le(), and
** sqlite3_result_text64() routines, if the text contains invalid
** UTF16 characters, the invalid characters might be converted
** into the unicode replacement character, U+FFFD.
**
** ^The sqlite3_result_value() interface sets the result of ** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy of the ** the application-defined function to be a copy of the
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The ** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
@@ -5817,51 +5949,6 @@ SQLITE_API int sqlite3_collation_needed16(
void(*)(void*,sqlite3*,int eTextRep,const void*) void(*)(void*,sqlite3*,int eTextRep,const void*)
); );
#ifdef SQLITE_HAS_CODEC
/*
** Specify the key for an encrypted database. This routine should be
** called right after sqlite3_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
SQLITE_API int sqlite3_key_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The key */
);
/*
** Change the key on an open database. If the current database is not
** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
SQLITE_API int sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);
/*
** Specify the activation key for a SEE database. Unless
** activated, none of the SEE routines will work.
*/
SQLITE_API void sqlite3_activate_see(
const char *zPassPhrase /* Activation phrase */
);
#endif
#ifdef SQLITE_ENABLE_CEROD #ifdef SQLITE_ENABLE_CEROD
/* /*
** Specify the activation key for a CEROD database. Unless ** Specify the activation key for a CEROD database. Unless
@@ -6100,6 +6187,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
*/ */
SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine the transaction state of a database
** METHOD: sqlite3
**
** ^The sqlite3_txn_state(D,S) interface returns the current
** [transaction state] of schema S in database connection D. ^If S is NULL,
** then the highest transaction state of any schema on database connection D
** is returned. Transaction states are (in order of lowest to highest):
** <ol>
** <li value="0"> SQLITE_TXN_NONE
** <li value="1"> SQLITE_TXN_READ
** <li value="2"> SQLITE_TXN_WRITE
** </ol>
** ^If the S argument to sqlite3_txn_state(D,S) is not the name of
** a valid schema, then -1 is returned.
*/
SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
/*
** CAPI3REF: Allowed return values from [sqlite3_txn_state()]
** KEYWORDS: {transaction state}
**
** These constants define the current transaction state of a database file.
** ^The [sqlite3_txn_state(D,S)] interface returns one of these
** constants in order to describe the transaction state of schema S
** in [database connection] D.
**
** <dl>
** [[SQLITE_TXN_NONE]] <dt>SQLITE_TXN_NONE</dt>
** <dd>The SQLITE_TXN_NONE state means that no transaction is currently
** pending.</dd>
**
** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt>
** <dd>The SQLITE_TXN_READ state means that the database is currently
** in a read transaction. Content has been read from the database file
** but nothing in the database file has changed. The transaction state
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are
** no other conflicting concurrent write transactions. The transaction
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
** [COMMIT].</dd>
**
** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt>
** <dd>The SQLITE_TXN_WRITE state means that the database is currently
** in a write transaction. Content has been written to the database file
** but has not yet committed. The transaction state will change to
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
*/
#define SQLITE_TXN_NONE 0
#define SQLITE_TXN_READ 1
#define SQLITE_TXN_WRITE 2
/* /*
** CAPI3REF: Find the next prepared statement ** CAPI3REF: Find the next prepared statement
** METHOD: sqlite3 ** METHOD: sqlite3
@@ -6190,7 +6328,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** ^In the case of an update, this is the [rowid] after the update takes place. ** ^In the case of an update, this is the [rowid] after the update takes place.
** **
** ^(The update hook is not invoked when internal system tables are ** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^ ** modified (i.e. sqlite_sequence).)^
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
** **
** ^In the current implementation, the update hook ** ^In the current implementation, the update hook
@@ -7292,7 +7430,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** <ul> ** <ul>
** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_FAST
** <li> SQLITE_MUTEX_RECURSIVE ** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER ** <li> SQLITE_MUTEX_STATIC_MAIN
** <li> SQLITE_MUTEX_STATIC_MEM ** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_OPEN ** <li> SQLITE_MUTEX_STATIC_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG ** <li> SQLITE_MUTEX_STATIC_PRNG
@@ -7494,7 +7632,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
*/ */
#define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_FAST 0
#define SQLITE_MUTEX_RECURSIVE 1 #define SQLITE_MUTEX_RECURSIVE 1
#define SQLITE_MUTEX_STATIC_MASTER 2 #define SQLITE_MUTEX_STATIC_MAIN 2
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ #define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ #define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
@@ -7509,6 +7647,10 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */ #define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */
#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */ #define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */
/* Legacy compatibility: */
#define SQLITE_MUTEX_STATIC_MASTER 2
/* /*
** CAPI3REF: Retrieve the mutex for a database connection ** CAPI3REF: Retrieve the mutex for a database connection
** METHOD: sqlite3 ** METHOD: sqlite3
@@ -7604,7 +7746,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_PENDING_BYTE 11
#define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ASSERT 12
#define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
@@ -7622,7 +7764,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_RESULT_INTREAL 27
#define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_PRNG_SEED 28
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ #define SQLITE_TESTCTRL_SEEK_COUNT 30
#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */
/* /*
** CAPI3REF: SQL Keyword Checking ** CAPI3REF: SQL Keyword Checking
@@ -9102,10 +9245,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
** **
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
** method of a [virtual table], then it returns true if and only if the ** method of a [virtual table], then it might return true if the
** column is being fetched as part of an UPDATE operation during which the ** column is being fetched as part of an UPDATE operation during which the
** column value will not change. Applications might use this to substitute ** column value will not change. The virtual table implementation can use
** a return value that is less expensive to compute and that the corresponding ** this hint as permission to substitute a return value that is less
** expensive to compute and that the corresponding
** [xUpdate] method understands as a "no-change" value. ** [xUpdate] method understands as a "no-change" value.
** **
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
@@ -9114,6 +9258,12 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
** In that case, [sqlite3_value_nochange(X)] will return true for the ** In that case, [sqlite3_value_nochange(X)] will return true for the
** same column in the [xUpdate] method. ** same column in the [xUpdate] method.
**
** The sqlite3_vtab_nochange() routine is an optimization. Virtual table
** implementations should continue to give a correct answer even if the
** sqlite3_vtab_nochange() interface were to always return false. In the
** current implementation, the sqlite3_vtab_nochange() interface does always
** returns false for the enhanced [UPDATE FROM] statement.
*/ */
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
@@ -9255,6 +9405,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/* /*
** CAPI3REF: Flush caches to disk mid-transaction ** CAPI3REF: Flush caches to disk mid-transaction
** METHOD: sqlite3
** **
** ^If a write-transaction is open on [database connection] D when the ** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
@@ -9287,6 +9438,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
/* /*
** CAPI3REF: The pre-update hook. ** CAPI3REF: The pre-update hook.
** METHOD: sqlite3
** **
** ^These interfaces are only available if SQLite is compiled using the ** ^These interfaces are only available if SQLite is compiled using the
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
@@ -9304,7 +9456,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** **
** ^The preupdate hook only fires for changes to real database tables; the ** ^The preupdate hook only fires for changes to real database tables; the
** preupdate hook is not invoked for changes to [virtual tables] or to ** preupdate hook is not invoked for changes to [virtual tables] or to
** system tables like sqlite_master or sqlite_stat1. ** system tables like sqlite_sequence or sqlite_stat1.
** **
** ^The second parameter to the preupdate callback is a pointer to ** ^The second parameter to the preupdate callback is a pointer to
** the [database connection] that registered the preupdate hook. ** the [database connection] that registered the preupdate hook.
@@ -9327,7 +9479,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** seventh parameter is the final rowid value of the row being inserted ** seventh parameter is the final rowid value of the row being inserted
** or updated. The value of the seventh parameter passed to the callback ** or updated. The value of the seventh parameter passed to the callback
** function is not defined for operations on WITHOUT ROWID tables, or for ** function is not defined for operations on WITHOUT ROWID tables, or for
** INSERT operations on rowid tables. ** DELETE operations on rowid tables.
** **
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
@@ -9389,6 +9541,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
/* /*
** CAPI3REF: Low-level system error code ** CAPI3REF: Low-level system error code
** METHOD: sqlite3
** **
** ^Attempt to return the underlying operating system error code or error ** ^Attempt to return the underlying operating system error code or error
** number that caused the most recent I/O error or failure to open a file. ** number that caused the most recent I/O error or failure to open a file.

View File

@@ -330,6 +330,13 @@ struct sqlite3_api_routines {
const char *(*filename_database)(const char*); const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*); const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*); const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(char*);
sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*);
}; };
/* /*
@@ -630,6 +637,12 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_filename_database sqlite3_api->filename_database #define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal #define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal #define sqlite3_filename_wal sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename sqlite3_api->create_filename
#define sqlite3_free_filename sqlite3_api->free_filename
#define sqlite3_database_file_object sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state sqlite3_api->txn_state
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)

View File

@@ -38,6 +38,14 @@
# pragma GCC diagnostic ignored "-Wignored-qualifiers" # pragma GCC diagnostic ignored "-Wignored-qualifiers"
#endif #endif
#define CARRAY_INT32 0 /* Data is 32-bit signed integers */
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE 2 /* Data is doubles */
#define CARRAY_TEXT 3 /* Data is char* */
extern "C" int sqlite3_carray_bind(
sqlite3_stmt *pStmt, int idx, void *aData, int nData, int mFlags, void (*xDestroy)(void *));
namespace Sqlite { namespace Sqlite {
BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database) BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database)
@@ -180,6 +188,54 @@ void BaseStatement::bind(int index, void *pointer)
checkForBindingError(resultCode); checkForBindingError(resultCode);
} }
void BaseStatement::bind(int index, Utils::span<int> values)
{
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
index,
values.data(),
static_cast<int>(values.size()),
CARRAY_INT32,
SQLITE_STATIC);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode);
}
void BaseStatement::bind(int index, Utils::span<long long> values)
{
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
index,
values.data(),
static_cast<int>(values.size()),
CARRAY_INT64,
SQLITE_STATIC);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode);
}
void BaseStatement::bind(int index, Utils::span<double> values)
{
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
index,
values.data(),
static_cast<int>(values.size()),
CARRAY_DOUBLE,
SQLITE_STATIC);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode);
}
void BaseStatement::bind(int index, Utils::span<const char *> values)
{
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
index,
values.data(),
static_cast<int>(values.size()),
CARRAY_TEXT,
SQLITE_STATIC);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode);
}
void BaseStatement::bind(int index, Utils::SmallStringView text) void BaseStatement::bind(int index, Utils::SmallStringView text)
{ {
int resultCode = sqlite3_bind_text(m_compiledStatement.get(), int resultCode = sqlite3_bind_text(m_compiledStatement.get(),

View File

@@ -77,12 +77,16 @@ public:
int columnCount() const; int columnCount() const;
void bind(int index, NullValue); void bind(int index, NullValue);
void bind(int index, int fetchValue); void bind(int index, int value);
void bind(int index, long long fetchValue); void bind(int index, long long value);
void bind(int index, double fetchValue); void bind(int index, double value);
void bind(int index, void *pointer); void bind(int index, void *pointer);
void bind(int index, Utils::SmallStringView fetchValue); void bind(int index, Utils::span<int> values);
void bind(int index, const Value &fetchValue); void bind(int index, Utils::span<long long> values);
void bind(int index, Utils::span<double> values);
void bind(int index, Utils::span<const char *> values);
void bind(int index, Utils::SmallStringView value);
void bind(int index, const Value &value);
void bind(int index, BlobView blobView); void bind(int index, BlobView blobView);
void bind(int index, uint value) { bind(index, static_cast<long long>(value)); } void bind(int index, uint value) { bind(index, static_cast<long long>(value)); }

View File

@@ -54,7 +54,7 @@ DatabaseBackend::~DatabaseBackend()
closeWithoutException(); closeWithoutException();
} }
void DatabaseBackend::setMmapSize(qint64 defaultSize, qint64 maximumSize) void DatabaseBackend::setRanslatorentriesapSize(qint64 defaultSize, qint64 maximumSize)
{ {
int resultCode = sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, defaultSize, maximumSize); int resultCode = sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, defaultSize, maximumSize);
checkMmapSizeIsSet(resultCode); checkMmapSizeIsSet(resultCode);

View File

@@ -50,7 +50,7 @@ public:
DatabaseBackend(DatabaseBackend &&) = delete; DatabaseBackend(DatabaseBackend &&) = delete;
DatabaseBackend &operator=(DatabaseBackend &&) = delete; DatabaseBackend &operator=(DatabaseBackend &&) = delete;
static void setMmapSize(qint64 defaultSize, qint64 maximumSize); static void setRanslatorentriesapSize(qint64 defaultSize, qint64 maximumSize);
static void activateMultiThreading(); static void activateMultiThreading();
static void activateLogging(); static void activateLogging();
static void initializeSqliteLibrary(); static void initializeSqliteLibrary();

View File

@@ -258,6 +258,62 @@ TEST_F(SqliteStatement, BindPointer)
ASSERT_THAT(statement.fetchIntValue(0), 1); ASSERT_THAT(statement.fetchIntValue(0), 1);
} }
TEST_F(SqliteStatement, BindIntCarray)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<int> values{3, 10, 20, 33, 55};
statement.bind(1, values);
statement.next();
statement.next();
statement.next();
statement.next();
ASSERT_THAT(statement.fetchIntValue(0), 33);
}
TEST_F(SqliteStatement, BindLongLongCarray)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<long long> values{3, 10, 20, 33, 55};
statement.bind(1, values);
statement.next();
statement.next();
statement.next();
statement.next();
ASSERT_THAT(statement.fetchLongLongValue(0), 33);
}
TEST_F(SqliteStatement, BindDoubleCarray)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<double> values{3.3, 10.2, 20.54, 33.21, 55};
statement.bind(1, values);
statement.next();
statement.next();
statement.next();
statement.next();
ASSERT_THAT(statement.fetchDoubleValue(0), 33.21);
}
TEST_F(SqliteStatement, BindTextCarray)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<const char *> values{"yi", "er", "san", "se", "wu"};
statement.bind(1, values);
statement.next();
statement.next();
statement.next();
statement.next();
ASSERT_THAT(statement.fetchSmallStringViewValue(0), Eq("se"));
}
TEST_F(SqliteStatement, BindBlob) TEST_F(SqliteStatement, BindBlob)
{ {
SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database);
@@ -378,6 +434,47 @@ TEST_F(SqliteStatement, WritePointerValues)
ASSERT_THAT(statement.template values<int>(5), ElementsAre(1, 1, 2, 3, 5)); ASSERT_THAT(statement.template values<int>(5), ElementsAre(1, 1, 2, 3, 5));
} }
TEST_F(SqliteStatement, WriteIntCarrayValues)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<int> values{3, 10, 20, 33, 55};
statement.write(Utils::span(values));
ASSERT_THAT(statement.template values<int>(5), ElementsAre(3, 10, 20, 33, 55));
}
TEST_F(SqliteStatement, WriteLongLongCarrayValues)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<long long> values{3, 10, 20, 33, 55};
statement.write(Utils::span(values));
ASSERT_THAT(statement.template values<long long>(5), ElementsAre(3, 10, 20, 33, 55));
}
TEST_F(SqliteStatement, WriteDoubleCarrayValues)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<double> values{3.3, 10.2, 20.54, 33.21, 55};
statement.write(Utils::span(values));
ASSERT_THAT(statement.template values<double>(5), ElementsAre(3.3, 10.2, 20.54, 33.21, 55));
}
TEST_F(SqliteStatement, WriteTextCarrayValues)
{
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
std::vector<const char *> values{"yi", "er", "san", "se", "wu"};
statement.write(Utils::span(values));
ASSERT_THAT(statement.template values<Utils::SmallString>(5),
ElementsAre("yi", "er", "san", "se", "wu"));
}
TEST_F(SqliteStatement, WriteNullValues) TEST_F(SqliteStatement, WriteNullValues)
{ {
WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);