Compare commits

...

43 Commits

Author SHA1 Message Date
dan 02f441e408 Add "PRAGMA checkpoint_fullfsync". Similar to "PRAGMA fullfsync", but enables full fsyncs only during checkpoint operations.
FossilOrigin-Name: 756589ad6e286a898ca34ff1b14d5bb4843529e1
2010-11-09 20:08:02 +00:00
drh 8c0b44a552 Back out the prior attempt to enable full-fsync for WAL and attempt the same
thing using a completely different approach.

FossilOrigin-Name: f59949fac1776ea2f58f41ee8aef8dd95b67725a
2010-11-09 01:53:48 +00:00
adam a6db3f058a Experimental changes to test defaulting to fullfsync for WAL mode
FossilOrigin-Name: 77b343cfc3bef9b1a99e98fec6073626dab05657
2010-11-09 00:47:45 +00:00
adam 985be1bce6 Integrated proxy locking file support for WAL journal mode and double free fix
FossilOrigin-Name: fd4d38fa66de85676189ff4922fb1bf5f8cac9c4
2010-11-09 00:43:59 +00:00
adam 99f24349ea fixed memory leak in proxy lock file error handling
FossilOrigin-Name: e01c5f3eda7fe6e6afe9c3894384f09b58173da1
2010-09-10 23:16:16 +00:00
adam 890b69fb83 replaced relative lock proxy paths with absolute
FossilOrigin-Name: 782c33512ab2b677b0734c591fcecddc5a655203
2010-09-10 20:19:06 +00:00
adam f5d6f1e0c5 replaced relative lock proxy paths with absolute
FossilOrigin-Name: 6a88cd46aeef3c50c91d5aadc61dd0b0982f8a4f
2010-09-10 00:59:28 +00:00
drh 5ec0cfe070 Make sure SQLite is running with MEMSTATUS enabled at the beginning of every
test script.

FossilOrigin-Name: b6e9a4d8f7d8b683b4098270e0be149df1ef295f
2010-09-10 00:18:12 +00:00
drh 3b3b1a538d Make sure MEMSTATUS is enabled at the beginning of the memsubsys2.test
script.

FossilOrigin-Name: cf23a354975f581c2cf2299e2b2a4e00819830ad
2010-09-09 23:40:42 +00:00
drh b0fa210aa3 The merge for check-in [415c448dc4] did not do exactly write, resulting in
a subtle bug in the SQLITE_FCNTL_SIZE_HINT logic.  This check-in is the
fix.

FossilOrigin-Name: badaaa18fd4a4402add6ae1b3ecadbb79f91fe37
2010-09-09 23:31:36 +00:00
drh 801829c812 Merge in the R-tree fix from the trunk.
FossilOrigin-Name: 02ee0bd5a305e3a6cd76f2e304f8a7effacd8433
2010-08-24 01:51:07 +00:00
drh 9b3c15e860 Merge changes through release 3.7.2 into the apple-osx branch.
FossilOrigin-Name: 415c448dc45a297bd1b0bbce25c4572eeab286f0
2010-08-24 01:08:11 +00:00
drh 61d3bfb78b Merge the 3.7.1 pre-release snapshot changes as of [2010-08-18]
into the apple-osx branch.

FossilOrigin-Name: 866e9286ae4226b2bec40ef18c672a41768abf1f
2010-08-18 00:24:09 +00:00
adam 45d55a254b Updating apple-osx with minor source fixes, database truncate and replace private calls and a bunch of conditionalization for tests running in different environments
FossilOrigin-Name: 5e2ee7db0f7a2a042b182336438107e2248d7b88
2010-08-18 00:09:47 +00:00
drh 51e5db70b6 Merge in all changes up to the 3.7.0.1 release.
FossilOrigin-Name: f88c6367d2f96cc93846ba38e6b963a1a3936e8d
2010-08-07 11:46:07 +00:00
drh f219bba933 Backport fix [a6bb2108bfb56] for a typo in the OS/2 interface.
FossilOrigin-Name: 042a1abb030a0711386add7eb6e10832cc8b0f57
2010-08-04 12:31:10 +00:00
drh a0166e1873 Update the version number to 3.7.0.1.
FossilOrigin-Name: 5074b85967df8f55739ba790924347c764288a88
2010-08-04 12:19:24 +00:00
drh aff0449d8f Backport fix [267492d3a7eff7b] for the performance regression caused by
automatic indexing and reported by ticket [8011086c85c6c4040].

FossilOrigin-Name: 3f367fe00e2adf87f3cc426466db4e3088e6f175
2010-08-04 12:13:35 +00:00
drh c55e9b815f Backport the [65b8636ac6e5] fix for ticket [51ae9cad317a1] to version 3.7.0.
FossilOrigin-Name: dec70c63d052bbe41fc4a065109d2845c67d3f15
2010-08-04 11:59:06 +00:00
drh 03ba419b3c Merge in changes up to and including the 3.6.23.1 release.
FossilOrigin-Name: 21ca87f69125a9e7124c6ddc566d17f64661b0d3
2010-06-16 19:48:56 +00:00
drh c4098a3d9f Cherry-pick the SQLITE_FCNTL_SIZE_HINT patch (check-in [2b7e3b4a30d6a7c4a8]
and bump the version number to 3.6.23.2.

FossilOrigin-Name: 776679af588625f13307369770979bccae7cf03a
2010-05-19 22:09:19 +00:00
drh 21ce77989a Disable the corruptE test which SQLITE_OVERSIZE_CELL_CHECK is enabled.
This is a cherrypick merge from check-in [1dc4f9fe9b83467ba].

FossilOrigin-Name: a40d080ca3c5f152f3296caf48f20728f61317de
2010-05-19 20:30:15 +00:00
drh 91973abb4b Include shell.c and sqlite3.def in the amalgamation ZIP archive.
Ticket [e063139eb3f8]

FossilOrigin-Name: b51fcac9fb4207810ee8d33ead47886e9c46d224
2010-03-31 11:56:47 +00:00
drh 722db051c6 Update the version number to 3.6.23.1.
FossilOrigin-Name: b078b588d617e07886ad156e9f54ade6d823568e
2010-03-26 22:28:06 +00:00
drh 87dd60cd8d Pull in other fixes from the trunk: check-ins [bea9258643],
[f186b6a619], and [bb591802ff].

FossilOrigin-Name: b1f342a6643829020beef542a0700d90822e6467
2010-03-26 21:53:11 +00:00
drh 7244fdc446 Fix to the crash8.test test script.
FossilOrigin-Name: f18a129a7aab09a1e0d34155e82bcbf7479a401d
2010-03-26 21:47:59 +00:00
drh 4f7e8fcded Enhance FTS3 to take advantage of the MAX() optimization.
Cherrypick of [b7e42ae774].

FossilOrigin-Name: 4b65b4805100852a2b6a834aa6efc0bbf25b539f
2010-03-26 17:42:57 +00:00
drh 95063a5774 Correctly handle strings with zero-length tokens in the FTS3 offsets()
function.  This is a cherrypick of [d37034f7fc].

FossilOrigin-Name: ff6ae4f0e461fb5f8d08a0092488b7cd71cffb05
2010-03-26 17:40:32 +00:00
drh ad7c2a87f5 After any rollback that modifies the database file, sync the database
before deleting the rollback journal.  This is a cherry-pick merge
of check-ins [b21b911f23] and [f2326dad4e]

FossilOrigin-Name: ca0bc2a22e893062876f67e0f53cbab44b45665d
2010-03-26 17:37:12 +00:00
adam cc3ec7cb2b fix merge error and compiler warning
FossilOrigin-Name: 5c0afe70a5ee2b378896bf30426823dc5ae4e95c
2010-02-26 22:05:01 +00:00
adam 3942b4b147 More double free paranoia
FossilOrigin-Name: 62dfb44b3b66c4acb1a7a10c44cbee1022a88883
2010-02-26 20:54:10 +00:00
drh 9aa0012a08 Merge latest changes from the trunk into the apple-osx branch.
FossilOrigin-Name: 4b72e39bd00572d9375639f4b978eff1b1d9aa20
2010-02-17 19:34:11 +00:00
adam efd8e3b33d Updated open mask to include SQLITE_OPEN_AUTOPROXY
FossilOrigin-Name: 7c3bede3f21812aa78105c6685654f12f0460eea
2010-01-26 01:14:33 +00:00
drh 0b90b2209f Align the os_unix.c source file with the version found on trunk.
FossilOrigin-Name: fa0f6c140e8ff9a5eed1d8a339fb6d55ecdca688
2010-01-20 13:20:22 +00:00
drh 9782039bde Update the Apple OS-X branch to include all of the latest changes in trunk.
FossilOrigin-Name: 96499b1dd69a0954e30e4b5b4f2272ab306afcdb
2010-01-20 01:26:07 +00:00
adam 332aa832ce robustness fixes for preventing a finalized statement from being reused
FossilOrigin-Name: a7a0c8d644873764cb799f9d6aacede4a4fb531f
2010-01-19 23:50:21 +00:00
drh bf4cad1e4c Update the OS-X branch to include all trunk changes through version 3.6.22.
FossilOrigin-Name: 541e2b488e4e40706e457c6d3b5647d53da02ce9
2010-01-06 13:12:48 +00:00
drh b0c5edcd06 Fix the main.mk makefile so that the sqlrr extension is built into the
amalgamation correctly.

FossilOrigin-Name: a3204d8a217d47e5120ab16918c1b7d4be5a021e
2009-12-23 18:06:49 +00:00
drh 2250799f0c Merge the latest changes on trunk (and especially the fix for
the (xANDy)OR(z) bug) into apple-osx.

FossilOrigin-Name: 5754a3a56144ee0e073c80651bf11cb23ee7f447
2009-12-16 23:46:11 +00:00
drh ca071dfd75 Merge all changes associated with the version 3.6.21 release into the OS-X
branch.

FossilOrigin-Name: ad08794d7239bb804eb39c00170821732b60cb65
2009-12-07 23:53:51 +00:00
adam ac0c39980a Fix for lock structure sharing with AFP-style locking
FossilOrigin-Name: 62f15c0aeaec5d778addb6edba62411c698bec0f
2009-11-09 19:30:44 +00:00
drh 04d4227255 Fix an undefined variable on non-Mac builds.
FossilOrigin-Name: 9552de8fb5ec7554c989edc138c0324c5fd0a206
2009-11-05 18:31:55 +00:00
adam e6c3c72c1b Merging in OSX customizations:
A ext/sqlrr/sqlrr.[ch]
-- add sql recording/replay support (very experimental extension -- pre alpha)

M ext/rtree/rtree.c
-- fix cast compiler warning

M src/func.c
-- substring backward compatiblity <rdar://problem/6778339> 

M src/legacy.c
-- replay recorder calls

M src/main.c
-- if SQLITE_ENABLE_AUTO_PROFILE, call sqlite3_profile when env(SQLITE_AUTO_PROFILE)   
-- replay recorder calls

M src/mem1.c
-- use custom malloc zone on single core systems

M src/os_unix.c
-- hostid via gethostuuid
-- read-only file system support for proxy locking
-- improved handling of simulated shared lock on AFP/SMB on 64 bit systems
-- disable whole-file-lock NFS file locking
-- fix for downgrading from exclusive to shared lock on NFS
-- proxy lock breaking & recreating local lock files
-- support SQLITE_OPEN_AUTOPROXY flag
-- only write 1st byte into new zero-length files if fs is DOS
-- cache fs type info in unixFile struct
-- force use of fsync() even if fdatasync() is available
-- remove flock locking style support for SMB
-- replace strcpy with strlcpy

M src/prepare.c
-- replay recorder calls

M src/sqlite.h.in
-- added SQLITE_OPEN_AUTOPROXY

M src/sqliteInt.h
-- include replay recorder header

M src/vdbeapi.c
-- checking for NULL statement for <rdar://6646331> 
-- replay recorder calls

FossilOrigin-Name: 941a01eb868815f566539e9ab21f807d9e798e40
2009-11-03 22:34:35 +00:00
63 changed files with 2297 additions and 481 deletions
+14
View File
@@ -325,6 +325,9 @@ SRC += \
SRC += \
$(TOP)/ext/rtree/rtree.h \
$(TOP)/ext/rtree/rtree.c
SRC += \
$(TOP)/ext/sqlrr/sqlrr.h \
$(TOP)/ext/sqlrr/sqlrr.c
# Generated source code files
@@ -460,6 +463,17 @@ EXTHDR += \
$(TOP)/ext/rtree/rtree.h
EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
$(TOP)/ext/sqlrr/sqlrr.h
# If using the amalgamation, use sqlite3.c directly to build the test
# fixture. Otherwise link against libsqlite3.la. (This distinction is
# necessary because the test fixture requires non-API symbols which are
# hidden when the library is built via the amalgamation).
#
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
TESTFIXTURE_SRC1 = sqlite3.c
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
Vendored Executable → Regular
View File
+2 -1
View File
@@ -63,6 +63,7 @@
#include <string.h>
#include <assert.h>
#include <stdint.h>
#ifndef SQLITE_AMALGAMATION
typedef sqlite3_int64 i64;
@@ -2709,7 +2710,7 @@ static int rtreeInit(
Rtree *pRtree;
int nDb; /* Length of string argv[1] */
int nName; /* Length of string argv[2] */
int eCoordType = (int)pAux;
int eCoordType = (int)(intptr_t)pAux;
const char *aErrMsg[] = {
0, /* 0 */
+54
View File
@@ -0,0 +1,54 @@
sqlrr - 10/19/2009
SQL Replay Recording
SUMMARY
-------------------------------------------------------
This extension enables recording sqlite API calls that access the database so that they can be replayed or examined.
USAGE
------------------------------------------------------
Recording is enabled by compiling sqlite with symbolic constant SQLITE_ENABLE_SQLRR defined.
By default logs are written to /tmp/<databasename>_<pid>_<connection_number>.sqlrr, to choose another directory, set the environment variable SQLITE_REPLAY_RECORD_DIR to that path.
FILE FORMAT
-----------------------------------------------------
file: <header>[<sql-command>]*
header: <signature><format-version>
signature: SQLRR (5 bytes)
format-version: n (1 byte)
sql-command: <timestamp><type><arg-data>
timestamp: n (16 bytes)
type: n (1 byte)
open 0
close 1
exec 8
bind-text 16
bind-double 17
bind-int 18
bind-null 19
bind-value 20
bind-clear 21
prep 32
step 33
reset 34
finalize 35
open-arg-data: <connection><path><flags>
close-arg-data: <connection>
exec-arg-data: <connection><len><statement-text>
bind-text-arg-data: <statement-ref><index><len><data>
bind-double-arg-data: <statement-ref><index><data>
bind-int-arg-data: <statement-ref><index><data>
bind-null-arg-data: <statement-ref><index>
bind-value-arg-data: <statement-ref><index><len><data> ???
bind-clear-arg-data: <statement-ref>
prep-arg-data: <connection><len><statement-text>
step-arg-data: <statement-ref>
reset-arg-data: <statement-ref>
finalize-arg-data: <statement-ref>
NOTES
+581
View File
@@ -0,0 +1,581 @@
/*
* sqlrr.c
*/
#include "sqlrr.h"
#if defined(SQLITE_ENABLE_SQLRR)
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/param.h>
#include <errno.h>
#include <pthread.h>
#include <libkern/OSAtomic.h>
#include "sqliteInt.h"
#include "vdbeInt.h"
#define LOGSUFFIXLEN 48
/*
* Data types
*/
typedef struct SRRLogRef SRRLogRef;
struct SRRLogRef {
int fd;
sqlite3 *db;
const char *dbPath;
char *logPath;
int connection;
int depth;
SRRLogRef *nextRef;
};
/*
* Globals
*/
SRRLogRef *logRefHead = NULL;
int dbLogCount = 0;
static int srr_enabled = 1;
pthread_mutex_t srr_log_mutex;
static volatile int32_t srr_initialized = 0;
/*
* Log management
*/
extern void SRRecInitialize() {
int go = OSAtomicCompareAndSwap32Barrier(0, 1, &srr_initialized);
if( go ){
pthread_mutex_init(&srr_log_mutex, NULL);
}
}
static SRRLogRef *createLog(sqlite3 *db, const char *dbPath) {
SRRLogRef *ref = NULL;
char *baseDir = getenv("SQLITE_REPLAY_RECORD_DIR");
char logPath[MAXPATHLEN] = "";
char suffix[LOGSUFFIXLEN] = "";
const char *dbName = dbPath;
int len = 0;
int index = 0;
int fd = -1;
size_t out;
unsigned char version = SRR_FILE_VERSION;
SRRecInitialize();
/* construct the path for the log file
* ${SQLITE_REPLAY_DIR}/<dbname>_<pid>_<connection_number>.sqlrr
*/
if (baseDir == NULL) {
baseDir = "/tmp"; /* getenv(TMPDIR) */
}
len = strlen(baseDir);
strlcat(logPath, baseDir, MAXPATHLEN);
if ((len>0) && (baseDir[len-1] != '/')) {
strlcat(logPath, "/", MAXPATHLEN);
}
len = strlen(dbPath);
for (index = len-2; index >= 0; index --){
if (dbPath[index] == '/') {
dbName = &dbPath[index+1];
break;
}
}
strlcat(logPath, dbName, MAXPATHLEN);
int cNum = ++dbLogCount;
snprintf(suffix, sizeof(suffix), "_%d_%d_XXXX.sqlrr", getpid(), cNum);
len = strlcat(logPath, suffix, MAXPATHLEN);
/* make it unique if we have the space */
if ((len + 1) < MAXPATHLEN) {
fd = mkstemps(logPath, 6);
} else {
fprintf(stderr, "Failed to create sqlite replay log path for %s [%s]\n", dbPath, logPath);
return NULL;
}
if (fd == -1) {
fprintf(stderr, "Failed to create sqlite replay log file for %s with path %s [%s]\n", dbPath, logPath, strerror(errno));
return NULL;
}
fprintf(stdout, "Writing sqlite replay log file %s\n", logPath);
out = write(fd, SRR_FILE_SIGNATURE, SRR_FILE_SIGNATURE_LEN);
if (out!=-1) {
out = write(fd, &version, 1);
}
if (out == -1){
fprintf(stderr, "Write failure on log [%s]: %s\n", logPath, strerror(errno));
close(fd);
return NULL;
}
len = strlen(logPath) + 1;
ref = (SRRLogRef *)malloc(sizeof(SRRLogRef));
ref->db = db;
ref->dbPath = dbPath;
ref->logPath = (char *)malloc(len * sizeof(char));
strlcpy(ref->logPath, logPath, len);
ref->fd = fd;
ref->connection = cNum;
ref->depth = 0;
pthread_mutex_lock(&srr_log_mutex);
ref->nextRef = logRefHead;
logRefHead = ref;
pthread_mutex_unlock(&srr_log_mutex);
return ref;
}
static void closeLog(sqlite3 *db) {
SRRLogRef *ref = NULL;
SRRLogRef *lastRef = NULL;
pthread_mutex_lock(&srr_log_mutex);
for (ref = logRefHead; ref != NULL; ref = ref->nextRef) {
if (ref->db == db) {
if (lastRef == NULL) {
logRefHead = ref->nextRef;
} else {
lastRef->nextRef = ref->nextRef;
}
}
}
pthread_mutex_unlock(&srr_log_mutex);
if (ref != NULL) {
fprintf(stdout, "Closing sqlite replay log file %s\n", ref->logPath);
close(ref->fd);
free(ref->logPath);
free(ref);
}
}
static SRRLogRef *getLog(sqlite3 *db) {
pthread_mutex_lock(&srr_log_mutex);
SRRLogRef *ref = logRefHead;
for (ref = logRefHead; ref != NULL; ref = ref->nextRef) {
if (ref->db == db) {
pthread_mutex_unlock(&srr_log_mutex);
return ref;
}
}
pthread_mutex_unlock(&srr_log_mutex);
return NULL;
}
/*
* SQLite recording API
*/
void SQLiteReplayRecorder(int flag) {
srr_enabled = flag;
}
// open-arg-data: <connection><len><path><flags>
void _SRRecOpen(sqlite3 *db, const char *path, int flags) {
if (!srr_enabled) return;
if (db) {
SRRLogRef *ref = createLog(db, path);
if (ref) {
SRRCommand code = SRROpen;
int len = strlen(path);
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out=write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) { out=write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
if (out!=-1) { out=write(ref->fd, &len, sizeof(len)); }
if (out!=-1) { out=write(ref->fd, path, len); }
if (out!=-1) { out=write(ref->fd, &flags, sizeof(flags)); }
if (out==-1) {
fprintf(stderr, "Error writing open to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(db);
}
}
}
}
//close-arg-data: <connection>
void SRRecClose(sqlite3 *db) {
if (!srr_enabled) return;
if (db) {
SRRLogRef *ref = getLog(db);
if (ref) {
SRRCommand code = SRRClose;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
if (out==-1) {
fprintf(stderr, "Error writing close to log file [%s]: %s\n", ref->logPath, strerror(errno));
}
closeLog(db);
}
}
}
// exec-arg-data: <connection><len><statement-text>
void SRRecExec(sqlite3 *db, const char *sql) {
if (!srr_enabled) return;
if (db) {
SRRLogRef *ref = getLog(db);
if (ref) {
if (ref->depth == 0) {
SRRCommand code = SRRExec;
int len = strlen(sql);
struct timeval tv;
size_t out;
ref->depth = 1;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
if (out!=-1) { out = write(ref->fd, &len, sizeof(len)); }
if (out!=-1) { out = write(ref->fd, sql, len); }
if (out==-1) {
fprintf(stderr, "Error writing exec to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(db);
}
} else {
ref->depth ++;
}
}
}
}
void SRRecExecEnd(sqlite3 *db) {
if (!srr_enabled) return;
if (db) {
SRRLogRef *ref = getLog(db);
if (ref) {
ref->depth --;
}
}
}
// prep-arg-data: <connection><len><statement-text><savesql><statement-ref>
void _SRRecPrepare(sqlite3 *db, const char *sql, int nBytes, int saveSql, sqlite3_stmt *pStmt) {
if (!srr_enabled) return;
if ((db!=NULL)&&(pStmt!=NULL)) {
SRRLogRef *ref = getLog(db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRPrepare;
struct timeval tv;
size_t out;
int sqlLen = nBytes;
if (sqlLen == -1) {
sqlLen = strlen(sql);
}
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
if (out!=-1) { out = write(ref->fd, &sqlLen, sizeof(sqlLen)); }
if (out!=-1) { out = write(ref->fd, sql, sqlLen); }
if (out!=-1) { out = write(ref->fd, &saveSql, sizeof(saveSql)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out==-1) {
fprintf(stderr, "Error writing prepare to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(db);
}
}
}
}
//step-arg-data: <statement-ref>
void SRRecStep(sqlite3_stmt *pStmt) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref) {
if (ref->depth == 0) {
SRRCommand code = SRRStep;
struct timeval tv;
size_t out;
ref->depth = 1;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out==-1) {
fprintf(stderr, "Error writing step to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
} else {
ref->depth ++;
}
}
}
}
void SRRecStepEnd(sqlite3_stmt *pStmt) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref) {
ref->depth --;
}
}
}
// reset-arg-data: <statement-ref>
void SRRecReset(sqlite3_stmt *pStmt) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRReset;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out==-1) {
fprintf(stderr, "Error writing reset to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// finalize-arg-data: <statement-ref>
void SRRecFinalize(sqlite3_stmt *pStmt) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRFinalize;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out==-1) {
fprintf(stderr, "Error writing finalize to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// bind-text-arg-data: <statement-ref><index><len><data>
void SRRecBindText(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRBindText;
struct timeval tv;
size_t out;
int64_t textLen = nData;
if (textLen == -1) {
textLen = strlen(zData);
}
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
if (out!=-1) { out = write(ref->fd, &textLen, sizeof(textLen)); }
if (out!=-1) { out = write(ref->fd, zData, textLen); }
if (out==-1) {
fprintf(stderr, "Error writing bind text to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// bind-blob-arg-data: <statement-ref><index><len>[<data>]
void SRRecBindBlob(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRBindBlob;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
if (zData == NULL) {
int64_t negNData = -nData;
if (out!=-1) { out = write(ref->fd, &negNData, sizeof(negNData)); }
} else {
if (out!=-1) { out = write(ref->fd, &nData, sizeof(nData)); }
if (out!=-1) { out = write(ref->fd, zData, nData); }
}
if (out==-1) {
fprintf(stderr, "Error writing bind blob to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// bind-double-arg-data: <statement-ref><index><data>
void SRRecBindDouble(sqlite3_stmt *pStmt, int i, double value) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRBindDouble;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
if (out!=-1) { out = write(ref->fd, &value, sizeof(value)); }
if (out==-1) {
fprintf(stderr, "Error writing bind double to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// bind-int-arg-data: <statement-ref><index><data>
void SRRecBindInt64(sqlite3_stmt *pStmt, int i, int64_t value) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRBindInt;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
if (out!=-1) { out = write(ref->fd, &value, sizeof(value)); }
if (out==-1) {
fprintf(stderr, "Error writing bind int to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// bind-null-arg-data: <statement-ref><index>
void SRRecBindNull(sqlite3_stmt *pStmt, int i) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRBindNull;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
if (out==-1) {
fprintf(stderr, "Error writing bind null to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
// bind-value-arg-data: <statement-ref><index><len><data> ???
void SRRecBindValue(sqlite3_stmt *pStmt, int i, const sqlite3_value *value) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
fprintf(stderr, "SRRecBindValue(sqlite3_bind_value) is not yet supported, closing [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
// bind-clear-arg-data: <statement-ref>
void SRRecClearBindings(sqlite3_stmt *pStmt) {
if (!srr_enabled) return;
if(pStmt!=NULL) {
Vdbe *v = (Vdbe *)pStmt;
SRRLogRef *ref = getLog(v->db);
if (ref && (ref->depth == 0)) {
SRRCommand code = SRRBindClear;
struct timeval tv;
size_t out;
gettimeofday(&tv, NULL);
out = write(ref->fd, &tv, sizeof(tv));
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
if (out!=-1) {
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
out = write(ref->fd, &stmtInt, sizeof(int64_t));
}
if (out==-1) {
fprintf(stderr, "Error writing clear bindings to log file [%s]: %s\n", ref->logPath, strerror(errno));
closeLog(ref->db);
}
}
}
}
#endif /* SQLITE_ENABLE_SQLRR */
+61
View File
@@ -0,0 +1,61 @@
/*
* sqlrr.h
*/
#ifndef _SQLRR_H_
#define _SQLRR_H_
/*
** Header constants
*/
#define SRR_FILE_SIGNATURE "SQLRR"
#define SRR_FILE_SIGNATURE_LEN 5
#define SRR_FILE_VERSION 0x1
#define SRR_FILE_VERSION_LEN 1
#if defined(SQLITE_ENABLE_SQLRR)
#include "sqlite3.h"
#include <sys/types.h>
#define SRRecOpen(A,B,C) if(!rc){_SRRecOpen(A,B,C);}
#define SRRecPrepare(A,B,C,D,E) if(!rc){_SRRecPrepare(A,B,C,D,E);}
typedef enum {
SRROpen = 0,
SRRClose = 1,
SRRExec = 8,
SRRBindText = 16,
SRRBindBlob = 17,
SRRBindDouble = 18,
SRRBindInt = 19,
SRRBindNull = 20,
SRRBindValue = 21,
SRRBindClear = 22,
SRRPrepare = 32,
SRRStep = 33,
SRRReset = 34,
SRRFinalize = 35
} SRRCommand;
extern void SQLiteReplayRecorder(int flag);
extern void _SRRecOpen(sqlite3 *db, const char *path, int flags);
extern void SRRecClose(sqlite3 *db);
extern void SRRecExec(sqlite3 *db, const char *sql);
extern void SRRecExecEnd(sqlite3 *db);
extern void _SRRecPrepare(sqlite3 *db, const char *sql, int nBytes, int saveSql, sqlite3_stmt *stmt);
extern void SRRecStep(sqlite3_stmt *pStmt);
extern void SRRecStepEnd(sqlite3_stmt *pStmt);
extern void SRRecReset(sqlite3_stmt *pStmt);
extern void SRRecFinalize(sqlite3_stmt *pStmt);
extern void SRRecBindText(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData);
extern void SRRecBindBlob(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData);
extern void SRRecBindDouble(sqlite3_stmt *pStmt, int i, double value);
extern void SRRecBindInt64(sqlite3_stmt *pStmt, int i, int64_t value);
extern void SRRecBindNull(sqlite3_stmt *pStmt, int i);
extern void SRRecBindValue(sqlite3_stmt *pStmt, int i, const sqlite3_value *value);
extern void SRRecClearBindings(sqlite3_stmt *pStmt);
#endif /* defined(SQLITE_ENABLE_SQLRR) */
#endif /* _SQLRR_H_ */
Executable → Regular
View File
+6 -2
View File
@@ -203,6 +203,8 @@ SRC += \
SRC += \
$(TOP)/ext/rtree/rtree.h \
$(TOP)/ext/rtree/rtree.c
SRC += \
$(TOP)/ext/sqlrr/sqlrr.c
# Generated source code files
@@ -335,6 +337,8 @@ EXTHDR += \
$(TOP)/ext/rtree/rtree.h
EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
$(TOP)/ext/sqlrr/sqlrr.h
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
@@ -356,10 +360,10 @@ sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
# files are automatically generated. This target takes care of
# all that automatic generation.
#
target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl
target_source: $(SRC) $(EXTHDR) $(TOP)/tool/vdbe-compress.tcl
rm -rf tsrc
mkdir tsrc
cp -f $(SRC) tsrc
cp -f $(SRC) $(EXTHDR) tsrc
rm tsrc/sqlite.h.in tsrc/parse.y
tclsh $(TOP)/tool/vdbe-compress.tcl <tsrc/vdbe.c >vdbe.new
mv vdbe.new tsrc/vdbe.c
+67 -72
View File
@@ -1,10 +1,7 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C The\sR-tree\smodule\sshould\snot\sassume\sthat\sits\sshadow\stables\sare\sconsistent.\nIf\sa\sproblem\sis\sfound\sin\sa\sshadow\stable,\sreturn\sSQLITE_CORRUPT.
D 2010-08-24T01:49:48
C Add\s"PRAGMA\scheckpoint_fullfsync".\sSimilar\sto\s"PRAGMA\sfullfsync",\sbut\senables\sfull\sfsyncs\sonly\sduring\scheckpoint\soperations.
D 2010-11-09T20:08:02
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 543f91f24cd7fee774ecc0a61c19704c0c3e78fd
F Makefile.in c58f7d37ad0f9b28655ba4e28c6cb0f879569cd7
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
@@ -24,7 +21,7 @@ F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure a5dab32df872ed3fe248c7f0cbc324595c169781 x
F configure a5dab32df872ed3fe248c7f0cbc324595c169781
F configure.ac 699040cc9abb7465dca5a2972bc89d227fd8f734
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
@@ -81,7 +78,7 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c 850e9a36567bbcce6bd85a4b68243cad8e3c2de2
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 1a39ad566196d2342f4a5ef337e165b7a016e6cd
F ext/rtree/rtree.c 4646fb3f52f11842450c6465af382589d8a232ab
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 51bb0cd0405970501e63258401ae5ad235a4f468
F ext/rtree/rtree2.test 7b665c44d25e51b3098068d983a39902b2e2d7a1
@@ -94,9 +91,12 @@ F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/tkt3363.test 2bf324f7908084a5f463de3109db9c6e607feb1b
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ext/sqlrr/README.txt 4239030e73023e72a2e727808cd433577d5bf730
F ext/sqlrr/sqlrr.c 8d1e6571cd6a6beabdb5bcdfe3a0e723b914db41
F ext/sqlrr/sqlrr.h 09e4f8929ad9bc2638732c0cc0db5eef8c417824
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk 26ad86cf0689940f19b3d608bbfdb3956b2fb9a7
F main.mk c65aaec3a68162beb49281cbfed56cf17f1701a1
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
@@ -128,20 +128,20 @@ F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd
F src/expr.c 9ee507c3dc6eaa5657cbd1dad026cdeda89c559f
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 58bbf52c6ddd3f64ca40a3230f9e548a83a5cb16
F src/func.c 464b0dc70618b896c402c574eb04bc5eacf35341
F src/func.c 62373e488ecf8b29a28548ff9d922a9fae36b808
F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c a4995747c062256582a90b4f87f716e11b067050
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/legacy.c 015826a958f690302d27e096a68d50b3657e4201
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
F src/loadext.c 6d422ea91cf3d2d00408c5a8f2391cd458da85f8
F src/main.c 99622181f36d68e9f2a851c7b34263b3dcd03470
F src/main.c 79573a52c9746bdc3e7942e0127556fa39cdbae5
F src/malloc.c 19a468460c7df72de245f10c06bd0625777b7c83
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 89d4ea8d5cdd55635cbaa48ad53132af6294cbb2
F src/mem1.c 0f36f1eecd786240924a56f8796ffa850d47a96f
F src/mem2.c 9e5f72e38573db9598fe60d3fa530d473cc8714e
F src/mem3.c 9b237d911ba9904142a804be727cc6664873f8a3
F src/mem5.c eb7a5cb98915dd7a086fa415ce3a5a0f20d0acff
@@ -157,16 +157,16 @@ F src/os.c 60178f518c4d6c0dcb59f7292232281d7bea2dcf
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
F src/os_unix.c 11194cbcf6a57456e58022dc537ab8c3497d9bb9
F src/os_unix.c 79cf726c9a0bcc4691a01389031513c10bf15bed
F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
F src/pager.c a5f5d9787b11dfb0b6082e6f5846d00b459a8e19
F src/pager.c b9809c31985b77437d89649b5dc351b45e01551b
F src/pager.h ef8c8f71ab022cc2fff768a1175dd32355be9dcd
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c e921e8a1d52c93abde63cb6dad1fa39770410c52
F src/pragma.c 8b24ce00a93de345b6c3bd1e1e2cfba9f63d2325
F src/prepare.c ce4c35a2b1d5fe916e4a46b70d24a6e997d7c4c6
F src/pragma.c 6a641dec2c137092ef2b7489e4943b878cf2cbfd
F src/prepare.c 23b5da0608820c9f76aa61d4955ebdbd23ffda36
F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
@@ -174,13 +174,14 @@ F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 8add6cab889fc02e1492eda8dba462ccf11f51dd
F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
F src/sqlite.h.in 2d72a6242df41c517e38eec8791abcf5484a36f1
F src/sqlite3_private.h 2a814d17913732831acf13e7e87860105a3416e4
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h e33b15e8176442bf7484f0e716edfd1ce03b2979
F src/sqliteInt.h a4231c81ff0d3767b61ca7a15268f91d778726b1
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c cacee9482417b6fc6043f6bb831ff9496d46242d
F src/test1.c 55005c9781b157b1d215ba145768783b9abae78c
F src/test1.c 6abff878520c77f10891b06c36a57b3226ebc3d4
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee
@@ -191,9 +192,9 @@ F src/test8.c 6b1d12912a04fe6fca8c45bb9c3ea022f4352228
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
F src/test_backup.c 64fd6173ad99daade1227aa17c3ca0d18fa5e5fa
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
F src/test_config.c 5a11c51af2156e2d07186930b36f2b8239a4393f
F src/test_config.c 91e758b037c7c58a6e3b3ce6babae883666174e9
F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c 13b582345fb1185a93e46c53310fae8547dcce20
@@ -221,10 +222,10 @@ F src/update.c 1521162d20c2994af1fdc8833e1a88dae09052c8
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
F src/vacuum.c 241a8386727c1497eba4955933356dfba6ff8c9f
F src/vdbe.c 66c262a923915e596379b1d597178e04c5d719e4
F src/vdbe.c 60ef76968e7ab2288ee1e39573a090e549fd8f3d
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
F src/vdbeInt.h ffd68c4d4229227a5089bec53a1c635146177abc
F src/vdbeapi.c d0f4407e465f261780ad725c1caece7d66a6aa35
F src/vdbeapi.c 232d20465aa606c12520840597361279c7a96236
F src/vdbeaux.c c73bcefcebfd3d2cf91bf6a41ef0fb0d884814c6
F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
F src/vdbemem.c e5673f81a2381b35c60e73ef0a8502be2ab1041e
@@ -250,7 +251,7 @@ F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
F test/async5.test f3592d79c84d6e83a5f50d3fd500445f7d97dfdf
F test/attach.test ce9660e51768fab93cf129787be886c5d6c4fd81
F test/attach.test ccdedd5496a0244f8e45366ba9253af30083ea84
F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437
F test/attach3.test bd9830bc3a0d22ed1310c9bff6896927937017dc
F test/attachmalloc.test 38d2da5fdaf09ba0add57296967a3061e5842584
@@ -271,7 +272,7 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test a8ec8073a20207456dab01a29ad9cde42b0dd103
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
F test/bind.test 30af0fc61bc3836034215cdbdeca46113ca1b4a1
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
@@ -351,11 +352,11 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test b1f9012cabc124af947165d15ffa62ad20f63db8
F test/exclusive.test 9e62270fdf967870921053e2ec0f293b67c140a4
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
F test/fallocate.test a9927b638567e2e776c112f54d701402a0e74023
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
F test/filefmt.test f77c92141960b7933bc6691631d2ad62257ef40a
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
@@ -474,7 +475,7 @@ F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
F test/journal2.test 50a3604768494d4a337f194f0a9480e7c57dcb72
F test/journal3.test ff175219be1b02d2f7e54297ad7e491b7533edb6
F test/journal3.test 7cfbd86429305c96c9d985665320db5364764d96
F test/jrnlmode.test e3fe6c4a2c3213d285650dc8e33aab7eaaa5ce53
F test/jrnlmode2.test a19e28de1a6ec898067e46a122f1b71c9323bf00
F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710
@@ -490,12 +491,13 @@ F test/lock.test 842e80b6be816c79525a20b098cca066989feed7
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test c82268c031d39345d05efa672f80b025481b3ae5
F test/lock5.test b2abb5e711bc59b0eae00f6c97a36ec9f458fada
F test/lock6.test 8df56060f396151777390982422c800d026e1722
F test/lock5.test d0d313f059ae5661726d3f197ba6ed8f69257d8e
F test/lock6.test 55bbfce7a6905be8282f125c2dbeb8688e2cfd8b
F test/lock7.test 64006c84c1c616657e237c7ad6532b765611cf64
F test/lock_common.tcl 18c637fc89e12f1ac0d27d2186f12c3d3f789e3e
F test/lock_proxy.test 95be9c32d79be25cf643b4e41a0aa0e53aa21621
F test/lookaside.test 382e7bc2fab23d902c8eafb1b9ed7ababfff75a6
F test/main.test 9d7bbfcc1b52c88ba7b2ba6554068ecf9939f252
F test/main.test 753e2b772c041bd8dbd17c7e4132b3981378eaab
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 927e6c8668a1d48c23aa6189bda02aff5a1b83de
F test/malloc3.test 4bc57f850b212f706f3e1b37c4eced1d5a727cd1
@@ -517,11 +519,11 @@ F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9
F test/malloc_common.tcl f4a04b7a733eb114a3da16eb39035cde2c851220
F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c
F test/memdb.test 0825155b2290e900264daaaf0334b6dfe69ea498
F test/malloc_common.tcl bd0b0916f03cb4f4c973bcb793f3057e84d5ecfb
F test/manydb.test 7faa0df55bbab2b14c25f323801db336c4e7ce3a
F test/memdb.test f773146f66ee2c635854a8264317f39a6cc3e18c
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 8fb47b7e2523f94c100f5885c5697505524de4b9
F test/memsubsys1.test 98d5ff4c9f534cc863c07b74043bd44921893f29
F test/memsubsys2.test 72a731225997ad5e8df89fdbeae9224616b6aecc
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
@@ -543,17 +545,17 @@ F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
F test/pager1.test 6922029d71a8090169c71a67a141b6b94ad17d50
F test/pager1.test 4d3bf78c043af2054cfb63897ef3f990a420c6a5
F test/pager2.test 0fbb6b6dc40ce1fecfe758c555a748ad2e9beaa3
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pagerfault.test 84c6a4fcfe1a9e450fc1cec86f5baebfb017e53e
F test/pagerfault.test f168ec2c659faccffc083ec1847bf4295dd67d14
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test 17498d1219f922d5a6da893a94c4dc7766fb2426
F test/pragma.test ed78d200f65c6998df51196cb8c39d5300570f24
F test/pragma.test 421476c181fe8ddb528dcaac8b043aa1544983df
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
@@ -591,7 +593,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b
F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e
F test/shared.test e5ed27551ba06b28e851101683f0caef1445f4ac
F test/shared2.test d6ba4ca1827ea36a1ac23a99e3c36eeac9165450
F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962
F test/shared4.test d0fadacb50bb6981b2fb9dc6d1da30fa1edddf83
@@ -613,8 +615,8 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/sqllimits1.test e90a0ed94452076f6a10209d378e06b5f75ef0a0
F test/stat.test 70fe540ffb285947aead5533dfd0c8c12f17f14e
F test/stmt.test 7915bd3e8380b956c095f40f41a775a30716e649
F test/stat.test 8b7342007bdb49a9427d57a9bb94d02d6e54f2d0
F test/stmt.test 8e39760750cdf8044d4ca441b2b95053817c9a5f
F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
@@ -622,10 +624,10 @@ F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
F test/table.test 04ba066432430657712d167ebf28080fe878d305
F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516
F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3
F test/tempdb.test 800c36623d67a2ad1f58784b9c5644e0405af6e6
F test/tempdb.test 285dda9fdf10730702549e8aa19c9258bbf753b8
F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
F test/tester.tcl 6135019fcfac363ea0e11aee670cc97080ab578e
F test/tester.tcl e4bed769a9e7b55d569fe90e9548fc86d405acf8
F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f
F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db
F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca
@@ -705,7 +707,7 @@ F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed
F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b
F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812
F test/tkt3442.test 89d7b41a4ec4d9d9b40ab8575d648579fb13cb4f
F test/tkt3457.test edbf54b05cbe5165f00192becbd621038f1615e4
F test/tkt3457.test 8a8f29536bf65b994bef5dde881404530b61a62a
F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d
@@ -787,22 +789,22 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
F test/wal.test 70227190e713b3e7eb2a7d5ec3510b66db01f327
F test/wal2.test 223f3e14d475730af772a7f5862d4bcfa7565c3a
F test/wal3.test 695ea0f6c516423c611891df9a285aacd33344e3
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
F test/wal.test d83c3d227e9e9bb5c7a0c1447ea4a3c6cd5fced4
F test/wal2.test 03f5f0e14cf26120d2bc2daedb6952a93b981c8e
F test/wal3.test 09278a6f54b3a847b502f426a63a0a3028c4e57e
F test/wal4.test 6a68c45bc1ca24a3592ec449ddcb92b29d0e0e87
F test/wal_common.tcl 895d76138043b86bdccf36494054bdabcf65837b
F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0
F test/walcksum.test a37b36375c595e61bdb7e1ec49b5f0979b6fc7ce
F test/walcrash.test e763841551d6b23677ccb419797c1589dcbdbaf5
F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
F test/walfault.test 05c470688d742688e455dd56816bd6bcffa298f8
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4ecd37284f245247f7935896ab66f6943f0432a0
F test/walshared.test 985b4a3406b2b2dace1d52a42d26a11dd6900981
F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c
F test/walbak.test 767e1c9e0ea0cfb907873b332883e66e187fa4bc
F test/walbig.test 78ac493db2abdb65b9c6cace5b851cc32df1d449
F test/walcksum.test cf6787f2ee1a6a3da6f0c2b20b9ede5153e4e03f
F test/walcrash.test 80c1cc3173a0ef09d8303fa556cb0187a36d82ea
F test/walcrash2.test 929c99d14ee2e3e3ef82585058968a8b12f72706
F test/walfault.test 60527645638532a565a8e729db287ef0dba85ece
F test/walhook.test c934ac5219fee2b4e7653d291db9107b8dc73bba
F test/walmode.test 8746ec81f78597e0f988d8e31347dc1b9b22ebbd
F test/walshared.test 51082db7d1edc720256c524e9b22e92c50f72149
F test/walslow.test 989854bc5c214700a9f2d545bb158643813b8881
F test/walthread.test e6e32e93ccebfa401dfc0dd930c79daa3472b0ae
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 3bf8006d441b66a57bee02bb420423f84eb8fde3
@@ -826,7 +828,7 @@ F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c.tcl aff0d53f0e84cf919922c0d02e767bdf5eeafb90
F tool/mksqlite3c.tcl be5206d081291aa4c0e1a328331171425bdbe77c
F tool/mksqlite3h.tcl eb100dce83f24b501b325b340f8b5eb8e5106b3b
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
@@ -849,14 +851,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 42537b60566f288167f1b5864a5435986838e3a3
R 2c180f83601b5fb3eca266f1d7990e7f
U drh
Z 10d60dee314996598be1db5d0c7786c6
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMcyU/oxKgR168RlERAix8AJ4mlLsRwIdCGZXuMMz9jxnrImU9JACffIYe
yL2XIDq+iw10tkqZ3HaRjys=
=n6uZ
-----END PGP SIGNATURE-----
P f59949fac1776ea2f58f41ee8aef8dd95b67725a
R 10ec051ad734b09d2ce7d88de83d010e
U dan
Z 13849545f92827f8d5abaf3d106e2e3f
+1 -1
View File
@@ -1 +1 @@
7f2f71cc9e3c39093f09231f448576cff6afb5fe
756589ad6e286a898ca34ff1b14d5bb4843529e1
+3
View File
@@ -207,6 +207,9 @@ static void substrFunc(
}
}
}
#ifdef SQLITE_SUBSTR_COMPATIBILITY
if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
#endif
if( argc==3 ){
p2 = sqlite3_value_int(argv[2]);
if( p2<0 ){
+9 -1
View File
@@ -16,6 +16,9 @@
*/
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_SQLRR
# include "sqlrr.h"
#endif
/*
** Execute SQL code. Return one of the SQLITE_ success/failure
@@ -43,7 +46,9 @@ int sqlite3_exec(
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
if( zSql==0 ) zSql = "";
#ifdef SQLITE_ENABLE_SQLRR
SRRecExec(db, zSql);
#endif
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK, 0);
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
@@ -124,6 +129,9 @@ int sqlite3_exec(
exec_out:
if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
sqlite3DbFree(db, azCols);
#ifdef SQLITE_ENABLE_SQLRR
SRRecExecEnd(db);
#endif
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
+25
View File
@@ -16,6 +16,9 @@
*/
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_SQLRR
# include "sqlrr.h"
#endif
#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
@@ -717,6 +720,10 @@ int sqlite3_close(sqlite3 *db){
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
#ifdef SQLITE_ENABLE_SQLRR
SRRecClose(db);
#endif
sqlite3_free(db);
return SQLITE_OK;
}
@@ -1658,6 +1665,12 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
}
return oldLimit;
}
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
static void profile_sql(void *aux, const char *sql, u64 ns) {
#pragma unused(aux)
fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000);
}
#endif
/*
** This routine does the work of opening a database on behalf of
@@ -1890,7 +1903,19 @@ opendb_out:
}else if( rc!=SQLITE_OK ){
db->magic = SQLITE_MAGIC_SICK;
}
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
if( db && !rc ){
char *envprofile = getenv("SQLITE_AUTO_PROFILE");
if( envprofile!=NULL ){
sqlite3_profile(db, profile_sql, NULL);
}
}
#endif
*ppDb = db;
#ifdef SQLITE_ENABLE_SQLRR
SRRecOpen(db, zFilename, flags);
#endif
return sqlite3ApiExit(0, rc);
}
+71 -3
View File
@@ -26,6 +26,28 @@
*/
#ifdef SQLITE_SYSTEM_MALLOC
#if (!defined(__APPLE__))
#define SQLITE_MALLOC(x) malloc(x)
#define SQLITE_FREE(x) free(x)
#define SQLITE_REALLOC(x,y) realloc((x),(y))
#else
#include <sys/sysctl.h>
#include <malloc/malloc.h>
#include <libkern/OSAtomic.h>
static malloc_zone_t* _sqliteZone_;
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
#endif
/*
** Like malloc(), but remember the size of the allocation
** so that we can find it later using sqlite3MemSize().
@@ -38,7 +60,7 @@ static void *sqlite3MemMalloc(int nByte){
sqlite3_int64 *p;
assert( nByte>0 );
nByte = ROUND8(nByte);
p = malloc( nByte+8 );
p = SQLITE_MALLOC( nByte+8 );
if( p ){
p[0] = nByte;
p++;
@@ -61,7 +83,7 @@ static void sqlite3MemFree(void *pPrior){
sqlite3_int64 *p = (sqlite3_int64*)pPrior;
assert( pPrior!=0 );
p--;
free(p);
SQLITE_FREE(p);
}
/*
@@ -91,7 +113,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
assert( pPrior!=0 && nByte>0 );
nByte = ROUND8(nByte);
p--;
p = realloc(p, nByte+8 );
p = SQLITE_REALLOC(p, nByte+8 );
if( p ){
p[0] = nByte;
p++;
@@ -115,6 +137,37 @@ static int sqlite3MemRoundup(int n){
** Initialize this module.
*/
static int sqlite3MemInit(void *NotUsed){
#if defined(__APPLE__)
if (_sqliteZone_) {
return SQLITE_OK;
}
int cpuCount;
size_t len;
len = sizeof(cpuCount);
sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); // one almost always wants to use "hw.activecpu" for MT decisions, but not here.
if (cpuCount > 1) {
// defer MT decisions to system malloc
_sqliteZone_ = malloc_default_zone();
} else {
// only 1 core, use our own zone to contention over global locks,
// e.g. we have our own dedicated locks
malloc_zone_t* newzone = malloc_create_zone(4096, 0);
malloc_set_zone_name(newzone, "Sqlite_Heap");
bool success;
do {
success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, (void * volatile *)&_sqliteZone_);
} while (!_sqliteZone_);
if (!success) {
// somebody registered a zone first
malloc_destroy_zone(newzone);
}
}
#endif
UNUSED_PARAMETER(NotUsed);
return SQLITE_OK;
}
@@ -123,6 +176,17 @@ static int sqlite3MemInit(void *NotUsed){
** Deinitialize this module.
*/
static void sqlite3MemShutdown(void *NotUsed){
#if (0 && defined(__APPLE__))
if (_sqliteZone_ && (_sqliteZone_ != malloc_default_zone())) {
malloc_zone_t* oldzone = _sqliteZone_;
bool success = OSAtomicCompareAndSwapPtrBarrier(oldzone, NULL, (void * volatile *)&_sqliteZone_);
if (success) {
malloc_destroy_zone(oldzone);
}
}
#endif
UNUSED_PARAMETER(NotUsed);
return;
}
@@ -147,4 +211,8 @@ void sqlite3MemSetDefault(void){
sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
}
#undef SQLITE_MALLOC
#undef SQLITE_FREE
#undef SQLITE_REALLOC
#endif /* SQLITE_SYSTEM_MALLOC */
+298 -26
View File
@@ -2808,6 +2808,12 @@ int sqlite3_fullsync_count = 0;
# define HAVE_FULLFSYNC 0
#endif
#ifdef SQLITE_USE_REQUEST_FULLFSYNC
#import <notify.h>
#import <libkern/OSAtomic.h>
static OSSpinLock notify_lock = 0;
#define REQUEST_FULLSYNC_NOTIFICATION "com.apple.reqsync"
#endif
/*
** The fsync() system call does not work as advertised on many
@@ -2867,7 +2873,16 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
rc = SQLITE_OK;
#elif HAVE_FULLFSYNC
if( fullSync ){
#ifdef SQLITE_USE_REQUEST_FULLFSYNC
rc = fsync(fd);
if (!rc) {
OSSpinLockLock(&notify_lock);
rc = notify_post(REQUEST_FULLSYNC_NOTIFICATION);
OSSpinLockUnlock(&notify_lock);
}
#else
rc = fcntl(fd, F_FULLFSYNC, 0);
#endif
}else{
rc = 1;
}
@@ -3096,6 +3111,12 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
return SQLITE_OK;
}
#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
#include "sqlite3_private.h"
#include <copyfile.h>
static int getDbPathForUnixFile(unixFile *pFile, char *dbPath);
#endif
/*
** Information and control of an open file handle.
*/
@@ -3133,6 +3154,219 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
case SQLITE_TRUNCATE_DATABASE: {
unixFile *pFile = (unixFile*)id;
int trc = SQLITE_OK;
int eFileLock = pFile->eFileLock;
int rc = SQLITE_OK;
char jPath[MAXPATHLEN+9];
size_t jLen;
if( eFileLock<SQLITE_LOCK_SHARED ){
rc = pFile->pMethod->xLock(id, SQLITE_LOCK_SHARED);
}
if( !rc && eFileLock<SQLITE_LOCK_EXCLUSIVE ){
rc = pFile->pMethod->xLock(id, SQLITE_LOCK_EXCLUSIVE);
}
if( rc ){
if( pFile->eFileLock > eFileLock ){
pFile->pMethod->xUnlock(id, eFileLock);
}
return rc;
}
rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L);
if( !rc && (SQLITE_OK==getDbPathForUnixFile(pFile, jPath)) ){
jLen = strlcat(jPath, "-journal", MAXPATHLEN+9);
if( jLen < MAXPATHLEN+9 ){
int jfd = open(jPath, O_TRUNC);
if( (jfd == -1) ){
if ( errno!=ENOENT ){
perror(jPath);
}
} else {
fsync(jfd);
close(jfd);
}
}
}else{
trc=rc;
}
if( !trc ){
trc = pFile->pMethod->xSync(id, SQLITE_SYNC_FULL);
}
if( pFile->eFileLock > eFileLock ){
int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_SHARED);
if (!rc) rc = unlockRC;
}
if( pFile->eFileLock > eFileLock ){
int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_NONE);
if (!rc) rc = unlockRC;
}
if( trc ){
return trc;
}
return rc;
}
case SQLITE_REPLACE_DATABASE: {
unixFile *pFile = (unixFile*)id;
int trc = SQLITE_OK;
int eFileLock = pFile->eFileLock;
int rc = SQLITE_OK;
char jPath[MAXPATHLEN+9];
size_t jLen;
sqlite3 *srcdb = (sqlite3 *)pArg;
Btree *pSrcBtree = NULL;
int eSrcFileLock = SQLITE_LOCK_NONE;
int srcLockRC = -1;
sqlite3_file *src_file = NULL;
unixFile *pSrcFile = NULL;
if( !sqlite3SafetyCheckOk(srcdb) ){
return SQLITE_MISUSE;
}
if( eFileLock<SQLITE_LOCK_SHARED ){
rc = pFile->pMethod->xLock(id, SQLITE_LOCK_SHARED);
}
if( !rc && eFileLock<SQLITE_LOCK_EXCLUSIVE ){
rc = pFile->pMethod->xLock(id, SQLITE_LOCK_EXCLUSIVE);
}
if( !rc ){
/* get the src file descriptor adhering to the db struct access rules
** this code is modeled after sqlite3_file_control() in main.c
*/
sqlite3_mutex_enter(srcdb->mutex);
if( srcdb->nDb>0 ){
pSrcBtree = srcdb->aDb[0].pBt;
}
if( pSrcBtree ){
Pager *pSrcPager;
sqlite3BtreeEnter(pSrcBtree);
pSrcPager = sqlite3BtreePager(pSrcBtree);
assert( pSrcPager!=0 );
src_file = sqlite3PagerFile(pSrcPager);
assert( src_file!=0 );
if( src_file->pMethods ){
pSrcFile = (unixFile *)src_file;
eSrcFileLock = pSrcFile->eFileLock;
if( eSrcFileLock<SQLITE_LOCK_SHARED ){
rc = pSrcFile->pMethod->xLock(src_file, SQLITE_LOCK_SHARED);
srcLockRC = rc; /* SQLITE_OK means we need to unlock later */
} else if( eSrcFileLock==SQLITE_LOCK_EXCLUSIVE ){
/* if the src database has an exclusive lock, verify that the
** it doesn't have a journal file with open transactions
*/
if( getDbPathForUnixFile(pSrcFile, jPath) ){
rc = SQLITE_INTERNAL;
}else{
jLen = strlcat(jPath, "-journal", MAXPATHLEN+9);
if( jLen < MAXPATHLEN+9 ){
int jfd = open(jPath, O_RDONLY);
if( jfd==-1 ){
if( errno!=ENOENT ){
pFile->lastErrno = errno;
rc = SQLITE_IOERR;
}
}else{
/* if the journal exists ensure there's no pending
** transaction by checking the journal header */
char magic[8];
ssize_t rlen = pread(jfd, magic, 8, 0);
if( rlen<0 ){
pFile->lastErrno = errno;
rc = SQLITE_IOERR;
}else if( rlen==8 ){
char test[8] = {'\0','\0','\0','\0','\0','\0','\0','\0'};
if( memcmp(magic,test,8) ){
rc = SQLITE_LOCKED;
}
}else if( rlen!=0 ){
rc = SQLITE_INTERNAL;
}
close(jfd);
}
}
}
}
}else{
rc = SQLITE_MISUSE;
}
if( rc ){
if( srcLockRC==SQLITE_OK ){
pSrcFile->pMethod->xUnlock(src_file, eSrcFileLock);
}
sqlite3BtreeLeave(pSrcBtree);
}
}
if( pSrcFile==NULL || (pSrcFile->h<0) ){
rc = SQLITE_INTERNAL;
sqlite3_mutex_leave(srcdb->mutex);
}
}
if( rc ){
/* unroll state changes and return error code */
if( pFile->eFileLock > eFileLock ){
pFile->pMethod->xUnlock(id, eFileLock);
}
return rc;
}else{
/* both databases are locked appropriately, copy file data
** and then unroll the locks we added.
*/
copyfile_state_t s;
s = copyfile_state_alloc();
if( fcopyfile(pSrcFile->h, pFile->h, s, COPYFILE_ALL) ){
switch(errno) {
case ENOMEM:
rc = SQLITE_NOMEM;
break;
default:
rc = SQLITE_INTERNAL;
}
}
copyfile_state_free(s);
if( srcLockRC==SQLITE_OK ){
pSrcFile->pMethod->xUnlock(src_file, eSrcFileLock);
}
sqlite3BtreeLeave(pSrcBtree);
sqlite3_mutex_leave(srcdb->mutex);
}
if( !rc && (SQLITE_OK==getDbPathForUnixFile(pFile, jPath)) ){
jLen = strlcat(jPath, "-journal", MAXPATHLEN+9);
if( jLen < MAXPATHLEN+9 ){
int jfd = open(jPath, O_TRUNC);
if( (jfd == -1) ){
if ( errno!=ENOENT ){
perror(jPath);
}
} else {
fsync(jfd);
close(jfd);
}
}
}else{
trc=rc;
}
if( !trc ){
trc = pFile->pMethod->xSync(id, SQLITE_SYNC_FULL);
}
if( pFile->eFileLock > eFileLock ){
int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_SHARED);
if (!rc) rc = unlockRC;
}
if( pFile->eFileLock > eFileLock ){
int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_NONE);
if (!rc) rc = unlockRC;
}
if( trc ){
return trc;
}
return rc;
}
#endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */
}
return SQLITE_ERROR;
}
@@ -3335,6 +3569,9 @@ static void unixShmPurge(unixFile *pFd){
}
}
static int isProxyLockingMode(unixFile *);
static const char *proxySharedMemoryBasePath(unixFile *);
/*
** Open a shared-memory area associated with open database file pDbFd.
** This particular implementation uses mmapped files.
@@ -3397,10 +3634,24 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
goto shm_open_err;
}
const char *zBasePath = pDbFd->zPath;
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
/* If pDbFd is configured with proxy locking mode, use the local
** lock file path to determine the -shm file path
*/
if( isProxyLockingMode(pDbFd) ){
zBasePath = proxySharedMemoryBasePath(pDbFd);
if( !zBasePath ){
rc = SQLITE_CANTOPEN_BKPT;
goto shm_open_err;
}
}
#endif
#ifdef SQLITE_SHM_DIRECTORY
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30;
#else
nShmFilename = 5 + (int)strlen(pDbFd->zPath);
nShmFilename = 5 + (int)strlen(zBasePath);
#endif
pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
@@ -3414,7 +3665,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
#endif
pShmNode->h = -1;
pDbFd->pInode->pShmNode = pShmNode;
@@ -3916,7 +4167,7 @@ static int proxyCheckReservedLock(sqlite3_file*, int*);
IOMETHODS(
proxyIoFinder, /* Finder function name */
proxyIoMethods, /* sqlite3_io_methods object name */
1, /* shared memory is disabled */
2, /* shared memory is enabled */
proxyClose, /* xClose method */
proxyLock, /* xLock method */
proxyUnlock, /* xUnlock method */
@@ -4636,6 +4887,9 @@ static int unixOpen(
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
}
if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
}
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
@@ -4651,35 +4905,24 @@ static int unixOpen(
if( envforce!=NULL ){
useProxy = atoi(envforce)>0;
}else{
struct statfs fsInfo;
if( statfs(zPath, &fsInfo) == -1 ){
/* In theory, the close(fd) call is sub-optimal. If the file opened
** with fd is a database file, and there are other connections open
** on that file that are currently holding advisory locks on it,
** then the call to close() will cancel those locks. In practice,
** we're assuming that statfs() doesn't fail very often. At least
** not while other file descriptors opened by the same process on
** the same file are working. */
p->lastErrno = errno;
if( dirfd>=0 ){
close(dirfd); /* silently leak if fail, in error */
}
close(fd); /* silently leak if fail, in error */
rc = SQLITE_IOERR_ACCESS;
goto open_finished;
}
useProxy = !(fsInfo.f_flags&MNT_LOCAL);
}
if( useProxy ){
rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
if( rc==SQLITE_OK ){
/* cache the pMethod in case the transform fails */
const struct sqlite3_io_methods *pMethod = pFile->pMethods;
rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
if( rc!=SQLITE_OK ){
/* Use unixClose to clean up the resources added in fillInUnixFile
** and clear all the structure's references. Specifically,
** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op
*/
unixClose(pFile);
if( pMethod!=NULL ){
pMethod->xClose(pFile);
}else{
unixClose(pFile);
}
return rc;
}
}
@@ -5276,6 +5519,28 @@ static int proxyCreateLockPath(const char *lockPath){
return 0;
}
static int isProxyLockingMode(unixFile *pFile) {
return (pFile->pMethod == &proxyIoMethods) ? 1 : 0;
}
/*
** Return the shared memory base path based on the lock proxy file if the
** lock proxy file is hosted on a shared memory compatible FS
*/
static const char *proxySharedMemoryBasePath(unixFile *pFile) {
proxyLockingContext *pCtx;
unixFile *pLockFile;
assert(pFile!=NULL && pFile->lockingContext!=NULL);
assert(pFile->pMethod == &proxyIoMethods);
pCtx = ((proxyLockingContext *)(pFile->lockingContext));
pLockFile = pCtx->lockProxy;
if( pLockFile->pMethod->iVersion>=2 && pLockFile->pMethod->xShmMap!=0 ){
return pCtx->lockProxyPath;
}
return NULL;
}
/*
** Create a new VFS file descriptor (stored in memory obtained from
** sqlite3_malloc) and open the file named "path" in the file descriptor.
@@ -5327,6 +5592,7 @@ static int proxyCreateUnixFile(
terrno = errno;
}
if( fd<0 ){
sqlite3_free(pUnused);
if( islockfile ){
return SQLITE_BUSY;
}
@@ -5876,7 +6142,7 @@ static int switchLockProxyPath(unixFile *pFile, const char *path) {
** This routine find the filename associated with pFile and writes it
** int dbPath.
*/
static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
static int getDbPathForUnixFile(unixFile *pFile, char *dbPath){
#if defined(__APPLE__)
if( pFile->pMethod == &afpIoMethods ){
/* afp style keeps a reference to the db path in the filePath field
@@ -5915,7 +6181,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
if( pFile->eFileLock!=NO_LOCK ){
return SQLITE_BUSY;
}
proxyGetDbPathForUnixFile(pFile, dbPath);
getDbPathForUnixFile(pFile, dbPath);
if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
lockPath=NULL;
}else{
@@ -5958,6 +6224,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
}
if( rc==SQLITE_OK && lockPath ){
pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
if( pCtx->lockProxyPath==NULL ){
rc = SQLITE_NOMEM;
}
}
if( rc==SQLITE_OK ){
@@ -5997,7 +6266,7 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
switch( op ){
case SQLITE_GET_LOCKPROXYFILE: {
unixFile *pFile = (unixFile*)id;
if( pFile->pMethod == &proxyIoMethods ){
if( isProxyLockingMode(pFile) ){
proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
proxyTakeConch(pFile);
if( pCtx->lockProxyPath ){
@@ -6013,10 +6282,13 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
case SQLITE_SET_LOCKPROXYFILE: {
unixFile *pFile = (unixFile*)id;
int rc = SQLITE_OK;
int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
int isProxyStyle = isProxyLockingMode(pFile);
if( pArg==NULL || (const char *)pArg==0 ){
if( isProxyStyle ){
/* turn off proxy locking - not supported */
/* turn off proxy locking - not supported. If support is added for
** switching proxy locking mode off then it will need to fail if
** the journal mode is WAL mode.
*/
rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
}else{
/* turn off proxy locking - already off - NOOP */
+27 -11
View File
@@ -619,6 +619,7 @@ struct Pager {
u8 tempFile; /* zFilename is a temporary file */
u8 readOnly; /* True for a read-only database */
u8 memDb; /* True to inhibit all file I/O */
u8 ckptFullSync; /* True to pass SYNC_FULL to WalCheckpoint() */
/**************************************************************************
** The following block contains those class members that change during
@@ -3082,6 +3083,19 @@ static int pagerOpenWalIfPresent(Pager *pPager){
}
return rc;
}
/*
** Return the value of the flags parameter that should be passed to
** sqlite3OsSync() when checkpointing a WAL file.
*/
static int walCkptSyncFlags(Pager *pPager){
int flags = 0;
if( pPager->noSync==0 ){
flags = pPager->sync_flags | (pPager->ckptFullSync?SQLITE_SYNC_FULL:0);
}
return flags;
}
#endif
/*
@@ -3262,10 +3276,16 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int fullFsync){
assert( 0==(fullFsync & ~(SQLITE_FullFSync|SQLITE_CkptFullFSync)) );
pPager->noSync = (level==1 || pPager->tempFile) ?1:0;
pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
if( fullFsync & SQLITE_FullFSync ){
pPager->sync_flags = SQLITE_SYNC_FULL;
}else{
pPager->sync_flags = SQLITE_SYNC_NORMAL;
}
pPager->ckptFullSync = (fullFsync & SQLITE_CkptFullFSync)!=0;
}
#endif
@@ -3651,8 +3671,7 @@ int sqlite3PagerClose(Pager *pPager){
/* pPager->errCode = 0; */
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
sqlite3WalClose(pPager->pWal,
(pPager->noSync ? 0 : pPager->sync_flags),
sqlite3WalClose(pPager->pWal, walCkptSyncFlags(pPager),
pPager->pageSize, pTmp
);
pPager->pWal = 0;
@@ -6521,10 +6540,8 @@ int sqlite3PagerCheckpoint(Pager *pPager){
int rc = SQLITE_OK;
if( pPager->pWal ){
u8 *zBuf = (u8 *)pPager->pTmpSpace;
rc = sqlite3WalCheckpoint(pPager->pWal,
(pPager->noSync ? 0 : pPager->sync_flags),
pPager->pageSize, zBuf
);
int flags = walCkptSyncFlags(pPager);
rc = sqlite3WalCheckpoint(pPager->pWal, flags, pPager->pageSize, zBuf);
}
return rc;
}
@@ -6629,9 +6646,8 @@ int sqlite3PagerCloseWal(Pager *pPager){
if( rc==SQLITE_OK && pPager->pWal ){
rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
if( rc==SQLITE_OK ){
rc = sqlite3WalClose(pPager->pWal,
(pPager->noSync ? 0 : pPager->sync_flags),
pPager->pageSize, (u8*)pPager->pTmpSpace
rc = sqlite3WalClose(pPager->pWal, walCkptSyncFlags(pPager),
pPager->pageSize, (u8*)pPager->pTmpSpace
);
pPager->pWal = 0;
}else{
+28 -21
View File
@@ -142,12 +142,12 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 *pValue){
Vdbe *v = sqlite3GetVdbe(pParse);
int mem = ++pParse->nMem;
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(*pValue));
if( pI64 ){
memcpy(pI64, &value, sizeof(value));
memcpy(pI64, pValue, sizeof(*pValue));
}
sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
sqlite3VdbeSetNumCols(v, 1);
@@ -172,6 +172,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
{ "empty_result_callbacks", SQLITE_NullCallback },
{ "legacy_file_format", SQLITE_LegacyFileFmt },
{ "fullfsync", SQLITE_FullFSync },
{ "checkpoint_fullfsync", SQLITE_CkptFullFSync },
{ "reverse_unordered_selects", SQLITE_ReverseOrder },
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
{ "automatic_index", SQLITE_AutoIndex },
@@ -209,7 +210,8 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
assert( v!=0 ); /* Already allocated by sqlite3Pragma() */
if( ALWAYS(v) ){
if( zRight==0 ){
returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
i64 value = ((db->flags & p->mask)!=0 ? 1 : 0);
returnSingleInt(pParse, p->zName, &value);
}else{
int mask = p->mask; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
@@ -406,8 +408,8 @@ void sqlite3Pragma(
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
returnSingleInt(pParse, "page_size", size);
i64 size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
returnSingleInt(pParse, "page_size", &size);
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
@@ -430,15 +432,15 @@ void sqlite3Pragma(
*/
if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){
Btree *pBt = pDb->pBt;
int newMax = 0;
i64 newMax = 0;
assert( pBt!=0 );
if( zRight ){
newMax = atoi(zRight);
}
if( ALWAYS(pBt) ){
newMax = sqlite3BtreeMaxPageCount(pBt, newMax);
newMax = sqlite3BtreeMaxPageCount(pBt, (int)newMax);
}
returnSingleInt(pParse, "max_page_count", newMax);
returnSingleInt(pParse, "max_page_count", &newMax);
}else
/*
@@ -451,7 +453,7 @@ void sqlite3Pragma(
*/
if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){
Btree *pBt = pDb->pBt;
int b = -1;
sqlite3_int64 b = -1;
assert( pBt!=0 );
if( zRight ){
b = getBoolean(zRight);
@@ -463,7 +465,7 @@ void sqlite3Pragma(
}
}
b = sqlite3BtreeSecureDelete(pBt, b);
returnSingleInt(pParse, "secure_delete", b);
returnSingleInt(pParse, "secure_delete", &b);
}else
/*
@@ -591,7 +593,7 @@ void sqlite3Pragma(
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
returnSingleInt(pParse, "journal_size_limit", iLimit);
returnSingleInt(pParse, "journal_size_limit", &iLimit);
}else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
@@ -611,13 +613,13 @@ void sqlite3Pragma(
goto pragma_out;
}
if( !zRight ){
int auto_vacuum;
i64 auto_vacuum;
if( ALWAYS(pBt) ){
auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt);
}else{
auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM;
}
returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
returnSingleInt(pParse, "auto_vacuum", &auto_vacuum);
}else{
int eAuto = getAutoVacuum(zRight);
assert( eAuto>=0 && eAuto<=2 );
@@ -699,7 +701,8 @@ void sqlite3Pragma(
if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
if( !zRight ){
returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
i64 cacheSize = pDb->pSchema->cache_size;
returnSingleInt(pParse, "cache_size", &cacheSize);
}else{
int size = atoi(zRight);
if( size<0 ) size = -size;
@@ -721,7 +724,8 @@ void sqlite3Pragma(
*/
if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
if( !zRight ){
returnSingleInt(pParse, "temp_store", db->temp_store);
i64 tempStore = db->temp_store;
returnSingleInt(pParse, "temp_store", &tempStore);
}else{
changeTempStorage(pParse, zRight);
}
@@ -835,7 +839,8 @@ void sqlite3Pragma(
if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
if( !zRight ){
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
i64 safetyLevel = pDb->safety_level-1;
returnSingleInt(pParse, "synchronous", &safetyLevel);
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
@@ -1411,13 +1416,15 @@ void sqlite3Pragma(
** of N.
*/
if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){
i64 walArg = 0;
if( zRight ){
int nAuto = atoi(zRight);
sqlite3_wal_autocheckpoint(db, nAuto);
}
returnSingleInt(pParse, "wal_autocheckpoint",
db->xWalCallback==sqlite3WalDefaultHook ?
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
if( db->xWalCallback==sqlite3WalDefaultHook ){
walArg = SQLITE_PTR_TO_INT(db->pWalArg);
}
returnSingleInt(pParse, "wal_autocheckpoint", &walArg);
}else
#endif
@@ -1503,7 +1510,7 @@ void sqlite3Pragma(
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
if( db->autoCommit ){
sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
(db->flags&SQLITE_FullFSync)!=0);
db->flags&(SQLITE_FullFSync|SQLITE_CkptFullFSync));
}
#endif
pragma_out:
+12 -1
View File
@@ -14,6 +14,9 @@
** from disk.
*/
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_SQLRR
# include "sqlrr.h"
#endif
/*
** Fill the InitData structure with an error message that indicates
@@ -761,6 +764,9 @@ int sqlite3_prepare(
){
int rc;
rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
#ifdef SQLITE_ENABLE_SQLRR
SRRecPrepare(db, zSql, nBytes, 0, *ppStmt);
#endif
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
@@ -773,6 +779,9 @@ int sqlite3_prepare_v2(
){
int rc;
rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
#ifdef SQLITE_ENABLE_SQLRR
SRRecPrepare(db, zSql, nBytes, 1, *ppStmt);
#endif
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
@@ -808,7 +817,9 @@ static int sqlite3Prepare16(
if( zSql8 ){
rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
}
#ifdef SQLITE_ENABLE_SQLRR
SRRecPrepare(db, zSql8, -1, 1, *ppStmt);
#endif
if( zTail8 && pzTail ){
/* If sqlite3_prepare returns a tail pointer, we calculate the
** equivalent pointer into the UTF-16 string by counting the unicode
+21
View File
@@ -0,0 +1,21 @@
/*
* sqlite3_private.h
*/
#ifndef _SQLITE3_PRIVATE_H
#define _SQLITE3_PRIVATE_H
/*
** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control()
** to truncate a database and its associated journal file to zero length.
*/
#define SQLITE_TRUNCATE_DATABASE 101
/*
** Pass the SQLITE_REPLACE_DATABASE operation code to sqlite3_file_control()
** and a sqlite3 pointer to another open database file to safely copy the
** contents of that database file into the receiving database.
*/
#define SQLITE_REPLACE_DATABASE 102
#endif
+1
View File
@@ -914,6 +914,7 @@ struct sqlite3 {
#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */
#define SQLITE_CkptFullFSync 0x20000000 /* Use full fsync on checkpoint */
/*
** Bits of the sqlite3.flags field that are used by the
+112
View File
@@ -3138,6 +3138,24 @@ static int test_clear_bindings(
return TCL_OK;
}
/*
** Usage: sqlite3_clear_bindings STMT
**
*/
static int test_clear_bindings_null(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
if( objc!=1 ){
return TCL_ERROR;
}
/* test for handling NULL <rdar://problem/6646331> */
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(0)));
return TCL_OK;
}
/*
** Usage: sqlite3_sleep MILLISECONDS
*/
@@ -4721,6 +4739,97 @@ static int file_control_lockproxy_test(
return TCL_OK;
}
#ifdef __APPLE__
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/errno.h>
#endif
/*
** tclcmd: path_is_local PWD
*/
static int path_is_local(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
const char *zPath;
int nPath;
if( objc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
return TCL_ERROR;
}
zPath = Tcl_GetStringFromObj(objv[1], &nPath);
#ifdef __APPLE__
{
struct statfs fsInfo;
if( statfs(zPath, &fsInfo) == -1 ){
int err = errno;
Tcl_AppendResult(interp, "Error calling statfs on path",
Tcl_NewIntObj(err), 0);
return TCL_ERROR;
}
if( fsInfo.f_flags&MNT_LOCAL ){
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
} else {
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
}
}
#else
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
#endif
return TCL_OK;
}
/*
** tclcmd: path_is_dos PWD
*/
static int path_is_dos(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
const char *zPath;
int nPath;
if( objc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
return TCL_ERROR;
}
zPath = Tcl_GetStringFromObj(objv[1], &nPath);
#ifdef __APPLE__
{
struct statfs fsInfo;
if( statfs(zPath, &fsInfo) == -1 ){
int err = errno;
Tcl_AppendResult(interp, "Error calling statfs on path",
Tcl_NewIntObj(err), 0);
return TCL_ERROR;
}
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
} else if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
} else {
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
}
}
#else
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
#endif
return TCL_OK;
}
/*
** tclcmd: sqlite3_vfs_list
@@ -5101,6 +5210,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_bind_parameter_name", test_bind_parameter_name, 0},
{ "sqlite3_bind_parameter_index", test_bind_parameter_index, 0},
{ "sqlite3_clear_bindings", test_clear_bindings, 0},
{ "sqlite3_clear_bindings_null", test_clear_bindings_null, 0},
{ "sqlite3_sleep", test_sleep, 0},
{ "sqlite3_errcode", test_errcode ,0 },
{ "sqlite3_extended_errcode", test_ex_errcode ,0 },
@@ -5187,6 +5297,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
{ "path_is_local", path_is_local, 0 },
{ "path_is_dos", path_is_dos, 0 },
/* Functions from os.h */
#ifndef SQLITE_OMIT_UTF16
+1 -1
View File
@@ -14,7 +14,7 @@
*/
#include "tcl.h"
#include <sqlite3.h>
#include "sqlite3.h"
#include <assert.h>
/* These functions are implemented in test1.c. */
+17 -1
View File
@@ -528,7 +528,23 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
#else
Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef __APPLE__
# if defined(__ppc__)
Tcl_SetVar2(interp, "os_options", "arch", "ppc", TCL_GLOBAL_ONLY);
# elif defined(__i386__)
Tcl_SetVar2(interp, "os_options", "arch", "i386", TCL_GLOBAL_ONLY);
# elif defined(__x86_64__)
Tcl_SetVar2(interp, "os_options", "arch", "x86_64", TCL_GLOBAL_ONLY);
# elif defined(__arm__)
Tcl_SetVar2(interp, "os_options", "arch", "arm", TCL_GLOBAL_ONLY);
# else
# error Unrecognized architecture for exec_options
# endif
#else
Tcl_SetVar2(interp, "os_options", "arch", "unknown", TCL_GLOBAL_ONLY);
#endif
#define LINKVAR(x) { \
static const int cv_ ## x = SQLITE_ ## x; \
Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
+1 -1
View File
@@ -580,7 +580,7 @@ int sqlite3VdbeExec(
** sqlite3_column_text16() failed. */
goto no_mem;
}
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || ((p->rc&0xFF) == SQLITE_LOCKED));
p->rc = SQLITE_OK;
assert( p->explain==0 );
p->pResultSet = 0;
+46 -2
View File
@@ -15,6 +15,9 @@
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#ifdef SQLITE_ENABLE_SQLRR
# include "sqlrr.h"
#endif
#ifndef SQLITE_OMIT_DEPRECATED
/*
@@ -37,7 +40,8 @@ int sqlite3_expired(sqlite3_stmt *pStmt){
** invalid). Return false if it is ok.
*/
static int vdbeSafety(Vdbe *p){
if( p->db==0 ){
sqlite3* db = p->db;
if((db==0) || (db->magic != SQLITE_MAGIC_OPEN) || ((p->magic != VDBE_MAGIC_RUN) && (p->magic != VDBE_MAGIC_HALT))){
sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement");
return 1;
}else{
@@ -68,6 +72,9 @@ int sqlite3_finalize(sqlite3_stmt *pStmt){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
#ifdef SQLITE_ENABLE_SQLRR
SRRecFinalize(pStmt);
#endif
sqlite3 *db = v->db;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
@@ -98,6 +105,9 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
#ifdef SQLITE_ENABLE_SQLRR
SRRecReset(pStmt);
#endif
sqlite3_mutex_enter(v->db->mutex);
rc = sqlite3VdbeReset(v);
sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0);
@@ -116,7 +126,14 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
sqlite3_mutex *mutex=NULL;
#endif
if( NULL==pStmt ){ return SQLITE_OK; } /* <rdar://problem/6646331> */
#ifdef SQLITE_ENABLE_SQLRR
SRRecClearBindings(pStmt);
#endif
#if SQLITE_THREADSAFE
mutex = ((Vdbe*)pStmt)->db->mutex;
#endif
sqlite3_mutex_enter(mutex);
for(i=0; i<p->nVar; i++){
@@ -1024,11 +1041,17 @@ int sqlite3_bind_blob(
int nData,
void (*xDel)(void*)
){
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindBlob(pStmt, i, zData, nData);
#endif
return bindText(pStmt, i, zData, nData, xDel, 0);
}
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindDouble(pStmt, i, rValue);
#endif
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
@@ -1037,11 +1060,17 @@ int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
return rc;
}
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindInt64(p, i, (i64)iValue);
#endif
return sqlite3_bind_int64(p, i, (i64)iValue);
}
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindInt64(pStmt, i, iValue);
#endif
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
@@ -1052,6 +1081,9 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindNull(pStmt, i);
#endif
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3_mutex_leave(p->db->mutex);
@@ -1065,6 +1097,9 @@ int sqlite3_bind_text(
int nData,
void (*xDel)(void*)
){
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindText(pStmt, i, zData, nData);
#endif
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
@@ -1075,6 +1110,9 @@ int sqlite3_bind_text16(
int nData,
void (*xDel)(void*)
){
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindText(pStmt, i, zData, nData);
#endif
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -1098,6 +1136,9 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
break;
}
case SQLITE_TEXT: {
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindText(pStmt, i, pValue->z, pValue->n);
#endif
rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT,
pValue->enc);
break;
@@ -1112,6 +1153,9 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
#ifdef SQLITE_ENABLE_SQLRR
SRRecBindBlob(pStmt, i, NULL, n);
#endif
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
+18 -17
View File
@@ -714,23 +714,24 @@ do_test attach-6.1 {
}
} {0 {}}
if {$tcl_platform(platform)=="unix"} {
do_test attach-6.2 {
sqlite3 dbx cannot-read
dbx eval {CREATE TABLE t1(a,b,c)}
dbx close
file attributes cannot-read -permission 0000
if {[file writable cannot-read]} {
puts "\n**** Tests do not work when run as root ****"
file delete -force cannot-read
exit 1
}
catchsql {
ATTACH DATABASE 'cannot-read' AS noread;
}
} {1 {unable to open database: cannot-read}}
do_test attach-6.2.2 {
db errorcode
} {14}
sqlite3 dbx cannot-read
dbx eval {CREATE TABLE t1(a,b,c)}
dbx close
file attributes cannot-read -permission 0000
if {[file writable cannot-read]} {
#puts "\n**** Tests do not work when run as root ****"
file delete -force cannot-read
#exit 1
} else {
do_test attach-6.2 {
catchsql {
ATTACH DATABASE 'cannot-read' AS noread;
}
} {1 {unable to open database: cannot-read}}
do_test attach-6.2.2 {
db errorcode
} {14}
}
file delete -force cannot-read
}
+3
View File
@@ -656,6 +656,9 @@ do_test bind-13.4 {
[sqlite3_column_type $VM 2]
} {NULL NULL NULL}
sqlite3_finalize $VM
do_test bind-13.5 {
sqlite3_clear_bindings_null
} {0}
#--------------------------------------------------------------------
# These tests attempt to reproduce bug #3463.
+1 -5
View File
@@ -401,12 +401,8 @@ sqlite db test.db
# if we're using proxy locks, we use 3 filedescriptors for a db
# that is open but NOT writing changes, normally
# sqlite uses 1 (proxy locking adds the conch and the local lock)
set using_proxy 0
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
set using_proxy $value
}
set extrafds 0
if {$using_proxy!=0} {
if {[forced_proxy_locking]} {
set extrafds 2
}
+1
View File
@@ -76,6 +76,7 @@ set skipwaltests [expr {
[permutation]=="journaltest" || [permutation]=="inmemory_journal"
}]
ifcapable !wal { set skipwaltests 1 }
if {![wal_is_ok]} { set skipwaltests 1 }
if {!$skipwaltests} {
db close
+1 -1
View File
@@ -20,7 +20,7 @@ source $testdir/malloc_common.tcl
# If a connection is required to create a journal file, it creates it with
# the same file-system permissions as the database file itself. Test this.
#
if {$::tcl_platform(platform) == "unix"} {
if {$::tcl_platform(platform) == "unix" && ![path_is_dos "."]} {
set umask [exec /bin/sh -c umask]
faultsim_delete_and_reopen
+73 -69
View File
@@ -106,87 +106,91 @@ if {[catch {sqlite3 db test.db -vfs unix-flock} msg]} {
return
}
do_test lock5-flock.1 {
sqlite3 db test.db -vfs unix-flock
execsql {
CREATE TABLE t1(a, b);
BEGIN;
INSERT INTO t1 VALUES(1, 2);
}
} {}
# Only run the flock tests on a local file system
if { [path_is_local "."] } {
# Make sure we are not accidentally using the dotfile locking scheme.
do_test lock5-flock.2 {
file exists test.db.lock
} {0}
do_test lock5-flock.1 {
sqlite3 db test.db -vfs unix-flock
execsql {
CREATE TABLE t1(a, b);
BEGIN;
INSERT INTO t1 VALUES(1, 2);
}
} {}
do_test lock5-flock.3 {
catch { sqlite3 db2 test.db -vfs unix-flock }
catchsql { SELECT * FROM t1 } db2
} {1 {database is locked}}
# Make sure we are not accidentally using the dotfile locking scheme.
do_test lock5-flock.2 {
file exists test.db.lock
} {0}
do_test lock5-flock.4 {
execsql COMMIT
catchsql { SELECT * FROM t1 } db2
} {0 {1 2}}
do_test lock5-flock.3 {
catch { sqlite3 db2 test.db -vfs unix-flock }
catchsql { SELECT * FROM t1 } db2
} {1 {database is locked}}
do_test lock5-flock.5 {
execsql BEGIN
catchsql { SELECT * FROM t1 } db2
} {0 {1 2}}
do_test lock5-flock.4 {
execsql COMMIT
catchsql { SELECT * FROM t1 } db2
} {0 {1 2}}
do_test lock5-flock.6 {
execsql {SELECT * FROM t1}
catchsql { SELECT * FROM t1 } db2
} {1 {database is locked}}
do_test lock5-flock.5 {
execsql BEGIN
catchsql { SELECT * FROM t1 } db2
} {0 {1 2}}
do_test lock5-flock.7 {
db close
catchsql { SELECT * FROM t1 } db2
} {0 {1 2}}
do_test lock5-flock.6 {
execsql {SELECT * FROM t1}
catchsql { SELECT * FROM t1 } db2
} {1 {database is locked}}
do_test lock5-flock.8 {
db2 close
} {}
do_test lock5-flock.7 {
db close
catchsql { SELECT * FROM t1 } db2
} {0 {1 2}}
#####################################################################
do_test lock5-flock.8 {
db2 close
} {}
do_test lock5-none.1 {
sqlite3 db test.db -vfs unix-none
sqlite3 db2 test.db -vfs unix-none
execsql {
BEGIN;
INSERT INTO t1 VALUES(3, 4);
}
} {}
do_test lock5-none.2 {
execsql { SELECT * FROM t1 }
} {1 2 3 4}
do_test lock5-flock.3 {
execsql { SELECT * FROM t1 } db2
} {1 2}
do_test lock5-none.4 {
execsql {
BEGIN;
SELECT * FROM t1;
} db2
} {1 2}
do_test lock5-none.5 {
execsql COMMIT
execsql {SELECT * FROM t1} db2
} {1 2}
#####################################################################
ifcapable memorymanage {
do_test lock5-none.6 {
sqlite3_release_memory 1000000
execsql {SELECT * FROM t1} db2
do_test lock5-none.1 {
sqlite3 db test.db -vfs unix-none
sqlite3 db2 test.db -vfs unix-none
execsql {
BEGIN;
INSERT INTO t1 VALUES(3, 4);
}
} {}
do_test lock5-none.2 {
execsql { SELECT * FROM t1 }
} {1 2 3 4}
}
do_test lock5-flock.3 {
execsql { SELECT * FROM t1 } db2
} {1 2}
do_test lock5-none.4 {
execsql {
BEGIN;
SELECT * FROM t1;
} db2
} {1 2}
do_test lock5-none.5 {
execsql COMMIT
execsql {SELECT * FROM t1} db2
} {1 2}
do_test lock5-flock.X {
db close
db2 close
} {}
ifcapable memorymanage {
do_test lock5-none.6 {
sqlite3_release_memory 1000000
execsql {SELECT * FROM t1} db2
} {1 2 3 4}
}
do_test lock5-flock.X {
db close
db2 close
} {}
}
ifcapable lock_proxy_pragmas {
set env(SQLITE_FORCE_PROXY_LOCKING) $::using_proxy
+5 -3
View File
@@ -126,9 +126,10 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
set lockpath
} {{:auto: (not held)}}
set lpp [exec mktemp -t fail]
do_test lock6-1.4.1 {
execsql "PRAGMA lock_proxy_file='$lpp'"
catchsql {
PRAGMA lock_proxy_file="notmine";
select * from sqlite_master;
} db
} {1 {database is locked}}
@@ -137,7 +138,7 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
execsql {
PRAGMA lock_proxy_file;
} db
} {notmine}
} $lpp
do_test lock6-1.5 {
testfixture $::tf1 {
@@ -150,9 +151,10 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
catch {testfixture $::tf1 {db close}}
set lpp [exec mktemp -t ok]
do_test lock6-1.6 {
execsql "PRAGMA lock_proxy_file='$lpp'"
execsql {
PRAGMA lock_proxy_file="mine";
select * from sqlite_master;
} db
} {}
+142
View File
@@ -0,0 +1,142 @@
# 2008 June 28
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is database proxy locks.
#
# $Id$
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# This file is only run if using the unix backend compiled with the
# SQLITE_ENABLE_LOCKING_STYLE macro.
db close
if {[catch {sqlite3 db test.db -vfs unix-none} msg]} {
finish_test
return
}
db close
file delete -force test.db.lock
#####################################################################
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
set ::using_proxy 0
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
set ::using_proxy $value
}
# enable the proxy locking for these tests
set env(SQLITE_FORCE_PROXY_LOCKING) "1"
# test conch file creation
#
catch { file delete lock_proxy_test.db }
catch { file delete .lock_proxy_test.db-conch }
# test that proxy locking mode creates conch files
do_test lock_proxy1.0 {
sqlite3 db2 lock_proxy_test.db
catchsql {
create table x(y);
} db2
file exists .lock_proxy_test.db-conch
} {1}
catch { db2 close }
# test proxy locking readonly file system handling
#
if {[file exists /usr/bin/hdiutil]} {
puts "Creating readonly file system for proxy locking tests..."
if {[file exists /Volumes/readonly]} {
exec hdiutil detach /Volumes/readonly
}
if {[file exists readonly.dmg]} {
file delete readonly.dmg
}
exec hdiutil create -megabytes 1 -fs HFS+ readonly.dmg -volname readonly
exec hdiutil attach readonly.dmg
# create test1.db and a .test1.db-conch for host4
set sqlite_hostid_num 4
sqlite3 db2 /Volumes/readonly/test1.db
execsql {
create table x(y);
} db2
db2 close
# create test2.db and a .test2.db-conch for host5
set sqlite_hostid_num 5
sqlite3 db2 /Volumes/readonly/test2.db
execsql {
create table x(y);
} db2
db2 close
# create test3.db without a conch file
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
sqlite3 db2 /Volumes/readonly/test3.db
execsql {
create table x(y);
} db2
db2 close
exec hdiutil detach /Volumes/readonly
exec hdiutil attach -readonly readonly.dmg
# test that an unwritable, host-mismatched conch file prevents
# read only proxy-locking mode database access
set env(SQLITE_FORCE_PROXY_LOCKING) "1"
do_test lock_proxy2.0 {
sqlite3 db2 /Volumes/readonly/test1.db
catchsql {
select * from sqlite_master;
} db2
} {1 {database is locked}}
catch { db2 close }
# test that an unwritable, host-matching conch file allows
# read only proxy-locking mode database access
do_test lock_proxy2.1 {
sqlite3 db2 /Volumes/readonly/test2.db
catchsql {
select * from sqlite_master;
} db2
} {0 {table x x 2 {CREATE TABLE x(y)}}}
catch { db2 close }
# test that an unwritable, nonexistant conch file allows
# read only proxy-locking mode database access
do_test lock_proxy2.2 {
sqlite3 db2 /Volumes/readonly/test3.db
catchsql {
select * from sqlite_master;
} db2
} {0 {table x x 2 {CREATE TABLE x(y)}}}
catch { db2 close }
exec hdiutil detach /Volumes/readonly
file delete readonly.dmg
}
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
set sqlite_hostid_num 0
}
#####################################################################
file delete -force test.db
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
set env(SQLITE_FORCE_PROXY_LOCKING) $::using_proxy
}
finish_test
+3 -3
View File
@@ -314,7 +314,7 @@ if {[permutation] == ""} {
#
do_test main-3.1 {
catch {db close}
foreach f [glob -nocomplain testdb/*] {file delete -force $f}
catch {foreach f [glob -nocomplain testdb/*] {file delete -force $f}}
file delete -force testdb
sqlite3 db testdb
set v [catch {execsql {SELECT * from T1 where x!!5}} msg]
@@ -322,7 +322,7 @@ do_test main-3.1 {
} {1 {unrecognized token: "!!"}}
do_test main-3.2 {
catch {db close}
foreach f [glob -nocomplain testdb/*] {file delete -force $f}
catch {foreach f [glob -nocomplain testdb/*] {file delete -force $f}}
file delete -force testdb
sqlite3 db testdb
set v [catch {execsql {SELECT * from T1 where ^x}} msg]
@@ -442,7 +442,7 @@ do_test main-3.2.30 {
do_test main-3.3 {
catch {db close}
foreach f [glob -nocomplain testdb/*] {file delete -force $f}
catch {foreach f [glob -nocomplain testdb/*] {file delete -force $f}}
file delete -force testdb
sqlite3 db testdb
execsql {
+1 -1
View File
@@ -412,7 +412,7 @@ proc do_malloc_test {tn args} {
set zRepeat "transient"
if {$::iRepeat} {set zRepeat "persistent"}
restore_prng_state
foreach file [glob -nocomplain test.db-mj*] {file delete -force $file}
catch {foreach file [glob -nocomplain test.db-mj*] {file delete -force $file}}
do_test ${tn}.${zRepeat}.${::n} {
+1 -5
View File
@@ -22,12 +22,8 @@ set N 300
# if we're using proxy locks, we use 5 filedescriptors for a db
# that is open and in the middle of writing changes, normally
# sqlite uses 3 (proxy locking adds the conch and the local lock)
set using_proxy 0
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
set using_proxy value
}
set num_fd_per_openwrite_db 3
if {$using_proxy>0} {
if {[forced_proxy_locking]} {
set num_fd_per_openwrite_db 5
}
+21 -18
View File
@@ -413,24 +413,27 @@ do_test memdb-8.2 {
# Test that auto-vacuum works with in-memory databases.
#
ifcapable autovacuum {
do_test memdb-9.1 {
db close
sqlite3 db test.db
db cache size 0
execsql {
PRAGMA auto_vacuum = full;
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(randstr(1000,1000));
INSERT INTO t1 VALUES(randstr(1000,1000));
INSERT INTO t1 VALUES(randstr(1000,1000));
}
set memused [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
set pgovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 1]
execsql { DELETE FROM t1 }
set memused2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
expr {($memused2 + 2048 < $memused) || $pgovfl==0}
} {1}
set msize [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
if {[lindex $msize 2]!=0} {
ifcapable autovacuum {
do_test memdb-9.1 {
db close
sqlite3 db test.db
db cache size 0
execsql {
PRAGMA auto_vacuum = full;
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(randstr(1000,1000));
INSERT INTO t1 VALUES(randstr(1000,1000));
INSERT INTO t1 VALUES(randstr(1000,1000));
}
set memused [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
set pgovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 1]
execsql { DELETE FROM t1 }
set memused2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
expr {($memused2 + 2048 < $memused) || $pgovfl==0}
} {1}
}
}
} ;# ifcapable memorydb
+36 -28
View File
@@ -191,17 +191,20 @@ build_test_db memsubsys1-5 {PRAGMA page_size=4096}
do_test memsubsys1-5.3 {
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
} 23
do_test memsubsys1-5.4 {
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
expr {$maxreq>4096}
} 1
do_test memsubsys1-5.5 {
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
} 0
do_test memsubsys1-5.6 {
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
expr {$s_ovfl>6000}
} 1
set msize [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
if {[lindex $msize 2]!=0} {
do_test memsubsys1-5.4 {
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
expr {$maxreq>4096}
} 1
do_test memsubsys1-5.5 {
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
} 0
do_test memsubsys1-5.6 {
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
expr {$s_ovfl>6000}
} 1
}
# Test 6: Activate both PAGECACHE and SCRATCH with a 4k page size.
# Make it so that SCRATCH is large enough
@@ -217,10 +220,13 @@ build_test_db memsubsys1-6 {PRAGMA page_size=4096}
do_test memsubsys1-6.3 {
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
} 23
do_test memsubsys1-6.4 {
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
expr {$maxreq>4096 && $maxreq<=(4096+$xtra_size)}
} 1
set msize [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
if {[lindex $msize 2]!=0} {
do_test memsubsys1-6.4 {
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
expr {$maxreq>4096 && $maxreq<=(4096+$xtra_size)}
} 1
}
do_test memsubsys1-6.5 {
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
} 1
@@ -277,19 +283,21 @@ do_test memsubsys1-8.1 {
do_test memsubsys1-8.2 {
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
} 0
do_test memsubsys1-8.3 {
sqlite3 db :memory:
db eval {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(zeroblob(400));
INSERT INTO t1 VALUES(zeroblob(400));
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
}
expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0}
} 1
db close
if {[lindex $msize 2]!=0} {
do_test memsubsys1-8.3 {
sqlite3 db :memory:
db eval {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(zeroblob(400));
INSERT INTO t1 VALUES(zeroblob(400));
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
}
expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0}
} 1
db close
}
sqlite3_shutdown
sqlite3_config_memstatus 0
sqlite3_initialize
+130 -110
View File
@@ -15,7 +15,7 @@ source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
@@ -540,7 +540,11 @@ foreach {tn1 tcl} {
# a valid page record (if the file page-size is 512 bytes). So as to
# make sure SQLite doesn't get confused by this.
#
set nPadding [expr 511 - $::mj_filename_length]
set target_length 511
if { [forced_proxy_locking] } {
set target_length 255
}
set nPadding [expr $target_length - $::mj_filename_length]
if {$tcl_platform(platform)=="windows"} {
# TBD need to figure out how to do this correctly for Windows!!!
set nPadding [expr 255 - $::mj_filename_length]
@@ -561,6 +565,7 @@ foreach {tn1 tcl} {
set padding [string repeat x [expr $nPadding %32]]
set prefix "test.db${padding}"
set prefix
}
} {
eval $tcl
@@ -1081,46 +1086,49 @@ do_execsql_test pager1-6.12 { PRAGMA max_page_count } {11}
# $ws: The expected size of the WAL file, in bytes, after executing
# the SQL script. Or -1 if the WAL is not expected to exist.
#
ifcapable wal {
faultsim_delete_and_reopen
foreach {tn sql res js ws} [subst {
1 {
CREATE TABLE t1(a, b);
PRAGMA auto_vacuum=OFF;
PRAGMA synchronous=NORMAL;
PRAGMA page_size=1024;
PRAGMA locking_mode=EXCLUSIVE;
PRAGMA journal_mode=TRUNCATE;
INSERT INTO t1 VALUES(1, 2);
} {exclusive truncate} 0 -1
2 {
BEGIN IMMEDIATE;
SELECT * FROM t1;
COMMIT;
} {1 2} 0 -1
3 {
BEGIN;
SELECT * FROM t1;
COMMIT;
} {1 2} 0 -1
4 { PRAGMA journal_mode = WAL } wal -1 -1
5 { INSERT INTO t1 VALUES(3, 4) } {} -1 [wal_file_size 1 1024]
6 { PRAGMA locking_mode = NORMAL } normal -1 [wal_file_size 1 1024]
7 { INSERT INTO t1 VALUES(5, 6); } {} -1 [wal_file_size 2 1024]
8 { PRAGMA journal_mode = TRUNCATE } truncate 0 -1
9 { INSERT INTO t1 VALUES(7, 8) } {} 0 -1
10 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8} 0 -1
}] {
do_execsql_test pager1-7.1.$tn.1 $sql $res
catch { set J -1 ; set J [file size test.db-journal] }
catch { set W -1 ; set W [file size test.db-wal] }
do_test pager1-7.1.$tn.2 { list $J $W } [list $js $ws]
set do_wal_tests [wal_is_ok]
if { $do_wal_tests } {
ifcapable wal {
faultsim_delete_and_reopen
foreach {tn sql res js ws} [subst {
1 {
CREATE TABLE t1(a, b);
PRAGMA auto_vacuum=OFF;
PRAGMA synchronous=NORMAL;
PRAGMA page_size=1024;
PRAGMA locking_mode=EXCLUSIVE;
PRAGMA journal_mode=TRUNCATE;
INSERT INTO t1 VALUES(1, 2);
} {exclusive truncate} 0 -1
2 {
BEGIN IMMEDIATE;
SELECT * FROM t1;
COMMIT;
} {1 2} 0 -1
3 {
BEGIN;
SELECT * FROM t1;
COMMIT;
} {1 2} 0 -1
4 { PRAGMA journal_mode = WAL } wal -1 -1
5 { INSERT INTO t1 VALUES(3, 4) } {} -1 [wal_file_size 1 1024]
6 { PRAGMA locking_mode = NORMAL } normal -1 [wal_file_size 1 1024]
7 { INSERT INTO t1 VALUES(5, 6); } {} -1 [wal_file_size 2 1024]
8 { PRAGMA journal_mode = TRUNCATE } truncate 0 -1
9 { INSERT INTO t1 VALUES(7, 8) } {} 0 -1
10 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8} 0 -1
}] {
do_execsql_test pager1-7.1.$tn.1 $sql $res
catch { set J -1 ; set J [file size test.db-journal] }
catch { set W -1 ; set W [file size test.db-wal] }
do_test pager1-7.1.$tn.2 { list $J $W } [list $js $ws]
}
}
}
@@ -1294,9 +1302,15 @@ do_test pager1-9.4.1 {
sqlite3_backup B db2 main db main
list [B step 10000] [B finish]
} {SQLITE_DONE SQLITE_OK}
do_test pager1-9.4.2 {
list [file size test.db2] [file size test.db]
} {0 0}
if { [path_is_dos "."] } {
do_test pager1-9.4.2_dos {
list [file size test.db2] [file size test.db]
} {0 1}
} else {
do_test pager1-9.4.2 {
list [file size test.db2] [file size test.db]
} {0 0}
}
db2 close
#-------------------------------------------------------------------------
@@ -1919,32 +1933,34 @@ do_test pager1-20.2.2 {
}
} {}
do_test pager1-20.3.1 {
faultsim_delete_and_reopen
db func a_string a_string
execsql {
PRAGMA cache_size = 10;
PRAGMA journal_mode = wal;
BEGIN;
CREATE TABLE t1(x);
CREATE TABLE t2(y);
INSERT INTO t1 VALUES(a_string(800));
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 2 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 4 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 8 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 16 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 32 */
COMMIT;
}
} {wal}
do_test pager1-20.3.2 {
execsql {
BEGIN;
INSERT INTO t2 VALUES('xxxx');
}
recursive_select 32 t1
execsql COMMIT
} {}
if { $do_wal_tests } {
do_test pager1-20.3.1 {
faultsim_delete_and_reopen
db func a_string a_string
execsql {
PRAGMA cache_size = 10;
PRAGMA journal_mode = wal;
BEGIN;
CREATE TABLE t1(x);
CREATE TABLE t2(y);
INSERT INTO t1 VALUES(a_string(800));
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 2 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 4 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 8 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 16 */
INSERT INTO t1 SELECT a_string(800) FROM t1; /* 32 */
COMMIT;
}
} {wal}
do_test pager1-20.3.2 {
execsql {
BEGIN;
INSERT INTO t2 VALUES('xxxx');
}
recursive_select 32 t1
execsql COMMIT
} {}
}
#-------------------------------------------------------------------------
# Test that a WAL database may not be opened if:
@@ -1952,28 +1968,30 @@ do_test pager1-20.3.2 {
# pager1-21.1.*: The VFS has an iVersion less than 2, or
# pager1-21.2.*: The VFS does not provide xShmXXX() methods.
#
do_test pager1-21.0 {
faultsim_delete_and_reopen
execsql {
PRAGMA journal_mode = WAL;
CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
INSERT INTO ko DEFAULT VALUES;
}
} {wal}
do_test pager1-21.1 {
testvfs tv -noshm 1
sqlite3 db2 test.db -vfs tv
catchsql { SELECT * FROM ko } db2
} {1 {unable to open database file}}
db2 close
tv delete
do_test pager1-21.2 {
testvfs tv -iversion 1
sqlite3 db2 test.db -vfs tv
catchsql { SELECT * FROM ko } db2
} {1 {unable to open database file}}
db2 close
tv delete
if { $do_wal_tests } {
do_test pager1-21.0 {
faultsim_delete_and_reopen
execsql {
PRAGMA journal_mode = WAL;
CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
INSERT INTO ko DEFAULT VALUES;
}
} {wal}
do_test pager1-21.1 {
testvfs tv -noshm 1
sqlite3 db2 test.db -vfs tv
catchsql { SELECT * FROM ko } db2
} {1 {unable to open database file}}
db2 close
tv delete
do_test pager1-21.2 {
testvfs tv -iversion 1
sqlite3 db2 test.db -vfs tv
catchsql { SELECT * FROM ko } db2
} {1 {unable to open database file}}
db2 close
tv delete
}
#-------------------------------------------------------------------------
# Test that a "PRAGMA wal_checkpoint":
@@ -2254,24 +2272,26 @@ do_test pager1.27.1 {
# the same database.
#
catch { db close }
do_multiclient_test tn {
do_test pager1-28.$tn.1 {
sql1 {
PRAGMA journal_mode = WAL;
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES('a', 'b');
}
} {wal}
do_test pager1-28.$tn.2 { sql2 { SELECT * FROM t1 } } {a b}
if {[wal_is_ok]} {
do_multiclient_test tn {
do_test pager1-28.$tn.1 {
sql1 {
PRAGMA journal_mode = WAL;
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES('a', 'b');
}
} {wal}
do_test pager1-28.$tn.2 { sql2 { SELECT * FROM t1 } } {a b}
do_test pager1-28.$tn.3 { sql1 { PRAGMA locking_mode=exclusive } } {exclusive}
do_test pager1-28.$tn.4 {
csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); }
} {1 {database is locked}}
code2 { db2 close ; sqlite3 db2 test.db }
do_test pager1-28.$tn.4 {
sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT }
} {}
do_test pager1-28.$tn.3 { sql1 { PRAGMA locking_mode=exclusive } } {exclusive}
do_test pager1-28.$tn.4 {
csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); }
} {1 {database is locked}}
code2 { db2 close ; sqlite3 db2 test.db }
do_test pager1-28.$tn.4 {
sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT }
} {}
}
}
#-------------------------------------------------------------------------
+33
View File
@@ -1046,6 +1046,39 @@ ifcapable crashtest {
}
#-------------------------------------------------------------------------
# When a 3.7.0 client opens a write-transaction on a database file that
# has been appended to or truncated by a pre-370 client, it updates
# the db-size in the file header immediately. This test case provokes
# errors during that operation.
#
do_test pagerfault-22-pre1 {
faultsim_delete_and_reopen
db func a_string a_string
execsql {
PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(a_string(3000));
CREATE TABLE t2(a);
INSERT INTO t2 VALUES(1);
}
db close
sql36231 { INSERT INTO t1 VALUES(a_string(3000)) }
faultsim_save_and_close
} {}
do_faultsim_test pagerfault-22 -prep {
faultsim_restore_and_reopen
} -body {
execsql { INSERT INTO t2 VALUES(2) }
execsql { SELECT * FROM t2 }
} -test {
faultsim_test_result {0 {1 2}}
faultsim_integrity_check
}
#-------------------------------------------------------------------------
# When a 3.7.0 client opens a write-transaction on a database file that
# has been appended to or truncated by a pre-370 client, it updates
+137 -32
View File
@@ -1292,7 +1292,12 @@ sqlite3 dbX :memory:
dbX eval {PRAGMA temp_store_directory = ""}
dbX close
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
set skip_lock_proxy_tests [path_is_dos "."]
ifcapable !lock_proxy_pragmas||prefer_proxy_locking {
set skip_lock_proxy_tests 1
}
if !$skip_lock_proxy_tests {
set sqlite_hostid_num 1
set using_proxy 0
@@ -1306,67 +1311,67 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
sqlite3 db test.db
# set lock proxy name and then query it via pragma interface
set lpp [exec mktemp -t 'proxy1']
do_test pragma-16.1 {
execsql {
PRAGMA lock_proxy_file="mylittleproxy";
select * from sqlite_master;
}
execsql {
PRAGMA lock_proxy_file;
}
} {mylittleproxy}
execsql "PRAGMA lock_proxy_file='$lpp'"
execsql "select * from sqlite_master"
execsql "PRAGMA lock_proxy_file"
} $lpp
# 2 database connections can share a lock proxy file
do_test pragma-16.2 {
sqlite3 db2 test.db
execsql {
PRAGMA lock_proxy_file="mylittleproxy";
} db2
execsql "PRAGMA lock_proxy_file='$lpp'" db2
} {}
db2 close
# 2nd database connection should auto-name an existing lock proxy file
do_test pragma-16.2.1 {
sqlite3 db2 test.db
execsql {
PRAGMA lock_proxy_file=":auto:";
select * from sqlite_master;
} db2
execsql {
PRAGMA lock_proxy_file;
} db2
} {mylittleproxy}
execsql "PRAGMA lock_proxy_file" db2
} $lpp
db2 close
set lpp2 [exec mktemp -t 'proxy2']
# 2nd database connection cannot override the lock proxy file
do_test pragma-16.3 {
sqlite3 db2 test.db
execsql {
PRAGMA lock_proxy_file="myotherproxy";
} db2
execsql "PRAGMA lock_proxy_file='$lpp2'" db2
catchsql {
select * from sqlite_master;
} db2
} {1 {database is locked}}
set lpp3 [exec mktemp -t 'proxy3']
# lock proxy file can be renamed if no other connections are active
do_test pragma-16.4 {
db2 close
db close
sqlite3 db2 test.db
execsql {
PRAGMA lock_proxy_file="myoriginalproxy";
PRAGMA lock_proxy_file="myotherproxy";
PRAGMA lock_proxy_file;
} db2
} {myotherproxy}
execsql "PRAGMA lock_proxy_file='$lpp3'" db2
execsql "PRAGMA lock_proxy_file='$lpp2'" db2
execsql "PRAGMA lock_proxy_file" db2
} $lpp2
db2 close
set env(SQLITE_FORCE_PROXY_LOCKING) "1"
# auto-naming should reuse the last proxy name when available
do_test pragma-16.5 {
sqlite3 db2 test.db
execsql {
PRAGMA lock_proxy_file=":auto:";
PRAGMA lock_proxy_file;
} db2
} {myotherproxy}
} $lpp2
# auto-naming a new proxy should use a predictable & unique name
do_test pragma-16.6 {
db2 close
sqlite3 db2 test2.db
@@ -1378,6 +1383,7 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
} {1}
set sqlite_hostid_num 2
# db access should be limited to one host at a time (simulate 2nd host id)
do_test pragma-16.7 {
sqlite3 db test2.db
execsql {
@@ -1389,6 +1395,7 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
} {1 {database is locked}}
db close
# default to using proxy locking (simulate network file system detection)
do_test pragma-16.8 {
sqlite3 db test2.db
catchsql {
@@ -1397,19 +1404,25 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
} {1 {database is locked}}
db2 close
set lpp4 [exec mktemp -t 'proxy4']
# check that db is unlocked after first host connection closes
do_test pragma-16.8.1 {
execsql {
PRAGMA lock_proxy_file="yetanotherproxy";
PRAGMA lock_proxy_file;
}
} {yetanotherproxy}
execsql "PRAGMA lock_proxy_file='$lpp4'"
execsql "select * from sqlite_master"
execsql "PRAGMA lock_proxy_file"
} $lpp4
do_test pragma-16.8.2 {
execsql {
create table mine(x);
create table if not exists mine(x);
insert into mine values (1);
}
} {}
db close
file delete -force proxytest.db
file delete -force .proxytest.db-conch
do_test pragma-16.9 {
sqlite3 db proxytest.db
set lockpath2 [execsql {
@@ -1419,6 +1432,98 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
string match "*proxytest.db:auto:" $lockpath2
} {1}
# ensure creating directories for a lock proxy file works
set lpp5 [exec mktemp -d -t "proxy5"]/sub/dir/lock
db close
file delete -force proxytest
do_test pragma-16.10.1 {
sqlite3 db proxytest.db
execsql "PRAGMA lock_proxy_file='$lpp5'"
set lockpath2 [execsql {
PRAGMA lock_proxy_file;
} db]
string match "*sub/dir/lock" $lockpath2
} {1}
# ensure that after deleting the path, setting ":auto:" works correctly
db close
file delete -force proxytest
do_test pragma-16.10.2 {
sqlite3 db proxytest.db
set lockpath3 [execsql {
PRAGMA lock_proxy_file=":auto:";
create table if not exists pt(y);
PRAGMA lock_proxy_file;
} db]
string match "*sub/dir/lock" $lockpath3
} {1}
# ensure that if the path can not be created (file instead of dir)
# setting :auto: deals with it by creating a new autonamed lock file
db close
file delete -force proxytest
close [open "proxytest" a]
do_test pragma-16.10.3 {
sqlite3 db proxytest.db
set lockpath2 [execsql {
PRAGMA lock_proxy_file=":auto:";
create table if not exists zz(y);
PRAGMA lock_proxy_file;
} db]
string match "*proxytest.db:auto:" $lockpath2
} {1}
# make sure we can deal with ugly file paths correctly
set lpp6 [exec mktemp -d -t "proxy6"]/./././////./proxytest/../proxytest/sub/dir/lock
db close
file delete -force proxytest
do_test pragma-16.10.4 {
sqlite3 db proxytest.db
execsql "PRAGMA lock_proxy_file='$lpp6'"
set lockpath4 [execsql {
create table if not exists aa(bb);
PRAGMA lock_proxy_file;
} db]
string match "*proxytest/sub/dir/lock" $lockpath4
} {1}
# ensure that if the path can not be created (perm), setting :auto: deals
db close
file delete -force proxytest
do_test pragma-16.10.5 {
sqlite3 db proxytest.db
execsql "PRAGMA lock_proxy_file='$lpp5'"
execsql {
create table if not exists bb(bb);
}
db close
file delete -force proxytest
file mkdir proxytest
file attributes proxytest -permission 0000
sqlite3 db proxytest.db
set lockpath5 [execsql {
PRAGMA lock_proxy_file=":auto:";
create table if not exists cc(bb);
PRAGMA lock_proxy_file;
} db]
string match "*proxytest.db:auto:" $lockpath5
} {1}
# ensure that if the path can not be created, locking fails
db close
do_test pragma-16.10.6 {
sqlite3 db proxytest.db
execsql "PRAGMA lock_proxy_file='$lpp5'"
catchsql {
create table if not exists faily(y);
PRAGMA lock_proxy_file;
} db
} {1 {database is locked}}
db close
file attributes proxytest -permission 0777
file delete -force proxytest
set env(SQLITE_FORCE_PROXY_LOCKING) $using_proxy
set sqlite_hostid_num 0
}
+1 -5
View File
@@ -45,13 +45,9 @@ ifcapable autovacuum {
# if we're using proxy locks, we use 2 filedescriptors for a db
# that is open but NOT yet locked, after a lock is taken we'll have 3,
# normally sqlite uses 1 (proxy locking adds the conch and the local lock)
set using_proxy 0
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
set using_proxy $value
}
set extrafds_prelock 0
set extrafds_postlock 0
if {$using_proxy>0} {
if {[forced_proxy_locking]} {
set extrafds_prelock 1
set extrafds_postlock 2
}
+7 -6
View File
@@ -30,12 +30,13 @@ do_execsql_test stat-0.0 {
CREATE VIRTUAL TABLE temp.stat USING dbstat;
SELECT * FROM stat;
} {}
do_execsql_test stat-0.1 {
PRAGMA journal_mode = WAL;
PRAGMA journal_mode = delete;
SELECT * FROM stat;
} {wal delete sqlite_master / 1 leaf 0 0 916 0}
if {[wal_is_ok]} {
do_execsql_test stat-0.1 {
PRAGMA journal_mode = WAL;
PRAGMA journal_mode = delete;
SELECT * FROM stat;
} {wal delete sqlite_master / 1 leaf 0 0 916 0}
}
do_test stat-1.0 {
execsql {
CREATE TABLE t1(a, b);
+24 -7
View File
@@ -30,8 +30,19 @@ if {$::TEMP_STORE==3} {
finish_test
return
}
# if we're using proxy locks, we use 3 filedescriptors for a db
# that is open but NOT writing changes, normally
# sqlite uses 1 (proxy locking adds the conch and the local lock)
set extrafds 0
if {[forced_proxy_locking]} {
set extrafds 2
}
do_test stmt-1.2 {
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {1}
do_test stmt-1.3 {
execsql {
@@ -39,16 +50,19 @@ do_test stmt-1.3 {
INSERT INTO t1 VALUES(1, 1);
}
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {2}
do_test stmt-1.4 {
execsql {
INSERT INTO t1 SELECT a+1, b+1 FROM t1;
}
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {3}
do_test stmt-1.5 {
execsql COMMIT
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {1}
do_test stmt-1.6.1 {
execsql {
@@ -56,34 +70,37 @@ do_test stmt-1.6.1 {
INSERT INTO t1 SELECT a+2, b+2 FROM t1;
}
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {2}
do_test stmt-1.6.2 {
execsql { INSERT INTO t1 SELECT a+4, b+4 FROM t1 }
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {3}
do_test stmt-1.7 {
execsql COMMIT
set sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds
} {1}
proc filecount {testname sql expected} {
proc filecount {testname sql expected extrafds} {
uplevel [list do_test $testname [subst -nocommand {
execsql BEGIN
execsql { $sql }
set ret [set sqlite_open_file_count]
execsql ROLLBACK
set ret
}] $expected]
}] [ expr $expected+$extrafds ] ]
}
filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2
filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2
filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2
filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2 $extrafds
filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2 $extrafds
filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2 $extrafds
filecount stmt-2.4 {
INSERT INTO t1 SELECT 9, 9;
INSERT INTO t1 SELECT 10, 10;
} 3
} 3 $extrafds
do_test stmt-2.5 {
execsql { CREATE INDEX i1 ON t1(b) }
@@ -91,6 +108,6 @@ do_test stmt-2.5 {
filecount stmt-2.6 {
REPLACE INTO t1 VALUES(5, 5);
REPLACE INTO t1 VALUES(5, 5);
} 3
} 3 $extrafds
finish_test
+7 -2
View File
@@ -52,6 +52,11 @@ do_test tempdb-1.2 {
}
} {}
set extrafds 0
if {[forced_proxy_locking]} {
set extrafds 2
}
do_test tempdb-2.1 {
# Set $::jrnl_in_memory if the journal file is expected to be in-memory.
# Similarly, set $::subj_in_memory if the sub-journal file is expected
@@ -76,7 +81,7 @@ do_test tempdb-2.2 {
}
catchsql { INSERT INTO t1 SELECT * FROM t2 }
set sqlite_open_file_count
} [expr 1 + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
} [expr 1 + $extrafds + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
do_test tempdb-2.3 {
execsql {
PRAGMA temp_store = 'memory';
@@ -88,6 +93,6 @@ do_test tempdb-2.3 {
}
catchsql { INSERT INTO t1 SELECT * FROM t2 }
set sqlite_open_file_count
} [expr 1 + (0==$jrnl_in_memory)]
} [expr 1 + $extrafds + (0==$jrnl_in_memory)]
finish_test
+41 -4
View File
@@ -245,6 +245,10 @@ reset_db
#
if {[info exists TC(count)]} return
# Make sure memory statistics are enabled.
#
sqlite3_config_memstatus 1
# Initialize the test counters and set up commands to access them.
# Or, if this is a slave interpreter, set up aliases to write the
# counters in the parent interpreter.
@@ -475,11 +479,15 @@ proc finalize_testing {} {
memdebug_log_sql leaks.sql
}
}
foreach f [glob -nocomplain test.db-*-journal] {
file delete -force $f
catch {
foreach f [glob -nocomplain test.db-*-journal] {
file delete -force $f
}
}
foreach f [glob -nocomplain test.db-mj*] {
file delete -force $f
catch {
foreach f [glob -nocomplain test.db-mj*] {
file delete -force $f
}
}
exit [expr {$nErr>0}]
}
@@ -1157,6 +1165,35 @@ proc presql {} {
set presql
}
proc forced_proxy_locking {} {
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
set force_proxy_value 0
set force_key "SQLITE_FORCE_PROXY_LOCKING="
foreach {env_pair} [exec env] {
if { [string first $force_key $env_pair] == 0} {
set force_proxy_value [string range $env_pair [string length $force_key] end]
}
}
if { "$force_proxy_value " == "1 " } {
return 1
}
}
return 0
}
proc wal_is_ok {} {
if { [forced_proxy_locking] } {
return 1
}
if { ![path_is_local "."] } {
return 0
}
if { [path_is_dos "."] } {
return 0
}
return 1
}
#-------------------------------------------------------------------------
#
proc slave_test_script {script} {
+22 -20
View File
@@ -62,26 +62,28 @@ do_test tkt3457-1.1 {
execsql COMMIT
} {}
do_test tkt3457-1.2 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions ---------
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
do_test tkt3457-1.3 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions -w--w--w-
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
do_test tkt3457-1.4 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions r--r--r--
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
if { ![path_is_dos "."] } {
do_test tkt3457-1.2 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions ---------
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
do_test tkt3457-1.3 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions -w--w--w-
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
do_test tkt3457-1.4 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions r--r--r--
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
do_test tkt3457-1.5 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions rw-rw-rw-
catchsql { SELECT * FROM t1 }
} {0 {1 2 3 4 5 6}}
do_test tkt3457-1.5 {
file copy -force bak.db-journal test.db-journal
file attributes test.db-journal -permissions rw-rw-rw-
catchsql { SELECT * FROM t1 }
} {0 {1 2 3 4 5 6}}
}
finish_test
+4
View File
@@ -20,6 +20,10 @@ source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
proc reopen_db {} {
catch { db close }
+59
View File
@@ -20,6 +20,10 @@ source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] || [path_is_dos "."]} {
finish_test
return
}
proc set_tvfs_hdr {file args} {
@@ -1149,4 +1153,59 @@ if {$::tcl_platform(platform) == "unix"} {
}
}
#-------------------------------------------------------------------------
# Test that "PRAGMA checkpoint_fullsync" appears to be working.
#
foreach {tn sql reslist} {
1 { } {8 0 3 0 5 0}
2 { PRAGMA checkpoint_fullfsync = 1 } {8 4 3 2 5 2}
3 { PRAGMA checkpoint_fullfsync = 0 } {8 0 3 0 5 0}
} {
faultsim_delete_and_reopen
execsql $sql
do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal}
set sqlite_sync_count 0
set sqlite_fullsync_count 0
do_execsql_test wal2-14.$tn.2 {
PRAGMA wal_autocheckpoint = 10;
CREATE TABLE t1(a, b); -- 2 wal syncs
INSERT INTO t1 VALUES(1, 2); -- 1 wal sync
PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync
BEGIN;
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
COMMIT; -- 1 wal sync
PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync
} {10}
do_test wal2-14.$tn.3 {
list $sqlite_sync_count $sqlite_fullsync_count
} [lrange $reslist 0 1]
set sqlite_sync_count 0
set sqlite_fullsync_count 0
do_test wal2-14.$tn.4 {
execsql { INSERT INTO t1 VALUES(7, zeroblob(12*4096)) }
list $sqlite_sync_count $sqlite_fullsync_count
} [lrange $reslist 2 3]
set sqlite_sync_count 0
set sqlite_fullsync_count 0
do_test wal2-14.$tn.5 {
execsql { PRAGMA wal_autocheckpoint = 1000 }
execsql { INSERT INTO t1 VALUES(9, 10) }
execsql { INSERT INTO t1 VALUES(11, 12) }
execsql { INSERT INTO t1 VALUES(13, 14) }
db close
list $sqlite_sync_count $sqlite_fullsync_count
} [lrange $reslist 4 5]
}
finish_test
+5 -1
View File
@@ -19,6 +19,10 @@ source $testdir/lock_common.tcl
source $testdir/wal_common.tcl
source $testdir/malloc_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
set a_string_counter 1
proc a_string {n} {
@@ -613,7 +617,7 @@ T delete
#-------------------------------------------------------------------------
#
do_test wal3-8.1 {
file delete -force test.db test.db-journal test.db wal
file delete -force test.db test.db-journal test.db wal .test.db-conch
sqlite3 db test.db
sqlite3 db2 test.db
execsql {
+4
View File
@@ -16,6 +16,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] || [path_is_dos "."]} {
finish_test
return
}
do_test wal4-1.1 {
execsql {
+4
View File
@@ -21,6 +21,10 @@ source $testdir/malloc_common.tcl
do_not_use_codec
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
# Test organization:
+4
View File
@@ -27,6 +27,10 @@ ifcapable !lfs {
finish_test
return
}
if { ![wal_is_ok] } {
finish_test
return
}
set a_string_counter 1
proc a_string {n} {
+4
View File
@@ -16,6 +16,10 @@ source $testdir/lock_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
# Read and return the contents of file $filename. Treat the content as
# binary data.
+4
View File
@@ -28,6 +28,10 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
db close
+4
View File
@@ -16,6 +16,10 @@ source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
#-------------------------------------------------------------------------
+4
View File
@@ -19,6 +19,10 @@ source $testdir/malloc_common.tcl
source $testdir/lock_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
#-------------------------------------------------------------------------
# This test case, walfault-1-*, simulates faults while executing a
+4
View File
@@ -22,6 +22,10 @@ source $testdir/tester.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
set ::wal_hook [list]
proc wal_hook {zDb nEntry} {
+14
View File
@@ -35,6 +35,20 @@ ifcapable !wal {
finish_test
return
}
if { ![wal_is_ok] && ![path_is_dos "."]} {
do_test walmode-0.1 {
execsql { PRAGMA journal_mode = wal }
} {delete}
do_test walmode-0.2 {
execsql { PRAGMA main.journal_mode = wal }
} {delete}
do_test walmode-0.3 {
execsql { PRAGMA main.journal_mode }
} {delete}
finish_test
return
}
do_test walmode-1.1 {
set sqlite_sync_count 0
+7
View File
@@ -15,6 +15,13 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
db close
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
+4
View File
@@ -18,6 +18,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !wal {finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
proc reopen_db {} {
catch { db close }
+4
View File
@@ -19,6 +19,10 @@ source $testdir/tester.tcl
source $testdir/lock_common.tcl
if {[run_thread_tests]==0} { finish_test ; return }
ifcapable !wal { finish_test ; return }
if { ![wal_is_ok] } {
finish_test
return
}
set sqlite_walsummary_mmap_incr 64
+2
View File
@@ -107,6 +107,7 @@ foreach hdr {
sqliteicu.h
sqliteInt.h
sqliteLimit.h
sqlrr.h
vdbe.h
vdbeInt.h
wal.h
@@ -305,6 +306,7 @@ foreach file {
rtree.c
icu.c
fts3_icu.c
sqlrr.c
} {
copy_file tsrc/$file
}