diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c index ff6d994d90..a446238be3 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c @@ -28,7 +28,14 @@ ** README.md ** configure ** configure.ac +** doc/compile-for-windows.md +** doc/jsonb.md +** doc/testrunner.md +** doc/trusted-schema.md +** doc/vdbesort-memory.md +** doc/wal-lock.md ** ext/fts5/fts5_tokenize.c +** ext/jni/README.md ** ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java ** ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java ** ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java @@ -81,38 +88,9 @@ ** src/where.c ** src/wherecode.c ** test/all.test -** test/dbdata.test -** test/dbfuzz.c -** test/dbfuzz001.test -** test/dbfuzz2-seed1.db -** test/dbfuzz2.c -** test/dbpage.test -** test/dbpagefault.test -** test/dbstatus.test -** test/dbstatus2.test -** test/delete_db.test -** test/fuzzdata1.db -** test/fuzzdata2.db -** test/fuzzdata3.db -** test/fuzzdata4.db -** test/fuzzdata5.db -** test/fuzzdata6.db -** test/fuzzdata7.db -** test/fuzzdata8.db -** test/indexedby.test -** test/manydb.test -** test/memdb.test -** test/memdb1.test -** test/memdb2.test -** test/optfuzz-db01.c -** test/optfuzz-db01.txt +** test/json/README.md ** test/permutations.test -** test/resetdb.test ** test/rowvaluevtab.test -** test/sessionfuzz-data1.db -** test/tempdb.test -** test/tempdb2.test -** test/tkt-94c04eaadb.test ** tool/mkkeywordhash.c ** tool/mksqlite3c-noext.tcl ** tool/mksqlite3c.tcl @@ -65386,18 +65364,25 @@ SQLITE_PRIVATE int sqlite3PagerWalInsert(Pager *pPager, unsigned int iFrame, voi } if (iFrame <= mxFrame) { unsigned long frame_len = nBuf-24; - unsigned char current[frame_len]; + unsigned char *current; + + current = (unsigned char *)sqlite3MallocZero(frame_len); + if (current == NULL) { + return SQLITE_NOMEM; + } rc = pPager->wal->methods.xReadFrame(pPager->wal->pData, iFrame, frame_len, current); if (rc != SQLITE_OK) { + sqlite3_free(current); return rc; } int conflict = 0; - if (memcmp(pBuf+24, current, frame_len) != 0) { + if (memcmp((unsigned char*)pBuf+24, current, frame_len) != 0) { conflict = 1; } if (pConflict) { *pConflict = conflict; } + sqlite3_free(current); if (conflict) { return SQLITE_ERROR; } @@ -67628,6 +67613,15 @@ static int walCheckpoint( } } + +#ifdef LIBSQL_CHECKPOINT_ONLY_FULL + // in case of LIBSQL_CHECKPOINT_ONLY_FULL option we want to either checkpoint whole WAL or quickly abort the checkpoint + if( mxSafeFrame!=walIndexHdr(pWal)->mxFrame ){ + rc = SQLITE_BUSY; + goto walcheckpoint_out; + } +#endif + /* Allocate the iterator */ if( pInfo->nBackfillnBackfill, &pIter, mxSafeFrame, xCb == NULL); @@ -121878,6 +121872,10 @@ SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){ int libsql_handle_extra_attach_params(sqlite3* db, const char* zName, const char* zPath, sqlite3_value* pKey, char** zErrDyn); #endif +#ifdef LIBSQL_ENCRYPTION +SQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**); +#endif + /* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: @@ -122037,6 +122035,16 @@ static void attachFunc( rc = libsql_handle_extra_attach_params(db, zName, zPath, argv, &zErrDyn); } #endif + +#ifdef LIBSQL_ENCRYPTION + /* If the ATTACH statement came with key parameter, then lets handle it here. */ + if( rc==SQLITE_OK ){ + if( argv != NULL && argv[0] != NULL && argv[1] != NULL && argv[2] != NULL ){ + rc = sqlite3mcHandleAttachKey(db, zName, zPath, argv[2], &zErrDyn); + } + } +#endif + sqlite3_free_filename( zPath ); /* If the file was opened successfully, read the schema for the new database. diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h index ef0237bde4..be068ebe3f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h @@ -89,6 +89,9 @@ extern "C" { #ifndef SQLITE_SYSAPI # define SQLITE_SYSAPI #endif +#ifndef LIBSQL_API +# define LIBSQL_API +#endif /* ** These no-op macros are used in front of interfaces to mark those @@ -146,9 +149,11 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.2" -#define SQLITE_VERSION_NUMBER 3044002 -#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" +#define SQLITE_VERSION "3.45.1" +#define SQLITE_VERSION_NUMBER 3045001 +#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1" + +#define LIBSQL_VERSION "0.2.3" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -187,6 +192,8 @@ SQLITE_API const char *sqlite3_libversion(void); SQLITE_API const char *sqlite3_sourceid(void); SQLITE_API int sqlite3_libversion_number(void); +SQLITE_API const char *libsql_libversion(void); + /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** @@ -1007,6 +1014,13 @@ struct sqlite3_io_methods { ** ^When there are multiple VFS shims in the stack, this opcode finds the ** upper-most shim only. ** +**
  • [[SQLITE_FCNTL_WAL_METHODS_POINTER]] +** ^The [SQLITE_FCNTL_WAL_METHODS_POINTER] opcode finds a pointer to the top-level +** WAL methods currently in use. ^(The argument X in +** sqlite3_file_control(db,SQLITE_FCNTL_WAL_METHODS_POINTER,X) must be +** of type "[libsql_wal_methods] **". This opcodes will set *X +** to a pointer to the top-level WAL methods.)^ +** **
  • [[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding @@ -1243,6 +1257,9 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +// libSQL extension +#define SQLITE_FCNTL_WAL_METHODS_POINTER 129 + /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE @@ -1271,6 +1288,16 @@ typedef struct sqlite3_mutex sqlite3_mutex; */ typedef struct sqlite3_api_routines sqlite3_api_routines; +/* +** CAPI3REF: Loadable Extension Thunk +** +** A pointer to the opaque libsql_api_routines structure is passed as +** the fourth parameter to entry points of [loadable extensions]. This +** structure must be typedefed in order to work around compiler warnings +** on some platforms. +*/ +typedef struct libsql_api_routines libsql_api_routines; + /* ** CAPI3REF: File Name ** @@ -3751,6 +3778,40 @@ SQLITE_API int sqlite3_open_v2( const char *zVfs /* Name of VFS module to use */ ); +typedef struct libsql_wal_manager libsql_wal_manager; + +SQLITE_API int libsql_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal /* Name of WAL module to use */ +); + +/* deprecated, only works with zWal == NULL */ +SQLITE_API int libsql_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + const char *zWal, /* Name of WAL module to use */ + void* pWalMethodsData /* User data, passed to the libsql_wal struct*/ +); + +SQLITE_API int libsql_open_v3( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use, NULL for default */ + libsql_wal_manager wal_manager /* wal_manager instance, in charge of instanciating a wal */ +); + +typedef struct sqlite3_wal sqlite3_wal; +SQLITE_API int sqlite3_wal_backfilled(sqlite3_wal *pWal); +SQLITE_API unsigned int sqlite3_wal_frame_page_no(sqlite3_wal *pWal, unsigned int iFrame); + +SQLITE_API LIBSQL_API int libsql_try_initialize_wasm_func_table(sqlite3 *db); + /* ** CAPI3REF: Obtain Values For URI Parameters ** @@ -3954,15 +4015,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not an +** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** @@ -5327,6 +5390,8 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); +SQLITE_API void libsql_stmt_interrupt(sqlite3_stmt *stmt); + /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -7323,6 +7388,11 @@ struct sqlite3_module { ** Those below are for version 4 and greater. */ int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, const char *zTabName, int mFlags, char **pzErr); + + // reserved for sqlite extension + void (*reserved[5])(); + // following methods are added by libsql + int (*xPreparedSql)(sqlite3_vtab_cursor*, const char*); }; /* @@ -7606,9 +7676,9 @@ SQLITE_API int sqlite3_drop_modules( ** freed by sqlite3_free() and the zErrMsg field will be zeroed. */ struct sqlite3_vtab { - const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* Number of open cursors */ - char *zErrMsg; /* Error message from sqlite3_mprintf() */ + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Number of open cursors */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; @@ -7938,6 +8008,28 @@ SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); +/* +** CAPI3REF: Virtual WAL Methods +** +** Virtual WAL methods can be redefined in order to change the default +** behavior of the write-ahead log. +** Methods can be registered and unregistered. +** The following interfaces are provided. +** +** ^The libsql_wal_methods_find() interface returns a pointer +** to the methods given their identifier. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zName is NULL then the default implementation is returned. +** +** ^New WAL methods are registered with libsql_wal_methods_register(). +** ^Same methods can be registered multiple times without injury. +** +** ^Unregister WAL methods with the libsql_wal_methods_unregister() interface. +*/ +typedef struct libsql_wal_methods libsql_wal_methods; + /* ** CAPI3REF: Mutexes ** @@ -8037,9 +8129,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior @@ -8298,6 +8392,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ @@ -8643,6 +8738,10 @@ SQLITE_API int sqlite3_status64( */ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +#ifdef LIBSQL_CUSTOM_PAGER_CODEC +SQLITE_API void *libsql_leak_pager(sqlite3*); +#endif + /* ** CAPI3REF: Status Parameters for database connections ** KEYWORDS: {SQLITE_DBSTATUS options} @@ -8860,6 +8959,14 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. ** ** +** +** [[LIBSQL_STMTSTATUS_ROWS_READ]] +** [[LIBSQL_STMTSTATUS_ROWS_WRITTEN]] +**
    LIBSQL_STMTSTATUS_ROWS_READ
    +** LIBSQL_STMTSTATUS_ROWS_WRITTEN
    +**
    ^LIBSQL_STMTSTATUS_ROWS_READ is the number of rows read when executing +** this statement. LIBSQL_STMTSTATUS_ROWS_WRITTEN value is the number of +** rows written. */ #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 #define SQLITE_STMTSTATUS_SORT 2 @@ -8871,6 +8978,10 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 +#define LIBSQL_STMTSTATUS_BASE 1024 +#define LIBSQL_STMTSTATUS_ROWS_READ LIBSQL_STMTSTATUS_BASE + 1 +#define LIBSQL_STMTSTATUS_ROWS_WRITTEN LIBSQL_STMTSTATUS_BASE + 2 + /* ** CAPI3REF: Custom Page Cache Object ** @@ -10424,6 +10535,75 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); #endif +/* +** CAPI3REF: The close hook. +** METHOD: sqlite3 +** +** ^The [libsql_close_hook()] interface registers a callback function +** that is invoked prior to closing the database connection. +** ^At most one close hook may be registered at a time on a single +** [database connection]; each call to [libsql_close_hook()] overrides +** the previous setting. +** ^The close hook is disabled by invoking [libsql_close_hook()] +** with a NULL pointer as the second parameter. +** ^The third parameter to [libsql_close_hook()] is passed through as +** the first parameter to callbacks. +*/ +SQLITE_API void *libsql_close_hook(sqlite3 *db, void (*xClose)(void *pCtx, sqlite3 *db), void *arg); + +/* +** CAPI3REF: Disable WAL checkpointing +** METHOD: sqlite3 +** +** ^The [libsql_wal_disable_checkpoint(D)] interface disables automatic +** checkpointing of the WAL file for [database connection] D. +** +** Note: This function disables WAL checkpointing entirely, including when +** the last database connection is closed. This is different from +** sqlite3_wal_autocheckpoint() which only disables automatic checkpoints +** for the current connection, but still allows checkpointing when the +** connection is closed. +*/ +SQLITE_API int libsql_wal_disable_checkpoint(sqlite3 *db); + +/* +** CAPI3REF: Get the number of frames in the WAL file +** METHOD: sqlite3 +** +** ^The [libsql_wal_frame_count(D,P)] interface returns the number of frames +** in the WAL file for [database connection] D into *P. +*/ +SQLITE_API int libsql_wal_frame_count(sqlite3*, unsigned int*); + +/* +** CAPI3REF: Get a frame from the WAL file +** METHOD: sqlite3 +** +** ^The [libsql_wal_get_frame(D,I,P,S)] interface extracts frame I from +** the WAL file for [database connection] D into memory obtained from +** [sqlite3_malloc64()] and returns a pointer to that memory. The size of +** the memory allocated is given by S. +*/ +SQLITE_API int libsql_wal_get_frame(sqlite3*, unsigned int, void*, unsigned int); + +/* +** CAPI3REF: Begin frame insertion into the WAL +** METHOD: sqlite3 +*/ +SQLITE_API int libsql_wal_insert_begin(sqlite3*); + +/* +** CAPI3REF: End frame insertion into the WAL +** METHOD: sqlite3 +*/ +SQLITE_API int libsql_wal_insert_end(sqlite3*); + +/* +** CAPI3REF: Insert a frame into the WAL +** METHOD: sqlite3 +*/ +SQLITE_API int libsql_wal_insert_frame(sqlite3*, unsigned int, void *, unsigned int, int *); + /* ** CAPI3REF: Low-level system error code ** METHOD: sqlite3 @@ -10781,8 +10961,9 @@ SQLITE_API int sqlite3_deserialize( #if defined(__wasi__) # undef SQLITE_WASI # define SQLITE_WASI 1 -# undef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ +// NOTICE: we do support WAL mode, we just don't support shared memory +//# undef SQLITE_OMIT_WAL +//# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ # ifndef SQLITE_OMIT_LOAD_EXTENSION # define SQLITE_OMIT_LOAD_EXTENSION # endif @@ -12811,8 +12992,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -12822,8 +13006,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -12839,12 +13025,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -12870,6 +13057,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -12984,9 +13175,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13021,6 +13245,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* @@ -13298,3 +13529,357 @@ struct fts5_api { #endif /* _FTS5_H */ /******** End of fts5.h *********/ +/******** Begin file page_header.h *********/ +// SPDX-License-Identifier: MIT + +#ifndef LIBSQL_PAGE_HEADER_H +#define LIBSQL_PAGE_HEADER_H + +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +typedef struct Pager Pager; +typedef struct libsql_pghdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct libsql_pghdr { + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ + void *pExtra; /* Extra content */ + PCache *pCache; /* PRIVATE: Cache that owns this page */ + PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ + Pager *pPager; /* The pager this page is part of */ + unsigned int pgno; /* Page number for this page */ + unsigned int pageHash; /* Hash of page content */ + unsigned short flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above, except pCache, are public. All that follow are + ** private to pcache.c and should not be accessed by other modules. + ** pCache is grouped with the public elements for efficiency. + */ + unsigned long long nRef; /* Number of users of this page */ + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ + /* NB: pDirtyNext and pDirtyPrev are undefined if the + ** PgHdr object is not dirty */ +}; + +typedef struct libsql_pghdr libsql_pghdr; + +#endif // LIBSQL_PAGE_HEADER_H + +/******** End of page_header.h *********/ +/******** Begin file wal.h *********/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef SQLITE_WAL_H +#define SQLITE_WAL_H + + +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): +*/ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct libsql_wal libsql_wal; +typedef struct libsql_wal_manager libsql_wal_manager; +/* Opaque types for wal method data */ +typedef struct wal_impl wal_impl; +typedef struct wal_manager_impl wal_manager_impl; + +typedef struct libsql_wal_methods { + int iVersion; /* Current version is 1, versioning is here for backward compatibility */ + + /* Set the limiting size of a WAL file. */ + void (*xLimit)(wal_impl* pWal, long long limit); + + /* Used by readers to open (lock) and close (unlock) a snapshot. A + ** snapshot is like a read-transaction. It is the state of the database + ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and + ** preserves the current state even if the other threads or processes + ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the + ** transaction and releases the lock. + */ + int (*xBeginReadTransaction)(wal_impl* pWal, int *); + void (*xEndReadTransaction)(wal_impl *); + + /* Read a page from the write-ahead log, if it is present. */ + int (*xFindFrame)(wal_impl* pWal, unsigned int, unsigned int *); + int (*xReadFrame)(wal_impl* pWal, unsigned int, int, unsigned char *); + int (*xReadFrameRaw)(wal_impl* pWal, unsigned int, int, unsigned char *); + + /* If the WAL is not empty, return the size of the database. */ + unsigned int (*xDbsize)(wal_impl* pWal); + + /* Obtain or release the WRITER lock. */ + int (*xBeginWriteTransaction)(wal_impl* pWal); + int (*xEndWriteTransaction)(wal_impl* pWal); + + /* Undo any frames written (but not committed) to the log */ + int (*xUndo)(wal_impl* pWal, int (*xUndo)(void *, unsigned int), void *pUndoCtx); + + /* Return an integer that records the current (uncommitted) write + ** position in the WAL */ + void (*xSavepoint)(wal_impl* pWal, unsigned int *aWalData); + + /* Move the write position of the WAL back to iFrame. Called in + ** response to a ROLLBACK TO command. */ + int (*xSavepointUndo)(wal_impl* pWal, unsigned int *aWalData); + + /* Return the number of frames in the WAL */ + int (*xFrameCount)(wal_impl* pWal, int, unsigned int *); + + /* Write a frame or frames to the log. */ + int (*xFrames)(wal_impl* pWal, int, libsql_pghdr *, unsigned int, int, int, int*); + + /* Copy pages from the log to the database file */ + int (*xCheckpoint)( + wal_impl* pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + unsigned char *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt, /* OUT: Number of backfilled frames in WAL */ + /* + * Called for each page being inserted in the wal, and once if the whole checkpoint operation was successfull with pPage == NULL + */ + int (*xCb)(void* pCbData, int mxSafeFrame, const unsigned char* pPage, int nPage, int page_no, int frame_no), /* called */ + void* pCbData /* user data passed to xCb */ + ); + + /* Return the value to pass to a sqlite3_wal_hook callback, the + ** number of frames in the WAL at the point of the last commit since + ** sqlite3WalCallback() was called. If no commits have occurred since + ** the last call, then return 0. + */ + int (*xCallback)(wal_impl* pWal); + + /* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) + ** by the pager layer on the database file. + */ + int (*xExclusiveMode)(wal_impl* pWal, int op); + + /* Return true if the argument is non-NULL and the WAL module is using + ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the + ** WAL module is using shared-memory, return false. + */ + int (*xHeapMemory)(wal_impl* pWal); + + // Only needed with SQLITE_ENABLE_SNAPSHOT, but part of the ABI + int (*xSnapshotGet)(wal_impl* pWal, sqlite3_snapshot **ppSnapshot); + void (*xSnapshotOpen)(wal_impl* pWal, sqlite3_snapshot *pSnapshot); + int (*xSnapshotRecover)(wal_impl* pWal); + int (*xSnapshotCheck)(void* pWal, sqlite3_snapshot *pSnapshot); + void (*xSnapshotUnlock)(wal_impl* pWal); + + // Only needed with SQLITE_ENABLE_ZIPVFS, but part of the ABI + /* If the WAL file is not empty, return the number of bytes of content + ** stored in each frame (i.e. the db page-size when the WAL was created). + */ + int (*xFramesize)(wal_impl* pWal); + + + /* Return the sqlite3_file object for the WAL file */ + sqlite3_file *(*xFile)(wal_impl* pWal); + + // Only needed with SQLITE_ENABLE_SETLK_TIMEOUT + int (*xWriteLock)(wal_impl* pWal, int bLock); + + void (*xDb)(wal_impl* pWal, sqlite3 *db); +} libsql_wal_methods; + + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object followed by one instance of the WalCkptInfo object. +** For all versions of SQLite through 3.10.0 and probably beyond, +** the locking bytes (WalCkptInfo.aLock) start at offset 120 and +** the total header size is 136 bytes. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + unsigned int iVersion; /* Wal-index version */ + unsigned int unused; /* Unused (padding) field */ + unsigned int iChange; /* Counter incremented each transaction */ + unsigned char isInit; /* 1 when initialized */ + unsigned char bigEndCksum; /* True if checksums in WAL are big-endian */ + unsigned short szPage; /* Database page size in bytes. 1==64K */ + unsigned int mxFrame; /* Index of last valid frame in the WAL */ + unsigned int nPage; /* Size of database in pages */ + unsigned int aFrameCksum[2]; /* Checksum of last frame in log */ + unsigned int aSalt[2]; /* Two salt values copied from WAL header */ + unsigned int aCksum[2]; /* Checksum over all prior fields */ +}; + +struct libsql_wal_manager { + /* True if the implementation relies on shared memory routines (e.g. locks) */ + int bUsesShm; + + /* Open and close a connection to a write-ahead log. */ + int (*xOpen)(wal_manager_impl* pData, sqlite3_vfs*, sqlite3_file*, int no_shm_mode, long long max_size, const char* zMainDbFileName, libsql_wal* out_wal); + int (*xClose)(wal_manager_impl* pData, wal_impl* pWal, sqlite3* db, int sync_flags, int nBuf, unsigned char *zBuf); + + /* destroy resources for this wal */ + int (*xLogDestroy)(wal_manager_impl* pData, sqlite3_vfs *vfs, const char* zMainDbFileName); + /* returns whether this wal exists */ + int (*xLogExists)(wal_manager_impl* pData, sqlite3_vfs *vfs, const char* zMainDbFileName, int* exist); + /* destructor */ + void (*xDestroy)(wal_manager_impl* pData); + + wal_manager_impl* pData; +}; + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +typedef struct sqlite3_wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + unsigned int iCallback; /* Value to pass to log callback (or 0) */ + long long mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile unsigned int **apWiData; /* Pointer to wal-index content in memory */ + unsigned int szPage; /* Database page size */ + short readLock; /* Which read lock is being held. -1 for none */ + unsigned char syncFlags; /* Flags to use to sync header writes */ + unsigned char exclusiveMode; /* Non-zero if connection is in exclusive mode */ + unsigned char writeLock; /* True if in a write transaction */ + unsigned char ckptLock; /* True if holding a checkpoint lock */ + unsigned char readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + unsigned char truncateOnCommit; /* True to truncate WAL file on commit */ + unsigned char syncHeader; /* Fsync the WAL header if true */ + unsigned char padToSectorBoundary; /* Pad transactions out to the next sector */ + unsigned char bShmUnreliable; /* SHM content is read-only and unreliable */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + unsigned int minFrame; /* Ignore wal frames before this one */ + unsigned int iReCksum; /* On commit, recalculate checksums from here */ + const char *zWalName; /* Name of WAL file */ + unsigned int nCkpt; /* Checkpoint sequence counter in the wal-header */ + unsigned char lockError; /* True if a locking error has occurred */ + WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + sqlite3 *db; +} sqlite3_wal; + +struct libsql_wal { + libsql_wal_methods methods; /* virtual wal methods */ + wal_impl* pData; /* methods receiver */ +}; + +typedef struct RefCountedWalManager { + int n; + libsql_wal_manager ref; + int is_static; +} RefCountedWalManager; + +int make_ref_counted_wal_manager(libsql_wal_manager wal_manager, RefCountedWalManager **out); +void destroy_wal_manager(RefCountedWalManager *p); +RefCountedWalManager* clone_wal_manager(RefCountedWalManager *p); + +SQLITE_API int sqlite3_wal_backfilled(sqlite3_wal* pWal); +SQLITE_API unsigned int sqlite3_wal_frame_page_no(sqlite3_wal *pWal, unsigned int iFrame); + +RefCountedWalManager *make_sqlite3_wal_manager_rc(); + +SQLITE_API extern const libsql_wal_manager sqlite3_wal_manager; + +#endif /* SQLITE_WAL_H */ + +/******** End of wal.h *********/ +/******** Begin file wasm_bindings.h *********/ +/* SPDX-License-Identifier: MIT */ +#ifdef LIBSQL_ENABLE_WASM_RUNTIME + +#ifndef LIBSQL_WASM_BINDINGS_H +#define LIBSQL_WASM_BINDINGS_H + +typedef struct libsql_wasm_engine_t libsql_wasm_engine_t; +typedef struct libsql_wasm_module_t libsql_wasm_module_t; + +typedef struct libsql_wasm_udf_api { + int (*libsql_value_type)(sqlite3_value*); + int (*libsql_value_int)(sqlite3_value*); + double (*libsql_value_double)(sqlite3_value*); + const unsigned char *(*libsql_value_text)(sqlite3_value*); + const void *(*libsql_value_blob)(sqlite3_value*); + int (*libsql_value_bytes)(sqlite3_value*); + void (*libsql_result_error)(sqlite3_context*, const char*, int); + void (*libsql_result_error_nomem)(sqlite3_context*); + void (*libsql_result_int)(sqlite3_context*, int); + void (*libsql_result_double)(sqlite3_context*, double); + void (*libsql_result_text)(sqlite3_context*, const char*, int, void(*)(void*)); + void (*libsql_result_blob)(sqlite3_context*, const void*, int, void(*)(void*)); + void (*libsql_result_null)(sqlite3_context*); + void *(*libsql_malloc)(int); + void (*libsql_free)(void *); +} libsql_wasm_udf_api; + +/* +** Runs a WebAssembly user-defined function. +** Additional data can be accessed via sqlite3_user_data(context) +*/ +SQLITE_API void libsql_run_wasm(struct libsql_wasm_udf_api *api, sqlite3_context *context, + libsql_wasm_engine_t *engine, libsql_wasm_module_t *module, const char *func_name, int argc, sqlite3_value **argv); + +/* +** Compiles a WebAssembly module. Can accept both .wat and binary Wasm format, depending on the implementation. +** err_msg_buf needs to be deallocated with libsql_free_wasm_module. +*/ +SQLITE_API libsql_wasm_module_t *libsql_compile_wasm_module(libsql_wasm_engine_t* engine, const char *pSrcBody, int nBody, + void *(*alloc_err_buf)(unsigned long long), char **err_msg_buf); + +/* +** Frees a module allocated with libsql_compile_wasm_module +*/ +SQLITE_API void libsql_free_wasm_module(void *module); + +/* +** Creates a new wasm engine +*/ +SQLITE_API libsql_wasm_engine_t *libsql_wasm_engine_new(); +SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); + +#endif //LIBSQL_WASM_BINDINGS_H +#endif //LIBSQL_ENABLE_WASM_RUNTIME + +/******** End of wasm_bindings.h *********/ diff --git a/libsql-sqlite3/test/rust_suite/Cargo.toml b/libsql-sqlite3/test/rust_suite/Cargo.toml index 90a8251ebf..d6b12cb158 100644 --- a/libsql-sqlite3/test/rust_suite/Cargo.toml +++ b/libsql-sqlite3/test/rust_suite/Cargo.toml @@ -15,6 +15,7 @@ tempfile = "3.3" wabt = "0.10.0" hex = "0.4.3" rustc-hash = "1" +which = "=4.4.0" [features] default = [] diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 9a8a708e08..830cdd2d42 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -142,6 +142,18 @@ fn build_bundled() -> Result<()> { "libsql-ffi/bundled/src/sqlite3.h", ])?; + // Also update SQLite3MultipleCiphers bundled files + // These are used when building with --features multiple-ciphers + run_cp(&[ + "libsql-sqlite3/sqlite3.c", + "libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c", + ])?; + + run_cp(&[ + "libsql-sqlite3/sqlite3.h", + "libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h", + ])?; + Ok(()) }