mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge the latest enhancements from trunk.
FossilOrigin-Name: 91e5c07eaf884d3598df8eb54f0910a80df48397
This commit is contained in:
@@ -1032,7 +1032,7 @@ FTS5_SRC = \
|
|||||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||||
cp $(TOP)/ext/fts5/fts5parse.y .
|
cp $(TOP)/ext/fts5/fts5parse.y .
|
||||||
rm -f fts5parse.h
|
rm -f fts5parse.h
|
||||||
./lemon $(OPTS) fts5parse.y
|
./lemon$(BEXE) $(OPTS) fts5parse.y
|
||||||
|
|
||||||
fts5parse.h: fts5parse.c
|
fts5parse.h: fts5parse.c
|
||||||
|
|
||||||
@@ -1164,8 +1164,9 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
|
|||||||
# symbols that do not begin with "sqlite3_". It is run as part of the
|
# symbols that do not begin with "sqlite3_". It is run as part of the
|
||||||
# releasetest.tcl script.
|
# releasetest.tcl script.
|
||||||
#
|
#
|
||||||
|
VALIDIDS=' sqlite3(changeset|changegroup|session)?_'
|
||||||
checksymbols: sqlite3.lo
|
checksymbols: sqlite3.lo
|
||||||
nm -g --defined-only sqlite3.o | egrep -v ' sqlite3(changeset|session)?_' ; test $$? -ne 0
|
nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
|
||||||
echo '0 errors out of 1 tests'
|
echo '0 errors out of 1 tests'
|
||||||
|
|
||||||
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
|
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
|
||||||
|
@@ -24,12 +24,22 @@
|
|||||||
*/
|
*/
|
||||||
void usage(const char *zArgv0){
|
void usage(const char *zArgv0){
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s [-step NSTEP] TARGET-DB RBU-DB\n"
|
"Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Argument RBU-DB must be an RBU database containing an update suitable for\n"
|
"Where options are:\n"
|
||||||
" target database TARGET-DB. If NSTEP is set to less than or equal to zero\n"
|
"\n"
|
||||||
" (the default value), this program attempts to apply the entire update to\n"
|
" -step NSTEP\n"
|
||||||
" the target database.\n"
|
" -vacuum\n"
|
||||||
|
"\n"
|
||||||
|
" If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
|
||||||
|
" database containing an update suitable for target database TARGET-DB.\n"
|
||||||
|
" Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
|
||||||
|
" RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
|
||||||
|
" API documentation for details).\n"
|
||||||
|
"\n"
|
||||||
|
" If NSTEP is set to less than or equal to zero (the default value), this \n"
|
||||||
|
" program attempts to perform the entire update or vacuum operation before\n"
|
||||||
|
" exiting\n"
|
||||||
"\n"
|
"\n"
|
||||||
" If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
|
" If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
|
||||||
" to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
|
" to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
|
||||||
@@ -69,29 +79,43 @@ int main(int argc, char **argv){
|
|||||||
char *zErrmsg; /* Error message, if any */
|
char *zErrmsg; /* Error message, if any */
|
||||||
sqlite3rbu *pRbu; /* RBU handle */
|
sqlite3rbu *pRbu; /* RBU handle */
|
||||||
int nStep = 0; /* Maximum number of step() calls */
|
int nStep = 0; /* Maximum number of step() calls */
|
||||||
|
int bVacuum = 0;
|
||||||
int rc;
|
int rc;
|
||||||
sqlite3_int64 nProgress = 0;
|
sqlite3_int64 nProgress = 0;
|
||||||
|
int nArg = argc-2;
|
||||||
|
|
||||||
/* Process command line arguments. Following this block local variables
|
if( argc<3 ) usage(argv[0]);
|
||||||
** zTarget, zRbu and nStep are all set. */
|
for(i=1; i<nArg; i++){
|
||||||
if( argc==5 ){
|
const char *zArg = argv[i];
|
||||||
size_t nArg1 = strlen(argv[1]);
|
int nArg = strlen(zArg);
|
||||||
if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]);
|
if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
|
||||||
nStep = atoi(argv[2]);
|
bVacuum = 1;
|
||||||
}else if( argc!=3 ){
|
}else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i<nArg-1 ){
|
||||||
usage(argv[0]);
|
i++;
|
||||||
|
nStep = atoi(argv[i]);
|
||||||
|
}else{
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zTarget = argv[argc-2];
|
zTarget = argv[argc-2];
|
||||||
zRbu = argv[argc-1];
|
zRbu = argv[argc-1];
|
||||||
|
|
||||||
report_default_vfs();
|
report_default_vfs();
|
||||||
|
|
||||||
/* Open an RBU handle. If nStep is less than or equal to zero, call
|
/* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
|
||||||
|
** regular RBU update handle otherwise. */
|
||||||
|
if( bVacuum ){
|
||||||
|
pRbu = sqlite3rbu_vacuum(zTarget, zRbu);
|
||||||
|
}else{
|
||||||
|
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
||||||
|
}
|
||||||
|
report_rbu_vfs(pRbu);
|
||||||
|
|
||||||
|
/* If nStep is less than or equal to zero, call
|
||||||
** sqlite3rbu_step() until either the RBU has been completely applied
|
** sqlite3rbu_step() until either the RBU has been completely applied
|
||||||
** or an error occurs. Or, if nStep is greater than zero, call
|
** or an error occurs. Or, if nStep is greater than zero, call
|
||||||
** sqlite3rbu_step() a maximum of nStep times. */
|
** sqlite3rbu_step() a maximum of nStep times. */
|
||||||
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
|
||||||
report_rbu_vfs(pRbu);
|
|
||||||
for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++);
|
for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++);
|
||||||
nProgress = sqlite3rbu_progress(pRbu);
|
nProgress = sqlite3rbu_progress(pRbu);
|
||||||
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
||||||
|
98
ext/rbu/rbufault3.test
Normal file
98
ext/rbu/rbufault3.test
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# 2016 April 20
|
||||||
|
#
|
||||||
|
# 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 contains fault injection tests for RBU vacuum operations.
|
||||||
|
#
|
||||||
|
|
||||||
|
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||||
|
source $testdir/malloc_common.tcl
|
||||||
|
set ::testprefix rbufault3
|
||||||
|
|
||||||
|
foreach {fault errlist} {
|
||||||
|
oom-* {
|
||||||
|
{1 SQLITE_NOMEM}
|
||||||
|
{1 SQLITE_IOERR_NOMEM}
|
||||||
|
{1 {SQLITE_NOMEM - out of memory}}
|
||||||
|
}
|
||||||
|
|
||||||
|
ioerr-* {
|
||||||
|
{1 {SQLITE_IOERR - disk I/O error}}
|
||||||
|
{1 SQLITE_IOERR}
|
||||||
|
{1 SQLITE_IOERR_WRITE}
|
||||||
|
{1 SQLITE_IOERR_FSYNC}
|
||||||
|
{1 SQLITE_IOERR_READ}
|
||||||
|
{1 {SQLITE_IOERR - unable to open database: test.db2}}
|
||||||
|
{1 {SQLITE_ERROR - unable to open database: test.db2}}
|
||||||
|
{1 {SQLITE_ERROR - SQL logic error or missing database}}
|
||||||
|
}
|
||||||
|
|
||||||
|
cantopen* {
|
||||||
|
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
|
||||||
|
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
|
||||||
|
{1 {SQLITE_CANTOPEN - unable to open database file}}
|
||||||
|
{1 SQLITE_CANTOPEN}
|
||||||
|
}
|
||||||
|
|
||||||
|
} {
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 0 {
|
||||||
|
CREATE TABLE target(x UNIQUE, y, z, PRIMARY KEY(y));
|
||||||
|
INSERT INTO target VALUES(1, 2, 3);
|
||||||
|
INSERT INTO target VALUES(4, 5, 6);
|
||||||
|
INSERT INTO target VALUES(7, 8, 9);
|
||||||
|
CREATE INDEX i1 ON target(z);
|
||||||
|
}
|
||||||
|
faultsim_save_and_close
|
||||||
|
|
||||||
|
do_faultsim_test 1 -faults $fault -prep {
|
||||||
|
faultsim_restore_and_reopen
|
||||||
|
forcedelete test.db2
|
||||||
|
} -body {
|
||||||
|
sqlite3rbu_vacuum rbu test.db test.db2
|
||||||
|
while {[rbu step]=="SQLITE_OK"} {}
|
||||||
|
rbu close
|
||||||
|
} -test {
|
||||||
|
eval [list faultsim_test_result {0 SQLITE_DONE} {*}$::errlist]
|
||||||
|
}
|
||||||
|
|
||||||
|
do_faultsim_test 2 -faults $fault -prep {
|
||||||
|
faultsim_restore_and_reopen
|
||||||
|
forcedelete test.db2
|
||||||
|
} -body {
|
||||||
|
sqlite3rbu_vacuum rbu test.db test.db2
|
||||||
|
rbu step
|
||||||
|
rbu close
|
||||||
|
} -test {
|
||||||
|
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
|
||||||
|
}
|
||||||
|
|
||||||
|
forcedelete test.db2
|
||||||
|
sqlite3rbu_vacuum rbu test.db test.db2
|
||||||
|
rbu step
|
||||||
|
rbu close
|
||||||
|
faultsim_save_and_close
|
||||||
|
|
||||||
|
do_faultsim_test 3 -faults $fault -prep {
|
||||||
|
faultsim_restore_and_reopen
|
||||||
|
forcedelete test.db2
|
||||||
|
} -body {
|
||||||
|
sqlite3rbu_vacuum rbu test.db test.db2
|
||||||
|
rbu step
|
||||||
|
rbu close
|
||||||
|
} -test {
|
||||||
|
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
410
ext/rbu/rbuvacuum.test
Normal file
410
ext/rbu/rbuvacuum.test
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
# 2016 April 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 contains tests for the RBU module. More specifically, it
|
||||||
|
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
|
||||||
|
# expected.
|
||||||
|
#
|
||||||
|
|
||||||
|
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||||
|
set ::testprefix rbuvacuum
|
||||||
|
|
||||||
|
proc do_rbu_vacuum_test {tn step} {
|
||||||
|
uplevel [list do_test $tn.1 {
|
||||||
|
if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||||
|
while 1 {
|
||||||
|
if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||||
|
set rc [rbu step]
|
||||||
|
if {$rc!="SQLITE_OK"} break
|
||||||
|
if {$step==1} { rbu close }
|
||||||
|
}
|
||||||
|
rbu close
|
||||||
|
} {SQLITE_DONE}]
|
||||||
|
|
||||||
|
uplevel [list do_execsql_test $tn.2 {
|
||||||
|
PRAGMA integrity_check
|
||||||
|
} ok]
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach step {0 1} {
|
||||||
|
|
||||||
|
set ::testprefix rbuvacuum-step=$step
|
||||||
|
reset_db
|
||||||
|
|
||||||
|
# Simplest possible vacuum.
|
||||||
|
do_execsql_test 1.0 {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||||
|
INSERT INTO t1 VALUES(1, 2, 3);
|
||||||
|
INSERT INTO t1 VALUES(4, 5, 6);
|
||||||
|
INSERT INTO t1 VALUES(7, 8, 9);
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {ok}
|
||||||
|
do_rbu_vacuum_test 1.1 $step
|
||||||
|
|
||||||
|
# A vacuum that actually reclaims space.
|
||||||
|
do_execsql_test 1.2.1 {
|
||||||
|
INSERT INTO t1 VALUES(8, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(9, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(10, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(11, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(12, randomblob(900), randomblob(900));
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {12}
|
||||||
|
do_execsql_test 1.2.2 {
|
||||||
|
DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {12}
|
||||||
|
do_rbu_vacuum_test 1.2.3 $step
|
||||||
|
do_execsql_test 1.2.4 {
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {3}
|
||||||
|
|
||||||
|
# Add an index to the table.
|
||||||
|
do_execsql_test 1.3.1 {
|
||||||
|
CREATE INDEX t1b ON t1(b);
|
||||||
|
INSERT INTO t1 VALUES(13, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(14, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(15, randomblob(900), randomblob(900));
|
||||||
|
INSERT INTO t1 VALUES(16, randomblob(900), randomblob(900));
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {18}
|
||||||
|
do_execsql_test 1.3.2 {
|
||||||
|
DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {18}
|
||||||
|
do_rbu_vacuum_test 1.3.3 $step
|
||||||
|
do_execsql_test 1.3.4 {
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {5}
|
||||||
|
|
||||||
|
# WITHOUT ROWID table.
|
||||||
|
do_execsql_test 1.4.1 {
|
||||||
|
CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID;
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 1, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 2, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 3, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 4, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 6, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 7, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 8, randomblob(900));
|
||||||
|
|
||||||
|
DELETE FROM t2 WHERE b BETWEEN 2 AND 7;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {20}
|
||||||
|
do_rbu_vacuum_test 1.4.2 $step
|
||||||
|
do_execsql_test 1.4.3 {
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {10}
|
||||||
|
|
||||||
|
# WITHOUT ROWID table with an index.
|
||||||
|
do_execsql_test 1.4.1 {
|
||||||
|
CREATE INDEX t2c ON t2(c);
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 9, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 10, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 11, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 12, randomblob(900));
|
||||||
|
INSERT INTO t2 VALUES(randomblob(900), 13, randomblob(900));
|
||||||
|
|
||||||
|
DELETE FROM t2 WHERE b BETWEEN 8 AND 12;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {35}
|
||||||
|
do_rbu_vacuum_test 1.4.2 $step
|
||||||
|
do_execsql_test 1.4.3 {
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {15}
|
||||||
|
do_execsql_test 1.4.4 {
|
||||||
|
VACUUM;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {15}
|
||||||
|
|
||||||
|
do_execsql_test 1.5.1 {
|
||||||
|
CREATE TABLE t3(a, b, c);
|
||||||
|
INSERT INTO t3 VALUES('a', 'b', 'c');
|
||||||
|
INSERT INTO t3 VALUES('d', 'e', 'f');
|
||||||
|
INSERT INTO t3 VALUES('g', 'h', 'i');
|
||||||
|
}
|
||||||
|
do_rbu_vacuum_test 1.5.2 $step
|
||||||
|
do_execsql_test 1.5.3 {
|
||||||
|
SELECT * FROM t3
|
||||||
|
} {a b c d e f g h i}
|
||||||
|
do_execsql_test 1.5.4 {
|
||||||
|
CREATE INDEX t3a ON t3(a);
|
||||||
|
CREATE INDEX t3b ON t3(b);
|
||||||
|
CREATE INDEX t3c ON t3(c);
|
||||||
|
INSERT INTO t3 VALUES('j', 'k', 'l');
|
||||||
|
DELETE FROM t3 WHERE a = 'g';
|
||||||
|
}
|
||||||
|
do_rbu_vacuum_test 1.5.5 $step
|
||||||
|
do_execsql_test 1.5.6 {
|
||||||
|
SELECT rowid, * FROM t3 ORDER BY b
|
||||||
|
} {1 a b c 2 d e f 4 j k l}
|
||||||
|
|
||||||
|
do_execsql_test 1.6.1 {
|
||||||
|
CREATE TABLE t4(a PRIMARY KEY, b, c);
|
||||||
|
INSERT INTO t4 VALUES('a', 'b', 'c');
|
||||||
|
INSERT INTO t4 VALUES('d', 'e', 'f');
|
||||||
|
INSERT INTO t4 VALUES('g', 'h', 'i');
|
||||||
|
}
|
||||||
|
do_rbu_vacuum_test 1.6.2 $step
|
||||||
|
do_execsql_test 1.6.3 {
|
||||||
|
SELECT * FROM t4
|
||||||
|
} {a b c d e f g h i}
|
||||||
|
do_execsql_test 1.6.4 {
|
||||||
|
CREATE INDEX t4a ON t4(a);
|
||||||
|
CREATE INDEX t4b ON t4(b);
|
||||||
|
CREATE INDEX t4c ON t4(c);
|
||||||
|
|
||||||
|
INSERT INTO t4 VALUES('j', 'k', 'l');
|
||||||
|
DELETE FROM t4 WHERE a='g';
|
||||||
|
}
|
||||||
|
do_rbu_vacuum_test 1.6.5 $step
|
||||||
|
do_execsql_test 1.6.6 {
|
||||||
|
SELECT * FROM t4 ORDER BY b
|
||||||
|
} {a b c d e f j k l}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 1.7.0 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'one');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'two');
|
||||||
|
DELETE FROM t1 WHERE a=2;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'three');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'four');
|
||||||
|
DELETE FROM t1 WHERE a=4;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'five');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'six');
|
||||||
|
DELETE FROM t1 WHERE a=6;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
} {1 one 3 three 5 five}
|
||||||
|
do_rbu_vacuum_test 1.7.1 $step
|
||||||
|
do_execsql_test 1.7.2 {
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'seven');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
} {1 one 3 three 5 five 7 seven}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 1.8.0 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||||
|
CREATE INDEX i1 ON t1(b);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'one');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'two');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'three');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'four');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'five');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'six');
|
||||||
|
ANALYZE;
|
||||||
|
SELECT * FROM sqlite_stat1;
|
||||||
|
} {t1 i1 {6 1}}
|
||||||
|
do_rbu_vacuum_test 1.8.1 $step
|
||||||
|
do_execsql_test 1.7.2 {
|
||||||
|
SELECT * FROM sqlite_stat1;
|
||||||
|
} {t1 i1 {6 1}}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 1.9.0 {
|
||||||
|
PRAGMA page_size = 8192;
|
||||||
|
PRAGMA auto_vacuum = 2;
|
||||||
|
PRAGMA user_version = 412;
|
||||||
|
PRAGMA application_id = 413;
|
||||||
|
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||||
|
CREATE INDEX i1 ON t1(b);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'one');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'two');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'three');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'four');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'five');
|
||||||
|
INSERT INTO t1 VALUES(NULL, 'six');
|
||||||
|
|
||||||
|
PRAGMA main.page_size;
|
||||||
|
PRAGMA main.auto_vacuum;
|
||||||
|
PRAGMA main.user_version;
|
||||||
|
PRAGMA main.application_id;
|
||||||
|
} {8192 2 412 413}
|
||||||
|
|
||||||
|
do_rbu_vacuum_test 1.9.1 $step
|
||||||
|
do_execsql_test 1.9.2 {
|
||||||
|
PRAGMA main.page_size;
|
||||||
|
PRAGMA main.auto_vacuum;
|
||||||
|
PRAGMA main.user_version;
|
||||||
|
PRAGMA main.application_id;
|
||||||
|
} {8192 2 412 413}
|
||||||
|
|
||||||
|
# Vacuum a database with a large sqlite_master table.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_test 1.10.1 {
|
||||||
|
for {set i 1} {$i < 50} {incr i} {
|
||||||
|
execsql "PRAGMA page_size = 1024"
|
||||||
|
execsql "CREATE TABLE t$i (a, b, c, PRIMARY KEY(a, b));"
|
||||||
|
execsql "
|
||||||
|
INSERT INTO t$i VALUES(1, 2, 3);
|
||||||
|
INSERT INTO t$i VALUES(4, 5, 6);
|
||||||
|
"
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
do_rbu_vacuum_test 1.10.2 $step
|
||||||
|
|
||||||
|
# Database with empty tables.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 1.11.1 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||||
|
INSERT INTO t4 VALUES(1, 2);
|
||||||
|
}
|
||||||
|
do_rbu_vacuum_test 1.11.2 $step
|
||||||
|
do_execsql_test 1.11.3 {
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
SELECT * FROM t4;
|
||||||
|
} {1 2}
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 1.12.1 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
}
|
||||||
|
do_rbu_vacuum_test 1.12.2 $step
|
||||||
|
do_execsql_test 1.12.3 {
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
SELECT * FROM t4;
|
||||||
|
} {1 2}
|
||||||
|
}
|
||||||
|
set ::testprefix rbuvacuum
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test some error cases:
|
||||||
|
#
|
||||||
|
# 2.1.* the db being vacuumed being in wal mode already.
|
||||||
|
# 2.2.* database modified mid vacuum.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 2.1.0 {
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
INSERT INTO t1 VALUES(3, 4);
|
||||||
|
INSERT INTO t1 VALUES(5, 6);
|
||||||
|
INSERT INTO t1 VALUES(7, 8);
|
||||||
|
PRAGMA journal_mode = wal;
|
||||||
|
INSERT INTO t1 VALUES(9, 10);
|
||||||
|
} wal
|
||||||
|
do_test 2.1.1 {
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
rbu step
|
||||||
|
} {SQLITE_ERROR}
|
||||||
|
do_test 2.1.2 {
|
||||||
|
list [catch { rbu close } msg] $msg
|
||||||
|
} {1 {SQLITE_ERROR - cannot vacuum wal mode database}}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 2.2.0 {
|
||||||
|
CREATE TABLE tx(a PRIMARY KEY, b BLOB);
|
||||||
|
INSERT INTO tx VALUES(1, randomblob(900));
|
||||||
|
INSERT INTO tx SELECT a+1, randomblob(900) FROM tx;
|
||||||
|
INSERT INTO tx SELECT a+2, randomblob(900) FROM tx;
|
||||||
|
INSERT INTO tx SELECT a+4, randomblob(900) FROM tx;
|
||||||
|
INSERT INTO tx SELECT a+8, randomblob(900) FROM tx;
|
||||||
|
}
|
||||||
|
db_save_and_close
|
||||||
|
for {set i 1} 1 {incr i} {
|
||||||
|
db_restore_and_reopen
|
||||||
|
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
for {set step 0} {$step<$i} {incr step} { rbu step }
|
||||||
|
rbu close
|
||||||
|
if {[file exists test.db-wal]} break
|
||||||
|
|
||||||
|
execsql { INSERT INTO tx VALUES(20, 20) }
|
||||||
|
|
||||||
|
do_test 2.2.$i.1 {
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
rbu step
|
||||||
|
} {SQLITE_BUSY}
|
||||||
|
do_test 2.2.$i.2 {
|
||||||
|
list [catch { rbu close } msg] $msg
|
||||||
|
} {1 {SQLITE_BUSY - database modified during rbu vacuum}}
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test that a database that uses custom collation sequences can be RBU
|
||||||
|
# vacuumed.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
forcedelete state.db
|
||||||
|
proc noop {args} {}
|
||||||
|
proc length_cmp {x y} {
|
||||||
|
set n1 [string length $x]
|
||||||
|
set n2 [string length $y]
|
||||||
|
return [expr $n1 - $n2]
|
||||||
|
}
|
||||||
|
sqlite3_create_collation_v2 db length length_cmp noop
|
||||||
|
|
||||||
|
do_execsql_test 3.0 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1 VALUES(1, 'i');
|
||||||
|
INSERT INTO t1 VALUES(2, 'iiii');
|
||||||
|
INSERT INTO t1 VALUES(3, 'ii');
|
||||||
|
INSERT INTO t1 VALUES(4, 'iii');
|
||||||
|
SELECT a FROM t1 ORDER BY b COLLATE length;
|
||||||
|
} {1 3 4 2}
|
||||||
|
do_execsql_test 3.1 {
|
||||||
|
CREATE INDEX i1 ON t1(b COLLATE length);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test 3.2 {
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
while {[rbu step]=="SQLITE_OK"} {}
|
||||||
|
list [catch { rbu close } msg] $msg
|
||||||
|
} {1 {SQLITE_ERROR - no such collation sequence: length}}
|
||||||
|
|
||||||
|
do_test 3.3 {
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
set db1 [rbu db 0]
|
||||||
|
sqlite3_create_collation_v2 $db1 length length_cmp noop
|
||||||
|
while {[rbu step]=="SQLITE_OK"} {}
|
||||||
|
list [catch { rbu close } msg] $msg
|
||||||
|
} {1 {SQLITE_ERROR - no such collation sequence: length}}
|
||||||
|
|
||||||
|
do_test 3.4 {
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
set db1 [rbu db 1]
|
||||||
|
sqlite3_create_collation_v2 $db1 length length_cmp noop
|
||||||
|
while {[rbu step]=="SQLITE_OK"} {}
|
||||||
|
list [catch { rbu close } msg] $msg
|
||||||
|
} {1 {SQLITE_ERROR - no such collation sequence: length}}
|
||||||
|
|
||||||
|
do_test 3.5 {
|
||||||
|
sqlite3rbu_vacuum rbu test.db state.db
|
||||||
|
set db1 [rbu db 0]
|
||||||
|
set db2 [rbu db 1]
|
||||||
|
|
||||||
|
sqlite3_create_collation_v2 $db1 length length_cmp noop
|
||||||
|
sqlite3_create_collation_v2 $db2 length length_cmp noop
|
||||||
|
|
||||||
|
while {[rbu step]=="SQLITE_OK"} {}
|
||||||
|
list [catch { rbu close } msg] $msg
|
||||||
|
} {0 SQLITE_DONE}
|
||||||
|
|
||||||
|
|
||||||
|
catch { db close }
|
||||||
|
finish_test
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@@ -314,6 +314,38 @@ sqlite3rbu *sqlite3rbu_open(
|
|||||||
const char *zState
|
const char *zState
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Open an RBU handle to perform an RBU vacuum on database file zTarget.
|
||||||
|
** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
|
||||||
|
** that it can be suspended and resumed like an RBU update.
|
||||||
|
**
|
||||||
|
** The second argument to this function, which may not be NULL, identifies
|
||||||
|
** a database in which to store the state of the RBU vacuum operation if
|
||||||
|
** it is suspended. The first time sqlite3rbu_vacuum() is called, to start
|
||||||
|
** an RBU vacuum operation, the state database should either not exist or
|
||||||
|
** be empty (contain no tables). If an RBU vacuum is suspended by calling
|
||||||
|
** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
|
||||||
|
** returned SQLITE_DONE, the vacuum state is stored in the state database.
|
||||||
|
** The vacuum can be resumed by calling this function to open a new RBU
|
||||||
|
** handle specifying the same target and state databases.
|
||||||
|
**
|
||||||
|
** This function does not delete the state database after an RBU vacuum
|
||||||
|
** is completed, even if it created it. However, if the call to
|
||||||
|
** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
|
||||||
|
** of the state tables within the state database are zeroed. This way,
|
||||||
|
** the next call to sqlite3rbu_vacuum() opens a handle that starts a
|
||||||
|
** new RBU vacuum operation.
|
||||||
|
**
|
||||||
|
** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
|
||||||
|
** describing the sqlite3rbu_create_vfs() API function below for
|
||||||
|
** a description of the complications associated with using RBU with
|
||||||
|
** zipvfs databases.
|
||||||
|
*/
|
||||||
|
sqlite3rbu *sqlite3rbu_vacuum(
|
||||||
|
const char *zTarget,
|
||||||
|
const char *zState
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Internally, each RBU connection uses a separate SQLite database
|
** Internally, each RBU connection uses a separate SQLite database
|
||||||
** connection to access the target and rbu update databases. This
|
** connection to access the target and rbu update databases. This
|
||||||
|
@@ -20,8 +20,9 @@
|
|||||||
#include <tcl.h>
|
#include <tcl.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/* From main.c (apparently...) */
|
/* From main.c */
|
||||||
extern const char *sqlite3ErrName(int);
|
extern const char *sqlite3ErrName(int);
|
||||||
|
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
|
||||||
|
|
||||||
void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
|
void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
|
||||||
Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx);
|
Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx);
|
||||||
@@ -66,7 +67,8 @@ static int test_sqlite3rbu_cmd(
|
|||||||
{"create_rbu_delta", 2, ""}, /* 2 */
|
{"create_rbu_delta", 2, ""}, /* 2 */
|
||||||
{"savestate", 2, ""}, /* 3 */
|
{"savestate", 2, ""}, /* 3 */
|
||||||
{"dbMain_eval", 3, "SQL"}, /* 4 */
|
{"dbMain_eval", 3, "SQL"}, /* 4 */
|
||||||
{"bp_progress", 2, ""}, /* 5 */
|
{"bp_progress", 2, ""}, /* 5 */
|
||||||
|
{"db", 3, "RBU"}, /* 6 */
|
||||||
{0,0,0}
|
{0,0,0}
|
||||||
};
|
};
|
||||||
int iCmd;
|
int iCmd;
|
||||||
@@ -149,6 +151,22 @@ static int test_sqlite3rbu_cmd(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 6: /* db */ {
|
||||||
|
int bArg;
|
||||||
|
if( Tcl_GetBooleanFromObj(interp, objv[2], &bArg) ){
|
||||||
|
ret = TCL_ERROR;
|
||||||
|
}else{
|
||||||
|
char zBuf[50];
|
||||||
|
sqlite3 *db = sqlite3rbu_db(pRbu, bArg);
|
||||||
|
if( sqlite3TestMakePointerStr(interp, zBuf, (void*)db) ){
|
||||||
|
ret = TCL_ERROR;
|
||||||
|
}else{
|
||||||
|
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: /* seems unlikely */
|
default: /* seems unlikely */
|
||||||
assert( !"cannot happen" );
|
assert( !"cannot happen" );
|
||||||
break;
|
break;
|
||||||
@@ -187,6 +205,34 @@ static int test_sqlite3rbu(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Tclcmd: sqlite3rbu_vacuum CMD <target-db> <state-db>
|
||||||
|
*/
|
||||||
|
static int test_sqlite3rbu_vacuum(
|
||||||
|
ClientData clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3rbu *pRbu = 0;
|
||||||
|
const char *zCmd;
|
||||||
|
const char *zTarget;
|
||||||
|
const char *zStateDb = 0;
|
||||||
|
|
||||||
|
if( objc!=4 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB STATE-DB");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
zCmd = Tcl_GetString(objv[1]);
|
||||||
|
zTarget = Tcl_GetString(objv[2]);
|
||||||
|
zStateDb = Tcl_GetString(objv[3]);
|
||||||
|
|
||||||
|
pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
|
||||||
|
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
|
||||||
|
Tcl_SetObjResult(interp, objv[1]);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
|
** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
|
||||||
*/
|
*/
|
||||||
@@ -274,6 +320,7 @@ int SqliteRbu_Init(Tcl_Interp *interp){
|
|||||||
Tcl_ObjCmdProc *xProc;
|
Tcl_ObjCmdProc *xProc;
|
||||||
} aObjCmd[] = {
|
} aObjCmd[] = {
|
||||||
{ "sqlite3rbu", test_sqlite3rbu },
|
{ "sqlite3rbu", test_sqlite3rbu },
|
||||||
|
{ "sqlite3rbu_vacuum", test_sqlite3rbu_vacuum },
|
||||||
{ "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs },
|
{ "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs },
|
||||||
{ "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs },
|
{ "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs },
|
||||||
{ "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test },
|
{ "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test },
|
||||||
|
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
|
|||||||
}
|
}
|
||||||
source [file join [file dirname [info script]] session_common.tcl]
|
source [file join [file dirname [info script]] session_common.tcl]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
ifcapable !session {finish_test; return}
|
||||||
|
|
||||||
set testprefix sessionfault
|
set testprefix sessionfault
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
|
|||||||
}
|
}
|
||||||
source [file join [file dirname [info script]] session_common.tcl]
|
source [file join [file dirname [info script]] session_common.tcl]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
ifcapable !session {finish_test; return}
|
||||||
set testprefix sessionfault2
|
set testprefix sessionfault2
|
||||||
|
|
||||||
do_execsql_test 1.0.0 {
|
do_execsql_test 1.0.0 {
|
||||||
|
@@ -592,14 +592,19 @@ static int sessionChangeEqual(
|
|||||||
int iCol; /* Used to iterate through table columns */
|
int iCol; /* Used to iterate through table columns */
|
||||||
|
|
||||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||||
int n1 = sessionSerialLen(a1);
|
if( pTab->abPK[iCol] ){
|
||||||
int n2 = sessionSerialLen(a2);
|
int n1 = sessionSerialLen(a1);
|
||||||
|
int n2 = sessionSerialLen(a2);
|
||||||
|
|
||||||
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
|
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
a1 += n1;
|
||||||
|
a2 += n2;
|
||||||
|
}else{
|
||||||
|
if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
|
||||||
|
if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
|
||||||
}
|
}
|
||||||
if( pTab->abPK[iCol] || bLeftPkOnly==0 ) a1 += n1;
|
|
||||||
if( pTab->abPK[iCol] || bRightPkOnly==0 ) a2 += n2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
126
manifest
126
manifest
@@ -1,6 +1,6 @@
|
|||||||
C Merge\sall\srecent\senhancements\sfrom\strunk.
|
C Merge\sthe\slatest\senhancements\sfrom\strunk.
|
||||||
D 2016-04-20T12:16:05.997
|
D 2016-04-29T16:01:18.190
|
||||||
F Makefile.in eba680121821b8a60940a81454316f47a341487a
|
F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
|
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
|
||||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||||
@@ -222,7 +222,7 @@ F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
|||||||
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||||
F ext/rbu/rbu.c ba3983dceffa0938532e79142f391737513de023
|
F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4
|
||||||
F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1
|
F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1
|
||||||
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
|
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
|
||||||
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
|
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
|
||||||
@@ -243,12 +243,14 @@ F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
|
|||||||
F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091
|
F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091
|
||||||
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
||||||
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||||
|
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
|
||||||
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||||
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
|
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
|
||||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||||
F ext/rbu/sqlite3rbu.c 9097f1d95666dbef72ca61d5b6a13a84660735ac
|
F ext/rbu/rbuvacuum.test 66e02cf299836770e718e95c36686be0b26dbda3
|
||||||
F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2
|
F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958
|
||||||
F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d
|
F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930
|
||||||
|
F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e
|
||||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||||
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
|
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
|
||||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||||
@@ -289,9 +291,9 @@ F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26
|
|||||||
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
||||||
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
|
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
|
||||||
F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596
|
F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596
|
||||||
F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40
|
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||||
F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88
|
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||||
F ext/session/sqlite3session.c beb300cd1b5c5054062c8e6e807b10475e363410
|
F ext/session/sqlite3session.c beb43b6b888801bb006320bc236baa95f4cc32ae
|
||||||
F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d
|
F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d
|
||||||
F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15
|
F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15
|
||||||
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
||||||
@@ -329,18 +331,18 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
|||||||
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
|
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
|
||||||
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
|
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
|
||||||
F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
|
F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
|
||||||
F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198
|
F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
|
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
|
||||||
F src/func.c 552d300265aed09eea21f68ac742a440550c0062
|
F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1
|
||||||
F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
|
F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
|
||||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36
|
||||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
|
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
|
||||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||||
F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002
|
F src/loadext.c 8b3a73f0624c5f7cadbd5cb89940783bee1d39a6
|
||||||
F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46
|
F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca
|
||||||
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
|
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||||
@@ -359,38 +361,38 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905
|
|||||||
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
||||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||||
F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f
|
F src/os_unix.c 8422fba2eb592fbbb2d4006b6f2a67cad8951495
|
||||||
F src/os_win.c b169437dff859e308b3726594094a2f8ca922941
|
F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e
|
||||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||||
F src/pager.c 476884ce8d8e845daf88f1b12b8ca446bac5fdc5
|
F src/pager.c 41559a2b4461a6cf4b24bedb47d4e303d02729b5
|
||||||
F src/pager.h 6656436178c295d0668520739118e71a46163b8e
|
F src/pager.h 6656436178c295d0668520739118e71a46163b8e
|
||||||
F src/parse.y 2e1d371f99535ff29d1cd85052aa11cc636e21c8
|
F src/parse.y 2e1d371f99535ff29d1cd85052aa11cc636e21c8
|
||||||
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
|
F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8
|
||||||
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9
|
||||||
F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05
|
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
|
||||||
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
|
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
|
||||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||||
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
||||||
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
|
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
|
||||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||||
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
|
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
|
||||||
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d
|
||||||
F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b
|
F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d
|
||||||
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
|
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
|
||||||
F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5
|
F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
|
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
|
||||||
F src/sqliteInt.h 0d9f22432cf553bab15e25cf168b57d93396922b
|
F src/sqliteInt.h e6ac0d8f8cbb062a57882858b1deed1a7924314b
|
||||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||||
F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060
|
F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060
|
||||||
F src/test1.c 457c601302b8a0f5960dffd17b6a2877603841dd
|
F src/test1.c ee8fd5c32acb93fb6fe885ca4801cfab85f5563f
|
||||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
F src/test3.c 0df6f8dbb4cbaa7106397c70a271fa6a43659042
|
||||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||||
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
|
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
|
||||||
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
|
F src/test6.c 2c014d4977efd6107ec9eef3dfdec56ac516f824
|
||||||
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
|
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
|
||||||
F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75
|
F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75
|
||||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||||
@@ -402,14 +404,14 @@ F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239
|
|||||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||||
F src/test_config.c 5165f79b3aea5305627ac36dd7b9b5f124572da1
|
F src/test_config.c 5165f79b3aea5305627ac36dd7b9b5f124572da1
|
||||||
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
||||||
F src/test_devsym.c 7e73009d5297b603c11c66d7c7d6723d4b5c73e1
|
F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58
|
||||||
F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b
|
F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b
|
||||||
F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254
|
F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254
|
||||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||||
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
|
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
|
||||||
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
|
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
|
||||||
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
||||||
F src/test_journal.c da540964c675fde39487da2bc664096af97190d8
|
F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a
|
||||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||||
F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950
|
F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950
|
||||||
F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9
|
F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9
|
||||||
@@ -425,7 +427,7 @@ F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
|||||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||||
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
|
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
|
||||||
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
||||||
F src/test_syscall.c 4889d374f5a5856b7951f7a67c6401f7b938c6f5
|
F src/test_syscall.c 268c072541162564a882c57f54a6fee12ef4a4d2
|
||||||
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
|
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
|
||||||
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
||||||
F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c
|
F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c
|
||||||
@@ -439,9 +441,9 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
|
|||||||
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
||||||
F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d
|
F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d
|
||||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||||
F src/util.c 187a0a2aaa3c5d2ccd2ab0143b2fd9e86d6bc816
|
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
|
||||||
F src/vacuum.c c1a94413f8fa9d9b2cbe3af9a89377f777be676c
|
F src/vacuum.c c1a94413f8fa9d9b2cbe3af9a89377f777be676c
|
||||||
F src/vdbe.c 226c51cced9aa6f66748f626413d3f0348f2fcb8
|
F src/vdbe.c 4f0378eb44406a6a61686dff7970fa314f0f44bd
|
||||||
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
|
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
|
||||||
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
|
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
|
||||||
F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
|
F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
|
||||||
@@ -510,7 +512,7 @@ F test/autovacuum.test 92c24eedbdb68e49f3fb71f26f9ce6d8988cac15
|
|||||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||||
F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d
|
F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d
|
||||||
F test/backup.test b79299a536a4c6d919094786595b95be56d02014
|
F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989
|
||||||
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
|
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
|
||||||
F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32
|
F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32
|
||||||
F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4
|
F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4
|
||||||
@@ -551,7 +553,7 @@ F test/capi3c.test 0b9edb0c2156a964b9271cd5ea7ae56736cc2fcb
|
|||||||
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||||
F test/cffault.test aadc1f61f8811cb600e3e069acbf8796f472a096
|
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||||
F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485
|
F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485
|
||||||
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
|
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
|
||||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||||
@@ -614,7 +616,7 @@ F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
|||||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||||
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
|
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
|
||||||
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
|
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
|
||||||
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
|
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||||
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
|
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
|
||||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||||
@@ -646,7 +648,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
|||||||
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||||
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
||||||
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
|
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
|
||||||
F test/e_vacuum.test 4d5b391384bb7d56bb9337d956f08035332421fc
|
F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3
|
||||||
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||||
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
||||||
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
||||||
@@ -661,7 +663,7 @@ F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
|
|||||||
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
|
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
|
||||||
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
||||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
|
||||||
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
||||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||||
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||||
@@ -810,7 +812,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
|||||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||||
F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
|
F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
|
||||||
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
|
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
|
||||||
F test/hook.test 40523db3aa76d62bda71c26f824fa0eabc420f0e
|
F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e
|
||||||
F test/icu.test 73956798bace8982909c00476b216714a6d0559a
|
F test/icu.test 73956798bace8982909c00476b216714a6d0559a
|
||||||
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
|
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
|
||||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||||
@@ -827,7 +829,7 @@ F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
|
|||||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||||
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
||||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||||
F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac
|
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
|
||||||
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||||
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
|
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
|
||||||
@@ -864,7 +866,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
|||||||
F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a
|
F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a
|
||||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||||
@@ -879,9 +881,9 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a
|
|||||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||||
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
|
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
|
||||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||||
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
|
F test/loadext.test 42a3b8166dfcadcb0e0c8710dc520d97c31a8b98
|
||||||
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
|
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
|
||||||
F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5
|
F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
|
||||||
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
||||||
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
|
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
|
||||||
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
|
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
|
||||||
@@ -970,7 +972,7 @@ F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d
|
|||||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||||
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
|
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
|
||||||
F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1
|
F test/pagerfault.test 42ff797b1e6426c141cc7ee8b7417c9f27427950
|
||||||
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
||||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||||
F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0
|
F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0
|
||||||
@@ -978,10 +980,10 @@ F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
|||||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||||
F test/permutations.test cd1fa041074ed08eeaa563e4d1bacb0c69337ec1
|
F test/permutations.test b6b3e165fdc1b8c82a820033646dbfc6a7a01746
|
||||||
F test/pragma.test dd5313eee9c6d9d4726593a68ede8768d3b50ccc
|
F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8
|
||||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||||
F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922
|
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||||
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
|
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
|
||||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||||
@@ -989,7 +991,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
|||||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||||
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
|
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
|
||||||
F test/quota.test 36cd78b178c4eb0401d4f25754ef410fbd9df2a7
|
F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a
|
||||||
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
|
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
|
||||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||||
@@ -1027,7 +1029,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
|||||||
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
||||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||||
F test/select4.test d926792a5e4d88fef0ddcddeb45d27ce75f7296c
|
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
|
||||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||||
F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61
|
F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61
|
||||||
@@ -1093,7 +1095,7 @@ F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
|||||||
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
|
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
|
||||||
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
||||||
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
|
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
|
||||||
F test/stat.test b65bad7120c52583b8f0054d99eff80718119a77
|
F test/stat.test 66e95f97b9f724f9ab921d054ee0db3c2689f1ee
|
||||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||||
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
|
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
|
||||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||||
@@ -1103,7 +1105,7 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
|||||||
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||||
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
||||||
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||||
F test/sync.test 2f607e1821aa3af3c5c53b58835c05e511c95899
|
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
|
||||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||||
F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906
|
F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906
|
||||||
@@ -1112,9 +1114,11 @@ F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
|||||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||||
F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa
|
F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa
|
||||||
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
||||||
|
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||||
|
F test/temptable2.test c3d8c138f493207612960bbd6a8c50e84975e2ee
|
||||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||||
F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553
|
F test/tester.tcl 30c7a9be8601d1c1c9c93d013545ebcb28d64254
|
||||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||||
@@ -1130,10 +1134,10 @@ F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
|||||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||||
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
|
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
|
||||||
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
|
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
|
||||||
F test/tkt-2d1a5c67d.test d371279946622698ab393ff88cad9f5f6d82960b
|
F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
|
||||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||||
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
|
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
|
||||||
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
|
F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
|
||||||
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
|
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
|
||||||
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
||||||
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||||
@@ -1144,7 +1148,7 @@ F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
|
|||||||
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
|
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
|
||||||
F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1
|
F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1
|
||||||
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
|
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
|
||||||
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
|
F test/tkt-5d863f876e.test 726e76d725f6fe0eb2fc8a522b721b79807380ee
|
||||||
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
|
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
|
||||||
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
|
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
|
||||||
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
|
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
|
||||||
@@ -1160,7 +1164,7 @@ F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
|
|||||||
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
|
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
|
||||||
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
|
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
|
||||||
F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
|
F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
|
||||||
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
|
F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
|
||||||
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
|
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
|
||||||
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
|
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
|
||||||
F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
|
F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
|
||||||
@@ -1399,7 +1403,7 @@ F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
|
|||||||
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
|
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
|
||||||
F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf
|
F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf
|
||||||
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
||||||
F test/zerodamage.test 2d725c214b883e25ae6bb85ef228ecdfa03c6a7b
|
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
|
||||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||||
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
|
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
|
||||||
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
||||||
@@ -1415,7 +1419,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa
|
|||||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||||
F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506
|
F tool/lemon.c 83318dff3911e47f2b85e136e56aa1c4674a2d2b
|
||||||
F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6
|
F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6
|
||||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||||
@@ -1485,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P d7381efff47c0a2f307478f196d03df7534f19e3 eba27d4d17a76884292667d570d542e580ee3e77
|
P 1f709fbf931e4d75848fc90532e2bc67ccd47cd4 9d0a5ae00273686ea35b43bc2ffaa8775c176363
|
||||||
R b2d94baa5aa70083709fce61087ef618
|
R 53ca713e0bf5b0eed86d88e36153628f
|
||||||
U drh
|
U drh
|
||||||
Z 09ace714760db63cbd8099bd8f9784df
|
Z e98bb20abec63c17e483c921950d1a1a
|
||||||
|
@@ -1 +1 @@
|
|||||||
1f709fbf931e4d75848fc90532e2bc67ccd47cd4
|
91e5c07eaf884d3598df8eb54f0910a80df48397
|
@@ -2360,7 +2360,7 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){
|
|||||||
}
|
}
|
||||||
p->iReg = 0;
|
p->iReg = 0;
|
||||||
pParse->nColCache--;
|
pParse->nColCache--;
|
||||||
assert( cacheIsValid(pParse) );
|
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2405,7 +2405,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
|||||||
p->tempReg = 0;
|
p->tempReg = 0;
|
||||||
p->lru = pParse->iCacheCnt++;
|
p->lru = pParse->iCacheCnt++;
|
||||||
pParse->nColCache++;
|
pParse->nColCache++;
|
||||||
assert( cacheIsValid(pParse) );
|
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1386,6 +1386,14 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
|
|||||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||||
char *zErrMsg = 0;
|
char *zErrMsg = 0;
|
||||||
|
|
||||||
|
/* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
|
||||||
|
** flag is set. See the sqlite3_enable_load_extension() API.
|
||||||
|
*/
|
||||||
|
if( (db->flags & SQLITE_LoadExtFunc)==0 ){
|
||||||
|
sqlite3_result_error(context, "not authorized", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( argc==2 ){
|
if( argc==2 ){
|
||||||
zProc = (const char *)sqlite3_value_text(argv[1]);
|
zProc = (const char *)sqlite3_value_text(argv[1]);
|
||||||
}else{
|
}else{
|
||||||
|
@@ -55,7 +55,7 @@ void sqlite3HashClear(Hash *pH){
|
|||||||
static unsigned int strHash(const char *z){
|
static unsigned int strHash(const char *z){
|
||||||
unsigned int h = 0;
|
unsigned int h = 0;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
while( (c = (unsigned char)*z++)!=0 ){
|
while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
|
h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@@ -148,7 +148,7 @@ static HashElem *findElementWithHash(
|
|||||||
int count; /* Number of elements left to test */
|
int count; /* Number of elements left to test */
|
||||||
unsigned int h; /* The computed hash */
|
unsigned int h; /* The computed hash */
|
||||||
|
|
||||||
if( pH->ht ){
|
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
struct _ht *pEntry;
|
struct _ht *pEntry;
|
||||||
h = strHash(pKey) % pH->htsize;
|
h = strHash(pKey) % pH->htsize;
|
||||||
pEntry = &pH->ht[h];
|
pEntry = &pH->ht[h];
|
||||||
|
@@ -464,8 +464,9 @@ static int sqlite3LoadExtension(
|
|||||||
/* Ticket #1863. To avoid a creating security problems for older
|
/* Ticket #1863. To avoid a creating security problems for older
|
||||||
** applications that relink against newer versions of SQLite, the
|
** applications that relink against newer versions of SQLite, the
|
||||||
** ability to run load_extension is turned off by default. One
|
** ability to run load_extension is turned off by default. One
|
||||||
** must call sqlite3_enable_load_extension() to turn on extension
|
** must call either sqlite3_enable_load_extension(db) or
|
||||||
** loading. Otherwise you get the following error.
|
** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
|
||||||
|
** to turn on extension loading.
|
||||||
*/
|
*/
|
||||||
if( (db->flags & SQLITE_LoadExtension)==0 ){
|
if( (db->flags & SQLITE_LoadExtension)==0 ){
|
||||||
if( pzErrMsg ){
|
if( pzErrMsg ){
|
||||||
@@ -604,9 +605,9 @@ void sqlite3CloseExtensions(sqlite3 *db){
|
|||||||
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
|
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
if( onoff ){
|
if( onoff ){
|
||||||
db->flags |= SQLITE_LoadExtension;
|
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
|
||||||
}else{
|
}else{
|
||||||
db->flags &= ~SQLITE_LoadExtension;
|
db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_leave(db->mutex);
|
sqlite3_mutex_leave(db->mutex);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
|
@@ -804,6 +804,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
|||||||
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
||||||
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
||||||
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
||||||
|
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
||||||
|
@@ -4288,10 +4288,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
|||||||
pShmNode->h = -1;
|
pShmNode->h = -1;
|
||||||
pDbFd->pInode->pShmNode = pShmNode;
|
pDbFd->pInode->pShmNode = pShmNode;
|
||||||
pShmNode->pInode = pDbFd->pInode;
|
pShmNode->pInode = pDbFd->pInode;
|
||||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||||
if( pShmNode->mutex==0 ){
|
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||||
rc = SQLITE_NOMEM_BKPT;
|
if( pShmNode->mutex==0 ){
|
||||||
goto shm_open_err;
|
rc = SQLITE_NOMEM_BKPT;
|
||||||
|
goto shm_open_err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pInode->bProcessLock==0 ){
|
if( pInode->bProcessLock==0 ){
|
||||||
@@ -5416,14 +5418,14 @@ static const char *unixTempFileDir(void){
|
|||||||
|
|
||||||
if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
|
if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
|
||||||
if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
|
if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
|
||||||
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
|
for(i=0; i<=sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
|
||||||
if( zDir==0 ) continue;
|
if( zDir==0 ) continue;
|
||||||
if( osStat(zDir, &buf) ) continue;
|
if( osStat(zDir, &buf) ) continue;
|
||||||
if( !S_ISDIR(buf.st_mode) ) continue;
|
if( !S_ISDIR(buf.st_mode) ) continue;
|
||||||
if( osAccess(zDir, 07) ) continue;
|
if( osAccess(zDir, 03) ) continue;
|
||||||
break;
|
return zDir;
|
||||||
}
|
}
|
||||||
return zDir;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5439,9 +5441,11 @@ static int unixGetTempname(int nBuf, char *zBuf){
|
|||||||
** using the io-error infrastructure to test that SQLite handles this
|
** using the io-error infrastructure to test that SQLite handles this
|
||||||
** function failing.
|
** function failing.
|
||||||
*/
|
*/
|
||||||
|
zBuf[0] = 0;
|
||||||
SimulateIOError( return SQLITE_IOERR );
|
SimulateIOError( return SQLITE_IOERR );
|
||||||
|
|
||||||
zDir = unixTempFileDir();
|
zDir = unixTempFileDir();
|
||||||
|
if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
|
||||||
do{
|
do{
|
||||||
u64 r;
|
u64 r;
|
||||||
sqlite3_randomness(sizeof(r), &r);
|
sqlite3_randomness(sizeof(r), &r);
|
||||||
|
19
src/os_win.c
19
src/os_win.c
@@ -1260,8 +1260,8 @@ int sqlite3_win32_reset_heap(){
|
|||||||
int rc;
|
int rc;
|
||||||
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
|
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
|
||||||
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
|
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
|
||||||
MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
|
MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
|
||||||
MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
|
MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
|
||||||
sqlite3_mutex_enter(pMaster);
|
sqlite3_mutex_enter(pMaster);
|
||||||
sqlite3_mutex_enter(pMem);
|
sqlite3_mutex_enter(pMem);
|
||||||
winMemAssertMagic();
|
winMemAssertMagic();
|
||||||
@@ -3169,9 +3169,8 @@ static int winLock(sqlite3_file *id, int locktype){
|
|||||||
** the PENDING_LOCK byte is temporary.
|
** the PENDING_LOCK byte is temporary.
|
||||||
*/
|
*/
|
||||||
newLocktype = pFile->locktype;
|
newLocktype = pFile->locktype;
|
||||||
if( (pFile->locktype==NO_LOCK)
|
if( pFile->locktype==NO_LOCK
|
||||||
|| ( (locktype==EXCLUSIVE_LOCK)
|
|| (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
|
||||||
&& (pFile->locktype==RESERVED_LOCK))
|
|
||||||
){
|
){
|
||||||
int cnt = 3;
|
int cnt = 3;
|
||||||
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
|
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
|
||||||
@@ -3765,10 +3764,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
|||||||
pShmNode->pNext = winShmNodeList;
|
pShmNode->pNext = winShmNodeList;
|
||||||
winShmNodeList = pShmNode;
|
winShmNodeList = pShmNode;
|
||||||
|
|
||||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||||
if( pShmNode->mutex==0 ){
|
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||||
rc = SQLITE_IOERR_NOMEM_BKPT;
|
if( pShmNode->mutex==0 ){
|
||||||
goto shm_open_err;
|
rc = SQLITE_IOERR_NOMEM_BKPT;
|
||||||
|
goto shm_open_err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = winOpen(pDbFd->pVfs,
|
rc = winOpen(pDbFd->pVfs,
|
||||||
|
133
src/pager.c
133
src/pager.c
@@ -875,6 +875,7 @@ static int assert_pager_state(Pager *p){
|
|||||||
** state.
|
** state.
|
||||||
*/
|
*/
|
||||||
if( MEMDB ){
|
if( MEMDB ){
|
||||||
|
assert( !isOpen(p->fd) );
|
||||||
assert( p->noSync );
|
assert( p->noSync );
|
||||||
assert( p->journalMode==PAGER_JOURNALMODE_OFF
|
assert( p->journalMode==PAGER_JOURNALMODE_OFF
|
||||||
|| p->journalMode==PAGER_JOURNALMODE_MEMORY
|
|| p->journalMode==PAGER_JOURNALMODE_MEMORY
|
||||||
@@ -963,7 +964,7 @@ static int assert_pager_state(Pager *p){
|
|||||||
** back to OPEN state.
|
** back to OPEN state.
|
||||||
*/
|
*/
|
||||||
assert( pPager->errCode!=SQLITE_OK );
|
assert( pPager->errCode!=SQLITE_OK );
|
||||||
assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
|
assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1175,6 +1176,8 @@ static int jrnlBufferSize(Pager *pPager){
|
|||||||
|
|
||||||
return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
|
return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
# define jrnlBufferSize(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1868,13 +1871,17 @@ static void pager_unlock(Pager *pPager){
|
|||||||
** it can safely move back to PAGER_OPEN state. This happens in both
|
** it can safely move back to PAGER_OPEN state. This happens in both
|
||||||
** normal and exclusive-locking mode.
|
** normal and exclusive-locking mode.
|
||||||
*/
|
*/
|
||||||
|
assert( pPager->errCode==SQLITE_OK || !MEMDB );
|
||||||
if( pPager->errCode ){
|
if( pPager->errCode ){
|
||||||
assert( !MEMDB );
|
if( pPager->tempFile==0 ){
|
||||||
pager_reset(pPager);
|
pager_reset(pPager);
|
||||||
pPager->changeCountDone = pPager->tempFile;
|
pPager->changeCountDone = 0;
|
||||||
pPager->eState = PAGER_OPEN;
|
pPager->eState = PAGER_OPEN;
|
||||||
pPager->errCode = SQLITE_OK;
|
}else{
|
||||||
|
pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER);
|
||||||
|
}
|
||||||
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||||
|
pPager->errCode = SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPager->journalOff = 0;
|
pPager->journalOff = 0;
|
||||||
@@ -1918,6 +1925,25 @@ static int pager_error(Pager *pPager, int rc){
|
|||||||
|
|
||||||
static int pager_truncate(Pager *pPager, Pgno nPage);
|
static int pager_truncate(Pager *pPager, Pgno nPage);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The write transaction open on the pager passed as the only argument is
|
||||||
|
** being committed. This function returns true if all dirty pages should
|
||||||
|
** be flushed to disk, or false otherwise. Pages should be flushed to disk
|
||||||
|
** unless one of the following is true:
|
||||||
|
**
|
||||||
|
** * The db is an in-memory database.
|
||||||
|
**
|
||||||
|
** * The db is a temporary database and the db file has not been opened.
|
||||||
|
**
|
||||||
|
** * The db is a temporary database and the cache contains less than
|
||||||
|
** C/4 dirty pages, where C is the configured cache-size.
|
||||||
|
*/
|
||||||
|
static int pagerFlushOnCommit(Pager *pPager){
|
||||||
|
if( pPager->tempFile==0 ) return 1;
|
||||||
|
if( !isOpen(pPager->fd) ) return 0;
|
||||||
|
return (sqlite3PCachePercentDirty(pPager->pPCache)>=25);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine ends a transaction. A transaction is usually ended by
|
** This routine ends a transaction. A transaction is usually ended by
|
||||||
** either a COMMIT or a ROLLBACK operation. This routine may be called
|
** either a COMMIT or a ROLLBACK operation. This routine may be called
|
||||||
@@ -2055,7 +2081,11 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
|
|||||||
|
|
||||||
pagerFreeBitvecs(pPager);
|
pagerFreeBitvecs(pPager);
|
||||||
pPager->nRec = 0;
|
pPager->nRec = 0;
|
||||||
sqlite3PcacheCleanAll(pPager->pPCache);
|
if( MEMDB || pagerFlushOnCommit(pPager) ){
|
||||||
|
sqlite3PcacheCleanAll(pPager->pPCache);
|
||||||
|
}else{
|
||||||
|
sqlite3PcacheClearWritable(pPager->pPCache);
|
||||||
|
}
|
||||||
sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
|
sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
|
||||||
|
|
||||||
if( pagerUseWal(pPager) ){
|
if( pagerUseWal(pPager) ){
|
||||||
@@ -2340,7 +2370,7 @@ static int pager_playback_one_page(
|
|||||||
pPg = sqlite3PagerLookup(pPager, pgno);
|
pPg = sqlite3PagerLookup(pPager, pgno);
|
||||||
}
|
}
|
||||||
assert( pPg || !MEMDB );
|
assert( pPg || !MEMDB );
|
||||||
assert( pPager->eState!=PAGER_OPEN || pPg==0 );
|
assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile );
|
||||||
PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
|
PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
|
||||||
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
|
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
|
||||||
(isMainJrnl?"main-journal":"sub-journal")
|
(isMainJrnl?"main-journal":"sub-journal")
|
||||||
@@ -2423,9 +2453,13 @@ static int pager_playback_one_page(
|
|||||||
** be written out into the database file before its journal file
|
** be written out into the database file before its journal file
|
||||||
** segment is synced. If a crash occurs during or following this,
|
** segment is synced. If a crash occurs during or following this,
|
||||||
** database corruption may ensue.
|
** database corruption may ensue.
|
||||||
|
**
|
||||||
|
** Update: Another exception is for temp files that are not
|
||||||
|
** in-memory databases. In this case the page may have been dirty
|
||||||
|
** at the start of the transaction.
|
||||||
*/
|
*/
|
||||||
assert( !pagerUseWal(pPager) );
|
assert( !pagerUseWal(pPager) );
|
||||||
sqlite3PcacheMakeClean(pPg);
|
if( pPager->tempFile==0 ) sqlite3PcacheMakeClean(pPg);
|
||||||
}
|
}
|
||||||
pager_set_pagehash(pPg);
|
pager_set_pagehash(pPg);
|
||||||
|
|
||||||
@@ -3227,6 +3261,8 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
|||||||
*/
|
*/
|
||||||
assert( pPager->eState==PAGER_OPEN );
|
assert( pPager->eState==PAGER_OPEN );
|
||||||
assert( pPager->eLock>=SHARED_LOCK );
|
assert( pPager->eLock>=SHARED_LOCK );
|
||||||
|
assert( isOpen(pPager->fd) );
|
||||||
|
assert( pPager->tempFile==0 );
|
||||||
nPage = sqlite3WalDbsize(pPager->pWal);
|
nPage = sqlite3WalDbsize(pPager->pWal);
|
||||||
|
|
||||||
/* If the number of pages in the database is not available from the
|
/* If the number of pages in the database is not available from the
|
||||||
@@ -3234,14 +3270,11 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
|||||||
** the database file. If the size of the database file is not an
|
** the database file. If the size of the database file is not an
|
||||||
** integer multiple of the page-size, round up the result.
|
** integer multiple of the page-size, round up the result.
|
||||||
*/
|
*/
|
||||||
if( nPage==0 ){
|
if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){
|
||||||
i64 n = 0; /* Size of db file in bytes */
|
i64 n = 0; /* Size of db file in bytes */
|
||||||
assert( isOpen(pPager->fd) || pPager->tempFile );
|
int rc = sqlite3OsFileSize(pPager->fd, &n);
|
||||||
if( isOpen(pPager->fd) ){
|
if( rc!=SQLITE_OK ){
|
||||||
int rc = sqlite3OsFileSize(pPager->fd, &n);
|
return rc;
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
|
nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
|
||||||
}
|
}
|
||||||
@@ -4317,8 +4350,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
|
|||||||
|
|
||||||
/* This function is only called for rollback pagers in WRITER_DBMOD state. */
|
/* This function is only called for rollback pagers in WRITER_DBMOD state. */
|
||||||
assert( !pagerUseWal(pPager) );
|
assert( !pagerUseWal(pPager) );
|
||||||
assert( pPager->eState==PAGER_WRITER_DBMOD );
|
assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
|
||||||
assert( pPager->eLock==EXCLUSIVE_LOCK );
|
assert( pPager->eLock==EXCLUSIVE_LOCK );
|
||||||
|
assert( isOpen(pPager->fd) || pList->pDirty==0 );
|
||||||
|
|
||||||
/* If the file is a temp-file has not yet been opened, open it now. It
|
/* If the file is a temp-file has not yet been opened, open it now. It
|
||||||
** is not possible for rc to be other than SQLITE_OK if this branch
|
** is not possible for rc to be other than SQLITE_OK if this branch
|
||||||
@@ -4992,6 +5026,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
|
|||||||
if( rc==SQLITE_OK && !locked ){
|
if( rc==SQLITE_OK && !locked ){
|
||||||
Pgno nPage; /* Number of pages in database file */
|
Pgno nPage; /* Number of pages in database file */
|
||||||
|
|
||||||
|
assert( pPager->tempFile==0 );
|
||||||
rc = pagerPagecount(pPager, &nPage);
|
rc = pagerPagecount(pPager, &nPage);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
/* If the database is zero pages in size, that means that either (1) the
|
/* If the database is zero pages in size, that means that either (1) the
|
||||||
@@ -5084,17 +5119,17 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
|||||||
/* This routine is only called from b-tree and only when there are no
|
/* This routine is only called from b-tree and only when there are no
|
||||||
** outstanding pages. This implies that the pager state should either
|
** outstanding pages. This implies that the pager state should either
|
||||||
** be OPEN or READER. READER is only possible if the pager is or was in
|
** be OPEN or READER. READER is only possible if the pager is or was in
|
||||||
** exclusive access mode.
|
** exclusive access mode. */
|
||||||
*/
|
|
||||||
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
|
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
|
||||||
assert( assert_pager_state(pPager) );
|
assert( assert_pager_state(pPager) );
|
||||||
assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
|
assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
|
||||||
if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
|
assert( pPager->errCode==SQLITE_OK );
|
||||||
|
|
||||||
if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
|
if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
|
||||||
int bHotJournal = 1; /* True if there exists a hot journal-file */
|
int bHotJournal = 1; /* True if there exists a hot journal-file */
|
||||||
|
|
||||||
assert( !MEMDB );
|
assert( !MEMDB );
|
||||||
|
assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK );
|
||||||
|
|
||||||
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -5180,7 +5215,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
|||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
rc = pagerSyncHotJournal(pPager);
|
rc = pagerSyncHotJournal(pPager);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = pager_playback(pPager, 1);
|
rc = pager_playback(pPager, !pPager->tempFile);
|
||||||
pPager->eState = PAGER_OPEN;
|
pPager->eState = PAGER_OPEN;
|
||||||
}
|
}
|
||||||
}else if( !pPager->exclusiveMode ){
|
}else if( !pPager->exclusiveMode ){
|
||||||
@@ -5276,7 +5311,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
|||||||
rc = pagerBeginReadTransaction(pPager);
|
rc = pagerBeginReadTransaction(pPager);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
|
if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
|
||||||
rc = pagerPagecount(pPager, &pPager->dbSize);
|
rc = pagerPagecount(pPager, &pPager->dbSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5419,7 +5454,7 @@ int sqlite3PagerGet(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if( rc==SQLITE_OK && pData ){
|
if( rc==SQLITE_OK && pData ){
|
||||||
if( pPager->eState>PAGER_READER ){
|
if( pPager->eState>PAGER_READER || pPager->tempFile ){
|
||||||
pPg = sqlite3PagerLookup(pPager, pgno);
|
pPg = sqlite3PagerLookup(pPager, pgno);
|
||||||
}
|
}
|
||||||
if( pPg==0 ){
|
if( pPg==0 ){
|
||||||
@@ -5486,7 +5521,8 @@ int sqlite3PagerGet(
|
|||||||
goto pager_acquire_err;
|
goto pager_acquire_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
|
assert( !isOpen(pPager->fd) || !MEMDB );
|
||||||
|
if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
|
||||||
if( pgno>pPager->mxPgno ){
|
if( pgno>pPager->mxPgno ){
|
||||||
rc = SQLITE_FULL;
|
rc = SQLITE_FULL;
|
||||||
goto pager_acquire_err;
|
goto pager_acquire_err;
|
||||||
@@ -5628,24 +5664,24 @@ static int pager_open_journal(Pager *pPager){
|
|||||||
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
|
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
|
||||||
sqlite3MemJournalOpen(pPager->jfd);
|
sqlite3MemJournalOpen(pPager->jfd);
|
||||||
}else{
|
}else{
|
||||||
const int flags = /* VFS flags to open journal file */
|
int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||||
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
|
int nSpill;
|
||||||
(pPager->tempFile ?
|
|
||||||
(SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
|
if( pPager->tempFile ){
|
||||||
(SQLITE_OPEN_MAIN_JOURNAL)
|
flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
|
||||||
);
|
nSpill = sqlite3Config.nStmtSpill;
|
||||||
|
}else{
|
||||||
|
flags |= SQLITE_OPEN_MAIN_JOURNAL;
|
||||||
|
nSpill = jrnlBufferSize(pPager);
|
||||||
|
}
|
||||||
|
|
||||||
/* Verify that the database still has the same name as it did when
|
/* Verify that the database still has the same name as it did when
|
||||||
** it was originally opened. */
|
** it was originally opened. */
|
||||||
rc = databaseIsUnmoved(pPager);
|
rc = databaseIsUnmoved(pPager);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
rc = sqlite3JournalOpen (
|
||||||
rc = sqlite3JournalOpen(
|
pVfs, pPager->zJournal, pPager->jfd, flags, nSpill
|
||||||
pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
|
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
|
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
|
||||||
@@ -6019,6 +6055,7 @@ int sqlite3PagerWrite(PgHdr *pPg){
|
|||||||
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
|
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
|
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
|
||||||
|
assert( pPager->tempFile==0 );
|
||||||
return pagerWriteLargeSector(pPg);
|
return pagerWriteLargeSector(pPg);
|
||||||
}else{
|
}else{
|
||||||
return pager_write(pPg);
|
return pager_write(pPg);
|
||||||
@@ -6325,17 +6362,21 @@ int sqlite3PagerCommitPhaseOne(
|
|||||||
/* If a prior error occurred, report that error again. */
|
/* If a prior error occurred, report that error again. */
|
||||||
if( NEVER(pPager->errCode) ) return pPager->errCode;
|
if( NEVER(pPager->errCode) ) return pPager->errCode;
|
||||||
|
|
||||||
|
/* Provide the ability to easily simulate an I/O error during testing */
|
||||||
|
if( (rc = sqlite3FaultSim(400))!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n",
|
PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n",
|
||||||
pPager->zFilename, zMaster, pPager->dbSize));
|
pPager->zFilename, zMaster, pPager->dbSize));
|
||||||
|
|
||||||
/* If no database changes have been made, return early. */
|
/* If no database changes have been made, return early. */
|
||||||
if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
|
if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
|
||||||
|
|
||||||
if( MEMDB ){
|
assert( MEMDB==0 || pPager->tempFile );
|
||||||
|
assert( isOpen(pPager->fd) || pPager->tempFile );
|
||||||
|
if( 0==pagerFlushOnCommit(pPager) ){
|
||||||
/* If this is an in-memory db, or no pages have been written to, or this
|
/* If this is an in-memory db, or no pages have been written to, or this
|
||||||
** function has already been called, it is mostly a no-op. However, any
|
** function has already been called, it is mostly a no-op. However, any
|
||||||
** backup in progress needs to be restarted.
|
** backup in progress needs to be restarted. */
|
||||||
*/
|
|
||||||
sqlite3BackupRestart(pPager->pBackup);
|
sqlite3BackupRestart(pPager->pBackup);
|
||||||
}else{
|
}else{
|
||||||
if( pagerUseWal(pPager) ){
|
if( pagerUseWal(pPager) ){
|
||||||
@@ -6674,10 +6715,10 @@ void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return true if this is an in-memory pager.
|
** Return true if this is an in-memory or temp-file backed pager.
|
||||||
*/
|
*/
|
||||||
int sqlite3PagerIsMemdb(Pager *pPager){
|
int sqlite3PagerIsMemdb(Pager *pPager){
|
||||||
return MEMDB;
|
return pPager->tempFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6957,7 +6998,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
|||||||
/* In order to be able to rollback, an in-memory database must journal
|
/* In order to be able to rollback, an in-memory database must journal
|
||||||
** the page we are moving from.
|
** the page we are moving from.
|
||||||
*/
|
*/
|
||||||
if( MEMDB ){
|
if( pPager->tempFile ){
|
||||||
rc = sqlite3PagerWrite(pPg);
|
rc = sqlite3PagerWrite(pPg);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
}
|
}
|
||||||
@@ -7014,7 +7055,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
|||||||
assert( !pPgOld || pPgOld->nRef==1 );
|
assert( !pPgOld || pPgOld->nRef==1 );
|
||||||
if( pPgOld ){
|
if( pPgOld ){
|
||||||
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
|
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
|
||||||
if( MEMDB ){
|
if( pPager->tempFile ){
|
||||||
/* Do not discard pages from an in-memory database since we might
|
/* Do not discard pages from an in-memory database since we might
|
||||||
** need to rollback later. Just move the page out of the way. */
|
** need to rollback later. Just move the page out of the way. */
|
||||||
sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
|
sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
|
||||||
@@ -7031,7 +7072,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
|||||||
** to exist, in case the transaction needs to roll back. Use pPgOld
|
** to exist, in case the transaction needs to roll back. Use pPgOld
|
||||||
** as the original page since it has already been allocated.
|
** as the original page since it has already been allocated.
|
||||||
*/
|
*/
|
||||||
if( MEMDB ){
|
if( pPager->tempFile ){
|
||||||
assert( pPgOld );
|
assert( pPgOld );
|
||||||
sqlite3PcacheMove(pPgOld, origPgno);
|
sqlite3PcacheMove(pPgOld, origPgno);
|
||||||
sqlite3PagerUnrefNotNull(pPgOld);
|
sqlite3PagerUnrefNotNull(pPgOld);
|
||||||
@@ -7284,7 +7325,8 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
|
|||||||
** Unless this is an in-memory or temporary database, clear the pager cache.
|
** Unless this is an in-memory or temporary database, clear the pager cache.
|
||||||
*/
|
*/
|
||||||
void sqlite3PagerClearCache(Pager *pPager){
|
void sqlite3PagerClearCache(Pager *pPager){
|
||||||
if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
|
assert( MEMDB==0 || pPager->tempFile );
|
||||||
|
if( pPager->tempFile==0 ) pager_reset(pPager);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -7463,6 +7505,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
|||||||
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
||||||
pPager->pWal = 0;
|
pPager->pWal = 0;
|
||||||
pagerFixMaplimit(pPager);
|
pagerFixMaplimit(pPager);
|
||||||
|
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
26
src/pcache.c
26
src/pcache.c
@@ -254,7 +254,7 @@ sqlite3_pcache_page *sqlite3PcacheFetch(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** If the sqlite3PcacheFetch() routine is unable to allocate a new
|
** If the sqlite3PcacheFetch() routine is unable to allocate a new
|
||||||
** page because new clean pages are available for reuse and the cache
|
** page because no clean pages are available for reuse and the cache
|
||||||
** size limit has been reached, then this routine can be invoked to
|
** size limit has been reached, then this routine can be invoked to
|
||||||
** try harder to allocate a page. This routine might invoke the stress
|
** try harder to allocate a page. This routine might invoke the stress
|
||||||
** callback to spill dirty pages to the journal. It will then try to
|
** callback to spill dirty pages to the journal. It will then try to
|
||||||
@@ -439,6 +439,17 @@ void sqlite3PcacheCleanAll(PCache *pCache){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
|
||||||
|
*/
|
||||||
|
void sqlite3PcacheClearWritable(PCache *pCache){
|
||||||
|
PgHdr *p;
|
||||||
|
for(p=pCache->pDirty; p; p=p->pDirtyNext){
|
||||||
|
p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
|
||||||
|
}
|
||||||
|
pCache->pSynced = pCache->pDirtyTail;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
|
** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
|
||||||
*/
|
*/
|
||||||
@@ -484,7 +495,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
|
|||||||
** it must be that pgno==0.
|
** it must be that pgno==0.
|
||||||
*/
|
*/
|
||||||
assert( p->pgno>0 );
|
assert( p->pgno>0 );
|
||||||
if( ALWAYS(p->pgno>pgno) ){
|
if( p->pgno>pgno ){
|
||||||
assert( p->flags&PGHDR_DIRTY );
|
assert( p->flags&PGHDR_DIRTY );
|
||||||
sqlite3PcacheMakeClean(p);
|
sqlite3PcacheMakeClean(p);
|
||||||
}
|
}
|
||||||
@@ -675,6 +686,17 @@ void sqlite3PcacheShrink(PCache *pCache){
|
|||||||
*/
|
*/
|
||||||
int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
|
int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the number of dirty pages currently in the cache, as a percentage
|
||||||
|
** of the configured cache size.
|
||||||
|
*/
|
||||||
|
int sqlite3PCachePercentDirty(PCache *pCache){
|
||||||
|
PgHdr *pDirty;
|
||||||
|
int nDirty = 0;
|
||||||
|
int nCache = numberOfCachePages(pCache);
|
||||||
|
for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
|
||||||
|
return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
|
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
|
||||||
/*
|
/*
|
||||||
|
@@ -99,6 +99,7 @@ void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */
|
|||||||
void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */
|
void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */
|
||||||
void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */
|
void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */
|
||||||
void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */
|
void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */
|
||||||
|
void sqlite3PcacheClearWritable(PCache*);
|
||||||
|
|
||||||
/* Change a page number. Used by incr-vacuum. */
|
/* Change a page number. Used by incr-vacuum. */
|
||||||
void sqlite3PcacheMove(PgHdr*, Pgno);
|
void sqlite3PcacheMove(PgHdr*, Pgno);
|
||||||
@@ -173,4 +174,7 @@ void sqlite3PCacheSetDefault(void);
|
|||||||
int sqlite3HeaderSizePcache(void);
|
int sqlite3HeaderSizePcache(void);
|
||||||
int sqlite3HeaderSizePcache1(void);
|
int sqlite3HeaderSizePcache1(void);
|
||||||
|
|
||||||
|
/* Number of dirty pages as a percentage of the configured cache size */
|
||||||
|
int sqlite3PCachePercentDirty(PCache*);
|
||||||
|
|
||||||
#endif /* _PCACHE_H_ */
|
#endif /* _PCACHE_H_ */
|
||||||
|
@@ -690,8 +690,8 @@ static int pcache1Init(void *NotUsed){
|
|||||||
|
|
||||||
#if SQLITE_THREADSAFE
|
#if SQLITE_THREADSAFE
|
||||||
if( sqlite3GlobalConfig.bCoreMutex ){
|
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||||
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
|
pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
|
||||||
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
|
pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if( pcache1.separateCache
|
if( pcache1.separateCache
|
||||||
|
99
src/rowset.c
99
src/rowset.c
@@ -57,8 +57,9 @@
|
|||||||
** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
|
** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
|
||||||
** primitives are constant time. The cost of DESTROY is O(N).
|
** primitives are constant time. The cost of DESTROY is O(N).
|
||||||
**
|
**
|
||||||
** There is an added cost of O(N) when switching between TEST and
|
** TEST and SMALLEST may not be used by the same RowSet. This used to
|
||||||
** SMALLEST primitives.
|
** be possible, but the feature was not used, so it was removed in order
|
||||||
|
** to simplify the code.
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -179,7 +180,9 @@ void sqlite3RowSetClear(RowSet *p){
|
|||||||
*/
|
*/
|
||||||
static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
|
static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
|
||||||
assert( p!=0 );
|
assert( p!=0 );
|
||||||
if( p->nFresh==0 ){
|
if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
/* We could allocate a fresh RowSetEntry each time one is needed, but it
|
||||||
|
** is more efficient to pull a preallocated entry from the pool */
|
||||||
struct RowSetChunk *pNew;
|
struct RowSetChunk *pNew;
|
||||||
pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew));
|
pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew));
|
||||||
if( pNew==0 ){
|
if( pNew==0 ){
|
||||||
@@ -213,7 +216,9 @@ void sqlite3RowSetInsert(RowSet *p, i64 rowid){
|
|||||||
pEntry->pRight = 0;
|
pEntry->pRight = 0;
|
||||||
pLast = p->pLast;
|
pLast = p->pLast;
|
||||||
if( pLast ){
|
if( pLast ){
|
||||||
if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
|
if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
/* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags
|
||||||
|
** where possible */
|
||||||
p->rsFlags &= ~ROWSET_SORTED;
|
p->rsFlags &= ~ROWSET_SORTED;
|
||||||
}
|
}
|
||||||
pLast->pRight = pEntry;
|
pLast->pRight = pEntry;
|
||||||
@@ -335,23 +340,29 @@ static struct RowSetEntry *rowSetNDeepTree(
|
|||||||
){
|
){
|
||||||
struct RowSetEntry *p; /* Root of the new tree */
|
struct RowSetEntry *p; /* Root of the new tree */
|
||||||
struct RowSetEntry *pLeft; /* Left subtree */
|
struct RowSetEntry *pLeft; /* Left subtree */
|
||||||
if( *ppList==0 ){
|
if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
|
/* Prevent unnecessary deep recursion when we run out of entries */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( iDepth==1 ){
|
if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
|
/* This branch causes a *balanced* tree to be generated. A valid tree
|
||||||
|
** is still generated without this branch, but the tree is wildly
|
||||||
|
** unbalanced and inefficient. */
|
||||||
|
pLeft = rowSetNDeepTree(ppList, iDepth-1);
|
||||||
|
p = *ppList;
|
||||||
|
if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
/* It is safe to always return here, but the resulting tree
|
||||||
|
** would be unbalanced */
|
||||||
|
return pLeft;
|
||||||
|
}
|
||||||
|
p->pLeft = pLeft;
|
||||||
|
*ppList = p->pRight;
|
||||||
|
p->pRight = rowSetNDeepTree(ppList, iDepth-1);
|
||||||
|
}else{
|
||||||
p = *ppList;
|
p = *ppList;
|
||||||
*ppList = p->pRight;
|
*ppList = p->pRight;
|
||||||
p->pLeft = p->pRight = 0;
|
p->pLeft = p->pRight = 0;
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
pLeft = rowSetNDeepTree(ppList, iDepth-1);
|
|
||||||
p = *ppList;
|
|
||||||
if( p==0 ){
|
|
||||||
return pLeft;
|
|
||||||
}
|
|
||||||
p->pLeft = pLeft;
|
|
||||||
*ppList = p->pRight;
|
|
||||||
p->pRight = rowSetNDeepTree(ppList, iDepth-1);
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,40 +389,6 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Take all the entries on p->pEntry and on the trees in p->pForest and
|
|
||||||
** sort them all together into one big ordered list on p->pEntry.
|
|
||||||
**
|
|
||||||
** This routine should only be called once in the life of a RowSet.
|
|
||||||
*/
|
|
||||||
static void rowSetToList(RowSet *p){
|
|
||||||
|
|
||||||
/* This routine is called only once */
|
|
||||||
assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
|
|
||||||
|
|
||||||
if( (p->rsFlags & ROWSET_SORTED)==0 ){
|
|
||||||
p->pEntry = rowSetEntrySort(p->pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* While this module could theoretically support it, sqlite3RowSetNext()
|
|
||||||
** is never called after sqlite3RowSetText() for the same RowSet. So
|
|
||||||
** there is never a forest to deal with. Should this change, simply
|
|
||||||
** remove the assert() and the #if 0. */
|
|
||||||
assert( p->pForest==0 );
|
|
||||||
#if 0
|
|
||||||
while( p->pForest ){
|
|
||||||
struct RowSetEntry *pTree = p->pForest->pLeft;
|
|
||||||
if( pTree ){
|
|
||||||
struct RowSetEntry *pHead, *pTail;
|
|
||||||
rowSetTreeToList(pTree, &pHead, &pTail);
|
|
||||||
p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
|
|
||||||
}
|
|
||||||
p->pForest = p->pForest->pRight;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Extract the smallest element from the RowSet.
|
** Extract the smallest element from the RowSet.
|
||||||
** Write the element into *pRowid. Return 1 on success. Return
|
** Write the element into *pRowid. Return 1 on success. Return
|
||||||
@@ -419,18 +396,30 @@ static void rowSetToList(RowSet *p){
|
|||||||
**
|
**
|
||||||
** After this routine has been called, the sqlite3RowSetInsert()
|
** After this routine has been called, the sqlite3RowSetInsert()
|
||||||
** routine may not be called again.
|
** routine may not be called again.
|
||||||
|
**
|
||||||
|
** This routine may not be called after sqlite3RowSetTest() has
|
||||||
|
** been used. Older versions of RowSet allowed that, but as the
|
||||||
|
** capability was not used by the code generator, it was removed
|
||||||
|
** for code economy.
|
||||||
*/
|
*/
|
||||||
int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
|
int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
|
||||||
assert( p!=0 );
|
assert( p!=0 );
|
||||||
|
assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */
|
||||||
|
|
||||||
/* Merge the forest into a single sorted list on first call */
|
/* Merge the forest into a single sorted list on first call */
|
||||||
if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
|
if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
p->pEntry = rowSetEntrySort(p->pEntry);
|
||||||
|
}
|
||||||
|
p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the next entry on the list */
|
/* Return the next entry on the list */
|
||||||
if( p->pEntry ){
|
if( p->pEntry ){
|
||||||
*pRowid = p->pEntry->v;
|
*pRowid = p->pEntry->v;
|
||||||
p->pEntry = p->pEntry->pRight;
|
p->pEntry = p->pEntry->pRight;
|
||||||
if( p->pEntry==0 ){
|
if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
|
/* Free memory immediately, rather than waiting on sqlite3_finalize() */
|
||||||
sqlite3RowSetClear(p);
|
sqlite3RowSetClear(p);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -453,13 +442,15 @@ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
|
|||||||
/* This routine is never called after sqlite3RowSetNext() */
|
/* This routine is never called after sqlite3RowSetNext() */
|
||||||
assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
|
assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
|
||||||
|
|
||||||
/* Sort entries into the forest on the first test of a new batch
|
/* Sort entries into the forest on the first test of a new batch.
|
||||||
|
** To save unnecessary work, only do this when the batch number changes.
|
||||||
*/
|
*/
|
||||||
if( iBatch!=pRowSet->iBatch ){
|
if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
p = pRowSet->pEntry;
|
p = pRowSet->pEntry;
|
||||||
if( p ){
|
if( p ){
|
||||||
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
|
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
|
||||||
if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
|
if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
/* Only sort the current set of entiries if they need it */
|
||||||
p = rowSetEntrySort(p);
|
p = rowSetEntrySort(p);
|
||||||
}
|
}
|
||||||
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
|
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
|
||||||
|
14
src/select.c
14
src/select.c
@@ -3785,14 +3785,18 @@ static int pushDownWhereTerms(
|
|||||||
){
|
){
|
||||||
Expr *pNew;
|
Expr *pNew;
|
||||||
int nChng = 0;
|
int nChng = 0;
|
||||||
|
Select *pX; /* For looping over compound SELECTs in pSubq */
|
||||||
if( pWhere==0 ) return 0;
|
if( pWhere==0 ) return 0;
|
||||||
if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
|
for(pX=pSubq; pX; pX=pX->pPrior){
|
||||||
testcase( pSubq->selFlags & SF_Aggregate );
|
if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
|
||||||
testcase( pSubq->selFlags & SF_Recursive );
|
testcase( pX->selFlags & SF_Aggregate );
|
||||||
return 0; /* restrictions (1) and (2) */
|
testcase( pX->selFlags & SF_Recursive );
|
||||||
|
testcase( pX!=pSubq );
|
||||||
|
return 0; /* restrictions (1) and (2) */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( pSubq->pLimit!=0 ){
|
if( pSubq->pLimit!=0 ){
|
||||||
return 0; /* restriction (3) */
|
return 0; /* restriction (3) */
|
||||||
}
|
}
|
||||||
while( pWhere->op==TK_AND ){
|
while( pWhere->op==TK_AND ){
|
||||||
nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
|
nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
|
||||||
|
@@ -1932,12 +1932,30 @@ struct sqlite3_mem_methods {
|
|||||||
** following this call. The second parameter may be a NULL pointer, in
|
** following this call. The second parameter may be a NULL pointer, in
|
||||||
** which case the new setting is not reported back. </dd>
|
** which case the new setting is not reported back. </dd>
|
||||||
**
|
**
|
||||||
|
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
|
||||||
|
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
|
||||||
|
** interface independently of the [load_extension()] SQL function.
|
||||||
|
** The [sqlite3_enable_load_extension()] API enables or disables both the
|
||||||
|
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
|
||||||
|
** There should be two additional arguments.
|
||||||
|
** When the first argument to this interface is 1, then only the C-API is
|
||||||
|
** enabled and the SQL function remains disabled. If the first argment to
|
||||||
|
** this interface is 0, then both the C-API and the SQL function are disabled.
|
||||||
|
** If the first argument is -1, then no changes are made to state of either the
|
||||||
|
** C-API or the SQL function.
|
||||||
|
** The second parameter is a pointer to an integer into which
|
||||||
|
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
|
||||||
|
** is disabled or enabled following this call. The second parameter may
|
||||||
|
** be a NULL pointer, in which case the new setting is not reported back.
|
||||||
|
** </dd>
|
||||||
|
**
|
||||||
** </dl>
|
** </dl>
|
||||||
*/
|
*/
|
||||||
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
||||||
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
|
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
|
||||||
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
|
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
|
||||||
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
|
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
|
||||||
|
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5474,9 +5492,18 @@ int sqlite3_table_column_metadata(
|
|||||||
** should free this memory by calling [sqlite3_free()].
|
** should free this memory by calling [sqlite3_free()].
|
||||||
**
|
**
|
||||||
** ^Extension loading must be enabled using
|
** ^Extension loading must be enabled using
|
||||||
** [sqlite3_enable_load_extension()] prior to calling this API,
|
** [sqlite3_enable_load_extension()] or
|
||||||
|
** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
|
||||||
|
** prior to calling this API,
|
||||||
** otherwise an error will be returned.
|
** otherwise an error will be returned.
|
||||||
**
|
**
|
||||||
|
** <b>Security warning:</b> It is recommended that the
|
||||||
|
** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
|
||||||
|
** interface. The use of the [sqlite3_enable_load_extension()] interface
|
||||||
|
** should be avoided. This will keep the SQL function [load_extension()]
|
||||||
|
** disabled and prevent SQL injections from giving attackers
|
||||||
|
** access to extension loading capabilities.
|
||||||
|
**
|
||||||
** See also the [load_extension() SQL function].
|
** See also the [load_extension() SQL function].
|
||||||
*/
|
*/
|
||||||
int sqlite3_load_extension(
|
int sqlite3_load_extension(
|
||||||
@@ -5499,6 +5526,17 @@ int sqlite3_load_extension(
|
|||||||
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
|
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
|
||||||
** to turn extension loading on and call it with onoff==0 to turn
|
** to turn extension loading on and call it with onoff==0 to turn
|
||||||
** it back off again.
|
** it back off again.
|
||||||
|
**
|
||||||
|
** ^This interface enables or disables both the C-API
|
||||||
|
** [sqlite3_load_extension()] and the SQL function [load_extension()].
|
||||||
|
** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
|
||||||
|
** to enable or disable only the C-API.
|
||||||
|
**
|
||||||
|
** <b>Security warning:</b> It is recommended that extension loading
|
||||||
|
** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
|
||||||
|
** rather than this interface, so the [load_extension()] SQL function
|
||||||
|
** remains disabled. This will prevent SQL injections from giving attackers
|
||||||
|
** access to extension loading capabilities.
|
||||||
*/
|
*/
|
||||||
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
|
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
|
||||||
|
|
||||||
|
@@ -15,6 +15,33 @@
|
|||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
|
|
||||||
|
/* Special Comments:
|
||||||
|
**
|
||||||
|
** Some comments have special meaning to the tools that measure test
|
||||||
|
** coverage:
|
||||||
|
**
|
||||||
|
** NO_TEST - The branches on this line are not
|
||||||
|
** measured by branch coverage. This is
|
||||||
|
** used on lines of code that actually
|
||||||
|
** implement parts of coverage testing.
|
||||||
|
**
|
||||||
|
** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false
|
||||||
|
** and the correct answer is still obtained,
|
||||||
|
** though perhaps more slowly.
|
||||||
|
**
|
||||||
|
** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true
|
||||||
|
** and the correct answer is still obtained,
|
||||||
|
** though perhaps more slowly.
|
||||||
|
**
|
||||||
|
** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread
|
||||||
|
** that would be harmless and undetectable
|
||||||
|
** if it did occur.
|
||||||
|
**
|
||||||
|
** In all cases, the special comment must be enclosed in the usual
|
||||||
|
** slash-asterisk...asterisk-slash comment marks, with no spaces between the
|
||||||
|
** asterisks and the comment text.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Make sure that rand_s() is available on Windows systems with MSVC 2005
|
** Make sure that rand_s() is available on Windows systems with MSVC 2005
|
||||||
** or higher.
|
** or higher.
|
||||||
@@ -1383,13 +1410,14 @@ struct sqlite3 {
|
|||||||
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
|
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
|
||||||
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
|
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
|
||||||
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
|
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
|
||||||
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
|
#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */
|
||||||
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
|
#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */
|
||||||
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
|
#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */
|
||||||
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
|
#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
|
||||||
#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
|
#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
|
||||||
#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
|
#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
|
||||||
#define SQLITE_Fts3Tokenizer 0x20000000 /* Enable fts3_tokenizer(2) */
|
#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
|
||||||
|
#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
11
src/test1.c
11
src/test1.c
@@ -1271,7 +1271,7 @@ static int sqlite3_mprintf_int64(
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
for(i=2; i<5; i++){
|
for(i=2; i<5; i++){
|
||||||
if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
|
if( sqlite3Atoi64(argv[i], &a[i-2], sqlite3Strlen30(argv[i]), SQLITE_UTF8) ){
|
||||||
Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
|
Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
@@ -5213,7 +5213,9 @@ static int vfs_unregister_all(
|
|||||||
/*
|
/*
|
||||||
** tclcmd: vfs_reregister_all
|
** tclcmd: vfs_reregister_all
|
||||||
**
|
**
|
||||||
** Restore all VFSes that were removed using vfs_unregister_all
|
** Restore all VFSes that were removed using vfs_unregister_all. Taking
|
||||||
|
** care to put the linked list back together in the same order as it was
|
||||||
|
** in before vfs_unregister_all was invoked.
|
||||||
*/
|
*/
|
||||||
static int vfs_reregister_all(
|
static int vfs_reregister_all(
|
||||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||||
@@ -5222,8 +5224,8 @@ static int vfs_reregister_all(
|
|||||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||||
){
|
){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<nVfs; i++){
|
for(i=nVfs-1; i>=0; i--){
|
||||||
sqlite3_vfs_register(apVfs[i], i==0);
|
sqlite3_vfs_register(apVfs[i], 1);
|
||||||
}
|
}
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
@@ -6988,6 +6990,7 @@ static int test_sqlite3_db_config(
|
|||||||
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
|
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||||
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||||
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||||
|
{ "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
int v;
|
int v;
|
||||||
|
@@ -547,7 +547,7 @@ static int btree_from_db(
|
|||||||
/*
|
/*
|
||||||
** Usage: btree_ismemdb ID
|
** Usage: btree_ismemdb ID
|
||||||
**
|
**
|
||||||
** Return true if the B-Tree is in-memory.
|
** Return true if the B-Tree is currently stored entirely in memory.
|
||||||
*/
|
*/
|
||||||
static int btree_ismemdb(
|
static int btree_ismemdb(
|
||||||
void *NotUsed,
|
void *NotUsed,
|
||||||
@@ -557,6 +557,7 @@ static int btree_ismemdb(
|
|||||||
){
|
){
|
||||||
Btree *pBt;
|
Btree *pBt;
|
||||||
int res;
|
int res;
|
||||||
|
sqlite3_file *pFile;
|
||||||
|
|
||||||
if( argc!=2 ){
|
if( argc!=2 ){
|
||||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||||
@@ -566,7 +567,8 @@ static int btree_ismemdb(
|
|||||||
pBt = sqlite3TestTextToPtr(argv[1]);
|
pBt = sqlite3TestTextToPtr(argv[1]);
|
||||||
sqlite3_mutex_enter(pBt->db->mutex);
|
sqlite3_mutex_enter(pBt->db->mutex);
|
||||||
sqlite3BtreeEnter(pBt);
|
sqlite3BtreeEnter(pBt);
|
||||||
res = sqlite3PagerIsMemdb(sqlite3BtreePager(pBt));
|
pFile = sqlite3PagerFile(sqlite3BtreePager(pBt));
|
||||||
|
res = (pFile->pMethods==0);
|
||||||
sqlite3BtreeLeave(pBt);
|
sqlite3BtreeLeave(pBt);
|
||||||
sqlite3_mutex_leave(pBt->db->mutex);
|
sqlite3_mutex_leave(pBt->db->mutex);
|
||||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res));
|
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res));
|
||||||
|
28
src/test6.c
28
src/test6.c
@@ -701,6 +701,10 @@ static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
|
|||||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||||
return pVfs->xCurrentTime(pVfs, pTimeOut);
|
return pVfs->xCurrentTime(pVfs, pTimeOut);
|
||||||
}
|
}
|
||||||
|
static int cfGetLastError(sqlite3_vfs *pCfVfs, int n, char *z){
|
||||||
|
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||||
|
return pVfs->xGetLastError(pVfs, n, z);
|
||||||
|
}
|
||||||
|
|
||||||
static int processDevSymArgs(
|
static int processDevSymArgs(
|
||||||
Tcl_Interp *interp,
|
Tcl_Interp *interp,
|
||||||
@@ -827,7 +831,7 @@ static int crashEnableCmd(
|
|||||||
cfRandomness, /* xRandomness */
|
cfRandomness, /* xRandomness */
|
||||||
cfSleep, /* xSleep */
|
cfSleep, /* xSleep */
|
||||||
cfCurrentTime, /* xCurrentTime */
|
cfCurrentTime, /* xCurrentTime */
|
||||||
0, /* xGetlastError */
|
cfGetLastError, /* xGetLastError */
|
||||||
0, /* xCurrentTimeInt64 */
|
0, /* xCurrentTimeInt64 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -940,6 +944,27 @@ static int devSymObjCmd(
|
|||||||
devsym_register(iDc, iSectorSize);
|
devsym_register(iDc, iSectorSize);
|
||||||
|
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** tclcmd: unregister_devsim
|
||||||
|
*/
|
||||||
|
static int dsUnregisterObjCmd(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
void devsym_unregister(void);
|
||||||
|
|
||||||
|
if( objc!=1 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
devsym_unregister();
|
||||||
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1010,6 +1035,7 @@ int Sqlitetest6_Init(Tcl_Interp *interp){
|
|||||||
Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
|
Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
|
||||||
Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
|
Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
|
||||||
Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
|
Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
|
||||||
|
Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0);
|
||||||
Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
|
Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
|
||||||
Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
|
Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -396,4 +396,11 @@ void devsym_register(int iDeviceChar, int iSectorSize){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void devsym_unregister(){
|
||||||
|
sqlite3_vfs_unregister(&devsym_vfs);
|
||||||
|
g.pVfs = 0;
|
||||||
|
g.iDeviceChar = 0;
|
||||||
|
g.iSectorSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -160,6 +160,7 @@ static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut);
|
|||||||
static int jtSleep(sqlite3_vfs*, int microseconds);
|
static int jtSleep(sqlite3_vfs*, int microseconds);
|
||||||
static int jtCurrentTime(sqlite3_vfs*, double*);
|
static int jtCurrentTime(sqlite3_vfs*, double*);
|
||||||
static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
|
static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
|
||||||
|
static int jtGetLastError(sqlite3_vfs*, int, char*);
|
||||||
|
|
||||||
static sqlite3_vfs jt_vfs = {
|
static sqlite3_vfs jt_vfs = {
|
||||||
2, /* iVersion */
|
2, /* iVersion */
|
||||||
@@ -179,7 +180,7 @@ static sqlite3_vfs jt_vfs = {
|
|||||||
jtRandomness, /* xRandomness */
|
jtRandomness, /* xRandomness */
|
||||||
jtSleep, /* xSleep */
|
jtSleep, /* xSleep */
|
||||||
jtCurrentTime, /* xCurrentTime */
|
jtCurrentTime, /* xCurrentTime */
|
||||||
0, /* xGetLastError */
|
jtGetLastError, /* xGetLastError */
|
||||||
jtCurrentTimeInt64 /* xCurrentTimeInt64 */
|
jtCurrentTimeInt64 /* xCurrentTimeInt64 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -285,9 +286,10 @@ static int jtRead(
|
|||||||
** b) The file-name specified when the file was opened matches
|
** b) The file-name specified when the file was opened matches
|
||||||
** all but the final 8 characters of the journal file name.
|
** all but the final 8 characters of the journal file name.
|
||||||
**
|
**
|
||||||
** c) There is currently a reserved lock on the file.
|
** c) There is currently a reserved lock on the file. This
|
||||||
|
** condition is waived if the noLock argument is non-zero.
|
||||||
**/
|
**/
|
||||||
static jt_file *locateDatabaseHandle(const char *zJournal){
|
static jt_file *locateDatabaseHandle(const char *zJournal, int noLock){
|
||||||
jt_file *pMain = 0;
|
jt_file *pMain = 0;
|
||||||
enterJtMutex();
|
enterJtMutex();
|
||||||
for(pMain=g.pList; pMain; pMain=pMain->pNext){
|
for(pMain=g.pList; pMain; pMain=pMain->pNext){
|
||||||
@@ -295,7 +297,7 @@ static jt_file *locateDatabaseHandle(const char *zJournal){
|
|||||||
if( (pMain->flags&SQLITE_OPEN_MAIN_DB)
|
if( (pMain->flags&SQLITE_OPEN_MAIN_DB)
|
||||||
&& ((int)strlen(pMain->zName)==nName)
|
&& ((int)strlen(pMain->zName)==nName)
|
||||||
&& 0==memcmp(pMain->zName, zJournal, nName)
|
&& 0==memcmp(pMain->zName, zJournal, nName)
|
||||||
&& (pMain->eLock>=SQLITE_LOCK_RESERVED)
|
&& ((pMain->eLock>=SQLITE_LOCK_RESERVED) || noLock)
|
||||||
){
|
){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -517,7 +519,7 @@ static int jtWrite(
|
|||||||
jt_file *p = (jt_file *)pFile;
|
jt_file *p = (jt_file *)pFile;
|
||||||
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
|
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
|
||||||
if( iOfst==0 ){
|
if( iOfst==0 ){
|
||||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
|
||||||
assert( pMain );
|
assert( pMain );
|
||||||
|
|
||||||
if( iAmt==28 ){
|
if( iAmt==28 ){
|
||||||
@@ -562,7 +564,7 @@ static int jtWrite(
|
|||||||
|
|
||||||
rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
|
rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
|
||||||
if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){
|
if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){
|
||||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
|
||||||
int rc2 = readJournalFile(p, pMain);
|
int rc2 = readJournalFile(p, pMain);
|
||||||
if( rc==SQLITE_OK ) rc = rc2;
|
if( rc==SQLITE_OK ) rc = rc2;
|
||||||
}
|
}
|
||||||
@@ -576,7 +578,7 @@ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
|||||||
jt_file *p = (jt_file *)pFile;
|
jt_file *p = (jt_file *)pFile;
|
||||||
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
|
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
|
||||||
/* Truncating a journal file. This is the end of a transaction. */
|
/* Truncating a journal file. This is the end of a transaction. */
|
||||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
|
||||||
closeTransaction(pMain);
|
closeTransaction(pMain);
|
||||||
}
|
}
|
||||||
if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
|
if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
|
||||||
@@ -604,11 +606,10 @@ static int jtSync(sqlite3_file *pFile, int flags){
|
|||||||
** jt_file.pWritable bitvec of the main database file associated with
|
** jt_file.pWritable bitvec of the main database file associated with
|
||||||
** this journal file.
|
** this journal file.
|
||||||
*/
|
*/
|
||||||
pMain = locateDatabaseHandle(p->zName);
|
pMain = locateDatabaseHandle(p->zName, 0);
|
||||||
assert(pMain);
|
|
||||||
|
|
||||||
/* Set the bitvec values */
|
/* Set the bitvec values */
|
||||||
if( pMain->pWritable ){
|
if( pMain && pMain->pWritable ){
|
||||||
pMain->nSync++;
|
pMain->nSync++;
|
||||||
rc = readJournalFile(p, pMain);
|
rc = readJournalFile(p, pMain);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -730,7 +731,7 @@ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
|||||||
int nPath = (int)strlen(zPath);
|
int nPath = (int)strlen(zPath);
|
||||||
if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
|
if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
|
||||||
/* Deleting a journal file. The end of a transaction. */
|
/* Deleting a journal file. The end of a transaction. */
|
||||||
jt_file *pMain = locateDatabaseHandle(zPath);
|
jt_file *pMain = locateDatabaseHandle(zPath, 0);
|
||||||
if( pMain ){
|
if( pMain ){
|
||||||
closeTransaction(pMain);
|
closeTransaction(pMain);
|
||||||
}
|
}
|
||||||
@@ -825,6 +826,10 @@ static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
|
|||||||
return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut);
|
return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jtGetLastError(sqlite3_vfs *pVfs, int n, char *z){
|
||||||
|
return g.pVfs->xGetLastError(g.pVfs, n, z);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
** Start of public API.
|
** Start of public API.
|
||||||
*/
|
*/
|
||||||
|
@@ -722,14 +722,20 @@ static int test_syscall(
|
|||||||
};
|
};
|
||||||
int iCmd;
|
int iCmd;
|
||||||
int rc;
|
int rc;
|
||||||
|
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
|
||||||
|
|
||||||
if( objc<2 ){
|
if( objc<2 ){
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
|
Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
rc = Tcl_GetIndexFromObjStruct(interp,
|
if( pVfs->iVersion<3 || pVfs->xSetSystemCall==0 ){
|
||||||
objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
|
Tcl_AppendResult(interp, "VFS does not support xSetSystemCall", 0);
|
||||||
);
|
rc = TCL_ERROR;
|
||||||
|
}else{
|
||||||
|
rc = Tcl_GetIndexFromObjStruct(interp,
|
||||||
|
objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
|
||||||
|
);
|
||||||
|
}
|
||||||
if( rc!=TCL_OK ) return rc;
|
if( rc!=TCL_OK ) return rc;
|
||||||
return aCmd[iCmd].xCmd(clientData, interp, objc, objv);
|
return aCmd[iCmd].xCmd(clientData, interp, objc, objv);
|
||||||
}
|
}
|
||||||
|
111
src/util.c
111
src/util.c
@@ -355,7 +355,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
|||||||
int eValid = 1; /* True exponent is either not used or is well-formed */
|
int eValid = 1; /* True exponent is either not used or is well-formed */
|
||||||
double result;
|
double result;
|
||||||
int nDigits = 0;
|
int nDigits = 0;
|
||||||
int nonNum = 0;
|
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
|
||||||
|
|
||||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||||
*pResult = 0.0; /* Default return value, in case of an error */
|
*pResult = 0.0; /* Default return value, in case of an error */
|
||||||
@@ -368,7 +368,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
|||||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||||
for(i=3-enc; i<length && z[i]==0; i+=2){}
|
for(i=3-enc; i<length && z[i]==0; i+=2){}
|
||||||
nonNum = i<length;
|
nonNum = i<length;
|
||||||
zEnd = z+i+enc-3;
|
zEnd = &z[i^1];
|
||||||
z += (enc&1);
|
z += (enc&1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,9 +384,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
|||||||
z+=incr;
|
z+=incr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip leading zeroes */
|
|
||||||
while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
|
|
||||||
|
|
||||||
/* copy max significant digits to significand */
|
/* copy max significant digits to significand */
|
||||||
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
||||||
s = s*10 + (*z - '0');
|
s = s*10 + (*z - '0');
|
||||||
@@ -403,12 +400,13 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
|||||||
z+=incr;
|
z+=incr;
|
||||||
/* copy digits from after decimal to significand
|
/* copy digits from after decimal to significand
|
||||||
** (decrease exponent by d to shift decimal right) */
|
** (decrease exponent by d to shift decimal right) */
|
||||||
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
while( z<zEnd && sqlite3Isdigit(*z) ){
|
||||||
s = s*10 + (*z - '0');
|
if( s<((LARGEST_INT64-9)/10) ){
|
||||||
z+=incr, nDigits++, d--;
|
s = s*10 + (*z - '0');
|
||||||
|
d--;
|
||||||
|
}
|
||||||
|
z+=incr, nDigits++;
|
||||||
}
|
}
|
||||||
/* skip non-significant digits */
|
|
||||||
while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
|
|
||||||
}
|
}
|
||||||
if( z>=zEnd ) goto do_atof_calc;
|
if( z>=zEnd ) goto do_atof_calc;
|
||||||
|
|
||||||
@@ -416,7 +414,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
|||||||
if( *z=='e' || *z=='E' ){
|
if( *z=='e' || *z=='E' ){
|
||||||
z+=incr;
|
z+=incr;
|
||||||
eValid = 0;
|
eValid = 0;
|
||||||
if( z>=zEnd ) goto do_atof_calc;
|
|
||||||
|
/* This branch is needed to avoid a (harmless) buffer overread. The
|
||||||
|
** special comment alerts the mutation tester that the correct answer
|
||||||
|
** is obtained even if the branch is omitted */
|
||||||
|
if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
|
||||||
|
|
||||||
/* get sign of exponent */
|
/* get sign of exponent */
|
||||||
if( *z=='-' ){
|
if( *z=='-' ){
|
||||||
esign = -1;
|
esign = -1;
|
||||||
@@ -433,9 +436,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* skip trailing spaces */
|
/* skip trailing spaces */
|
||||||
if( nDigits && eValid ){
|
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
||||||
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
|
||||||
}
|
|
||||||
|
|
||||||
do_atof_calc:
|
do_atof_calc:
|
||||||
/* adjust exponent by d, and update sign */
|
/* adjust exponent by d, and update sign */
|
||||||
@@ -447,41 +448,51 @@ do_atof_calc:
|
|||||||
esign = 1;
|
esign = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if 0 significand */
|
if( s==0 ) {
|
||||||
if( !s ) {
|
/* In the IEEE 754 standard, zero is signed. */
|
||||||
/* In the IEEE 754 standard, zero is signed.
|
result = sign<0 ? -(double)0 : (double)0;
|
||||||
** Add the sign if we've seen at least one digit */
|
|
||||||
result = (sign<0 && nDigits) ? -(double)0 : (double)0;
|
|
||||||
} else {
|
} else {
|
||||||
/* attempt to reduce exponent */
|
/* Attempt to reduce exponent.
|
||||||
if( esign>0 ){
|
**
|
||||||
while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
|
** Branches that are not required for the correct answer but which only
|
||||||
}else{
|
** help to obtain the correct answer faster are marked with special
|
||||||
while( !(s%10) && e>0 ) e--,s/=10;
|
** comments, as a hint to the mutation tester.
|
||||||
|
*/
|
||||||
|
while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
|
if( esign>0 ){
|
||||||
|
if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
s *= 10;
|
||||||
|
}else{
|
||||||
|
if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
s /= 10;
|
||||||
|
}
|
||||||
|
e--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust the sign of significand */
|
/* adjust the sign of significand */
|
||||||
s = sign<0 ? -s : s;
|
s = sign<0 ? -s : s;
|
||||||
|
|
||||||
/* if exponent, scale significand as appropriate
|
if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
** and store in result. */
|
result = (double)s;
|
||||||
if( e ){
|
}else{
|
||||||
LONGDOUBLE_TYPE scale = 1.0;
|
LONGDOUBLE_TYPE scale = 1.0;
|
||||||
/* attempt to handle extremely small/large numbers better */
|
/* attempt to handle extremely small/large numbers better */
|
||||||
if( e>307 && e<342 ){
|
if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
|
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||||
if( esign<0 ){
|
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
|
||||||
result = s / scale;
|
if( esign<0 ){
|
||||||
result /= 1.0e+308;
|
result = s / scale;
|
||||||
}else{
|
result /= 1.0e+308;
|
||||||
result = s * scale;
|
}else{
|
||||||
result *= 1.0e+308;
|
result = s * scale;
|
||||||
}
|
result *= 1.0e+308;
|
||||||
}else if( e>=342 ){
|
}
|
||||||
if( esign<0 ){
|
}else{ assert( e>=342 );
|
||||||
result = 0.0*s;
|
if( esign<0 ){
|
||||||
}else{
|
result = 0.0*s;
|
||||||
result = 1e308*1e308*s; /* Infinity */
|
}else{
|
||||||
|
result = 1e308*1e308*s; /* Infinity */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
/* 1.0e+22 is the largest power of 10 than can be
|
/* 1.0e+22 is the largest power of 10 than can be
|
||||||
@@ -494,8 +505,6 @@ do_atof_calc:
|
|||||||
result = s * scale;
|
result = s * scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
result = (double)s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +512,7 @@ do_atof_calc:
|
|||||||
*pResult = result;
|
*pResult = result;
|
||||||
|
|
||||||
/* return true if number and no extra non-whitespace chracters after */
|
/* return true if number and no extra non-whitespace chracters after */
|
||||||
return z>=zEnd && nDigits>0 && eValid && nonNum==0;
|
return z==zEnd && nDigits>0 && eValid && nonNum==0;
|
||||||
#else
|
#else
|
||||||
return !sqlite3Atoi64(z, pResult, length, enc);
|
return !sqlite3Atoi64(z, pResult, length, enc);
|
||||||
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
||||||
@@ -565,7 +574,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
|||||||
int neg = 0; /* assume positive */
|
int neg = 0; /* assume positive */
|
||||||
int i;
|
int i;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
int nonNum = 0;
|
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
|
||||||
const char *zStart;
|
const char *zStart;
|
||||||
const char *zEnd = zNum + length;
|
const char *zEnd = zNum + length;
|
||||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||||
@@ -576,7 +585,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
|||||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||||
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
|
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
|
||||||
nonNum = i<length;
|
nonNum = i<length;
|
||||||
zEnd = zNum+i+enc-3;
|
zEnd = &zNum[i^1];
|
||||||
zNum += (enc&1);
|
zNum += (enc&1);
|
||||||
}
|
}
|
||||||
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
||||||
@@ -603,8 +612,11 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
|||||||
testcase( i==18 );
|
testcase( i==18 );
|
||||||
testcase( i==19 );
|
testcase( i==19 );
|
||||||
testcase( i==20 );
|
testcase( i==20 );
|
||||||
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum)
|
if( &zNum[i]<zEnd /* Extra bytes at the end */
|
||||||
|| i>19*incr || nonNum ){
|
|| (i==0 && zStart==zNum) /* No digits */
|
||||||
|
|| i>19*incr /* Too many digits */
|
||||||
|
|| nonNum /* UTF16 with high-order bytes non-zero */
|
||||||
|
){
|
||||||
/* zNum is empty or contains non-numeric text or is longer
|
/* zNum is empty or contains non-numeric text or is longer
|
||||||
** than 19 digits (thus guaranteeing that it is too large) */
|
** than 19 digits (thus guaranteeing that it is too large) */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -646,7 +658,6 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
|
|||||||
#ifndef SQLITE_OMIT_HEX_INTEGER
|
#ifndef SQLITE_OMIT_HEX_INTEGER
|
||||||
if( z[0]=='0'
|
if( z[0]=='0'
|
||||||
&& (z[1]=='x' || z[1]=='X')
|
&& (z[1]=='x' || z[1]=='X')
|
||||||
&& sqlite3Isxdigit(z[2])
|
|
||||||
){
|
){
|
||||||
u64 u = 0;
|
u64 u = 0;
|
||||||
int i, k;
|
int i, k;
|
||||||
@@ -1408,7 +1419,7 @@ LogEst sqlite3LogEst(u64 x){
|
|||||||
if( x<2 ) return 0;
|
if( x<2 ) return 0;
|
||||||
while( x<8 ){ y -= 10; x <<= 1; }
|
while( x<8 ){ y -= 10; x <<= 1; }
|
||||||
}else{
|
}else{
|
||||||
while( x>255 ){ y += 40; x >>= 4; }
|
while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
|
||||||
while( x>15 ){ y += 10; x >>= 1; }
|
while( x>15 ){ y += 10; x >>= 1; }
|
||||||
}
|
}
|
||||||
return a[x&7] + y - 10;
|
return a[x&7] + y - 10;
|
||||||
|
17
src/vdbe.c
17
src/vdbe.c
@@ -215,7 +215,7 @@ static VdbeCursor *allocateCursor(
|
|||||||
(eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
|
(eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
|
||||||
|
|
||||||
assert( iCur>=0 && iCur<p->nCursor );
|
assert( iCur>=0 && iCur<p->nCursor );
|
||||||
if( p->apCsr[iCur] ){
|
if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
|
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
|
||||||
p->apCsr[iCur] = 0;
|
p->apCsr[iCur] = 0;
|
||||||
}
|
}
|
||||||
@@ -292,7 +292,7 @@ static void applyAffinity(
|
|||||||
if( affinity>=SQLITE_AFF_NUMERIC ){
|
if( affinity>=SQLITE_AFF_NUMERIC ){
|
||||||
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|
||||||
|| affinity==SQLITE_AFF_NUMERIC );
|
|| affinity==SQLITE_AFF_NUMERIC );
|
||||||
if( (pRec->flags & MEM_Int)==0 ){
|
if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
if( (pRec->flags & MEM_Real)==0 ){
|
if( (pRec->flags & MEM_Real)==0 ){
|
||||||
if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
|
if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
|
||||||
}else{
|
}else{
|
||||||
@@ -302,10 +302,13 @@ static void applyAffinity(
|
|||||||
}else if( affinity==SQLITE_AFF_TEXT ){
|
}else if( affinity==SQLITE_AFF_TEXT ){
|
||||||
/* Only attempt the conversion to TEXT if there is an integer or real
|
/* Only attempt the conversion to TEXT if there is an integer or real
|
||||||
** representation (blob and NULL do not get converted) but no string
|
** representation (blob and NULL do not get converted) but no string
|
||||||
** representation.
|
** representation. It would be harmless to repeat the conversion if
|
||||||
*/
|
** there is already a string rep, but it is pointless to waste those
|
||||||
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
|
** CPU cycles. */
|
||||||
sqlite3VdbeMemStringify(pRec, enc, 1);
|
if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
|
if( (pRec->flags&(MEM_Real|MEM_Int)) ){
|
||||||
|
sqlite3VdbeMemStringify(pRec, enc, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pRec->flags &= ~(MEM_Real|MEM_Int);
|
pRec->flags &= ~(MEM_Real|MEM_Int);
|
||||||
}
|
}
|
||||||
@@ -542,7 +545,7 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
|
|||||||
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
|
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
|
||||||
pOut = &p->aMem[pOp->p2];
|
pOut = &p->aMem[pOp->p2];
|
||||||
memAboutToChange(p, pOut);
|
memAboutToChange(p, pOut);
|
||||||
if( VdbeMemDynamic(pOut) ){
|
if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/
|
||||||
return out2PrereleaseWithClear(pOut);
|
return out2PrereleaseWithClear(pOut);
|
||||||
}else{
|
}else{
|
||||||
pOut->flags = MEM_Int;
|
pOut->flags = MEM_Int;
|
||||||
|
@@ -164,7 +164,7 @@ foreach zOpenScript [list {
|
|||||||
set file_dest temp
|
set file_dest temp
|
||||||
}] {
|
}] {
|
||||||
foreach rows_dest {0 3 10} {
|
foreach rows_dest {0 3 10} {
|
||||||
foreach pgsz_dest {512 1024 2048} {
|
foreach pgsz_dest {512 1024 2048 4096} {
|
||||||
foreach nPagePerStep {1 200} {
|
foreach nPagePerStep {1 200} {
|
||||||
|
|
||||||
# Open the databases.
|
# Open the databases.
|
||||||
@@ -176,17 +176,16 @@ foreach nPagePerStep {1 200} {
|
|||||||
# in-memory destination is only possible if the initial destination
|
# in-memory destination is only possible if the initial destination
|
||||||
# page size is the same as the source page size (in this case 1024 bytes).
|
# page size is the same as the source page size (in this case 1024 bytes).
|
||||||
#
|
#
|
||||||
set isMemDest [expr {
|
set isMemDest [expr { $zDestFile eq ":memory:" || $file_dest eq "temp" }]
|
||||||
$zDestFile eq ":memory:" || $file_dest eq "temp" && $TEMP_STORE>=2
|
|
||||||
}]
|
|
||||||
|
|
||||||
if { $isMemDest==0 || $pgsz_dest == 1024 } {
|
if 0 {
|
||||||
if 0 {
|
puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile"
|
||||||
puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile"
|
puts -nonewline " (as $db_dest.$file_dest)"
|
||||||
puts -nonewline " (as $db_dest.$file_dest)"
|
puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest"
|
||||||
puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest"
|
puts ""
|
||||||
puts ""
|
}
|
||||||
}
|
|
||||||
|
if { $isMemDest==0 || $pgsz_dest==1024 || $rows_dest==0 } {
|
||||||
|
|
||||||
# Set up the content of the source database.
|
# Set up the content of the source database.
|
||||||
execsql {
|
execsql {
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
set testprefix cacheflush
|
set testprefix cffault
|
||||||
source $testdir/malloc_common.tcl
|
source $testdir/malloc_common.tcl
|
||||||
|
|
||||||
# Run the supplied SQL on a copy of the database currently stored on
|
# Run the supplied SQL on a copy of the database currently stored on
|
||||||
|
@@ -86,7 +86,7 @@ do_test 2.3 { db_write db 1 } {0 4 0}
|
|||||||
do_test 2.4 { db_write db 0 } {0 0 0}
|
do_test 2.4 { db_write db 0 } {0 0 0}
|
||||||
do_test 2.5 { db_write db 1 } {0 0 0}
|
do_test 2.5 { db_write db 1 } {0 0 0}
|
||||||
|
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
do_test 2.6 {
|
do_test 2.6 {
|
||||||
execsql { PRAGMA journal_mode = WAL }
|
execsql { PRAGMA journal_mode = WAL }
|
||||||
db_write db 1
|
db_write db 1
|
||||||
|
@@ -176,7 +176,7 @@ if {![nonzero_reserved_bytes]} {
|
|||||||
# EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
|
# EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
|
||||||
# auto_vacuum support property can be changed using VACUUM.
|
# auto_vacuum support property can be changed using VACUUM.
|
||||||
#
|
#
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
do_test e_vacuum-1.3.3.1 {
|
do_test e_vacuum-1.3.3.1 {
|
||||||
execsql { PRAGMA journal_mode = wal }
|
execsql { PRAGMA journal_mode = wal }
|
||||||
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
|
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
|
||||||
|
@@ -19,6 +19,7 @@ source $testdir/lock_common.tcl
|
|||||||
|
|
||||||
|
|
||||||
foreach jm {rollback wal} {
|
foreach jm {rollback wal} {
|
||||||
|
if {![wal_is_capable] && $jm=="wal"} continue
|
||||||
|
|
||||||
set testprefix exists-$jm
|
set testprefix exists-$jm
|
||||||
|
|
||||||
|
@@ -704,7 +704,7 @@ do_execsql_test 7.5.2.0 {
|
|||||||
ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
|
ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcapable !session {
|
if 0 {
|
||||||
# At time of writing, these two are broken. They demonstrate that the
|
# At time of writing, these two are broken. They demonstrate that the
|
||||||
# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
|
# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
|
||||||
# has been used to add a column with a default value other than NULL.
|
# has been used to add a column with a default value other than NULL.
|
||||||
|
@@ -134,7 +134,7 @@ do_test incrvacuum2-3.2 {
|
|||||||
|
|
||||||
integrity_check incrvacuum2-3.3
|
integrity_check incrvacuum2-3.3
|
||||||
|
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
# At one point, when a specific page was being extracted from the b-tree
|
# At one point, when a specific page was being extracted from the b-tree
|
||||||
# free-list (e.g. during an incremental-vacuum), all trunk pages that
|
# free-list (e.g. during an incremental-vacuum), all trunk pages that
|
||||||
# occurred before the specific page in the free-list trunk were being
|
# occurred before the specific page in the free-list trunk were being
|
||||||
|
@@ -204,7 +204,7 @@ db close
|
|||||||
# delete the journal file when committing the transaction that switches
|
# delete the journal file when committing the transaction that switches
|
||||||
# the system to WAL mode.
|
# the system to WAL mode.
|
||||||
#
|
#
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
do_test journal2-2.1 {
|
do_test journal2-2.1 {
|
||||||
faultsim_delete_and_reopen
|
faultsim_delete_and_reopen
|
||||||
set ::oplog [list]
|
set ::oplog [list]
|
||||||
|
@@ -111,7 +111,7 @@ do_test loadext-1.2 {
|
|||||||
#
|
#
|
||||||
do_test loadext-1.3 {
|
do_test loadext-1.3 {
|
||||||
sqlite3 db2 test.db
|
sqlite3 db2 test.db
|
||||||
sqlite3_enable_load_extension db2 1
|
sqlite3_db_config db2 SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1
|
||||||
catchsql {
|
catchsql {
|
||||||
SELECT half(1.0);
|
SELECT half(1.0);
|
||||||
} db2
|
} db2
|
||||||
@@ -256,6 +256,7 @@ do_test loadext-4.2 {
|
|||||||
}
|
}
|
||||||
} {0 {{}}}
|
} {0 {{}}}
|
||||||
|
|
||||||
|
# disable all extension loading
|
||||||
do_test loadext-4.3 {
|
do_test loadext-4.3 {
|
||||||
sqlite3_enable_load_extension db 0
|
sqlite3_enable_load_extension db 0
|
||||||
catchsql {
|
catchsql {
|
||||||
@@ -263,6 +264,15 @@ do_test loadext-4.3 {
|
|||||||
}
|
}
|
||||||
} {1 {not authorized}}
|
} {1 {not authorized}}
|
||||||
|
|
||||||
|
# enable C-api extension loading only. Show that the SQL function
|
||||||
|
# still does not work.
|
||||||
|
do_test loadext-4.4 {
|
||||||
|
sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1
|
||||||
|
catchsql {
|
||||||
|
SELECT load_extension($::testextension,'testloadext_init')
|
||||||
|
}
|
||||||
|
} {1 {not authorized}}
|
||||||
|
|
||||||
source $testdir/malloc_common.tcl
|
source $testdir/malloc_common.tcl
|
||||||
|
|
||||||
|
|
||||||
|
@@ -423,8 +423,9 @@ do_test lock-6.5 {
|
|||||||
# * there exists one or more active read-only statements, and
|
# * there exists one or more active read-only statements, and
|
||||||
# * a transaction that modified zero database pages is committed.
|
# * a transaction that modified zero database pages is committed.
|
||||||
#
|
#
|
||||||
set temp_status unlocked
|
#set temp_status unlocked
|
||||||
if {$TEMP_STORE>=2} {set temp_status unknown}
|
#if {$TEMP_STORE>=2} {set temp_status unknown}
|
||||||
|
set temp_status unknown
|
||||||
do_test lock-7.1 {
|
do_test lock-7.1 {
|
||||||
set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL]
|
set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL]
|
||||||
sqlite3_step $STMT
|
sqlite3_step $STMT
|
||||||
|
@@ -684,22 +684,24 @@ do_faultsim_test pagerfault-14a -prep {
|
|||||||
# is not possible to change the page-size of an in-memory database. Even
|
# is not possible to change the page-size of an in-memory database. Even
|
||||||
# using the backup API.
|
# using the backup API.
|
||||||
#
|
#
|
||||||
if {$TEMP_STORE<2} {
|
# Update: It is no longer possible to change the page size of any temp
|
||||||
do_faultsim_test pagerfault-14b -prep {
|
# database after it has been created.
|
||||||
catch { db2 close }
|
#
|
||||||
faultsim_restore_and_reopen
|
do_faultsim_test pagerfault-14b -prep {
|
||||||
|
catch { db2 close }
|
||||||
|
faultsim_restore_and_reopen
|
||||||
sqlite3 db2 ""
|
sqlite3 db2 ""
|
||||||
db2 eval { PRAGMA page_size = 4096; CREATE TABLE xx(a) }
|
db2 eval { PRAGMA page_size = 4096; CREATE TABLE xx(a) }
|
||||||
} -body {
|
} -body {
|
||||||
sqlite3_backup B db2 main db main
|
sqlite3_backup B db2 main db main
|
||||||
B step 200
|
B step 200
|
||||||
set rc [B finish]
|
set rc [B finish]
|
||||||
if {[string match SQLITE_IOERR_* $rc]} {set rc SQLITE_IOERR}
|
if {[string match SQLITE_IOERR_* $rc]} {set rc SQLITE_IOERR}
|
||||||
if {$rc != "SQLITE_OK"} { error [sqlite3_test_errstr $rc] }
|
if {$rc != "SQLITE_OK"} { error [sqlite3_test_errstr $rc] }
|
||||||
set {} {}
|
set {} {}
|
||||||
} -test {
|
} -test {
|
||||||
faultsim_test_result {0 {}} {1 {sqlite3_backup_init() failed}}
|
faultsim_test_result {1 {attempt to write a readonly database}} \
|
||||||
}
|
{1 {sqlite3_backup_init() failed}}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_faultsim_test pagerfault-14c -prep {
|
do_faultsim_test pagerfault-14c -prep {
|
||||||
|
@@ -728,7 +728,7 @@ test_suite "inmemory_journal" -description {
|
|||||||
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
|
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
|
||||||
vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test
|
vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test
|
||||||
e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test
|
e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test
|
||||||
fts3snippet.test mmapfault.test
|
fts3snippet.test mmapfault.test sessionfault.test sessionfault2.test
|
||||||
|
|
||||||
# Exclude test scripts that use tcl IO to access journal files or count
|
# Exclude test scripts that use tcl IO to access journal files or count
|
||||||
# the number of fsync() calls.
|
# the number of fsync() calls.
|
||||||
@@ -942,7 +942,9 @@ test_suite "journaltest" -description {
|
|||||||
unregister_jt_vfs
|
unregister_jt_vfs
|
||||||
} -files [test_set $::allquicktests -exclude {
|
} -files [test_set $::allquicktests -exclude {
|
||||||
wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test
|
wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test
|
||||||
async4.test bigfile.test backcompat.test
|
async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
|
||||||
|
pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
|
||||||
|
pager2.test *fault* rowal* snapshot* superlock* symlink.test
|
||||||
}]
|
}]
|
||||||
|
|
||||||
if {[info commands register_demovfs] != ""} {
|
if {[info commands register_demovfs] != ""} {
|
||||||
@@ -1050,15 +1052,13 @@ proc run_tests {name args} {
|
|||||||
set ::G(isquick) 1
|
set ::G(isquick) 1
|
||||||
set ::G(perm:dbconfig) $options(-dbconfig)
|
set ::G(perm:dbconfig) $options(-dbconfig)
|
||||||
|
|
||||||
uplevel $options(-initialize)
|
|
||||||
|
|
||||||
foreach file [lsort $options(-files)] {
|
foreach file [lsort $options(-files)] {
|
||||||
|
uplevel $options(-initialize)
|
||||||
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
|
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
|
||||||
slave_test_file $file
|
slave_test_file $file
|
||||||
|
uplevel $options(-shutdown)
|
||||||
}
|
}
|
||||||
|
|
||||||
uplevel $options(-shutdown)
|
|
||||||
|
|
||||||
unset ::G(perm:name)
|
unset ::G(perm:name)
|
||||||
unset ::G(perm:prefix)
|
unset ::G(perm:prefix)
|
||||||
unset ::G(perm:presql)
|
unset ::G(perm:presql)
|
||||||
|
@@ -1083,7 +1083,20 @@ do_test pragma-8.2.15 {
|
|||||||
# "memory" or "disk" as appropriate.
|
# "memory" or "disk" as appropriate.
|
||||||
#
|
#
|
||||||
proc check_temp_store {} {
|
proc check_temp_store {} {
|
||||||
db eval {CREATE TEMP TABLE IF NOT EXISTS a(b)}
|
db eval {
|
||||||
|
PRAGMA temp.cache_size = 1;
|
||||||
|
CREATE TEMP TABLE IF NOT EXISTS a(b);
|
||||||
|
DELETE FROM a;
|
||||||
|
INSERT INTO a VALUES(randomblob(1000));
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
INSERT INTO a SELECT * FROM a;
|
||||||
|
}
|
||||||
db eval {PRAGMA database_list} {
|
db eval {PRAGMA database_list} {
|
||||||
if {$name=="temp"} {
|
if {$name=="temp"} {
|
||||||
set bt [btree_from_db db 1]
|
set bt [btree_from_db db 1]
|
||||||
|
@@ -221,7 +221,7 @@ ifcapable shared_cache {
|
|||||||
# This will not work with the in-memory journal permutation, as opening
|
# This will not work with the in-memory journal permutation, as opening
|
||||||
# [db2] switches the journal mode back to "memory"
|
# [db2] switches the journal mode back to "memory"
|
||||||
#
|
#
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
if {[permutation]!="inmemory_journal"} {
|
if {[permutation]!="inmemory_journal"} {
|
||||||
|
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
|
@@ -527,4 +527,6 @@ do_faultsim_test quota-5.6 -prep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
catch { sqlite3_quota_shutdown }
|
catch { sqlite3_quota_shutdown }
|
||||||
|
catch { db close }
|
||||||
|
forcedelete test.db
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -968,6 +968,42 @@ do_execsql_test select4-16.3 {
|
|||||||
ORDER BY t3.a;
|
ORDER BY t3.a;
|
||||||
} {95 96 97 98 99}
|
} {95 96 97 98 99}
|
||||||
|
|
||||||
|
# Ticket https://www.sqlite.org/src/tktview/f7f8c97e975978d45 on 2016-04-25
|
||||||
|
#
|
||||||
|
# The where push-down optimization from 2015-06-02 is suppose to disable
|
||||||
|
# on aggregate subqueries. But if the subquery is a compound where the
|
||||||
|
# last SELECT is non-aggregate but some other SELECT is an aggregate, the
|
||||||
|
# test is incomplete and the optimization is not properly disabled.
|
||||||
|
#
|
||||||
|
# The following test cases verify that the fix works.
|
||||||
|
#
|
||||||
|
do_execsql_test select4-17.1 {
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1(a int, b int);
|
||||||
|
INSERT INTO t1 VALUES(1,2),(1,18),(2,19);
|
||||||
|
SELECT x, y FROM (
|
||||||
|
SELECT 98 AS x, 99 AS y
|
||||||
|
UNION
|
||||||
|
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a
|
||||||
|
) AS w WHERE y>=20
|
||||||
|
ORDER BY +x;
|
||||||
|
} {1 20 98 99}
|
||||||
|
do_execsql_test select4-17.2 {
|
||||||
|
SELECT x, y FROM (
|
||||||
|
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a
|
||||||
|
UNION
|
||||||
|
SELECT 98 AS x, 99 AS y
|
||||||
|
) AS w WHERE y>=20
|
||||||
|
ORDER BY +x;
|
||||||
|
} {1 20 98 99}
|
||||||
|
do_catchsql_test select4-17.3 {
|
||||||
|
SELECT x, y FROM (
|
||||||
|
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a LIMIT 3
|
||||||
|
UNION
|
||||||
|
SELECT 98 AS x, 99 AS y
|
||||||
|
) AS w WHERE y>=20
|
||||||
|
ORDER BY +x;
|
||||||
|
} {1 {LIMIT clause should come after UNION not before}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -37,7 +37,7 @@ do_execsql_test stat-0.0 {
|
|||||||
SELECT * FROM stat;
|
SELECT * FROM stat;
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
do_execsql_test stat-0.1 {
|
do_execsql_test stat-0.1 {
|
||||||
PRAGMA journal_mode = WAL;
|
PRAGMA journal_mode = WAL;
|
||||||
PRAGMA journal_mode = delete;
|
PRAGMA journal_mode = delete;
|
||||||
|
@@ -81,6 +81,7 @@ do_test sync-1.3 {
|
|||||||
set sqlite_sync_count
|
set sqlite_sync_count
|
||||||
} 11
|
} 11
|
||||||
ifcapable pager_pragmas {
|
ifcapable pager_pragmas {
|
||||||
|
if {[permutation]!="journaltest"} {
|
||||||
do_test sync-1.4 {
|
do_test sync-1.4 {
|
||||||
set sqlite_sync_count 0
|
set sqlite_sync_count 0
|
||||||
execsql {
|
execsql {
|
||||||
@@ -94,6 +95,7 @@ ifcapable pager_pragmas {
|
|||||||
set sqlite_sync_count
|
set sqlite_sync_count
|
||||||
} 0
|
} 0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
134
test/tempfault.test
Normal file
134
test/tempfault.test
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# 2016 April 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# This file contains tests for fault-injection when SQLite is used with
|
||||||
|
# a temp file database.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
source $testdir/malloc_common.tcl
|
||||||
|
set testprefix tempfault
|
||||||
|
|
||||||
|
# sqlite3_memdebug_vfs_oom_test 0
|
||||||
|
|
||||||
|
do_faultsim_test 1 -faults * -prep {
|
||||||
|
sqlite3 db ""
|
||||||
|
db eval {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
INSERT INTO t1 VALUES(3, 4);
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
execsql { INSERT INTO t1 VALUES(5, 6) }
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
set rc [catch { execsql { SELECT * FROM t1 } } msg]
|
||||||
|
if {$rc==0 && $msg != "1 2 3 4 5 6" && $msg != "1 2 3 4"} {
|
||||||
|
error "data mismatch 1: $msg"
|
||||||
|
}
|
||||||
|
if {$testrc==0 && $msg != "1 2 3 4 5 6"} {
|
||||||
|
error "data mismatch 2: $msg"
|
||||||
|
}
|
||||||
|
faultsim_integrity_check
|
||||||
|
}
|
||||||
|
|
||||||
|
do_faultsim_test 2 -faults * -prep {
|
||||||
|
sqlite3 db ""
|
||||||
|
db eval {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
PRAGMA cache_size = 10;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(b, a);
|
||||||
|
WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100)
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
execsql { UPDATE t1 SET a = randomblob(99) }
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
faultsim_integrity_check db
|
||||||
|
}
|
||||||
|
|
||||||
|
catch { db close }
|
||||||
|
do_faultsim_test 2.1 -faults * -prep {
|
||||||
|
if {[info commands db]==""} {
|
||||||
|
sqlite3 db ""
|
||||||
|
execsql {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
PRAGMA cache_size = 10;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(b, a);
|
||||||
|
WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100)
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
execsql { UPDATE t1 SET a = randomblob(99) }
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
faultsim_integrity_check db
|
||||||
|
}
|
||||||
|
|
||||||
|
do_faultsim_test 3 -faults * -prep {
|
||||||
|
sqlite3 db ""
|
||||||
|
db eval {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
PRAGMA cache_size = 10;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(b, a);
|
||||||
|
WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<50)
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
execsql {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET a = randomblob(99);
|
||||||
|
SAVEPOINT abc;
|
||||||
|
UPDATE t1 SET a = randomblob(98) WHERE (rowid%10)==0;
|
||||||
|
ROLLBACK TO abc;
|
||||||
|
UPDATE t1 SET a = randomblob(97) WHERE (rowid%5)==0;
|
||||||
|
ROLLBACK TO abc;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
faultsim_integrity_check db
|
||||||
|
}
|
||||||
|
|
||||||
|
do_faultsim_test 4 -faults * -prep {
|
||||||
|
sqlite3 db ""
|
||||||
|
db eval {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
PRAGMA cache_size = 10;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(b, a);
|
||||||
|
WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<50)
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
execsql {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET a = randomblob(99);
|
||||||
|
SAVEPOINT abc;
|
||||||
|
UPDATE t1 SET a = randomblob(98) WHERE (rowid%10)==0;
|
||||||
|
ROLLBACK TO abc;
|
||||||
|
UPDATE t1 SET a = randomblob(97) WHERE (rowid%5)==0;
|
||||||
|
ROLLBACK TO abc;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_memdebug_vfs_oom_test 1
|
||||||
|
finish_test
|
356
test/temptable2.test
Normal file
356
test/temptable2.test
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
# 2016 March 3
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
set testprefix temptable2
|
||||||
|
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
CREATE TEMP TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 1.2 {
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100000 )
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM X;
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_execsql_test 1.3 {
|
||||||
|
PRAGMA temp.integrity_check;
|
||||||
|
} {ok}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 2.1 {
|
||||||
|
CREATE TEMP TABLE t2(a, b);
|
||||||
|
INSERT INTO t2 VALUES(1, 2);
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_execsql_test 2.2 {
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t2 VALUES(3, 4);
|
||||||
|
SELECT * FROM t2;
|
||||||
|
} {1 2 3 4}
|
||||||
|
|
||||||
|
do_execsql_test 2.3 {
|
||||||
|
ROLLBACK;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
} {1 2}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 3.1.1 {
|
||||||
|
PRAGMA main.cache_size = 10;
|
||||||
|
PRAGMA temp.cache_size = 10;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(a, b);
|
||||||
|
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 )
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
} {1000}
|
||||||
|
do_execsql_test 3.1.2 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
|
||||||
|
ROLLBACK;
|
||||||
|
}
|
||||||
|
do_execsql_test 3.1.3 {
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
} {1000}
|
||||||
|
do_execsql_test 3.1.4 { PRAGMA temp.integrity_check } {ok}
|
||||||
|
|
||||||
|
do_execsql_test 3.2.1 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
|
||||||
|
SAVEPOINT abc;
|
||||||
|
UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==1;
|
||||||
|
ROLLBACK TO abc;
|
||||||
|
UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==2;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
do_execsql_test 3.2.2 { PRAGMA temp.integrity_check } {ok}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 4.1.1 {
|
||||||
|
PRAGMA main.cache_size = 10;
|
||||||
|
PRAGMA temp.cache_size = 10;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(a, b);
|
||||||
|
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<10 )
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
PRAGMA temp.page_count;
|
||||||
|
} {10 9}
|
||||||
|
|
||||||
|
do_execsql_test 4.1.2 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET b=randomblob(100);
|
||||||
|
ROLLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 4.1.3 {
|
||||||
|
CREATE TEMP TABLE t2(a, b);
|
||||||
|
CREATE INDEX i2 ON t2(a, b);
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
|
||||||
|
INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
|
||||||
|
SELECT count(*) FROM t2;
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
} {500 10}
|
||||||
|
|
||||||
|
do_test 4.1.4 {
|
||||||
|
set n [db one { PRAGMA temp.page_count }]
|
||||||
|
expr ($n >280 && $n < 300)
|
||||||
|
} 1
|
||||||
|
|
||||||
|
do_execsql_test 4.1.4 { PRAGMA temp.integrity_check } {ok}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 5.1.1 {
|
||||||
|
PRAGMA main.cache_size = 10;
|
||||||
|
PRAGMA temp.cache_size = 10;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE t2(a, b);
|
||||||
|
CREATE INDEX i2 ON t2(a, b);
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
|
||||||
|
INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(a, b);
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test that the temp database is now much bigger than the configured
|
||||||
|
# cache size (10 pages).
|
||||||
|
do_test 5.1.2 {
|
||||||
|
set n [db one { PRAGMA temp.page_count }]
|
||||||
|
expr ($n > 270 && $n < 290)
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_execsql_test 5.1.3 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET a=2;
|
||||||
|
UPDATE t2 SET a=randomblob(100);
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
ROLLBACK;
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_execsql_test 5.1.4 {
|
||||||
|
UPDATE t2 SET a=randomblob(100);
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
} {1 2}
|
||||||
|
|
||||||
|
do_execsql_test 5.1.5 { PRAGMA temp.integrity_check } {ok}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test this:
|
||||||
|
#
|
||||||
|
# 1. Page is DIRTY at the start of a transaction.
|
||||||
|
# 2. Page is written out as part of the transaction.
|
||||||
|
# 3. Page is then read back in.
|
||||||
|
# 4. Transaction is rolled back. Is the page now clean or dirty?
|
||||||
|
#
|
||||||
|
# This actually does work. Step 4 marks the page as clean. But it also
|
||||||
|
# writes to the database file itself. So marking it clean is correct -
|
||||||
|
# the page does match the contents of the db file.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
|
||||||
|
do_execsql_test 6.1 {
|
||||||
|
PRAGMA main.cache_size = 10;
|
||||||
|
PRAGMA temp.cache_size = 10;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE t1(x);
|
||||||
|
INSERT INTO t1 VALUES('one');
|
||||||
|
|
||||||
|
CREATE TEMP TABLE t2(a, b);
|
||||||
|
CREATE INDEX i2 ON t2(a, b);
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
|
||||||
|
INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 6.2 {
|
||||||
|
UPDATE t1 SET x='two'; -- step 1
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t2 SET a=randomblob(100); -- step 2
|
||||||
|
SELECT * FROM t1; -- step 3
|
||||||
|
ROLLBACK; -- step 4
|
||||||
|
|
||||||
|
SELECT count(*) FROM t2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
} {two 500 two}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
sqlite3 db ""
|
||||||
|
do_execsql_test 7.1 {
|
||||||
|
PRAGMA auto_vacuum=INCREMENTAL;
|
||||||
|
CREATE TABLE t1(x);
|
||||||
|
INSERT INTO t1 VALUES(zeroblob(900));
|
||||||
|
INSERT INTO t1 VALUES(zeroblob(900));
|
||||||
|
INSERT INTO t1 SELECT x FROM t1;
|
||||||
|
INSERT INTO t1 SELECT x FROM t1;
|
||||||
|
INSERT INTO t1 SELECT x FROM t1;
|
||||||
|
INSERT INTO t1 SELECT x FROM t1;
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM t1 WHERE rowid%2;
|
||||||
|
PRAGMA incremental_vacuum(4);
|
||||||
|
ROLLBACK;
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {ok}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Try changing the page size using a backup operation when pages are
|
||||||
|
# stored in main-memory only.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 8.1 {
|
||||||
|
PRAGMA auto_vacuum = OFF;
|
||||||
|
CREATE TABLE t2(a, b);
|
||||||
|
CREATE INDEX i2 ON t2(a, b);
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<20 )
|
||||||
|
INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} {13}
|
||||||
|
|
||||||
|
do_test 8.2 {
|
||||||
|
sqlite3 tmp ""
|
||||||
|
execsql {
|
||||||
|
PRAGMA auto_vacuum = OFF;
|
||||||
|
PRAGMA page_size = 8192;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
CREATE INDEX i1 ON t1(a, b);
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100 )
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
PRAGMA page_count;
|
||||||
|
} tmp
|
||||||
|
} {10}
|
||||||
|
|
||||||
|
do_test 8.3 {
|
||||||
|
sqlite3_backup B tmp main db main
|
||||||
|
B step 5
|
||||||
|
B finish
|
||||||
|
} {SQLITE_READONLY}
|
||||||
|
|
||||||
|
do_test 8.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
PRAGMA page_size;
|
||||||
|
} tmp
|
||||||
|
} {100 ok 8192}
|
||||||
|
|
||||||
|
do_test 8.5 {
|
||||||
|
tmp eval { UPDATE t1 SET a=randomblob(100) }
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_test 8.6 {
|
||||||
|
sqlite3_backup B tmp main db main
|
||||||
|
B step 1000
|
||||||
|
B finish
|
||||||
|
} {SQLITE_READONLY}
|
||||||
|
|
||||||
|
tmp close
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Try inserts and deletes with a large db in auto-vacuum mode. Check
|
||||||
|
#
|
||||||
|
foreach {tn mode} {
|
||||||
|
1 delete
|
||||||
|
2 wal
|
||||||
|
} {
|
||||||
|
reset_db
|
||||||
|
sqlite3 db ""
|
||||||
|
do_execsql_test 9.$tn.1.1 {
|
||||||
|
PRAGMA cache_size = 15;
|
||||||
|
PRAGMA auto_vacuum = 1;
|
||||||
|
}
|
||||||
|
execsql "PRAGMA journal_mode = $mode"
|
||||||
|
|
||||||
|
do_execsql_test 9.$tn.1.2 {
|
||||||
|
CREATE TABLE tx(a, b);
|
||||||
|
CREATE INDEX i1 ON tx(a);
|
||||||
|
CREATE INDEX i2 ON tx(b);
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 )
|
||||||
|
INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
|
||||||
|
for {set i 2} {$i<20} {incr i} {
|
||||||
|
do_execsql_test 9.$tn.$i.1 { DELETE FROM tx WHERE (random()%3)==0 }
|
||||||
|
|
||||||
|
do_execsql_test 9.$tn.$i.2 { PRAGMA integrity_check } ok
|
||||||
|
|
||||||
|
do_execsql_test 9.$tn.$i.3 {
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<400 )
|
||||||
|
INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 9.$tn.$i.4 { PRAGMA integrity_check } ok
|
||||||
|
|
||||||
|
do_execsql_test 9.$tn.$i.5 {
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM tx WHERE (random()%3)==0;
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
|
||||||
|
INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 9.$tn.$i.6 { PRAGMA integrity_check } ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# When using mmap mode with a temp file, SQLite must search the cache
|
||||||
|
# before using a mapped page even when there is no write transaction
|
||||||
|
# open. For a temp file, the on-disk version may not be up to date.
|
||||||
|
#
|
||||||
|
sqlite3 db ""
|
||||||
|
do_execsql_test 10.0 {
|
||||||
|
PRAGMA cache_size = 50;
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID;
|
||||||
|
CREATE INDEX i1 ON t1(a);
|
||||||
|
CREATE TABLE t2(x, y);
|
||||||
|
INSERT INTO t2 VALUES(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 10.1 {
|
||||||
|
BEGIN;
|
||||||
|
WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
|
||||||
|
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t2 VALUES(3, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[permutation]!="journaltest"} {
|
||||||
|
# The journaltest permutation does not support mmap, so this part of
|
||||||
|
# the test is omitted.
|
||||||
|
do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 10.3 { SELECT * FROM t2 } {1 2 3 4}
|
||||||
|
do_execsql_test 10.4 { PRAGMA integrity_check } ok
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
@@ -1944,6 +1944,12 @@ proc wal_check_journal_mode {testname {db db}} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc wal_is_capable {} {
|
||||||
|
ifcapable !wal { return 0 }
|
||||||
|
if {[permutation]=="journaltest"} { return 0 }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
proc permutation {} {
|
proc permutation {} {
|
||||||
set perm ""
|
set perm ""
|
||||||
catch {set perm $::G(perm:name)}
|
catch {set perm $::G(perm:name)}
|
||||||
|
@@ -19,7 +19,8 @@ set testdir [file dirname $argv0]
|
|||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
set testprefix tkt-2d1a5c67d
|
set testprefix tkt-2d1a5c67d
|
||||||
|
|
||||||
ifcapable {!wal || !vtab} {finish_test; return}
|
ifcapable {!vtab} {finish_test; return}
|
||||||
|
if {[wal_is_capable]==0} {finish_test; return}
|
||||||
|
|
||||||
for {set ii 1} {$ii<=10} {incr ii} {
|
for {set ii 1} {$ii<=10} {incr ii} {
|
||||||
do_test tkt-2d1a5c67d.1.$ii {
|
do_test tkt-2d1a5c67d.1.$ii {
|
||||||
|
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
|
|||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
source $testdir/malloc_common.tcl
|
source $testdir/malloc_common.tcl
|
||||||
|
|
||||||
ifcapable !wal { finish_test ; return }
|
if {![wal_is_capable]} { finish_test ; return }
|
||||||
|
|
||||||
do_execsql_test tkt-313723c356.1 {
|
do_execsql_test tkt-313723c356.1 {
|
||||||
PRAGMA page_size = 1024;
|
PRAGMA page_size = 1024;
|
||||||
|
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
|
|||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
source $testdir/lock_common.tcl
|
source $testdir/lock_common.tcl
|
||||||
set ::testprefix tkt-5d863f876e
|
set ::testprefix tkt-5d863f876e
|
||||||
ifcapable !wal {finish_test ; return }
|
if {![wal_is_capable]} {finish_test ; return }
|
||||||
|
|
||||||
do_multiclient_test tn {
|
do_multiclient_test tn {
|
||||||
do_test $tn.1 {
|
do_test $tn.1 {
|
||||||
|
@@ -50,4 +50,6 @@ for {set i 0} {$i < 100} {incr i} {
|
|||||||
} {ok}
|
} {ok}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch { db close }
|
||||||
|
unregister_devsim
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -89,7 +89,7 @@ do_test zerodamage-2.1 {
|
|||||||
concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
|
concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
|
||||||
} {0 0 24704}
|
} {0 0 24704}
|
||||||
|
|
||||||
ifcapable wal {
|
if {[wal_is_capable]} {
|
||||||
# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
|
# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
|
||||||
# WAL file does not get too big.
|
# WAL file does not get too big.
|
||||||
#
|
#
|
||||||
|
@@ -4402,7 +4402,8 @@ void ReportTable(
|
|||||||
writeRuleText(out, rp);
|
writeRuleText(out, rp);
|
||||||
fprintf(out, " */\n"); lineno++;
|
fprintf(out, " */\n"); lineno++;
|
||||||
for(rp2=rp->next; rp2; rp2=rp2->next){
|
for(rp2=rp->next; rp2; rp2=rp2->next){
|
||||||
if( rp2->code==rp->code ){
|
if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix
|
||||||
|
&& rp2->codeSuffix==rp->codeSuffix ){
|
||||||
fprintf(out," case %d: /* ", rp2->iRule);
|
fprintf(out," case %d: /* ", rp2->iRule);
|
||||||
writeRuleText(out, rp2);
|
writeRuleText(out, rp2);
|
||||||
fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++;
|
fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++;
|
||||||
|
Reference in New Issue
Block a user