Compare commits
156 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a56e248ea2 | |||
| a751fddd01 | |||
| 8cec7ac644 | |||
| 016214ddf7 | |||
| 3b171836ec | |||
| 21219fe313 | |||
| 4c6a1298f8 | |||
| b11e7e6aa7 | |||
| 3c44d50e47 | |||
| 9dc32eaa33 | |||
| 3903ad4497 | |||
| 655219897a | |||
| a4ccda2979 | |||
| 17b83d28b8 | |||
| 94dbae0c8d | |||
| 2fdb32316d | |||
| ec79dfaf7e | |||
| 2eec675e6e | |||
| ee8e00f53f | |||
| 0ed22ad847 | |||
| 936c8e42e1 | |||
| 0d8cea5109 | |||
| 68796a609b | |||
| ba9c7c10cc | |||
| 7d13a403c4 | |||
| b7e87a53c7 | |||
| e24103baad | |||
| 4891bf00db | |||
| 467d804e1a | |||
| ff46ff5c73 | |||
| b60eb8bf6e | |||
| 5d30acad2f | |||
| d352e7d6ac | |||
| 47409209c2 | |||
| 07a7cd3714 | |||
| 47e42cd143 | |||
| 757372ab56 | |||
| 9d086cc562 | |||
| 1fd73f2693 | |||
| 5267068d3d | |||
| 0205717b93 | |||
| cc74eafee5 | |||
| 45d92dd539 | |||
| 6fe6b73a8d | |||
| 7a1cc96197 | |||
| 1e6ee1929c | |||
| 832406c2b4 | |||
| 7331bc0002 | |||
| 6f5c4810bc | |||
| b9b790e8cc | |||
| ecd48447b2 | |||
| f578ed6838 | |||
| b17135d81f | |||
| 5d2f5f4655 | |||
| 1adff07cb9 | |||
| 5b39dd45e8 | |||
| d17b9114aa | |||
| 6c9cc2c4f8 | |||
| ca773a51de | |||
| ade7cd53ab | |||
| e3d452a826 | |||
| faff28a478 | |||
| 70cfee98e5 | |||
| d94023257b | |||
| 1651f418e5 | |||
| 77508c4768 | |||
| ce8a1720d6 | |||
| d9da500bd7 | |||
| 82ac3d8211 | |||
| 73b1ef33ef | |||
| b77b56bd52 | |||
| 86b7bb29da | |||
| e81feadb41 | |||
| 6c45111957 | |||
| 029eb1bf15 | |||
| 2a27e5e4cb | |||
| 6702d6dadc | |||
| 6c75609f48 | |||
| 981dcb6236 | |||
| 3f17a238bb | |||
| 5666f09523 | |||
| 8f1396ae8b | |||
| aed427074b | |||
| 348093c719 | |||
| b90edad19d | |||
| b321a9b0fa | |||
| 234f384386 | |||
| 7271df982d | |||
| f54bc90ca3 | |||
| fa4d43fb64 | |||
| c77906eedd | |||
| e1c2be1134 | |||
| 2303f0859c | |||
| 938ede2078 | |||
| 0f1e95e616 | |||
| ebc672832f | |||
| 67f562233f | |||
| 80189c5bfe | |||
| 17e08c6149 | |||
| e809deee13 | |||
| 226fda81af | |||
| c25b39e41d | |||
| 1a2a4f12dc | |||
| 50c9522c24 | |||
| 9bf3da81a0 | |||
| 174f4fa241 | |||
| aae84d814c | |||
| ea8c9a43aa | |||
| ca97a18493 | |||
| 69105498b9 | |||
| bd74861e91 | |||
| 6d671d4c09 | |||
| 8caab4aebe | |||
| b3168a0056 | |||
| 2c34d3c61e | |||
| d59a566707 | |||
| 254bcdd02d | |||
| e31602c62d | |||
| 1e469f79b1 | |||
| 6fdd8fc5f0 | |||
| e5fd180648 | |||
| b83e6e9420 | |||
| d9df7cb876 | |||
| 281ee2f754 | |||
| f552a23740 | |||
| 3eeda95d36 | |||
| 1f3762607d | |||
| d445ed094a | |||
| ce909d1aae | |||
| 0f297b6e50 | |||
| 2d111c8bbb | |||
| 665f3d209b | |||
| c5140b39ce | |||
| 93543215e0 | |||
| e698c1f79e | |||
| 597bf19266 | |||
| eeb778d506 | |||
| 2c4328ed87 | |||
| f17e510ee5 | |||
| ca72570a11 | |||
| d597b966d9 | |||
| c30d437376 | |||
| e05f922583 | |||
| 6456b3929c | |||
| 816fc35956 | |||
| 8eed108df1 | |||
| 6cbf8e173f | |||
| 2df2b3d05f | |||
| 40927fd61e | |||
| 50182fa846 | |||
| 5d122d308f | |||
| 288e98fb4b | |||
| bfcf8d6d67 | |||
| 24f1b25c7b | |||
| 3400e78f38 | |||
| 055cc1e431 |
@@ -428,6 +428,7 @@ TESTSRC += \
|
||||
$(TOP)/ext/expert/sqlite3expert.c \
|
||||
$(TOP)/ext/expert/test_expert.c \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/bgckpt.c \
|
||||
$(TOP)/ext/misc/appendvfs.c \
|
||||
$(TOP)/ext/misc/basexx.c \
|
||||
$(TOP)/ext/misc/carray.c \
|
||||
|
||||
@@ -1572,6 +1572,7 @@ TESTEXT = \
|
||||
$(TOP)\ext\misc\amatch.c \
|
||||
$(TOP)\ext\misc\appendvfs.c \
|
||||
$(TOP)\ext\misc\basexx.c \
|
||||
$(TOP)\ext\misc\bgckpt.c \
|
||||
$(TOP)\ext\misc\carray.c \
|
||||
$(TOP)\ext\misc\cksumvfs.c \
|
||||
$(TOP)\ext\misc\closure.c \
|
||||
|
||||
@@ -19,7 +19,7 @@ dnl to configure the system for the local environment.
|
||||
# so that we create the export library with the dll.
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
AC_INIT([sqlite],[3.46.0])
|
||||
AC_INIT([sqlite],[3.46.1])
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.46.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.46.1.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.46.0'
|
||||
PACKAGE_STRING='sqlite 3.46.0'
|
||||
PACKAGE_VERSION='3.46.1'
|
||||
PACKAGE_STRING='sqlite 3.46.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1472,7 +1472,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.46.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.46.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1537,7 +1537,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.46.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.46.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1668,7 +1668,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.46.0
|
||||
sqlite configure 3.46.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2087,7 +2087,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.46.0, which was
|
||||
It was created by sqlite $as_me 3.46.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -12481,7 +12481,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.46.0, which was
|
||||
This file was extended by sqlite $as_me 3.46.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12547,7 +12547,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.46.0
|
||||
sqlite config.status 3.46.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
|
||||
Wal2 Mode Notes
|
||||
===============
|
||||
|
||||
## Activating/Deactivating Wal2 Mode
|
||||
|
||||
"Wal2" mode is very similar to "wal" mode. To change a database to wal2 mode,
|
||||
use the command:
|
||||
|
||||
>
|
||||
PRAGMA journal_mode = wal2;
|
||||
|
||||
It is not possible to change a database directly from "wal" mode to "wal2"
|
||||
mode. Instead, it must first be changed to rollback mode. So, to change a wal
|
||||
mode database to wal2 mode, the following two commands may be used:
|
||||
|
||||
>
|
||||
PRAGMA journal_mode = delete;
|
||||
PRAGMA journal_mode = wal2;
|
||||
|
||||
A database in wal2 mode may only be accessed by versions of SQLite compiled
|
||||
from this branch. Attempting to use any other version of SQLite results in an
|
||||
SQLITE_NOTADB error. A wal2 mode database may be changed back to rollback mode
|
||||
(making it accessible by all versions of SQLite) using:
|
||||
|
||||
>
|
||||
PRAGMA journal_mode = delete;
|
||||
|
||||
## The Advantage of Wal2 Mode
|
||||
|
||||
In legacy wal mode, when a writer writes data to the database, it doesn't
|
||||
modify the database file directly. Instead, it appends new data to the
|
||||
"<database>-wal" file. Readers read data from both the original database
|
||||
file and the "<database>-wal" file. At some point, data is copied from the
|
||||
"<database>-wal" file into the database file, after which the wal file can
|
||||
be deleted or overwritten. Copying data from the wal file into the database
|
||||
file is called a "checkpoint", and may be done explictly (either by "PRAGMA
|
||||
wal_checkpoint" or sqlite3_wal_checkpoint_v2()), or
|
||||
automatically (by configuring "PRAGMA wal_autocheckpoint" - this is the
|
||||
default).
|
||||
|
||||
Checkpointers do not block writers, and writers do not block checkpointers.
|
||||
However, if a writer writes to the database while a checkpoint is ongoing,
|
||||
then the new data is appended to the end of the wal file. This means that,
|
||||
even following the checkpoint, the wal file cannot be overwritten or deleted,
|
||||
and so all subsequent transactions must also be appended to the wal file. The
|
||||
work of the checkpointer is not wasted - SQLite remembers which parts of the
|
||||
wal file have already been copied into the db file so that the next checkpoint
|
||||
does not have to do so again - but it does mean that the wal file may grow
|
||||
indefinitely if the checkpointer never gets a chance to finish without a
|
||||
writer appending to the wal file. There are also circumstances in which
|
||||
long-running readers may prevent a checkpointer from checkpointing the entire
|
||||
wal file - also causing the wal file to grow indefinitely in a busy system.
|
||||
|
||||
Wal2 mode does not have this problem. In wal2 mode, wal files do not grow
|
||||
indefinitely even if the checkpointer never has a chance to finish
|
||||
uninterrupted.
|
||||
|
||||
In wal2 mode, the system uses two wal files instead of one. The files are named
|
||||
"<database>-wal" and "<database>-wal2", where "<database>" is of
|
||||
course the name of the database file. When data is written to the database, the
|
||||
writer begins by appending the new data to the first wal file. Once the first
|
||||
wal file has grown large enough, writers switch to appending data to the second
|
||||
wal file. At this point the first wal file can be checkpointed (after which it
|
||||
can be overwritten). Then, once the second wal file has grown large enough and
|
||||
the first wal file has been checkpointed, writers switch back to the first wal
|
||||
file. And so on.
|
||||
|
||||
## Application Programming
|
||||
|
||||
From the point of view of the user, the main differences between wal and
|
||||
wal2 mode are to do with checkpointing:
|
||||
|
||||
* In wal mode, a checkpoint may be attempted at any time. In wal2
|
||||
mode, the checkpointer has to wait until writers have switched
|
||||
to the "other" wal file before a checkpoint can take place.
|
||||
|
||||
* In wal mode, the wal-hook (callback registered using
|
||||
sqlite3_wal_hook()) is invoked after a transaction is committed
|
||||
with the total number of pages in the wal file as an argument. In wal2
|
||||
mode, the argument is either the total number of uncheckpointed pages in
|
||||
both wal files, or - if the "other" wal file is empty or already
|
||||
checkpointed - 0.
|
||||
|
||||
Clients are recommended to use the same strategies for checkpointing wal2 mode
|
||||
databases as for wal databases - by registering a wal-hook using
|
||||
sqlite3_wal_hook() and attempting a checkpoint when the parameter
|
||||
exceeds a certain threshold.
|
||||
|
||||
However, it should be noted that although the wal-hook is invoked after each
|
||||
transaction is committed to disk and database locks released, it is still
|
||||
invoked from within the sqlite3_step() call used to execute the "COMMIT"
|
||||
command. In BEGIN CONCURRENT systems, where the "COMMIT" is often protected by
|
||||
an application mutex, this may reduce concurrency. In such systems, instead of
|
||||
executing a checkpoint from within the wal-hook, a thread might defer this
|
||||
action until after the application mutex has been released.
|
||||
|
||||
|
||||
@@ -53,11 +53,6 @@
|
||||
# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */
|
||||
#endif
|
||||
|
||||
#if CIO_WIN_WC_XLATE
|
||||
/* Character used to represent a known-incomplete UTF-8 char group (�) */
|
||||
static WCHAR cBadGroup = 0xfffd;
|
||||
#endif
|
||||
|
||||
#if CIO_WIN_WC_XLATE
|
||||
static HANDLE handleOfFile(FILE *pf){
|
||||
int fileDesc = _fileno(pf);
|
||||
|
||||
@@ -465,6 +465,13 @@ do_execsql_test 5.3 {
|
||||
t2 t2_idx_0001295b {100 20 5}
|
||||
}
|
||||
|
||||
do_catchsql_test 5.4 {
|
||||
SELECT sqlite_expert_rem(123, 123);
|
||||
} {1 {no such function: sqlite_expert_rem}}
|
||||
do_catchsql_test 5.5 {
|
||||
SELECT sqlite_expert_sample();
|
||||
} {1 {no such function: sqlite_expert_sample}}
|
||||
|
||||
if 0 {
|
||||
do_test expert1-6.0 {
|
||||
catchcmd :memory: {
|
||||
|
||||
@@ -626,7 +626,7 @@ static int expertFilter(
|
||||
pCsr->pData = 0;
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
|
||||
"SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
|
||||
"SELECT * FROM main.%Q WHERE sqlite_expert_sample()", pVtab->pTab->zName
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1500,7 +1500,7 @@ struct IdxRemCtx {
|
||||
};
|
||||
|
||||
/*
|
||||
** Implementation of scalar function rem().
|
||||
** Implementation of scalar function sqlite_expert_rem().
|
||||
*/
|
||||
static void idxRemFunc(
|
||||
sqlite3_context *pCtx,
|
||||
@@ -1513,7 +1513,7 @@ static void idxRemFunc(
|
||||
assert( argc==2 );
|
||||
|
||||
iSlot = sqlite3_value_int(argv[0]);
|
||||
assert( iSlot<=p->nSlot );
|
||||
assert( iSlot<p->nSlot );
|
||||
pSlot = &p->aSlot[iSlot];
|
||||
|
||||
switch( pSlot->eType ){
|
||||
@@ -1624,7 +1624,8 @@ static int idxPopulateOneStat1(
|
||||
const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
|
||||
const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
|
||||
zCols = idxAppendText(&rc, zCols,
|
||||
"%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
|
||||
"%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s",
|
||||
zComma, zName, nCol, zName, zColl
|
||||
);
|
||||
zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
|
||||
}
|
||||
@@ -1757,13 +1758,13 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
|
||||
rc = sqlite3_create_function(
|
||||
dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
|
||||
rc = sqlite3_create_function(dbrem, "sqlite_expert_rem",
|
||||
2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(
|
||||
p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
|
||||
rc = sqlite3_create_function(p->db, "sqlite_expert_sample",
|
||||
0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1815,6 +1816,9 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
|
||||
}
|
||||
|
||||
sqlite3_create_function(p->db, "sqlite_expert_rem", 2, SQLITE_UTF8, 0,0,0,0);
|
||||
sqlite3_create_function(p->db, "sqlite_expert_sample", 0,SQLITE_UTF8,0,0,0,0);
|
||||
|
||||
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -324,7 +324,11 @@ int sqlite3Fts5ExprNew(
|
||||
}
|
||||
|
||||
sqlite3_free(sParse.apPhrase);
|
||||
*pzErr = sParse.zErr;
|
||||
if( 0==*pzErr ){
|
||||
*pzErr = sParse.zErr;
|
||||
}else{
|
||||
sqlite3_free(sParse.zErr);
|
||||
}
|
||||
return sParse.rc;
|
||||
}
|
||||
|
||||
@@ -2452,6 +2456,7 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
|
||||
assert( pRight->eType==FTS5_STRING
|
||||
|| pRight->eType==FTS5_TERM
|
||||
|| pRight->eType==FTS5_EOF
|
||||
|| (pRight->eType==FTS5_AND && pParse->bPhraseToAnd)
|
||||
);
|
||||
|
||||
if( pLeft->eType==FTS5_AND ){
|
||||
|
||||
+19
-10
@@ -1700,6 +1700,7 @@ static int fts5UpdateMethod(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
rc = fts5SpecialDelete(pTab, apVal);
|
||||
bUpdateOrDelete = 1;
|
||||
}
|
||||
}else{
|
||||
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
|
||||
@@ -2874,14 +2875,16 @@ int sqlite3Fts5GetTokenizer(
|
||||
if( pMod==0 ){
|
||||
assert( nArg>0 );
|
||||
rc = SQLITE_ERROR;
|
||||
*pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
|
||||
if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
|
||||
}else{
|
||||
rc = pMod->x.xCreate(
|
||||
pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok
|
||||
);
|
||||
pConfig->pTokApi = &pMod->x;
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
|
||||
if( pzErr && rc!=SQLITE_NOMEM ){
|
||||
*pzErr = sqlite3_mprintf("error in tokenizer constructor");
|
||||
}
|
||||
}else{
|
||||
pConfig->ePattern = sqlite3Fts5TokenizerPattern(
|
||||
pMod->x.xCreate, pConfig->pTok
|
||||
@@ -2975,17 +2978,23 @@ static int fts5IntegrityMethod(
|
||||
|
||||
assert( pzErr!=0 && *pzErr==0 );
|
||||
UNUSED_PARAM(isQuick);
|
||||
assert( pTab->p.pConfig->pzErrmsg==0 );
|
||||
pTab->p.pConfig->pzErrmsg = pzErr;
|
||||
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
|
||||
if( (rc&0xff)==SQLITE_CORRUPT ){
|
||||
*pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
|
||||
zSchema, zTabname);
|
||||
rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
|
||||
" FTS5 table %s.%s: %s",
|
||||
zSchema, zTabname, sqlite3_errstr(rc));
|
||||
if( *pzErr==0 && rc!=SQLITE_OK ){
|
||||
if( (rc&0xff)==SQLITE_CORRUPT ){
|
||||
*pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
|
||||
zSchema, zTabname);
|
||||
rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
|
||||
}else{
|
||||
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
|
||||
" FTS5 table %s.%s: %s",
|
||||
zSchema, zTabname, sqlite3_errstr(rc));
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
|
||||
pTab->p.pConfig->pzErrmsg = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ static int fts5AsciiCreate(
|
||||
int i;
|
||||
memset(p, 0, sizeof(AsciiTokenizer));
|
||||
memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
|
||||
const char *zArg = azArg[i+1];
|
||||
if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
|
||||
fts5AsciiAddExceptions(p, zArg, 1);
|
||||
@@ -90,6 +90,7 @@ static int fts5AsciiCreate(
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
fts5AsciiDelete((Fts5Tokenizer*)p);
|
||||
p = 0;
|
||||
@@ -381,17 +382,16 @@ static int fts5UnicodeCreate(
|
||||
}
|
||||
|
||||
/* Search for a "categories" argument */
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
|
||||
if( 0==sqlite3_stricmp(azArg[i], "categories") ){
|
||||
zCat = azArg[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = unicodeSetCategories(p, zCat);
|
||||
}
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
|
||||
const char *zArg = azArg[i+1];
|
||||
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
|
||||
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
|
||||
@@ -416,6 +416,7 @@ static int fts5UnicodeCreate(
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
|
||||
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
@@ -1298,7 +1299,7 @@ static int fts5TriCreate(
|
||||
int i;
|
||||
pNew->bFold = 1;
|
||||
pNew->iFoldParam = 0;
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
|
||||
const char *zArg = azArg[i+1];
|
||||
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
|
||||
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
|
||||
@@ -1316,6 +1317,7 @@ static int fts5TriCreate(
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
|
||||
|
||||
if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
|
||||
rc = SQLITE_ERROR;
|
||||
|
||||
@@ -377,4 +377,28 @@ do_catchsql_test 12.3.3 {
|
||||
SELECT fts5_collist(t1, 1) FROM t1('one AND two');
|
||||
} {0 1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 13.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=ascii);
|
||||
INSERT INTO t1 VALUES('a b c'), ('d e f');
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
do_catchsql_test 13.2 {
|
||||
SELECT highlight(t1, 0, '[', ']') FROM t1
|
||||
} {0 {{a b c} {d e f}}}
|
||||
|
||||
do_execsql_test 13.3 {
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_schema SET sql = 'CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=blah)'
|
||||
WHERE name = 't1';
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 13.4 {
|
||||
SELECT highlight(t1, 0, '[', ']') FROM t1
|
||||
} {1 {no such tokenizer: blah}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -380,5 +380,32 @@ do_execsql_test 12.3 {
|
||||
} {ok}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 13.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=ascii);
|
||||
INSERT INTO t1 VALUES('a b c'), ('d e f');
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 13.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {0 ok}
|
||||
|
||||
do_execsql_test 13.3 {
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_schema SET sql = 'CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=blah)'
|
||||
WHERE name = 't1';
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
breakpoint
|
||||
do_catchsql_test 13.4 {
|
||||
PRAGMA integrity_check;
|
||||
} {1 {no such tokenizer: blah}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -42,6 +42,22 @@ do_execsql_test 1.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE xyz USING fts5 (
|
||||
name,
|
||||
content=''
|
||||
);
|
||||
|
||||
INSERT INTO xyz(xyz, rank) VALUES('secure-delete', 1);
|
||||
INSERT INTO xyz (rowid, name) VALUES(1, 'A');
|
||||
INSERT INTO xyz (rowid, name) VALUES(2, 'A');
|
||||
INSERT INTO xyz(xyz, rowid, name) VALUES('delete', 2, 'A');
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
pragma quick_check;
|
||||
} {ok}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,5 +85,25 @@ do_execsql_test 1.7 {
|
||||
SELECT highlight(t1, 0, '>', '<') FROM t1('BB mess');
|
||||
} {AAdont>BBmess<}
|
||||
|
||||
# 2024-08-06 https://sqlite.org/forum/forumpost/171bcc2bcd
|
||||
# Error handling of tokenize= arguments.
|
||||
#
|
||||
foreach {n tkz} {
|
||||
1 {ascii none}
|
||||
2 {unicode61 none}
|
||||
3 {porter none}
|
||||
4 {trigram none}
|
||||
5 {ascii none 0}
|
||||
6 {unicode61 none 0}
|
||||
7 {porter none 0}
|
||||
8 {trigram none 0}
|
||||
} {
|
||||
db eval {DROP TABLE IF EXISTS t2;}
|
||||
do_catchsql_test 2.$n "
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(a,b,c,tokenize='$tkz');
|
||||
" {1 {error in tokenizer constructor}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -69,6 +69,9 @@ do_execsql_test 2.0 {
|
||||
INSERT INTO t1 VALUES('abcdefghijklm');
|
||||
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
|
||||
}
|
||||
do_catchsql_test 2.0.1 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(z, tokenize='trigram case_sensitive');
|
||||
} {1 {error in tokenizer constructor}}
|
||||
|
||||
foreach {tn s res} {
|
||||
1 abc "(abc)defghijklm"
|
||||
@@ -206,7 +209,7 @@ do_execsql_test 7.0 {
|
||||
(20, "жираф.png"),
|
||||
(30, "cat.png"),
|
||||
(40, "кот.png"),
|
||||
(50, "misic-🎵-.mp3");
|
||||
(50, "misic-ðµ-.mp3");
|
||||
}
|
||||
do_execsql_test 7.1 {
|
||||
SELECT rowid FROM f WHERE +filename GLOB '*ир*';
|
||||
|
||||
@@ -21,6 +21,9 @@ do_execsql_test 1.0 "
|
||||
INSERT INTO t1 VALUES('abc\u0303defghijklm');
|
||||
INSERT INTO t1 VALUES('a\u0303b\u0303c\u0303defghijklm');
|
||||
"
|
||||
do_catchsql_test 1.0.1 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(z, tokenize='trigram remove_diacritics');
|
||||
} {1 {error in tokenizer constructor}}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT highlight(t1, 0, '(', ')') FROM t1('abc');
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
** 2017-10-11
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
*/
|
||||
|
||||
#if !defined(SQLITE_TEST) || defined(SQLITE_OS_UNIX)
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
** API declarations.
|
||||
*/
|
||||
typedef struct Checkpointer Checkpointer;
|
||||
int sqlite3_bgckpt_create(const char *zFilename, Checkpointer **pp);
|
||||
int sqlite3_bgckpt_checkpoint(Checkpointer *p, int bBlock);
|
||||
void sqlite3_bgckpt_destroy(Checkpointer *p);
|
||||
|
||||
|
||||
struct Checkpointer {
|
||||
sqlite3 *db; /* Database handle */
|
||||
|
||||
pthread_t thread; /* Background thread */
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
|
||||
int rc; /* Error from "PRAGMA wal_checkpoint" */
|
||||
int bCkpt; /* True if checkpoint requested */
|
||||
int bExit; /* True if exit requested */
|
||||
};
|
||||
|
||||
static void *bgckptThreadMain(void *pCtx){
|
||||
int rc = SQLITE_OK;
|
||||
Checkpointer *p = (Checkpointer*)pCtx;
|
||||
|
||||
while( rc==SQLITE_OK ){
|
||||
int bExit;
|
||||
|
||||
pthread_mutex_lock(&p->mutex);
|
||||
if( p->bCkpt==0 && p->bExit==0 ){
|
||||
pthread_cond_wait(&p->cond, &p->mutex);
|
||||
}
|
||||
p->bCkpt = 0;
|
||||
bExit = p->bExit;
|
||||
pthread_mutex_unlock(&p->mutex);
|
||||
|
||||
if( bExit ) break;
|
||||
rc = sqlite3_exec(p->db, "PRAGMA wal_checkpoint", 0, 0, 0);
|
||||
if( rc==SQLITE_BUSY ){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&p->mutex);
|
||||
p->rc = rc;
|
||||
pthread_mutex_unlock(&p->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sqlite3_bgckpt_destroy(Checkpointer *p){
|
||||
if( p ){
|
||||
void *ret = 0;
|
||||
|
||||
/* Signal the background thread to exit */
|
||||
pthread_mutex_lock(&p->mutex);
|
||||
p->bExit = 1;
|
||||
pthread_cond_broadcast(&p->cond);
|
||||
pthread_mutex_unlock(&p->mutex);
|
||||
|
||||
pthread_join(p->thread, &ret);
|
||||
sqlite3_close(p->db);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sqlite3_bgckpt_create(const char *zFilename, Checkpointer **pp){
|
||||
Checkpointer *pNew = 0;
|
||||
int rc;
|
||||
|
||||
pNew = (Checkpointer*)sqlite3_malloc(sizeof(Checkpointer));
|
||||
if( pNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pNew, 0, sizeof(Checkpointer));
|
||||
rc = sqlite3_open(zFilename, &pNew->db);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
pthread_mutex_init(&pNew->mutex, 0);
|
||||
pthread_cond_init(&pNew->cond, 0);
|
||||
pthread_create(&pNew->thread, 0, bgckptThreadMain, (void*)pNew);
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_bgckpt_destroy(pNew);
|
||||
pNew = 0;
|
||||
}
|
||||
*pp = pNew;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sqlite3_bgckpt_checkpoint(Checkpointer *p, int bBlock){
|
||||
int rc;
|
||||
pthread_mutex_lock(&p->mutex);
|
||||
rc = p->rc;
|
||||
if( rc==SQLITE_OK ){
|
||||
p->bCkpt = 1;
|
||||
pthread_cond_broadcast(&p->cond);
|
||||
}
|
||||
pthread_mutex_unlock(&p->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
|
||||
#if defined(INCLUDE_SQLITE_TCL_H)
|
||||
# include "sqlite_tcl.h"
|
||||
#else
|
||||
# include "tcl.h"
|
||||
# ifndef SQLITE_TCLAPI
|
||||
# define SQLITE_TCLAPI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
const char *sqlite3ErrName(int rc);
|
||||
|
||||
static void SQLITE_TCLAPI bgckpt_del(void * clientData){
|
||||
Checkpointer *pCkpt = (Checkpointer*)clientData;
|
||||
sqlite3_bgckpt_destroy(pCkpt);
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: $ckpt SUBCMD ...
|
||||
*/
|
||||
static int SQLITE_TCLAPI bgckpt_obj_cmd(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
Checkpointer *pCkpt = (Checkpointer*)clientData;
|
||||
const char *aCmd[] = { "checkpoint", "destroy", 0 };
|
||||
int iCmd;
|
||||
|
||||
if( objc<2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SUBCMD ...");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( Tcl_GetIndexFromObj(interp, objv[1], aCmd, "sub-command", 0, &iCmd) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
switch( iCmd ){
|
||||
case 0: {
|
||||
int rc;
|
||||
int bBlock = 0;
|
||||
|
||||
if( objc>3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?BLOCKING?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==3 && Tcl_GetBooleanFromObj(interp, objv[2], &bBlock) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = sqlite3_bgckpt_checkpoint(pCkpt, bBlock);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: {
|
||||
Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: bgckpt CMDNAME FILENAME
|
||||
*/
|
||||
static int SQLITE_TCLAPI bgckpt_cmd(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
const char *zCmd;
|
||||
const char *zFilename;
|
||||
int rc;
|
||||
Checkpointer *pCkpt;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "CMDNAME FILENAME");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zCmd = Tcl_GetString(objv[1]);
|
||||
zFilename = Tcl_GetString(objv[2]);
|
||||
|
||||
rc = sqlite3_bgckpt_create(zFilename, &pCkpt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_CreateObjCommand(interp, zCmd, bgckpt_obj_cmd, (void*)pCkpt, bgckpt_del);
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int Bgckpt_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(interp, "bgckpt", bgckpt_cmd, 0, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_TEST */
|
||||
|
||||
#else
|
||||
#if defined(INCLUDE_SQLITE_TCL_H)
|
||||
# include "sqlite_tcl.h"
|
||||
#else
|
||||
# include "tcl.h"
|
||||
# ifndef SQLITE_TCLAPI
|
||||
# define SQLITE_TCLAPI
|
||||
# endif
|
||||
#endif
|
||||
int Bgckpt_Init(Tcl_Interp *interp){ return TCL_OK; }
|
||||
#endif
|
||||
|
||||
@@ -363,8 +363,8 @@ static int recoverError(
|
||||
va_start(ap, zFmt);
|
||||
if( zFmt ){
|
||||
z = sqlite3_vmprintf(zFmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
va_end(ap);
|
||||
sqlite3_free(p->zErrMsg);
|
||||
p->zErrMsg = z;
|
||||
p->errCode = errCode;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
_fiddle_exec
|
||||
_fiddle_interrupt
|
||||
_fiddle_experiment
|
||||
_fiddle_the_db
|
||||
_fiddle_db_arg
|
||||
_fiddle_db_filename
|
||||
_fiddle_exec
|
||||
_fiddle_experiment
|
||||
_fiddle_interrupt
|
||||
_fiddle_main
|
||||
_fiddle_reset_db
|
||||
_fiddle_db_handle
|
||||
_fiddle_db_vfs
|
||||
_fiddle_export_db
|
||||
@@ -1,8 +1,3 @@
|
||||
_malloc
|
||||
_free
|
||||
_realloc
|
||||
_sqlite3_aggregate_context
|
||||
_sqlite3_auto_extension
|
||||
_sqlite3_bind_blob
|
||||
_sqlite3_bind_double
|
||||
_sqlite3_bind_int
|
||||
@@ -10,16 +5,11 @@ _sqlite3_bind_int64
|
||||
_sqlite3_bind_null
|
||||
_sqlite3_bind_parameter_count
|
||||
_sqlite3_bind_parameter_index
|
||||
_sqlite3_bind_pointer
|
||||
_sqlite3_bind_text
|
||||
_sqlite3_busy_handler
|
||||
_sqlite3_busy_timeout
|
||||
_sqlite3_cancel_auto_extension
|
||||
_sqlite3_changes
|
||||
_sqlite3_changes64
|
||||
_sqlite3_clear_bindings
|
||||
_sqlite3_close_v2
|
||||
_sqlite3_collation_needed
|
||||
_sqlite3_column_blob
|
||||
_sqlite3_column_bytes
|
||||
_sqlite3_column_count
|
||||
@@ -30,28 +20,12 @@ _sqlite3_column_int64
|
||||
_sqlite3_column_name
|
||||
_sqlite3_column_text
|
||||
_sqlite3_column_type
|
||||
_sqlite3_column_value
|
||||
_sqlite3_commit_hook
|
||||
_sqlite3_compileoption_get
|
||||
_sqlite3_compileoption_used
|
||||
_sqlite3_complete
|
||||
_sqlite3_context_db_handle
|
||||
_sqlite3_create_collation
|
||||
_sqlite3_create_collation_v2
|
||||
_sqlite3_create_function
|
||||
_sqlite3_create_function_v2
|
||||
_sqlite3_create_module
|
||||
_sqlite3_create_module_v2
|
||||
_sqlite3_create_window_function
|
||||
_sqlite3_data_count
|
||||
_sqlite3_db_filename
|
||||
_sqlite3_db_handle
|
||||
_sqlite3_db_name
|
||||
_sqlite3_db_status
|
||||
_sqlite3_declare_vtab
|
||||
_sqlite3_deserialize
|
||||
_sqlite3_drop_modules
|
||||
_sqlite3_errcode
|
||||
_sqlite3_errmsg
|
||||
_sqlite3_error_offset
|
||||
_sqlite3_errstr
|
||||
@@ -59,39 +33,16 @@ _sqlite3_exec
|
||||
_sqlite3_expanded_sql
|
||||
_sqlite3_extended_errcode
|
||||
_sqlite3_extended_result_codes
|
||||
_sqlite3_file_control
|
||||
_sqlite3_finalize
|
||||
_sqlite3_free
|
||||
_sqlite3_get_auxdata
|
||||
_sqlite3_get_autocommit
|
||||
_sqlite3_initialize
|
||||
_sqlite3_keyword_count
|
||||
_sqlite3_keyword_name
|
||||
_sqlite3_keyword_check
|
||||
_sqlite3_last_insert_rowid
|
||||
_sqlite3_interrupt
|
||||
_sqlite3_libversion
|
||||
_sqlite3_libversion_number
|
||||
_sqlite3_limit
|
||||
_sqlite3_malloc
|
||||
_sqlite3_malloc64
|
||||
_sqlite3_msize
|
||||
_sqlite3_open
|
||||
_sqlite3_open_v2
|
||||
_sqlite3_overload_function
|
||||
_sqlite3_prepare_v2
|
||||
_sqlite3_prepare_v3
|
||||
_sqlite3_preupdate_blobwrite
|
||||
_sqlite3_preupdate_count
|
||||
_sqlite3_preupdate_depth
|
||||
_sqlite3_preupdate_hook
|
||||
_sqlite3_preupdate_new
|
||||
_sqlite3_preupdate_old
|
||||
_sqlite3_progress_handler
|
||||
_sqlite3_randomness
|
||||
_sqlite3_realloc
|
||||
_sqlite3_realloc64
|
||||
_sqlite3_reset
|
||||
_sqlite3_reset_auto_extension
|
||||
_sqlite3_result_blob
|
||||
_sqlite3_result_double
|
||||
_sqlite3_result_error
|
||||
@@ -99,106 +50,23 @@ _sqlite3_result_error_code
|
||||
_sqlite3_result_error_nomem
|
||||
_sqlite3_result_error_toobig
|
||||
_sqlite3_result_int
|
||||
_sqlite3_result_int64
|
||||
_sqlite3_result_null
|
||||
_sqlite3_result_pointer
|
||||
_sqlite3_result_subtype
|
||||
_sqlite3_result_text
|
||||
_sqlite3_result_zeroblob
|
||||
_sqlite3_result_zeroblob64
|
||||
_sqlite3_rollback_hook
|
||||
_sqlite3_serialize
|
||||
_sqlite3_set_authorizer
|
||||
_sqlite3_set_auxdata
|
||||
_sqlite3_set_last_insert_rowid
|
||||
_sqlite3_shutdown
|
||||
_sqlite3_sourceid
|
||||
_sqlite3_sql
|
||||
_sqlite3_status
|
||||
_sqlite3_status64
|
||||
_sqlite3_step
|
||||
_sqlite3_stmt_isexplain
|
||||
_sqlite3_stmt_readonly
|
||||
_sqlite3_stmt_status
|
||||
_sqlite3_strglob
|
||||
_sqlite3_stricmp
|
||||
_sqlite3_strlike
|
||||
_sqlite3_strnicmp
|
||||
_sqlite3_table_column_metadata
|
||||
_sqlite3_total_changes
|
||||
_sqlite3_total_changes64
|
||||
_sqlite3_trace_v2
|
||||
_sqlite3_txn_state
|
||||
_sqlite3_update_hook
|
||||
_sqlite3_uri_boolean
|
||||
_sqlite3_uri_int64
|
||||
_sqlite3_uri_key
|
||||
_sqlite3_uri_parameter
|
||||
_sqlite3_user_data
|
||||
_sqlite3_value_blob
|
||||
_sqlite3_value_bytes
|
||||
_sqlite3_value_double
|
||||
_sqlite3_value_dup
|
||||
_sqlite3_value_free
|
||||
_sqlite3_value_frombind
|
||||
_sqlite3_value_int
|
||||
_sqlite3_value_int64
|
||||
_sqlite3_value_nochange
|
||||
_sqlite3_value_numeric_type
|
||||
_sqlite3_value_pointer
|
||||
_sqlite3_value_subtype
|
||||
_sqlite3_value_text
|
||||
_sqlite3_value_type
|
||||
_sqlite3_vfs_find
|
||||
_sqlite3_vfs_register
|
||||
_sqlite3_vfs_unregister
|
||||
_sqlite3_vtab_collation
|
||||
_sqlite3_vtab_distinct
|
||||
_sqlite3_vtab_in
|
||||
_sqlite3_vtab_in_first
|
||||
_sqlite3_vtab_in_next
|
||||
_sqlite3_vtab_nochange
|
||||
_sqlite3_vtab_on_conflict
|
||||
_sqlite3_vtab_rhs_value
|
||||
_sqlite3changegroup_add
|
||||
_sqlite3changegroup_add_strm
|
||||
_sqlite3changegroup_delete
|
||||
_sqlite3changegroup_new
|
||||
_sqlite3changegroup_output
|
||||
_sqlite3changegroup_output_strm
|
||||
_sqlite3changeset_apply
|
||||
_sqlite3changeset_apply_strm
|
||||
_sqlite3changeset_apply_v2
|
||||
_sqlite3changeset_apply_v2_strm
|
||||
_sqlite3changeset_concat
|
||||
_sqlite3changeset_concat_strm
|
||||
_sqlite3changeset_conflict
|
||||
_sqlite3changeset_finalize
|
||||
_sqlite3changeset_fk_conflicts
|
||||
_sqlite3changeset_invert
|
||||
_sqlite3changeset_invert_strm
|
||||
_sqlite3changeset_new
|
||||
_sqlite3changeset_next
|
||||
_sqlite3changeset_old
|
||||
_sqlite3changeset_op
|
||||
_sqlite3changeset_pk
|
||||
_sqlite3changeset_start
|
||||
_sqlite3changeset_start_strm
|
||||
_sqlite3changeset_start_v2
|
||||
_sqlite3changeset_start_v2_strm
|
||||
_sqlite3session_attach
|
||||
_sqlite3session_changeset
|
||||
_sqlite3session_changeset_size
|
||||
_sqlite3session_changeset_strm
|
||||
_sqlite3session_config
|
||||
_sqlite3session_create
|
||||
_sqlite3session_delete
|
||||
_sqlite3session_diff
|
||||
_sqlite3session_enable
|
||||
_sqlite3session_indirect
|
||||
_sqlite3session_isempty
|
||||
_sqlite3session_memory_used
|
||||
_sqlite3session_object_config
|
||||
_sqlite3session_patchset
|
||||
_sqlite3session_patchset_strm
|
||||
_sqlite3session_table_filter
|
||||
_sqlite3_wasm_db_error
|
||||
_sqlite3_wasm_enum_json
|
||||
_malloc
|
||||
_free
|
||||
|
||||
@@ -87,35 +87,6 @@ const installAsyncProxy = function(){
|
||||
const log = (...args)=>logImpl(2, ...args);
|
||||
const warn = (...args)=>logImpl(1, ...args);
|
||||
const error = (...args)=>logImpl(0, ...args);
|
||||
const metrics = Object.create(null);
|
||||
metrics.reset = ()=>{
|
||||
let k;
|
||||
const r = (m)=>(m.count = m.time = m.wait = 0);
|
||||
for(k in state.opIds){
|
||||
r(metrics[k] = Object.create(null));
|
||||
}
|
||||
let s = metrics.s11n = Object.create(null);
|
||||
s = s.serialize = Object.create(null);
|
||||
s.count = s.time = 0;
|
||||
s = metrics.s11n.deserialize = Object.create(null);
|
||||
s.count = s.time = 0;
|
||||
};
|
||||
metrics.dump = ()=>{
|
||||
let k, n = 0, t = 0, w = 0;
|
||||
for(k in state.opIds){
|
||||
const m = metrics[k];
|
||||
n += m.count;
|
||||
t += m.time;
|
||||
w += m.wait;
|
||||
m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0;
|
||||
}
|
||||
console.log(globalThis?.location?.href,
|
||||
"metrics for",globalThis?.location?.href,":\n",
|
||||
metrics,
|
||||
"\nTotal of",n,"op(s) for",t,"ms",
|
||||
"approx",w,"ms spent waiting on OPFS APIs.");
|
||||
console.log("Serialization metrics:",metrics.s11n);
|
||||
};
|
||||
|
||||
/**
|
||||
__openFiles is a map of sqlite3_file pointers (integers) to
|
||||
@@ -265,23 +236,34 @@ const installAsyncProxy = function(){
|
||||
this.name = 'GetSyncHandleError';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Attempts to find a suitable SQLITE_xyz result code for Error
|
||||
object e. Returns either such a translation or rc if if it does
|
||||
not know how to translate the exception.
|
||||
*/
|
||||
GetSyncHandleError.convertRc = (e,rc)=>{
|
||||
if(1){
|
||||
return (
|
||||
e instanceof GetSyncHandleError
|
||||
&& ((e.cause.name==='NoModificationAllowedError')
|
||||
/* Inconsistent exception.name from Chrome/ium with the
|
||||
same exception.message text: */
|
||||
|| (e.cause.name==='DOMException'
|
||||
&& 0===e.cause.message.indexOf('Access Handles cannot')))
|
||||
) ? (
|
||||
/*console.warn("SQLITE_BUSY",e),*/
|
||||
state.sq3Codes.SQLITE_BUSY
|
||||
) : rc;
|
||||
}else{
|
||||
return rc;
|
||||
if( e instanceof GetSyncHandleError ){
|
||||
if( e.cause.name==='NoModificationAllowedError'
|
||||
/* Inconsistent exception.name from Chrome/ium with the
|
||||
same exception.message text: */
|
||||
|| (e.cause.name==='DOMException'
|
||||
&& 0===e.cause.message.indexOf('Access Handles cannot')) ){
|
||||
return state.sq3Codes.SQLITE_BUSY;
|
||||
}else if( 'NotFoundError'===e.cause.name ){
|
||||
/**
|
||||
Maintenance reminder: SQLITE_NOTFOUND, though it looks like
|
||||
a good match, has different semantics than NotFoundError
|
||||
and is not suitable here.
|
||||
*/
|
||||
return state.sq3Codes.SQLITE_CANTOPEN;
|
||||
}
|
||||
}else if( 'NotFoundError'===e?.name ){
|
||||
return state.sq3Codes.SQLITE_CANTOPEN;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the sync access handle associated with the given file
|
||||
handle object (which must be a valid handle object, as created by
|
||||
@@ -347,37 +329,6 @@ const installAsyncProxy = function(){
|
||||
if(fh.readOnly) toss(opName+"(): File is read-only: "+fh.filenameAbs);
|
||||
};
|
||||
|
||||
/**
|
||||
We track 2 different timers: the "metrics" timer records how much
|
||||
time we spend performing work. The "wait" timer records how much
|
||||
time we spend waiting on the underlying OPFS timer. See the calls
|
||||
to mTimeStart(), mTimeEnd(), wTimeStart(), and wTimeEnd()
|
||||
throughout this file to see how they're used.
|
||||
*/
|
||||
const __mTimer = Object.create(null);
|
||||
__mTimer.op = undefined;
|
||||
__mTimer.start = undefined;
|
||||
const mTimeStart = (op)=>{
|
||||
__mTimer.start = performance.now();
|
||||
__mTimer.op = op;
|
||||
//metrics[op] || toss("Maintenance required: missing metrics for",op);
|
||||
++metrics[op].count;
|
||||
};
|
||||
const mTimeEnd = ()=>(
|
||||
metrics[__mTimer.op].time += performance.now() - __mTimer.start
|
||||
);
|
||||
const __wTimer = Object.create(null);
|
||||
__wTimer.op = undefined;
|
||||
__wTimer.start = undefined;
|
||||
const wTimeStart = (op)=>{
|
||||
__wTimer.start = performance.now();
|
||||
__wTimer.op = op;
|
||||
//metrics[op] || toss("Maintenance required: missing metrics for",op);
|
||||
};
|
||||
const wTimeEnd = ()=>(
|
||||
metrics[__wTimer.op].wait += performance.now() - __wTimer.start
|
||||
);
|
||||
|
||||
/**
|
||||
Gets set to true by the 'opfs-async-shutdown' command to quit the
|
||||
wait loop. This is only intended for debugging purposes: we cannot
|
||||
@@ -388,37 +339,24 @@ const installAsyncProxy = function(){
|
||||
|
||||
/**
|
||||
Asynchronous wrappers for sqlite3_vfs and sqlite3_io_methods
|
||||
methods, as well as helpers like mkdir(). Maintenance reminder:
|
||||
members are in alphabetical order to simplify finding them.
|
||||
methods, as well as helpers like mkdir().
|
||||
*/
|
||||
const vfsAsyncImpls = {
|
||||
'opfs-async-metrics': async ()=>{
|
||||
mTimeStart('opfs-async-metrics');
|
||||
metrics.dump();
|
||||
storeAndNotify('opfs-async-metrics', 0);
|
||||
mTimeEnd();
|
||||
},
|
||||
'opfs-async-shutdown': async ()=>{
|
||||
flagAsyncShutdown = true;
|
||||
storeAndNotify('opfs-async-shutdown', 0);
|
||||
},
|
||||
mkdir: async (dirname)=>{
|
||||
mTimeStart('mkdir');
|
||||
let rc = 0;
|
||||
wTimeStart('mkdir');
|
||||
try {
|
||||
await getDirForFilename(dirname+"/filepart", true);
|
||||
}catch(e){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR;
|
||||
}finally{
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('mkdir', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xAccess: async (filename)=>{
|
||||
mTimeStart('xAccess');
|
||||
/* OPFS cannot support the full range of xAccess() queries
|
||||
sqlite3 calls for. We can essentially just tell if the file
|
||||
is accessible, but if it is then it's automatically writable
|
||||
@@ -431,26 +369,20 @@ const installAsyncProxy = function(){
|
||||
accessible, non-0 means not accessible.
|
||||
*/
|
||||
let rc = 0;
|
||||
wTimeStart('xAccess');
|
||||
try{
|
||||
const [dh, fn] = await getDirForFilename(filename);
|
||||
await dh.getFileHandle(fn);
|
||||
}catch(e){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR;
|
||||
}finally{
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xAccess', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xClose: async function(fid/*sqlite3_file pointer*/){
|
||||
const opName = 'xClose';
|
||||
mTimeStart(opName);
|
||||
__implicitLocks.delete(fid);
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
wTimeStart(opName);
|
||||
if(fh){
|
||||
delete __openFiles[fid];
|
||||
await closeSyncHandle(fh);
|
||||
@@ -462,15 +394,11 @@ const installAsyncProxy = function(){
|
||||
state.s11n.serialize();
|
||||
rc = state.sq3Codes.SQLITE_NOTFOUND;
|
||||
}
|
||||
wTimeEnd();
|
||||
storeAndNotify(opName, rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xDelete: async function(...args){
|
||||
mTimeStart('xDelete');
|
||||
const rc = await vfsAsyncImpls.xDeleteNoWait(...args);
|
||||
storeAndNotify('xDelete', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xDeleteNoWait: async function(filename, syncDir = 0, recursive = false){
|
||||
/* The syncDir flag is, for purposes of the VFS API's semantics,
|
||||
@@ -486,7 +414,6 @@ const installAsyncProxy = function(){
|
||||
is false.
|
||||
*/
|
||||
let rc = 0;
|
||||
wTimeStart('xDelete');
|
||||
try {
|
||||
while(filename){
|
||||
const [hDir, filenamePart] = await getDirForFilename(filename, false);
|
||||
@@ -502,14 +429,11 @@ const installAsyncProxy = function(){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_DELETE;
|
||||
}
|
||||
wTimeEnd();
|
||||
return rc;
|
||||
},
|
||||
xFileSize: async function(fid/*sqlite3_file pointer*/){
|
||||
mTimeStart('xFileSize');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
wTimeStart('xFileSize');
|
||||
try{
|
||||
const sz = await (await getSyncHandle(fh,'xFileSize')).getSize();
|
||||
state.s11n.serialize(Number(sz));
|
||||
@@ -518,19 +442,15 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
wTimeEnd();
|
||||
storeAndNotify('xFileSize', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xLock: async function(fid/*sqlite3_file pointer*/,
|
||||
lockType/*SQLITE_LOCK_...*/){
|
||||
mTimeStart('xLock');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
const oldLockType = fh.xLock;
|
||||
fh.xLock = lockType;
|
||||
if( !fh.syncHandle ){
|
||||
wTimeStart('xLock');
|
||||
try {
|
||||
await getSyncHandle(fh,'xLock');
|
||||
__implicitLocks.delete(fid);
|
||||
@@ -539,18 +459,14 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK);
|
||||
fh.xLock = oldLockType;
|
||||
}
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xLock',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xOpen: async function(fid/*sqlite3_file pointer*/, filename,
|
||||
flags/*SQLITE_OPEN_...*/,
|
||||
opfsFlags/*OPFS_...*/){
|
||||
const opName = 'xOpen';
|
||||
mTimeStart(opName);
|
||||
const create = (state.sq3Codes.SQLITE_OPEN_CREATE & flags);
|
||||
wTimeStart('xOpen');
|
||||
try{
|
||||
let hDir, filenamePart;
|
||||
try {
|
||||
@@ -558,8 +474,6 @@ const installAsyncProxy = function(){
|
||||
}catch(e){
|
||||
state.s11n.storeException(1,e);
|
||||
storeAndNotify(opName, state.sq3Codes.SQLITE_NOTFOUND);
|
||||
mTimeEnd();
|
||||
wTimeEnd();
|
||||
return;
|
||||
}
|
||||
if( state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN & opfsFlags ){
|
||||
@@ -571,7 +485,6 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
}
|
||||
const hFile = await hDir.getFileHandle(filenamePart, {create});
|
||||
wTimeEnd();
|
||||
const fh = Object.assign(Object.create(null),{
|
||||
fid: fid,
|
||||
filenameAbs: filename,
|
||||
@@ -586,76 +499,50 @@ const installAsyncProxy = function(){
|
||||
fh.releaseImplicitLocks =
|
||||
(opfsFlags & state.opfsFlags.OPFS_UNLOCK_ASAP)
|
||||
|| state.opfsFlags.defaultUnlockAsap;
|
||||
if(0 /* this block is modelled after something wa-sqlite
|
||||
does but it leads to immediate contention on journal files.
|
||||
Update: this approach reportedly only works for DELETE journal
|
||||
mode. */
|
||||
&& (0===(flags & state.sq3Codes.SQLITE_OPEN_MAIN_DB))){
|
||||
/* sqlite does not lock these files, so go ahead and grab an OPFS
|
||||
lock. */
|
||||
fh.xLock = "xOpen"/* Truthy value to keep entry from getting
|
||||
flagged as auto-locked. String value so
|
||||
that we can easily distinguish is later
|
||||
if needed. */;
|
||||
await getSyncHandle(fh,'xOpen');
|
||||
}
|
||||
__openFiles[fid] = fh;
|
||||
storeAndNotify(opName, 0);
|
||||
}catch(e){
|
||||
wTimeEnd();
|
||||
error(opName,e);
|
||||
state.s11n.storeException(1,e);
|
||||
storeAndNotify(opName, state.sq3Codes.SQLITE_IOERR);
|
||||
}
|
||||
mTimeEnd();
|
||||
},
|
||||
xRead: async function(fid/*sqlite3_file pointer*/,n,offset64){
|
||||
mTimeStart('xRead');
|
||||
let rc = 0, nRead;
|
||||
const fh = __openFiles[fid];
|
||||
try{
|
||||
wTimeStart('xRead');
|
||||
nRead = (await getSyncHandle(fh,'xRead')).read(
|
||||
fh.sabView.subarray(0, n),
|
||||
{at: Number(offset64)}
|
||||
);
|
||||
wTimeEnd();
|
||||
if(nRead < n){/* Zero-fill remaining bytes */
|
||||
fh.sabView.fill(0, nRead, n);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
}catch(e){
|
||||
if(undefined===nRead) wTimeEnd();
|
||||
error("xRead() failed",e,fh);
|
||||
state.s11n.storeException(1,e);
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_READ);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
storeAndNotify('xRead',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xSync: async function(fid/*sqlite3_file pointer*/,flags/*ignored*/){
|
||||
mTimeStart('xSync');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
if(!fh.readOnly && fh.syncHandle){
|
||||
try {
|
||||
wTimeStart('xSync');
|
||||
await fh.syncHandle.flush();
|
||||
}catch(e){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_FSYNC;
|
||||
}
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xSync',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xTruncate: async function(fid/*sqlite3_file pointer*/,size){
|
||||
mTimeStart('xTruncate');
|
||||
let rc = 0;
|
||||
const fh = __openFiles[fid];
|
||||
wTimeStart('xTruncate');
|
||||
try{
|
||||
affirmNotRO('xTruncate', fh);
|
||||
await (await getSyncHandle(fh,'xTruncate')).truncate(size);
|
||||
@@ -665,33 +552,25 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_TRUNCATE);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
wTimeEnd();
|
||||
storeAndNotify('xTruncate',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xUnlock: async function(fid/*sqlite3_file pointer*/,
|
||||
lockType/*SQLITE_LOCK_...*/){
|
||||
mTimeStart('xUnlock');
|
||||
let rc = 0;
|
||||
const fh = __openFiles[fid];
|
||||
if( state.sq3Codes.SQLITE_LOCK_NONE===lockType
|
||||
&& fh.syncHandle ){
|
||||
wTimeStart('xUnlock');
|
||||
try { await closeSyncHandle(fh) }
|
||||
catch(e){
|
||||
state.s11n.storeException(1,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
|
||||
}
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xUnlock',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){
|
||||
mTimeStart('xWrite');
|
||||
let rc;
|
||||
const fh = __openFiles[fid];
|
||||
wTimeStart('xWrite');
|
||||
try{
|
||||
affirmNotRO('xWrite', fh);
|
||||
rc = (
|
||||
@@ -705,9 +584,7 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_WRITE);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
wTimeEnd();
|
||||
storeAndNotify('xWrite',rc);
|
||||
mTimeEnd();
|
||||
}
|
||||
}/*vfsAsyncImpls*/;
|
||||
|
||||
@@ -741,8 +618,6 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
};
|
||||
state.s11n.deserialize = function(clear=false){
|
||||
++metrics.s11n.deserialize.count;
|
||||
const t = performance.now();
|
||||
const argc = viewU8[0];
|
||||
const rc = argc ? [] : null;
|
||||
if(argc){
|
||||
@@ -767,12 +642,9 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
if(clear) viewU8[0] = 0;
|
||||
//log("deserialize:",argc, rc);
|
||||
metrics.s11n.deserialize.time += performance.now() - t;
|
||||
return rc;
|
||||
};
|
||||
state.s11n.serialize = function(...args){
|
||||
const t = performance.now();
|
||||
++metrics.s11n.serialize.count;
|
||||
if(args.length){
|
||||
//log("serialize():",args);
|
||||
const typeIds = [];
|
||||
@@ -803,7 +675,6 @@ const installAsyncProxy = function(){
|
||||
}else{
|
||||
viewU8[0] = 0;
|
||||
}
|
||||
metrics.s11n.serialize.time += performance.now() - t;
|
||||
};
|
||||
|
||||
state.s11n.storeException = state.asyncS11nExceptions
|
||||
@@ -885,7 +756,6 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
});
|
||||
initS11n();
|
||||
metrics.reset();
|
||||
log("init state",state);
|
||||
wPost('opfs-async-inited');
|
||||
waitLoop();
|
||||
@@ -898,9 +768,6 @@ const installAsyncProxy = function(){
|
||||
waitLoop();
|
||||
}
|
||||
break;
|
||||
case 'opfs-async-metrics':
|
||||
metrics.dump();
|
||||
break;
|
||||
}
|
||||
};
|
||||
wPost('opfs-async-loaded');
|
||||
|
||||
@@ -392,6 +392,7 @@ const installOpfsVfs = function callee(options){
|
||||
'SQLITE_ACCESS_EXISTS',
|
||||
'SQLITE_ACCESS_READWRITE',
|
||||
'SQLITE_BUSY',
|
||||
'SQLITE_CANTOPEN',
|
||||
'SQLITE_ERROR',
|
||||
'SQLITE_IOERR',
|
||||
'SQLITE_IOERR_ACCESS',
|
||||
@@ -444,7 +445,7 @@ const installOpfsVfs = function callee(options){
|
||||
OPFS_UNLINK_BEFORE_OPEN: 0x02,
|
||||
/**
|
||||
If true, any async routine which implicitly acquires a sync
|
||||
access handle (i.e. an OPFS lock) will release that locks at
|
||||
access handle (i.e. an OPFS lock) will release that lock at
|
||||
the end of the call which acquires it. If false, such
|
||||
"autolocks" are not released until the VFS is idle for some
|
||||
brief amount of time.
|
||||
@@ -471,9 +472,22 @@ const installOpfsVfs = function callee(options){
|
||||
Atomics.notify(state.sabOPView, state.opIds.whichOp)
|
||||
/* async thread will take over here */;
|
||||
const t = performance.now();
|
||||
Atomics.wait(state.sabOPView, state.opIds.rc, -1)
|
||||
/* When this wait() call returns, the async half will have
|
||||
completed the operation and reported its results. */;
|
||||
while('not-equal'!==Atomics.wait(state.sabOPView, state.opIds.rc, -1)){
|
||||
/*
|
||||
The reason for this loop is buried in the details of a long
|
||||
discussion at:
|
||||
|
||||
https://github.com/sqlite/sqlite-wasm/issues/12
|
||||
|
||||
Summary: in at least one browser flavor, under high loads,
|
||||
the wait()/notify() pairings can get out of sync. Calling
|
||||
wait() here until it returns 'not-equal' gets them back in
|
||||
sync.
|
||||
*/
|
||||
}
|
||||
/* When the above wait() call returns 'not-equal', the async
|
||||
half will have completed the operation and reported its results
|
||||
in the state.opIds.rc slot of the SAB. */
|
||||
const rc = Atomics.load(state.sabOPView, state.opIds.rc);
|
||||
metrics[op].wait += performance.now() - t;
|
||||
if(rc && state.asyncS11nExceptions){
|
||||
@@ -720,9 +734,18 @@ const installOpfsVfs = function callee(options){
|
||||
involve an inherent race condition. For the time being,
|
||||
pending a better solution, we simply report whether the
|
||||
given pFile is open.
|
||||
|
||||
Update 2024-06-12: based on forum discussions, this
|
||||
function now always sets pOut to 0 (false):
|
||||
|
||||
https://sqlite.org/forum/forumpost/a2f573b00cda1372
|
||||
*/
|
||||
const f = __openFiles[pFile];
|
||||
wasm.poke(pOut, f.lockType ? 1 : 0, 'i32');
|
||||
if(1){
|
||||
wasm.poke(pOut, 0, 'i32');
|
||||
}else{
|
||||
const f = __openFiles[pFile];
|
||||
wasm.poke(pOut, f.lockType ? 1 : 0, 'i32');
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
xClose: function(pFile){
|
||||
@@ -738,7 +761,6 @@ const installOpfsVfs = function callee(options){
|
||||
return rc;
|
||||
},
|
||||
xDeviceCharacteristics: function(pFile){
|
||||
//debug("xDeviceCharacteristics(",pFile,")");
|
||||
return capi.SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
|
||||
},
|
||||
xFileControl: function(pFile, opId, pArg){
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
//#ifnot omit-oo1
|
||||
/*
|
||||
2022-08-24
|
||||
|
||||
@@ -42,13 +41,9 @@
|
||||
- `onready` (optional, but...): this callback is called with no
|
||||
arguments when the worker fires its initial
|
||||
'sqlite3-api'/'worker1-ready' message, which it does when
|
||||
sqlite3.initWorker1API() completes its initialization. This is the
|
||||
simplest way to tell the worker to kick off work at the earliest
|
||||
opportunity, and the only way to know when the worker module has
|
||||
completed loading. The irony of using a callback for this, instead
|
||||
of returning a promise from sqlite3Worker1Promiser() is not lost on
|
||||
the developers: see sqlite3Worker1Promiser.v2() which uses a
|
||||
Promise instead.
|
||||
sqlite3.initWorker1API() completes its initialization. This is
|
||||
the simplest way to tell the worker to kick off work at the
|
||||
earliest opportunity.
|
||||
|
||||
- `onunhandled` (optional): a callback which gets passed the
|
||||
message event object for any worker.onmessage() events which
|
||||
@@ -119,7 +114,7 @@
|
||||
by all client code except that which tests this API. The `row`
|
||||
property contains the row result in the form implied by the
|
||||
`rowMode` option (defaulting to `'array'`). The `rowNumber` is a
|
||||
1-based integer value incremented by 1 on each call into the
|
||||
1-based integer value incremented by 1 on each call into th
|
||||
callback.
|
||||
|
||||
At the end of the result set, the same event is fired with
|
||||
@@ -127,17 +122,8 @@
|
||||
the end of the result set has been reached. Note that the rows
|
||||
arrive via worker-posted messages, with all the implications
|
||||
of that.
|
||||
|
||||
Notable shortcomings:
|
||||
|
||||
- This API was not designed with ES6 modules in mind. Neither Firefox
|
||||
nor Safari support, as of March 2023, the {type:"module"} flag to the
|
||||
Worker constructor, so that particular usage is not something we're going
|
||||
to target for the time being:
|
||||
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker
|
||||
*/
|
||||
globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfig){
|
||||
self.sqlite3Worker1Promiser = function callee(config = callee.defaultConfig){
|
||||
// Inspired by: https://stackoverflow.com/a/52439530
|
||||
if(1===arguments.length && 'function'===typeof arguments[0]){
|
||||
const f = config;
|
||||
@@ -160,7 +146,6 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi
|
||||
if(!config.worker) config.worker = callee.defaultConfig.worker;
|
||||
if('function'===typeof config.worker) config.worker = config.worker();
|
||||
let dbId;
|
||||
let promiserFunc;
|
||||
config.worker.onmessage = function(ev){
|
||||
ev = ev.data;
|
||||
debug('worker1.onmessage',ev);
|
||||
@@ -168,14 +153,14 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi
|
||||
if(!msgHandler){
|
||||
if(ev && 'sqlite3-api'===ev.type && 'worker1-ready'===ev.result) {
|
||||
/*fired one time when the Worker1 API initializes*/
|
||||
if(config.onready) config.onready(promiserFunc);
|
||||
if(config.onready) config.onready();
|
||||
return;
|
||||
}
|
||||
msgHandler = handlerMap[ev.type] /* check for exec per-row callback */;
|
||||
if(msgHandler && msgHandler.onrow){
|
||||
msgHandler.onrow(ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(config.onunhandled) config.onunhandled(arguments[0]);
|
||||
else err("sqlite3Worker1Promiser() unhandled worker message:",ev);
|
||||
return;
|
||||
@@ -197,19 +182,19 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi
|
||||
try {msgHandler.resolve(ev)}
|
||||
catch(e){msgHandler.reject(e)}
|
||||
}/*worker.onmessage()*/;
|
||||
return promiserFunc = function(/*(msgType, msgArgs) || (msgEnvelope)*/){
|
||||
return function(/*(msgType, msgArgs) || (msgEnvelope)*/){
|
||||
let msg;
|
||||
if(1===arguments.length){
|
||||
msg = arguments[0];
|
||||
}else if(2===arguments.length){
|
||||
msg = Object.create(null);
|
||||
msg.type = arguments[0];
|
||||
msg.args = arguments[1];
|
||||
msg.dbId = msg.args.dbId;
|
||||
msg = {
|
||||
type: arguments[0],
|
||||
args: arguments[1]
|
||||
};
|
||||
}else{
|
||||
toss("Invalid arguments for sqlite3Worker1Promiser()-created factory.");
|
||||
toss("Invalid arugments for sqlite3Worker1Promiser()-created factory.");
|
||||
}
|
||||
if(!msg.dbId && msg.type!=='open') msg.dbId = dbId;
|
||||
if(!msg.dbId) msg.dbId = dbId;
|
||||
msg.messageId = genMsgId(msg);
|
||||
msg.departureTime = performance.now();
|
||||
const proxy = Object.create(null);
|
||||
@@ -251,96 +236,28 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi
|
||||
return p;
|
||||
};
|
||||
}/*sqlite3Worker1Promiser()*/;
|
||||
|
||||
globalThis.sqlite3Worker1Promiser.defaultConfig = {
|
||||
self.sqlite3Worker1Promiser.defaultConfig = {
|
||||
worker: function(){
|
||||
//#if target=es6-module
|
||||
return new Worker(new URL("sqlite3-worker1-bundler-friendly.mjs", import.meta.url),{
|
||||
type: 'module'
|
||||
});
|
||||
//#if target=es6-bundler-friendly
|
||||
return new Worker("sqlite3-worker1.js");
|
||||
//#else
|
||||
let theJs = "sqlite3-worker1.js";
|
||||
if(this.currentScript){
|
||||
const src = this.currentScript.src.split('/');
|
||||
src.pop();
|
||||
theJs = src.join('/')+'/' + theJs;
|
||||
//sqlite3.config.warn("promiser currentScript, theJs =",this.currentScript,theJs);
|
||||
}else if(globalThis.location){
|
||||
//sqlite3.config.warn("promiser globalThis.location =",globalThis.location);
|
||||
const urlParams = new URL(globalThis.location.href).searchParams;
|
||||
//console.warn("promiser currentScript, theJs =",this.currentScript,theJs);
|
||||
}else{
|
||||
//console.warn("promiser self.location =",self.location);
|
||||
const urlParams = new URL(self.location.href).searchParams;
|
||||
if(urlParams.has('sqlite3.dir')){
|
||||
theJs = urlParams.get('sqlite3.dir') + '/' + theJs;
|
||||
}
|
||||
}
|
||||
return new Worker(theJs + globalThis.location.search);
|
||||
return new Worker(theJs + self.location.search);
|
||||
//#endif
|
||||
}
|
||||
//#ifnot target=es6-module
|
||||
.bind({
|
||||
currentScript: globalThis?.document?.currentScript
|
||||
})
|
||||
//#endif
|
||||
,
|
||||
}.bind({
|
||||
currentScript: self?.document?.currentScript
|
||||
}),
|
||||
onerror: (...args)=>console.error('worker1 promiser error',...args)
|
||||
}/*defaultConfig*/;
|
||||
|
||||
/**
|
||||
sqlite3Worker1Promiser.v2(), added in 3.46, works identically to
|
||||
sqlite3Worker1Promiser() except that it returns a Promise instead
|
||||
of relying an an onready callback in the config object. The Promise
|
||||
resolves to the same factory function which
|
||||
sqlite3Worker1Promiser() returns.
|
||||
|
||||
If config is-a function or is an object which contains an onready
|
||||
function, that function is replaced by a proxy which will resolve
|
||||
after calling the original function and will reject if that
|
||||
function throws.
|
||||
*/
|
||||
sqlite3Worker1Promiser.v2 = function(config){
|
||||
let oldFunc;
|
||||
if( 'function' == typeof config ){
|
||||
oldFunc = config;
|
||||
config = {};
|
||||
}else if('function'===typeof config?.onready){
|
||||
oldFunc = config.onready;
|
||||
delete config.onready;
|
||||
}
|
||||
const promiseProxy = Object.create(null);
|
||||
config = Object.assign((config || Object.create(null)),{
|
||||
onready: async function(func){
|
||||
try {
|
||||
if( oldFunc ) await oldFunc(func);
|
||||
promiseProxy.resolve(func);
|
||||
}
|
||||
catch(e){promiseProxy.reject(e)}
|
||||
}
|
||||
});
|
||||
const p = new Promise(function(resolve,reject){
|
||||
promiseProxy.resolve = resolve;
|
||||
promiseProxy.reject = reject;
|
||||
});
|
||||
try{
|
||||
this.original(config);
|
||||
}catch(e){
|
||||
promiseProxy.reject(e);
|
||||
}
|
||||
return p;
|
||||
}.bind({
|
||||
/* We do this because clients are
|
||||
recommended to delete globalThis.sqlite3Worker1Promiser. */
|
||||
original: sqlite3Worker1Promiser
|
||||
});
|
||||
|
||||
//#if target=es6-module
|
||||
/**
|
||||
When built as a module, we export sqlite3Worker1Promiser.v2()
|
||||
instead of sqlite3Worker1Promise() because (A) its interface is more
|
||||
conventional for ESM usage and (B) the ESM option export option for
|
||||
this API did not exist until v2 was created, so there's no backwards
|
||||
incompatibility.
|
||||
*/
|
||||
export default sqlite3Worker1Promiser.v2;
|
||||
//#endif /* target=es6-module */
|
||||
//#else
|
||||
/* Built with the omit-oo1 flag. */
|
||||
//#endif ifnot omit-oo1
|
||||
};
|
||||
|
||||
@@ -273,6 +273,11 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
</div> <!-- #view-split -->
|
||||
<!-- Maintenance notes:
|
||||
|
||||
... TODO... currently being refactored...
|
||||
|
||||
-->
|
||||
<script src="fiddle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -343,6 +343,7 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/appendvfs.c \
|
||||
$(TOP)/ext/misc/basexx.c \
|
||||
$(TOP)/ext/misc/bgckpt.c \
|
||||
$(TOP)/ext/misc/carray.c \
|
||||
$(TOP)/ext/misc/cksumvfs.c \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
C Version\s3.46.0
|
||||
D 2024-05-23T13:25:27.566
|
||||
C Merge\sthe\slatest\sbranch-3.46\schanges\sinto\swal2\sas\sa\snew\ssub-branch\ncalled\swal2-3.46.
|
||||
D 2024-08-10T20:02:18.839
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 993a7874e3d3721df61846f03dda4a9ef7490da11953ae36ba1bb0c0346eaf4a
|
||||
F Makefile.in 10051e3e2f86dbb3a49aa368f558f9964b1ab3a4de29731000883e6e6829fd14
|
||||
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
||||
F Makefile.msc e64a52619310d3067f6c38f56eedd15918a82dade70954197d6da486ad99d7f4
|
||||
F Makefile.msc 0b51124d78552562866331d1906010c2e7acc05c2d284b9faa33efc776bfea31
|
||||
F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3
|
||||
F VERSION c84541c6a9e8426462176fbb1f9ecb5cfd7d1bb56228053ff7eeba8841673eb6
|
||||
F VERSION 01b0b94ee03b29c27cb72ef03c460cd9476dee97b0cf8cf74b17a201e199820a
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||
F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
|
||||
@@ -24,7 +24,7 @@ F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d
|
||||
F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196
|
||||
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
|
||||
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
|
||||
F autoconf/tea/configure.ac 9e74135563a901d9b1a019bad1c9d73a6659fa32325f6a565bef72bfb0ec7297
|
||||
F autoconf/tea/configure.ac 629148599fb2c29003b34e72dd161473b5fe23b6f26a2281200e9581daaede95
|
||||
F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb
|
||||
F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
|
||||
F autoconf/tea/pkgIndex.tcl.in b9eb6dd37f64e08e637d576b3c83259814b9cddd78bec4af2e5abfc6c5c750ce
|
||||
@@ -35,7 +35,7 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034
|
||||
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
|
||||
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
|
||||
F configure 40f7af9ed5ca0d44a4b9bc7ad34f1ee4867bb4eeb19e75036be6bed66193a498 x
|
||||
F configure 1728380292e4153caf04870b0734c771b9cdc73be655181618f7b8253f2d9d5c x
|
||||
F configure.ac f25bd7843120f2c2b8bc9db5a92b0502bbdd28e68907415c3d42fc8e57c657b9
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
@@ -49,16 +49,17 @@ F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d
|
||||
F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
F doc/wal-lock.md 781726aaba20bafeceb7ba9f91d5c98c6731691b30c954e37cf0b49a053d461d
|
||||
F doc/wal2.md a807405a05e19a4945c5905a9ffa0fe45b8560dd7572461192501f565c19cdb5
|
||||
F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
|
||||
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
|
||||
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
|
||||
F ext/consio/console_io.c f32b757c9ee7fdf68e7586bee306f8368759e7cd12febb2a6839199b1c1af395 x
|
||||
F ext/consio/console_io.c b4885dfea71ed583315de8f0792a29d5fc7c7460b4a26c0aebe5cda5da8b38f8 x
|
||||
F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 53a749de08939e3bc14f804e97410927d46fa772cbce0247d7e8fa6fc2523b0c
|
||||
F ext/expert/sqlite3expert.c c8cea5ff15fbe792cccc4992a9b40b706411c41d32611f617897fecac6ff06a4
|
||||
F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b
|
||||
F ext/expert/sqlite3expert.c 8b09aeb2b95a9fca8b6628b522bf4d69aa746ff64c38eb1e99a9b5fad8cf03b9
|
||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee
|
||||
@@ -97,15 +98,15 @@ F ext/fts5/fts5Int.h defa43c0932265138ee910ca416e6baccf8b774e0f3d610e74be1ab2880
|
||||
F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1
|
||||
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
|
||||
F ext/fts5/fts5_config.c 8072a207034b51ae9b7694121d1b5715c794e94b275e088f70ae532378ca5cdf
|
||||
F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696
|
||||
F ext/fts5/fts5_expr.c d6a48d81aa96d68090187059f48dba2184e0cb0fd3b50a5a84a649a865cb31a5
|
||||
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
||||
F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379
|
||||
F ext/fts5/fts5_main.c d68bd9533d5a638b7f6fae61c3cb0a15257dcdcccedaf3d0b3c9f55940c85048
|
||||
F ext/fts5/fts5_main.c 0a8fc885851d76af6ea670090231ed23b9f8f349f44080e79a0f59b1d54511bb
|
||||
F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934
|
||||
F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
|
||||
F ext/fts5/fts5_tokenize.c 83cfcede3898001cab84432a36ce1503e3080cf9b1c682b022ec82e267ea4c13
|
||||
F ext/fts5/fts5_tokenize.c 2321cbcef0bb99ed326d58f02cbd907e678c86572a72a434d08f6cb78e346dbd
|
||||
F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00
|
||||
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
||||
F ext/fts5/fts5_vocab.c 209e0c151e108d5f3621fa24b91e9b02f3750ee6c3f9ccec312df39481b68a09
|
||||
@@ -126,7 +127,7 @@ F ext/fts5/test/fts5ak.test f459a64c9d38698af72a7c657ab6349bca96150241dd69fcce75
|
||||
F ext/fts5/test/fts5al.test 00c4c1c6a1366b73aa48ce2068c634520867c3cf7f5d1676ebbb775ee1f35734
|
||||
F ext/fts5/test/fts5alter.test 5565f7e4605512b69171ac18ca84398603f9f6456dbe377beeca97e83cc242cd
|
||||
F ext/fts5/test/fts5auto.test 78989e6527ce69c9eddbef7392fea5c10b0010cd2b2ae68eec7bc869c471e691
|
||||
F ext/fts5/test/fts5aux.test ed3596469f85a6cff5f6060e0cd9e3f9602051d8db2b497f5d12c85d39f20a62
|
||||
F ext/fts5/test/fts5aux.test e0866d924289423164c539576229ea589990e6dd38d05a0b6f8752ad51d70bb4
|
||||
F ext/fts5/test/fts5auxdata.test eacc97ff04892f1a5f3d4df5a73f8bcbc3955ea1d12c9f24137eb1fc079e7611
|
||||
F ext/fts5/test/fts5bigid.test 2860854c2561a57594192b00c33a29f91cb85e25f3d6c03b5c2b8f62708f39dd
|
||||
F ext/fts5/test/fts5bigpl.test 6466c89b38439f0aba26ac09e232a6b963f29b1cbe1304f6a664fe1e7a8f5fd3
|
||||
@@ -178,7 +179,7 @@ F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b99
|
||||
F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717
|
||||
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
|
||||
F ext/fts5/test/fts5hash.test dc7bc7e0cdeb42cfce31294ad2f8fcf43192bfd0145bb7f3ecc5465d8c72696f
|
||||
F ext/fts5/test/fts5integrity.test f1723fe9fb9381b26c946ab4d7505041434df2c449d1cd53f45c7bf8c098dfa2
|
||||
F ext/fts5/test/fts5integrity.test f7a9dc2c2b8db0db024eaa546ed56add97f869b67064e258c36dcdd0243f25f2
|
||||
F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227
|
||||
F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28
|
||||
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
|
||||
@@ -218,7 +219,7 @@ F ext/fts5/test/fts5secure4.test 0d10a80590c07891478700af7793b232962042677432b98
|
||||
F ext/fts5/test/fts5secure5.test c07a68ced5951567ac116c22f2d2aafae497e47fe9fcb6a335c22f9c7a4f2c3a
|
||||
F ext/fts5/test/fts5secure6.test 74bf04733cc523bccca519bb03d3b4e2ed6f6e3db7c59bf6be82c88a0ac857fd
|
||||
F ext/fts5/test/fts5secure7.test fd03d0868d64340a1db8615b02e5508fea409de13910114e4f19eaefc120777a
|
||||
F ext/fts5/test/fts5secure8.test eb3579e9d58b0acad97e8082dee1f99b2d393198f03500b453c2b25761c0c298
|
||||
F ext/fts5/test/fts5secure8.test e68c0ac4447f415ff3e4e82531e99548289286f9f3a29c8cd53036113fe28602
|
||||
F ext/fts5/test/fts5securefault.test dbca2b6a1c16700017f5051138991b705410889933f2a37c57ae8a23b296b10b
|
||||
F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b
|
||||
F ext/fts5/test/fts5simple2.test 8dd2389ee75e21a1429fe87e5f8c7d9a97ad1470304a8a2d3ba4b8c3c345fecd
|
||||
@@ -228,9 +229,9 @@ F ext/fts5/test/fts5synonym2.test e2f6ff68c4fbe12a866a3a87510f553d9dac99bcb74c10
|
||||
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
|
||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
|
||||
F ext/fts5/test/fts5tokenizer2.test cb5428c7cfb3b6a74b7adfcde65506e329112003e8dffa7501d01c2d18d02569
|
||||
F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0
|
||||
F ext/fts5/test/fts5trigram2.test 9fe4207f8a4241747aff1005258b564958588d21bfd240d6cd4c2e955d31c156
|
||||
F ext/fts5/test/fts5tokenizer2.test b9d734c1b10bc317a377ffea3ecb5c2937313113a02e364f167d0c7f8c81c282
|
||||
F ext/fts5/test/fts5trigram.test be914555deb8504dde682bd5aa343d00c4da37dfad20709a5bac30d5f97f2ef5
|
||||
F ext/fts5/test/fts5trigram2.test 4043f8836bbbb0ce37b86dd1e741431c6c595c7e4ba4fc8e26f21dc3b540e228
|
||||
F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b
|
||||
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
|
||||
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
|
||||
@@ -378,6 +379,7 @@ F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e
|
||||
F ext/misc/base64.c a71b131e50300c654a66c469a25b62874481f3d1cb3beb56aca9a68edd812e0d
|
||||
F ext/misc/base85.c 073054111988db593ef5fdb87ab8c459df1ea0c3aaaddf0f5bfa3d72b7e6280a
|
||||
F ext/misc/basexx.c 89ad6b76558efbceb627afd5e2ef1d84b2e96d9aaf9b7ecb20e3d00b51be6fcf
|
||||
F ext/misc/bgckpt.c 49ae19aa03e6da393db5d17da256374d4c4d36889fdd89d6e4bc93aca2b752e6
|
||||
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
|
||||
F ext/misc/btreeinfo.c cb952620eedf5c0b7625b678f0f08e54d2ec0011d4e50efda5ebdc97f3df7d04
|
||||
F ext/misc/carray.c 34fac63770971611c5285de0a9f0ac67d504eaf66be891f637add9290f1c76a5
|
||||
@@ -494,7 +496,7 @@ F ext/recover/recoverpgsz.test 3658ab8e68475b1bb87d6af88baa04551c84b73280a566a1b
|
||||
F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f
|
||||
F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411
|
||||
F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486
|
||||
F ext/recover/sqlite3recover.c 65ef0f56301a16c0536c9839fb7e23540c9c4f75da0afe3b7b4d163c8f624404
|
||||
F ext/recover/sqlite3recover.c 2dcf6b56c5e0e2b43fc4c6115b689ab194c374ced7f7f8380ad9a24d8ef24ac9
|
||||
F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959
|
||||
F ext/recover/test_recover.c fd871a40f2238022bedcbdf3cb493b91225edaa94d6ae8892af97a10e7ccc4ba
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
@@ -590,7 +592,7 @@ F ext/session/test_session.c 8bcc857125372e640f75ab63b4188080f9bbab92b65f86dfd16
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle 7fb73f7150ab79d83bb45a67d257553c905c78cd3d693101699243f36c5ae6c3
|
||||
F ext/wasm/GNUmakefile 21f015f342e4ed9b7ff632c10750512259d26c836a34f4f535673fae9a7c9fcc
|
||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
||||
@@ -599,7 +601,7 @@ F ext/wasm/SQLTester/SQLTester.mjs ce765c0ad7d57f93553d12ef4dca574deb00300134a26
|
||||
F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638
|
||||
F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d
|
||||
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api f442460ed9a109e637dd3ea1caa4489553ad9414e8988118b208bb7a4bbece6b
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api c5eaceabb9e759aaae7d3101a4a3e542f96ab2c99d89a80ce20ec18c23115f33
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73
|
||||
@@ -614,13 +616,13 @@ F ext/wasm/api/sqlite3-api-oo1.js c373cc04625a96bd3f01ce8ebeac93a5d38dbda6215818
|
||||
F ext/wasm/api/sqlite3-api-prologue.js b347a0c5350247f90174a0ad9b9e72a99a5f837f31f78f60fcdb829b2ca30b63
|
||||
F ext/wasm/api/sqlite3-api-worker1.js 9704b77b5eb9d0d498ceeaf3e7a837021b14c52ac15d6556c7f97e278ec725c3
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 196ad83d36ca794e564044788c9d21b964679d63cad865f604da37c4afc9a285
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js dd4054e4f673027c330c96a04cf0a03b118156f01b076dc4e9d604dbdd7bfc51
|
||||
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 8433ee332d5f5e39fb19427fccb7bad7f44aa99b5504daad3343fc128c311e78
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 3c72f1a0e6a7343c8c882d29d01bb440f10be12c844651605b486e76f3d6cc8c
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 834dcea56e27064ae8429780c85393c82b8f83fc23a1ebebb41849392bfe30bf
|
||||
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js a2fcbc3fecdd0eea229283584ebc122f29d98194083675dbe5cb2cf3a17fe309
|
||||
F ext/wasm/api/sqlite3-wasm.c 9267174b9b0591b4f71193542ab57adf95bb9415f7d3453acf4a8ca8052f5e6c
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f10c3ecd9df06f6320073c2ce230a7ed7c56034d8b88c1e57095f2a97faf423a
|
||||
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
|
||||
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
|
||||
F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd
|
||||
@@ -645,8 +647,8 @@ F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c
|
||||
F ext/wasm/fiddle.make 3c2eace29255d6ddd219f5d8cc2728cb28b9fe717ea80b6062c2a6178947a16b
|
||||
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||
F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce
|
||||
F ext/wasm/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08
|
||||
F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1
|
||||
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
|
||||
F ext/wasm/index-dist.html 564b5ec5669676482c5a25dea9e721d8eafed426ecb155f93d29aeff8507511f
|
||||
F ext/wasm/index.html 4337f495416756802669f69f9f9f3df9f87ee4c1918e6718719b4b5718e4713a
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
|
||||
@@ -674,7 +676,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk e5da4b6c13f2b15bba7f1efb0a47089dfdde0973e85a024785485655d59fd758
|
||||
F main.mk bb35adafb59f4dc5df6b1c09727e26bf5af354bcea69fd7014204c9deb9e783f
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
@@ -686,20 +688,20 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
|
||||
F src/alter.c e1b6782b85dd758f89e5c588e4e3eb82638c2dafc0c857b79a43bb8ec1746fca
|
||||
F src/alter.c bb663fddf1fe0e2e6d8758b2b7fb6374e7c057a6ca3955f37a48986806029765
|
||||
F src/analyze.c a3df28274e2565ba5656577d7e3fd262169a213e6eb0bd47890e0f0729a4031c
|
||||
F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39
|
||||
F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
|
||||
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
||||
F src/btree.c 71b80e77b255144db47180fda8138740608e382a44231942464029b1a45fc036
|
||||
F src/btree.c c22fa652e41ce259cedd7a7b90c51f0f895bb4265c20fc1be8529dea6227e9be
|
||||
F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0
|
||||
F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
|
||||
F src/build.c 11ec7014a3c468e7b3ccc8dda8d9111cd5a29a358df18818788601e0600aaabd
|
||||
F src/build.c 237ccc0290d131d646be722f418e92ee0a38043aee25e7dfdc75f8ce5b3abe4e
|
||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
|
||||
F src/ctime.c 1842f79c04abcf79cb3037e5dc110bc76f91951bb4b4fc4a41bcbd370371b39c
|
||||
F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
||||
@@ -707,13 +709,13 @@ F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
||||
F src/expr.c f7bad20d2f74005f1f876e7fbb627222ea28250e44b296b047403720c5c21818
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00
|
||||
F src/func.c 283d4f3b2751a1d9339fd93a8a013d1948fd5f4474a3cab0955eb4fafd445d0f
|
||||
F src/func.c f1f57c6863c1380f31ecf3d61732495bfff847a8e35a832c7e306e310db5a799
|
||||
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
|
||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 4bd7c7e54a1062dcd0214b7a6296f7194eb10fb14d3ddca1ed20b01c2a86a18c
|
||||
F src/insert.c 8ff11e9e54c5fc1fe89707b3d41cf44ad2822f712bd3b5da68338ea42518847e
|
||||
F src/json.c bf1b51e32158b3d01d96a878d3dba8d2e633a7e5bf2534d4617f89de8a6b9a91
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
||||
@@ -741,25 +743,25 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210
|
||||
F src/os_unix.c 6227cbc4ac93046f121436886cf3712da6f4e2082af6314f976eeae1d86b794a
|
||||
F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56
|
||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||
F src/parse.y 50516253433303673ff6b009983bb246d1527415e5a9af22acc51b0eedb9a10d
|
||||
F src/pager.c 6ba34a87afec0fe450f200527f34bf42d9c699d25c9161dc339f36bce833aeb5
|
||||
F src/pager.h fc0c95d27f2aefffcb39b4373b3557e89e1b4b9a36b183cc04d6f22002bf0ad2
|
||||
F src/parse.y 1a526e56da1d8255196bd59d4ca3e26d912d3dc26d18663ade25dd328945062e
|
||||
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
|
||||
F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684
|
||||
F src/pragma.c d206a9a757faceb812183faa2ed328145795c8067a44f981b0478736f68d4144
|
||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce
|
||||
F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 22f1fa3423b377c02ae78d451cfeb1c2d96dcf0389c0642cbdcd19d3bfd7ae01
|
||||
F src/resolve.c 4f4c99b8714fa04844a0f1f96ee69eefc8928e300af9247a46cfe80f78f8997c
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 1a841c38974d45cf15a7611398479182b61ad4c187423c380741d8b1688fe607
|
||||
F src/shell.c.in 885dafabb3f16d68bdb4576683afb0e39a1939f50985b162255bf656c470babf
|
||||
F src/shell.c.in ebb698028ec031e0b1595865500097d2005f977be0efd14bd8b0ddf634d5ed8d
|
||||
F src/sqlite.h.in c71d9ef76a6d32dc7ff2d373f2e57ce09056af26c1457bcadae5358b7628c7c3
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 6a9fa3902c9faca2b57060e822f2afadfbf96d64c4ede81e201f0e0c42d7e4aa
|
||||
F src/sqliteInt.h 9d022fc8dc3fccd69e518c115101ab4c3d4cb45a79549c1a4c26fec492eb2cfb
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -784,7 +786,7 @@ F src/test_demovfs.c 38a459d1c78fd9afa770445b224c485e079018d6ac07332ff9bd07b54d2
|
||||
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
|
||||
F src/test_fs.c 56cc17e4fdc57efa61695026e2ba96e910b17060d7ee01d775ec048791522e2f
|
||||
F src/test_func.c 4d2dc7e3e0946e55091784ddaf0302294f2ee300614f6f3e19a4b38df77d5167
|
||||
F src/test_hexio.c 9478e56a0f08e07841a014a93b20e4ba2709ab56d039d1ca8020e26846aa19bd
|
||||
F src/test_hexio.c a605a100e628d39330044ae5f34cb19d50843061ed3178c3f83b37aef65f7e0a
|
||||
F src/test_init.c f2cc4774b7c9140f76e45ecbb2ae219f68e3acbbe248c0179db666a70eae9f08
|
||||
F src/test_intarray.c 26ffba666beb658d73cd925d9b4fb56913a3ca9aaeac122b3691436abb192b92
|
||||
F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293
|
||||
@@ -805,7 +807,7 @@ F src/test_schema.c cbfd7a9a9b6b40d4377d0c76a6c5b2a58387385977f26edab4e77eb5f90a
|
||||
F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a
|
||||
F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e
|
||||
F src/test_syscall.c 9fdb13b1df05e639808d44fcb8f6064aaded32b6565c00b215cfd05a060d1aca
|
||||
F src/test_tclsh.c aaf0d1de4a518a8db5ad38e5262be3e48b4a74ad1909f2dba753cecb30979d5d
|
||||
F src/test_tclsh.c 6f7c38934a24b48cbffb6542754b2ada693e5a8f7f9509f1074a55652e5c53c9
|
||||
F src/test_tclvar.c 3273f9d59395b336e381b53cfc68ec6ebdaada4e93106a2e976ffb0550504e1c
|
||||
F src/test_thread.c 7ddcf0c8b79fa3c1d172f82f322302c963d923cdb503c6171f3c8081586d0b01
|
||||
F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43
|
||||
@@ -824,11 +826,11 @@ F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
|
||||
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
||||
F src/util.c 4d6d7ebfe6772a1b950c97bbb1d1a72ad4874617ec498ab8aa73b7f5a43e44bb
|
||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||
F src/vdbe.c 3b1793c5d2235ae89b01ef051a33d7d2ad3704c71799653b112686735ad401ff
|
||||
F src/vdbe.c 0d55d87710fb1ee62864acef96faed08f05d5bfcf085734ca5f471d36c1cbd6b
|
||||
F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f
|
||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||
F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
|
||||
F src/vdbeaux.c 3bcf13776c39bf660a52b4b97f6389a421c2756f9ffbf4c0d94f73e1935d8d9c
|
||||
F src/vdbeaux.c afa3c19a70d0b33acf2790fcc6a577fedb264d816397d1c01a507611cad40f46
|
||||
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
|
||||
F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89
|
||||
F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547
|
||||
@@ -836,10 +838,10 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
|
||||
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
|
||||
F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
|
||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||
F src/wal.c 2586d8f3503ed7a59cb3becb380bd90a5ca218c2d331d3d33e3bed58d26aa1ae
|
||||
F src/wal.h 97b8a9903387401377b59507e86b93a148ef1ad4e5ce0f23659a12dcdce56af2
|
||||
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
||||
F src/where.c 6f02c3936d1f9a637d8d7b5ad7362371af3e4434b0ec1eb950189a83de560d59
|
||||
F src/where.c 839956666ce9f6b5d4951fc1f27e976951aac66920c82f9cdc5036b61b54ef7b
|
||||
F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8
|
||||
F src/wherecode.c f5255f49d1f42b6e7e6b0362ff3522fa88cbcaa7213e52f9374744027ecdebca
|
||||
F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd
|
||||
@@ -1013,7 +1015,7 @@ F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568
|
||||
F test/corrupt7.test ffa86896fe63a3d00b0a131e1e64f402e4da9f7e5d89609d6501c851e511d73a
|
||||
F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
|
||||
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
|
||||
F test/corruptA.test 112f4b2ae0b95ebf3ea63718642fb969a93acea557ace3a307234d19c245989b
|
||||
F test/corruptA.test 56e8f321adaf3411960e9d2c7136669d8e1a91cbde6cf401ea84e6d6c7ccbe10
|
||||
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
|
||||
F test/corruptC.test 7d6d9e907334ea3ccb7111a0656cafa30a28f8a5f2aaf1c45ad712236302856a
|
||||
F test/corruptD.test 614320aa519f6bf6c7dd2f581f9513ff7b6826954180cca1a606d0e25ea084a3
|
||||
@@ -1503,7 +1505,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/pendingrace.test 6aa33756b950c4529f79c4f3817a9a1e4025bd0d9961571a05c0279bd183d9c6
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80
|
||||
F test/permutations.test e285997e45dfbb522ca1ba2e034a008a905b30a369690022c68f926a4229033e
|
||||
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
||||
F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
@@ -1528,7 +1530,7 @@ F test/quote.test 7b01b2a261bc26d9821aea9f4941ce1e08191d62fc55ba8862440fb3a59197
|
||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
|
||||
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
|
||||
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/rdonly.test 21e99ee237265d0cf95a0c84b50c784e834acaa4ef05d92a27b262626a656682
|
||||
F test/readonly.test c1985f0b4ab55041f2ba629dadc6578a3ff0f0e5b0ec7912e85c51f49c3e82fe
|
||||
F test/recover.test 6463509a7404e0c35431dd9b4a1c3b4a29d7a6af8a08462b31670c8a5a616d3a
|
||||
F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1
|
||||
@@ -1536,7 +1538,7 @@ F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed13
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/returning1.test 38eee9d07ac1dd4fbd4ce7373497f3783db86b9a76f13ea6a9f9afaf934f888b
|
||||
F test/returning1.test 212cd4111bb941a60abf608f20250db666c21eb1bc4d49217e96c87ff3ab9d1a
|
||||
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
|
||||
@@ -1559,11 +1561,11 @@ F test/rowvaluefault.test 963ae9cdaed30a85a29668dd514e639f3556cae903ee9f172ea972
|
||||
F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f
|
||||
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
|
||||
F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09
|
||||
F test/savepoint.test 6e9804a17767f08432c7a5e738b9a8f4b891d243110b63d3a41d270d3d1378ec
|
||||
F test/savepoint.test 63a120ec4fbbd5025b238c259d12ed0516fbf4bca6384041cb995ade9a5f00d2
|
||||
F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
|
||||
F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
|
||||
F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint6.test 48a645a7bb3a59a6fcf06a7364cfe5b655c336760de39068f7c241b0fc80d963
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e
|
||||
@@ -1584,7 +1586,7 @@ F test/select3.test 180223af31e1ca5537dd395ef9708ae18e651a233777fd366fd0d75469fc
|
||||
F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
|
||||
F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
|
||||
F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f
|
||||
F test/select7.test f659f231489349e8c5734e610803d7654207318f
|
||||
F test/select7.test b825420da8a0b5722fdb77f3369f6396a3d198c46e8787eb26ff9425d4ac9d27
|
||||
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
|
||||
F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812
|
||||
F test/selectA.test 1da8ce3884c326e11d2855baffb76436b0d7e044404af8a2a70d1399a4ff7e29
|
||||
@@ -1614,7 +1616,7 @@ F test/shell1.test 17a5ca9c6f24f807b2f505b4b38fcbce143d96cd8664c06c34bbbe0672bf7
|
||||
F test/shell2.test 56da24128304c9ab67da2964cc80beff7b35761c446ec6e6e98bff2775b15026
|
||||
F test/shell3.test 5ad4b2813717956414f2c0c8a2027895cd98ccf7dd54dbacbde4d4f5591ce5a1
|
||||
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
|
||||
F test/shell5.test 5b2ab1c0540217773f939927c24163a56257446da3f564d4724042620bfea762
|
||||
F test/shell5.test 6a49440bddc33a132f856fb189e71228f8132963655d12a2c8b8a161263b9632
|
||||
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
|
||||
F test/shell7.test 753c6ece5361df50025a50cadf378ea36db9cc05fb23d7a96cff7fa130626ef9
|
||||
F test/shell8.test aea51ecbcd4494c746b096aeff51d841d04d5f0dc4b62eb42427f16109b87acd
|
||||
@@ -1696,7 +1698,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl fe617b88c7eb08bdf983d2aaa31c20fbf439eee7b8e0d61ca636fcd0c305bbbf
|
||||
F test/tester.tcl 7977c8a32fcd09b5c51548a6db43e827f05ca1fd44598bb7986702bcfa1f0cd4
|
||||
F test/testrunner.tcl 1386667c04207d0a540ce1a9bc5ee0b734f7a3ba856c14a03943fb4f32de55bb
|
||||
F test/testrunner_data.tcl 3d36660cfd55ea5e20e661e8f94c0520feebcb437848f9b98b33c483cc479c0c
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
@@ -1919,7 +1921,7 @@ F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3
|
||||
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
|
||||
F test/upsert5.test 9953b180d02d1369cdbb6c73c900834e5fef8cb78e98e07511c8762ec21cc176
|
||||
F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35
|
||||
F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384
|
||||
F test/uri.test 8f27eaa41804099fca15101e30fd1b29aebbebf32d4e3c24614fa6319216936d
|
||||
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
|
||||
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
|
||||
F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da
|
||||
@@ -1965,8 +1967,20 @@ F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
|
||||
F test/vtabdistinct.test 7688f0889358f849fd60bbfde1ded38b014b18066076d4bfbb75395804dfe072
|
||||
F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12
|
||||
F test/vtabrhs1.test 9b5ecbc74a689500c33a4b2b36761f9bcc22fcc4e3f9d21066ee0c9c74cf5f6c
|
||||
F test/wal.test b7cc6984709f54afbf8441747ced1f646af120bf0c1b1d847bfa39306fbea089
|
||||
F test/wal.test 07d61ee522bc203235a7979645d6c5d84f86882afad5b678532ee37b5b85b133
|
||||
F test/wal2.test 31f6e2c404b9f2cdf9ca19b105a1742fdc19653c2c936da39e3658c617524046
|
||||
F test/wal2big.test 829141cbecdda4329db8fa38705424c4a73db72a06b9540b06811a825d330409
|
||||
F test/wal2fault.test 2e8e60cacd5bcd451618aeffd05f676894d17202d3e2986e288d36e2c5993249
|
||||
F test/wal2lock.test 0ef98d72dc6bcf7711dedd684760488400d9a9a6eec0dc5d3822060437793552
|
||||
F test/wal2openclose.test 2b26be723ea7f4263c8d5d70b37efd1c359561a0526e39466c45fe8e6478daee
|
||||
F test/wal2recover.test 28b3fa0acb4e8725211a02803cd51116cd048841a876224f244af78039ba34fa
|
||||
F test/wal2recover2.test 3fe5d5932b16a3a38304a85bafed1f965faef40c230fd450838a0502e61343bb
|
||||
F test/wal2recover3.test 4a91689e165a38bc401736e6518188c2b0ff4fa1566d1810b8867536db128177
|
||||
F test/wal2rewrite.test 6ca6f631ffcf871240beab5f02608913fd075c6d0d31310b026c8383c65c9f9c
|
||||
F test/wal2rollback.test 23adc4a099b23f6aaea8b04fdca1c35861d887dd80f8be7da2d5273eb777e428
|
||||
F test/wal2savepoint.test 2c82bd6a6ee5066c156040d2e9c2415646fcf96116ae7ad127eaf0c0b4a85f22
|
||||
F test/wal2simple.test 320a08927f307d0ead26fa3fcef4e3f64279f49be9504f918cb33294f75aeec8
|
||||
F test/wal2snapshot.test 7a5f4629a3c43a43c3440b8b2ea9f07de91a46b0b9eea5f08f62b5bf5b6468df
|
||||
F test/wal3.test 5de023bb862fd1eb9d2ad26fa8d9c43abb5370582e5b08b2ae0d6f93661bc310
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9
|
||||
@@ -1992,7 +2006,7 @@ F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
|
||||
F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
|
||||
F test/walpersist.test 8d78a1ec91299163451417b451a2bac3481f8eb9f455b1ca507a6625c927ca6e
|
||||
F test/walprotocol.test 1b3f922125e341703f6e946d77fdc564d38fb3e07a9385cfdc6c99cac1ecf878
|
||||
F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db868eebc131
|
||||
F test/walprotocol2.test 7e4bedd5ee83607e2928ac438bf7332a396b980d3e02aa0746509ce11ad1f13c
|
||||
F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
|
||||
F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc
|
||||
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
|
||||
@@ -2034,7 +2048,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
|
||||
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
|
||||
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/window1.test 5e8abe56a7d667eeddbba6de180086dcf69ed528d046447a25464f945ece101f
|
||||
F test/window1.test 79dc3b9a2226f622d7e104a1fc750d1c4c3c08d6147b59085bdbe05352947ffa
|
||||
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
||||
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
@@ -2111,7 +2125,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c61e5f x
|
||||
F tool/mkctimec.tcl eec31c692f65585a33c567e4592e0a14817789d43618343cf942b6bfd957cbab x
|
||||
F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
|
||||
F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
@@ -2191,11 +2205,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 3210e1ca4d0efedf9710c97abd050ba10d3af98cb1f029c26daa84daf42fbc7e
|
||||
R 03f38bbe86d08cc2accd8330faccbd25
|
||||
T +sym-major-release *
|
||||
T +sym-release *
|
||||
T +sym-version-3.46.0 *
|
||||
P fdc0e1480a941d494e556331544cb40b2a997e8709e2c7fab1bed572007eb88d fc956353d3762d0e655b88f9d0c1a3840b40453a22e97160ccdf60485be56a92
|
||||
R 5eb44bd2dbdcbc353faa29da62f5ade1
|
||||
T *branch * wal2-3.46
|
||||
T *sym-wal2-3.46 *
|
||||
T -sym-wal2 *
|
||||
U drh
|
||||
Z 82f35d0822d1dfbb574e5dd2459b4a36
|
||||
Z e71227a71dc795f5e1dac20ad8c1c5a2
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e
|
||||
b917d07fc66c5af9e4839c4b9ed2e54bc18cca5209d54f32b34b65d31dfc3740
|
||||
|
||||
+1
-1
@@ -1320,7 +1320,7 @@ static int renameResolveTrigger(Parse *pParse){
|
||||
/* ALWAYS() because if the table of the trigger does not exist, the
|
||||
** error would have been hit before this point */
|
||||
if( ALWAYS(pParse->pTriggerTab) ){
|
||||
rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
|
||||
rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0;
|
||||
}
|
||||
|
||||
/* Resolve symbols in WHEN clause */
|
||||
|
||||
+5
-5
@@ -3308,10 +3308,10 @@ static int lockBtree(BtShared *pBt){
|
||||
goto page1_init_failed;
|
||||
}
|
||||
#else
|
||||
if( page1[18]>2 ){
|
||||
if( page1[18]>3 ){
|
||||
pBt->btsFlags |= BTS_READ_ONLY;
|
||||
}
|
||||
if( page1[19]>2 ){
|
||||
if( page1[19]>3 ){
|
||||
goto page1_init_failed;
|
||||
}
|
||||
|
||||
@@ -3323,9 +3323,9 @@ static int lockBtree(BtShared *pBt){
|
||||
** may not be the latest version - there may be a newer one in the log
|
||||
** file.
|
||||
*/
|
||||
if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){
|
||||
if( page1[19]>=2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){
|
||||
int isOpen = 0;
|
||||
rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
|
||||
rc = sqlite3PagerOpenWal(pBt->pPager, (page1[19]==3), &isOpen);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto page1_init_failed;
|
||||
}else{
|
||||
@@ -11388,7 +11388,7 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
|
||||
BtShared *pBt = pBtree->pBt;
|
||||
int rc; /* Return code */
|
||||
|
||||
assert( iVersion==1 || iVersion==2 );
|
||||
assert( iVersion==1 || iVersion==2 || iVersion==3 );
|
||||
|
||||
/* If setting the version fields to 1, do not automatically open the
|
||||
** WAL connection, even if the version fields are currently set to 2.
|
||||
|
||||
+4
-3
@@ -3064,8 +3064,9 @@ create_view_fail:
|
||||
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
/*
|
||||
** The Table structure pTable is really a VIEW. Fill in the names of
|
||||
** the columns of the view in the pTable structure. Return the number
|
||||
** of errors. If an error is seen leave an error message in pParse->zErrMsg.
|
||||
** the columns of the view in the pTable structure. Return non-zero if
|
||||
** there are errors. If an error is seen an error message is left
|
||||
** in pParse->zErrMsg.
|
||||
*/
|
||||
static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
Table *pSelTab; /* A fake table from which we get the result set */
|
||||
@@ -3188,7 +3189,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
sqlite3DeleteColumnNames(db, pTable);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIEW */
|
||||
return nErr;
|
||||
return nErr + pParse->nErr;
|
||||
}
|
||||
int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
assert( pTable!=0 );
|
||||
|
||||
@@ -779,6 +779,7 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#ifdef SQLITE_VDBE_COVERAGE
|
||||
"VDBE_COVERAGE",
|
||||
#endif
|
||||
"WAL2",
|
||||
#ifdef SQLITE_WIN32_MALLOC
|
||||
"WIN32_MALLOC",
|
||||
#endif
|
||||
|
||||
@@ -2206,6 +2206,8 @@ static void groupConcatValue(sqlite3_context *context){
|
||||
sqlite3_result_error_toobig(context);
|
||||
}else if( pAccum->accError==SQLITE_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else if( pGCC->nAccum>0 && pAccum->nChar==0 ){
|
||||
sqlite3_result_text(context, "", 1, SQLITE_STATIC);
|
||||
}else{
|
||||
const char *zText = sqlite3_str_value(pAccum);
|
||||
sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT);
|
||||
|
||||
@@ -717,6 +717,7 @@ Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){
|
||||
pRet->pSrc->nSrc = 1;
|
||||
pRet->pPrior = pLeft->pPrior;
|
||||
pRet->op = pLeft->op;
|
||||
if( pRet->pPrior ) pRet->selFlags |= SF_Values;
|
||||
pLeft->pPrior = 0;
|
||||
pLeft->op = TK_SELECT;
|
||||
assert( pLeft->pNext==0 );
|
||||
|
||||
+29
-25
@@ -789,20 +789,6 @@ static const unsigned char aJournalMagic[] = {
|
||||
# define USEFETCH(x) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The argument to this macro is a file descriptor (type sqlite3_file*).
|
||||
** Return 0 if it is not open, or non-zero (but not 1) if it is.
|
||||
**
|
||||
** This is so that expressions can be written as:
|
||||
**
|
||||
** if( isOpen(pPager->jfd) ){ ...
|
||||
**
|
||||
** instead of
|
||||
**
|
||||
** if( pPager->jfd->pMethods ){ ...
|
||||
*/
|
||||
#define isOpen(pFd) ((pFd)->pMethods!=0)
|
||||
|
||||
#ifdef SQLITE_DIRECT_OVERFLOW_READ
|
||||
/*
|
||||
** Return true if page pgno can be read directly from the database file
|
||||
@@ -933,6 +919,7 @@ static int assert_pager_state(Pager *p){
|
||||
assert( isOpen(p->jfd)
|
||||
|| p->journalMode==PAGER_JOURNALMODE_OFF
|
||||
|| p->journalMode==PAGER_JOURNALMODE_WAL
|
||||
|| p->journalMode==PAGER_JOURNALMODE_WAL2
|
||||
);
|
||||
}
|
||||
assert( pPager->dbOrigSize==pPager->dbFileSize );
|
||||
@@ -947,6 +934,7 @@ static int assert_pager_state(Pager *p){
|
||||
assert( isOpen(p->jfd)
|
||||
|| p->journalMode==PAGER_JOURNALMODE_OFF
|
||||
|| p->journalMode==PAGER_JOURNALMODE_WAL
|
||||
|| p->journalMode==PAGER_JOURNALMODE_WAL2
|
||||
|| (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
|
||||
);
|
||||
assert( pPager->dbOrigSize<=pPager->dbHintSize );
|
||||
@@ -959,6 +947,7 @@ static int assert_pager_state(Pager *p){
|
||||
assert( isOpen(p->jfd)
|
||||
|| p->journalMode==PAGER_JOURNALMODE_OFF
|
||||
|| p->journalMode==PAGER_JOURNALMODE_WAL
|
||||
|| p->journalMode==PAGER_JOURNALMODE_WAL2
|
||||
|| (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
|
||||
);
|
||||
break;
|
||||
@@ -2080,7 +2069,7 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){
|
||||
}
|
||||
pPager->journalOff = 0;
|
||||
}else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
|
||||
|| (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
|
||||
|| (pPager->exclusiveMode && pPager->journalMode<PAGER_JOURNALMODE_WAL)
|
||||
){
|
||||
rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile);
|
||||
pPager->journalOff = 0;
|
||||
@@ -2095,6 +2084,7 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){
|
||||
assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
|
||||
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
|
||||
|| pPager->journalMode==PAGER_JOURNALMODE_WAL
|
||||
|| pPager->journalMode==PAGER_JOURNALMODE_WAL2
|
||||
);
|
||||
sqlite3OsClose(pPager->jfd);
|
||||
if( bDelete ){
|
||||
@@ -3250,6 +3240,10 @@ static int pagerBeginReadTransaction(Pager *pPager){
|
||||
if( rc!=SQLITE_OK || changed ){
|
||||
pager_reset(pPager);
|
||||
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL
|
||||
|| pPager->journalMode==PAGER_JOURNALMODE_WAL2
|
||||
);
|
||||
pPager->journalMode = sqlite3WalJournalMode(pPager->pWal);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -3345,9 +3339,9 @@ static int pagerOpenWalIfPresent(Pager *pPager){
|
||||
rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
|
||||
}else{
|
||||
testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
|
||||
rc = sqlite3PagerOpenWal(pPager, 0);
|
||||
rc = sqlite3PagerOpenWal(pPager, 0, 0);
|
||||
}
|
||||
}else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
|
||||
}else if( pPager->journalMode>=PAGER_JOURNALMODE_WAL ){
|
||||
pPager->journalMode = PAGER_JOURNALMODE_DELETE;
|
||||
}
|
||||
}
|
||||
@@ -4851,6 +4845,7 @@ int sqlite3PagerOpen(
|
||||
nPathname + 8 + 1 + /* Journal filename */
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
nPathname + 4 + 1 + /* WAL filename */
|
||||
nPathname + 5 + 1 + /* Second WAL filename */
|
||||
#endif
|
||||
3 /* Terminator */
|
||||
);
|
||||
@@ -4903,6 +4898,8 @@ int sqlite3PagerOpen(
|
||||
sqlite3FileSuffix3(zFilename, pPager->zWal);
|
||||
pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1);
|
||||
#endif
|
||||
memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
|
||||
memcpy(pPtr, "-wal2", 5); pPtr += 5 + 1;
|
||||
}else{
|
||||
pPager->zWal = 0;
|
||||
}
|
||||
@@ -7339,7 +7336,8 @@ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
|
||||
|| eMode==PAGER_JOURNALMODE_OFF /* 2 */
|
||||
|| eMode==PAGER_JOURNALMODE_TRUNCATE /* 3 */
|
||||
|| eMode==PAGER_JOURNALMODE_MEMORY /* 4 */
|
||||
|| eMode==PAGER_JOURNALMODE_WAL /* 5 */ );
|
||||
|| eMode==PAGER_JOURNALMODE_WAL /* 5 */
|
||||
|| eMode==PAGER_JOURNALMODE_WAL2 /* 6 */ );
|
||||
|
||||
/* This routine is only called from the OP_JournalMode opcode, and
|
||||
** the logic there will never allow a temporary file to be changed
|
||||
@@ -7373,9 +7371,12 @@ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
|
||||
assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
|
||||
assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
|
||||
assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
|
||||
assert( (PAGER_JOURNALMODE_WAL2 & 5)==4 );
|
||||
|
||||
assert( isOpen(pPager->fd) || pPager->exclusiveMode );
|
||||
if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
|
||||
if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0
|
||||
&& eMode!=PAGER_JOURNALMODE_WAL2 /* TODO: fix this if possible */
|
||||
){
|
||||
/* In this case we would like to delete the journal file. If it is
|
||||
** not possible, then that is not a problem. Deleting the journal file
|
||||
** here is an optimization only.
|
||||
@@ -7550,7 +7551,7 @@ static int pagerExclusiveLock(Pager *pPager){
|
||||
** lock on the database file and use heap-memory to store the wal-index
|
||||
** in. Otherwise, use the normal shared-memory.
|
||||
*/
|
||||
static int pagerOpenWal(Pager *pPager){
|
||||
static int pagerOpenWal(Pager *pPager, int bWal2){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( pPager->pWal==0 && pPager->tempFile==0 );
|
||||
@@ -7571,7 +7572,7 @@ static int pagerOpenWal(Pager *pPager){
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalOpen(pPager->pVfs,
|
||||
pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, &pPager->pWal
|
||||
pPager->journalSizeLimit, bWal2, &pPager->pWal
|
||||
);
|
||||
}
|
||||
pagerFixMaplimit(pPager);
|
||||
@@ -7597,6 +7598,7 @@ static int pagerOpenWal(Pager *pPager){
|
||||
*/
|
||||
int sqlite3PagerOpenWal(
|
||||
Pager *pPager, /* Pager object */
|
||||
int bWal2, /* Open in wal2 mode if not already open */
|
||||
int *pbOpen /* OUT: Set to true if call is a no-op */
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
@@ -7613,9 +7615,9 @@ int sqlite3PagerOpenWal(
|
||||
/* Close any rollback journal previously open */
|
||||
sqlite3OsClose(pPager->jfd);
|
||||
|
||||
rc = pagerOpenWal(pPager);
|
||||
rc = pagerOpenWal(pPager, bWal2);
|
||||
if( rc==SQLITE_OK ){
|
||||
pPager->journalMode = PAGER_JOURNALMODE_WAL;
|
||||
pPager->journalMode = bWal2?PAGER_JOURNALMODE_WAL2:PAGER_JOURNALMODE_WAL;
|
||||
pPager->eState = PAGER_OPEN;
|
||||
}
|
||||
}else{
|
||||
@@ -7637,7 +7639,9 @@ int sqlite3PagerOpenWal(
|
||||
int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
|
||||
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL
|
||||
|| pPager->journalMode==PAGER_JOURNALMODE_WAL2
|
||||
);
|
||||
|
||||
/* If the log file is not already open, but does exist in the file-system,
|
||||
** it may need to be checkpointed before the connection can switch to
|
||||
@@ -7652,7 +7656,7 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK && logexists ){
|
||||
rc = pagerOpenWal(pPager);
|
||||
rc = pagerOpenWal(pPager, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-1
@@ -82,6 +82,23 @@ typedef struct PgHdr DbPage;
|
||||
#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
|
||||
#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
|
||||
#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
|
||||
#define PAGER_JOURNALMODE_WAL2 6 /* Use write-ahead logging mode 2 */
|
||||
|
||||
#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL || (x)==PAGER_JOURNALMODE_WAL2)
|
||||
|
||||
/*
|
||||
** The argument to this macro is a file descriptor (type sqlite3_file*).
|
||||
** Return 0 if it is not open, or non-zero (but not 1) if it is.
|
||||
**
|
||||
** This is so that expressions can be written as:
|
||||
**
|
||||
** if( isOpen(pPager->jfd) ){ ...
|
||||
**
|
||||
** instead of
|
||||
**
|
||||
** if( pPager->jfd->pMethods ){ ...
|
||||
*/
|
||||
#define isOpen(pFd) ((pFd)->pMethods!=0)
|
||||
|
||||
/*
|
||||
** Flags that make up the mask passed to sqlite3PagerGet().
|
||||
@@ -175,7 +192,7 @@ int sqlite3PagerSharedLock(Pager *pPager);
|
||||
int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
|
||||
int sqlite3PagerWalSupported(Pager *pPager);
|
||||
int sqlite3PagerWalCallback(Pager *pPager);
|
||||
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
|
||||
int sqlite3PagerOpenWal(Pager *pPager, int, int *pisOpen);
|
||||
int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
|
||||
# ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
|
||||
|
||||
+3
-3
@@ -530,9 +530,9 @@ cmd ::= select(X). {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( (p->selFlags & SF_MultiValue)==0 &&
|
||||
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
|
||||
cnt>mxSelect
|
||||
if( (p->selFlags & (SF_MultiValue|SF_Values))==0
|
||||
&& (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
|
||||
&& cnt>mxSelect
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
|
||||
}
|
||||
|
||||
+2
-1
@@ -290,7 +290,7 @@ const char *sqlite3JournalModename(int eMode){
|
||||
static char * const azModeName[] = {
|
||||
"delete", "persist", "off", "truncate", "memory"
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
, "wal"
|
||||
, "wal", "wal2"
|
||||
#endif
|
||||
};
|
||||
assert( PAGER_JOURNALMODE_DELETE==0 );
|
||||
@@ -299,6 +299,7 @@ const char *sqlite3JournalModename(int eMode){
|
||||
assert( PAGER_JOURNALMODE_TRUNCATE==3 );
|
||||
assert( PAGER_JOURNALMODE_MEMORY==4 );
|
||||
assert( PAGER_JOURNALMODE_WAL==5 );
|
||||
assert( PAGER_JOURNALMODE_WAL2==6 );
|
||||
assert( eMode>=0 && eMode<=ArraySize(azModeName) );
|
||||
|
||||
if( eMode==ArraySize(azModeName) ) return 0;
|
||||
|
||||
+10
-7
@@ -228,7 +228,7 @@ static void extendFJMatch(
|
||||
static SQLITE_NOINLINE int isValidSchemaTableName(
|
||||
const char *zTab, /* Name as it appears in the SQL */
|
||||
Table *pTab, /* The schema table we are trying to match */
|
||||
Schema *pSchema /* non-NULL if a database qualifier is present */
|
||||
const char *zDb /* non-NULL if a database qualifier is present */
|
||||
){
|
||||
const char *zLegacy;
|
||||
assert( pTab!=0 );
|
||||
@@ -239,7 +239,7 @@ static SQLITE_NOINLINE int isValidSchemaTableName(
|
||||
if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
|
||||
return 1;
|
||||
}
|
||||
if( pSchema==0 ) return 0;
|
||||
if( zDb==0 ) return 0;
|
||||
if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1;
|
||||
if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1;
|
||||
}else{
|
||||
@@ -422,7 +422,7 @@ static int lookupName(
|
||||
}
|
||||
}else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){
|
||||
if( pTab->tnum!=1 ) continue;
|
||||
if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue;
|
||||
if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue;
|
||||
}
|
||||
assert( ExprUseYTab(pExpr) );
|
||||
if( IN_RENAME_OBJECT && pItem->zAlias ){
|
||||
@@ -2154,6 +2154,9 @@ int sqlite3ResolveExprNames(
|
||||
** Resolve all names for all expression in an expression list. This is
|
||||
** just like sqlite3ResolveExprNames() except that it works for an expression
|
||||
** list rather than a single expression.
|
||||
**
|
||||
** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a
|
||||
** failure.
|
||||
*/
|
||||
int sqlite3ResolveExprListNames(
|
||||
NameContext *pNC, /* Namespace to resolve expressions in. */
|
||||
@@ -2162,7 +2165,7 @@ int sqlite3ResolveExprListNames(
|
||||
int i;
|
||||
int savedHasAgg = 0;
|
||||
Walker w;
|
||||
if( pList==0 ) return WRC_Continue;
|
||||
if( pList==0 ) return SQLITE_OK;
|
||||
w.pParse = pNC->pParse;
|
||||
w.xExprCallback = resolveExprStep;
|
||||
w.xSelectCallback = resolveSelectStep;
|
||||
@@ -2176,7 +2179,7 @@ int sqlite3ResolveExprListNames(
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
w.pParse->nHeight += pExpr->nHeight;
|
||||
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
|
||||
return WRC_Abort;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
#endif
|
||||
sqlite3WalkExprNN(&w, pExpr);
|
||||
@@ -2193,10 +2196,10 @@ int sqlite3ResolveExprListNames(
|
||||
(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
|
||||
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
|
||||
}
|
||||
if( w.pParse->nErr>0 ) return WRC_Abort;
|
||||
if( w.pParse->nErr>0 ) return SQLITE_ERROR;
|
||||
}
|
||||
pNC->ncFlags |= savedHasAgg;
|
||||
return WRC_Continue;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+9
-4
@@ -8977,7 +8977,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
import_cleanup(&sCtx);
|
||||
shell_out_of_memory();
|
||||
}
|
||||
nByte = strlen(zSql);
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
zSql = 0;
|
||||
@@ -8996,16 +8995,21 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
if( nCol==0 ) return 0; /* no columns, no error */
|
||||
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
|
||||
|
||||
nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */
|
||||
+ (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */
|
||||
+ strlen(zTable)*2 + 2 /* Quoted table name */
|
||||
+ nCol*2; /* Space for ",?" for each column */
|
||||
zSql = sqlite3_malloc64( nByte );
|
||||
if( zSql==0 ){
|
||||
import_cleanup(&sCtx);
|
||||
shell_out_of_memory();
|
||||
}
|
||||
if( zSchema ){
|
||||
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
|
||||
sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
|
||||
zSchema, zTable);
|
||||
}else{
|
||||
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
|
||||
sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
|
||||
}
|
||||
j = strlen30(zSql);
|
||||
for(i=1; i<nCol; i++){
|
||||
@@ -9014,6 +9018,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
zSql[j++] = ')';
|
||||
zSql[j] = 0;
|
||||
assert( j<nByte );
|
||||
if( eVerbose>=2 ){
|
||||
oputf("Insert using: %s\n", zSql);
|
||||
}
|
||||
|
||||
+1
-1
@@ -3388,7 +3388,7 @@ struct SrcList {
|
||||
#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
|
||||
#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
|
||||
#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */
|
||||
/* 0x2000 not currently used */
|
||||
#define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */
|
||||
#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
|
||||
/* 0x8000 not currently used */
|
||||
|
||||
|
||||
+17
-5
@@ -190,7 +190,7 @@ static int SQLITE_TCLAPI hexio_write(
|
||||
}
|
||||
|
||||
/*
|
||||
** USAGE: hexio_get_int HEXDATA
|
||||
** USAGE: hexio_get_int [-littleendian] HEXDATA
|
||||
**
|
||||
** Interpret the HEXDATA argument as a big-endian integer. Return
|
||||
** the value of that integer. HEXDATA can contain between 2 and 8
|
||||
@@ -207,12 +207,20 @@ static int SQLITE_TCLAPI hexio_get_int(
|
||||
const unsigned char *zIn;
|
||||
unsigned char *aOut;
|
||||
unsigned char aNum[4];
|
||||
int bLittle = 0;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA");
|
||||
if( objc==3 ){
|
||||
int n;
|
||||
char *z = Tcl_GetStringFromObj(objv[1], &n);
|
||||
if( n>=2 && n<=13 && memcmp(z, "-littleendian", n)==0 ){
|
||||
bLittle = 1;
|
||||
}
|
||||
}
|
||||
if( (objc-bLittle)!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "[-littleendian] HEXDATA");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn);
|
||||
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1+bLittle], &nIn);
|
||||
aOut = sqlite3_malloc( 1 + nIn/2 );
|
||||
if( aOut==0 ){
|
||||
return TCL_ERROR;
|
||||
@@ -225,7 +233,11 @@ static int SQLITE_TCLAPI hexio_get_int(
|
||||
memcpy(&aNum[4-nOut], aOut, nOut);
|
||||
}
|
||||
sqlite3_free(aOut);
|
||||
val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3];
|
||||
if( bLittle ){
|
||||
val = (aNum[3]<<24) | (aNum[2]<<16) | (aNum[1]<<8) | aNum[0];
|
||||
}else{
|
||||
val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3];
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(val));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ const char *sqlite3TestInit(Tcl_Interp *interp){
|
||||
extern int Fts5tcl_Init(Tcl_Interp *);
|
||||
extern int SqliteRbu_Init(Tcl_Interp*);
|
||||
extern int Sqlitetesttcl_Init(Tcl_Interp*);
|
||||
extern int Bgckpt_Init(Tcl_Interp*);
|
||||
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
||||
extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
|
||||
#endif
|
||||
@@ -168,6 +169,8 @@ const char *sqlite3TestInit(Tcl_Interp *interp){
|
||||
Fts5tcl_Init(interp);
|
||||
SqliteRbu_Init(interp);
|
||||
Sqlitetesttcl_Init(interp);
|
||||
Bgckpt_Init(interp);
|
||||
|
||||
|
||||
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
||||
Sqlitetestfts3_Init(interp);
|
||||
|
||||
+38
-25
@@ -7876,6 +7876,7 @@ case OP_JournalMode: { /* out2 */
|
||||
|| eNew==PAGER_JOURNALMODE_OFF
|
||||
|| eNew==PAGER_JOURNALMODE_MEMORY
|
||||
|| eNew==PAGER_JOURNALMODE_WAL
|
||||
|| eNew==PAGER_JOURNALMODE_WAL2
|
||||
|| eNew==PAGER_JOURNALMODE_QUERY
|
||||
);
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
@@ -7894,16 +7895,25 @@ case OP_JournalMode: { /* out2 */
|
||||
/* Do not allow a transition to journal_mode=WAL for a database
|
||||
** in temporary storage or if the VFS does not support shared memory
|
||||
*/
|
||||
if( eNew==PAGER_JOURNALMODE_WAL
|
||||
if( isWalMode(eNew)
|
||||
&& (sqlite3Strlen30(zFilename)==0 /* Temp file */
|
||||
|| !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */
|
||||
){
|
||||
eNew = eOld;
|
||||
}
|
||||
|
||||
if( (eNew!=eOld)
|
||||
&& (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
|
||||
){
|
||||
if( eNew!=eOld && (isWalMode(eNew) || isWalMode(eOld)) ){
|
||||
|
||||
/* Prevent changing directly to wal2 from wal mode. And vice versa. */
|
||||
if( isWalMode(eNew) && isWalMode(eOld) ){
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3VdbeError(p, "cannot change from %s to %s mode",
|
||||
sqlite3JournalModename(eOld), sqlite3JournalModename(eNew)
|
||||
);
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
|
||||
/* Prevent switching into or out of wal/wal2 mode mid-transaction */
|
||||
if( !db->autoCommit || db->nVdbeRead>1 ){
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3VdbeError(p,
|
||||
@@ -7911,31 +7921,34 @@ case OP_JournalMode: { /* out2 */
|
||||
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
|
||||
);
|
||||
goto abort_due_to_error;
|
||||
}else{
|
||||
|
||||
if( eOld==PAGER_JOURNALMODE_WAL ){
|
||||
/* If leaving WAL mode, close the log file. If successful, the call
|
||||
** to PagerCloseWal() checkpoints and deletes the write-ahead-log
|
||||
** file. An EXCLUSIVE lock may still be held on the database file
|
||||
** after a successful return.
|
||||
*/
|
||||
rc = sqlite3PagerCloseWal(pPager, db);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3PagerSetJournalMode(pPager, eNew);
|
||||
}
|
||||
}else if( eOld==PAGER_JOURNALMODE_MEMORY ){
|
||||
/* Cannot transition directly from MEMORY to WAL. Use mode OFF
|
||||
** as an intermediate */
|
||||
sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Open a transaction on the database file. Regardless of the journal
|
||||
** mode, this transaction always uses a rollback journal.
|
||||
if( isWalMode(eOld) ){
|
||||
/* If leaving WAL mode, close the log file. If successful, the call
|
||||
** to PagerCloseWal() checkpoints and deletes the write-ahead-log
|
||||
** file. An EXCLUSIVE lock may still be held on the database file
|
||||
** after a successful return.
|
||||
*/
|
||||
assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE );
|
||||
rc = sqlite3PagerCloseWal(pPager, db);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
|
||||
sqlite3PagerSetJournalMode(pPager, eNew);
|
||||
}
|
||||
}else if( eOld==PAGER_JOURNALMODE_MEMORY ){
|
||||
/* Cannot transition directly from MEMORY to WAL. Use mode OFF
|
||||
** as an intermediate */
|
||||
sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF);
|
||||
}
|
||||
|
||||
/* Open a transaction on the database file. Regardless of the journal
|
||||
** mode, this transaction always uses a rollback journal.
|
||||
*/
|
||||
assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE );
|
||||
if( rc==SQLITE_OK ){
|
||||
/* 1==rollback, 2==wal, 3==wal2 */
|
||||
rc = sqlite3BtreeSetVersion(pBt,
|
||||
1 + isWalMode(eNew) + (eNew==PAGER_JOURNALMODE_WAL2)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* ifndef SQLITE_OMIT_WAL */
|
||||
|
||||
+6
-3
@@ -2930,7 +2930,8 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
/* OFF */ 0,
|
||||
/* TRUNCATE */ 1,
|
||||
/* MEMORY */ 0,
|
||||
/* WAL */ 0
|
||||
/* WAL */ 0,
|
||||
/* WAL2 */ 0
|
||||
};
|
||||
Pager *pPager; /* Pager associated with pBt */
|
||||
needXcommit = 1;
|
||||
@@ -5336,7 +5337,8 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
|
||||
assert( iVar>0 );
|
||||
if( v ){
|
||||
Mem *pMem = &v->aVar[iVar-1];
|
||||
assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
|
||||
assert( (v->db->flags & SQLITE_EnableQPSG)==0
|
||||
|| (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 );
|
||||
if( 0==(pMem->flags & MEM_Null) ){
|
||||
sqlite3_value *pRet = sqlite3ValueNew(v->db);
|
||||
if( pRet ){
|
||||
@@ -5356,7 +5358,8 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
|
||||
*/
|
||||
void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
|
||||
assert( iVar>0 );
|
||||
assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
|
||||
assert( (v->db->flags & SQLITE_EnableQPSG)==0
|
||||
|| (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 );
|
||||
if( iVar>=32 ){
|
||||
v->expmask |= 0x80000000;
|
||||
}else{
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03)
|
||||
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
# define sqlite3WalOpen(x,y,z) 0
|
||||
# define sqlite3WalOpen(w,x,y,z) 0
|
||||
# define sqlite3WalLimit(x,y)
|
||||
# define sqlite3WalClose(v,w,x,y,z) 0
|
||||
# define sqlite3WalBeginReadTransaction(y,z) 0
|
||||
@@ -45,6 +45,7 @@
|
||||
# define sqlite3WalFramesize(z) 0
|
||||
# define sqlite3WalFindFrame(x,y,z) 0
|
||||
# define sqlite3WalFile(x) 0
|
||||
# define sqlite3WalJournalMode(x) 0
|
||||
# undef SQLITE_USE_SEH
|
||||
#else
|
||||
|
||||
@@ -56,7 +57,7 @@
|
||||
typedef struct Wal Wal;
|
||||
|
||||
/* Open and close a connection to a write-ahead log. */
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *,int,i64,int,Wal**);
|
||||
int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
|
||||
|
||||
/* Set the limiting size of a WAL file. */
|
||||
@@ -147,6 +148,9 @@ int sqlite3WalFramesize(Wal *pWal);
|
||||
/* Return the sqlite3_file object for the WAL file */
|
||||
sqlite3_file *sqlite3WalFile(Wal *pWal);
|
||||
|
||||
/* Return the journal mode (WAL or WAL2) used by this Wal object. */
|
||||
int sqlite3WalJournalMode(Wal *pWal);
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
int sqlite3WalWriteLock(Wal *pWal, int bLock);
|
||||
void sqlite3WalDb(Wal *pWal, sqlite3 *db);
|
||||
|
||||
+16
-35
@@ -3959,7 +3959,9 @@ static int whereLoopAddBtree(
|
||||
" according to whereIsCoveringIndex()\n", pProbe->zName));
|
||||
}
|
||||
}
|
||||
}else if( m==0 ){
|
||||
}else if( m==0
|
||||
&& (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
|
||||
){
|
||||
WHERETRACE(0x200,
|
||||
("-> %s a covering index according to bitmasks\n",
|
||||
pProbe->zName, m==0 ? "is" : "is not"));
|
||||
@@ -5848,6 +5850,10 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
|
||||
** the right-most table of a subquery that was flattened into the
|
||||
** main query and that subquery was the right-hand operand of an
|
||||
** inner join that held an ON or USING clause.
|
||||
** 6) The ORDER BY clause has 63 or fewer terms
|
||||
** 7) The omit-noop-join optimization is enabled.
|
||||
**
|
||||
** Items (1), (6), and (7) are checked by the caller.
|
||||
**
|
||||
** For example, given:
|
||||
**
|
||||
@@ -6261,6 +6267,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( pOrderBy && pOrderBy->nExpr>=BMS ){
|
||||
pOrderBy = 0;
|
||||
wctrlFlags &= ~WHERE_WANT_DISTINCT;
|
||||
wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */
|
||||
}
|
||||
|
||||
/* The number of tables in the FROM clause is limited by the number of
|
||||
@@ -6561,10 +6568,10 @@ WhereInfo *sqlite3WhereBegin(
|
||||
** in-line sqlite3WhereCodeOneLoopStart() for performance reasons.
|
||||
*/
|
||||
notReady = ~(Bitmask)0;
|
||||
if( pWInfo->nLevel>=2
|
||||
&& pResultSet!=0 /* these two combine to guarantee */
|
||||
&& 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */
|
||||
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
|
||||
if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */
|
||||
&& pResultSet!=0 /* Condition (1) */
|
||||
&& 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */
|
||||
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */
|
||||
){
|
||||
notReady = whereOmitNoopJoin(pWInfo, notReady);
|
||||
nTabList = pWInfo->nLevel;
|
||||
@@ -6884,26 +6891,6 @@ whereBeginError:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Return true if cursor iCur is opened by instruction k of the
|
||||
** bytecode. Used inside of assert() only.
|
||||
*/
|
||||
static int cursorIsOpen(Vdbe *v, int iCur, int k){
|
||||
while( k>=0 ){
|
||||
VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
|
||||
if( pOp->p1!=iCur ) continue;
|
||||
if( pOp->opcode==OP_Close ) return 0;
|
||||
if( pOp->opcode==OP_OpenRead ) return 1;
|
||||
if( pOp->opcode==OP_OpenWrite ) return 1;
|
||||
if( pOp->opcode==OP_OpenDup ) return 1;
|
||||
if( pOp->opcode==OP_OpenAutoindex ) return 1;
|
||||
if( pOp->opcode==OP_OpenEphemeral ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
/*
|
||||
** Generate the end of the WHERE loop. See comments on
|
||||
** sqlite3WhereBegin() for additional information.
|
||||
@@ -7203,16 +7190,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
** reference. Verify that this is harmless - that the
|
||||
** table being referenced really is open.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||
|| cursorIsOpen(v,pOp->p1,k)
|
||||
|| pOp->opcode==OP_Offset
|
||||
);
|
||||
#else
|
||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||
|| cursorIsOpen(v,pOp->p1,k)
|
||||
);
|
||||
#endif
|
||||
if( pLoop->wsFlags & WHERE_IDX_ONLY ){
|
||||
sqlite3ErrorMsg(pParse, "internal query planner error");
|
||||
pParse->rc = SQLITE_INTERNAL;
|
||||
}
|
||||
}
|
||||
}else if( pOp->opcode==OP_Rowid ){
|
||||
pOp->p1 = pLevel->iIdxCur;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ db close
|
||||
forcecopy test.db test.db-template
|
||||
|
||||
set unreadable_version 02
|
||||
ifcapable wal { set unreadable_version 03 }
|
||||
ifcapable wal { set unreadable_version 04 }
|
||||
do_test corruptA-2.1 {
|
||||
forcecopy test.db-template test.db
|
||||
hexio_write test.db 19 $unreadable_version ;# the read format number
|
||||
|
||||
+29
-9
@@ -465,18 +465,21 @@ lappend ::testsuitelist xxx
|
||||
test_suite "coverage-wal" -description {
|
||||
Coverage tests for file wal.c.
|
||||
} -files {
|
||||
wal.test wal2.test wal3.test wal4.test wal5.test
|
||||
wal2big.test wal2recover.test wal2rewrite.test
|
||||
wal2simple.test wal2snapshot.test wal2.test
|
||||
wal3.test wal4.test wal5.test
|
||||
wal64k.test wal6.test wal7.test wal8.test wal9.test
|
||||
walbak.test walbig.test walblock.test walcksum.test walcrash2.test
|
||||
walcrash3.test walcrash4.test walcrash.test walfault.test walhook.test
|
||||
walmode.test walnoshm.test waloverwrite.test walpersist.test
|
||||
walprotocol2.test walprotocol.test walro2.test walrofault.test
|
||||
walro.test walshared.test walslow.test walvfs.test
|
||||
walfault2.test
|
||||
nockpt.test
|
||||
|
||||
walbak.test walbig.test walblock.test walcksum.test
|
||||
walfault.test walhook.test walmode.test walnoshm.test
|
||||
waloverwrite.test walpersist.test walprotocol2.test
|
||||
walprotocol.test walro2.test walrofault.test walro.test
|
||||
walshared.test walslow.test wal.test
|
||||
wal2savepoint.test wal2lock.test wal2recover2.test
|
||||
walvfs.test walfault2.test nockpt.test
|
||||
snapshot2.test snapshot3.test snapshot4.test
|
||||
snapshot_fault.test snapshot.test snapshot_up.test
|
||||
walcrash2.test walcrash3.test walcrash4.test walcrash.test
|
||||
wal2fault.test
|
||||
}
|
||||
|
||||
test_suite "coverage-pager" -description {
|
||||
@@ -1034,6 +1037,23 @@ test_suite "wal" -description {
|
||||
fts3c.test fts3d.test fts3e.test fts3query.test
|
||||
}
|
||||
|
||||
test_suite "wal2" -description {
|
||||
Run tests with journal_mode=WAL2
|
||||
} -initialize {
|
||||
set ::G(savepoint6_iterations) 100
|
||||
} -shutdown {
|
||||
unset -nocomplain ::G(savepoint6_iterations)
|
||||
} -files {
|
||||
savepoint.test savepoint2.test savepoint6.test
|
||||
trans.test avtrans.test
|
||||
|
||||
fts3aa.test fts3ab.test fts3ac.test fts3ad.test
|
||||
fts3ae.test fts3af.test fts3ag.test fts3ah.test
|
||||
fts3ai.test fts3aj.test fts3ak.test fts3al.test
|
||||
fts3am.test fts3an.test fts3ao.test fts3b.test
|
||||
fts3c.test fts3d.test fts3e.test fts3query.test
|
||||
}
|
||||
|
||||
test_suite "rtree" -description {
|
||||
All R-tree related tests. Provides coverage of source file rtree.c.
|
||||
} -files [glob -nocomplain $::testdir/../ext/rtree/*.test]
|
||||
|
||||
+3
-3
@@ -41,7 +41,7 @@ do_test rdonly-1.1.1 {
|
||||
sqlite3_db_readonly db main
|
||||
} {0}
|
||||
|
||||
# Changes the write version from 1 to 3. Verify that the database
|
||||
# Changes the write version from 1 to 4. Verify that the database
|
||||
# can be read but not written.
|
||||
#
|
||||
do_test rdonly-1.2 {
|
||||
@@ -49,7 +49,7 @@ do_test rdonly-1.2 {
|
||||
hexio_get_int [hexio_read test.db 18 1]
|
||||
} 1
|
||||
do_test rdonly-1.3 {
|
||||
hexio_write test.db 18 03
|
||||
hexio_write test.db 18 04
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
@@ -83,7 +83,7 @@ do_test rdonly-1.5 {
|
||||
# the database is read-only until after it is locked.
|
||||
#
|
||||
set ro_version 02
|
||||
ifcapable wal { set ro_version 03 }
|
||||
ifcapable wal { set ro_version 04 }
|
||||
do_test rdonly-1.6 {
|
||||
hexio_write test.db 18 $ro_version ; # write-version
|
||||
hexio_write test.db 24 11223344 ; # change-counter
|
||||
|
||||
@@ -531,4 +531,17 @@ do_execsql_test 21.1 {
|
||||
INSERT INTO sqlite_temp_schema DEFAULT VALUES RETURNING sqlite_temp_schema.name;
|
||||
} {{}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 22.0 {
|
||||
PRAGMA writable_schema=ON;
|
||||
CREATE TABLE xyz (a);
|
||||
}
|
||||
do_catchsql_test 22.1 {
|
||||
INSERT INTO sqlite_temp_schema DEFAULT VALUES
|
||||
RETURNING
|
||||
(SELECT * FROM xyz AS sqlite_master WHERE a=sqlite_master.name);
|
||||
} {1 {no such column: sqlite_master.name}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-1
@@ -30,6 +30,7 @@ do_test savepoint-1.1 {
|
||||
RELEASE sp1;
|
||||
}
|
||||
} {}
|
||||
wal_check_journal_mode savepoint-1.1
|
||||
do_test savepoint-1.2 {
|
||||
execsql {
|
||||
SAVEPOINT sp1;
|
||||
@@ -807,7 +808,8 @@ do_test savepoint-11.6 {
|
||||
integrity_check savepoint-11.7
|
||||
do_test savepoint-11.8 {
|
||||
execsql { ROLLBACK }
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
file size test.db
|
||||
} {8192}
|
||||
|
||||
|
||||
+14
-3
@@ -15,6 +15,10 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
proc sql {zSql} {
|
||||
if {0 && $::debug_op} {
|
||||
puts stderr "$zSql ;"
|
||||
flush stderr
|
||||
}
|
||||
uplevel db eval [list $zSql]
|
||||
#puts stderr "$zSql ;"
|
||||
}
|
||||
@@ -67,11 +71,13 @@ proc x_to_y {x} {
|
||||
# delete_rows XVALUES
|
||||
#
|
||||
proc savepoint {zName} {
|
||||
if {$::debug_op} { puts stderr "savepoint $zName" ; flush stderr }
|
||||
catch { sql "SAVEPOINT $zName" }
|
||||
lappend ::lSavepoint [list $zName [array get ::aEntry]]
|
||||
}
|
||||
|
||||
proc rollback {zName} {
|
||||
if {$::debug_op} { puts stderr "rollback $zName" ; flush stderr }
|
||||
catch { sql "ROLLBACK TO $zName" }
|
||||
for {set i [expr {[llength $::lSavepoint]-1}]} {$i>=0} {incr i -1} {
|
||||
set zSavepoint [lindex $::lSavepoint $i 0]
|
||||
@@ -89,6 +95,7 @@ proc rollback {zName} {
|
||||
}
|
||||
|
||||
proc release {zName} {
|
||||
if {$::debug_op} { puts stderr "release $zName" ; flush stderr }
|
||||
catch { sql "RELEASE $zName" }
|
||||
for {set i [expr {[llength $::lSavepoint]-1}]} {$i>=0} {incr i -1} {
|
||||
set zSavepoint [lindex $::lSavepoint $i 0]
|
||||
@@ -104,6 +111,7 @@ proc release {zName} {
|
||||
}
|
||||
|
||||
proc insert_rows {lX} {
|
||||
if {$::debug_op} { puts stderr "insert_rows $lX" ; flush stderr }
|
||||
foreach x $lX {
|
||||
set y [x_to_y $x]
|
||||
|
||||
@@ -116,6 +124,7 @@ proc insert_rows {lX} {
|
||||
}
|
||||
|
||||
proc delete_rows {lX} {
|
||||
if {$::debug_op} { puts stderr "delete_rows $lX" ; flush stderr }
|
||||
foreach x $lX {
|
||||
# Update database [db]
|
||||
sql "DELETE FROM t1 WHERE x = $x"
|
||||
@@ -164,6 +173,11 @@ proc random_integers {nRes nRange} {
|
||||
}
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
set ::debug_op 0
|
||||
proc debug_ops {} {
|
||||
set ::debug_op 1
|
||||
}
|
||||
|
||||
proc database_op {} {
|
||||
set i [expr int(rand()*2)]
|
||||
if {$i==0} {
|
||||
@@ -185,9 +199,6 @@ proc savepoint_op {} {
|
||||
set C [lindex $cmds [expr int(rand()*6)]]
|
||||
set N [lindex $names [expr int(rand()*5)]]
|
||||
|
||||
#puts stderr " $C $N ; "
|
||||
#flush stderr
|
||||
|
||||
$C $N
|
||||
return ok
|
||||
}
|
||||
|
||||
@@ -155,6 +155,38 @@ if {[clang_sanitize_address]==0} {
|
||||
}
|
||||
}
|
||||
|
||||
# https://issues.chromium.org/issues/358174302
|
||||
# Need to support an unlimited number of terms in a VALUES clause, even
|
||||
# if some of those terms contain double-quoted string literals.
|
||||
#
|
||||
do_execsql_test select7-6.5 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a,b,c);
|
||||
}
|
||||
sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 10
|
||||
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 0
|
||||
do_catchsql_test select7-6.6 {
|
||||
INSERT INTO t1 VALUES
|
||||
(NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0),
|
||||
(0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""),
|
||||
(0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""),
|
||||
(0,NULL,0), (X'',X'',0.0);
|
||||
} {1 {no such column: "" - should this be a string literal in single-quotes?}}
|
||||
do_execsql_test select7-6.7 {
|
||||
SELECT count(*) FROM t1;
|
||||
} {0}
|
||||
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1
|
||||
do_catchsql_test select7-6.8 {
|
||||
INSERT INTO t1 VALUES
|
||||
(NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0),
|
||||
(0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""),
|
||||
(0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""),
|
||||
(0,NULL,0), (X'',X'',0.0);
|
||||
} {0 {}}
|
||||
do_execsql_test select7-6.9 {
|
||||
SELECT count(*) FROM t1;
|
||||
} {16}
|
||||
|
||||
# This block of tests verifies that bug aa92c76cd4 is fixed.
|
||||
#
|
||||
do_test select7-7.1 {
|
||||
|
||||
@@ -585,4 +585,16 @@ do_test shell5-7.1 {
|
||||
SELECT * FROM t1;}
|
||||
} {0 aaa|bbb|aaabbb}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
do_test shell5-8.1 {
|
||||
|
||||
set out [open shell5.csv w]
|
||||
fconfigure $out -translation lf
|
||||
puts $out x
|
||||
close $out
|
||||
|
||||
catchcmd :memory: {.import --csv shell5.csv '""""""""""""""""""""""""""""""""""""""""""""""'}
|
||||
} {0 {}}
|
||||
|
||||
finish_test
|
||||
|
||||
+20
-4
@@ -613,6 +613,7 @@ proc reset_db {} {
|
||||
forcedelete test.db
|
||||
forcedelete test.db-journal
|
||||
forcedelete test.db-wal
|
||||
forcedelete test.db-wal2
|
||||
sqlite3 db ./test.db
|
||||
set ::DB [sqlite3_connection_pointer db]
|
||||
if {[info exists ::SETUP_SQL]} {
|
||||
@@ -2326,17 +2327,32 @@ proc drop_all_indexes {{db db}} {
|
||||
# Returns true if this test should be run in WAL mode. False otherwise.
|
||||
#
|
||||
proc wal_is_wal_mode {} {
|
||||
expr {[permutation] eq "wal"}
|
||||
if {[permutation] eq "wal"} { return 1 }
|
||||
if {[permutation] eq "wal2"} { return 2 }
|
||||
return 0
|
||||
}
|
||||
proc wal_set_journal_mode {{db db}} {
|
||||
if { [wal_is_wal_mode] } {
|
||||
$db eval "PRAGMA journal_mode = WAL"
|
||||
switch -- [wal_is_wal_mode] {
|
||||
0 {
|
||||
}
|
||||
|
||||
1 {
|
||||
$db eval "PRAGMA journal_mode = WAL"
|
||||
}
|
||||
|
||||
2 {
|
||||
$db eval "PRAGMA journal_mode = WAL2"
|
||||
}
|
||||
}
|
||||
}
|
||||
proc wal_check_journal_mode {testname {db db}} {
|
||||
if { [wal_is_wal_mode] } {
|
||||
$db eval { SELECT * FROM sqlite_master }
|
||||
do_test $testname [list $db eval "PRAGMA main.journal_mode"] {wal}
|
||||
set expected "wal"
|
||||
if {[wal_is_wal_mode]==2} {
|
||||
set expected "wal2"
|
||||
}
|
||||
do_test $testname [list $db eval "PRAGMA main.journal_mode"] $expected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -282,11 +282,11 @@ ifcapable wal {
|
||||
INSERT INTO t2 VALUES('x', 'y');
|
||||
}
|
||||
lsort [array names ::T1]
|
||||
} {test.db1 test.db1-journal test.db1-wal}
|
||||
} {test.db1 test.db1-journal test.db1-wal test.db1-wal2}
|
||||
|
||||
do_test 5.1.2 {
|
||||
lsort [array names ::T2]
|
||||
} {test.db2 test.db2-journal test.db2-wal}
|
||||
} {test.db2 test.db2-journal test.db2-wal test.db2-wal2}
|
||||
db close
|
||||
|
||||
tvfs1 delete
|
||||
|
||||
+6
-6
@@ -1175,7 +1175,7 @@ foreach {tn pgsz works} {
|
||||
9 32768 1
|
||||
10 65536 1
|
||||
11 131072 0
|
||||
11 1016 0
|
||||
12 1016 0
|
||||
} {
|
||||
|
||||
if {$::SQLITE_MAX_PAGE_SIZE < $pgsz} {
|
||||
@@ -1185,14 +1185,14 @@ foreach {tn pgsz works} {
|
||||
for {set pg 1} {$pg <= 3} {incr pg} {
|
||||
forcecopy testX.db test.db
|
||||
forcedelete test.db-wal
|
||||
|
||||
|
||||
# Check that the database now exists and consists of three pages. And
|
||||
# that there is no associated wal file.
|
||||
#
|
||||
do_test wal-18.2.$tn.$pg.1 { file exists test.db-wal } 0
|
||||
do_test wal-18.2.$tn.$pg.2 { file exists test.db } 1
|
||||
do_test wal-18.2.$tn.$pg.3 { file size test.db } [expr 1024*3]
|
||||
|
||||
|
||||
do_test wal-18.2.$tn.$pg.4 {
|
||||
|
||||
# Create a wal file that contains a single frame (database page
|
||||
@@ -1224,16 +1224,16 @@ foreach {tn pgsz works} {
|
||||
puts -nonewline $fd $framehdr
|
||||
puts -nonewline $fd $framebody
|
||||
close $fd
|
||||
|
||||
|
||||
file size test.db-wal
|
||||
} [wal_file_size 1 $pgsz]
|
||||
|
||||
|
||||
do_test wal-18.2.$tn.$pg.5 {
|
||||
sqlite3 db test.db
|
||||
set rc [catch { db one {PRAGMA integrity_check} } msg]
|
||||
expr { $rc!=0 || $msg!="ok" }
|
||||
} $works
|
||||
|
||||
|
||||
db close
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# 2017 September 19
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# TESTRUNNER: slow
|
||||
#
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2big
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
CREATE INDEX t1c ON t1(c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 10000000;
|
||||
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<200000
|
||||
)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
} {wal2 10000000}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<200000
|
||||
)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
}
|
||||
|
||||
do_test 1.2 {
|
||||
list [expr [file size test.db-wal]>10000000] \
|
||||
[expr [file size test.db-wal2]>10000000]
|
||||
} {1 1}
|
||||
|
||||
do_test 1.3 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {400000 ok}
|
||||
|
||||
do_test 1.4 {
|
||||
db2 close
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {400000 ok}
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,52 @@
|
||||
# 2010 May 03
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
set testprefix wal2fault
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x,y);
|
||||
PRAGMA journal_mode = wal2;
|
||||
WITH s(i) AS ( SELECT 100 UNION ALL SELECT i-1 FROM s WHERE (i-1)>0 )
|
||||
INSERT INTO t1 SELECT i, randomblob(i) FROM s;
|
||||
WITH s(i) AS ( SELECT 100 UNION ALL SELECT i-1 FROM s WHERE (i-1)>0 )
|
||||
INSERT INTO t1 SELECT i, randomblob(i) FROM s;
|
||||
} {wal2}
|
||||
|
||||
do_test 1.1 {
|
||||
expr [file size test.db-wal]>10000
|
||||
} {1}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
execsql {
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
SELECT count(*) FROM sqlite_master;
|
||||
}
|
||||
} -body {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,106 @@
|
||||
# 2018 December 15
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2lock
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
db close
|
||||
testvfs tvfs
|
||||
sqlite3 db test.db -vfs tvfs
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA journal_mode = wal2;
|
||||
CREATE TABLE y1(y, yy);
|
||||
CREATE INDEX y1y ON y1(y);
|
||||
CREATE INDEX y1yy ON y1(yy);
|
||||
INSERT INTO y1 VALUES(1, 2), (3, 4), (5, 6);
|
||||
} {wal2}
|
||||
|
||||
tvfs script vfs_callback
|
||||
tvfs filter xShmLock
|
||||
|
||||
set ::lock [list]
|
||||
proc vfs_callback {func file name lock} {
|
||||
lappend ::lock $lock
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
do_execsql_test 1.1.1 {
|
||||
SELECT * FROM y1
|
||||
} {1 2 3 4 5 6}
|
||||
do_test 1.1.2 {
|
||||
set ::lock
|
||||
} {{4 1 lock shared} {4 1 unlock shared}}
|
||||
|
||||
set ::bFirst 1
|
||||
proc vfs_callback {func file name lock} {
|
||||
if {$::bFirst} {
|
||||
set ::bFirst 0
|
||||
return SQLITE_BUSY
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
do_execsql_test 1.2 {
|
||||
SELECT * FROM y1
|
||||
} {1 2 3 4 5 6}
|
||||
|
||||
set ::bFirst 1
|
||||
proc vfs_callback {func file name lock} {
|
||||
if {$::bFirst} {
|
||||
set ::bFirst 0
|
||||
return SQLITE_IOERR
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
do_catchsql_test 1.3 {
|
||||
SELECT * FROM y1
|
||||
} {1 {disk I/O error}}
|
||||
|
||||
puts "# Warning: This next test case causes SQLite to call xSleep(1) 100 times."
|
||||
puts "# Normally this equates to a delay of roughly 10 seconds, but if SQLite"
|
||||
puts "# is built on unix without HAVE_USLEEP defined, it may be much longer."
|
||||
proc vfs_callback {func file name lock} { return SQLITE_BUSY }
|
||||
do_catchsql_test 1.4 {
|
||||
SELECT * FROM y1
|
||||
} {1 {locking protocol}}
|
||||
proc vfs_callback {func file name lock} { return SQLITE_OK }
|
||||
|
||||
sqlite3 db2 test.db -vfs tvfs
|
||||
set ::bFirst 1
|
||||
|
||||
proc vfs_callback {func file name lock} {
|
||||
if {$::bFirst} {
|
||||
set ::bFirst 0
|
||||
db2 eval { INSERT INTO y1 VALUES(7, 8) }
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
SELECT * FROM y1
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
do_execsql_test 1.5.2 {
|
||||
SELECT * FROM y1
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
|
||||
db close
|
||||
db2 close
|
||||
tvfs delete
|
||||
finish_test
|
||||
@@ -0,0 +1,81 @@
|
||||
# 2017 September 19
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2openclose
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA journal_size_limit = 75000;
|
||||
} {wal2 0 75000}
|
||||
|
||||
do_test 1.1 {
|
||||
for {set ii 1} {$ii <= 200} {incr ii} {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES($ii, $ii, $ii);
|
||||
}
|
||||
}
|
||||
expr ([file size test.db-wal2] - 75000) > 30000
|
||||
} {1}
|
||||
|
||||
do_test 1.2 {
|
||||
db close
|
||||
list [file exists test.db-wal] [file exists test.db-wal2]
|
||||
} {0 0}
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 1.3 {
|
||||
SELECT sum(c) FROM t1
|
||||
} {20100}
|
||||
db close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
} {wal2}
|
||||
db_save_and_close
|
||||
|
||||
db_restore_and_reopen
|
||||
do_execsql_test 2.1 {
|
||||
SELECT * FROM t1;
|
||||
} {1 2 3}
|
||||
|
||||
do_test 2.2 {
|
||||
sqlite3 db2 test.db
|
||||
db2 eval {INSERT INTO t1 VALUES(4, 5, 6)}
|
||||
db2 close
|
||||
} {}
|
||||
|
||||
breakpoint
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 2.2 {
|
||||
SELECT * FROM t1;
|
||||
} {1 2 3 4 5 6}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,272 @@
|
||||
# 2018 December 13
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2recover
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
proc db_copy {from to} {
|
||||
forcecopy $from $to
|
||||
forcecopy ${from}-wal ${to}-wal
|
||||
forcecopy ${from}-wal2 ${to}-wal2
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
CREATE INDEX t1c ON t1(c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 15000;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
} {wal2 15000 0}
|
||||
|
||||
do_test 1.1 {
|
||||
for {set i 1} {$i <= 1000} {incr i} {
|
||||
execsql { INSERT INTO t1 VALUES(random(), random(), random()) }
|
||||
db_copy test.db test.db2
|
||||
sqlite3 db2 test.db
|
||||
set res [execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check;
|
||||
} db2]
|
||||
db2 close
|
||||
if {$res != [list $i ok]} {
|
||||
error "failure on iteration $i"
|
||||
}
|
||||
}
|
||||
set {} {}
|
||||
} {}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
CREATE TABLE t2(x UNIQUE);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(randomblob(4000));
|
||||
INSERT INTO t1 VALUES(randomblob(4000));
|
||||
INSERT INTO t1 VALUES(randomblob(4000));
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
INSERT INTO t2 VALUES(randomblob(4000));
|
||||
INSERT INTO t2 VALUES(randomblob(4000));
|
||||
INSERT INTO t2 VALUES(randomblob(4000));
|
||||
COMMIT;
|
||||
} {wal2 10000 0}
|
||||
do_test 2.0.1 {
|
||||
list [file size test.db] [file size test.db-wal] [file size test.db-wal2]
|
||||
} {5120 28328 28328}
|
||||
|
||||
# Test recovery with both wal files intact.
|
||||
#
|
||||
do_test 2.1 {
|
||||
db_copy test.db test.db2
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {3 3 ok}
|
||||
|
||||
do_test 2.2 {
|
||||
db2 close
|
||||
db_copy test.db test.db2
|
||||
hexio_write test.db2-wal 16 12345678
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
} db2
|
||||
} {0 3}
|
||||
|
||||
do_test 2.3 {
|
||||
db2 close
|
||||
db_copy test.db test.db2
|
||||
hexio_write test.db2-wal2 16 12345678
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {3 0 ok}
|
||||
|
||||
do_test 2.4 {
|
||||
db2 close
|
||||
db_copy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {3 0 ok}
|
||||
|
||||
do_test 2.5 {
|
||||
db2 close
|
||||
db_copy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal2
|
||||
forcecopy test.db-wal2 test.db2-wal
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {3 3 ok}
|
||||
|
||||
do_test 2.6 {
|
||||
db2 close
|
||||
db_copy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal2
|
||||
close [open test.db-wal w]
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {3 0 ok}
|
||||
|
||||
do_test 2.7 {
|
||||
db2 close
|
||||
db_copy test.db test.db2
|
||||
forcedelete test.db2-wal
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
PRAGMA integrity_check;
|
||||
} db2
|
||||
} {0 0 ok}
|
||||
db2 close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a TEXT, b TEXT, c TEXT);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
CREATE INDEX t1c ON t1(c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA cache_size = 5;
|
||||
} {wal2 10000 0}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 200)
|
||||
INSERT INTO t1 SELECT i, i, i FROM s;
|
||||
|
||||
INSERT INTO t1 VALUES(201, 201, 201);
|
||||
} {}
|
||||
|
||||
do_test 3.2 {
|
||||
list [file size test.db] [file size test.db-wal] [file size test.db-wal2]
|
||||
} {5120 15752 4224}
|
||||
|
||||
do_test 3.3 {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA cache_size = 5;
|
||||
BEGIN;
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 200)
|
||||
INSERT INTO t1 SELECT i, i, i FROM s;
|
||||
} db2
|
||||
list [file size test.db2] [file size test.db2-wal] [file size test.db2-wal2]
|
||||
} {5120 15752 23088}
|
||||
|
||||
|
||||
if {$tcl_platform(platform)!="windows"} {
|
||||
# These cannot be run under windows, as the *-shm file may not be read
|
||||
# while it is locked by the database connection.
|
||||
do_test 3.4 {
|
||||
set fd [open test.db2-shm]
|
||||
fconfigure $fd -encoding binary -translation binary
|
||||
set data [read $fd]
|
||||
close $fd
|
||||
|
||||
set fd [open test.db-shm w]
|
||||
fconfigure $fd -encoding binary -translation binary
|
||||
puts -nonewline $fd $data
|
||||
close $fd
|
||||
|
||||
execsql {
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 10)
|
||||
INSERT INTO t1 SELECT i, i, i FROM s;
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {211 ok}
|
||||
|
||||
do_test 3.5 {
|
||||
list [file size test.db] [file size test.db-wal] [file size test.db-wal2]
|
||||
} {5120 15752 18896}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
PRAGMA journal_mode = wal2;
|
||||
CREATE TABLE xyz(x, y, z);
|
||||
INSERT INTO xyz VALUES('x', 'y', 'z');
|
||||
} {wal2}
|
||||
db close
|
||||
do_test 4.1 {
|
||||
close [open test.db-wal w]
|
||||
file mkdir test.db-wal2
|
||||
sqlite3 db test.db
|
||||
catchsql { SELECT * FROM xyz }
|
||||
} {1 {unable to open database file}}
|
||||
db close
|
||||
file delete test.db-wal2
|
||||
db2 close
|
||||
|
||||
do_test 4.2 {
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
INSERT INTO xyz VALUES('a', 'b', 'c');
|
||||
}
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
forcedelete test.db2-wal2
|
||||
file mkdir test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
catchsql { SELECT * FROM xyz } db2
|
||||
} {1 {unable to open database file}}
|
||||
db2 close
|
||||
file delete test.db2-wal2
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
# 2018 December 13
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2recover2
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(x);
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t1 SELECT i FROM s;
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t2 SELECT i FROM s;
|
||||
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
} {wal2 10000}
|
||||
|
||||
set ::L 1125750
|
||||
set ::M 1126500
|
||||
set ::H 1127250
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
UPDATE t1 SET x=x+1;
|
||||
UPDATE t2 SET x=x+1 WHERE rowid<=750;
|
||||
|
||||
SELECT sum(x) FROM t1;
|
||||
SELECT sum(x) FROM t2;
|
||||
} [list $H $M]
|
||||
|
||||
do_test 1.2 {
|
||||
list [file size test.db] [file size test.db-wal] [file size test.db-wal2]
|
||||
} {31744 14704 7368}
|
||||
|
||||
proc cksum {zIn data} {
|
||||
if {[string length $zIn]==0} {
|
||||
set s0 0
|
||||
set s1 0
|
||||
} else {
|
||||
set s0 [hexio_get_int [string range $zIn 0 7]]
|
||||
set s1 [hexio_get_int [string range $zIn 8 15]]
|
||||
}
|
||||
set n [expr [string length $data] / 8]
|
||||
|
||||
for {set i 0} {$i < $n} {incr i 2} {
|
||||
set x0 [hexio_get_int -l [string range $data [expr $i*8] [expr $i*8+7]]]
|
||||
set x1 [hexio_get_int -l [string range $data [expr $i*8+8] [expr $i*8+8+7]]]
|
||||
|
||||
set s0 [expr ($s0 + $x0 + $s1) & 0xFFFFFFFF]
|
||||
set s1 [expr ($s1 + $x1 + $s0) & 0xFFFFFFFF]
|
||||
}
|
||||
|
||||
return "[hexio_render_int32 $s0][hexio_render_int32 $s1]"
|
||||
}
|
||||
|
||||
proc fix_wal_cksums {file} {
|
||||
# Fix the checksum on the wal header.
|
||||
set data [hexio_read $file 0 32]
|
||||
set cksum [cksum {} [string range $data 0 47]]
|
||||
set salt [hexio_read $file 16 8]
|
||||
hexio_write $file 24 $cksum
|
||||
|
||||
# Fix the checksums for all pages in the wal file.
|
||||
set pgsz [hexio_get_int [hexio_read $file 8 4]]
|
||||
set sz [file size $file]
|
||||
for {set off 32} {$off < $sz} {incr off [expr $pgsz+24]} {
|
||||
set e [hexio_read $file $off 8]
|
||||
set cksum [cksum $cksum $e]
|
||||
|
||||
set p [hexio_read $file [expr $off+24] $pgsz]
|
||||
set cksum [cksum $cksum $p]
|
||||
|
||||
hexio_write $file [expr $off+8] $salt
|
||||
hexio_write $file [expr $off+16] $cksum
|
||||
}
|
||||
}
|
||||
|
||||
proc wal_incr_hdrfield {file field} {
|
||||
switch -- $field {
|
||||
nCkpt { set offset 12 }
|
||||
salt0 { set offset 16 }
|
||||
salt1 { set offset 20 }
|
||||
default {
|
||||
error "unknown field $field - should be \"nCkpt\", \"salt0\" or \"salt1\""
|
||||
}
|
||||
}
|
||||
|
||||
# Increment the value in the wal header.
|
||||
set v [hexio_get_int [hexio_read $file $offset 4]]
|
||||
incr v
|
||||
hexio_write $file $offset [hexio_render_int32 $v]
|
||||
|
||||
# Fix various checksums
|
||||
fix_wal_cksums $file
|
||||
}
|
||||
|
||||
proc wal_set_nckpt {file val} {
|
||||
# Increment the value in the wal header.
|
||||
hexio_write $file 12 [hexio_render_int32 $val]
|
||||
|
||||
# Fix various checksums
|
||||
fix_wal_cksums $file
|
||||
}
|
||||
|
||||
proc wal_set_follow {file prevfile} {
|
||||
set pgsz [hexio_get_int [hexio_read $prevfile 8 4]]
|
||||
set sz [file size $prevfile]
|
||||
set cksum [hexio_read $prevfile [expr $sz-$pgsz-8] 8]
|
||||
|
||||
hexio_write $file 16 $cksum
|
||||
fix_wal_cksums $file
|
||||
}
|
||||
|
||||
foreach {tn file field} {
|
||||
1 test.db2-wal salt0
|
||||
2 test.db2-wal salt1
|
||||
3 test.db2-wal nCkpt
|
||||
4 test.db2-wal2 salt0
|
||||
5 test.db2-wal2 salt1
|
||||
6 test.db2-wal2 nCkpt
|
||||
} {
|
||||
do_test 1.3.$tn {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
wal_incr_hdrfield $file $field
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1;
|
||||
SELECT sum(x) FROM t2;
|
||||
} db2
|
||||
} [list $H $L]
|
||||
db2 close
|
||||
}
|
||||
|
||||
do_test 1.4 {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal2 test.db2-wal
|
||||
forcedelete test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1;
|
||||
SELECT sum(x) FROM t2;
|
||||
} db2
|
||||
} [list $L $M]
|
||||
|
||||
do_test 1.5 {
|
||||
db2 close
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal2 test.db2-wal
|
||||
forcecopy test.db-wal test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1;
|
||||
SELECT sum(x) FROM t2;
|
||||
} db2
|
||||
} [list $H $M]
|
||||
|
||||
db2 close
|
||||
foreach {tn file field} {
|
||||
1 test.db2-wal salt0
|
||||
2 test.db2-wal salt1
|
||||
3 test.db2-wal2 salt0
|
||||
4 test.db2-wal2 salt1
|
||||
} {
|
||||
do_test 1.6.$tn {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal2 test.db2-wal
|
||||
forcecopy test.db-wal test.db2-wal2
|
||||
wal_incr_hdrfield $file $field
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1;
|
||||
SELECT sum(x) FROM t2;
|
||||
} db2
|
||||
} [list $H $L]
|
||||
db2 close
|
||||
}
|
||||
|
||||
foreach {tn nCkpt1 nCkpt2 res} [list \
|
||||
1 2 1 "$H $M" \
|
||||
2 2 2 "$L $M" \
|
||||
3 3 1 "$H $L" \
|
||||
4 15 14 "$H $M" \
|
||||
5 0 15 "$H $M" \
|
||||
6 1 15 "$L $M" \
|
||||
] {
|
||||
do_test 1.7.$tn {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal2 test.db2-wal
|
||||
forcecopy test.db-wal test.db2-wal2
|
||||
|
||||
wal_set_nckpt test.db2-wal2 $nCkpt2
|
||||
wal_set_nckpt test.db2-wal $nCkpt1
|
||||
wal_set_follow test.db2-wal test.db2-wal2
|
||||
|
||||
|
||||
sqlite3 db2 test.db2
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1;
|
||||
SELECT sum(x) FROM t2;
|
||||
} db2
|
||||
} $res
|
||||
db2 close
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 1.8.1 {
|
||||
PRAGMA autovacuum = 0;
|
||||
PRAGMA page_size = 4096;
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(x);
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t1 SELECT i FROM s;
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t2 SELECT i FROM s;
|
||||
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t2 SELECT i FROM s;
|
||||
} {wal2 10000}
|
||||
|
||||
do_test 1.8.2 {
|
||||
list [file size test.db-wal] [file size test.db-wal2]
|
||||
} {24752 0}
|
||||
|
||||
do_execsql_test 1.8.3 { PRAGMA user_version = 123 }
|
||||
do_test 1.8.4 {
|
||||
list [file size test.db-wal] [file size test.db-wal2]
|
||||
} {24752 4152}
|
||||
|
||||
do_test 1.8.5 {
|
||||
hexio_write test.db-wal2 [expr 56+16] 0400
|
||||
fix_wal_cksums test.db-wal2
|
||||
} {}
|
||||
|
||||
ifcapable oversize_cell_check {
|
||||
set msg {database disk image is malformed}
|
||||
} else {
|
||||
set msg {malformed database schema (?)}
|
||||
}
|
||||
|
||||
do_test 1.8.6 {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
catchsql { SELECT * FROM sqlite_master } db2
|
||||
} [list 1 $msg]
|
||||
db2 close
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,52 @@
|
||||
# 2022 June 28
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2recover3
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(x);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
} {wal2 0 10000}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t1 SELECT i FROM s;
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1500 )
|
||||
INSERT INTO t2 SELECT i FROM s;
|
||||
}
|
||||
|
||||
db_save_and_close
|
||||
set fd [open sv_test.db-wal2 r+]
|
||||
seek $fd 4000
|
||||
puts -nonewline $fd 0
|
||||
close $fd
|
||||
|
||||
db_restore_and_reopen
|
||||
do_execsql_test 1.2 {
|
||||
SELECT sql FROM sqlite_schema;
|
||||
} {{CREATE TABLE t1(x)} {CREATE TABLE t2(x)}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# 2017 September 19
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2rewrite
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
proc filesize {filename} {
|
||||
if {[file exists $filename]} {
|
||||
return [file size $filename]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
foreach {tn jrnlmode} {
|
||||
1 wal
|
||||
2 wal2
|
||||
} {
|
||||
reset_db
|
||||
execsql "PRAGMA journal_mode = $jrnlmode"
|
||||
do_execsql_test $tn.1 {
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
PRAGMA cache_size = 5;
|
||||
PRAGMA wal_autocheckpoint = 10;
|
||||
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER, c BLOB);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
CREATE INDEX t1c ON t1(c);
|
||||
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION SELECT i+1 FROM s WHERE i<10
|
||||
)
|
||||
INSERT INTO t1 SELECT i, i, randomblob(800) FROM s;
|
||||
} {10000 10}
|
||||
|
||||
for {set i 0} {$i < 4} {incr i} {
|
||||
do_execsql_test $tn.$i.1 {
|
||||
UPDATE t1 SET c=randomblob(800) WHERE (b%10)==5 AND ($i%2)
|
||||
}
|
||||
do_execsql_test $tn.$i.2 {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
UPDATE t1 SET b=b+10, c=randomblob(800);
|
||||
}
|
||||
execsql COMMIT
|
||||
|
||||
do_test $tn.$i.3 { expr [filesize test.db-wal] < 100000 } 1
|
||||
do_test $tn.$i.4 { expr [filesize test.db-wal2] < 100000 } 1
|
||||
|
||||
set sum [db eval {SELECT sum(b), md5sum(c) FROM t1}]
|
||||
|
||||
do_test $tn.$i.5 {
|
||||
foreach f [glob -nocomplain test.db2*] {forcedelete $f}
|
||||
foreach f [glob -nocomplain test.db*] {
|
||||
forcecopy $f [string map {test.db test.db2} $f]
|
||||
}
|
||||
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval {SELECT sum(b), md5sum(c) FROM t1}
|
||||
} $sum
|
||||
db2 close
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,62 @@
|
||||
# 2017 September 19
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2rollback
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE TABLE t2(a, b, c);
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
CREATE INDEX i2 ON t1(b);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA cache_size = 5;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 1000
|
||||
)
|
||||
INSERT INTO t1 SELECT i, i, randomblob(200) FROM s;
|
||||
} {wal2 10000}
|
||||
|
||||
do_test 1.1 {
|
||||
expr [file size test.db-wal] > 10000
|
||||
} 1
|
||||
|
||||
do_test 1.2 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b+1;
|
||||
INSERT INTO t2 VALUES(1,2,3);
|
||||
}
|
||||
expr [file size test.db-wal2] > 10000
|
||||
} {1}
|
||||
|
||||
breakpoint
|
||||
do_execsql_test 1.3 {
|
||||
ROLLBACK;
|
||||
SELECT * FROM t2;
|
||||
SELECT count(*) FROM t1 WHERE a=b;
|
||||
PRAGMA integrity_check;
|
||||
} {1000 ok}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,73 @@
|
||||
# 2018 December 13
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2savepoint
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
CREATE INDEX t1c ON t1(c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 15000;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA cache_size = 5;
|
||||
} {wal2 15000 0}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 200)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
} {}
|
||||
|
||||
do_test 1.2 {
|
||||
list [file size test.db] [file size test.db-wal] [file size test.db-wal2]
|
||||
} {5120 23088 0}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
BEGIN;
|
||||
SAVEPOINT abc;
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 100)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
ROLLBACK TO abc;
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 10)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
COMMIT;
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check;
|
||||
} {210 ok}
|
||||
|
||||
do_execsql_test 1.4 {
|
||||
BEGIN;
|
||||
SAVEPOINT abc;
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 100)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
ROLLBACK TO abc;
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s where i < 10)
|
||||
INSERT INTO t1 SELECT random(), random(), random() FROM s;
|
||||
COMMIT;
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check;
|
||||
} {220 ok}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,475 @@
|
||||
# 2017 September 19
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix wal2simple
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests verify that a client can switch in and out of wal
|
||||
# and wal2 mode. But that it is not possible to change directly from wal
|
||||
# to wal2, or from wal2 to wal mode.
|
||||
#
|
||||
do_execsql_test 1.1.0 {
|
||||
PRAGMA journal_mode = wal2
|
||||
} {wal2}
|
||||
execsql { SELECT * FROM sqlite_master}
|
||||
do_execsql_test 1.x {
|
||||
PRAGMA journal_mode;
|
||||
PRAGMA main.journal_mode;
|
||||
} {wal2 wal2}
|
||||
db close
|
||||
do_test 1.1.1 { file size test.db } {1024}
|
||||
do_test 1.1.2 { hexio_read test.db 18 2 } 0303
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 1.2.0 {
|
||||
SELECT * FROM sqlite_master;
|
||||
PRAGMA journal_mode = delete;
|
||||
} {delete}
|
||||
db close
|
||||
do_test 1.2.1 { file size test.db } {1024}
|
||||
do_test 1.2.2 { hexio_read test.db 18 2 } 0101
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 1.3.0 {
|
||||
SELECT * FROM sqlite_master;
|
||||
PRAGMA journal_mode = wal;
|
||||
} {wal}
|
||||
db close
|
||||
do_test 1.3.1 { file size test.db } {1024}
|
||||
do_test 1.3.2 { hexio_read test.db 18 2 } 0202
|
||||
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 1.4.0 {
|
||||
PRAGMA journal_mode = wal2;
|
||||
} {1 {cannot change from wal to wal2 mode}}
|
||||
do_execsql_test 1.4.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
PRAGMA journal_mode = delete;
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_mode = wal2;
|
||||
} {wal delete wal2 wal2}
|
||||
do_catchsql_test 1.4.2 {
|
||||
PRAGMA journal_mode = wal;
|
||||
} {1 {cannot change from wal2 to wal mode}}
|
||||
db close
|
||||
do_test 1.4.3 { hexio_read test.db 18 2 } 0303
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that recovery in wal2 mode works.
|
||||
#
|
||||
forcedelete test.db test.db-wal test.db-wal2
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 5000;
|
||||
} {wal2 5000}
|
||||
|
||||
proc wal_hook {DB nm nFrame} { $DB eval { PRAGMA wal_checkpoint } }
|
||||
db wal_hook {wal_hook db}
|
||||
|
||||
for {set i 1} {$i <= 200} {incr i} {
|
||||
execsql { INSERT INTO t1 VALUES(NULL, randomblob(100)) }
|
||||
set res [db eval { SELECT sum(a), md5sum(b) FROM t1 }]
|
||||
|
||||
do_test 2.1.$i {
|
||||
foreach f [glob -nocomplain test.db2*] { forcedelete $f }
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval { SELECT sum(a), md5sum(b) FROM t1 }
|
||||
} $res
|
||||
|
||||
db2 close
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(x BLOB, y INTEGER PRIMARY KEY);
|
||||
CREATE INDEX i1 ON t1(x);
|
||||
PRAGMA cache_size = 5;
|
||||
PRAGMA journal_mode = wal2;
|
||||
} {wal2}
|
||||
|
||||
do_test 3.1 {
|
||||
execsql BEGIN
|
||||
for {set i 1} {$i < 1000} {incr i} {
|
||||
execsql { INSERT INTO t1 VALUES(randomblob(800), $i) }
|
||||
}
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
catch { db close }
|
||||
foreach f [glob -nocomplain test.db*] { forcedelete $f }
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE t1(x, y);
|
||||
PRAGMA journal_mode = wal2;
|
||||
} {wal2}
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
SELECT * FROM t1;
|
||||
} {}
|
||||
|
||||
do_execsql_test 4.2 {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
} {}
|
||||
|
||||
do_execsql_test 4.3 {
|
||||
SELECT * FROM t1;
|
||||
} {1 2}
|
||||
|
||||
do_test 4.4 {
|
||||
sqlite3 db2 test.db
|
||||
execsql { SELECT * FROM t1 } db2
|
||||
} {1 2}
|
||||
|
||||
do_test 4.5 {
|
||||
lsort [glob test.db*]
|
||||
} {test.db test.db-shm test.db-wal test.db-wal2}
|
||||
|
||||
do_test 4.6 {
|
||||
db close
|
||||
db2 close
|
||||
sqlite3 db test.db
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {1 2}
|
||||
|
||||
do_execsql_test 4.7 {
|
||||
PRAGMA journal_size_limit = 4000;
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
INSERT INTO t1 VALUES(11, 12);
|
||||
INSERT INTO t1 VALUES(13, 14);
|
||||
INSERT INTO t1 VALUES(15, 16);
|
||||
INSERT INTO t1 VALUES(17, 18);
|
||||
SELECT * FROM t1;
|
||||
} {4000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18}
|
||||
|
||||
do_test 4.8 {
|
||||
sqlite3 db2 test.db
|
||||
execsql { SELECT * FROM t1 } db2
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18}
|
||||
|
||||
do_test 4.9 {
|
||||
db close
|
||||
db2 close
|
||||
lsort [glob test.db*]
|
||||
} {test.db}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON t1(b, c);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 4000;
|
||||
} {wal2 4000}
|
||||
|
||||
proc wal_hook {DB nm nFrame} {
|
||||
$DB eval { PRAGMA wal_checkpoint }
|
||||
}
|
||||
db wal_hook [list wal_hook db]
|
||||
|
||||
|
||||
foreach js {4000 8000 12000} {
|
||||
foreach NROW [list 100 200 300 400 500 600 1000] {
|
||||
do_test 5.$js.$NROW.1 {
|
||||
db eval "DELETE FROM t1"
|
||||
db eval "PRAGMA journal_size_limit = $js"
|
||||
set nTotal 0
|
||||
for {set i 0} {$i < $NROW} {incr i} {
|
||||
db eval { INSERT INTO t1 VALUES($i, $i, randomblob(abs(random()%50))) }
|
||||
incr nTotal $i
|
||||
}
|
||||
set {} {}
|
||||
} {}
|
||||
|
||||
do_test 5.$js.$NROW.2 {
|
||||
sqlite3 db2 test.db
|
||||
db2 eval {
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*), sum(b) FROM t1;
|
||||
}
|
||||
} [list ok $NROW $nTotal]
|
||||
|
||||
db2 close
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE tx(x);
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA journal_size_limit = 3500;
|
||||
} {wal2 3500}
|
||||
|
||||
do_test 6.1 {
|
||||
for {set i 0} {$i < 10} {incr i} {
|
||||
execsql "CREATE TABLE t$i (x);"
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 6.2.1 {
|
||||
foreach f [glob -nocomplain test.db2*] { forcedelete $f }
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval { SELECT * FROM sqlite_master }
|
||||
} {}
|
||||
do_test 6.2.2 {
|
||||
db2 eval {
|
||||
PRAGMA journal_mode = wal2;
|
||||
SELECT * FROM sqlite_master;
|
||||
}
|
||||
} {wal2}
|
||||
|
||||
do_test 6.3.1 {
|
||||
db2 close
|
||||
foreach f [glob -nocomplain test.db2*] { forcedelete $f }
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
forcecopy test.db test.db2
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval { SELECT * FROM sqlite_master }
|
||||
} {table tx tx 2 {CREATE TABLE tx(x)}}
|
||||
do_test 6.3.2 {
|
||||
db2 eval {
|
||||
PRAGMA journal_mode = wal2;
|
||||
SELECT * FROM sqlite_master;
|
||||
}
|
||||
} {wal2 table tx tx 2 {CREATE TABLE tx(x)}}
|
||||
|
||||
do_test 6.4.1 {
|
||||
db2 close
|
||||
foreach f [glob -nocomplain test.db2*] { forcedelete $f }
|
||||
forcecopy test.db-wal2 test.db2-wal2
|
||||
forcecopy test.db-wal test.db2-wal
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval { SELECT * FROM sqlite_master }
|
||||
} {}
|
||||
do_test 6.4.2 {
|
||||
db2 eval {
|
||||
PRAGMA journal_mode = wal2;
|
||||
SELECT * FROM sqlite_master;
|
||||
}
|
||||
} {wal2}
|
||||
db2 close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
sqlite3 db2 test.db
|
||||
do_execsql_test 7.0 {
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
PRAGMA journal_mode = wal2;
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
BEGIN;
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES( randomblob(8000) );
|
||||
COMMIT;
|
||||
} {10000 wal2 0}
|
||||
|
||||
do_test 7.1 {
|
||||
list [file size test.db-wal] [file size test.db-wal2]
|
||||
} {9464 0}
|
||||
|
||||
# Connection db2 is holding a PART1 lock.
|
||||
#
|
||||
# 7.2.2: Test that the PART1 does not prevent db from switching to the
|
||||
# other wal file.
|
||||
#
|
||||
# 7.2.3: Test that the PART1 does prevent a checkpoint of test.db-wal.
|
||||
#
|
||||
# 7.2.4: Test that after the PART1 is released the checkpoint is possible.
|
||||
#
|
||||
do_test 7.2.1 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT count(*) FROM t1;
|
||||
} db2
|
||||
} {1}
|
||||
do_test 7.2.2 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES( randomblob(800) );
|
||||
INSERT INTO t1 VALUES( randomblob(800) );
|
||||
}
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {13656 3176 1024}
|
||||
do_test 7.2.3 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {13656 3176 1024}
|
||||
do_test 7.2.4 {
|
||||
execsql { END } db2
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {13656 3176 11264}
|
||||
|
||||
# Connection db2 is holding a PART2_FULL1 lock.
|
||||
#
|
||||
# 7.3.2: Test that the lock does not prevent checkpointing.
|
||||
#
|
||||
# 7.3.3: Test that the lock does prevent the writer from overwriting
|
||||
# test.db-wal.
|
||||
#
|
||||
# 7.3.4: Test that after the PART2_FULL1 is released the writer can
|
||||
# switch wal files and overwrite test.db-wal
|
||||
#
|
||||
db close
|
||||
db2 close
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
do_test 7.3.1 {
|
||||
execsql {
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
INSERT INTO t1 VALUES(randomblob(10000));
|
||||
INSERT INTO t1 VALUES(randomblob(500));
|
||||
}
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT count(*) FROM t1;
|
||||
} db2
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 3176 12288}
|
||||
do_test 7.3.2 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 3176 22528}
|
||||
do_test 7.3.3 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(randomblob(10000));
|
||||
INSERT INTO t1 VALUES(randomblob(500));
|
||||
}
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 18896 22528}
|
||||
do_test 7.3.4 {
|
||||
execsql END db2
|
||||
execsql { INSERT INTO t1 VALUES(randomblob(5000)); }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 18896 22528}
|
||||
|
||||
# Connection db2 is holding a PART2 lock.
|
||||
#
|
||||
# 7.4.2: Test that the lock does not prevent writer switching to test.db-wal.
|
||||
#
|
||||
# 7.3.3: Test that the lock does prevent checkpointing of test.db-wal2.
|
||||
#
|
||||
# 7.3.4: Test that after the PART2 is released test.db-wal2 can be
|
||||
# checkpointed.
|
||||
#
|
||||
db close
|
||||
db2 close
|
||||
breakpoint
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
do_test 7.4.1 {
|
||||
execsql {
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
INSERT INTO t1 VALUES(randomblob(10000));
|
||||
INSERT INTO t1 VALUES(randomblob(10000));
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT count(*) FROM t1;
|
||||
} db2
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 12608 50176}
|
||||
do_test 7.4.2 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(randomblob(5000));
|
||||
}
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 12608 50176}
|
||||
do_test 7.4.3 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 12608 50176}
|
||||
do_test 7.4.4 {
|
||||
execsql END db2
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 12608 60416}
|
||||
|
||||
# Connection db2 is holding a PART1_FULL2 lock.
|
||||
#
|
||||
# 7.5.2: Test that the lock does not prevent a checkpoint of test.db-wal2.
|
||||
#
|
||||
# 7.5.3: Test that the lock does prevent the writer from overwriting
|
||||
# test.db-wal2.
|
||||
#
|
||||
# 7.5.4: Test that after the PART1_FULL2 lock is released, the writer
|
||||
# can switch to test.db-wal2.
|
||||
#
|
||||
db close
|
||||
db2 close
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
do_test 7.5.1 {
|
||||
execsql {
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
PRAGMA journal_size_limit = 10000;
|
||||
INSERT INTO t1 VALUES(randomblob(10000));
|
||||
INSERT INTO t1 VALUES(randomblob(10000));
|
||||
PRAGMA wal_checkpoint;
|
||||
INSERT INTO t1 VALUES(randomblob(5000));
|
||||
}
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT count(*) FROM t1;
|
||||
} db2
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 12608 76800}
|
||||
do_test 7.5.2 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {12608 12608 87040}
|
||||
do_test 7.5.3.1 {
|
||||
execsql { INSERT INTO t1 VALUES(randomblob(5000)) }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {14704 12608 87040}
|
||||
do_test 7.5.3.2 {
|
||||
execsql { INSERT INTO t1 VALUES(randomblob(5000)) }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {22040 12608 87040}
|
||||
do_test 7.5.4 {
|
||||
execsql END db2
|
||||
execsql { INSERT INTO t1 VALUES(randomblob(5000)) }
|
||||
list [file size test.db-wal] [file size test.db-wal2] [file size test.db]
|
||||
} {22040 12608 87040}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# 2018 December 5
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL2" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
set testprefix wal2snapshot
|
||||
ifcapable !wal {finish_test ; return }
|
||||
ifcapable !snapshot {finish_test; return}
|
||||
|
||||
foreach {tn mode} {1 wal 2 wal2} {
|
||||
reset_db
|
||||
do_execsql_test $tn.1 "PRAGMA journal_mode = $mode" $mode
|
||||
|
||||
do_execsql_test $tn.2 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
BEGIN;
|
||||
}
|
||||
|
||||
# Check that sqlite3_snapshot_get() is an error for a wal2 db.
|
||||
#
|
||||
if {$tn==1} {
|
||||
do_test 1.3 {
|
||||
set S [sqlite3_snapshot_get db main]
|
||||
sqlite3_snapshot_free $S
|
||||
} {}
|
||||
} else {
|
||||
do_test 2.3 {
|
||||
list [catch { sqlite3_snapshot_get db main } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
}
|
||||
|
||||
# Check that sqlite3_snapshot_recover() is an error for a wal2 db.
|
||||
#
|
||||
do_execsql_test $tn.4 COMMIT
|
||||
if {$tn==1} {
|
||||
do_test 1.5 {
|
||||
sqlite3_snapshot_recover db main
|
||||
} {}
|
||||
} else {
|
||||
do_test 2.5 {
|
||||
list [catch { sqlite3_snapshot_recover db main } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
}
|
||||
|
||||
# Check that sqlite3_snapshot_open() is an error for a wal2 db.
|
||||
#
|
||||
if {$tn==1} {
|
||||
do_test 1.6 {
|
||||
execsql BEGIN
|
||||
set SNAPSHOT [sqlite3_snapshot_get_blob db main]
|
||||
sqlite3_snapshot_open_blob db main $SNAPSHOT
|
||||
execsql COMMIT
|
||||
} {}
|
||||
} else {
|
||||
do_test 2.6.1 {
|
||||
execsql BEGIN
|
||||
set res [
|
||||
list [catch { sqlite3_snapshot_open_blob db main $SNAPSHOT } msg] $msg
|
||||
]
|
||||
execsql COMMIT
|
||||
set res
|
||||
} {1 SQLITE_ERROR}
|
||||
do_test 2.6.2 {
|
||||
execsql BEGIN
|
||||
execsql {SELECT * FROM sqlite_master}
|
||||
set res [
|
||||
list [catch { sqlite3_snapshot_open_blob db main $SNAPSHOT } msg] $msg
|
||||
]
|
||||
execsql COMMIT
|
||||
set res
|
||||
} {1 SQLITE_ERROR}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ proc lock_callback {method filename handle lock} {
|
||||
db2 eval { INSERT INTO x VALUES('x') }
|
||||
}
|
||||
}
|
||||
db timeout 10
|
||||
db timeout 1100
|
||||
do_catchsql_test 2.4 {
|
||||
BEGIN EXCLUSIVE;
|
||||
} {0 {}}
|
||||
|
||||
@@ -2375,5 +2375,23 @@ do_execsql_test 77.2 {
|
||||
SELECT max(~likely(x)) FILTER (WHERE true) FROM t1 INDEXED BY t1x GROUP BY x;
|
||||
} {-2 -3 -5 -9}
|
||||
|
||||
# 2024-05-23 https://sqlite.org/forum/forumpost/bf8f43aa522c2299
|
||||
#
|
||||
# A bug in group_concat() when used as a window function, reported
|
||||
# just hours after the 3.46.0 release, though first appearing
|
||||
# in 3.28.0.
|
||||
#
|
||||
# When used as a window function, a group_concat() was not
|
||||
# correctly distinguishing between NULL and empty-string for
|
||||
# its return value.
|
||||
#
|
||||
do_execsql_test 78.1 {
|
||||
SELECT quote(group_concat(x) OVER ()) FROM (SELECT '' AS x);
|
||||
} ''
|
||||
do_execsql_test 78.2 {
|
||||
SELECT quote(group_concat(x) OVER (
|
||||
ORDER BY y RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING
|
||||
)) FROM (SELECT 'abc' AS x, 1 AS y);
|
||||
} NULL
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -389,6 +389,8 @@ set options(THREADSAFE) {
|
||||
#endif
|
||||
}
|
||||
|
||||
set options(WAL2) { "WAL2", }
|
||||
|
||||
proc trim_name {in} {
|
||||
set ret $in
|
||||
if {[string range $in 0 6]=="SQLITE_"} {
|
||||
|
||||
Reference in New Issue
Block a user