Compare commits
194 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7547f78889 | |||
| fdd72c9a2f | |||
| e82c6c39f4 | |||
| ef8e986bde | |||
| e3be8c8627 | |||
| fbc7e8845d | |||
| 08d418904a | |||
| d040e76442 | |||
| 56282a5bc7 | |||
| 4c5298f352 | |||
| 21c9b6bdc9 | |||
| 65eb64765c | |||
| 7de96f7fc1 | |||
| ab755ac81a | |||
| 6e0b6d52da | |||
| 188d488409 | |||
| f90e50f60b | |||
| 6adab7a1a8 | |||
| 023dd903cc | |||
| e5ebd22d99 | |||
| bcb8a868ce | |||
| 554052c600 | |||
| bc94dbb661 | |||
| 841810cef6 | |||
| 1bf44c7acb | |||
| 7dfe8e2bde | |||
| fbfe388d31 | |||
| e348fc7fe8 | |||
| 8f35eb024e | |||
| 60625313b0 | |||
| 1790bb36c5 | |||
| 896be7d93a | |||
| f012ae0759 | |||
| 3f5bc38037 | |||
| abd6d84a11 | |||
| 27338e6ed7 | |||
| d7a558a9fb | |||
| ced9813b12 | |||
| 75f2d540ac | |||
| 67f7c780f3 | |||
| 6109e50f87 | |||
| a478b3fa80 | |||
| b0a8ea046a | |||
| 370c9f498d | |||
| 716d6d2da7 | |||
| 34f7490311 | |||
| 6c96946475 | |||
| f7679ad19e | |||
| 227a1c482c | |||
| 2b8246e3e2 | |||
| 7e36962e6c | |||
| 7d9f3943ba | |||
| 85830a70c2 | |||
| 48ccef8059 | |||
| c3d53189fc | |||
| 81d1765ad8 | |||
| a9d79ae95d | |||
| db082408c6 | |||
| d409792838 | |||
| a2c16c084a | |||
| f6653871b2 | |||
| 07fa864d15 | |||
| 936c6d7e9e | |||
| 4ff7bc45c6 | |||
| a3a2b3bdc0 | |||
| 6d81449fc6 | |||
| 092d993cb7 | |||
| 98d2038fc2 | |||
| 3861f546e3 | |||
| a1f42c7c32 | |||
| a539c8a464 | |||
| db56bcbe42 | |||
| 57d6b25ec9 | |||
| e6ecd6630d | |||
| f9d18e472b | |||
| 5175b324b8 | |||
| f55a4cf80c | |||
| 0943f0bdc8 | |||
| 71be5c5c87 | |||
| fde3b1c715 | |||
| 50126644a5 | |||
| 12886632c6 | |||
| 4b11bad358 | |||
| ab5190a46c | |||
| d9883570f5 | |||
| e6a8bbbb62 | |||
| 2b6c874b13 | |||
| 8a1b87cb97 | |||
| 138eeeb1b0 | |||
| 6c5696381e | |||
| c86e51358b | |||
| 0aed84d19f | |||
| 41f89cc676 | |||
| 0d0614bdc6 | |||
| d1ab8065c1 | |||
| b7e3a326fe | |||
| dee6554811 | |||
| 893c0ffc29 | |||
| a64d5a15b7 | |||
| df737fe6f5 | |||
| aef49d7141 | |||
| 11ac84635b | |||
| a1afc7425a | |||
| e115ff8171 | |||
| 1cb90c668c | |||
| dba0cb2351 | |||
| f23da96636 | |||
| e5586a1a79 | |||
| 9d56c6df9a | |||
| 2753388e8a | |||
| 46fce002d9 | |||
| daf9a5a402 | |||
| 7909e54a22 | |||
| 23f29ec628 | |||
| aa1d67b1d9 | |||
| 99bd10979a | |||
| c00033125d | |||
| 6101d50471 | |||
| 48864df97d | |||
| b26e6c14fe | |||
| 7c49427fc2 | |||
| 5b068f8632 | |||
| c71b45e619 | |||
| d306e1a3a1 | |||
| eb97b29345 | |||
| 0e5fba790a | |||
| eecc398374 | |||
| 5d8a137218 | |||
| 339d6c6d17 | |||
| ce3ca25cbc | |||
| 5b4b255151 | |||
| a72014faf5 | |||
| 7af6547a5a | |||
| 11dcd11913 | |||
| b2d3de3bf4 | |||
| 27e6df4e41 | |||
| b19cad6b94 | |||
| 725e1ae52e | |||
| 706627b870 | |||
| 3c60421864 | |||
| f5840160b7 | |||
| 1ccce44937 | |||
| d383216383 | |||
| d7e8689078 | |||
| 7a3e147ee2 | |||
| 0fe456bb29 | |||
| 881bd79293 | |||
| b606ec52c7 | |||
| 09ff9e1664 | |||
| 3da0df9d18 | |||
| 6d235cb8d8 | |||
| 994ff6f587 | |||
| dbd4d5fc77 | |||
| fe7a5d11b6 | |||
| 5acefe7dbe | |||
| ef593f293e | |||
| 42c4bd02f4 | |||
| 459f63e7ed | |||
| a0272d8255 | |||
| cfc176973e | |||
| 77dfe91662 | |||
| b83c21e600 | |||
| e3664fb03c | |||
| e1df4e31ec | |||
| edf9a17b47 | |||
| 84fb4c22b9 | |||
| e0ac363c62 | |||
| 7015698b81 | |||
| 82e647d7c3 | |||
| 1d59d036de | |||
| 1488052d38 | |||
| 6e8a54fbd2 | |||
| 6ffb4975f7 | |||
| de97724827 | |||
| 503a686e09 | |||
| 016fff2b6e | |||
| dd1dd489d9 | |||
| 9cf37e718c | |||
| 8d0b81d764 | |||
| c9545442f9 | |||
| fbc1ddf079 | |||
| c6a67173bd | |||
| 132d93838d | |||
| f2874b0e1d | |||
| 295fc442b5 | |||
| 896f99e942 | |||
| 9138471141 | |||
| e0b605917e | |||
| 22d2730047 | |||
| b88e24fd59 | |||
| 87ade19eb9 | |||
| bc1a3c6ce2 | |||
| f38b65a85d | |||
| 51f0b6d568 |
+12
-1
@@ -357,6 +357,7 @@ TESTSRC = \
|
||||
$(TOP)/src/test_config.c \
|
||||
$(TOP)/src/test_demovfs.c \
|
||||
$(TOP)/src/test_devsym.c \
|
||||
$(TOP)/src/test_fs.c \
|
||||
$(TOP)/src/test_func.c \
|
||||
$(TOP)/src/test_fuzzer.c \
|
||||
$(TOP)/src/test_hexio.c \
|
||||
@@ -501,6 +502,11 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||
-o $@ $(TOP)/src/shell.c libsqlite3.la \
|
||||
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
# build on the target system. Some of the C source code and header
|
||||
@@ -518,6 +524,7 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||
|
||||
sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
|
||||
cp tsrc/shell.c tsrc/sqlite3ext.h .
|
||||
|
||||
tclsqlite3.c: sqlite3.c
|
||||
echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
|
||||
@@ -877,7 +884,8 @@ TESTFIXTURE_FLAGS += -DBUILD_sqlite
|
||||
|
||||
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
|
||||
TESTFIXTURE_SRC1 = sqlite3.c
|
||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
|
||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
|
||||
|
||||
testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
|
||||
@@ -943,8 +951,11 @@ clean:
|
||||
rm -f testfixture$(TEXE) test.db
|
||||
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
|
||||
rm -f sqlite3.c
|
||||
rm -f sqlite3rc.h
|
||||
rm -f shell.c sqlite3ext.h
|
||||
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
|
||||
rm -f sqlite-*-output.vsix
|
||||
rm -f mptester mptester.exe
|
||||
|
||||
distclean: clean
|
||||
rm -f config.log config.status libtool Makefile sqlite3.pc
|
||||
|
||||
@@ -813,6 +813,10 @@ sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
|
||||
$(TOP)\src\shell.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
||||
mptester.exe: $(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
|
||||
$(LTLINK) $(TOP)\mptest\mptest.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
# build on the target system. Some of the C source code and header
|
||||
@@ -830,6 +834,8 @@ sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
|
||||
|
||||
sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl
|
||||
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
|
||||
copy tsrc\shell.c .
|
||||
copy tsrc\sqlite3ext.h .
|
||||
|
||||
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
|
||||
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
|
||||
@@ -1248,8 +1254,10 @@ clean:
|
||||
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
|
||||
del /Q sqlite3.c
|
||||
del /Q sqlite3rc.h
|
||||
del /Q shell.c sqlite3ext.h
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
|
||||
del /Q sqlite-*-output.vsix
|
||||
del /Q mptester.exe
|
||||
|
||||
# Dynamic link library section.
|
||||
#
|
||||
|
||||
@@ -662,4 +662,6 @@ clean:
|
||||
rm -rf tsrc target_source
|
||||
rm -f testloadext.dll libtestloadext.so
|
||||
rm -f sqlite3.c fts?amal.c tclsqlite3.c
|
||||
rm -f sqlite3rc.h
|
||||
rm -f shell.c sqlite3ext.h
|
||||
rm -f $(SHPREFIX)sqlite3.$(SO)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.7.16.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.7.17.
|
||||
#
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.7.16'
|
||||
PACKAGE_STRING='sqlite 3.7.16'
|
||||
PACKAGE_VERSION='3.7.17'
|
||||
PACKAGE_STRING='sqlite 3.7.17'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@@ -1484,7 +1484,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.7.16 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.7.17 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1549,7 +1549,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.7.16:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.7.17:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1665,7 +1665,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.7.16
|
||||
sqlite configure 3.7.17
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
@@ -1679,7 +1679,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.7.16, which was
|
||||
It was created by sqlite $as_me 3.7.17, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -14032,7 +14032,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.7.16, which was
|
||||
This file was extended by sqlite $as_me 3.7.17, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -14085,7 +14085,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.7.16
|
||||
sqlite config.status 3.7.17
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** This is the header file for the generic hash-table implementation
|
||||
** used in SQLite. We've modified it slightly to serve as a standalone
|
||||
** hash table implementation for the full-text indexing module.
|
||||
**
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** This is the header file for the generic hash-table implementation
|
||||
** used in SQLite. We've modified it slightly to serve as a standalone
|
||||
** hash table implementation for the full-text indexing module.
|
||||
**
|
||||
|
||||
+2
-2
@@ -6779,7 +6779,7 @@ void sqlite3Fts2IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
|
||||
int sqlite3Fts2InitHashTable(sqlite3 *, fts2Hash *, const char *);
|
||||
|
||||
/*
|
||||
** Initialise the fts2 extension. If this extension is built as part
|
||||
** Initialize the fts2 extension. If this extension is built as part
|
||||
** of the sqlite library, then this function is called directly by
|
||||
** SQLite. If fts2 is built as a dynamically loadable extension, this
|
||||
** function is called by the sqlite3_extension_init() entry point.
|
||||
@@ -6797,7 +6797,7 @@ int sqlite3Fts2Init(sqlite3 *db){
|
||||
sqlite3Fts2IcuTokenizerModule(&pIcu);
|
||||
#endif
|
||||
|
||||
/* Allocate and initialise the hash-table used to store tokenizers. */
|
||||
/* Allocate and initialize the hash-table used to store tokenizers. */
|
||||
pHash = sqlite3_malloc(sizeof(fts2Hash));
|
||||
if( !pHash ){
|
||||
rc = SQLITE_NOMEM;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** This is the header file for the generic hash-table implementation
|
||||
** used in SQLite. We've modified it slightly to serve as a standalone
|
||||
** hash table implementation for the full-text indexing module.
|
||||
**
|
||||
|
||||
@@ -319,7 +319,7 @@ static void intTestFunc(
|
||||
/*
|
||||
** Set up SQL objects in database db used to access the contents of
|
||||
** the hash table pointed to by argument pHash. The hash table must
|
||||
** been initialised to use string keys, and to take a private copy
|
||||
** been initialized to use string keys, and to take a private copy
|
||||
** of the key when a value is inserted. i.e. by a call similar to:
|
||||
**
|
||||
** sqlite3Fts2HashInit(pHash, FTS2_HASH_STRING, 1);
|
||||
|
||||
@@ -70,7 +70,7 @@ struct sqlite3_tokenizer_module {
|
||||
** This method should return either SQLITE_OK (0), or an SQLite error
|
||||
** code. If SQLITE_OK is returned, then *ppTokenizer should be set
|
||||
** to point at the newly created tokenizer structure. The generic
|
||||
** sqlite3_tokenizer.pModule variable should not be initialised by
|
||||
** sqlite3_tokenizer.pModule variable should not be initialized by
|
||||
** this callback. The caller will do so.
|
||||
*/
|
||||
int (*xCreate)(
|
||||
|
||||
+5
-5
@@ -1571,7 +1571,7 @@ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
|
||||
}else{
|
||||
rc = sqlite3_reset(pCsr->pStmt);
|
||||
if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
|
||||
/* If no row was found and no error has occured, then the %_content
|
||||
/* If no row was found and no error has occurred, then the %_content
|
||||
** table is missing a row that is present in the full-text index.
|
||||
** The data structures are corrupt. */
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
@@ -2811,7 +2811,7 @@ static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){
|
||||
}
|
||||
|
||||
/*
|
||||
** This function retreives the doclist for the specified term (or term
|
||||
** This function retrieves the doclist for the specified term (or term
|
||||
** prefix) from the database.
|
||||
*/
|
||||
static int fts3TermSelect(
|
||||
@@ -3562,7 +3562,7 @@ void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Initialise the fts3 extension. If this extension is built as part
|
||||
** Initialize the fts3 extension. If this extension is built as part
|
||||
** of the sqlite library, then this function is called directly by
|
||||
** SQLite. If fts3 is built as a dynamically loadable extension, this
|
||||
** function is called by the sqlite3_extension_init() entry point.
|
||||
@@ -3596,7 +3596,7 @@ int sqlite3Fts3Init(sqlite3 *db){
|
||||
sqlite3Fts3SimpleTokenizerModule(&pSimple);
|
||||
sqlite3Fts3PorterTokenizerModule(&pPorter);
|
||||
|
||||
/* Allocate and initialise the hash-table used to store tokenizers. */
|
||||
/* Allocate and initialize the hash-table used to store tokenizers. */
|
||||
pHash = sqlite3_malloc(sizeof(Fts3Hash));
|
||||
if( !pHash ){
|
||||
rc = SQLITE_NOMEM;
|
||||
@@ -5195,7 +5195,7 @@ int sqlite3Fts3EvalPhraseStats(
|
||||
** of the current row.
|
||||
**
|
||||
** More specifically, the returned buffer contains 1 varint for each
|
||||
** occurence of the phrase in the column, stored using the normal (delta+2)
|
||||
** occurrence of the phrase in the column, stored using the normal (delta+2)
|
||||
** compression and is terminated by either an 0x01 or 0x00 byte. For example,
|
||||
** if the requested column contains "a b X c d X X" and the position-list
|
||||
** for 'X' is requested, the buffer returned may contain:
|
||||
|
||||
@@ -106,7 +106,7 @@ struct ParseContext {
|
||||
** This function is equivalent to the standard isspace() function.
|
||||
**
|
||||
** The standard isspace() can be awkward to use safely, because although it
|
||||
** is defined to accept an argument of type int, its behaviour when passed
|
||||
** is defined to accept an argument of type int, its behavior when passed
|
||||
** an integer that falls outside of the range of the unsigned char type
|
||||
** is undefined (and sometimes, "undefined" means segfault). This wrapper
|
||||
** is defined to accept an argument of type char, and always returns 0 for
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** This is the header file for the generic hash-table implementation
|
||||
** used in SQLite. We've modified it slightly to serve as a standalone
|
||||
** hash table implementation for the full-text indexing module.
|
||||
**
|
||||
|
||||
@@ -389,9 +389,9 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
||||
** is the snippet with the highest score, where scores are calculated
|
||||
** by adding:
|
||||
**
|
||||
** (a) +1 point for each occurence of a matchable phrase in the snippet.
|
||||
** (a) +1 point for each occurrence of a matchable phrase in the snippet.
|
||||
**
|
||||
** (b) +1000 points for the first occurence of each matchable phrase in
|
||||
** (b) +1000 points for the first occurrence of each matchable phrase in
|
||||
** the snippet for which the corresponding mCovered bit is not set.
|
||||
**
|
||||
** The selected snippet parameters are stored in structure *pFragment before
|
||||
|
||||
@@ -267,7 +267,7 @@ static int fts3_near_match_cmd(
|
||||
**
|
||||
** Whether or not the arguments are present, this command returns a list of
|
||||
** two integers - the initial chunksize and threshold when the command is
|
||||
** invoked. This can be used to restore the default behaviour after running
|
||||
** invoked. This can be used to restore the default behavior after running
|
||||
** tests. For example:
|
||||
**
|
||||
** # Override incr-load settings for testing:
|
||||
|
||||
@@ -428,7 +428,7 @@ static void intTestFunc(
|
||||
/*
|
||||
** Set up SQL objects in database db used to access the contents of
|
||||
** the hash table pointed to by argument pHash. The hash table must
|
||||
** been initialised to use string keys, and to take a private copy
|
||||
** been initialized to use string keys, and to take a private copy
|
||||
** of the key when a value is inserted. i.e. by a call similar to:
|
||||
**
|
||||
** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
|
||||
|
||||
@@ -70,7 +70,7 @@ struct sqlite3_tokenizer_module {
|
||||
** This method should return either SQLITE_OK (0), or an SQLite error
|
||||
** code. If SQLITE_OK is returned, then *ppTokenizer should be set
|
||||
** to point at the newly created tokenizer structure. The generic
|
||||
** sqlite3_tokenizer.pModule variable should not be initialised by
|
||||
** sqlite3_tokenizer.pModule variable should not be initialized by
|
||||
** this callback. The caller will do so.
|
||||
*/
|
||||
int (*xCreate)(
|
||||
|
||||
@@ -125,7 +125,7 @@ static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
|
||||
**
|
||||
** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic()
|
||||
** identifies as a diacritic) occurs in the zIn/nIn string it is ignored.
|
||||
** It is not possible to change the behaviour of the tokenizer with respect
|
||||
** It is not possible to change the behavior of the tokenizer with respect
|
||||
** to these codepoints.
|
||||
*/
|
||||
static int unicodeAddExceptions(
|
||||
|
||||
+18
-10
@@ -1482,6 +1482,7 @@ static int fts3SegReaderNextDocid(
|
||||
*pnOffsetList = (int)(p - pReader->pOffsetList - 1);
|
||||
}
|
||||
|
||||
/* List may have been edited in place by fts3EvalNearTrim() */
|
||||
while( p<pEnd && *p==0 ) p++;
|
||||
|
||||
/* If there are no more entries in the doclist, set pOffsetList to
|
||||
@@ -2497,9 +2498,13 @@ static int fts3DeleteSegdir(
|
||||
**
|
||||
** If there are no entries in the input position list for column iCol, then
|
||||
** *pnList is set to zero before returning.
|
||||
**
|
||||
** If parameter bZero is non-zero, then any part of the input list following
|
||||
** the end of the output list is zeroed before returning.
|
||||
*/
|
||||
static void fts3ColumnFilter(
|
||||
int iCol, /* Column to filter on */
|
||||
int bZero, /* Zero out anything following *ppList */
|
||||
char **ppList, /* IN/OUT: Pointer to position list */
|
||||
int *pnList /* IN/OUT: Size of buffer *ppList in bytes */
|
||||
){
|
||||
@@ -2528,6 +2533,9 @@ static void fts3ColumnFilter(
|
||||
p += sqlite3Fts3GetVarint32(p, &iCurrent);
|
||||
}
|
||||
|
||||
if( bZero && &pList[nList]!=pEnd ){
|
||||
memset(&pList[nList], 0, pEnd - &pList[nList]);
|
||||
}
|
||||
*ppList = pList;
|
||||
*pnList = nList;
|
||||
}
|
||||
@@ -2601,19 +2609,19 @@ int sqlite3Fts3MsrIncrNext(
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
|
||||
|
||||
if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
|
||||
rc = fts3MsrBufferData(pMsr, pList, nList+1);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
|
||||
pList = pMsr->aBuffer;
|
||||
}
|
||||
|
||||
if( pMsr->iColFilter>=0 ){
|
||||
fts3ColumnFilter(pMsr->iColFilter, &pList, &nList);
|
||||
fts3ColumnFilter(pMsr->iColFilter, 1, &pList, &nList);
|
||||
}
|
||||
|
||||
if( nList>0 ){
|
||||
if( fts3SegReaderIsPending(apSegment[0]) ){
|
||||
rc = fts3MsrBufferData(pMsr, pList, nList+1);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
*paPoslist = pMsr->aBuffer;
|
||||
assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
|
||||
}else{
|
||||
*paPoslist = pList;
|
||||
}
|
||||
*paPoslist = pList;
|
||||
*piDocid = iDocid;
|
||||
*pnPoslist = nList;
|
||||
break;
|
||||
@@ -2856,7 +2864,7 @@ int sqlite3Fts3SegReaderStep(
|
||||
}
|
||||
|
||||
if( isColFilter ){
|
||||
fts3ColumnFilter(pFilter->iCol, &pList, &nList);
|
||||
fts3ColumnFilter(pFilter->iCol, 0, &pList, &nList);
|
||||
}
|
||||
|
||||
if( !isIgnoreEmpty || nList>0 ){
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ SQLite. Documentation follows.
|
||||
<string> REGEXP <re-pattern>
|
||||
|
||||
This extension uses the ICU defaults for regular expression matching
|
||||
behaviour. Specifically, this means that:
|
||||
behavior. Specifically, this means that:
|
||||
|
||||
* Matching is case-sensitive,
|
||||
* Regular expression comments are not allowed within patterns, and
|
||||
|
||||
+1
-1
@@ -2665,7 +2665,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
|
||||
RtreeNode *pRoot; /* Root node of rtree structure */
|
||||
|
||||
|
||||
/* Obtain a reference to the root node to initialise Rtree.iDepth */
|
||||
/* Obtain a reference to the root node to initialize Rtree.iDepth */
|
||||
rc = nodeAcquire(pRtree, 1, 0, &pRoot);
|
||||
|
||||
/* Obtain a reference to the leaf node that contains the entry
|
||||
|
||||
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
|
||||
}
|
||||
source [file join [file dirname [info script]] rtree_util.tcl]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix rtree1
|
||||
|
||||
# Test plan:
|
||||
#
|
||||
|
||||
@@ -61,7 +61,7 @@ do_test rtree5-1.9 {
|
||||
do_test rtree5-1.10 {
|
||||
execsql { SELECT (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5 }
|
||||
} {2147483643 2147483647 -2147483648 -2147483643}
|
||||
do_test rtree5-1.10 {
|
||||
do_test rtree5-1.11 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(2, (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5)
|
||||
}
|
||||
|
||||
@@ -365,6 +365,10 @@ sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
|
||||
$(TOP)/src/shell.c \
|
||||
libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) $(THREADLIB)
|
||||
|
||||
sqlite3.o: sqlite3.c
|
||||
$(TCCX) -c sqlite3.c
|
||||
|
||||
@@ -385,6 +389,7 @@ target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl
|
||||
|
||||
sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl
|
||||
tclsh $(TOP)/tool/mksqlite3c.tcl
|
||||
cp tsrc/shell.c tsrc/sqlite3ext.h .
|
||||
echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
|
||||
cat sqlite3.c >>tclsqlite3.c
|
||||
echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
|
||||
@@ -621,5 +626,8 @@ clean:
|
||||
rm -f testfixture testfixture.exe
|
||||
rm -f threadtest3 threadtest3.exe
|
||||
rm -f sqlite3.c fts?amal.c tclsqlite3.c
|
||||
rm -f sqlite3rc.h
|
||||
rm -f shell.c sqlite3ext.h
|
||||
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
|
||||
rm -f sqlite-*-output.vsix
|
||||
rm -f mptester mptester.exe
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C Two\snew\sSQL\sfunctions:\sunicode()\sand\schar().
|
||||
D 2013-02-22T19:34:25.685
|
||||
C Expand\sscope\sof\sthe\sSQLITE_DISABLE_MMAP\sdefine\sfor\sthe\sWin32\sVFS.
|
||||
D 2013-04-11T22:52:44.089
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282
|
||||
F Makefile.in 3dd3fcb87b70c78d99b2c8a03e44ec86d6ca9ce2
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 1bed3bca025ee90441bb0c9f95f36f42b70bd839
|
||||
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
|
||||
F Makefile.msc a244e5b5ba2493625db95b4d46b79201ea868bfe
|
||||
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
F VERSION 6d4f66eaebabc42ef8c2a4d2d0caf4ce7ee81137
|
||||
F VERSION 05c7bd63b96f31cfdef5c766ed91307ac121f5aa
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 00d3a5fda47ee7dd3e68dc9dad7eeb439cd1ffea x
|
||||
F configure 8bb8bd13d3c918c4c1c73480930e81f955ac298a x
|
||||
F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
@@ -27,11 +27,11 @@ F ext/async/sqlite3async.c b5a3e30f538a9ffe81538b3063b4d5963f9bb422
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
||||
F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
|
||||
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
|
||||
F ext/fts1/fts1.c 3e7b253e61aab0bb1fea808c7a0ce36c19432acc
|
||||
F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6
|
||||
F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
|
||||
F ext/fts1/fts1_hash.h 957d378355ed29f672cd5add012ce8b088a5e089
|
||||
F ext/fts1/fts1_hash.h e7f0d761353996a8175eda351104acfde23afcb0
|
||||
F ext/fts1/fts1_porter.c b1c7304b8988ba3f764a147cdd32043b4913ea7b
|
||||
F ext/fts1/fts1_tokenizer.h fdea722c38a9f82ed921642981234f666e47919c
|
||||
F ext/fts1/fts1_tokenizer1.c fd00d1fe4dc30dfc5c64cba695ce34f4af20d2fa
|
||||
@@ -41,55 +41,55 @@ F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
|
||||
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
|
||||
F ext/fts2/README.tokenizers 21e3684ea5a095b55d70f6878b4ce6af5932dfb7
|
||||
F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts2/fts2.c 4ef7d7ecf590da0dd416ac54612c53a7d4175790
|
||||
F ext/fts2/fts2.c b48cc0bb657c0a421f4067b79aa0354bd16a046d
|
||||
F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa
|
||||
F ext/fts2/fts2_hash.c 2689e42e1107ea67207f725cf69cf8972d00cf93
|
||||
F ext/fts2/fts2_hash.h 9a5b1be94664139f93217a0770d7144425cffb3a
|
||||
F ext/fts2/fts2_hash.h 1824b99dfd8d0225facbdb26a2c87289b2e7dcf8
|
||||
F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188
|
||||
F ext/fts2/fts2_porter.c 747056987951f743e955c8479f1df21a565720fe
|
||||
F ext/fts2/fts2_tokenizer.c 26e993a00b2bd5b6e73c155597361710b12ffe25
|
||||
F ext/fts2/fts2_tokenizer.h a7e46462d935a314b2682287f12f27530a3ee08e
|
||||
F ext/fts2/fts2_tokenizer.c a86d08c9634fabfa237c8f379008de2e11248d36
|
||||
F ext/fts2/fts2_tokenizer.h 27a1a99ca2d615cf7e142839b8d79e8751b4529e
|
||||
F ext/fts2/fts2_tokenizer1.c 0123d21078e053bd98fd6186c5c6dc6d67969f2e
|
||||
F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
|
||||
F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c a867cafae0235324df64c5775cbf352a3f712cb9
|
||||
F ext/fts3/fts3.c 0eaedfc6d2eb22563ef1d044dcfed93b70ec79f2
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 1e58825246b56259267382d2f9902774c049460a
|
||||
F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e
|
||||
F ext/fts3/fts3_expr.c ceefcaf91344abbf6ceb3cadf404eef5be6924e6
|
||||
F ext/fts3/fts3_expr.c 6cb4410f87676ae633bd7923bbc78526cb839c4d
|
||||
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
|
||||
F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||
F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3
|
||||
F ext/fts3/fts3_snippet.c f6ebb3536069ceaa27e9f178f4a59379db44ac10
|
||||
F ext/fts3/fts3_snippet.c 5fcfcafff46a2a3a63b8e59fcb51987d01c74695
|
||||
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
|
||||
F ext/fts3/fts3_test.c 348f7d08cae05285794e23dc4fe8b8fdf66e264a
|
||||
F ext/fts3/fts3_tokenizer.c 3664bb8836ab7633cf9da786c9d6fd366be5ae2c
|
||||
F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68
|
||||
F ext/fts3/fts3_test.c f9a1a1702db1bfad3e2d0064746eeb808f125489
|
||||
F ext/fts3/fts3_tokenizer.c bbdc731bc91338050675c6d1da9ab82147391e16
|
||||
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559
|
||||
F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9
|
||||
F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896
|
||||
F ext/fts3/fts3_write.c c2166f7148a4ad8bcdad99a99d647b1091744e6b
|
||||
F ext/fts3/fts3_write.c d92c6cbe07363791cfe8b62b4dee67e6f8afc9e2
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
|
||||
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
|
||||
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl 7a9bc018e2962abb79563c5a39fe581fcbf2f675
|
||||
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
|
||||
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
|
||||
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c ebd07d0f06dc167f1424ff3940a5711a3a039982
|
||||
F ext/rtree/rtree.c 757abea591d4ff67c0ff4e8f9776aeda86b18c14
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
|
||||
F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc
|
||||
F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
|
||||
F ext/rtree/rtree5.test 9a229678a00f40e6aedb40cb3a07ec5444af892c
|
||||
F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e
|
||||
F ext/rtree/rtree6.test 3ff9113b4a872fa935309e3511cd9b7cdb4d2472
|
||||
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
|
||||
F ext/rtree/rtree8.test 9772e16da71e17e02bdebf0a5188590f289ab37d
|
||||
@@ -103,47 +103,53 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F main.mk 404cd38114d1a94ef6ad5aa01a1c8bb46da36161
|
||||
F main.mk dcb05737414488383369b93e33cf1a1484c4b6e6
|
||||
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
|
||||
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3f4ddeb152a4f83872f0fa7fcb48d9fd609893da
|
||||
F mptest/config02.test 962913ed2b537d60de4126db7fe54716865cdd22
|
||||
F mptest/crash01.test a5f31998ed48de8267d6620e8af107ec148e5f12
|
||||
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
|
||||
F mptest/mptest.c 53066ffe4ae6f0c4de451cc77985b88d0fee2aec
|
||||
F mptest/multiwrite01.test 81fbc17657964889b60750bd7bbb1deffe8f4d42
|
||||
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
|
||||
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
|
||||
F src/attach.c ea5247f240e2c08afd608e9beb380814b86655e1
|
||||
F src/analyze.c d5f895810e8ff9737c9ec7b76abc3dcff5860335
|
||||
F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 32e35a3a4ea55b45c0e5f74eeb793aec71491517
|
||||
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
|
||||
F src/backup.c b266767351ae2d847716c56fcb2a1fea7c761c03
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 7a80e4a67f32a2494c383a28a495bf3bd71cc230
|
||||
F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd
|
||||
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
|
||||
F src/build.c 73ca65f32938e4e0d94e831b61b5749b211b79be
|
||||
F src/btree.c 5f2c4fe72f663bba837c5d01a732799c1d1c93f8
|
||||
F src/btree.h d9490cd37aaeb530a41b07f06e1262950b1be916
|
||||
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
||||
F src/build.c 083da8466fd7e481cb8bd5264398f537507f6176
|
||||
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
|
||||
F src/ctime.c 61a53c7e0db5e7ba60cf23b73deaf6779aa715d3
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c 9b8d308979114991e5dc7cee958316e07186941d
|
||||
F src/expr.c f6c20285bd36e87ec47f4d840e90a32755e2a90c
|
||||
F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778
|
||||
F src/expr.c 48048fca951eedbc74aa32262154410d56c83812
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e16942bd5c8a868ac53287886464a5ed0e72b179
|
||||
F src/func.c 18b120b9a34daf6d38d50969b6f3471c09b2934a
|
||||
F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a
|
||||
F src/func.c d3fdcff9274bc161152e67ed3f626841c247f4b9
|
||||
F src/global.c d2494a1cea8f66a2cab8258449df07f8f0ae6330
|
||||
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
|
||||
F src/main.c 8d204866d1abf5100503dcd54d3187b88f6846b7
|
||||
F src/loadext.c 1422eba4aa2b1fb5f7b3aef574752272477d21e2
|
||||
F src/main.c 54a841854734b6731c4d026834788cac6a19f3d1
|
||||
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
|
||||
@@ -157,50 +163,50 @@ F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
|
||||
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
|
||||
F src/mutex_w32.c 32a9b3841e2d757355f0012b860b1bc5e01eafa0
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
|
||||
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
|
||||
F src/os.c ca679b293a6233327e418fd1dde2cd5db3e90932
|
||||
F src/os.h ae08bcc5f6ec6b339f4a2adf3931bb88cc14c3e4
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c dfdc04b126f7b05dcb2e2cc5c1262f98acbb49d9
|
||||
F src/os_win.c eabd00b813577d36bd66271cb08dd64ea0589dac
|
||||
F src/pager.c 4092c907222cfd451c74fe6bd2fd64b342f7190f
|
||||
F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0
|
||||
F src/os_unix.c 5707fcb125f043e2d3376ea862e8ec83633c5e0e
|
||||
F src/os_win.c 190be0e689be61b3dcb8c1d253bc967e09c1866e
|
||||
F src/pager.c 28f45e60d9a173368872d6e688e7a848c3926344
|
||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||
F src/parse.y 5d5e12772845805fdfeb889163516b84fbb9ae95
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
|
||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
|
||||
F src/pragma.c bdb484d0283965c431d4153f28c30f836a1f16b1
|
||||
F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
|
||||
F src/pragma.c 216d6c24520f7b2e267a2356e5d3269d28690f49
|
||||
F src/prepare.c 743e484233c51109666d402f470523553b41797c
|
||||
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 652ae6dc0f185b01b4536bb2fa7d878f13f0f1df
|
||||
F src/resolve.c 9079da7d59aed2bb14ec8315bc7f720dd85b5b65
|
||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||
F src/select.c e1c6f6abdf9f359f4e735cb8ae11d2f359bf52a9
|
||||
F src/shell.c 7c41bfcd9e5bf9d96b9215f79b03a5b2b44a3bca
|
||||
F src/sqlite.h.in 6296506a8fba279d8fa31f4abf01ab0cc92738a6
|
||||
F src/select.c 01540bcd3df3c8f1187158e77986028b1c667258
|
||||
F src/shell.c 319b7791cee6c763b60fde1b590bfaf62613cf37
|
||||
F src/sqlite.h.in f606903594d314d1b63e677affb1a03e3c9a49c7
|
||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||
F src/sqlite3ext.h 7183ab832e23db0f934494f16928da127a571d75
|
||||
F src/sqliteInt.h 601c887f6d9c92e75551873c0a34711fff745bed
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/sqliteInt.h 1c517a89cfdba28084093607ec79af70359c7f9b
|
||||
F src/sqliteLimit.h 3ea5c07b370b8033c30f66515ccf4e875c252429
|
||||
F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c 3213f3101e3b85f047d6e389da5a53d76d3d7540
|
||||
F src/test1.c 50003e3beccad5569f757598fc7ce81b4f21aa7e
|
||||
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
|
||||
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
|
||||
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
|
||||
F src/tclsqlite.c 9a716c737590d2f129d71c8fc7065e5aba0e7222
|
||||
F src/test1.c 6784fdacb35c33ba564ef749b62c4718fe515484
|
||||
F src/test2.c 29e7154112f7448d64204e8d31179cf497ecf425
|
||||
F src/test3.c 96aed72a8e1d542fed127e3e8350ae357712fa82
|
||||
F src/test4.c cea2c55110241e4674e66d476d29c914627999f5
|
||||
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
|
||||
F src/test6.c 938794c970ed6810036c8d28450ca28166524bf7
|
||||
F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
|
||||
F src/test6.c a437f76f9874d2563352a7e6cd0d43217663c220
|
||||
F src/test7.c f4b894b7931f8cf9f5cbf37cfa0727703f526a40
|
||||
F src/test8.c 58ea1d9698f3947e4662107ef98f429e84ae20e0
|
||||
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_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
|
||||
F src/test_config.c 09781397ccc24268cb895be0d4c21b4aad651486
|
||||
F src/test_config.c b6f5d680f0cf03d0ae9d6165bd2e447d9b356e4a
|
||||
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_fs.c 1c51e203b2c20235d8c3739f8c1fb13a7502915b
|
||||
F src/test_fs.c 8f786bfd0ad48030cf2a06fb1f050e9c60a150d7
|
||||
F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
|
||||
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
@@ -210,49 +216,49 @@ F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169
|
||||
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
F src/test_malloc.c 6982a357a6a6c24f281b91c89303a5c31075c392
|
||||
F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d
|
||||
F src/test_multiplex.c 0decc630b683979cb32d4b965efd90b6e55a786e
|
||||
F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8
|
||||
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
|
||||
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
|
||||
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 0e0e2e3bf6766b101ecccd8c042b66e44e9be8f5
|
||||
F src/test_quota.c 1ec82e02fd3643899e9a5de9684515e84641c91f
|
||||
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||
F src/test_regexp.c 58e0349f155bc307dfa209df4b03add0a7749866
|
||||
F src/test_regexp.c 06ae8138d41a793330f62351283dd6f6f21104f4
|
||||
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
|
||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
|
||||
F src/test_spellfix.c 83abe9d8c364cdd5f93bc06eaf40a349ebbf6c5c
|
||||
F src/test_sqllog.c 8acb843ddb9928dea8962e31bb09f421a72ffccb
|
||||
F src/test_spellfix.c 56dfa6d583ac34f61af0834d7b58d674e7e18e13
|
||||
F src/test_sqllog.c bc50e5afeb7fb50e77b4594e42302df9d05446aa
|
||||
F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
|
||||
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
|
||||
F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae
|
||||
F src/test_syscall.c 7e8293e4e6971b0f44c7f7f37b1315a8cc9f6018
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4
|
||||
F src/test_vfs.c c6260ef238c1142c8f8bd402db02216afd182ae3
|
||||
F src/test_vfs.c 8e6087a8b3dcc260282074b0efba14b76311120c
|
||||
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
|
||||
F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
|
||||
F src/trigger.c cd95ac64efa60e39faf9b5597443192ff27a22fa
|
||||
F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef
|
||||
F src/update.c a2a5631d618cbe240fc83725fa9e95c56ae0084c
|
||||
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
||||
F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
|
||||
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
||||
F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3
|
||||
F src/vdbe.c 292f8f7ced59c29c63fe17830cbe5f5a0230cdf0
|
||||
F src/vdbe.c 5f0047130f80c7fd0bc41bc51a653b5542c4fbd5
|
||||
F src/vdbe.h b52887278cb173e66188da84dfab216bea61119d
|
||||
F src/vdbeInt.h 396bb03eec560f768d1b86092b00f46c25575d3b
|
||||
F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c
|
||||
F src/vdbeaux.c 735a6905df302a7f3c715a82bd3af06dc7d74ef2
|
||||
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
|
||||
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
|
||||
F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9
|
||||
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
|
||||
F src/vdbeInt.h c1e830268b75f04a2901dd895b51a637a26c7045
|
||||
F src/vdbeapi.c 085cf9bf169b859a6c8fa43791702bac805cb7aa
|
||||
F src/vdbeaux.c ecb43014bcd3019e5aa2b5561e5c3a447f007a08
|
||||
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
|
||||
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
||||
F src/vdbesort.c 4fad64071ae120c25f39dcac572d716b9cadeb7f
|
||||
F src/vdbetrace.c a22263ab47f6ba4fcd176515cec1e732866b25f0
|
||||
F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
|
||||
F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2
|
||||
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
|
||||
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
||||
F src/wal.h a4d3da523d55a226a0b28e9058ef88d0a8051887
|
||||
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
|
||||
F src/where.c 43e05406f0e05960a62d4719ed77f551f8204d3f
|
||||
F src/where.c 4ad2329c439a30ddb915a780f6f80bdffafe3a64
|
||||
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
@@ -281,7 +287,7 @@ F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966
|
||||
F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test 304e82f31592820d3bde26ab6b75deaa123e1a6f
|
||||
F test/auth.test 1b21145e888130d60a03db0cb829d59df8f29266
|
||||
F test/auth2.test a2a371aa6df15f8b0c8109b33d3d7f0f73e4c9aa
|
||||
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
|
||||
F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf
|
||||
@@ -293,7 +299,7 @@ F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198
|
||||
F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62
|
||||
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
|
||||
F test/backup4.test 4d90389daeb781fe718816a4fc836ad1b06791d8
|
||||
F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0
|
||||
F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
|
||||
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
@@ -314,8 +320,9 @@ F test/boundary3.tcl 8901d6a503d0bf64251dd81cc74e5ad3add4b119
|
||||
F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
|
||||
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
|
||||
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||
F test/btreefault.test 06899a377f31a8c1a3048ec69831522d4e5c6045
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test f64136b0893c293d0b910ed057b3b711249099a7
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/capi2.test e8b18cc61090b6e5e388f54d6b125d711d1b265a
|
||||
F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
@@ -328,7 +335,7 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce
|
||||
F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49
|
||||
F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c
|
||||
F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248
|
||||
F test/collate4.test 031f7265c13308b724ba3c49f41cc04612bd92b1
|
||||
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
|
||||
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
|
||||
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
|
||||
@@ -359,7 +366,7 @@ F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
|
||||
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
|
||||
F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
|
||||
F test/crash5.test 13b9ca94e048194bca070e26160ce76b406c56be
|
||||
F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219
|
||||
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
|
||||
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
|
||||
F test/crash8.test 38767cb504bbe491de6be4a7006b154973a2309f
|
||||
@@ -369,41 +376,41 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/date.test f3228180c87bbe5d39c9397bf001c0095c3821b9
|
||||
F test/dbstatus.test 207e5b63fcb7b9c3bb8e1fdf38ebd4654ad0e54b
|
||||
F test/dbstatus2.test bf7396af964b89e39435babbcdf296ae8fc5f10a
|
||||
F test/dbstatus2.test f329941d5f4a8bc0ba6ec5735897ef0cf34e2f5f
|
||||
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
|
||||
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
|
||||
F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66
|
||||
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f
|
||||
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test 84da1414b2e6887fffd5ed571311b344c5b082ce
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721
|
||||
F test/e_createtable.test d4e17024b1831e7480f5736cf4e02516a5c90927
|
||||
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
|
||||
F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
|
||||
F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e
|
||||
F test/e_expr.test 5489424d3d9a452ac3701cdf4b680ae31a157894
|
||||
F test/e_fkey.test 89a2ff734a33693b997534eff90724573948be7b
|
||||
F test/e_fkey.test 79a985d95340c6072a884359426ce95cf33e656a
|
||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test d5331cc95e101af2508159fc98b6801631659ffe
|
||||
F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
|
||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||
F test/e_select.test 07e8d81268ba1ffcaf1dc4bec48956af150c42f9
|
||||
F test/e_select.test d5af998a402740d8f0488158d22075df2b6f88fa
|
||||
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
|
||||
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
|
||||
F test/e_uri.test bc240fbc6cbbbdff832ee05858432a25961ab36a
|
||||
F test/e_uri.test 8f2f56b29456a3f846276fa4e0993d4ef8a15b79
|
||||
F test/e_vacuum.test 331da289ae186656cf5f2eb27f577a89c0c221af
|
||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad
|
||||
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
||||
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
|
||||
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
F test/eqp.test 46aa946dd55c90635327898275d3e533d23a9845
|
||||
F test/errmsg.test 050717f1c6a5685de9c79f5f9f6b83d7c592f73a
|
||||
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
||||
F test/exclusive.test a1b324cb21834a490cd052d409d34789cfef57cb
|
||||
F test/exclusive2.test 372be98f6de44dd78734e364b7b626ea211761a6
|
||||
F test/exclusive2.test 354bdabe299a2546c898dff42f79079ff1590d88
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
||||
F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
|
||||
@@ -462,7 +469,7 @@ F test/fts3ae.test ce32a13b34b0260928e4213b4481acf801533bda
|
||||
F test/fts3af.test d394978c534eabf22dd0837e718b913fd66b499c
|
||||
F test/fts3ag.test 0b7d303f61ae5d620c4efb5e825713ea34ff9441
|
||||
F test/fts3ah.test dc9f66c32c296f1bc8bcc4535126bddfeca62894
|
||||
F test/fts3ai.test d29cee6ed653e30de478066881cec8aa766531b2
|
||||
F test/fts3ai.test 24058fdc6e9e5102c1fd8459591b114b6a85d285
|
||||
F test/fts3aj.test 0ed71e1dd9b03b843a857dc3eb9b15630e0104fc
|
||||
F test/fts3ak.test bd14deafe9d1586e8e9bf032411026ac4f8c925d
|
||||
F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f
|
||||
@@ -491,7 +498,7 @@ F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
F test/fts3malloc.test b86ea33db9e8c58c0c2f8027a9fcadaf6a1568be
|
||||
F test/fts3matchinfo.test ecb08f586d027eb03941bcfcded6cb9d8ccb3a66
|
||||
F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
|
||||
F test/fts3near.test 12895557870b0f9af7cc0be81a0171abb2d12f12
|
||||
F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1
|
||||
F test/fts3prefix2.test 477ca96e67f60745b7ac931cfa6e9b080c562da5
|
||||
F test/fts3query.test ef79d31fdb355d094baec1c1b24b60439a1fb8a2
|
||||
@@ -508,7 +515,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
|
||||
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
|
||||
F test/fts4unicode.test 25ccad45896f8e50f6a694cff738a35f798cdb40
|
||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
F test/func.test 0ea54895539c0586e86e2dcea59b05cc9e7dd6b2
|
||||
F test/func.test a4f24707e6af0bcd4cb5b856af4462db40b047b1
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
|
||||
F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
|
||||
@@ -526,7 +533,7 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
|
||||
F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3
|
||||
F test/incrblob.test 34765fa6fb5d8e0f256fc7d6497c04b205398849
|
||||
F test/incrblob.test 2100cb8964e4a106e5ca9bf80e2c5c3e8be33f77
|
||||
F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19
|
||||
F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7
|
||||
F test/incrblob4.test 09be37d3dd996a31ea6993bba7837ece549414a8
|
||||
@@ -534,12 +541,13 @@ F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597
|
||||
F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b
|
||||
F test/incrvacuum_ioerr.test 22f208d01c528403240e05beecc41dc98ed01637
|
||||
F test/incrvacuum3.test 2ffa9e4a23f072bd7902b9ae6471f8822a6522a7
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097
|
||||
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
|
||||
F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
|
||||
F test/index5.test edc8c64ca78bee140c21ce3836820fadf47906bb
|
||||
F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
|
||||
F test/indexedby.test be501e381b82b2f8ab406309ba7aac46e221f4ad
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
@@ -552,13 +560,13 @@ F test/instr.test a34e1d46a9eefb098a7167ef0e730a4a3d82fba0
|
||||
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
|
||||
F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
|
||||
F test/intpkey.test 7af30f6ae852d8d1c2b70e4bf1551946742e92d8
|
||||
F test/io.test 36d251507d72e92b965fb2f0801c2f0b56335bcf
|
||||
F test/io.test a4be25a446a99a0604ceecc039ee7363c56e4185
|
||||
F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8
|
||||
F test/ioerr2.test 9d71166f8466eda510f1af6137bdabaa82b5408d
|
||||
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test 13f0f9c31d706f0dd575995c369af07c0227e9a2
|
||||
F test/ioerr6.test cf25523b921d1a6a0e5b536cd4acb3c3d979ea52
|
||||
F test/join.test 8d63cc4d230a7affafa4b6ab0b97c49b8ccb365c
|
||||
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
@@ -590,8 +598,8 @@ F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95
|
||||
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
|
||||
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
|
||||
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test bc745155ff4252d4f35ec8316625b0dfe2abc659
|
||||
F test/malloc3.test 3e9eb921c4314acf4fb64230868fdb2e1ce60eea
|
||||
F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0
|
||||
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
@@ -605,12 +613,12 @@ F test/mallocC.test 3dffe16532f109293ce1ccecd0c31dca55ef08c4
|
||||
F test/mallocD.test f78c295e8e18ea3029e65ca08278690e00c22100
|
||||
F test/mallocE.test db1ed69d7eded1b080952e2a7c37f364ad241b08
|
||||
F test/mallocF.test 2d5c590ebc2fc7f0dcebdf5aa8498b9aed69107e
|
||||
F test/mallocG.test 4584d0d8ddb8009f16ca0c8bab1fa37f6358efa2
|
||||
F test/mallocG.test 0ff91b65c50bdaba680fb75d87fe4ad35bb7934f
|
||||
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 2930895b0962823ec679853e67e58dd6d8198b3c
|
||||
F test/malloc_common.tcl 9a98856549bfb3fab205edbc1317216edc52e70d
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6
|
||||
@@ -627,8 +635,10 @@ F test/misc3.test fe55130a43e444ee75e2156ff75dc96e964b5738
|
||||
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
|
||||
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test f00dad9a004da659330013e6f21819d018b683d3
|
||||
F test/misc7.test dd82ec9250b89178b96cd28b2aca70639d21e5b3
|
||||
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
|
||||
F test/mmap1.test f064a9025136cd688c982ccdae81c7b4fac95724
|
||||
F test/mmap2.test a5ba639f90b5fc487400a49e158e14e465943e98
|
||||
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
@@ -636,26 +646,28 @@ F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
|
||||
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
||||
F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a
|
||||
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
|
||||
F test/notify2.test 9503e51b9a272a5405c205ad61b7623d5a9ca489
|
||||
F test/notify2.test ce23eb522c9e1fff6443f96376fe67872202061c
|
||||
F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
|
||||
F test/notnull.test 2afad748d18fd66d01f66463de73b3e2501fb226
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/orderby1.test f33968647da5c546528fe4d2bf86c6a6a2e5a7ae
|
||||
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
|
||||
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
|
||||
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
|
||||
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
|
||||
F test/pager1.test 8e14e7cfd2fbfe65eabead73af10ceeb2fc676aa
|
||||
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
|
||||
F test/pager1.test 134144862f6a98f862dc2edda1b10ff499141bfa
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||
F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442
|
||||
F test/pagerfault.test bba948be0564254b823ec6ca1fd95fbbfb0839a3
|
||||
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
|
||||
F test/pagerfault3.test f16e2efcb5fc9996d1356f7cbc44c998318ae1d7
|
||||
F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
|
||||
F test/pageropt.test d6b695e6c12290c406150fc51eec32878d48df4c
|
||||
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/permutations.test 360b92859c0af814b3fe10b68746936389606501
|
||||
F test/permutations.test b6cb45ce4d3193b831231025c9d30c77317dd240
|
||||
F test/pragma.test 60d29cd3d8098a2c20bf4c072810f99e3bf2757a
|
||||
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
@@ -728,7 +740,7 @@ F test/softheap1.test c16709a16ad79fa43b32929b2e623d1d117ccf53
|
||||
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
|
||||
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
|
||||
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
|
||||
F test/speed1p.test c4a469f29f135f4d76c55b1f2a52f36e209466cc
|
||||
F test/speed1p.test b180e98609c7677382cf618c0ec9b69f789033a8
|
||||
F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded
|
||||
F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
@@ -738,21 +750,21 @@ F test/spellfix.test 52ae2680b1247c52b9e2b2116de3fd26a78e6bd2
|
||||
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
||||
F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7
|
||||
F test/subquery.test 869562de9e8c5d8147e0451a2ce5b58cf55ce389
|
||||
F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7
|
||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a
|
||||
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
|
||||
F test/syscall.test a653783d985108c4912cc64d341ffbbb55ad2806
|
||||
F test/sysfault.test 503f72712b2b21cb80dc9899e53c2e39484d0313
|
||||
F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
|
||||
F test/tester.tcl 0560b09498876da7714fff680c5d892b9228862f
|
||||
F test/tester.tcl 0d95028653ad6782e17400b7a32a046b87c67a48
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -777,12 +789,15 @@ F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||
F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9
|
||||
F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00
|
||||
F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e
|
||||
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
|
||||
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
|
||||
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
|
||||
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
|
||||
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
|
||||
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
|
||||
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
|
||||
F test/tkt-78e04e52ea.test 703e0bfb23d543edf0426a97e3bbd0ca346508ec
|
||||
F test/tkt-7a31705a7e6.test 5a7889fdb095ffbe1622413e0145de1637d421bd
|
||||
F test/tkt-7bbfb7d442.test dfa5c8097a8c353ae40705d6cddeb1f99c18b81a
|
||||
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
|
||||
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
|
||||
@@ -807,6 +822,7 @@ F test/tkt-f7b4edec.test d998a08ff2b18b7f62edce8e3044317c45efe6c7
|
||||
F test/tkt-f973c7ac31.test 1da0ed15ec2c7749fb5ce2828cd69d07153ad9f4
|
||||
F test/tkt-fa7bf5ec.test 9102dfea58aa371d78969da735f9392c57e2e035
|
||||
F test/tkt-fc62af4523.test 72825d3febdedcd5593a27989fc05accdbfc2bb4
|
||||
F test/tkt-fc7bd6358f.test 634bb4af7d661e82d6b61b80c86727bad698e08f
|
||||
F test/tkt1435.test f8c52c41de6e5ca02f1845f3a46e18e25cadac00
|
||||
F test/tkt1443.test bacc311da5c96a227bf8c167e77a30c99f8e8368
|
||||
F test/tkt1444.test a9d72f9e942708bd82dde6c707da61c489e213e9
|
||||
@@ -829,7 +845,7 @@ F test/tkt2285.test cca17be61cf600b397188e77e7143844d2b977e9
|
||||
F test/tkt2332.test fc955609b958ca86dfa102832243370a0cc84070
|
||||
F test/tkt2339.test 73bd17818924cd2ac442e5fd9916b58565739450
|
||||
F test/tkt2391.test ab7a11be7402da8b51a5be603425367aa0684567
|
||||
F test/tkt2409.test 464d55beb32e3b12ce2b4bbf9857d063c4c34297
|
||||
F test/tkt2409.test be0d60e7d283f639dccea4b0b5e1cd3a4851fb5b
|
||||
F test/tkt2450.test 77ed94863f2049c1420288ddfea2d41e5e0971d6
|
||||
F test/tkt2565.test 8be666e927cb207aae88188f31c331870878b650
|
||||
F test/tkt2640.test 28134f5d1e05658ef182520cf0b680fa3de5211b
|
||||
@@ -871,7 +887,7 @@ F test/tkt3718.test 3b59dcb5c4e7754dacd91e7fd353a61492cc402a
|
||||
F test/tkt3731.test 0c5f4cbffe102d43c3b2188af91a9e36348f974b
|
||||
F test/tkt3757.test 10cd679a88675c880533083fc79ac04324525595
|
||||
F test/tkt3761.test b95ea9c98f21cf91325f18a984887e62caceab33
|
||||
F test/tkt3762.test 2a9f3b03df44ec49ec0cfa8d5da6574c2a7853df
|
||||
F test/tkt3762.test 4d439ff7abdc8d9323150269d182c37c2d514576
|
||||
F test/tkt3773.test 7bca904d2a647a6a4a291bd86d7fd7c73855b789
|
||||
F test/tkt3791.test a6624b9a80b216a26cf473607f42f3e51898c267
|
||||
F test/tkt3793.test d90ffd75c52413908d15e1c44fc2ea9c80fcc449
|
||||
@@ -906,7 +922,7 @@ F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
|
||||
F test/trigger7.test b39e6dee1debe0ff9c2ef66326668f149f07c9c4
|
||||
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
|
||||
F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40
|
||||
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
|
||||
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
|
||||
F test/triggerC.test a7b4367392c755bc5fd5fff88011753e6b6afe90
|
||||
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
|
||||
@@ -926,7 +942,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
||||
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b
|
||||
F test/view.test 977eb3fa17b44f73fc2b636172dc9136311024ce
|
||||
F test/view.test 4057630287bfa5955628fe90a13d4c225d1c7352
|
||||
F test/vtab1.test 4403f987860ebddef1ce2de6db7216421035339d
|
||||
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
|
||||
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
|
||||
@@ -945,11 +961,11 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839
|
||||
F test/wal.test a040047d7f2b9f34bc4d597964e5e7c09609c635
|
||||
F test/wal.test 20fb8d0f8e65e50eb675994cc3a4f0e692fd4faf
|
||||
F test/wal2.test d4b470f13c87f6d8268b004380afa04c3c67cb90
|
||||
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437
|
||||
F test/wal5.test 13c980d4d8d2d6b558361f19bed4ab31d41a2c7c
|
||||
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034
|
||||
@@ -961,7 +977,7 @@ F test/walcksum.test f5447800a157c9e2234fbb8e80243f0813941bde
|
||||
F test/walcrash.test 4457436593be8c136f9148487c7dccd5e9013af2
|
||||
F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
|
||||
F test/walcrash3.test 595e44c6197f0d0aa509fc135be2fd0209d11a2c
|
||||
F test/walfault.test 97394d8de82a99f7abf1c12ed229640607fd0ad2
|
||||
F test/walfault.test 54ad6e849c727f4da463964b9eb8c8e8e155cf82
|
||||
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
|
||||
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
|
||||
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
|
||||
@@ -987,7 +1003,7 @@ F test/whereD.test 3f3ee93825c94804f1fc91eef2de0d365981759a
|
||||
F test/whereE.test 7bd34945797efef15819368479bacc34215e4e1d
|
||||
F test/whereF.test a0e296643cabe5278379bc1a0aa158cf3c54a1c9
|
||||
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
||||
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
|
||||
F test/win32lock.test 21810396eee150680cc398970839e6abdcb807b9
|
||||
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
||||
F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c
|
||||
F tool/build-all-msvc.bat 74fb6e5cca66ebdb6c9bbafb2f8b802f08146d38 x
|
||||
@@ -1005,8 +1021,8 @@ F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02
|
||||
F tool/mksqlite3c.tcl 589c7f44e990be1b8443cfe4808dce392b0327fa
|
||||
F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8
|
||||
F tool/mksqlite3c.tcl a570a0b0847f5659482087f70e409ac45ce93b91
|
||||
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
|
||||
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
|
||||
F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
@@ -1014,7 +1030,7 @@ F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
F tool/showdb.c 16960a5ce59d8b1d70dc3bdc51e2c0fe7bb91359
|
||||
F tool/showdb.c acd24ea035a3bd2ffe266f1ef8a161812c29b2f0
|
||||
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
|
||||
F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
@@ -1034,10 +1050,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P 9bd9bd9cab8c804c1a51d472199459176044a633
|
||||
R 57460c96631f0b503379401f124964ab
|
||||
T *branch * unicode-function
|
||||
T *sym-unicode-function *
|
||||
P f1b524b9d9ea3db96d54ac55c39f15e6879085bd
|
||||
R 81fda886c4b87168bc8522f21db6569f
|
||||
T *branch * winDisableMmap
|
||||
T *sym-winDisableMmap *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z ff410097880c23c389e99514cc7f5a15
|
||||
U mistachkin
|
||||
Z d00cd2eed7d26c94b83b76365b3988fe
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
209b21085b9767f10f6ffb7c7cac756fcb74ded5
|
||||
daa168f3dad995c4b7dd60e7717db90639e167c2
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
** Configure five tasks in different ways, then run tests.
|
||||
*/
|
||||
--if vfsname() GLOB 'unix'
|
||||
PRAGMA page_size=8192;
|
||||
--task 1
|
||||
PRAGMA journal_mode=PERSIST;
|
||||
PRAGMA mmap_limit=0;
|
||||
--end
|
||||
--task 2
|
||||
PRAGMA journal_mode=TRUNCATE;
|
||||
PRAGMA mmap_limit=28672;
|
||||
--end
|
||||
--task 3
|
||||
PRAGMA journal_mode=MEMORY;
|
||||
--end
|
||||
--task 4
|
||||
PRAGMA journal_mode=OFF;
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--wait all
|
||||
PRAGMA page_size=16384;
|
||||
VACUUM;
|
||||
CREATE TABLE pgsz(taskid, sz INTEGER);
|
||||
--task 1
|
||||
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 2
|
||||
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 3
|
||||
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 4
|
||||
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 5
|
||||
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--wait all
|
||||
SELECT sz FROM pgsz;
|
||||
--match 16384 16384 16384 16384 16384
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
** Configure five tasks in different ways, then run tests.
|
||||
*/
|
||||
PRAGMA page_size=512;
|
||||
--task 1
|
||||
PRAGMA mmap_limit=0;
|
||||
--end
|
||||
--task 2
|
||||
PRAGMA mmap_limit=28672;
|
||||
--end
|
||||
--task 3
|
||||
PRAGMA mmap_limit=8192;
|
||||
--end
|
||||
--task 4
|
||||
PRAGMA mmap_limit=65536;
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
PRAGMA page_size=1024;
|
||||
VACUUM;
|
||||
CREATE TABLE pgsz(taskid, sz INTEGER);
|
||||
--task 1
|
||||
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 2
|
||||
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 3
|
||||
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 4
|
||||
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 5
|
||||
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
--wait all
|
||||
SELECT sz FROM pgsz;
|
||||
--match 1024 1024 1024 1024 1024
|
||||
PRAGMA page_size=2048;
|
||||
VACUUM;
|
||||
DELETE FROM pgsz;
|
||||
--task 1
|
||||
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 2
|
||||
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 3
|
||||
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 4
|
||||
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 5
|
||||
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
--wait all
|
||||
SELECT sz FROM pgsz;
|
||||
--match 2048 2048 2048 2048 2048
|
||||
PRAGMA page_size=8192;
|
||||
VACUUM;
|
||||
DELETE FROM pgsz;
|
||||
--task 1
|
||||
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 2
|
||||
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 3
|
||||
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 4
|
||||
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 5
|
||||
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
--wait all
|
||||
SELECT sz FROM pgsz;
|
||||
--match 8192 8192 8192 8192 8192
|
||||
PRAGMA page_size=16384;
|
||||
VACUUM;
|
||||
DELETE FROM pgsz;
|
||||
--task 1
|
||||
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 2
|
||||
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 3
|
||||
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 4
|
||||
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--task 5
|
||||
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
|
||||
--end
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
--wait all
|
||||
SELECT sz FROM pgsz;
|
||||
--match 16384 16384 16384 16384 16384
|
||||
PRAGMA auto_vacuum=FULL;
|
||||
VACUUM;
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
--wait all
|
||||
PRAGMA auto_vacuum=FULL;
|
||||
PRAGMA page_size=512;
|
||||
VACUUM;
|
||||
--source multiwrite01.test
|
||||
--source crash02.subtest
|
||||
@@ -0,0 +1,102 @@
|
||||
/* Test cases involving incomplete transactions that must be rolled back.
|
||||
*/
|
||||
--task 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
--sleep 1
|
||||
INSERT INTO t1 VALUES(1, randomblob(2000));
|
||||
INSERT INTO t1 VALUES(2, randomblob(1000));
|
||||
--sleep 1
|
||||
INSERT INTO t1 SELECT a+2, randomblob(1500) FROM t1;
|
||||
INSERT INTO t1 SELECT a+4, randomblob(1500) FROM t1;
|
||||
INSERT INTO t1 SELECT a+8, randomblob(1500) FROM t1;
|
||||
--sleep 1
|
||||
INSERT INTO t1 SELECT a+16, randomblob(1500) FROM t1;
|
||||
--sleep 1
|
||||
INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1;
|
||||
SELECT count(*) FROM t1;
|
||||
--match 64
|
||||
SELECT avg(length(b)) FROM t1;
|
||||
--match 1500.0
|
||||
--sleep 2
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t1;
|
||||
--match 247
|
||||
SELECT a FROM t1 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
SELECT a FROM t1 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--wait 1
|
||||
--task 2
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t2 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t2;
|
||||
--match 247
|
||||
SELECT a FROM t2 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t2b ON t2(b);
|
||||
SELECT a FROM t2 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 3
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t3 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t3;
|
||||
--match 247
|
||||
SELECT a FROM t3 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t3b ON t3(b);
|
||||
SELECT a FROM t3 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 4
|
||||
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t4 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t4;
|
||||
--match 247
|
||||
SELECT a FROM t4 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t4b ON t4(b);
|
||||
SELECT a FROM t4 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 5
|
||||
CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t5 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t5;
|
||||
--match 247
|
||||
SELECT a FROM t5 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t5b ON t5(b);
|
||||
SELECT a FROM t5 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
|
||||
--wait all
|
||||
/* After the database file has been set up, run the crash2 subscript
|
||||
** multiple times. */
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
--source crash02.subtest
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
** This script is called from crash01.test and config02.test and perhaps other
|
||||
** script. After the database file has been set up, make a big rollback
|
||||
** journal in client 1, then crash client 1.
|
||||
** Then in the other clients, do an integrity check.
|
||||
*/
|
||||
--task 1 leave-hot-journal
|
||||
--sleep 5
|
||||
--finish
|
||||
PRAGMA cache_size=10;
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=randomblob(20000);
|
||||
UPDATE t2 SET b=randomblob(20000);
|
||||
UPDATE t3 SET b=randomblob(20000);
|
||||
UPDATE t4 SET b=randomblob(20000);
|
||||
UPDATE t5 SET b=randomblob(20000);
|
||||
UPDATE t1 SET b=NULL;
|
||||
UPDATE t2 SET b=NULL;
|
||||
UPDATE t3 SET b=NULL;
|
||||
UPDATE t4 SET b=NULL;
|
||||
UPDATE t5 SET b=NULL;
|
||||
--print Task one crashing an incomplete transaction
|
||||
--exit 1
|
||||
--end
|
||||
--task 2 integrity_check-2
|
||||
SELECT count(*) FROM t1;
|
||||
--match 64
|
||||
--sleep 100
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
--end
|
||||
--task 3 integrity_check-3
|
||||
SELECT count(*) FROM t1;
|
||||
--match 64
|
||||
--sleep 100
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
--end
|
||||
--task 4 integrity_check-4
|
||||
SELECT count(*) FROM t1;
|
||||
--match 64
|
||||
--sleep 100
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
--end
|
||||
--task 5 integrity_check-5
|
||||
SELECT count(*) FROM t1;
|
||||
--match 64
|
||||
--sleep 100
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
--end
|
||||
--wait all
|
||||
+1315
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
** This script sets up five different tasks all writing and updating
|
||||
** the database at the same time, but each in its own table.
|
||||
*/
|
||||
--task 1 build-t1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
--sleep 1
|
||||
INSERT INTO t1 VALUES(1, randomblob(2000));
|
||||
INSERT INTO t1 VALUES(2, randomblob(1000));
|
||||
--sleep 1
|
||||
INSERT INTO t1 SELECT a+2, randomblob(1500) FROM t1;
|
||||
INSERT INTO t1 SELECT a+4, randomblob(1500) FROM t1;
|
||||
INSERT INTO t1 SELECT a+8, randomblob(1500) FROM t1;
|
||||
--sleep 1
|
||||
INSERT INTO t1 SELECT a+16, randomblob(1500) FROM t1;
|
||||
--sleep 1
|
||||
INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1;
|
||||
SELECT count(*) FROM t1;
|
||||
--match 64
|
||||
SELECT avg(length(b)) FROM t1;
|
||||
--match 1500.0
|
||||
--sleep 2
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t1;
|
||||
--match 247
|
||||
SELECT a FROM t1 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
SELECT a FROM t1 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
|
||||
|
||||
--task 2 build-t2
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
--sleep 1
|
||||
INSERT INTO t2 VALUES(1, randomblob(2000));
|
||||
INSERT INTO t2 VALUES(2, randomblob(1000));
|
||||
--sleep 1
|
||||
INSERT INTO t2 SELECT a+2, randomblob(1500) FROM t2;
|
||||
INSERT INTO t2 SELECT a+4, randomblob(1500) FROM t2;
|
||||
INSERT INTO t2 SELECT a+8, randomblob(1500) FROM t2;
|
||||
--sleep 1
|
||||
INSERT INTO t2 SELECT a+16, randomblob(1500) FROM t2;
|
||||
--sleep 1
|
||||
INSERT INTO t2 SELECT a+32, randomblob(1500) FROM t2;
|
||||
SELECT count(*) FROM t2;
|
||||
--match 64
|
||||
SELECT avg(length(b)) FROM t2;
|
||||
--match 1500.0
|
||||
--sleep 2
|
||||
UPDATE t2 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t2;
|
||||
--match 247
|
||||
SELECT a FROM t2 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t2b ON t2(b);
|
||||
SELECT a FROM t2 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
|
||||
--task 3 build-t3
|
||||
DROP TABLE IF EXISTS t3;
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
--sleep 1
|
||||
INSERT INTO t3 VALUES(1, randomblob(2000));
|
||||
INSERT INTO t3 VALUES(2, randomblob(1000));
|
||||
--sleep 1
|
||||
INSERT INTO t3 SELECT a+2, randomblob(1500) FROM t3;
|
||||
INSERT INTO t3 SELECT a+4, randomblob(1500) FROM t3;
|
||||
INSERT INTO t3 SELECT a+8, randomblob(1500) FROM t3;
|
||||
--sleep 1
|
||||
INSERT INTO t3 SELECT a+16, randomblob(1500) FROM t3;
|
||||
--sleep 1
|
||||
INSERT INTO t3 SELECT a+32, randomblob(1500) FROM t3;
|
||||
SELECT count(*) FROM t3;
|
||||
--match 64
|
||||
SELECT avg(length(b)) FROM t3;
|
||||
--match 1500.0
|
||||
--sleep 2
|
||||
UPDATE t3 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t3;
|
||||
--match 247
|
||||
SELECT a FROM t3 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t3b ON t3(b);
|
||||
SELECT a FROM t3 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
|
||||
--task 4 build-t4
|
||||
DROP TABLE IF EXISTS t4;
|
||||
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||
--sleep 1
|
||||
INSERT INTO t4 VALUES(1, randomblob(2000));
|
||||
INSERT INTO t4 VALUES(2, randomblob(1000));
|
||||
--sleep 1
|
||||
INSERT INTO t4 SELECT a+2, randomblob(1500) FROM t4;
|
||||
INSERT INTO t4 SELECT a+4, randomblob(1500) FROM t4;
|
||||
INSERT INTO t4 SELECT a+8, randomblob(1500) FROM t4;
|
||||
--sleep 1
|
||||
INSERT INTO t4 SELECT a+16, randomblob(1500) FROM t4;
|
||||
--sleep 1
|
||||
INSERT INTO t4 SELECT a+32, randomblob(1500) FROM t4;
|
||||
SELECT count(*) FROM t4;
|
||||
--match 64
|
||||
SELECT avg(length(b)) FROM t4;
|
||||
--match 1500.0
|
||||
--sleep 2
|
||||
UPDATE t4 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t4;
|
||||
--match 247
|
||||
SELECT a FROM t4 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t4b ON t4(b);
|
||||
SELECT a FROM t4 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
|
||||
--task 5 build-t5
|
||||
DROP TABLE IF EXISTS t5;
|
||||
CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
|
||||
--sleep 1
|
||||
INSERT INTO t5 VALUES(1, randomblob(2000));
|
||||
INSERT INTO t5 VALUES(2, randomblob(1000));
|
||||
--sleep 1
|
||||
INSERT INTO t5 SELECT a+2, randomblob(1500) FROM t5;
|
||||
INSERT INTO t5 SELECT a+4, randomblob(1500) FROM t5;
|
||||
INSERT INTO t5 SELECT a+8, randomblob(1500) FROM t5;
|
||||
--sleep 1
|
||||
INSERT INTO t5 SELECT a+16, randomblob(1500) FROM t5;
|
||||
--sleep 1
|
||||
INSERT INTO t5 SELECT a+32, randomblob(1500) FROM t5;
|
||||
SELECT count(*) FROM t5;
|
||||
--match 64
|
||||
SELECT avg(length(b)) FROM t5;
|
||||
--match 1500.0
|
||||
--sleep 2
|
||||
UPDATE t5 SET b='x'||a||'y';
|
||||
SELECT total(length(b)) FROM t5;
|
||||
--match 247
|
||||
SELECT a FROM t5 WHERE b='x17y';
|
||||
--match 17
|
||||
CREATE INDEX t5b ON t5(b);
|
||||
SELECT a FROM t5 WHERE b='x17y';
|
||||
--match 17
|
||||
SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
|
||||
--wait all
|
||||
SELECT count(*), total(length(b)) FROM t1;
|
||||
--match 64 247
|
||||
SELECT count(*), total(length(b)) FROM t2;
|
||||
--match 64 247
|
||||
SELECT count(*), total(length(b)) FROM t3;
|
||||
--match 64 247
|
||||
SELECT count(*), total(length(b)) FROM t4;
|
||||
--match 64 247
|
||||
SELECT count(*), total(length(b)) FROM t5;
|
||||
--match 64 247
|
||||
|
||||
--task 1
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 5
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 3
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 2
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 4
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--wait all
|
||||
|
||||
--task 5
|
||||
DROP INDEX t5b;
|
||||
--sleep 5
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
CREATE INDEX t5b ON t5(b DESC);
|
||||
--end
|
||||
--task 3
|
||||
DROP INDEX t3b;
|
||||
--sleep 5
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
CREATE INDEX t3b ON t3(b DESC);
|
||||
--end
|
||||
--task 1
|
||||
DROP INDEX t1b;
|
||||
--sleep 5
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
CREATE INDEX t1b ON t1(b DESC);
|
||||
--end
|
||||
--task 2
|
||||
DROP INDEX t2b;
|
||||
--sleep 5
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
CREATE INDEX t2b ON t2(b DESC);
|
||||
--end
|
||||
--task 4
|
||||
DROP INDEX t4b;
|
||||
--sleep 5
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
CREATE INDEX t4b ON t4(b DESC);
|
||||
--end
|
||||
--wait all
|
||||
|
||||
--task 1
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 5
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 3
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 2
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 4
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--wait all
|
||||
|
||||
VACUUM;
|
||||
PRAGMA integrity_check(10);
|
||||
--match ok
|
||||
|
||||
--task 1
|
||||
UPDATE t1 SET b=randomblob(20000);
|
||||
--sleep 5
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
SELECT a FROM t1 WHERE b='x63y';
|
||||
--match 63
|
||||
--end
|
||||
--task 2
|
||||
UPDATE t2 SET b=randomblob(20000);
|
||||
--sleep 5
|
||||
UPDATE t2 SET b='x'||a||'y';
|
||||
SELECT a FROM t2 WHERE b='x63y';
|
||||
--match 63
|
||||
--end
|
||||
--task 3
|
||||
UPDATE t3 SET b=randomblob(20000);
|
||||
--sleep 5
|
||||
UPDATE t3 SET b='x'||a||'y';
|
||||
SELECT a FROM t3 WHERE b='x63y';
|
||||
--match 63
|
||||
--end
|
||||
--task 4
|
||||
UPDATE t4 SET b=randomblob(20000);
|
||||
--sleep 5
|
||||
UPDATE t4 SET b='x'||a||'y';
|
||||
SELECT a FROM t4 WHERE b='x63y';
|
||||
--match 63
|
||||
--end
|
||||
--task 5
|
||||
UPDATE t5 SET b=randomblob(20000);
|
||||
--sleep 5
|
||||
UPDATE t5 SET b='x'||a||'y';
|
||||
SELECT a FROM t5 WHERE b='x63y';
|
||||
--match 63
|
||||
--end
|
||||
--wait all
|
||||
|
||||
--task 1
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 5
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 3
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 2
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--task 4
|
||||
SELECT t1.a FROM t1, t2
|
||||
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
|
||||
ORDER BY t1.a LIMIT 4
|
||||
--match 33 34 35 36
|
||||
SELECT t3.a FROM t3, t4
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
--end
|
||||
--wait all
|
||||
+2
-2
@@ -473,7 +473,7 @@ static void analyzeOneTable(
|
||||
/* Do not gather statistics on views or virtual tables */
|
||||
return;
|
||||
}
|
||||
if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
|
||||
if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
|
||||
/* Do not gather statistics on system tables */
|
||||
return;
|
||||
}
|
||||
@@ -883,7 +883,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
if( pIndex==0 ) break;
|
||||
pIndex->aiRowEst[i] = v;
|
||||
if( *z==' ' ) z++;
|
||||
if( memcmp(z, "unordered", 10)==0 ){
|
||||
if( strcmp(z, "unordered")==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ static void attachFunc(
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the new entry in the db->aDb[] array and initialise the schema
|
||||
/* Allocate the new entry in the db->aDb[] array and initialize the schema
|
||||
** hash tables.
|
||||
*/
|
||||
if( db->aDb==db->aDbStatic ){
|
||||
@@ -126,7 +126,7 @@ static void attachFunc(
|
||||
|
||||
/* Open the database file. If the btree is successfully opened, use
|
||||
** it to obtain the database schema. At this point the schema may
|
||||
** or may not be initialised.
|
||||
** or may not be initialized.
|
||||
*/
|
||||
flags = db->openFlags;
|
||||
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
|
||||
|
||||
+20
-4
@@ -397,7 +397,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
const Pgno iSrcPg = p->iNext; /* Source page number */
|
||||
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
|
||||
DbPage *pSrcPg; /* Source page object */
|
||||
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
|
||||
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
|
||||
PAGER_ACQUIRE_READONLY);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
|
||||
sqlite3PagerUnref(pSrcPg);
|
||||
@@ -462,7 +463,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
|
||||
}
|
||||
assert( nDestTruncate>0 );
|
||||
sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
|
||||
|
||||
if( pgszSrc<pgszDest ){
|
||||
/* If the source page-size is smaller than the destination page-size,
|
||||
@@ -476,6 +476,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
*/
|
||||
const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
|
||||
sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
|
||||
Pgno iPg;
|
||||
int nDstPage;
|
||||
i64 iOff;
|
||||
i64 iEnd;
|
||||
|
||||
@@ -486,13 +488,26 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
&& iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
|
||||
));
|
||||
|
||||
/* This call ensures that all data required to recreate the original
|
||||
/* This block ensures that all data required to recreate the original
|
||||
** database has been stored in the journal for pDestPager and the
|
||||
** journal synced to disk. So at this point we may safely modify
|
||||
** the database file in any way, knowing that if a power failure
|
||||
** occurs, the original database will be reconstructed from the
|
||||
** journal file. */
|
||||
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
|
||||
sqlite3PagerPagecount(pDestPager, &nDstPage);
|
||||
for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
|
||||
if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
|
||||
DbPage *pPg;
|
||||
rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pPg);
|
||||
sqlite3PagerUnref(pPg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
|
||||
}
|
||||
|
||||
/* Write the extra pages and truncate the database file as required */
|
||||
iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
|
||||
@@ -519,6 +534,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
rc = sqlite3PagerSync(pDestPager);
|
||||
}
|
||||
}else{
|
||||
sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
|
||||
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@
|
||||
/*
|
||||
** A bitmap is an instance of the following structure.
|
||||
**
|
||||
** This bitmap records the existance of zero or more bits
|
||||
** This bitmap records the existence of zero or more bits
|
||||
** with values between 1 and iSize, inclusive.
|
||||
**
|
||||
** There are three possible representations of the bitmap.
|
||||
|
||||
+274
-140
@@ -43,6 +43,25 @@ int sqlite3BtreeTrace=1; /* True to enable tracing */
|
||||
*/
|
||||
#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1)
|
||||
|
||||
/*
|
||||
** Values passed as the 5th argument to allocateBtreePage()
|
||||
*/
|
||||
#define BTALLOC_ANY 0 /* Allocate any page */
|
||||
#define BTALLOC_EXACT 1 /* Allocate exact page if possible */
|
||||
#define BTALLOC_LE 2 /* Allocate any page <= the parameter */
|
||||
|
||||
/*
|
||||
** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not
|
||||
** defined, or 0 if it is. For example:
|
||||
**
|
||||
** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum);
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
#define IfNotOmitAV(expr) (expr)
|
||||
#else
|
||||
#define IfNotOmitAV(expr) 0
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
/*
|
||||
** A list of BtShared objects that are eligible for participation
|
||||
@@ -556,6 +575,19 @@ static void btreeClearHasContent(BtShared *pBt){
|
||||
pBt->pHasContent = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Release all of the apPage[] pages for a cursor.
|
||||
*/
|
||||
static void btreeReleaseAllCursorPages(BtCursor *pCur){
|
||||
int i;
|
||||
for(i=0; i<=pCur->iPage; i++){
|
||||
releasePage(pCur->apPage[i]);
|
||||
pCur->apPage[i] = 0;
|
||||
}
|
||||
pCur->iPage = -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Save the current cursor position in the variables BtCursor.nKey
|
||||
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
|
||||
@@ -595,12 +627,7 @@ static int saveCursorPosition(BtCursor *pCur){
|
||||
assert( !pCur->apPage[0]->intKey || !pCur->pKey );
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
int i;
|
||||
for(i=0; i<=pCur->iPage; i++){
|
||||
releasePage(pCur->apPage[i]);
|
||||
pCur->apPage[i] = 0;
|
||||
}
|
||||
pCur->iPage = -1;
|
||||
btreeReleaseAllCursorPages(pCur);
|
||||
pCur->eState = CURSOR_REQUIRESEEK;
|
||||
}
|
||||
|
||||
@@ -618,11 +645,15 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( pExcept==0 || pExcept->pBt==pBt );
|
||||
for(p=pBt->pCursor; p; p=p->pNext){
|
||||
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
|
||||
p->eState==CURSOR_VALID ){
|
||||
int rc = saveCursorPosition(p);
|
||||
if( SQLITE_OK!=rc ){
|
||||
return rc;
|
||||
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
|
||||
if( p->eState==CURSOR_VALID ){
|
||||
int rc = saveCursorPosition(p);
|
||||
if( SQLITE_OK!=rc ){
|
||||
return rc;
|
||||
}
|
||||
}else{
|
||||
testcase( p->iPage>0 );
|
||||
btreeReleaseAllCursorPages(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1550,13 +1581,17 @@ static int btreeGetPage(
|
||||
BtShared *pBt, /* The btree */
|
||||
Pgno pgno, /* Number of the page to fetch */
|
||||
MemPage **ppPage, /* Return the page in this parameter */
|
||||
int noContent /* Do not load page content if true */
|
||||
int noContent, /* Do not load page content if true */
|
||||
int bReadonly /* True if a read-only (mmap) page is ok */
|
||||
){
|
||||
int rc;
|
||||
DbPage *pDbPage;
|
||||
int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0)
|
||||
| (bReadonly ? PAGER_ACQUIRE_READONLY : 0);
|
||||
|
||||
assert( noContent==0 || bReadonly==0 );
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
|
||||
if( rc ) return rc;
|
||||
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
|
||||
return SQLITE_OK;
|
||||
@@ -1599,9 +1634,10 @@ u32 sqlite3BtreeLastPage(Btree *p){
|
||||
** may remain unchanged, or it may be set to an invalid value.
|
||||
*/
|
||||
static int getAndInitPage(
|
||||
BtShared *pBt, /* The database file */
|
||||
Pgno pgno, /* Number of the page to get */
|
||||
MemPage **ppPage /* Write the page pointer here */
|
||||
BtShared *pBt, /* The database file */
|
||||
Pgno pgno, /* Number of the page to get */
|
||||
MemPage **ppPage, /* Write the page pointer here */
|
||||
int bReadonly /* True if a read-only (mmap) page is ok */
|
||||
){
|
||||
int rc;
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
@@ -1609,7 +1645,7 @@ static int getAndInitPage(
|
||||
if( pgno>btreePagecount(pBt) ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = btreeGetPage(pBt, pgno, ppPage, 0);
|
||||
rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = btreeInitPage(*ppPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -1840,6 +1876,7 @@ int sqlite3BtreeOpen(
|
||||
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
|
||||
EXTRA_SIZE, flags, vfsFlags, pageReinit);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3PagerSetMmapLimit(pBt->pPager, db->mxMmap);
|
||||
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -2106,6 +2143,19 @@ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the limit on the amount of the database file that may be
|
||||
** memory mapped.
|
||||
*/
|
||||
int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 mxMmap){
|
||||
BtShared *pBt = p->pBt;
|
||||
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||
sqlite3BtreeEnter(p);
|
||||
sqlite3PagerSetMmapLimit(pBt->pPager, mxMmap);
|
||||
sqlite3BtreeLeave(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the way data is synced to disk in order to increase or decrease
|
||||
** how well the database resists damage due to OS crashes and power
|
||||
@@ -2210,7 +2260,7 @@ int sqlite3BtreeGetPageSize(Btree *p){
|
||||
** known that the shared b-tree mutex is held, but the mutex on the
|
||||
** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
|
||||
** were to be called, it might collide with some other operation on the
|
||||
** database handle that owns *p, causing undefined behaviour.
|
||||
** database handle that owns *p, causing undefined behavior.
|
||||
*/
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p){
|
||||
assert( sqlite3_mutex_held(p->pBt->mutex) );
|
||||
@@ -2331,7 +2381,7 @@ static int lockBtree(BtShared *pBt){
|
||||
assert( pBt->pPage1==0 );
|
||||
rc = sqlite3PagerSharedLock(pBt->pPager);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
rc = btreeGetPage(pBt, 1, &pPage1, 0);
|
||||
rc = btreeGetPage(pBt, 1, &pPage1, 0, 0);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
/* Do some checking to help insure the file we opened really is
|
||||
@@ -2595,6 +2645,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
||||
if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
|
||||
goto trans_begun;
|
||||
}
|
||||
assert( IfNotOmitAV(pBt->bDoTruncate)==0 );
|
||||
|
||||
/* Write transactions are not possible on a read-only database */
|
||||
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
|
||||
@@ -2889,7 +2940,7 @@ static int relocatePage(
|
||||
** iPtrPage.
|
||||
*/
|
||||
if( eType!=PTRMAP_ROOTPAGE ){
|
||||
rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
|
||||
rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -2911,24 +2962,23 @@ static int relocatePage(
|
||||
static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
|
||||
|
||||
/*
|
||||
** Perform a single step of an incremental-vacuum. If successful,
|
||||
** return SQLITE_OK. If there is no work to do (and therefore no
|
||||
** point in calling this function again), return SQLITE_DONE.
|
||||
** Perform a single step of an incremental-vacuum. If successful, return
|
||||
** SQLITE_OK. If there is no work to do (and therefore no point in
|
||||
** calling this function again), return SQLITE_DONE. Or, if an error
|
||||
** occurs, return some other error code.
|
||||
**
|
||||
** More specificly, this function attempts to re-organize the
|
||||
** database so that the last page of the file currently in use
|
||||
** is no longer in use.
|
||||
** More specificly, this function attempts to re-organize the database so
|
||||
** that the last page of the file currently in use is no longer in use.
|
||||
**
|
||||
** If the nFin parameter is non-zero, this function assumes
|
||||
** that the caller will keep calling incrVacuumStep() until
|
||||
** it returns SQLITE_DONE or an error, and that nFin is the
|
||||
** number of pages the database file will contain after this
|
||||
** process is complete. If nFin is zero, it is assumed that
|
||||
** incrVacuumStep() will be called a finite amount of times
|
||||
** which may or may not empty the freelist. A full autovacuum
|
||||
** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0.
|
||||
** Parameter nFin is the number of pages that this database would contain
|
||||
** were this function called until it returns SQLITE_DONE.
|
||||
**
|
||||
** If the bCommit parameter is non-zero, this function assumes that the
|
||||
** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE
|
||||
** or an error. bCommit is passed true for an auto-vacuum-on-commmit
|
||||
** operation, or false for an incremental vacuum.
|
||||
*/
|
||||
static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
|
||||
Pgno nFreeList; /* Number of pages still on the free-list */
|
||||
int rc;
|
||||
|
||||
@@ -2953,15 +3003,15 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
}
|
||||
|
||||
if( eType==PTRMAP_FREEPAGE ){
|
||||
if( nFin==0 ){
|
||||
if( bCommit==0 ){
|
||||
/* Remove the page from the files free-list. This is not required
|
||||
** if nFin is non-zero. In that case, the free-list will be
|
||||
** if bCommit is non-zero. In that case, the free-list will be
|
||||
** truncated to zero after this function returns, so it doesn't
|
||||
** matter if it still contains some garbage entries.
|
||||
*/
|
||||
Pgno iFreePg;
|
||||
MemPage *pFreePg;
|
||||
rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
|
||||
rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -2971,34 +3021,37 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
} else {
|
||||
Pgno iFreePg; /* Index of free page to move pLastPg to */
|
||||
MemPage *pLastPg;
|
||||
u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
|
||||
Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
|
||||
|
||||
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
|
||||
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* If nFin is zero, this loop runs exactly once and page pLastPg
|
||||
/* If bCommit is zero, this loop runs exactly once and page pLastPg
|
||||
** is swapped with the first free page pulled off the free list.
|
||||
**
|
||||
** On the other hand, if nFin is greater than zero, then keep
|
||||
** On the other hand, if bCommit is greater than zero, then keep
|
||||
** looping until a free-page located within the first nFin pages
|
||||
** of the file is found.
|
||||
*/
|
||||
if( bCommit==0 ){
|
||||
eMode = BTALLOC_LE;
|
||||
iNear = nFin;
|
||||
}
|
||||
do {
|
||||
MemPage *pFreePg;
|
||||
rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
|
||||
rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(pLastPg);
|
||||
return rc;
|
||||
}
|
||||
releasePage(pFreePg);
|
||||
}while( nFin!=0 && iFreePg>nFin );
|
||||
}while( bCommit && iFreePg>nFin );
|
||||
assert( iFreePg<iLastPg );
|
||||
|
||||
rc = sqlite3PagerWrite(pLastPg->pDbPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
|
||||
}
|
||||
rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit);
|
||||
releasePage(pLastPg);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
@@ -3006,29 +3059,39 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
}
|
||||
}
|
||||
|
||||
if( nFin==0 ){
|
||||
iLastPg--;
|
||||
while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
|
||||
if( PTRMAP_ISPAGE(pBt, iLastPg) ){
|
||||
MemPage *pPg;
|
||||
rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPg->pDbPage);
|
||||
releasePage(pPg);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if( bCommit==0 ){
|
||||
do {
|
||||
iLastPg--;
|
||||
}
|
||||
sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
|
||||
}while( iLastPg==PENDING_BYTE_PAGE(pBt) || PTRMAP_ISPAGE(pBt, iLastPg) );
|
||||
pBt->bDoTruncate = 1;
|
||||
pBt->nPage = iLastPg;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** The database opened by the first argument is an auto-vacuum database
|
||||
** nOrig pages in size containing nFree free pages. Return the expected
|
||||
** size of the database in pages following an auto-vacuum operation.
|
||||
*/
|
||||
static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){
|
||||
int nEntry; /* Number of entries on one ptrmap page */
|
||||
Pgno nPtrmap; /* Number of PtrMap pages to be freed */
|
||||
Pgno nFin; /* Return value */
|
||||
|
||||
nEntry = pBt->usableSize/5;
|
||||
nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
|
||||
nFin = nOrig - nFree - nPtrmap;
|
||||
if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
|
||||
nFin--;
|
||||
}
|
||||
while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
|
||||
nFin--;
|
||||
}
|
||||
|
||||
return nFin;
|
||||
}
|
||||
|
||||
/*
|
||||
** A write-transaction must be opened before calling this function.
|
||||
** It performs a single unit of work towards an incremental vacuum.
|
||||
@@ -3046,11 +3109,24 @@ int sqlite3BtreeIncrVacuum(Btree *p){
|
||||
if( !pBt->autoVacuum ){
|
||||
rc = SQLITE_DONE;
|
||||
}else{
|
||||
invalidateAllOverflowCache(pBt);
|
||||
rc = incrVacuumStep(pBt, 0, btreePagecount(pBt));
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
put4byte(&pBt->pPage1->aData[28], pBt->nPage);
|
||||
Pgno nOrig = btreePagecount(pBt);
|
||||
Pgno nFree = get4byte(&pBt->pPage1->aData[36]);
|
||||
Pgno nFin = finalDbSize(pBt, nOrig, nFree);
|
||||
|
||||
if( nOrig<nFin ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else if( nFree>0 ){
|
||||
rc = saveAllCursors(pBt, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
invalidateAllOverflowCache(pBt);
|
||||
rc = incrVacuumStep(pBt, nFin, nOrig, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
put4byte(&pBt->pPage1->aData[28], pBt->nPage);
|
||||
}
|
||||
}else{
|
||||
rc = SQLITE_DONE;
|
||||
}
|
||||
}
|
||||
sqlite3BtreeLeave(p);
|
||||
@@ -3077,9 +3153,7 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
if( !pBt->incrVacuum ){
|
||||
Pgno nFin; /* Number of pages in database after autovacuuming */
|
||||
Pgno nFree; /* Number of pages on the freelist initially */
|
||||
Pgno nPtrmap; /* Number of PtrMap pages to be freed */
|
||||
Pgno iFree; /* The next page to be freed */
|
||||
int nEntry; /* Number of entries on one ptrmap page */
|
||||
Pgno nOrig; /* Database size before freeing */
|
||||
|
||||
nOrig = btreePagecount(pBt);
|
||||
@@ -3092,26 +3166,20 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
}
|
||||
|
||||
nFree = get4byte(&pBt->pPage1->aData[36]);
|
||||
nEntry = pBt->usableSize/5;
|
||||
nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
|
||||
nFin = nOrig - nFree - nPtrmap;
|
||||
if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
|
||||
nFin--;
|
||||
}
|
||||
while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
|
||||
nFin--;
|
||||
}
|
||||
nFin = finalDbSize(pBt, nOrig, nFree);
|
||||
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
|
||||
|
||||
if( nFin<nOrig ){
|
||||
rc = saveAllCursors(pBt, 0, 0);
|
||||
}
|
||||
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
|
||||
rc = incrVacuumStep(pBt, nFin, iFree);
|
||||
rc = incrVacuumStep(pBt, nFin, iFree, 1);
|
||||
}
|
||||
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
put4byte(&pBt->pPage1->aData[32], 0);
|
||||
put4byte(&pBt->pPage1->aData[36], 0);
|
||||
put4byte(&pBt->pPage1->aData[28], nFin);
|
||||
sqlite3PagerTruncateImage(pBt->pPager, nFin);
|
||||
pBt->bDoTruncate = 1;
|
||||
pBt->nPage = nFin;
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -3119,7 +3187,7 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
}
|
||||
}
|
||||
|
||||
assert( nRef==sqlite3PagerRefcount(pPager) );
|
||||
assert( nRef>=sqlite3PagerRefcount(pPager) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3166,6 +3234,9 @@ int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if( pBt->bDoTruncate ){
|
||||
sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage);
|
||||
}
|
||||
#endif
|
||||
rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
|
||||
sqlite3BtreeLeave(p);
|
||||
@@ -3181,6 +3252,9 @@ static void btreeEndTransaction(Btree *p){
|
||||
BtShared *pBt = p->pBt;
|
||||
assert( sqlite3BtreeHoldsMutex(p) );
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
pBt->bDoTruncate = 0;
|
||||
#endif
|
||||
btreeClearHasContent(pBt);
|
||||
if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
|
||||
/* If there are other active statements that belong to this database
|
||||
@@ -3369,7 +3443,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode){
|
||||
/* The rollback may have destroyed the pPage1->aData value. So
|
||||
** call btreeGetPage() on page 1 again to make
|
||||
** sure pPage1->aData is set correctly. */
|
||||
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
|
||||
if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){
|
||||
int nPage = get4byte(28+(u8*)pPage1->aData);
|
||||
testcase( nPage==0 );
|
||||
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
|
||||
@@ -3803,7 +3877,7 @@ static int getOverflowPage(
|
||||
|
||||
assert( next==0 || rc==SQLITE_DONE );
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = btreeGetPage(pBt, ovfl, &pPage, 0);
|
||||
rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
|
||||
assert( rc==SQLITE_OK || pPage==0 );
|
||||
if( rc==SQLITE_OK ){
|
||||
next = get4byte(pPage->aData);
|
||||
@@ -4024,7 +4098,9 @@ static int accessPayload(
|
||||
|
||||
{
|
||||
DbPage *pDbPage;
|
||||
rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
|
||||
(eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
aPayload = sqlite3PagerGetData(pDbPage);
|
||||
nextPage = get4byte(aPayload);
|
||||
@@ -4203,10 +4279,11 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
||||
assert( pCur->iPage>=0 );
|
||||
if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
rc = getAndInitPage(pBt, newPgno, &pNewPage);
|
||||
rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));
|
||||
if( rc ) return rc;
|
||||
pCur->apPage[i+1] = pNewPage;
|
||||
pCur->aiIdx[i+1] = 0;
|
||||
@@ -4323,7 +4400,7 @@ static int moveToRoot(BtCursor *pCur){
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
|
||||
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
return rc;
|
||||
@@ -4853,21 +4930,23 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
** an error. *ppPage and *pPgno are undefined in the event of an error.
|
||||
** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
|
||||
**
|
||||
** If the "nearby" parameter is not 0, then a (feeble) effort is made to
|
||||
** If the "nearby" parameter is not 0, then an effort is made to
|
||||
** locate a page close to the page number "nearby". This can be used in an
|
||||
** attempt to keep related pages close to each other in the database file,
|
||||
** which in turn can make database access faster.
|
||||
**
|
||||
** If the "exact" parameter is not 0, and the page-number nearby exists
|
||||
** anywhere on the free-list, then it is guarenteed to be returned. This
|
||||
** is only used by auto-vacuum databases when allocating a new table.
|
||||
** If the eMode parameter is BTALLOC_EXACT and the nearby page exists
|
||||
** anywhere on the free-list, then it is guaranteed to be returned. If
|
||||
** eMode is BTALLOC_LT then the page returned will be less than or equal
|
||||
** to nearby if any such page exists. If eMode is BTALLOC_ANY then there
|
||||
** are no restrictions on which page is returned.
|
||||
*/
|
||||
static int allocateBtreePage(
|
||||
BtShared *pBt,
|
||||
MemPage **ppPage,
|
||||
Pgno *pPgno,
|
||||
Pgno nearby,
|
||||
u8 exact
|
||||
BtShared *pBt, /* The btree */
|
||||
MemPage **ppPage, /* Store pointer to the allocated page here */
|
||||
Pgno *pPgno, /* Store the page number here */
|
||||
Pgno nearby, /* Search for a page near this one */
|
||||
u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */
|
||||
){
|
||||
MemPage *pPage1;
|
||||
int rc;
|
||||
@@ -4878,6 +4957,7 @@ static int allocateBtreePage(
|
||||
Pgno mxPage; /* Total size of the database file */
|
||||
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
|
||||
pPage1 = pBt->pPage1;
|
||||
mxPage = btreePagecount(pBt);
|
||||
n = get4byte(&pPage1->aData[36]);
|
||||
@@ -4890,21 +4970,24 @@ static int allocateBtreePage(
|
||||
Pgno iTrunk;
|
||||
u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
|
||||
|
||||
/* If the 'exact' parameter was true and a query of the pointer-map
|
||||
/* If eMode==BTALLOC_EXACT and a query of the pointer-map
|
||||
** shows that the page 'nearby' is somewhere on the free-list, then
|
||||
** the entire-list will be searched for that page.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( exact && nearby<=mxPage ){
|
||||
u8 eType;
|
||||
assert( nearby>0 );
|
||||
assert( pBt->autoVacuum );
|
||||
rc = ptrmapGet(pBt, nearby, &eType, 0);
|
||||
if( rc ) return rc;
|
||||
if( eType==PTRMAP_FREEPAGE ){
|
||||
searchList = 1;
|
||||
if( eMode==BTALLOC_EXACT ){
|
||||
if( nearby<=mxPage ){
|
||||
u8 eType;
|
||||
assert( nearby>0 );
|
||||
assert( pBt->autoVacuum );
|
||||
rc = ptrmapGet(pBt, nearby, &eType, 0);
|
||||
if( rc ) return rc;
|
||||
if( eType==PTRMAP_FREEPAGE ){
|
||||
searchList = 1;
|
||||
}
|
||||
}
|
||||
*pPgno = nearby;
|
||||
}else if( eMode==BTALLOC_LE ){
|
||||
searchList = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4917,7 +5000,8 @@ static int allocateBtreePage(
|
||||
|
||||
/* The code within this loop is run only once if the 'searchList' variable
|
||||
** is not true. Otherwise, it runs once for each trunk-page on the
|
||||
** free-list until the page 'nearby' is located.
|
||||
** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT)
|
||||
** or until a page less than 'nearby' is located (eMode==BTALLOC_LT)
|
||||
*/
|
||||
do {
|
||||
pPrevTrunk = pTrunk;
|
||||
@@ -4930,7 +5014,7 @@ static int allocateBtreePage(
|
||||
if( iTrunk>mxPage ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
|
||||
}
|
||||
if( rc ){
|
||||
pTrunk = 0;
|
||||
@@ -4959,11 +5043,13 @@ static int allocateBtreePage(
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto end_allocate_page;
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
}else if( searchList && nearby==iTrunk ){
|
||||
}else if( searchList
|
||||
&& (nearby==iTrunk || (iTrunk<nearby && eMode==BTALLOC_LE))
|
||||
){
|
||||
/* The list is being searched and this trunk page is the page
|
||||
** to allocate, regardless of whether it has leaves.
|
||||
*/
|
||||
assert( *pPgno==iTrunk );
|
||||
*pPgno = iTrunk;
|
||||
*ppPage = pTrunk;
|
||||
searchList = 0;
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
@@ -4992,7 +5078,7 @@ static int allocateBtreePage(
|
||||
goto end_allocate_page;
|
||||
}
|
||||
testcase( iNewTrunk==mxPage );
|
||||
rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
|
||||
rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
@@ -5026,14 +5112,24 @@ static int allocateBtreePage(
|
||||
unsigned char *aData = pTrunk->aData;
|
||||
if( nearby>0 ){
|
||||
u32 i;
|
||||
int dist;
|
||||
closest = 0;
|
||||
dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
|
||||
for(i=1; i<k; i++){
|
||||
int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
|
||||
if( d2<dist ){
|
||||
closest = i;
|
||||
dist = d2;
|
||||
if( eMode==BTALLOC_LE ){
|
||||
for(i=0; i<k; i++){
|
||||
iPage = get4byte(&aData[8+i*4]);
|
||||
if( iPage<=nearby ){
|
||||
closest = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
int dist;
|
||||
dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
|
||||
for(i=1; i<k; i++){
|
||||
int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
|
||||
if( d2<dist ){
|
||||
closest = i;
|
||||
dist = d2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -5047,7 +5143,9 @@ static int allocateBtreePage(
|
||||
goto end_allocate_page;
|
||||
}
|
||||
testcase( iPage==mxPage );
|
||||
if( !searchList || iPage==nearby ){
|
||||
if( !searchList
|
||||
|| (iPage==nearby || (iPage<nearby && eMode==BTALLOC_LE))
|
||||
){
|
||||
int noContent;
|
||||
*pPgno = iPage;
|
||||
TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
|
||||
@@ -5060,7 +5158,7 @@ static int allocateBtreePage(
|
||||
}
|
||||
put4byte(&aData[4], k-1);
|
||||
noContent = !btreeGetHasContent(pBt, *pPgno);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -5074,8 +5172,26 @@ static int allocateBtreePage(
|
||||
pPrevTrunk = 0;
|
||||
}while( searchList );
|
||||
}else{
|
||||
/* There are no pages on the freelist, so create a new page at the
|
||||
** end of the file */
|
||||
/* There are no pages on the freelist, so append a new page to the
|
||||
** database image.
|
||||
**
|
||||
** Normally, new pages allocated by this block can be requested from the
|
||||
** pager layer with the 'no-content' flag set. This prevents the pager
|
||||
** from trying to read the pages content from disk. However, if the
|
||||
** current transaction has already run one or more incremental-vacuum
|
||||
** steps, then the page we are about to allocate may contain content
|
||||
** that is required in the event of a rollback. In this case, do
|
||||
** not set the no-content flag. This causes the pager to load and journal
|
||||
** the current page content before overwriting it.
|
||||
**
|
||||
** Note that the pager will not actually attempt to load or journal
|
||||
** content for any page that really does lie past the end of the database
|
||||
** file on disk. So the effects of disabling the no-content optimization
|
||||
** here are confined to those pages that lie between the end of the
|
||||
** database image and the end of the database file.
|
||||
*/
|
||||
int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate));
|
||||
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
if( rc ) return rc;
|
||||
pBt->nPage++;
|
||||
@@ -5090,7 +5206,7 @@ static int allocateBtreePage(
|
||||
MemPage *pPg = 0;
|
||||
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
|
||||
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
|
||||
rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1);
|
||||
rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pPg->pDbPage);
|
||||
releasePage(pPg);
|
||||
@@ -5104,7 +5220,7 @@ static int allocateBtreePage(
|
||||
*pPgno = pBt->nPage;
|
||||
|
||||
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -5172,7 +5288,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
/* If the secure_delete option is enabled, then
|
||||
** always fully overwrite deleted information with zeros.
|
||||
*/
|
||||
if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
|
||||
if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) )
|
||||
|| ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
|
||||
){
|
||||
goto freepage_out;
|
||||
@@ -5199,7 +5315,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
u32 nLeaf; /* Initial number of leaf cells on trunk page */
|
||||
|
||||
iTrunk = get4byte(&pPage1->aData[32]);
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto freepage_out;
|
||||
}
|
||||
@@ -5245,7 +5361,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** first trunk in the free-list is full. Either way, the page being freed
|
||||
** will become the new first trunk page in the free-list.
|
||||
*/
|
||||
if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
|
||||
if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){
|
||||
goto freepage_out;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
@@ -5432,7 +5548,7 @@ static int fillInCell(
|
||||
** If this is the first overflow page, then write a partial entry
|
||||
** to the pointer-map. If we write nothing to this pointer-map slot,
|
||||
** then the optimistic overflow chain processing in clearCell()
|
||||
** may misinterpret the uninitialised values and delete the
|
||||
** may misinterpret the uninitialized values and delete the
|
||||
** wrong pages from the database.
|
||||
*/
|
||||
if( pBt->autoVacuum && rc==SQLITE_OK ){
|
||||
@@ -6046,7 +6162,7 @@ static int balance_nonroot(
|
||||
}
|
||||
pgno = get4byte(pRight);
|
||||
while( 1 ){
|
||||
rc = getAndInitPage(pBt, pgno, &apOld[i]);
|
||||
rc = getAndInitPage(pBt, pgno, &apOld[i], 0);
|
||||
if( rc ){
|
||||
memset(apOld, 0, (i+1)*sizeof(MemPage*));
|
||||
goto balance_cleanup;
|
||||
@@ -6905,7 +7021,7 @@ int sqlite3BtreeInsert(
|
||||
insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
|
||||
assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
|
||||
|
||||
/* If no error has occured and pPage has an overflow cell, call balance()
|
||||
/* If no error has occurred and pPage has an overflow cell, call balance()
|
||||
** to redistribute the cells within the tree. Since balance() may move
|
||||
** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
|
||||
** variables.
|
||||
@@ -7119,7 +7235,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
** be moved to the allocated page (unless the allocated page happens
|
||||
** to reside at pgnoRoot).
|
||||
*/
|
||||
rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
|
||||
rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7134,10 +7250,17 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
u8 eType = 0;
|
||||
Pgno iPtrPage = 0;
|
||||
|
||||
/* Save the positions of any open cursors. This is required in
|
||||
** case they are holding a reference to an xFetch reference
|
||||
** corresponding to page pgnoRoot. */
|
||||
rc = saveAllCursors(pBt, 0, 0);
|
||||
releasePage(pPageMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Move the page currently at pgnoRoot to pgnoMove. */
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7158,7 +7281,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7234,7 +7357,7 @@ static int clearDatabasePage(
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
|
||||
rc = getAndInitPage(pBt, pgno, &pPage);
|
||||
rc = getAndInitPage(pBt, pgno, &pPage, 0);
|
||||
if( rc ) return rc;
|
||||
for(i=0; i<pPage->nCell; i++){
|
||||
pCell = findCell(pPage, i);
|
||||
@@ -7336,7 +7459,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
return SQLITE_LOCKED_SHAREDCACHE;
|
||||
}
|
||||
|
||||
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
|
||||
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3BtreeClearTable(p, iTable, 0);
|
||||
if( rc ){
|
||||
@@ -7371,7 +7494,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
*/
|
||||
MemPage *pMove;
|
||||
releasePage(pPage);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7381,7 +7504,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
return rc;
|
||||
}
|
||||
pMove = 0;
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
|
||||
freePage(pMove, &rc);
|
||||
releasePage(pMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -7793,7 +7916,7 @@ static int checkTreePage(
|
||||
usableSize = pBt->usableSize;
|
||||
if( iPage==0 ) return 0;
|
||||
if( checkRef(pCheck, iPage, zParentContext) ) return 0;
|
||||
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
|
||||
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"unable to get the page. error code=%d", rc);
|
||||
return 0;
|
||||
@@ -8265,6 +8388,17 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
||||
return SQLITE_ABORT;
|
||||
}
|
||||
|
||||
/* Save the positions of all other cursors open on this table. This is
|
||||
** required in case any of them are holding references to an xFetch
|
||||
** version of the b-tree page modified by the accessPayload call below.
|
||||
**
|
||||
** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
|
||||
** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
|
||||
** saveAllCursors can only return SQLITE_OK.
|
||||
*/
|
||||
VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
|
||||
assert( rc==SQLITE_OK );
|
||||
|
||||
/* Check some assumptions:
|
||||
** (a) the cursor is open for writing,
|
||||
** (b) there is a read/write transaction open,
|
||||
|
||||
@@ -63,6 +63,7 @@ int sqlite3BtreeOpen(
|
||||
|
||||
int sqlite3BtreeClose(Btree*);
|
||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
|
||||
int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
|
||||
int sqlite3BtreeSyncDisabled(Btree*);
|
||||
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
|
||||
|
||||
@@ -411,6 +411,7 @@ struct BtShared {
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
u8 autoVacuum; /* True if auto-vacuum is enabled */
|
||||
u8 incrVacuum; /* True if incr-vacuum is enabled */
|
||||
u8 bDoTruncate; /* True to truncate db on commit */
|
||||
#endif
|
||||
u8 inTransaction; /* Transaction state */
|
||||
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
|
||||
|
||||
+3
-35
@@ -2100,7 +2100,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
|
||||
/* Drop all SQLITE_MASTER table and index entries that refer to the
|
||||
** table. The program name loops through the master table and deletes
|
||||
** every row that refers to a table of the same name as the one being
|
||||
** dropped. Triggers are handled seperately because a trigger can be
|
||||
** dropped. Triggers are handled separately because a trigger can be
|
||||
** created in the temp database that refers to a table in another
|
||||
** database.
|
||||
*/
|
||||
@@ -2392,9 +2392,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
int tnum; /* Root page of index */
|
||||
Vdbe *v; /* Generate code into this virtual machine */
|
||||
KeyInfo *pKey; /* KeyInfo for index */
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
int regIdxKey; /* Registers containing the index key */
|
||||
#endif
|
||||
int regRecord; /* Register holding assemblied index record */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
|
||||
@@ -2422,13 +2419,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
(char *)pKey, P4_KEYINFO_HANDOFF);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
/* Open the sorter cursor if we are to use one. */
|
||||
iSorter = pParse->nTab++;
|
||||
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
|
||||
#else
|
||||
iSorter = iTab;
|
||||
#endif
|
||||
|
||||
/* Open the table. Loop through all rows of the table, inserting index
|
||||
** records into the sorter. */
|
||||
@@ -2436,7 +2429,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
|
||||
regRecord = sqlite3GetTempReg(pParse);
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
|
||||
@@ -2456,30 +2448,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
|
||||
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||
#else
|
||||
regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
|
||||
addr2 = addr1 + 1;
|
||||
if( pIndex->onError!=OE_None ){
|
||||
const int regRowid = regIdxKey + pIndex->nColumn;
|
||||
const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
|
||||
void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
|
||||
|
||||
/* The registers accessed by the OP_IsUnique opcode were allocated
|
||||
** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey()
|
||||
** call above. Just before that function was freed they were released
|
||||
** (made available to the compiler for reuse) using
|
||||
** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique
|
||||
** opcode use the values stored within seems dangerous. However, since
|
||||
** we can be sure that no other temp registers have been allocated
|
||||
** since sqlite3ReleaseTempRange() was called, it is safe to do so.
|
||||
*/
|
||||
sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
|
||||
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
|
||||
"indexed columns are not unique", P4_STATIC);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||
#endif
|
||||
sqlite3ReleaseTempReg(pParse, regRecord);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
@@ -2594,7 +2562,7 @@ Index *sqlite3CreateIndex(
|
||||
assert( pTab!=0 );
|
||||
assert( pParse->nErr==0 );
|
||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
|
||||
&& memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
|
||||
&& sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
|
||||
goto exit_create_index;
|
||||
}
|
||||
@@ -2839,7 +2807,7 @@ Index *sqlite3CreateIndex(
|
||||
** However the ON CONFLICT clauses are different. If both this
|
||||
** constraint and the previous equivalent constraint have explicit
|
||||
** ON CONFLICT clauses this is an error. Otherwise, use the
|
||||
** explicitly specified behaviour for the index.
|
||||
** explicitly specified behavior for the index.
|
||||
*/
|
||||
if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
|
||||
+6
-3
@@ -57,12 +57,18 @@ static const char * const azCompileOpt[] = {
|
||||
#ifdef SQLITE_DEFAULT_LOCKING_MODE
|
||||
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_MMAP_LIMIT
|
||||
"DEFAULT_MMAP_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_LIMIT),
|
||||
#endif
|
||||
#ifdef SQLITE_DISABLE_DIRSYNC
|
||||
"DISABLE_DIRSYNC",
|
||||
#endif
|
||||
#ifdef SQLITE_DISABLE_LFS
|
||||
"DISABLE_LFS",
|
||||
#endif
|
||||
#ifdef SQLITE_DISABLE_MMAP
|
||||
"DISABLE_MMAP",
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
||||
"ENABLE_ATOMIC_WRITE",
|
||||
#endif
|
||||
@@ -263,9 +269,6 @@ static const char * const azCompileOpt[] = {
|
||||
#ifdef SQLITE_OMIT_MEMORYDB
|
||||
"OMIT_MEMORYDB",
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
"OMIT_MERGE_SORT",
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
|
||||
"OMIT_OR_OPTIMIZATION",
|
||||
#endif
|
||||
|
||||
+18
-20
@@ -93,30 +93,28 @@ void sqlite3MaterializeView(
|
||||
int iCur /* Cursor number for ephemerial table */
|
||||
){
|
||||
SelectDest dest;
|
||||
Select *pDup;
|
||||
Select *pSel;
|
||||
SrcList *pFrom;
|
||||
sqlite3 *db = pParse->db;
|
||||
int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
|
||||
|
||||
pDup = sqlite3SelectDup(db, pView->pSelect, 0);
|
||||
if( pWhere ){
|
||||
SrcList *pFrom;
|
||||
|
||||
pWhere = sqlite3ExprDup(db, pWhere, 0);
|
||||
pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
|
||||
if( pFrom ){
|
||||
assert( pFrom->nSrc==1 );
|
||||
pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName);
|
||||
pFrom->a[0].pSelect = pDup;
|
||||
assert( pFrom->a[0].pOn==0 );
|
||||
assert( pFrom->a[0].pUsing==0 );
|
||||
}else{
|
||||
sqlite3SelectDelete(db, pDup);
|
||||
}
|
||||
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
|
||||
if( pDup ) pDup->selFlags |= SF_Materialize;
|
||||
pWhere = sqlite3ExprDup(db, pWhere, 0);
|
||||
pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
|
||||
|
||||
if( pFrom ){
|
||||
assert( pFrom->nSrc==1 );
|
||||
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
|
||||
pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
|
||||
assert( pFrom->a[0].pOn==0 );
|
||||
assert( pFrom->a[0].pUsing==0 );
|
||||
}
|
||||
|
||||
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
|
||||
if( pSel ) pSel->selFlags |= SF_Materialize;
|
||||
|
||||
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
|
||||
sqlite3Select(pParse, pDup, &dest);
|
||||
sqlite3SelectDelete(db, pDup);
|
||||
sqlite3Select(pParse, pSel, &dest);
|
||||
sqlite3SelectDelete(db, pSel);
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
|
||||
|
||||
|
||||
+10
-8
@@ -638,7 +638,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
|
||||
*/
|
||||
ynVar i;
|
||||
for(i=0; i<pParse->nzVar; i++){
|
||||
if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
|
||||
if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
|
||||
pExpr->iColumn = x = (ynVar)i+1;
|
||||
break;
|
||||
}
|
||||
@@ -1456,10 +1456,11 @@ int sqlite3CodeOnce(Parse *pParse){
|
||||
**
|
||||
** The returned value of this function indicates the b-tree type, as follows:
|
||||
**
|
||||
** IN_INDEX_ROWID - The cursor was opened on a database table.
|
||||
** IN_INDEX_INDEX - The cursor was opened on a database index.
|
||||
** IN_INDEX_EPH - The cursor was opened on a specially created and
|
||||
** populated epheremal table.
|
||||
** IN_INDEX_ROWID - The cursor was opened on a database table.
|
||||
** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index.
|
||||
** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index.
|
||||
** IN_INDEX_EPH - The cursor was opened on a specially created and
|
||||
** populated epheremal table.
|
||||
**
|
||||
** An existing b-tree might be used if the RHS expression pX is a simple
|
||||
** subquery such as:
|
||||
@@ -1582,7 +1583,8 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
|
||||
sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
|
||||
pKey,P4_KEYINFO_HANDOFF);
|
||||
VdbeComment((v, "%s", pIdx->zName));
|
||||
eType = IN_INDEX_INDEX;
|
||||
assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
|
||||
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
|
||||
|
||||
sqlite3VdbeJumpHere(v, iAddr);
|
||||
if( prNotFound && !pTab->aCol[iCol].notNull ){
|
||||
@@ -3540,7 +3542,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
int r1, r2;
|
||||
|
||||
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
|
||||
if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
|
||||
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
|
||||
if( NEVER(pExpr==0) ) return; /* No way this can happen */
|
||||
op = pExpr->op;
|
||||
switch( op ){
|
||||
@@ -3660,7 +3662,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
int r1, r2;
|
||||
|
||||
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
|
||||
if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
|
||||
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
|
||||
if( pExpr==0 ) return;
|
||||
|
||||
/* The value of pExpr->op and op are related as follows:
|
||||
|
||||
+24
-11
@@ -693,6 +693,13 @@ static int patternCompare(
|
||||
return *zString==0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The sqlite3_strglob() interface.
|
||||
*/
|
||||
int sqlite3_strglob(const char *zGlobPattern, const char *zString){
|
||||
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Count the number of times that the LIKE operator (or GLOB which is
|
||||
** just a variation of LIKE) gets called. This is used for testing
|
||||
@@ -972,6 +979,7 @@ static void unicodeFunc(
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const unsigned char *z = sqlite3_value_text(argv[0]);
|
||||
(void)argc;
|
||||
if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z));
|
||||
}
|
||||
|
||||
@@ -993,23 +1001,28 @@ static void charFunc(
|
||||
return;
|
||||
}
|
||||
for(i=0; i<argc; i++){
|
||||
sqlite3_int64 x = sqlite3_value_int64(argv[i]);
|
||||
sqlite3_int64 x;
|
||||
unsigned c;
|
||||
x = sqlite3_value_int64(argv[i]);
|
||||
if( x<0 || x>0x10ffff ) x = 0xfffd;
|
||||
c = (unsigned)(x & 0x1fffff);
|
||||
if( c<=0xFFFF ){
|
||||
*zOut++ = (u8)(c&0x00FF);
|
||||
*zOut++ = (u8)((c>>8)&0x00FF);
|
||||
if( c<0x00080 ){
|
||||
*zOut++ = (u8)(c&0xFF);
|
||||
}else if( c<0x00800 ){
|
||||
*zOut++ = 0xC0 + (u8)((c>>6)&0x1F);
|
||||
*zOut++ = 0x80 + (u8)(c & 0x3F);
|
||||
}else if( c<0x10000 ){
|
||||
*zOut++ = 0xE0 + (u8)((c>>12)&0x0F);
|
||||
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
|
||||
*zOut++ = 0x80 + (u8)(c & 0x3F);
|
||||
}else{
|
||||
if( c>=0xd800 && c<=0xdbff ) c = 0xfffd;
|
||||
*zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));
|
||||
*zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));
|
||||
*zOut++ = (u8)(c&0x00FF);
|
||||
*zOut++ = (u8)(0x00DC + ((c>>8)&0x03));
|
||||
}
|
||||
*zOut++ = 0xF0 + (u8)((c>>18) & 0x07);
|
||||
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F);
|
||||
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
|
||||
*zOut++ = 0x80 + (u8)(c & 0x3F);
|
||||
} \
|
||||
}
|
||||
sqlite3_result_text16le(context, (char*)z, (int)(zOut-z), sqlite3_free);
|
||||
sqlite3_result_text(context, (char*)z, (int)(zOut-z), sqlite3_free);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -156,6 +156,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
(void*)0, /* pHeap */
|
||||
0, /* nHeap */
|
||||
0, 0, /* mnHeap, mxHeap */
|
||||
SQLITE_DEFAULT_MMAP_LIMIT, /* mxMmap */
|
||||
(void*)0, /* pScratch */
|
||||
0, /* szScratch */
|
||||
0, /* nScratch */
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** This is the header file for the generic hash-table implementation
|
||||
** used in SQLite.
|
||||
*/
|
||||
#ifndef _SQLITE_HASH_H_
|
||||
|
||||
+4
-8
@@ -38,7 +38,6 @@ int sqlite3_exec(
|
||||
const char *zLeftover; /* Tail of unprocessed SQL */
|
||||
sqlite3_stmt *pStmt = 0; /* The current SQL statement */
|
||||
char **azCols = 0; /* Names of result columns */
|
||||
int nRetry = 0; /* Number of retry attempts */
|
||||
int callbackIsInit; /* True if callback data is initialized */
|
||||
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
@@ -46,12 +45,12 @@ int sqlite3_exec(
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3Error(db, SQLITE_OK, 0);
|
||||
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
|
||||
while( rc==SQLITE_OK && zSql[0] ){
|
||||
int nCol;
|
||||
char **azVals = 0;
|
||||
|
||||
pStmt = 0;
|
||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
|
||||
assert( rc==SQLITE_OK || pStmt==0 );
|
||||
if( rc!=SQLITE_OK ){
|
||||
continue;
|
||||
@@ -108,11 +107,8 @@ int sqlite3_exec(
|
||||
if( rc!=SQLITE_ROW ){
|
||||
rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
|
||||
pStmt = 0;
|
||||
if( rc!=SQLITE_SCHEMA ){
|
||||
nRetry = 0;
|
||||
zSql = zLeftover;
|
||||
while( sqlite3Isspace(zSql[0]) ) zSql++;
|
||||
}
|
||||
zSql = zLeftover;
|
||||
while( sqlite3Isspace(zSql[0]) ) zSql++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,6 +378,19 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
sqlite3_blob_reopen,
|
||||
sqlite3_vtab_config,
|
||||
sqlite3_vtab_on_conflict,
|
||||
sqlite3_close_v2,
|
||||
sqlite3_db_filename,
|
||||
sqlite3_db_readonly,
|
||||
sqlite3_db_release_memory,
|
||||
sqlite3_errstr,
|
||||
sqlite3_stmt_busy,
|
||||
sqlite3_stmt_readonly,
|
||||
sqlite3_stricmp,
|
||||
sqlite3_uri_boolean,
|
||||
sqlite3_uri_int64,
|
||||
sqlite3_uri_parameter,
|
||||
sqlite3_vsnprintf,
|
||||
sqlite3_wal_checkpoint_v2
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+9
-1
@@ -496,6 +496,13 @@ int sqlite3_config(int op, ...){
|
||||
}
|
||||
#endif
|
||||
|
||||
case SQLITE_CONFIG_MMAP_LIMIT: {
|
||||
sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
|
||||
if( mxMmap<0 ) mxMmap = SQLITE_DEFAULT_MMAP_LIMIT;
|
||||
sqlite3GlobalConfig.mxMmap = mxMmap;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
@@ -885,7 +892,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
|
||||
/* If we reach this point, it means that the database connection has
|
||||
** closed all sqlite3_stmt and sqlite3_backup objects and has been
|
||||
** pased to sqlite3_close (meaning that it is a zombie). Therefore,
|
||||
** passed to sqlite3_close (meaning that it is a zombie). Therefore,
|
||||
** go ahead and free all resources.
|
||||
*/
|
||||
|
||||
@@ -2316,6 +2323,7 @@ static int openDatabase(
|
||||
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
|
||||
db->autoCommit = 1;
|
||||
db->nextAutovac = -1;
|
||||
db->mxMmap = sqlite3GlobalConfig.mxMmap;
|
||||
db->nextPagesize = 0;
|
||||
db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
|
||||
#if SQLITE_DEFAULT_FILE_FORMAT<4
|
||||
|
||||
@@ -141,6 +141,26 @@ int sqlite3OsShmMap(
|
||||
return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
|
||||
}
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
/* The real implementation of xFetch and xUnfetch */
|
||||
int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
|
||||
DO_OS_MALLOC_TEST(id);
|
||||
return id->pMethods->xFetch(id, iOff, iAmt, pp);
|
||||
}
|
||||
int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
|
||||
return id->pMethods->xUnfetch(id, iOff, p);
|
||||
}
|
||||
#else
|
||||
/* No-op stubs to use when memory-mapped I/O is disabled */
|
||||
int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
|
||||
*pp = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The next group of routines are convenience wrappers around the
|
||||
** VFS methods.
|
||||
|
||||
@@ -259,6 +259,8 @@ int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
|
||||
int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
|
||||
void sqlite3OsShmBarrier(sqlite3_file *id);
|
||||
int sqlite3OsShmUnmap(sqlite3_file *id, int);
|
||||
int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
|
||||
int sqlite3OsUnfetch(sqlite3_file *, i64, void *);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+395
-15
@@ -225,6 +225,11 @@ struct unixFile {
|
||||
const char *zPath; /* Name of the file */
|
||||
unixShm *pShm; /* Shared memory segment information */
|
||||
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
|
||||
int nFetchOut; /* Number of outstanding xFetch refs */
|
||||
sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */
|
||||
sqlite3_int64 mmapOrigsize; /* Actual size of mapping at pMapRegion */
|
||||
sqlite3_int64 mmapLimit; /* Configured FCNTL_MMAP_LIMIT value */
|
||||
void *pMapRegion; /* Memory mapped region */
|
||||
#ifdef __QNXNTO__
|
||||
int sectorSize; /* Device sector size */
|
||||
int deviceCharacteristics; /* Precomputed device characteristics */
|
||||
@@ -249,7 +254,9 @@ struct unixFile {
|
||||
unsigned char transCntrChng; /* True if the transaction counter changed */
|
||||
unsigned char dbUpdate; /* True if any part of database file changed */
|
||||
unsigned char inNormalWrite; /* True if in a normal write operation */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
/* In test mode, increase the size of this structure a bit so that
|
||||
** it is larger than the struct CrashFile defined in test6.c.
|
||||
@@ -273,6 +280,7 @@ struct unixFile {
|
||||
#define UNIXFILE_DELETE 0x20 /* Delete on close */
|
||||
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
|
||||
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
|
||||
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
|
||||
|
||||
/*
|
||||
** Include code that is common to all os_*.c files
|
||||
@@ -306,6 +314,17 @@ struct unixFile {
|
||||
#define threadid 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** HAVE_MREMAP defaults to true on Linux and false everywhere else.
|
||||
*/
|
||||
#if !defined(HAVE_MREMAP)
|
||||
# if defined(__linux__) && defined(_GNU_SOURCE)
|
||||
# define HAVE_MREMAP 1
|
||||
# else
|
||||
# define HAVE_MREMAP 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Different Unix systems declare open() in different ways. Same use
|
||||
** open(const char*,int,mode_t). Others use open(const char*,int,...).
|
||||
@@ -337,7 +356,7 @@ static int openDirectory(const char*, int*);
|
||||
** to all overrideable system calls.
|
||||
*/
|
||||
static struct unix_syscall {
|
||||
const char *zName; /* Name of the sytem call */
|
||||
const char *zName; /* Name of the system call */
|
||||
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
|
||||
sqlite3_syscall_ptr pDefault; /* Default value */
|
||||
} aSyscall[] = {
|
||||
@@ -437,6 +456,19 @@ static struct unix_syscall {
|
||||
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
|
||||
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
|
||||
|
||||
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
|
||||
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
|
||||
|
||||
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
||||
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
|
||||
|
||||
#if HAVE_MREMAP
|
||||
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
|
||||
#else
|
||||
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
|
||||
#endif
|
||||
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
/*
|
||||
@@ -552,7 +584,10 @@ static int robust_open(const char *z, int f, mode_t m){
|
||||
if( fd>=0 ){
|
||||
if( m!=0 ){
|
||||
struct stat statbuf;
|
||||
if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
|
||||
if( osFstat(fd, &statbuf)==0
|
||||
&& statbuf.st_size==0
|
||||
&& (statbuf.st_mode&0777)!=m
|
||||
){
|
||||
osFchmod(fd, m);
|
||||
}
|
||||
}
|
||||
@@ -765,7 +800,6 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
****************** Begin Unique File ID Utility Used By VxWorks ***************
|
||||
**
|
||||
@@ -1101,7 +1135,6 @@ static int unixLogErrorAtLine(
|
||||
zErr = strerror(iErrno);
|
||||
#endif
|
||||
|
||||
assert( errcode!=SQLITE_OK );
|
||||
if( zPath==0 ) zPath = "";
|
||||
sqlite3_log(errcode,
|
||||
"os_unix.c:%d: (%d) %s(%s) - %s",
|
||||
@@ -1267,6 +1300,50 @@ static int findInodeInfo(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Check a unixFile that is a database. Verify the following:
|
||||
**
|
||||
** (1) There is exactly one hard link on the file
|
||||
** (2) The file is not a symbolic link
|
||||
** (3) The file has not been renamed or unlinked
|
||||
**
|
||||
** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
|
||||
*/
|
||||
static void verifyDbFile(unixFile *pFile){
|
||||
struct stat buf;
|
||||
int rc;
|
||||
if( pFile->ctrlFlags & UNIXFILE_WARNED ){
|
||||
/* One or more of the following warnings have already been issued. Do not
|
||||
** repeat them so as not to clutter the error log */
|
||||
return;
|
||||
}
|
||||
rc = osFstat(pFile->h, &buf);
|
||||
if( rc!=0 ){
|
||||
sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
|
||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||
return;
|
||||
}
|
||||
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
||||
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||
return;
|
||||
}
|
||||
if( buf.st_nlink>1 ){
|
||||
sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
|
||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||
return;
|
||||
}
|
||||
if( pFile->pInode!=0
|
||||
&& ((rc = osStat(pFile->zPath, &buf))!=0
|
||||
|| buf.st_ino!=pFile->pInode->fileId.ino)
|
||||
){
|
||||
sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
|
||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This routine checks if there is a RESERVED lock held on the specified
|
||||
** file by this or any other process. If such a lock is held, set *pResOut
|
||||
@@ -1797,9 +1874,13 @@ end_unlock:
|
||||
** the requested locking level, this routine is a no-op.
|
||||
*/
|
||||
static int unixUnlock(sqlite3_file *id, int eFileLock){
|
||||
assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
|
||||
return posixUnlock(id, eFileLock, 0);
|
||||
}
|
||||
|
||||
static int unixMapfile(unixFile *pFd, i64 nByte);
|
||||
static void unixUnmapfile(unixFile *pFd);
|
||||
|
||||
/*
|
||||
** This function performs the parts of the "close file" operation
|
||||
** common to all locking schemes. It closes the directory and file
|
||||
@@ -1812,6 +1893,7 @@ static int unixUnlock(sqlite3_file *id, int eFileLock){
|
||||
*/
|
||||
static int closeUnixFile(sqlite3_file *id){
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
unixUnmapfile(pFile);
|
||||
if( pFile->h>=0 ){
|
||||
robust_close(pFile, pFile->h, __LINE__);
|
||||
pFile->h = -1;
|
||||
@@ -1838,6 +1920,7 @@ static int closeUnixFile(sqlite3_file *id){
|
||||
static int unixClose(sqlite3_file *id){
|
||||
int rc = SQLITE_OK;
|
||||
unixFile *pFile = (unixFile *)id;
|
||||
verifyDbFile(pFile);
|
||||
unixUnlock(id, NO_LOCK);
|
||||
unixEnterMutex();
|
||||
|
||||
@@ -1906,7 +1989,7 @@ static int nolockClose(sqlite3_file *id) {
|
||||
/******************************************************************************
|
||||
************************* Begin dot-file Locking ******************************
|
||||
**
|
||||
** The dotfile locking implementation uses the existance of separate lock
|
||||
** The dotfile locking implementation uses the existence of separate lock
|
||||
** files (really a directory) to control access to the database. This works
|
||||
** on just about every filesystem imaginable. But there are serious downsides:
|
||||
**
|
||||
@@ -1921,7 +2004,7 @@ static int nolockClose(sqlite3_file *id) {
|
||||
**
|
||||
** Dotfile locking works by creating a subdirectory in the same directory as
|
||||
** the database and with the same name but with a ".lock" extension added.
|
||||
** The existance of a lock directory implies an EXCLUSIVE lock. All other
|
||||
** The existence of a lock directory implies an EXCLUSIVE lock. All other
|
||||
** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
|
||||
*/
|
||||
|
||||
@@ -3079,6 +3162,23 @@ static int unixRead(
|
||||
);
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
/* Deal with as much of this read request as possible by transfering
|
||||
** data from the memory mapping using memcpy(). */
|
||||
if( offset<pFile->mmapSize ){
|
||||
if( offset+amt <= pFile->mmapSize ){
|
||||
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
int nCopy = pFile->mmapSize - offset;
|
||||
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
|
||||
pBuf = &((u8 *)pBuf)[nCopy];
|
||||
amt -= nCopy;
|
||||
offset += nCopy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
got = seekAndRead(pFile, offset, pBuf, amt);
|
||||
if( got==amt ){
|
||||
return SQLITE_OK;
|
||||
@@ -3183,6 +3283,23 @@ static int unixWrite(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
/* Deal with as much of this write request as possible by transfering
|
||||
** data from the memory mapping using memcpy(). */
|
||||
if( offset<pFile->mmapSize ){
|
||||
if( offset+amt <= pFile->mmapSize ){
|
||||
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
int nCopy = pFile->mmapSize - offset;
|
||||
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
|
||||
pBuf = &((u8 *)pBuf)[nCopy];
|
||||
amt -= nCopy;
|
||||
offset += nCopy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
|
||||
amt -= wrote;
|
||||
offset += wrote;
|
||||
@@ -3410,7 +3527,7 @@ static int unixSync(sqlite3_file *id, int flags){
|
||||
}
|
||||
|
||||
/* Also fsync the directory containing the file if the DIRSYNC flag
|
||||
** is set. This is a one-time occurrance. Many systems (examples: AIX)
|
||||
** is set. This is a one-time occurrence. Many systems (examples: AIX)
|
||||
** are unable to fsync a directory, so ignore errors on the fsync.
|
||||
*/
|
||||
if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
|
||||
@@ -3465,6 +3582,14 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the file was just truncated to a size smaller than the currently
|
||||
** mapped region, reduce the effective mapping size as well. SQLite will
|
||||
** use read() and write() to access data beyond this point from now on.
|
||||
*/
|
||||
if( nByte<pFile->mmapSize ){
|
||||
pFile->mmapSize = nByte;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
@@ -3553,6 +3678,19 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
||||
}
|
||||
}
|
||||
|
||||
if( pFile->mmapLimit>0 && nByte>pFile->mmapSize ){
|
||||
int rc;
|
||||
if( pFile->szChunk<=0 ){
|
||||
if( robust_ftruncate(pFile->h, nByte) ){
|
||||
pFile->lastErrno = errno;
|
||||
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
||||
}
|
||||
}
|
||||
|
||||
rc = unixMapfile(pFile, nByte);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -3620,6 +3758,15 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_MMAP_LIMIT: {
|
||||
i64 newLimit = *(i64*)pArg;
|
||||
*(i64*)pArg = pFile->mmapLimit;
|
||||
if( newLimit>=0 ){
|
||||
pFile->mmapLimit = newLimit;
|
||||
if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* The pager calls this method to signal that it has done
|
||||
** a rollback and that the database is therefore unchanged and
|
||||
@@ -3932,7 +4079,7 @@ static void unixShmPurge(unixFile *pFd){
|
||||
sqlite3_mutex_free(p->mutex);
|
||||
for(i=0; i<p->nRegion; i++){
|
||||
if( p->h>=0 ){
|
||||
munmap(p->apRegion[i], p->szRegion);
|
||||
osMunmap(p->apRegion[i], p->szRegion);
|
||||
}else{
|
||||
sqlite3_free(p->apRegion[i]);
|
||||
}
|
||||
@@ -4205,7 +4352,7 @@ static int unixShmMap(
|
||||
while(pShmNode->nRegion<=iRegion){
|
||||
void *pMem;
|
||||
if( pShmNode->h>=0 ){
|
||||
pMem = mmap(0, szRegion,
|
||||
pMem = osMmap(0, szRegion,
|
||||
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
|
||||
);
|
||||
@@ -4422,6 +4569,235 @@ static int unixShmUnmap(
|
||||
# define unixShmUnmap 0
|
||||
#endif /* #ifndef SQLITE_OMIT_WAL */
|
||||
|
||||
/*
|
||||
** If it is currently memory mapped, unmap file pFd.
|
||||
*/
|
||||
static void unixUnmapfile(unixFile *pFd){
|
||||
assert( pFd->nFetchOut==0 );
|
||||
#ifndef SQLITE_DISABLE_MMAP
|
||||
if( pFd->pMapRegion ){
|
||||
osMunmap(pFd->pMapRegion, pFd->mmapOrigsize);
|
||||
pFd->pMapRegion = 0;
|
||||
pFd->mmapSize = 0;
|
||||
pFd->mmapOrigsize = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SQLITE_DISABLE_MMAP
|
||||
/*
|
||||
** Return the system page size.
|
||||
*/
|
||||
static int unixGetPagesize(void){
|
||||
#if HAVE_MREMAP
|
||||
return 512;
|
||||
#elif defined(_BSD_SOURCE)
|
||||
return getpagesize();
|
||||
#else
|
||||
return (int)sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
}
|
||||
#endif /* SQLITE_DISABLE_MMAP */
|
||||
|
||||
#ifndef SQLITE_DISABLE_MMAP
|
||||
/*
|
||||
** Attempt to set the size of the memory mapping maintained by file
|
||||
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
||||
**
|
||||
** If successful, this function sets the following variables:
|
||||
**
|
||||
** unixFile.pMapRegion
|
||||
** unixFile.mmapSize
|
||||
** unixFile.mmapOrigsize
|
||||
**
|
||||
** If unsuccessful, an error message is logged via sqlite3_log() and
|
||||
** the three variables above are zeroed. In this case SQLite should
|
||||
** continue accessing the database using the xRead() and xWrite()
|
||||
** methods.
|
||||
*/
|
||||
static void unixRemapfile(
|
||||
unixFile *pFd, /* File descriptor object */
|
||||
i64 nNew /* Required mapping size */
|
||||
){
|
||||
const char *zErr = "mmap";
|
||||
int h = pFd->h; /* File descriptor open on db file */
|
||||
u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */
|
||||
i64 nOrig = pFd->mmapOrigsize; /* Size of pOrig region in bytes */
|
||||
u8 *pNew = 0; /* Location of new mapping */
|
||||
int flags = PROT_READ; /* Flags to pass to mmap() */
|
||||
|
||||
assert( pFd->nFetchOut==0 );
|
||||
assert( nNew>pFd->mmapSize );
|
||||
assert( nNew<=pFd->mmapLimit );
|
||||
assert( nNew>0 );
|
||||
assert( pFd->mmapOrigsize>=pFd->mmapSize );
|
||||
assert( MAP_FAILED!=0 );
|
||||
|
||||
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
||||
|
||||
if( pOrig ){
|
||||
const int szSyspage = unixGetPagesize();
|
||||
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
|
||||
u8 *pReq = &pOrig[nReuse];
|
||||
|
||||
/* Unmap any pages of the existing mapping that cannot be reused. */
|
||||
if( nReuse!=nOrig ){
|
||||
osMunmap(pReq, nOrig-nReuse);
|
||||
}
|
||||
|
||||
#if HAVE_MREMAP
|
||||
pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
|
||||
zErr = "mremap";
|
||||
#else
|
||||
pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
|
||||
if( pNew!=MAP_FAILED ){
|
||||
if( pNew!=pReq ){
|
||||
osMunmap(pNew, nNew - nReuse);
|
||||
pNew = 0;
|
||||
}else{
|
||||
pNew = pOrig;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The attempt to extend the existing mapping failed. Free it. */
|
||||
if( pNew==MAP_FAILED || pNew==0 ){
|
||||
osMunmap(pOrig, nReuse);
|
||||
}
|
||||
}
|
||||
|
||||
/* If pNew is still NULL, try to create an entirely new mapping. */
|
||||
if( pNew==0 ){
|
||||
pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
|
||||
}
|
||||
|
||||
if( pNew==MAP_FAILED ){
|
||||
pNew = 0;
|
||||
nNew = 0;
|
||||
unixLogError(SQLITE_OK, zErr, pFd->zPath);
|
||||
|
||||
/* If the mmap() above failed, assume that all subsequent mmap() calls
|
||||
** will probably fail too. Fall back to using xRead/xWrite exclusively
|
||||
** in this case. */
|
||||
pFd->mmapLimit = 0;
|
||||
}
|
||||
pFd->pMapRegion = (void *)pNew;
|
||||
pFd->mmapSize = pFd->mmapOrigsize = nNew;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Memory map or remap the file opened by file-descriptor pFd (if the file
|
||||
** is already mapped, the existing mapping is replaced by the new). Or, if
|
||||
** there already exists a mapping for this file, and there are still
|
||||
** outstanding xFetch() references to it, this function is a no-op.
|
||||
**
|
||||
** If parameter nByte is non-negative, then it is the requested size of
|
||||
** the mapping to create. Otherwise, if nByte is less than zero, then the
|
||||
** requested size is the size of the file on disk. The actual size of the
|
||||
** created mapping is either the requested size or the value configured
|
||||
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
|
||||
**
|
||||
** SQLITE_OK is returned if no error occurs (even if the mapping is not
|
||||
** recreated as a result of outstanding references) or an SQLite error
|
||||
** code otherwise.
|
||||
*/
|
||||
static int unixMapfile(unixFile *pFd, i64 nByte){
|
||||
#ifndef SQLITE_DISABLE_MMAP
|
||||
i64 nMap = nByte;
|
||||
int rc;
|
||||
|
||||
assert( nMap>=0 || pFd->nFetchOut==0 );
|
||||
if( pFd->nFetchOut>0 ) return SQLITE_OK;
|
||||
|
||||
if( nMap<0 ){
|
||||
struct stat statbuf; /* Low-level file information */
|
||||
rc = osFstat(pFd->h, &statbuf);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return SQLITE_IOERR_FSTAT;
|
||||
}
|
||||
nMap = statbuf.st_size;
|
||||
}
|
||||
if( nMap>pFd->mmapLimit ){
|
||||
nMap = pFd->mmapLimit;
|
||||
}
|
||||
|
||||
if( nMap!=pFd->mmapSize ){
|
||||
if( nMap>0 ){
|
||||
unixRemapfile(pFd, nMap);
|
||||
}else{
|
||||
unixUnmapfile(pFd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If possible, return a pointer to a mapping of file fd starting at offset
|
||||
** iOff. The mapping must be valid for at least nAmt bytes.
|
||||
**
|
||||
** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
|
||||
** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
|
||||
** Finally, if an error does occur, return an SQLite error code. The final
|
||||
** value of *pp is undefined in this case.
|
||||
**
|
||||
** If this function does return a pointer, the caller must eventually
|
||||
** release the reference by calling unixUnfetch().
|
||||
*/
|
||||
static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
|
||||
#ifndef SQLITE_DISABLE_MMAP
|
||||
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
|
||||
#endif
|
||||
*pp = 0;
|
||||
|
||||
#ifndef SQLITE_DISABLE_MMAP
|
||||
if( pFd->mmapLimit>0 ){
|
||||
if( pFd->pMapRegion==0 ){
|
||||
int rc = unixMapfile(pFd, -1);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
if( pFd->mmapSize >= iOff+nAmt ){
|
||||
*pp = &((u8 *)pFd->pMapRegion)[iOff];
|
||||
pFd->nFetchOut++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the third argument is non-NULL, then this function releases a
|
||||
** reference obtained by an earlier call to unixFetch(). The second
|
||||
** argument passed to this function must be the same as the corresponding
|
||||
** argument that was passed to the unixFetch() invocation.
|
||||
**
|
||||
** Or, if the third argument is NULL, then this function is being called
|
||||
** to inform the VFS layer that, according to POSIX, any existing mapping
|
||||
** may now be invalid and should be unmapped.
|
||||
*/
|
||||
static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
|
||||
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
|
||||
|
||||
/* If p==0 (unmap the entire file) then there must be no outstanding
|
||||
** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
|
||||
** then there must be at least one outstanding. */
|
||||
assert( (p==0)==(pFd->nFetchOut==0) );
|
||||
|
||||
/* If p!=0, it must match the iOff value. */
|
||||
assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
|
||||
|
||||
if( p ){
|
||||
pFd->nFetchOut--;
|
||||
}else{
|
||||
unixUnmapfile(pFd);
|
||||
}
|
||||
|
||||
assert( pFd->nFetchOut>=0 );
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Here ends the implementation of all sqlite3_file methods.
|
||||
**
|
||||
@@ -4480,7 +4856,9 @@ static const sqlite3_io_methods METHOD = { \
|
||||
unixShmMap, /* xShmMap */ \
|
||||
unixShmLock, /* xShmLock */ \
|
||||
unixShmBarrier, /* xShmBarrier */ \
|
||||
unixShmUnmap /* xShmUnmap */ \
|
||||
unixShmUnmap, /* xShmUnmap */ \
|
||||
unixFetch, /* xFetch */ \
|
||||
unixUnfetch, /* xUnfetch */ \
|
||||
}; \
|
||||
static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \
|
||||
UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \
|
||||
@@ -4497,7 +4875,7 @@ static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \
|
||||
IOMETHODS(
|
||||
posixIoFinder, /* Finder function name */
|
||||
posixIoMethods, /* sqlite3_io_methods object name */
|
||||
2, /* shared memory is enabled */
|
||||
3, /* shared memory and mmap are enabled */
|
||||
unixClose, /* xClose method */
|
||||
unixLock, /* xLock method */
|
||||
unixUnlock, /* xUnlock method */
|
||||
@@ -4748,11 +5126,12 @@ static int fillInUnixFile(
|
||||
pNew->pVfs = pVfs;
|
||||
pNew->zPath = zFilename;
|
||||
pNew->ctrlFlags = (u8)ctrlFlags;
|
||||
pNew->mmapLimit = sqlite3GlobalConfig.mxMmap;
|
||||
if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
|
||||
"psow", SQLITE_POWERSAFE_OVERWRITE) ){
|
||||
pNew->ctrlFlags |= UNIXFILE_PSOW;
|
||||
}
|
||||
if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
|
||||
if( strcmp(pVfs->zName,"unix-excl")==0 ){
|
||||
pNew->ctrlFlags |= UNIXFILE_EXCL;
|
||||
}
|
||||
|
||||
@@ -4784,7 +5163,7 @@ static int fillInUnixFile(
|
||||
unixEnterMutex();
|
||||
rc = findInodeInfo(pNew, &pNew->pInode);
|
||||
if( rc!=SQLITE_OK ){
|
||||
/* If an error occured in findInodeInfo(), close the file descriptor
|
||||
/* If an error occurred in findInodeInfo(), close the file descriptor
|
||||
** immediately, before releasing the mutex. findInodeInfo() may fail
|
||||
** in two scenarios:
|
||||
**
|
||||
@@ -4892,6 +5271,7 @@ static int fillInUnixFile(
|
||||
}else{
|
||||
pNew->pMethod = pLockingStyle;
|
||||
OpenCounter(+1);
|
||||
verifyDbFile(pNew);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -5422,7 +5802,7 @@ static int unixDelete(
|
||||
}
|
||||
|
||||
/*
|
||||
** Test the existance of or access permissions of file zPath. The
|
||||
** Test the existence of or access permissions of file zPath. The
|
||||
** test performed depends on the value of flags:
|
||||
**
|
||||
** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
|
||||
@@ -6985,7 +7365,7 @@ int sqlite3_os_init(void){
|
||||
|
||||
/* Double-check that the aSyscall[] array has been constructed
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==21 );
|
||||
assert( ArraySize(aSyscall)==24 );
|
||||
|
||||
/* Register all VFSes defined in the aVfs[] array */
|
||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||
|
||||
+311
-36
@@ -150,11 +150,20 @@ struct winFile {
|
||||
winceLock local; /* Locks obtained by this instance of winFile */
|
||||
winceLock *shared; /* Global shared lock memory for the file */
|
||||
#endif
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
int nFetchOut; /* Number of outstanding xFetch references */
|
||||
HANDLE hMap; /* Handle for accessing memory mapping */
|
||||
void *pMapRegion; /* Area memory mapped */
|
||||
sqlite3_int64 mmapSize; /* Usable size of mapped region */
|
||||
sqlite3_int64 mmapOrigsize; /* Actual size of mapped region */
|
||||
sqlite3_int64 mmapLimit; /* Configured FCNTL_MMAP_LIMIT value */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** Allowed values for winFile.ctrlFlags
|
||||
*/
|
||||
#define WINFILE_RDONLY 0x02 /* Connection is read only */
|
||||
#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
|
||||
#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
|
||||
|
||||
@@ -308,7 +317,7 @@ static int sqlite3_os_type = 0;
|
||||
** to all overrideable system calls.
|
||||
*/
|
||||
static struct win_syscall {
|
||||
const char *zName; /* Name of the sytem call */
|
||||
const char *zName; /* Name of the system call */
|
||||
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
|
||||
sqlite3_syscall_ptr pDefault; /* Default value */
|
||||
} aSyscall[] = {
|
||||
@@ -1838,7 +1847,8 @@ static BOOL winceLockFile(
|
||||
}
|
||||
|
||||
/* Want a pending lock? */
|
||||
else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
|
||||
else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
|
||||
&& nNumberOfBytesToLockLow == 1){
|
||||
/* If no pending lock has been acquired, then acquire it */
|
||||
if (pFile->shared->bPending == 0) {
|
||||
pFile->shared->bPending = TRUE;
|
||||
@@ -1848,7 +1858,8 @@ static BOOL winceLockFile(
|
||||
}
|
||||
|
||||
/* Want a reserved lock? */
|
||||
else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
|
||||
else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
|
||||
&& nNumberOfBytesToLockLow == 1){
|
||||
if (pFile->shared->bReserved == 0) {
|
||||
pFile->shared->bReserved = TRUE;
|
||||
pFile->local.bReserved = TRUE;
|
||||
@@ -1891,7 +1902,8 @@ static BOOL winceUnlockFile(
|
||||
|
||||
/* Did we just have a reader lock? */
|
||||
else if (pFile->local.nReaders){
|
||||
assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
|
||||
assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
|
||||
|| nNumberOfBytesToUnlockLow == 1);
|
||||
pFile->local.nReaders --;
|
||||
if (pFile->local.nReaders == 0)
|
||||
{
|
||||
@@ -1902,7 +1914,8 @@ static BOOL winceUnlockFile(
|
||||
}
|
||||
|
||||
/* Releasing a pending lock */
|
||||
else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
|
||||
else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
|
||||
&& nNumberOfBytesToUnlockLow == 1){
|
||||
if (pFile->local.bPending){
|
||||
pFile->local.bPending = FALSE;
|
||||
pFile->shared->bPending = FALSE;
|
||||
@@ -1910,7 +1923,8 @@ static BOOL winceUnlockFile(
|
||||
}
|
||||
}
|
||||
/* Releasing a reserved lock */
|
||||
else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
|
||||
else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
|
||||
&& nNumberOfBytesToUnlockLow == 1){
|
||||
if (pFile->local.bReserved) {
|
||||
pFile->local.bReserved = FALSE;
|
||||
pFile->shared->bReserved = FALSE;
|
||||
@@ -2020,7 +2034,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
|
||||
** containing the lower 32-bits of the new file-offset. Or, if it fails,
|
||||
** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
|
||||
** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
|
||||
** whether an error has actually occured, it is also necessary to call
|
||||
** whether an error has actually occurred, it is also necessary to call
|
||||
** GetLastError().
|
||||
*/
|
||||
dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
@@ -2056,6 +2070,9 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Forward references to VFS methods */
|
||||
static int winUnmapfile(winFile*);
|
||||
|
||||
/*
|
||||
** Close a file.
|
||||
**
|
||||
@@ -2077,6 +2094,12 @@ static int winClose(sqlite3_file *id){
|
||||
#endif
|
||||
OSTRACE(("CLOSE %d\n", pFile->h));
|
||||
assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
rc = winUnmapfile(pFile);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
#endif
|
||||
|
||||
do{
|
||||
rc = osCloseHandle(pFile->h);
|
||||
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
|
||||
@@ -2125,9 +2148,27 @@ static int winRead(
|
||||
int nRetry = 0; /* Number of retrys */
|
||||
|
||||
assert( id!=0 );
|
||||
assert( amt>0 );
|
||||
SimulateIOError(return SQLITE_IOERR_READ);
|
||||
OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
/* Deal with as much of this read request as possible by transfering
|
||||
** data from the memory mapping using memcpy(). */
|
||||
if( offset<pFile->mmapSize ){
|
||||
if( offset+amt <= pFile->mmapSize ){
|
||||
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
int nCopy = (int)(pFile->mmapSize - offset);
|
||||
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
|
||||
pBuf = &((u8 *)pBuf)[nCopy];
|
||||
amt -= nCopy;
|
||||
offset += nCopy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE
|
||||
if( seekWinFile(pFile, offset) ){
|
||||
return SQLITE_FULL;
|
||||
@@ -2166,7 +2207,7 @@ static int winWrite(
|
||||
int amt, /* Number of bytes to write */
|
||||
sqlite3_int64 offset /* Offset into the file to begin writing at */
|
||||
){
|
||||
int rc = 0; /* True if error has occured, else false */
|
||||
int rc = 0; /* True if error has occurred, else false */
|
||||
winFile *pFile = (winFile*)id; /* File handle */
|
||||
int nRetry = 0; /* Number of retries */
|
||||
|
||||
@@ -2177,6 +2218,23 @@ static int winWrite(
|
||||
|
||||
OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
/* Deal with as much of this write request as possible by transfering
|
||||
** data from the memory mapping using memcpy(). */
|
||||
if( offset<pFile->mmapSize ){
|
||||
if( offset+amt <= pFile->mmapSize ){
|
||||
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
int nCopy = (int)(pFile->mmapSize - offset);
|
||||
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
|
||||
pBuf = &((u8 *)pBuf)[nCopy];
|
||||
amt -= nCopy;
|
||||
offset += nCopy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE
|
||||
rc = seekWinFile(pFile, offset);
|
||||
if( rc==0 ){
|
||||
@@ -2244,6 +2302,7 @@ static int winWrite(
|
||||
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
|
||||
winFile *pFile = (winFile*)id; /* File handle object */
|
||||
int rc = SQLITE_OK; /* Return code for this function */
|
||||
DWORD lastErrno;
|
||||
|
||||
assert( pFile );
|
||||
|
||||
@@ -2262,13 +2321,24 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
|
||||
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
|
||||
if( seekWinFile(pFile, nByte) ){
|
||||
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
|
||||
"winTruncate1", pFile->zPath);
|
||||
}else if( 0==osSetEndOfFile(pFile->h) ){
|
||||
pFile->lastErrno = osGetLastError();
|
||||
"winTruncate1", pFile->zPath);
|
||||
}else if( 0==osSetEndOfFile(pFile->h) &&
|
||||
((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
|
||||
pFile->lastErrno = lastErrno;
|
||||
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
|
||||
"winTruncate2", pFile->zPath);
|
||||
"winTruncate2", pFile->zPath);
|
||||
}
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
/* If the file was truncated to a size smaller than the currently
|
||||
** mapped region, reduce the effective mapping size as well. SQLite will
|
||||
** use read() and write() to access data beyond this point from now on.
|
||||
*/
|
||||
if( pFile->pMapRegion && nByte<pFile->mmapSize ){
|
||||
pFile->mmapSize = nByte;
|
||||
}
|
||||
#endif
|
||||
|
||||
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
|
||||
return rc;
|
||||
}
|
||||
@@ -2636,7 +2706,7 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
rc = 1;
|
||||
OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
|
||||
}else{
|
||||
rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
|
||||
rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
|
||||
if( rc ){
|
||||
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
|
||||
}
|
||||
@@ -2776,6 +2846,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
case SQLITE_FCNTL_MMAP_LIMIT: {
|
||||
i64 newLimit = *(i64*)pArg;
|
||||
*(i64*)pArg = pFile->mmapLimit;
|
||||
if( newLimit>=0 ) pFile->mmapLimit = newLimit;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return SQLITE_NOTFOUND;
|
||||
}
|
||||
@@ -3073,7 +3151,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
rc = winOpen(pDbFd->pVfs,
|
||||
pShmNode->zFilename, /* Name of the file (UTF-8) */
|
||||
(sqlite3_file*)&pShmNode->hFile, /* File handle here */
|
||||
SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
|
||||
SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||||
0);
|
||||
if( SQLITE_OK!=rc ){
|
||||
goto shm_open_err;
|
||||
@@ -3446,6 +3524,192 @@ shmpage_out:
|
||||
# define winShmUnmap 0
|
||||
#endif /* #ifndef SQLITE_OMIT_WAL */
|
||||
|
||||
/*
|
||||
** Cleans up the mapped region of the specified file, if any.
|
||||
*/
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
static int winUnmapfile(winFile *pFile){
|
||||
assert( pFile!=0 );
|
||||
if( pFile->pMapRegion ){
|
||||
if( !osUnmapViewOfFile(pFile->pMapRegion) ){
|
||||
pFile->lastErrno = osGetLastError();
|
||||
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
|
||||
"winUnmap1", pFile->zPath);
|
||||
}
|
||||
pFile->pMapRegion = 0;
|
||||
pFile->mmapSize = 0;
|
||||
pFile->mmapOrigsize = 0;
|
||||
}
|
||||
if( pFile->hMap!=NULL ){
|
||||
if( !osCloseHandle(pFile->hMap) ){
|
||||
pFile->lastErrno = osGetLastError();
|
||||
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
|
||||
"winUnmap2", pFile->zPath);
|
||||
}
|
||||
pFile->hMap = NULL;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Memory map or remap the file opened by file-descriptor pFd (if the file
|
||||
** is already mapped, the existing mapping is replaced by the new). Or, if
|
||||
** there already exists a mapping for this file, and there are still
|
||||
** outstanding xFetch() references to it, this function is a no-op.
|
||||
**
|
||||
** If parameter nByte is non-negative, then it is the requested size of
|
||||
** the mapping to create. Otherwise, if nByte is less than zero, then the
|
||||
** requested size is the size of the file on disk. The actual size of the
|
||||
** created mapping is either the requested size or the value configured
|
||||
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
|
||||
**
|
||||
** SQLITE_OK is returned if no error occurs (even if the mapping is not
|
||||
** recreated as a result of outstanding references) or an SQLite error
|
||||
** code otherwise.
|
||||
*/
|
||||
static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
|
||||
sqlite3_int64 nMap = nByte;
|
||||
int rc;
|
||||
|
||||
assert( nMap>=0 || pFd->nFetchOut==0 );
|
||||
if( pFd->nFetchOut>0 ) return SQLITE_OK;
|
||||
|
||||
if( nMap<0 ){
|
||||
rc = winFileSize((sqlite3_file*)pFd, &nMap);
|
||||
if( rc ){
|
||||
return SQLITE_IOERR_FSTAT;
|
||||
}
|
||||
}
|
||||
if( nMap>pFd->mmapLimit ){
|
||||
nMap = pFd->mmapLimit;
|
||||
}
|
||||
nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
|
||||
|
||||
if( nMap==0 && pFd->mmapSize>0 ){
|
||||
winUnmapfile(pFd);
|
||||
}
|
||||
if( nMap!=pFd->mmapSize ){
|
||||
void *pNew = 0;
|
||||
DWORD protect = PAGE_READONLY;
|
||||
DWORD flags = FILE_MAP_READ;
|
||||
|
||||
winUnmapfile(pFd);
|
||||
if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
|
||||
protect = PAGE_READWRITE;
|
||||
flags |= FILE_MAP_WRITE;
|
||||
}
|
||||
#if SQLITE_OS_WINRT
|
||||
pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
|
||||
#elif defined(SQLITE_WIN32_HAS_WIDE)
|
||||
pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
|
||||
(DWORD)((nMap>>32) & 0xffffffff),
|
||||
(DWORD)(nMap & 0xffffffff), NULL);
|
||||
#elif defined(SQLITE_WIN32_HAS_ANSI)
|
||||
pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
|
||||
(DWORD)((nMap>>32) & 0xffffffff),
|
||||
(DWORD)(nMap & 0xffffffff), NULL);
|
||||
#endif
|
||||
if( pFd->hMap==NULL ){
|
||||
pFd->lastErrno = osGetLastError();
|
||||
rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
|
||||
"winMapfile", pFd->zPath);
|
||||
/* Log the error, but continue normal operation using xRead/xWrite */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
assert( (nMap % winSysInfo.dwPageSize)==0 );
|
||||
#if SQLITE_OS_WINRT
|
||||
pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
|
||||
#else
|
||||
assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
|
||||
pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
|
||||
#endif
|
||||
if( pNew==NULL ){
|
||||
osCloseHandle(pFd->hMap);
|
||||
pFd->hMap = NULL;
|
||||
pFd->lastErrno = osGetLastError();
|
||||
winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
|
||||
"winMapfile", pFd->zPath);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
pFd->pMapRegion = pNew;
|
||||
pFd->mmapSize = nMap;
|
||||
pFd->mmapOrigsize = nMap;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* !defined(SQLITE_DISABLE_MMAP) */
|
||||
|
||||
/*
|
||||
** If possible, return a pointer to a mapping of file fd starting at offset
|
||||
** iOff. The mapping must be valid for at least nAmt bytes.
|
||||
**
|
||||
** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
|
||||
** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
|
||||
** Finally, if an error does occur, return an SQLite error code. The final
|
||||
** value of *pp is undefined in this case.
|
||||
**
|
||||
** If this function does return a pointer, the caller must eventually
|
||||
** release the reference by calling unixUnfetch().
|
||||
*/
|
||||
static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
winFile *pFd = (winFile*)fd; /* The underlying database file */
|
||||
#endif
|
||||
*pp = 0;
|
||||
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
if( pFd->mmapLimit>0 ){
|
||||
if( pFd->pMapRegion==0 ){
|
||||
int rc = winMapfile(pFd, -1);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
if( pFd->mmapSize >= iOff+nAmt ){
|
||||
*pp = &((u8 *)pFd->pMapRegion)[iOff];
|
||||
pFd->nFetchOut++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the third argument is non-NULL, then this function releases a
|
||||
** reference obtained by an earlier call to unixFetch(). The second
|
||||
** argument passed to this function must be the same as the corresponding
|
||||
** argument that was passed to the unixFetch() invocation.
|
||||
**
|
||||
** Or, if the third argument is NULL, then this function is being called
|
||||
** to inform the VFS layer that, according to POSIX, any existing mapping
|
||||
** may now be invalid and should be unmapped.
|
||||
*/
|
||||
static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
winFile *pFd = (winFile*)fd; /* The underlying database file */
|
||||
|
||||
/* If p==0 (unmap the entire file) then there must be no outstanding
|
||||
** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
|
||||
** then there must be at least one outstanding. */
|
||||
assert( (p==0)==(pFd->nFetchOut==0) );
|
||||
|
||||
/* If p!=0, it must match the iOff value. */
|
||||
assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
|
||||
|
||||
if( p ){
|
||||
pFd->nFetchOut--;
|
||||
}else{
|
||||
/* FIXME: If Windows truly always prevents truncating or deleting a
|
||||
** file while a mapping is held, then the following winUnmapfile() call
|
||||
** is unnecessary can can be omitted - potentially improving
|
||||
** performance. */
|
||||
winUnmapfile(pFd);
|
||||
}
|
||||
|
||||
assert( pFd->nFetchOut>=0 );
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Here ends the implementation of all sqlite3_file methods.
|
||||
**
|
||||
@@ -3457,7 +3721,7 @@ shmpage_out:
|
||||
** sqlite3_file for win32.
|
||||
*/
|
||||
static const sqlite3_io_methods winIoMethod = {
|
||||
2, /* iVersion */
|
||||
3, /* iVersion */
|
||||
winClose, /* xClose */
|
||||
winRead, /* xRead */
|
||||
winWrite, /* xWrite */
|
||||
@@ -3473,7 +3737,9 @@ static const sqlite3_io_methods winIoMethod = {
|
||||
winShmMap, /* xShmMap */
|
||||
winShmLock, /* xShmLock */
|
||||
winShmBarrier, /* xShmBarrier */
|
||||
winShmUnmap /* xShmUnmap */
|
||||
winShmUnmap, /* xShmUnmap */
|
||||
winFetch, /* xFetch */
|
||||
winUnfetch /* xUnfetch */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -3649,9 +3915,7 @@ static int winOpen(
|
||||
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
|
||||
int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
|
||||
int isCreate = (flags & SQLITE_OPEN_CREATE);
|
||||
#ifndef NDEBUG
|
||||
int isReadonly = (flags & SQLITE_OPEN_READONLY);
|
||||
#endif
|
||||
int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -3827,7 +4091,9 @@ static int winOpen(
|
||||
sqlite3_free(zConverted);
|
||||
if( isReadWrite && !isExclusive ){
|
||||
return winOpen(pVfs, zName, id,
|
||||
((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
|
||||
((flags|SQLITE_OPEN_READONLY) &
|
||||
~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
|
||||
pOutFlags);
|
||||
}else{
|
||||
return SQLITE_CANTOPEN_BKPT;
|
||||
}
|
||||
@@ -3860,11 +4126,21 @@ static int winOpen(
|
||||
pFile->pMethod = &winIoMethod;
|
||||
pFile->pVfs = pVfs;
|
||||
pFile->h = h;
|
||||
if( isReadonly ){
|
||||
pFile->ctrlFlags |= WINFILE_RDONLY;
|
||||
}
|
||||
if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
|
||||
pFile->ctrlFlags |= WINFILE_PSOW;
|
||||
}
|
||||
pFile->lastErrno = NO_ERROR;
|
||||
pFile->zPath = zName;
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
pFile->hMap = NULL;
|
||||
pFile->pMapRegion = 0;
|
||||
pFile->mmapSize = 0;
|
||||
pFile->mmapOrigsize = 0;
|
||||
pFile->mmapLimit = sqlite3GlobalConfig.mxMmap;
|
||||
#endif
|
||||
|
||||
OpenCounter(+1);
|
||||
return rc;
|
||||
@@ -3910,7 +4186,8 @@ static int winDelete(
|
||||
attr = sAttrData.dwFileAttributes;
|
||||
}else{
|
||||
lastErrno = osGetLastError();
|
||||
if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
|
||||
if( lastErrno==ERROR_FILE_NOT_FOUND
|
||||
|| lastErrno==ERROR_PATH_NOT_FOUND ){
|
||||
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -3922,7 +4199,8 @@ static int winDelete(
|
||||
#endif
|
||||
if ( attr==INVALID_FILE_ATTRIBUTES ){
|
||||
lastErrno = osGetLastError();
|
||||
if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
|
||||
if( lastErrno==ERROR_FILE_NOT_FOUND
|
||||
|| lastErrno==ERROR_PATH_NOT_FOUND ){
|
||||
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -3949,7 +4227,8 @@ static int winDelete(
|
||||
attr = osGetFileAttributesA(zConverted);
|
||||
if ( attr==INVALID_FILE_ATTRIBUTES ){
|
||||
lastErrno = osGetLastError();
|
||||
if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
|
||||
if( lastErrno==ERROR_FILE_NOT_FOUND
|
||||
|| lastErrno==ERROR_PATH_NOT_FOUND ){
|
||||
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -3983,7 +4262,7 @@ static int winDelete(
|
||||
}
|
||||
|
||||
/*
|
||||
** Check the existance and status of a file.
|
||||
** Check the existence and status of a file.
|
||||
*/
|
||||
static int winAccess(
|
||||
sqlite3_vfs *pVfs, /* Not used on win32 */
|
||||
@@ -4117,16 +4396,12 @@ static int winFullPathname(
|
||||
*/
|
||||
char zOut[MAX_PATH+1];
|
||||
memset(zOut, 0, MAX_PATH+1);
|
||||
cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
|
||||
cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
|
||||
MAX_PATH+1);
|
||||
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
|
||||
sqlite3_data_directory, zOut);
|
||||
}else{
|
||||
/*
|
||||
** NOTE: The Cygwin docs state that the maximum length needed
|
||||
** for the buffer passed to cygwin_conv_to_full_win32_path
|
||||
** is MAX_PATH.
|
||||
*/
|
||||
cygwin_conv_to_full_win32_path(zRelative, zFull);
|
||||
cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
@@ -4284,9 +4559,9 @@ static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
|
||||
}
|
||||
static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
|
||||
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
|
||||
return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
|
||||
}
|
||||
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
@@ -4384,7 +4659,8 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
|
||||
#endif
|
||||
/* 2^32 - to avoid use of LL and warnings in gcc */
|
||||
static const sqlite3_int64 max32BitValue =
|
||||
(sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
|
||||
(sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
|
||||
(sqlite3_int64)294967296;
|
||||
|
||||
#if SQLITE_OS_WINCE
|
||||
SYSTEMTIME time;
|
||||
@@ -4493,7 +4769,6 @@ int sqlite3_os_init(void){
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==74 );
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/* get memory map allocation granularity */
|
||||
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
|
||||
#if SQLITE_OS_WINRT
|
||||
@@ -4501,8 +4776,8 @@ int sqlite3_os_init(void){
|
||||
#else
|
||||
osGetSystemInfo(&winSysInfo);
|
||||
#endif
|
||||
assert(winSysInfo.dwAllocationGranularity > 0);
|
||||
#endif
|
||||
assert( winSysInfo.dwAllocationGranularity>0 );
|
||||
assert( winSysInfo.dwPageSize>0 );
|
||||
|
||||
sqlite3_vfs_register(&winVfs, 1);
|
||||
return SQLITE_OK;
|
||||
|
||||
+270
-69
@@ -273,7 +273,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
|
||||
** * A write transaction is active.
|
||||
** * An EXCLUSIVE or greater lock is held on the database file.
|
||||
** * All writing and syncing of journal and database data has finished.
|
||||
** If no error occured, all that remains is to finalize the journal to
|
||||
** If no error occurred, all that remains is to finalize the journal to
|
||||
** commit the transaction. If an error did occur, the caller will need
|
||||
** to rollback the transaction.
|
||||
**
|
||||
@@ -521,7 +521,7 @@ struct PagerSavepoint {
|
||||
**
|
||||
** doNotSpill, doNotSyncSpill
|
||||
**
|
||||
** These two boolean variables control the behaviour of cache-spills
|
||||
** These two boolean variables control the behavior of cache-spills
|
||||
** (calls made by the pcache module to the pagerStress() routine to
|
||||
** write cached data to the file-system in order to free up memory).
|
||||
**
|
||||
@@ -655,6 +655,11 @@ struct Pager {
|
||||
PagerSavepoint *aSavepoint; /* Array of active savepoints */
|
||||
int nSavepoint; /* Number of elements in aSavepoint[] */
|
||||
char dbFileVers[16]; /* Changes whenever database file changes */
|
||||
|
||||
u8 bUseFetch; /* True to use xFetch() */
|
||||
int nMmapOut; /* Number of mmap pages currently outstanding */
|
||||
sqlite3_int64 mxMmap; /* Desired maximum mmap size */
|
||||
PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
|
||||
/*
|
||||
** End of the routinely-changing class members
|
||||
***************************************************************************/
|
||||
@@ -765,6 +770,16 @@ static const unsigned char aJournalMagic[] = {
|
||||
# define MEMDB pPager->memDb
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
|
||||
** interfaces to access the database using memory-mapped I/O.
|
||||
*/
|
||||
#ifdef SQLITE_DISABLE_MMAP
|
||||
# define USEFETCH(x) 0
|
||||
#else
|
||||
# define USEFETCH(x) ((x)->bUseFetch)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The maximum legal page number is (2^31 - 1).
|
||||
*/
|
||||
@@ -1399,7 +1414,7 @@ static int writeJournalHdr(Pager *pPager){
|
||||
memset(zHeader, 0, sizeof(aJournalMagic)+4);
|
||||
}
|
||||
|
||||
/* The random check-hash initialiser */
|
||||
/* The random check-hash initializer */
|
||||
sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
|
||||
put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
|
||||
/* The initial database size */
|
||||
@@ -1838,6 +1853,8 @@ static int pager_error(Pager *pPager, int rc){
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pager_truncate(Pager *pPager, Pgno nPage);
|
||||
|
||||
/*
|
||||
** This routine ends a transaction. A transaction is usually ended by
|
||||
** either a COMMIT or a ROLLBACK operation. This routine may be called
|
||||
@@ -1891,7 +1908,7 @@ static int pager_error(Pager *pPager, int rc){
|
||||
** to the first error encountered (the journal finalization one) is
|
||||
** returned.
|
||||
*/
|
||||
static int pager_end_transaction(Pager *pPager, int hasMaster){
|
||||
static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
|
||||
int rc = SQLITE_OK; /* Error code from journal finalization operation */
|
||||
int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
|
||||
|
||||
@@ -1977,7 +1994,17 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
|
||||
*/
|
||||
rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
|
||||
assert( rc2==SQLITE_OK );
|
||||
}else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
|
||||
/* This branch is taken when committing a transaction in rollback-journal
|
||||
** mode if the database file on disk is larger than the database image.
|
||||
** At this point the journal has been finalized and the transaction
|
||||
** successfully committed, but the EXCLUSIVE lock is still held on the
|
||||
** file. So it is safe to truncate the database file to its minimum
|
||||
** required size. */
|
||||
assert( pPager->eLock==EXCLUSIVE_LOCK );
|
||||
rc = pager_truncate(pPager, pPager->dbSize);
|
||||
}
|
||||
|
||||
if( !pPager->exclusiveMode
|
||||
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
|
||||
){
|
||||
@@ -2016,7 +2043,7 @@ static void pagerUnlockAndRollback(Pager *pPager){
|
||||
sqlite3EndBenignMalloc();
|
||||
}else if( !pPager->exclusiveMode ){
|
||||
assert( pPager->eState==PAGER_READER );
|
||||
pager_end_transaction(pPager, 0);
|
||||
pager_end_transaction(pPager, 0, 0);
|
||||
}
|
||||
}
|
||||
pager_unlock(pPager);
|
||||
@@ -2240,7 +2267,7 @@ static int pager_playback_one_page(
|
||||
i64 ofst = (pgno-1)*(i64)pPager->pageSize;
|
||||
testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
|
||||
assert( !pagerUseWal(pPager) );
|
||||
rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst);
|
||||
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
|
||||
if( pgno>pPager->dbFileSize ){
|
||||
pPager->dbFileSize = pgno;
|
||||
}
|
||||
@@ -2631,6 +2658,7 @@ static int pager_playback(Pager *pPager, int isHot){
|
||||
int res = 1; /* Value returned by sqlite3OsAccess() */
|
||||
char *zMaster = 0; /* Name of master journal file if any */
|
||||
int needPagerReset; /* True to reset page prior to first page rollback */
|
||||
int nPlayback = 0; /* Total number of pages restored from journal */
|
||||
|
||||
/* Figure out how many records are in the journal. Abort early if
|
||||
** the journal is empty.
|
||||
@@ -2731,7 +2759,9 @@ static int pager_playback(Pager *pPager, int isHot){
|
||||
needPagerReset = 0;
|
||||
}
|
||||
rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( rc==SQLITE_OK ){
|
||||
nPlayback++;
|
||||
}else{
|
||||
if( rc==SQLITE_DONE ){
|
||||
pPager->journalOff = szJ;
|
||||
break;
|
||||
@@ -2791,7 +2821,7 @@ end_playback:
|
||||
rc = sqlite3PagerSync(pPager);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = pager_end_transaction(pPager, zMaster[0]!='\0');
|
||||
rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
}
|
||||
if( rc==SQLITE_OK && zMaster[0] && res ){
|
||||
@@ -2801,6 +2831,10 @@ end_playback:
|
||||
rc = pager_delmaster(pPager, zMaster);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
}
|
||||
if( isHot && nPlayback ){
|
||||
sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
|
||||
nPlayback, pPager->zJournal);
|
||||
}
|
||||
|
||||
/* The Pager.sectorSize variable may have been updated while rolling
|
||||
** back a journal created by a process with a different sector size
|
||||
@@ -2822,11 +2856,10 @@ end_playback:
|
||||
** If an IO error occurs, then the IO error is returned to the caller.
|
||||
** Otherwise, SQLITE_OK is returned.
|
||||
*/
|
||||
static int readDbPage(PgHdr *pPg){
|
||||
static int readDbPage(PgHdr *pPg, u32 iFrame){
|
||||
Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
|
||||
Pgno pgno = pPg->pgno; /* Page number to read */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int isInWal = 0; /* True if page is in log file */
|
||||
int pgsz = pPager->pageSize; /* Number of bytes to read */
|
||||
|
||||
assert( pPager->eState>=PAGER_READER && !MEMDB );
|
||||
@@ -2838,11 +2871,10 @@ static int readDbPage(PgHdr *pPg){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
if( pagerUseWal(pPager) ){
|
||||
if( iFrame ){
|
||||
/* Try to pull the page from the write-ahead log. */
|
||||
rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData);
|
||||
}
|
||||
if( rc==SQLITE_OK && !isInWal ){
|
||||
rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
|
||||
}else{
|
||||
i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
|
||||
rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
|
||||
if( rc==SQLITE_IOERR_SHORT_READ ){
|
||||
@@ -2921,12 +2953,17 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){
|
||||
Pager *pPager = (Pager *)pCtx;
|
||||
PgHdr *pPg;
|
||||
|
||||
assert( pagerUseWal(pPager) );
|
||||
pPg = sqlite3PagerLookup(pPager, iPg);
|
||||
if( pPg ){
|
||||
if( sqlite3PcachePageRefcount(pPg)==1 ){
|
||||
sqlite3PcacheDrop(pPg);
|
||||
}else{
|
||||
rc = readDbPage(pPg);
|
||||
u32 iFrame = 0;
|
||||
rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = readDbPage(pPg, iFrame);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pPager->xReiniter(pPg);
|
||||
}
|
||||
@@ -3070,6 +3107,7 @@ static int pagerBeginReadTransaction(Pager *pPager){
|
||||
rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
|
||||
if( rc!=SQLITE_OK || changed ){
|
||||
pager_reset(pPager);
|
||||
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -3331,6 +3369,29 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
|
||||
sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
|
||||
}
|
||||
|
||||
/*
|
||||
** Invoke SQLITE_FCNTL_MMAP_LIMIT based on the current value of mxMmap.
|
||||
*/
|
||||
static void pagerFixMaplimit(Pager *pPager){
|
||||
#if !defined(SQLITE_DISABLE_MMAP)
|
||||
sqlite3_file *fd = pPager->fd;
|
||||
if( isOpen(fd) ){
|
||||
sqlite3_int64 mx;
|
||||
pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->mxMmap>0;
|
||||
mx = pPager->mxMmap;
|
||||
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_LIMIT, &mx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the maximum size of any memory mapping made of the database file.
|
||||
*/
|
||||
void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 mxMmap){
|
||||
pPager->mxMmap = mxMmap;
|
||||
pagerFixMaplimit(pPager);
|
||||
}
|
||||
|
||||
/*
|
||||
** Free as much memory as possible from the pager.
|
||||
*/
|
||||
@@ -3566,6 +3627,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
|
||||
assert( nReserve>=0 && nReserve<1000 );
|
||||
pPager->nReserve = (i16)nReserve;
|
||||
pagerReportSize(pPager);
|
||||
pagerFixMaplimit(pPager);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -3719,7 +3781,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
|
||||
** dirty page were to be discarded from the cache via the pagerStress()
|
||||
** routine, pagerStress() would not write the current page content to
|
||||
** the database file. If a savepoint transaction were rolled back after
|
||||
** this happened, the correct behaviour would be to restore the current
|
||||
** this happened, the correct behavior would be to restore the current
|
||||
** content of the page. However, since this content is not present in either
|
||||
** the database file or the portion of the rollback journal and
|
||||
** sub-journal rolled back the content could not be restored and the
|
||||
@@ -3743,12 +3805,26 @@ static void assertTruncateConstraint(Pager *pPager){
|
||||
** function does not actually modify the database file on disk. It
|
||||
** just sets the internal state of the pager object so that the
|
||||
** truncation will be done when the current transaction is committed.
|
||||
**
|
||||
** This function is only called right before committing a transaction.
|
||||
** Once this function has been called, the transaction must either be
|
||||
** rolled back or committed. It is not safe to call this function and
|
||||
** then continue writing to the database.
|
||||
*/
|
||||
void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
|
||||
assert( pPager->dbSize>=nPage );
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
||||
pPager->dbSize = nPage;
|
||||
assertTruncateConstraint(pPager);
|
||||
|
||||
/* At one point the code here called assertTruncateConstraint() to
|
||||
** ensure that all pages being truncated away by this operation are,
|
||||
** if one or more savepoints are open, present in the savepoint
|
||||
** journal so that they can be restored if the savepoint is rolled
|
||||
** back. This is no longer necessary as this function is now only
|
||||
** called right before committing a transaction. So although the
|
||||
** Pager object may still have open savepoints (Pager.nSavepoint!=0),
|
||||
** they cannot be rolled back. So the assertTruncateConstraint() call
|
||||
** is no longer correct. */
|
||||
}
|
||||
|
||||
|
||||
@@ -3777,6 +3853,81 @@ static int pagerSyncHotJournal(Pager *pPager){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Obtain a reference to a memory mapped page object for page number pgno.
|
||||
** The new object will use the pointer pData, obtained from xFetch().
|
||||
** If successful, set *ppPage to point to the new page reference
|
||||
** and return SQLITE_OK. Otherwise, return an SQLite error code and set
|
||||
** *ppPage to zero.
|
||||
**
|
||||
** Page references obtained by calling this function should be released
|
||||
** by calling pagerReleaseMapPage().
|
||||
*/
|
||||
static int pagerAcquireMapPage(
|
||||
Pager *pPager, /* Pager object */
|
||||
Pgno pgno, /* Page number */
|
||||
void *pData, /* xFetch()'d data for this page */
|
||||
PgHdr **ppPage /* OUT: Acquired page object */
|
||||
){
|
||||
PgHdr *p; /* Memory mapped page to return */
|
||||
|
||||
if( pPager->pMmapFreelist ){
|
||||
*ppPage = p = pPager->pMmapFreelist;
|
||||
pPager->pMmapFreelist = p->pDirty;
|
||||
p->pDirty = 0;
|
||||
memset(p->pExtra, 0, pPager->nExtra);
|
||||
}else{
|
||||
*ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
|
||||
if( p==0 ){
|
||||
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
p->pExtra = (void *)&p[1];
|
||||
p->flags = PGHDR_MMAP;
|
||||
p->nRef = 1;
|
||||
p->pPager = pPager;
|
||||
}
|
||||
|
||||
assert( p->pExtra==(void *)&p[1] );
|
||||
assert( p->pPage==0 );
|
||||
assert( p->flags==PGHDR_MMAP );
|
||||
assert( p->pPager==pPager );
|
||||
assert( p->nRef==1 );
|
||||
|
||||
p->pgno = pgno;
|
||||
p->pData = pData;
|
||||
pPager->nMmapOut++;
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Release a reference to page pPg. pPg must have been returned by an
|
||||
** earlier call to pagerAcquireMapPage().
|
||||
*/
|
||||
static void pagerReleaseMapPage(PgHdr *pPg){
|
||||
Pager *pPager = pPg->pPager;
|
||||
pPager->nMmapOut--;
|
||||
pPg->pDirty = pPager->pMmapFreelist;
|
||||
pPager->pMmapFreelist = pPg;
|
||||
|
||||
assert( pPager->fd->pMethods->iVersion>=3 );
|
||||
sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
|
||||
}
|
||||
|
||||
/*
|
||||
** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
|
||||
*/
|
||||
static void pagerFreeMapHdrs(Pager *pPager){
|
||||
PgHdr *p;
|
||||
PgHdr *pNext;
|
||||
for(p=pPager->pMmapFreelist; p; p=pNext){
|
||||
pNext = p->pDirty;
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Shutdown the page cache. Free all memory and close all files.
|
||||
**
|
||||
@@ -3797,6 +3948,7 @@ int sqlite3PagerClose(Pager *pPager){
|
||||
assert( assert_pager_state(pPager) );
|
||||
disable_simulated_io_errors();
|
||||
sqlite3BeginBenignMalloc();
|
||||
pagerFreeMapHdrs(pPager);
|
||||
/* pPager->errCode = 0; */
|
||||
pPager->exclusiveMode = 0;
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
@@ -4058,7 +4210,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
|
||||
** file size will be.
|
||||
*/
|
||||
assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
|
||||
if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
|
||||
if( rc==SQLITE_OK
|
||||
&& (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize
|
||||
){
|
||||
sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
|
||||
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
|
||||
pPager->dbHintSize = pPager->dbSize;
|
||||
@@ -4612,6 +4766,7 @@ int sqlite3PagerOpen(
|
||||
/* pPager->pBusyHandlerArg = 0; */
|
||||
pPager->xReiniter = xReinit;
|
||||
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
|
||||
/* pPager->mxMmap = SQLITE_DEFAULT_MMAP_LIMIT // will be set by btree.c */
|
||||
|
||||
*ppPager = pPager;
|
||||
return SQLITE_OK;
|
||||
@@ -4801,6 +4956,11 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
goto failed;
|
||||
}
|
||||
if( bHotJournal ){
|
||||
if( pPager->readOnly ){
|
||||
rc = SQLITE_READONLY_ROLLBACK;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Get an EXCLUSIVE lock on the database file. At this point it is
|
||||
** important that a RESERVED lock is not obtained on the way to the
|
||||
** EXCLUSIVE lock. If it were, another process might open the
|
||||
@@ -4898,9 +5058,11 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
);
|
||||
}
|
||||
|
||||
if( !pPager->tempFile
|
||||
&& (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0)
|
||||
){
|
||||
if( !pPager->tempFile && (
|
||||
pPager->pBackup
|
||||
|| sqlite3PcachePagecount(pPager->pPCache)>0
|
||||
|| USEFETCH(pPager)
|
||||
)){
|
||||
/* The shared-lock has just been acquired on the database file
|
||||
** and there are already pages in the cache (from a previous
|
||||
** read or write transaction). Check to see if the database
|
||||
@@ -4926,7 +5088,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
if( nPage>0 ){
|
||||
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
|
||||
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
|
||||
goto failed;
|
||||
}
|
||||
}else{
|
||||
@@ -4935,6 +5097,16 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
|
||||
if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
|
||||
pager_reset(pPager);
|
||||
|
||||
/* Unmap the database file. It is possible that external processes
|
||||
** may have truncated the database file and then extended it back
|
||||
** to its original size while this process was not holding a lock.
|
||||
** In this case there may exist a Pager.pMap mapping that appears
|
||||
** to be the right size but is not actually valid. Avoid this
|
||||
** possibility by unmapping the db here. */
|
||||
if( USEFETCH(pPager) ){
|
||||
sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4976,7 +5148,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
** nothing to rollback, so this routine is a no-op.
|
||||
*/
|
||||
static void pagerUnlockIfUnused(Pager *pPager){
|
||||
if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
|
||||
if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
|
||||
pagerUnlockAndRollback(pPager);
|
||||
}
|
||||
}
|
||||
@@ -5035,13 +5207,24 @@ int sqlite3PagerAcquire(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
int noContent /* Do not bother reading content from disk if true */
|
||||
int flags /* PAGER_ACQUIRE_XXX flags */
|
||||
){
|
||||
int rc;
|
||||
PgHdr *pPg;
|
||||
int rc = SQLITE_OK;
|
||||
PgHdr *pPg = 0;
|
||||
u32 iFrame = 0; /* Frame to read from WAL file */
|
||||
const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
|
||||
|
||||
/* It is acceptable to use a read-only (mmap) page for any page except
|
||||
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
|
||||
** flag was specified by the caller. And so long as the db is not a
|
||||
** temporary or in-memory database. */
|
||||
const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
|
||||
&& (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY))
|
||||
);
|
||||
|
||||
assert( pPager->eState>=PAGER_READER );
|
||||
assert( assert_pager_state(pPager) );
|
||||
assert( noContent==0 || bMmapOk==0 );
|
||||
|
||||
if( pgno==0 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
@@ -5052,6 +5235,39 @@ int sqlite3PagerAcquire(
|
||||
if( pPager->errCode!=SQLITE_OK ){
|
||||
rc = pPager->errCode;
|
||||
}else{
|
||||
|
||||
if( bMmapOk && pagerUseWal(pPager) ){
|
||||
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
|
||||
if( rc!=SQLITE_OK ) goto pager_acquire_err;
|
||||
}
|
||||
|
||||
if( iFrame==0 && bMmapOk ){
|
||||
void *pData = 0;
|
||||
|
||||
rc = sqlite3OsFetch(pPager->fd,
|
||||
(i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
|
||||
);
|
||||
|
||||
if( rc==SQLITE_OK && pData ){
|
||||
if( pPager->eState>PAGER_READER ){
|
||||
(void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
|
||||
}
|
||||
if( pPg==0 ){
|
||||
rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
|
||||
}else{
|
||||
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
|
||||
}
|
||||
if( pPg ){
|
||||
assert( rc==SQLITE_OK );
|
||||
*ppPage = pPg;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto pager_acquire_err;
|
||||
}
|
||||
}
|
||||
|
||||
rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
|
||||
}
|
||||
|
||||
@@ -5110,9 +5326,13 @@ int sqlite3PagerAcquire(
|
||||
memset(pPg->pData, 0, pPager->pageSize);
|
||||
IOTRACE(("ZERO %p %d\n", pPager, pgno));
|
||||
}else{
|
||||
if( pagerUseWal(pPager) && bMmapOk==0 ){
|
||||
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
|
||||
if( rc!=SQLITE_OK ) goto pager_acquire_err;
|
||||
}
|
||||
assert( pPg->pPager==pPager );
|
||||
pPager->aStat[PAGER_STAT_MISS]++;
|
||||
rc = readDbPage(pPg);
|
||||
rc = readDbPage(pPg, iFrame);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto pager_acquire_err;
|
||||
}
|
||||
@@ -5165,7 +5385,11 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
|
||||
void sqlite3PagerUnref(DbPage *pPg){
|
||||
if( pPg ){
|
||||
Pager *pPager = pPg->pPager;
|
||||
sqlite3PcacheRelease(pPg);
|
||||
if( pPg->flags & PGHDR_MMAP ){
|
||||
pagerReleaseMapPage(pPg);
|
||||
}else{
|
||||
sqlite3PcacheRelease(pPg);
|
||||
}
|
||||
pagerUnlockIfUnused(pPager);
|
||||
}
|
||||
}
|
||||
@@ -5500,6 +5724,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
||||
Pager *pPager = pPg->pPager;
|
||||
Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
|
||||
|
||||
assert( (pPg->flags & PGHDR_MMAP)==0 );
|
||||
assert( pPager->eState>=PAGER_WRITER_LOCKED );
|
||||
assert( pPager->eState!=PAGER_ERROR );
|
||||
assert( assert_pager_state(pPager) );
|
||||
@@ -5885,36 +6110,6 @@ int sqlite3PagerCommitPhaseOne(
|
||||
#endif
|
||||
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
|
||||
|
||||
/* If this transaction has made the database smaller, then all pages
|
||||
** being discarded by the truncation must be written to the journal
|
||||
** file.
|
||||
**
|
||||
** Before reading the pages with page numbers larger than the
|
||||
** current value of Pager.dbSize, set dbSize back to the value
|
||||
** that it took at the start of the transaction. Otherwise, the
|
||||
** calls to sqlite3PagerGet() return zeroed pages instead of
|
||||
** reading data from the database file.
|
||||
*/
|
||||
if( pPager->dbSize<pPager->dbOrigSize
|
||||
&& pPager->journalMode!=PAGER_JOURNALMODE_OFF
|
||||
){
|
||||
Pgno i; /* Iterator variable */
|
||||
const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
|
||||
const Pgno dbSize = pPager->dbSize; /* Database image size */
|
||||
pPager->dbSize = pPager->dbOrigSize;
|
||||
for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
|
||||
if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
|
||||
PgHdr *pPage; /* Page to journal */
|
||||
rc = sqlite3PagerGet(pPager, i, &pPage);
|
||||
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
|
||||
rc = sqlite3PagerWrite(pPage);
|
||||
sqlite3PagerUnref(pPage);
|
||||
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
|
||||
}
|
||||
}
|
||||
pPager->dbSize = dbSize;
|
||||
}
|
||||
|
||||
/* Write the master journal name into the journal file. If a master
|
||||
** journal file name has already been written to the journal file,
|
||||
** or if zMaster is NULL (no master journal), then this call is a no-op.
|
||||
@@ -5942,11 +6137,14 @@ int sqlite3PagerCommitPhaseOne(
|
||||
goto commit_phase_one_exit;
|
||||
}
|
||||
sqlite3PcacheCleanAll(pPager->pPCache);
|
||||
|
||||
/* If the file on disk is not the same size as the database image,
|
||||
** then use pager_truncate to grow or shrink the file here.
|
||||
*/
|
||||
if( pPager->dbSize!=pPager->dbFileSize ){
|
||||
|
||||
/* If the file on disk is smaller than the database image, use
|
||||
** pager_truncate to grow the file here. This can happen if the database
|
||||
** image was extended as part of the current transaction and then the
|
||||
** last page in the db image moved to the free-list. In this case the
|
||||
** last page is never written out to disk, leaving the database file
|
||||
** undersized. Fix this now if it is the case. */
|
||||
if( pPager->dbSize>pPager->dbFileSize ){
|
||||
Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
|
||||
assert( pPager->eState==PAGER_WRITER_DBMOD );
|
||||
rc = pager_truncate(pPager, nNew);
|
||||
@@ -6019,7 +6217,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){
|
||||
}
|
||||
|
||||
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
|
||||
rc = pager_end_transaction(pPager, pPager->setMaster);
|
||||
rc = pager_end_transaction(pPager, pPager->setMaster, 1);
|
||||
return pager_error(pPager, rc);
|
||||
}
|
||||
|
||||
@@ -6064,11 +6262,11 @@ int sqlite3PagerRollback(Pager *pPager){
|
||||
if( pagerUseWal(pPager) ){
|
||||
int rc2;
|
||||
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
|
||||
rc2 = pager_end_transaction(pPager, pPager->setMaster);
|
||||
rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
}else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
|
||||
int eState = pPager->eState;
|
||||
rc = pager_end_transaction(pPager, 0);
|
||||
rc = pager_end_transaction(pPager, 0, 0);
|
||||
if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
|
||||
/* This can happen using journal_mode=off. Move the pager to the error
|
||||
** state to indicate that the contents of the cache may not be trusted.
|
||||
@@ -6083,7 +6281,7 @@ int sqlite3PagerRollback(Pager *pPager){
|
||||
}
|
||||
|
||||
assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_FULL
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
|
||||
|| rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR );
|
||||
|
||||
/* If an error occurs during a ROLLBACK, we can no longer trust the pager
|
||||
@@ -6466,7 +6664,8 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
||||
*/
|
||||
if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
|
||||
needSyncPgno = pPg->pgno;
|
||||
assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
|
||||
assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
|
||||
pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
|
||||
assert( pPg->flags&PGHDR_DIRTY );
|
||||
}
|
||||
|
||||
@@ -6816,11 +7015,12 @@ static int pagerOpenWal(Pager *pPager){
|
||||
** (e.g. due to malloc() failure), return an error code.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalOpen(pPager->pVfs,
|
||||
rc = sqlite3WalOpen(pPager->pVfs,
|
||||
pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, &pPager->pWal
|
||||
);
|
||||
}
|
||||
pagerFixMaplimit(pPager);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -6911,6 +7111,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
|
||||
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
||||
pPager->pWal = 0;
|
||||
pagerFixMaplimit(pPager);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
@@ -78,6 +78,12 @@ typedef struct PgHdr DbPage;
|
||||
#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
|
||||
#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
|
||||
|
||||
/*
|
||||
** Flags that make up the mask passed to sqlite3PagerAcquire().
|
||||
*/
|
||||
#define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */
|
||||
#define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */
|
||||
|
||||
/*
|
||||
** The remainder of this file contains the declarations of the functions
|
||||
** that make up the Pager sub-system API. See source code comments for
|
||||
@@ -102,6 +108,7 @@ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
|
||||
int sqlite3PagerSetPagesize(Pager*, u32*, int);
|
||||
int sqlite3PagerMaxPageCount(Pager*, int);
|
||||
void sqlite3PagerSetCachesize(Pager*, int);
|
||||
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
|
||||
void sqlite3PagerShrink(Pager*);
|
||||
void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
|
||||
int sqlite3PagerLockingMode(Pager *, int);
|
||||
|
||||
@@ -53,6 +53,8 @@ struct PgHdr {
|
||||
#define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */
|
||||
#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */
|
||||
|
||||
#define PGHDR_MMAP 0x040 /* This is an mmap page object */
|
||||
|
||||
/* Initialize and shutdown the page cache subsystem */
|
||||
int sqlite3PcacheInitialize(void);
|
||||
void sqlite3PcacheShutdown(void);
|
||||
|
||||
+43
-3
@@ -319,7 +319,7 @@ void sqlite3Pragma(
|
||||
int rc; /* return value form SQLITE_FCNTL_PRAGMA */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
Db *pDb; /* The specific database being pragmaed */
|
||||
Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); /* Prepared statement */
|
||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
|
||||
|
||||
if( v==0 ) return;
|
||||
sqlite3VdbeRunOnlyOnce(v);
|
||||
@@ -402,11 +402,12 @@ void sqlite3Pragma(
|
||||
static const VdbeOpList getCacheSize[] = {
|
||||
{ OP_Transaction, 0, 0, 0}, /* 0 */
|
||||
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
|
||||
{ OP_IfPos, 1, 7, 0},
|
||||
{ OP_IfPos, 1, 8, 0},
|
||||
{ OP_Integer, 0, 2, 0},
|
||||
{ OP_Subtract, 1, 2, 1},
|
||||
{ OP_IfPos, 1, 7, 0},
|
||||
{ OP_IfPos, 1, 8, 0},
|
||||
{ OP_Integer, 0, 1, 0}, /* 6 */
|
||||
{ OP_Noop, 0, 0, 0},
|
||||
{ OP_ResultRow, 1, 1, 0},
|
||||
};
|
||||
int addr;
|
||||
@@ -744,6 +745,43 @@ void sqlite3Pragma(
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]mmap_limit(N)
|
||||
**
|
||||
** Used to set mapping size limit. The mapping size limit is
|
||||
** used to limit the aggregate size of all memory mapped regions of the
|
||||
** database file. If this parameter is set to zero, then memory mapping
|
||||
** is not used at all. If N is negative, then the default memory map
|
||||
** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_LIMIT) is set.
|
||||
** The parameter N is measured in bytes.
|
||||
**
|
||||
** This value is advisory. The underlying VFS is free to memory map
|
||||
** as little or as much as it wants. Except, if N is set to 0 then the
|
||||
** upper layers will never invoke the xFetch interfaces to the VFS.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"mmap_limit")==0 ){
|
||||
sqlite3_int64 mx;
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( zRight ){
|
||||
int ii;
|
||||
sqlite3Atoi64(zRight, &mx, 1000, SQLITE_UTF8);
|
||||
if( mx<0 ) mx = sqlite3GlobalConfig.mxMmap;
|
||||
if( pId2->n==0 ) db->mxMmap = mx;
|
||||
for(ii=db->nDb-1; ii>=0; ii--){
|
||||
if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
|
||||
sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, mx);
|
||||
}
|
||||
}
|
||||
}
|
||||
mx = -1;
|
||||
if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_LIMIT,&mx)==SQLITE_OK ){
|
||||
#if defined(SQLITE_DISABLE_MMAP)
|
||||
mx = 0;
|
||||
#endif
|
||||
returnSingleInt(pParse, "mmap_limit", mx);
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA temp_store
|
||||
** PRAGMA temp_store = "default"|"memory"|"file"
|
||||
@@ -1130,6 +1168,7 @@ void sqlite3Pragma(
|
||||
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
|
||||
|
||||
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
|
||||
FKey *pFK; /* A foreign key constraint */
|
||||
Table *pTab; /* Child table contain "REFERENCES" keyword */
|
||||
@@ -1241,6 +1280,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeJumpHere(v, addrTop);
|
||||
}
|
||||
}else
|
||||
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
|
||||
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
+7
-4
@@ -179,7 +179,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
|
||||
/* zMasterSchema and zInitScript are set to point at the master schema
|
||||
** and initialisation script appropriate for the database being
|
||||
** initialised. zMasterName is the name of the master table.
|
||||
** initialized. zMasterName is the name of the master table.
|
||||
*/
|
||||
if( !OMIT_TEMPDB && iDb==1 ){
|
||||
zMasterSchema = temp_master_schema;
|
||||
@@ -259,11 +259,15 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
*/
|
||||
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
|
||||
if( iDb==0 ){
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
u8 encoding;
|
||||
/* If opening the main database, set ENC(db). */
|
||||
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
|
||||
if( encoding==0 ) encoding = SQLITE_UTF8;
|
||||
ENC(db) = encoding;
|
||||
#else
|
||||
ENC(db) = SQLITE_UTF8;
|
||||
#endif
|
||||
}else{
|
||||
/* If opening an attached database, the encoding much match ENC(db) */
|
||||
if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
|
||||
@@ -400,7 +404,7 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){
|
||||
}
|
||||
}
|
||||
|
||||
/* Once all the other databases have been initialised, load the schema
|
||||
/* Once all the other databases have been initialized, load the schema
|
||||
** for the TEMP database. This is loaded last, as the TEMP database
|
||||
** schema may contain references to objects in other databases.
|
||||
*/
|
||||
@@ -423,7 +427,7 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is a no-op if the database schema is already initialised.
|
||||
** This routine is a no-op if the database schema is already initialized.
|
||||
** Otherwise, the schema is loaded. An error code is returned.
|
||||
*/
|
||||
int sqlite3ReadSchema(Parse *pParse){
|
||||
@@ -650,7 +654,6 @@ static int sqlite3Prepare(
|
||||
}
|
||||
#endif
|
||||
|
||||
assert( db->init.busy==0 || saveSqlFlag==0 );
|
||||
if( db->init.busy==0 ){
|
||||
Vdbe *pVdbe = pParse->pVdbe;
|
||||
sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
|
||||
|
||||
+2
-2
@@ -165,12 +165,12 @@ int sqlite3MatchSpanName(
|
||||
){
|
||||
int n;
|
||||
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
|
||||
if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
|
||||
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
|
||||
return 0;
|
||||
}
|
||||
zSpan += n+1;
|
||||
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
|
||||
if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
|
||||
if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){
|
||||
return 0;
|
||||
}
|
||||
zSpan += n+1;
|
||||
|
||||
+1
-1
@@ -4570,7 +4570,7 @@ int sqlite3Select(
|
||||
** value of x, the only row required).
|
||||
**
|
||||
** A special flag must be passed to sqlite3WhereBegin() to slightly
|
||||
** modify behaviour as follows:
|
||||
** modify behavior as follows:
|
||||
**
|
||||
** + If the query is a "SELECT min(x)", then the loop coded by
|
||||
** where.c should not iterate over any values with a NULL value
|
||||
|
||||
+45
-8
@@ -1552,6 +1552,43 @@ static int booleanValue(char *zArg){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Interpret zArg as an integer value, possibly with suffixes.
|
||||
*/
|
||||
static sqlite3_int64 integerValue(const char *zArg){
|
||||
sqlite3_int64 v = 0;
|
||||
static const struct { char *zSuffix; int iMult; } aMult[] = {
|
||||
{ "KiB", 1024 },
|
||||
{ "MiB", 1024*1024 },
|
||||
{ "GiB", 1024*1024*1024 },
|
||||
{ "KB", 1000 },
|
||||
{ "MB", 1000000 },
|
||||
{ "GB", 1000000000 },
|
||||
{ "K", 1000 },
|
||||
{ "M", 1000000 },
|
||||
{ "G", 1000000000 },
|
||||
};
|
||||
int i;
|
||||
int isNeg = 0;
|
||||
if( zArg[0]=='-' ){
|
||||
isNeg = 1;
|
||||
zArg++;
|
||||
}else if( zArg[0]=='+' ){
|
||||
zArg++;
|
||||
}
|
||||
while( isdigit(zArg[0]) ){
|
||||
v = v*10 + zArg[0] - '0';
|
||||
zArg++;
|
||||
}
|
||||
for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
|
||||
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
|
||||
v *= aMult[i].iMult;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isNeg? -v : v;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close an output file, assuming it is not stderr or stdout
|
||||
*/
|
||||
@@ -2469,7 +2506,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
/* sqlite3_test_control(int, uint) */
|
||||
case SQLITE_TESTCTRL_PENDING_BYTE:
|
||||
if( nArg==3 ){
|
||||
unsigned int opt = (unsigned int)atoi(azArg[2]);
|
||||
unsigned int opt = (unsigned int)integerValue(azArg[2]);
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
printf("%d (0x%08x)\n", rc, rc);
|
||||
} else {
|
||||
@@ -2561,7 +2598,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
|
||||
if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
|
||||
extern int sqlite3WhereTrace;
|
||||
sqlite3WhereTrace = atoi(azArg[1]);
|
||||
sqlite3WhereTrace = booleanValue(azArg[1]);
|
||||
}else
|
||||
#endif
|
||||
|
||||
@@ -2882,6 +2919,7 @@ static const char zOptions[] =
|
||||
" -interactive force interactive I/O\n"
|
||||
" -line set output mode to 'line'\n"
|
||||
" -list set output mode to 'list'\n"
|
||||
" -mmap N default mmap size set to N\n"
|
||||
#ifdef SQLITE_ENABLE_MULTIPLEX
|
||||
" -multiplex enable the multiplexor VFS\n"
|
||||
#endif
|
||||
@@ -3001,12 +3039,7 @@ int main(int argc, char **argv){
|
||||
sqlite3_int64 szHeap;
|
||||
|
||||
zSize = cmdline_option_value(argc, argv, ++i);
|
||||
szHeap = atoi(zSize);
|
||||
for(j=0; (c = zSize[j])!=0; j++){
|
||||
if( c=='M' ){ szHeap *= 1000000; break; }
|
||||
if( c=='K' ){ szHeap *= 1000; break; }
|
||||
if( c=='G' ){ szHeap *= 1000000000; break; }
|
||||
}
|
||||
szHeap = integerValue(zSize);
|
||||
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
|
||||
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
|
||||
#endif
|
||||
@@ -3026,6 +3059,8 @@ int main(int argc, char **argv){
|
||||
extern int sqlite3_multiple_initialize(const char*,int);
|
||||
sqlite3_multiplex_initialize(0, 1);
|
||||
#endif
|
||||
}else if( strcmp(z,"-mmap")==0 ){
|
||||
sqlite3_config(SQLITE_CONFIG_MMAP_LIMIT, integerValue(cmdline_option_value(argc,argv,++i)));
|
||||
}else if( strcmp(z,"-vfs")==0 ){
|
||||
sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
|
||||
if( pVfs ){
|
||||
@@ -3111,6 +3146,8 @@ int main(int argc, char **argv){
|
||||
stdin_is_interactive = 0;
|
||||
}else if( strcmp(z,"-heap")==0 ){
|
||||
i++;
|
||||
}else if( strcmp(z,"-mmap")==0 ){
|
||||
i++;
|
||||
}else if( strcmp(z,"-vfs")==0 ){
|
||||
i++;
|
||||
#ifdef SQLITE_ENABLE_VFSTRACE
|
||||
|
||||
+63
-9
@@ -283,7 +283,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
** [sqlite3_blob_close | close] all [BLOB handles], and
|
||||
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
|
||||
** with the [sqlite3] object prior to attempting to close the object. ^If
|
||||
** sqlite3_close() is called on a [database connection] that still has
|
||||
** sqlite3_close_v2() is called on a [database connection] that still has
|
||||
** outstanding [prepared statements], [BLOB handles], and/or
|
||||
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
|
||||
** of resources is deferred until all [prepared statements], [BLOB handles],
|
||||
@@ -420,6 +420,8 @@ int sqlite3_exec(
|
||||
#define SQLITE_FORMAT 24 /* Auxiliary database format error */
|
||||
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
|
||||
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
|
||||
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
|
||||
#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
|
||||
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
|
||||
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
|
||||
/* end-of-error-codes */
|
||||
@@ -470,6 +472,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
|
||||
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
|
||||
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
|
||||
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
|
||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
||||
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
|
||||
@@ -478,6 +481,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
||||
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
|
||||
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
|
||||
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
|
||||
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
|
||||
@@ -488,6 +492,8 @@ int sqlite3_exec(
|
||||
#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
|
||||
#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
|
||||
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
@@ -727,6 +733,9 @@ struct sqlite3_io_methods {
|
||||
void (*xShmBarrier)(sqlite3_file*);
|
||||
int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
|
||||
/* Methods above are valid for version 2 */
|
||||
int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
|
||||
int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
|
||||
/* Methods above are valid for version 3 */
|
||||
/* Additional methods may be added in future releases */
|
||||
};
|
||||
|
||||
@@ -863,7 +872,8 @@ struct sqlite3_io_methods {
|
||||
** it is able to override built-in [PRAGMA] statements.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
|
||||
** ^This file-control may be invoked by SQLite on the database file handle
|
||||
** ^The [SQLITE_FCNTL_BUSYHANDLER]
|
||||
** file-control may be invoked by SQLite on the database file handle
|
||||
** shortly after it is opened in order to provide a custom VFS with access
|
||||
** to the connections busy-handler callback. The argument is of type (void **)
|
||||
** - an array of two (void *) values. The first (void *) actually points
|
||||
@@ -874,13 +884,24 @@ struct sqlite3_io_methods {
|
||||
** current operation.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
|
||||
** ^Application can invoke this file-control to have SQLite generate a
|
||||
** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
|
||||
** to have SQLite generate a
|
||||
** temporary filename using the same algorithm that is followed to generate
|
||||
** temporary filenames for TEMP tables and other internal uses. The
|
||||
** argument should be a char** which will be filled with the filename
|
||||
** written into memory obtained from [sqlite3_malloc()]. The caller should
|
||||
** invoke [sqlite3_free()] on the result to avoid a memory leak.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_MMAP_LIMIT]]
|
||||
** The [SQLITE_FCNTL_MMAP_LIMIT] file control is used to query or set the
|
||||
** maximum number of bytes that will be used for memory-mapped I/O.
|
||||
** The argument is a pointer to a value of type sqlite3_int64 that
|
||||
** is an advisory maximum number of bytes in the file to memory map. The
|
||||
** pointer is overwritten with the old value. The limit is not changed if
|
||||
** the originally pointed to is negative, and so the current limit can be
|
||||
** queried by passing in a pointer to a negative number. This file-control
|
||||
** is used internally to implement [PRAGMA mmap_limit].
|
||||
**
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@@ -899,6 +920,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_PRAGMA 14
|
||||
#define SQLITE_FCNTL_BUSYHANDLER 15
|
||||
#define SQLITE_FCNTL_TEMPFILENAME 16
|
||||
#define SQLITE_FCNTL_MMAP_LIMIT 18
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle
|
||||
@@ -1627,6 +1649,18 @@ struct sqlite3_mem_methods {
|
||||
** points to has just been executed. Or, if the fourth parameter is 2, then
|
||||
** the connection being passed as the second parameter is being closed. The
|
||||
** third parameter is passed NULL In this case.
|
||||
**
|
||||
** [[SQLITE_CONFIG_MMAP_LIMIT]]
|
||||
** <dt>SQLITE_CONFIG_MMAP_LIMIT
|
||||
** <dd>The sole argument should be a 64-bit integer (an sqlite3_int64) that
|
||||
** is the default maximum number of bytes of process address space that
|
||||
** should be used for accessing each database file using memory mapping.
|
||||
** The default setting can be overridden by each database connection using
|
||||
** either the [PRAGMA mmap_limit] command, or by using the
|
||||
** [SQLITE_FCNTL_MMAP_LIMIT] file control. The value set here overrides the
|
||||
** compile-time default that is set using [SQLITE_DEFAULT_MMAP_LIMIT].
|
||||
** If the argument to this option is negative, then
|
||||
** the memory map limit is set to the compile-time default.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
||||
@@ -1650,6 +1684,7 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
|
||||
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
|
||||
#define SQLITE_CONFIG_MMAP_LIMIT 22 /* sqlite3_int64 */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Database Connection Configuration Options
|
||||
@@ -2674,7 +2709,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
||||
** sqlite3_open_v2(). ^Setting the cache parameter to "private" is
|
||||
** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
|
||||
** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
|
||||
** a URI filename, its value overrides any behaviour requested by setting
|
||||
** a URI filename, its value overrides any behavior requested by setting
|
||||
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
|
||||
** </ul>
|
||||
**
|
||||
@@ -3992,7 +4027,8 @@ SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
|
||||
SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
|
||||
SQLITE_DEPRECATED int sqlite3_global_recover(void);
|
||||
SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
|
||||
SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
|
||||
SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
|
||||
void*,sqlite3_int64);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -4072,14 +4108,17 @@ int sqlite3_value_numeric_type(sqlite3_value*);
|
||||
** In those cases, sqlite3_aggregate_context() might be called for the
|
||||
** first time from within xFinal().)^
|
||||
**
|
||||
** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is
|
||||
** less than or equal to zero or if a memory allocate error occurs.
|
||||
** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer
|
||||
** when first called if N is less than or equal to zero or if a memory
|
||||
** allocate error occurs.
|
||||
**
|
||||
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
|
||||
** determined by the N parameter on first successful call. Changing the
|
||||
** value of N in subsequent call to sqlite3_aggregate_context() within
|
||||
** the same aggregate function instance will not resize the memory
|
||||
** allocation.)^
|
||||
** allocation.)^ Within the xFinal callback, it is customary to set
|
||||
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
|
||||
** pointless memory allocations occur.
|
||||
**
|
||||
** ^SQLite automatically frees the memory allocated by
|
||||
** sqlite3_aggregate_context() when the aggregate query concludes.
|
||||
@@ -6373,7 +6412,7 @@ struct sqlite3_pcache_page {
|
||||
** parameter to help it determined what action to take:
|
||||
**
|
||||
** <table border=1 width=85% align=center>
|
||||
** <tr><th> createFlag <th> Behaviour when page is not already in cache
|
||||
** <tr><th> createFlag <th> Behavior when page is not already in cache
|
||||
** <tr><td> 0 <td> Do not allocate a new page. Return NULL.
|
||||
** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
|
||||
** Otherwise return NULL.
|
||||
@@ -6802,6 +6841,21 @@ int sqlite3_unlock_notify(
|
||||
int sqlite3_stricmp(const char *, const char *);
|
||||
int sqlite3_strnicmp(const char *, const char *, int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: String Globbing
|
||||
*
|
||||
** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
|
||||
** the glob pattern P, and it returns non-zero if string X does not match
|
||||
** the glob pattern P. ^The definition of glob pattern matching used in
|
||||
** [sqlite3_strglob(P,X) is the same as for the "X GLOB P" operator in the
|
||||
** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case
|
||||
** sensitive.
|
||||
**
|
||||
** Note that this routine returns zero on a match and non-zero if the strings
|
||||
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
|
||||
*/
|
||||
int sqlite3_strglob(const char *zGlob, const char *zStr);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Error Logging Interface
|
||||
**
|
||||
|
||||
+16
-1
@@ -66,6 +66,10 @@
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
|
||||
# define _BSD_SOURCE
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Include standard header files as necessary
|
||||
*/
|
||||
@@ -535,6 +539,14 @@ extern const int sqlite3one;
|
||||
# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Disable MMAP on platforms where it is not supported
|
||||
*/
|
||||
#if defined(__OpenBSD__) || defined(__QNXNTO__)
|
||||
# undef SQLITE_DISABLE_MMAP
|
||||
# define SQLITE_DISABLE_MMAP 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** An instance of the following structure is used to store the busy-handler
|
||||
@@ -830,6 +842,7 @@ struct sqlite3 {
|
||||
int nDb; /* Number of backends currently in use */
|
||||
int flags; /* Miscellaneous flags. See below */
|
||||
i64 lastRowid; /* ROWID of most recent insert (see above) */
|
||||
i64 mxMmap; /* Default mmap_limit setting */
|
||||
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
|
||||
int errCode; /* Most recent error code (SQLITE_*) */
|
||||
int errMask; /* & result codes with this before returning */
|
||||
@@ -2501,6 +2514,7 @@ struct Sqlite3Config {
|
||||
void *pHeap; /* Heap storage space */
|
||||
int nHeap; /* Size of pHeap[] */
|
||||
int mnReq, mxReq; /* Min and max heap requests sizes */
|
||||
sqlite3_int64 mxMmap; /* Maximum mmap() space per open file */
|
||||
void *pScratch; /* Scratch memory */
|
||||
int szScratch; /* Size of each scratch buffer */
|
||||
int nScratch; /* Number of scratch buffers */
|
||||
@@ -3259,7 +3273,8 @@ const char *sqlite3JournalModename(int);
|
||||
|
||||
#define IN_INDEX_ROWID 1
|
||||
#define IN_INDEX_EPH 2
|
||||
#define IN_INDEX_INDEX 3
|
||||
#define IN_INDEX_INDEX_ASC 3
|
||||
#define IN_INDEX_INDEX_DESC 4
|
||||
int sqlite3FindInIndex(Parse *, Expr *, int*);
|
||||
|
||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
||||
|
||||
@@ -206,3 +206,27 @@
|
||||
#ifndef SQLITE_MAX_TRIGGER_DEPTH
|
||||
# define SQLITE_MAX_TRIGGER_DEPTH 1000
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Default maximum size of memory used by xFetch in the VFS.
|
||||
*/
|
||||
#ifdef SQLITE_DISABLE_MMAP
|
||||
# undef SQLITE_DEFAULT_MMAP_LIMIT
|
||||
# define SQLITE_DEFAULT_MMAP_LIMIT 0
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <TargetConditionals.h>
|
||||
# if TARGET_OS_IPHONE
|
||||
# define SQLITE_DEFAULT_MMAP_LIMIT 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef SQLITE_DEFAULT_MMAP_LIMIT
|
||||
# if defined(__linux__) \
|
||||
|| defined(_WIN32) \
|
||||
|| (defined(__APPLE__) && defined(__MACH__)) \
|
||||
|| defined(__sun)
|
||||
# define SQLITE_DEFAULT_MMAP_LIMIT 268435456 /* = 256*1024*1024 */
|
||||
# else
|
||||
# define SQLITE_DEFAULT_MMAP_LIMIT 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -1005,7 +1005,7 @@ static int DbTransPostCmd(
|
||||
/* This is a tricky scenario to handle. The most likely cause of an
|
||||
** error is that the exec() above was an attempt to commit the
|
||||
** top-level transaction that returned SQLITE_BUSY. Or, less likely,
|
||||
** that an IO-error has occured. In either case, throw a Tcl exception
|
||||
** that an IO-error has occurred. In either case, throw a Tcl exception
|
||||
** and try to rollback the transaction.
|
||||
**
|
||||
** But it could also be that the user executed one or more BEGIN,
|
||||
|
||||
+97
-63
@@ -116,70 +116,76 @@ int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
|
||||
|
||||
const char *sqlite3TestErrorName(int rc){
|
||||
const char *zName = 0;
|
||||
switch( rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
|
||||
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
|
||||
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
|
||||
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
|
||||
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
|
||||
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
|
||||
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
|
||||
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
|
||||
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
|
||||
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
|
||||
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
|
||||
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
|
||||
case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
|
||||
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
|
||||
case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
|
||||
case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
|
||||
case SQLITE_CONSTRAINT_FOREIGNKEY:
|
||||
zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
|
||||
case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break;
|
||||
case SQLITE_CONSTRAINT_PRIMARYKEY:
|
||||
zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
|
||||
case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break;
|
||||
case SQLITE_CONSTRAINT_COMMITHOOK:
|
||||
zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
|
||||
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
|
||||
case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
|
||||
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
|
||||
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
|
||||
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
|
||||
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
|
||||
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
|
||||
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
|
||||
case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
|
||||
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
|
||||
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
|
||||
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
|
||||
case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break;
|
||||
case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break;
|
||||
case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break;
|
||||
case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break;
|
||||
case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break;
|
||||
case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break;
|
||||
case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
|
||||
case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
|
||||
case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
|
||||
case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break;
|
||||
case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
|
||||
case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
|
||||
case SQLITE_IOERR_CHECKRESERVEDLOCK:
|
||||
zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
|
||||
case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break;
|
||||
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
|
||||
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
|
||||
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
|
||||
default: zName = "SQLITE_Unknown"; break;
|
||||
int i;
|
||||
for(i=0; i<2 && zName==0; i++, rc &= 0xff){
|
||||
switch( rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
|
||||
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
|
||||
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
|
||||
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
|
||||
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
|
||||
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
|
||||
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
|
||||
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
|
||||
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
|
||||
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
|
||||
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
|
||||
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
|
||||
case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
|
||||
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
|
||||
case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
|
||||
case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
|
||||
case SQLITE_CONSTRAINT_FOREIGNKEY:
|
||||
zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
|
||||
case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break;
|
||||
case SQLITE_CONSTRAINT_PRIMARYKEY:
|
||||
zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
|
||||
case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break;
|
||||
case SQLITE_CONSTRAINT_COMMITHOOK:
|
||||
zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
|
||||
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
|
||||
case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
|
||||
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
|
||||
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
|
||||
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
|
||||
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
|
||||
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
|
||||
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
|
||||
case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
|
||||
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
|
||||
case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break;
|
||||
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
|
||||
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
|
||||
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
|
||||
case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break;
|
||||
case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break;
|
||||
case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break;
|
||||
case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break;
|
||||
case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break;
|
||||
case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break;
|
||||
case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
|
||||
case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
|
||||
case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
|
||||
case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break;
|
||||
case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
|
||||
case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
|
||||
case SQLITE_IOERR_CHECKRESERVEDLOCK:
|
||||
zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
|
||||
case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break;
|
||||
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
|
||||
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
|
||||
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
|
||||
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
|
||||
}
|
||||
}
|
||||
if( zName==0 ) zName = "SQLITE_Unknown";
|
||||
return zName;
|
||||
}
|
||||
#define t1ErrorName sqlite3TestErrorName
|
||||
@@ -5843,6 +5849,31 @@ static int test_test_control(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#if SQLITE_OS_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
static int test_getrusage(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
char buf[1024];
|
||||
struct rusage r;
|
||||
memset(&r, 0, sizeof(r));
|
||||
getrusage(RUSAGE_SELF, &r);
|
||||
|
||||
sprintf(buf, "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
|
||||
(int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec,
|
||||
(int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec,
|
||||
(int)r.ru_minflt, (int)r.ru_majflt
|
||||
);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WIN
|
||||
/*
|
||||
** Information passed from the main thread into the windows file locker
|
||||
@@ -6232,6 +6263,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "print_explain_query_plan", test_print_eqp, 0 },
|
||||
#endif
|
||||
{ "sqlite3_test_control", test_test_control },
|
||||
#if SQLITE_OS_UNIX
|
||||
{ "getrusage", test_getrusage },
|
||||
#endif
|
||||
};
|
||||
static int bitmask_size = sizeof(Bitmask)*8;
|
||||
int i;
|
||||
|
||||
+13
-41
@@ -19,35 +19,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** Interpret an SQLite error number
|
||||
*/
|
||||
static char *errorName(int rc){
|
||||
char *zName;
|
||||
switch( rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
|
||||
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
|
||||
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
|
||||
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
|
||||
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
|
||||
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
|
||||
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
|
||||
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
|
||||
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
|
||||
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
|
||||
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
|
||||
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
|
||||
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
|
||||
default: zName = "SQLITE_Unknown"; break;
|
||||
}
|
||||
return zName;
|
||||
}
|
||||
extern const char *sqlite3TestErrorName(int rc);
|
||||
|
||||
/*
|
||||
** Page size and reserved size used for testing.
|
||||
@@ -87,7 +59,7 @@ static int pager_open(
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,
|
||||
pager_test_reiniter);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3PagerSetCachesize(pPager, nPage);
|
||||
@@ -119,7 +91,7 @@ static int pager_close(
|
||||
pPager = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerClose(pPager);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -146,7 +118,7 @@ static int pager_rollback(
|
||||
pPager = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerRollback(pPager);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -173,12 +145,12 @@ static int pager_commit(
|
||||
pPager = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3PagerCommitPhaseTwo(pPager);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -205,7 +177,7 @@ static int pager_stmt_begin(
|
||||
pPager = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerOpenSavepoint(pPager, 1);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -233,7 +205,7 @@ static int pager_stmt_rollback(
|
||||
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, 0);
|
||||
sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -260,7 +232,7 @@ static int pager_stmt_commit(
|
||||
pPager = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -353,7 +325,7 @@ static int page_get(
|
||||
rc = sqlite3PagerGet(pPager, pgno, &pPage);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
|
||||
@@ -507,7 +479,7 @@ static int page_write(
|
||||
pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerWrite(pPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pData = sqlite3PagerGetData(pPage);
|
||||
@@ -556,7 +528,7 @@ static int fake_big_file(
|
||||
(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
|
||||
);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, "open failed: ", sqlite3TestErrorName(rc), 0);
|
||||
sqlite3_free(zFile);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -566,7 +538,7 @@ static int fake_big_file(
|
||||
sqlite3OsCloseFree(fd);
|
||||
sqlite3_free(zFile);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, "write failed: ", sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
|
||||
+8
-32
@@ -19,31 +19,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** Interpret an SQLite error number
|
||||
*/
|
||||
static char *errorName(int rc){
|
||||
char *zName;
|
||||
switch( rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
|
||||
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
|
||||
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
|
||||
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
|
||||
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
|
||||
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
|
||||
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
|
||||
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
|
||||
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
|
||||
default: zName = "SQLITE_Unknown"; break;
|
||||
}
|
||||
return zName;
|
||||
}
|
||||
extern const char *sqlite3TestErrorName(int rc);
|
||||
|
||||
/*
|
||||
** A bogus sqlite3 connection structure for use in the btree
|
||||
@@ -89,7 +65,7 @@ static int btree_open(
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
|
||||
sqlite3_free(zFilename);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3BtreeSetCacheSize(pBt, nCache);
|
||||
@@ -119,7 +95,7 @@ static int btree_close(
|
||||
pBt = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3BtreeClose(pBt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
nRefSqlite3--;
|
||||
@@ -156,7 +132,7 @@ static int btree_begin_transaction(
|
||||
rc = sqlite3BtreeBeginTrans(pBt, 1);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -250,7 +226,7 @@ static int btree_cursor(
|
||||
sqlite3BtreeLeave(pBt);
|
||||
if( rc ){
|
||||
ckfree((char *)pCur);
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
|
||||
@@ -285,7 +261,7 @@ static int btree_close_cursor(
|
||||
sqlite3BtreeLeave(pBt);
|
||||
ckfree((char *)pCur);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
@@ -319,7 +295,7 @@ static int btree_next(
|
||||
rc = sqlite3BtreeNext(pCur, &res);
|
||||
sqlite3BtreeLeave(pCur->pBtree);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
|
||||
@@ -354,7 +330,7 @@ static int btree_first(
|
||||
rc = sqlite3BtreeFirst(pCur, &res);
|
||||
sqlite3BtreeLeave(pCur->pBtree);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
|
||||
|
||||
+3
-28
@@ -20,6 +20,8 @@
|
||||
#include <sched.h>
|
||||
#include <ctype.h>
|
||||
|
||||
extern const char *sqlite3TestErrorName(int rc);
|
||||
|
||||
/*
|
||||
** Each thread is controlled by an instance of the following
|
||||
** structure.
|
||||
@@ -372,34 +374,7 @@ static int tcl_thread_result(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
thread_wait(&threadset[i]);
|
||||
switch( threadset[i].rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
|
||||
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
|
||||
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
|
||||
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
|
||||
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
|
||||
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
|
||||
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
|
||||
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
|
||||
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
|
||||
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
|
||||
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
|
||||
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
|
||||
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
|
||||
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
|
||||
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
|
||||
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
|
||||
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
|
||||
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
|
||||
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
|
||||
default: zName = "SQLITE_Unknown"; break;
|
||||
}
|
||||
zName = sqlite3TestErrorName(threadset[i].rc);
|
||||
Tcl_AppendResult(interp, zName, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ typedef struct WriteBuffer WriteBuffer;
|
||||
** an aligned write() of an integer number of 512 byte regions, then
|
||||
** option (3) above is never selected. Instead, each 512 byte region
|
||||
** is either correctly written or left completely untouched. Similar
|
||||
** logic governs the behaviour if any of the other ATOMICXXX flags
|
||||
** logic governs the behavior if any of the other ATOMICXXX flags
|
||||
** is set.
|
||||
**
|
||||
** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set
|
||||
|
||||
+3
-28
@@ -376,6 +376,8 @@ static int tcl_client_colname(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
extern const char *sqlite3TestErrorName(int rc);
|
||||
|
||||
/*
|
||||
** Usage: client_result ID
|
||||
**
|
||||
@@ -403,34 +405,7 @@ static int tcl_client_result(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
client_wait(&threadset[i]);
|
||||
switch( threadset[i].rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
|
||||
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
|
||||
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
|
||||
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
|
||||
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
|
||||
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
|
||||
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
|
||||
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
|
||||
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
|
||||
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
|
||||
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
|
||||
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
|
||||
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
|
||||
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
|
||||
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
|
||||
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
|
||||
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
|
||||
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
|
||||
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
|
||||
default: zName = "SQLITE_Unknown"; break;
|
||||
}
|
||||
zName = sqlite3TestErrorName(threadset[i].rc);
|
||||
Tcl_AppendResult(interp, zName, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+7
-5
@@ -87,6 +87,12 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DISABLE_MMAP
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mmap", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mmap", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if 1 /* def SQLITE_MEMDEBUG */
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -395,11 +401,7 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
|
||||
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
|
||||
Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ static int fsConnect(
|
||||
}
|
||||
zTbl = argv[3];
|
||||
|
||||
nByte = sizeof(fs_vtab) + strlen(zTbl) + 1 + strlen(zDb) + 1;
|
||||
nByte = sizeof(fs_vtab) + (int)strlen(zTbl) + 1 + (int)strlen(zDb) + 1;
|
||||
pVtab = (fs_vtab *)sqlite3MallocZero( nByte );
|
||||
if( !pVtab ) return SQLITE_NOMEM;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
/*
|
||||
** These should be defined to be the same as the values in
|
||||
** sqliteInt.h. They are defined seperately here so that
|
||||
** sqliteInt.h. They are defined separately here so that
|
||||
** the multiplex VFS shim can be built as a loadable
|
||||
** module.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -1295,7 +1295,7 @@ int sqlite3_quota_remove(const char *zFilename){
|
||||
if( pGroup ){
|
||||
for(pFile=pGroup->pFiles; pFile && rc==SQLITE_OK; pFile=pNextFile){
|
||||
pNextFile = pFile->pNext;
|
||||
diff = memcmp(zFull, pFile->zFilename, nFull);
|
||||
diff = strncmp(zFull, pFile->zFilename, nFull);
|
||||
if( diff==0 && ((c = pFile->zFilename[nFull])==0 || c=='/' || c=='\\') ){
|
||||
if( pFile->nRef ){
|
||||
pFile->deleteOnClose = 1;
|
||||
|
||||
+5
-4
@@ -107,7 +107,7 @@ struct ReCompiled {
|
||||
char *aOp; /* Operators for the virtual machine */
|
||||
int *aArg; /* Arguments to each operator */
|
||||
unsigned (*xNextChar)(ReInput*); /* Next character function */
|
||||
char zInit[12]; /* Initial text to match */
|
||||
unsigned char zInit[12]; /* Initial text to match */
|
||||
int nInit; /* Number of characters in zInit */
|
||||
unsigned nState; /* Number of entries in aOp[] and aArg[] */
|
||||
unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
|
||||
@@ -188,13 +188,14 @@ int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
|
||||
|
||||
in.z = zIn;
|
||||
in.i = 0;
|
||||
in.mx = nIn>=0 ? nIn : strlen((char const*)zIn);
|
||||
in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);
|
||||
|
||||
/* Look for the initial prefix match, if there is one. */
|
||||
if( pRe->nInit ){
|
||||
unsigned char x = pRe->zInit[0];
|
||||
while( in.i+pRe->nInit<=in.mx
|
||||
&& (zIn[in.i]!=x || memcmp(zIn+in.i, pRe->zInit, pRe->nInit)!=0)
|
||||
&& (zIn[in.i]!=x ||
|
||||
strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
|
||||
){
|
||||
in.i++;
|
||||
}
|
||||
@@ -627,7 +628,7 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
|
||||
}
|
||||
pRe->sIn.z = (unsigned char*)zIn;
|
||||
pRe->sIn.i = 0;
|
||||
pRe->sIn.mx = strlen(zIn);
|
||||
pRe->sIn.mx = (int)strlen(zIn);
|
||||
zErr = re_subcompile_re(pRe);
|
||||
if( zErr ){
|
||||
re_free(pRe);
|
||||
|
||||
+6
-6
@@ -744,22 +744,22 @@ static int utf8Len(unsigned char c, int N){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE (non-zero) of the To side of the given cost matches
|
||||
** Return TRUE (non-zero) if the To side of the given cost matches
|
||||
** the given string.
|
||||
*/
|
||||
static int matchTo(EditDist3Cost *p, const char *z, int n){
|
||||
if( p->nTo>n ) return 0;
|
||||
if( memcmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0;
|
||||
if( strncmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE (non-zero) of the To side of the given cost matches
|
||||
** Return TRUE (non-zero) if the From side of the given cost matches
|
||||
** the given string.
|
||||
*/
|
||||
static int matchFrom(EditDist3Cost *p, const char *z, int n){
|
||||
assert( p->nFrom<=n );
|
||||
if( memcmp(p->a, z, p->nFrom)!=0 ) return 0;
|
||||
if( strncmp(p->a, z, p->nFrom)!=0 ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1952,7 +1952,7 @@ static int spellfix1Init(
|
||||
);
|
||||
}
|
||||
for(i=3; rc==SQLITE_OK && i<argc; i++){
|
||||
if( memcmp(argv[i],"edit_cost_table=",16)==0 && pNew->zCostTable==0 ){
|
||||
if( strncmp(argv[i],"edit_cost_table=",16)==0 && pNew->zCostTable==0 ){
|
||||
pNew->zCostTable = spellfix1Dequote(&argv[i][16]);
|
||||
if( pNew->zCostTable==0 ) rc = SQLITE_NOMEM;
|
||||
continue;
|
||||
@@ -2681,7 +2681,7 @@ static int spellfix1Update(
|
||||
p->pConfig3 = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( memcmp(zCmd,"edit_cost_table=",16)==0 ){
|
||||
if( strncmp(zCmd,"edit_cost_table=",16)==0 ){
|
||||
editDist3ConfigDelete(p->pConfig3);
|
||||
p->pConfig3 = 0;
|
||||
sqlite3_free(p->zCostTable);
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
**
|
||||
** Usually, if the application opens the same database file more than once
|
||||
** (either by attaching it or by using more than one database handle), only
|
||||
** a single copy is made. This behaviour may be overridden (so that a
|
||||
** a single copy is made. This behavior may be overridden (so that a
|
||||
** separate copy is taken each time the database file is opened or attached)
|
||||
** by setting the environment variable SQLITE_SQLLOG_REUSE_FILES to 0.
|
||||
**
|
||||
|
||||
+33
-2
@@ -23,7 +23,7 @@
|
||||
**
|
||||
** open close access getcwd stat fstat
|
||||
** ftruncate fcntl read pread pread64 write
|
||||
** pwrite pwrite64 fchmod fallocate
|
||||
** pwrite pwrite64 fchmod fallocate mmap
|
||||
**
|
||||
** test_syscall uninstall
|
||||
** Uninstall all wrapper functions.
|
||||
@@ -81,6 +81,7 @@
|
||||
/* From test1.c */
|
||||
extern const char *sqlite3TestErrorName(int);
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -106,7 +107,8 @@ static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off);
|
||||
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off);
|
||||
static int ts_fchmod(int fd, mode_t mode);
|
||||
static int ts_fallocate(int fd, off_t off, off_t len);
|
||||
|
||||
static void *ts_mmap(void *, size_t, int, int, int, off_t);
|
||||
static void *ts_mremap(void*, size_t, size_t, int, ...);
|
||||
|
||||
struct TestSyscallArray {
|
||||
const char *zName;
|
||||
@@ -131,6 +133,8 @@ struct TestSyscallArray {
|
||||
/* 13 */ { "pwrite64", (sqlite3_syscall_ptr)ts_pwrite64, 0, 0, 0 },
|
||||
/* 14 */ { "fchmod", (sqlite3_syscall_ptr)ts_fchmod, 0, 0, 0 },
|
||||
/* 15 */ { "fallocate", (sqlite3_syscall_ptr)ts_fallocate, 0, 0, 0 },
|
||||
/* 16 */ { "mmap", (sqlite3_syscall_ptr)ts_mmap, 0, 0, 0 },
|
||||
/* 17 */ { "mremap", (sqlite3_syscall_ptr)ts_mremap, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -152,6 +156,8 @@ struct TestSyscallArray {
|
||||
aSyscall[13].xOrig)
|
||||
#define orig_fchmod ((int(*)(int,mode_t))aSyscall[14].xOrig)
|
||||
#define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig)
|
||||
#define orig_mmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[16].xOrig)
|
||||
#define orig_mremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[17].xOrig)
|
||||
|
||||
/*
|
||||
** This function is called exactly once from within each invocation of a
|
||||
@@ -377,6 +383,31 @@ static int ts_fallocate(int fd, off_t off, off_t len){
|
||||
return orig_fallocate(fd, off, len);
|
||||
}
|
||||
|
||||
static void *ts_mmap(
|
||||
void *pAddr,
|
||||
size_t nByte,
|
||||
int prot,
|
||||
int flags,
|
||||
int fd,
|
||||
off_t iOff
|
||||
){
|
||||
if( tsIsFailErrno("mmap") ){
|
||||
return MAP_FAILED;
|
||||
}
|
||||
return orig_mmap(pAddr, nByte, prot, flags, fd, iOff);
|
||||
}
|
||||
|
||||
static void *ts_mremap(void *a, size_t b, size_t c, int d, ...){
|
||||
va_list ap;
|
||||
void *pArg;
|
||||
if( tsIsFailErrno("mremap") ){
|
||||
return MAP_FAILED;
|
||||
}
|
||||
va_start(ap, d);
|
||||
pArg = va_arg(ap, void *);
|
||||
return orig_mremap(a, b, c, d, pArg);
|
||||
}
|
||||
|
||||
static int test_syscall_install(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
|
||||
+26
-18
@@ -125,8 +125,9 @@ struct Testvfs {
|
||||
#define TESTVFS_ACCESS_MASK 0x00004000
|
||||
#define TESTVFS_FULLPATHNAME_MASK 0x00008000
|
||||
#define TESTVFS_READ_MASK 0x00010000
|
||||
#define TESTVFS_UNLOCK_MASK 0x00020000
|
||||
|
||||
#define TESTVFS_ALL_MASK 0x0001FFFF
|
||||
#define TESTVFS_ALL_MASK 0x0003FFFF
|
||||
|
||||
|
||||
#define TESTVFS_MAX_PAGES 1024
|
||||
@@ -265,7 +266,8 @@ static void tvfsExecTcl(
|
||||
const char *zMethod,
|
||||
Tcl_Obj *arg1,
|
||||
Tcl_Obj *arg2,
|
||||
Tcl_Obj *arg3
|
||||
Tcl_Obj *arg3,
|
||||
Tcl_Obj *arg4
|
||||
){
|
||||
int rc; /* Return code from Tcl_EvalObj() */
|
||||
Tcl_Obj *pEval;
|
||||
@@ -282,6 +284,7 @@ static void tvfsExecTcl(
|
||||
if( arg1 ) Tcl_ListObjAppendElement(p->interp, pEval, arg1);
|
||||
if( arg2 ) Tcl_ListObjAppendElement(p->interp, pEval, arg2);
|
||||
if( arg3 ) Tcl_ListObjAppendElement(p->interp, pEval, arg3);
|
||||
if( arg4 ) Tcl_ListObjAppendElement(p->interp, pEval, arg4);
|
||||
|
||||
rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
|
||||
if( rc!=TCL_OK ){
|
||||
@@ -302,7 +305,7 @@ static int tvfsClose(sqlite3_file *pFile){
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_CLOSE_MASK ){
|
||||
tvfsExecTcl(p, "xClose",
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -333,7 +336,7 @@ static int tvfsRead(
|
||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||
if( p->pScript && p->mask&TESTVFS_READ_MASK ){
|
||||
tvfsExecTcl(p, "xRead",
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -362,7 +365,7 @@ static int tvfsWrite(
|
||||
if( p->pScript && p->mask&TESTVFS_WRITE_MASK ){
|
||||
tvfsExecTcl(p, "xWrite",
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId,
|
||||
Tcl_NewWideIntObj(iOfst)
|
||||
Tcl_NewWideIntObj(iOfst), Tcl_NewIntObj(iAmt)
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -390,7 +393,7 @@ static int tvfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_TRUNCATE_MASK ){
|
||||
tvfsExecTcl(p, "xTruncate",
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -431,7 +434,7 @@ static int tvfsSync(sqlite3_file *pFile, int flags){
|
||||
|
||||
tvfsExecTcl(p, "xSync",
|
||||
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId,
|
||||
Tcl_NewStringObj(zFlags, -1)
|
||||
Tcl_NewStringObj(zFlags, -1), 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -465,8 +468,12 @@ static int tvfsLock(sqlite3_file *pFile, int eLock){
|
||||
** Unlock an tvfs-file.
|
||||
*/
|
||||
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
|
||||
TestvfsFd *p = tvfsGetFd(pFile);
|
||||
return sqlite3OsUnlock(p->pReal, eLock);
|
||||
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||
if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
|
||||
return SQLITE_IOERR_UNLOCK;
|
||||
}
|
||||
return sqlite3OsUnlock(pFd->pReal, eLock);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -578,7 +585,7 @@ static int tvfsOpen(
|
||||
z += strlen(z) + 1;
|
||||
}
|
||||
}
|
||||
tvfsExecTcl(p, "xOpen", Tcl_NewStringObj(pFd->zFilename, -1), pArg, 0);
|
||||
tvfsExecTcl(p, "xOpen", Tcl_NewStringObj(pFd->zFilename, -1), pArg, 0, 0);
|
||||
Tcl_DecrRefCount(pArg);
|
||||
if( tvfsResultCode(p, &rc) ){
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
@@ -635,7 +642,7 @@ static int tvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_DELETE_MASK ){
|
||||
tvfsExecTcl(p, "xDelete",
|
||||
Tcl_NewStringObj(zPath, -1), Tcl_NewIntObj(dirSync), 0
|
||||
Tcl_NewStringObj(zPath, -1), Tcl_NewIntObj(dirSync), 0, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -663,7 +670,7 @@ static int tvfsAccess(
|
||||
if( flags==SQLITE_ACCESS_READWRITE ) zArg = "SQLITE_ACCESS_READWRITE";
|
||||
if( flags==SQLITE_ACCESS_READ ) zArg = "SQLITE_ACCESS_READ";
|
||||
tvfsExecTcl(p, "xAccess",
|
||||
Tcl_NewStringObj(zPath, -1), Tcl_NewStringObj(zArg, -1), 0
|
||||
Tcl_NewStringObj(zPath, -1), Tcl_NewStringObj(zArg, -1), 0, 0
|
||||
);
|
||||
if( tvfsResultCode(p, &rc) ){
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
@@ -691,7 +698,7 @@ static int tvfsFullPathname(
|
||||
Testvfs *p = (Testvfs *)pVfs->pAppData;
|
||||
if( p->pScript && p->mask&TESTVFS_FULLPATHNAME_MASK ){
|
||||
int rc;
|
||||
tvfsExecTcl(p, "xFullPathname", Tcl_NewStringObj(zPath, -1), 0, 0);
|
||||
tvfsExecTcl(p, "xFullPathname", Tcl_NewStringObj(zPath, -1), 0, 0, 0);
|
||||
if( tvfsResultCode(p, &rc) ){
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
@@ -771,7 +778,7 @@ static int tvfsShmOpen(sqlite3_file *pFile){
|
||||
*/
|
||||
Tcl_ResetResult(p->interp);
|
||||
if( p->pScript && p->mask&TESTVFS_SHMOPEN_MASK ){
|
||||
tvfsExecTcl(p, "xShmOpen", Tcl_NewStringObj(pFd->zFilename, -1), 0, 0);
|
||||
tvfsExecTcl(p, "xShmOpen", Tcl_NewStringObj(pFd->zFilename, -1), 0, 0, 0);
|
||||
if( tvfsResultCode(p, &rc) ){
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
@@ -841,7 +848,7 @@ static int tvfsShmMap(
|
||||
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(pgsz));
|
||||
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(isWrite));
|
||||
tvfsExecTcl(p, "xShmMap",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, pArg
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, pArg, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
Tcl_DecrRefCount(pArg);
|
||||
@@ -891,7 +898,7 @@ static int tvfsShmLock(
|
||||
}
|
||||
tvfsExecTcl(p, "xShmLock",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId,
|
||||
Tcl_NewStringObj(zLock, -1)
|
||||
Tcl_NewStringObj(zLock, -1), 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -937,7 +944,7 @@ static void tvfsShmBarrier(sqlite3_file *pFile){
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){
|
||||
tvfsExecTcl(p, "xShmBarrier",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0, 0
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -961,7 +968,7 @@ static int tvfsShmUnmap(
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_SHMCLOSE_MASK ){
|
||||
tvfsExecTcl(p, "xShmUnmap",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
@@ -1099,6 +1106,7 @@ static int testvfs_obj_cmd(
|
||||
{ "xClose", TESTVFS_CLOSE_MASK },
|
||||
{ "xAccess", TESTVFS_ACCESS_MASK },
|
||||
{ "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
|
||||
{ "xUnlock", TESTVFS_UNLOCK_MASK },
|
||||
};
|
||||
Tcl_Obj **apElem = 0;
|
||||
int nElem = 0;
|
||||
|
||||
+1
-1
@@ -458,7 +458,7 @@ void sqlite3Update(
|
||||
|
||||
/* The row-trigger may have deleted the row being updated. In this
|
||||
** case, jump to the next row. No updates or AFTER triggers are
|
||||
** required. This behaviour - what happens when the row being updated
|
||||
** required. This behavior - what happens when the row being updated
|
||||
** is deleted or renamed by a BEFORE trigger - is left undefined in the
|
||||
** documentation.
|
||||
*/
|
||||
|
||||
+31
-7
@@ -261,7 +261,7 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
|
||||
*/
|
||||
int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
int incr = (enc==SQLITE_UTF8?1:2);
|
||||
int incr;
|
||||
const char *zEnd = z + length;
|
||||
/* sign * significand * (10 ^ (esign * exponent)) */
|
||||
int sign = 1; /* sign of significand */
|
||||
@@ -272,10 +272,22 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
int eValid = 1; /* True exponent is either not used or is well-formed */
|
||||
double result;
|
||||
int nDigits = 0;
|
||||
int nonNum = 0;
|
||||
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
*pResult = 0.0; /* Default return value, in case of an error */
|
||||
|
||||
if( enc==SQLITE_UTF16BE ) z++;
|
||||
if( enc==SQLITE_UTF8 ){
|
||||
incr = 1;
|
||||
}else{
|
||||
int i;
|
||||
incr = 2;
|
||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
for(i=3-enc; i<length && z[i]==0; i+=2){}
|
||||
nonNum = i<length;
|
||||
zEnd = z+i+enc-3;
|
||||
z += (enc&1);
|
||||
}
|
||||
|
||||
/* skip leading spaces */
|
||||
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
||||
@@ -408,7 +420,7 @@ do_atof_calc:
|
||||
*pResult = result;
|
||||
|
||||
/* return true if number and no extra non-whitespace chracters after */
|
||||
return z>=zEnd && nDigits>0 && eValid;
|
||||
return z>=zEnd && nDigits>0 && eValid && nonNum==0;
|
||||
#else
|
||||
return !sqlite3Atoi64(z, pResult, length, enc);
|
||||
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
||||
@@ -457,21 +469,33 @@ static int compare2pow63(const char *zNum, int incr){
|
||||
** signed 64-bit integer, its negative -9223372036854665808 can be.
|
||||
**
|
||||
** If zNum is too big for a 64-bit integer and is not
|
||||
** 9223372036854665808 then return 1.
|
||||
** 9223372036854665808 or if zNum contains any non-numeric text,
|
||||
** then return 1.
|
||||
**
|
||||
** length is the number of bytes in the string (bytes, not characters).
|
||||
** The string is not necessarily zero-terminated. The encoding is
|
||||
** given by enc.
|
||||
*/
|
||||
int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||
int incr = (enc==SQLITE_UTF8?1:2);
|
||||
int incr;
|
||||
u64 u = 0;
|
||||
int neg = 0; /* assume positive */
|
||||
int i;
|
||||
int c = 0;
|
||||
int nonNum = 0;
|
||||
const char *zStart;
|
||||
const char *zEnd = zNum + length;
|
||||
if( enc==SQLITE_UTF16BE ) zNum++;
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
if( enc==SQLITE_UTF8 ){
|
||||
incr = 1;
|
||||
}else{
|
||||
incr = 2;
|
||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
|
||||
nonNum = i<length;
|
||||
zEnd = zNum+i+enc-3;
|
||||
zNum += (enc&1);
|
||||
}
|
||||
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
||||
if( zNum<zEnd ){
|
||||
if( *zNum=='-' ){
|
||||
@@ -496,7 +520,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||
testcase( i==18 );
|
||||
testcase( i==19 );
|
||||
testcase( i==20 );
|
||||
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
|
||||
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr || nonNum ){
|
||||
/* zNum is empty or contains non-numeric text or is longer
|
||||
** than 19 digits (thus guaranteeing that it is too large) */
|
||||
return 1;
|
||||
|
||||
+2
-25
@@ -152,11 +152,7 @@ int sqlite3_found_count = 0;
|
||||
&& sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
|
||||
|
||||
/* Return true if the cursor was opened using the OP_OpenSorter opcode. */
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
# define isSorter(x) 0
|
||||
#else
|
||||
# define isSorter(x) ((x)->pSorter!=0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Argument pMem points at a register that will be passed to a
|
||||
@@ -3321,17 +3317,12 @@ case OP_OpenEphemeral: {
|
||||
case OP_SorterOpen: {
|
||||
VdbeCursor *pCx;
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
|
||||
if( pCx==0 ) goto no_mem;
|
||||
pCx->pKeyInfo = pOp->p4.pKeyInfo;
|
||||
pCx->pKeyInfo->enc = ENC(p->db);
|
||||
pCx->isSorter = 1;
|
||||
rc = sqlite3VdbeSorterInit(db, pCx);
|
||||
#else
|
||||
pOp->opcode = OP_OpenEphemeral;
|
||||
pc--;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3524,7 +3515,7 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
** r.flags = 0;
|
||||
** }
|
||||
*/
|
||||
r.flags = (u16)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
|
||||
r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
|
||||
assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY );
|
||||
assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY );
|
||||
assert( oc!=OP_SeekGe || r.flags==0 );
|
||||
@@ -4214,15 +4205,10 @@ case OP_SorterCompare: {
|
||||
case OP_SorterData: {
|
||||
VdbeCursor *pC;
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
pOut = &aMem[pOp->p2];
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC->isSorter );
|
||||
rc = sqlite3VdbeSorterRowkey(pC, pOut);
|
||||
#else
|
||||
pOp->opcode = OP_RowKey;
|
||||
pc--;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4421,9 +4407,6 @@ case OP_Last: { /* jump */
|
||||
** correctly optimizing out sorts.
|
||||
*/
|
||||
case OP_SorterSort: /* jump */
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
pOp->opcode = OP_Sort;
|
||||
#endif
|
||||
case OP_Sort: { /* jump */
|
||||
#ifdef SQLITE_TEST
|
||||
sqlite3_sort_count++;
|
||||
@@ -4502,9 +4485,6 @@ case OP_Rewind: { /* jump */
|
||||
** number P5-1 in the prepared statement is incremented.
|
||||
*/
|
||||
case OP_SorterNext: /* jump */
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
pOp->opcode = OP_Next;
|
||||
#endif
|
||||
case OP_Prev: /* jump */
|
||||
case OP_Next: { /* jump */
|
||||
VdbeCursor *pC;
|
||||
@@ -4555,9 +4535,6 @@ case OP_Next: { /* jump */
|
||||
** for tables is OP_Insert.
|
||||
*/
|
||||
case OP_SorterInsert: /* in2 */
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
pOp->opcode = OP_IdxInsert;
|
||||
#endif
|
||||
case OP_IdxInsert: { /* in2 */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
@@ -5784,7 +5761,7 @@ case OP_VOpen: {
|
||||
/* Initialize sqlite3_vtab_cursor base class */
|
||||
pVtabCursor->pVtab = pVtab;
|
||||
|
||||
/* Initialise vdbe cursor object */
|
||||
/* Initialize vdbe cursor object */
|
||||
pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
|
||||
if( pCur ){
|
||||
pCur->pVtabCursor = pVtabCursor;
|
||||
|
||||
+8
-10
@@ -18,6 +18,14 @@
|
||||
#ifndef _VDBEINT_H_
|
||||
#define _VDBEINT_H_
|
||||
|
||||
/*
|
||||
** The maximum number of times that a statement will try to reparse
|
||||
** itself before giving up and returning SQLITE_SCHEMA.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_SCHEMA_RETRY
|
||||
# define SQLITE_MAX_SCHEMA_RETRY 50
|
||||
#endif
|
||||
|
||||
/*
|
||||
** SQL is translated into a sequence of instructions to be
|
||||
** executed by a virtual machine. Each instruction is an instance
|
||||
@@ -429,15 +437,6 @@ int sqlite3VdbeFrameRestore(VdbeFrame *);
|
||||
void sqlite3VdbeMemStoreType(Mem *pMem);
|
||||
int sqlite3VdbeTransferError(Vdbe *p);
|
||||
|
||||
#ifdef SQLITE_OMIT_MERGE_SORT
|
||||
# define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK
|
||||
# define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK
|
||||
# define sqlite3VdbeSorterClose(Y,Z)
|
||||
# define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK
|
||||
# define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK
|
||||
# define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK
|
||||
# define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK
|
||||
#else
|
||||
int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
|
||||
void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
|
||||
int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
|
||||
@@ -445,7 +444,6 @@ int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
|
||||
int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
|
||||
int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
|
||||
int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
||||
void sqlite3VdbeEnter(Vdbe*);
|
||||
|
||||
+2
-10
@@ -445,7 +445,7 @@ end_of_step:
|
||||
assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
|
||||
if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
|
||||
/* If this statement was prepared using sqlite3_prepare_v2(), and an
|
||||
** error has occured, then return the error code in p->rc to the
|
||||
** error has occurred, then return the error code in p->rc to the
|
||||
** caller. Set the error code in the database handle to the same value.
|
||||
*/
|
||||
rc = sqlite3VdbeTransferError(p);
|
||||
@@ -453,14 +453,6 @@ end_of_step:
|
||||
return (rc&db->errMask);
|
||||
}
|
||||
|
||||
/*
|
||||
** The maximum number of times that a statement will try to reparse
|
||||
** itself before giving up and returning SQLITE_SCHEMA.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_SCHEMA_RETRY
|
||||
# define SQLITE_MAX_SCHEMA_RETRY 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This is the top-level implementation of sqlite3_step(). Call
|
||||
** sqlite3Step() to do most of the work. If a schema error occurs,
|
||||
@@ -1198,7 +1190,7 @@ int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
|
||||
if( zName ){
|
||||
for(i=0; i<p->nzVar; i++){
|
||||
const char *z = p->azVar[i];
|
||||
if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
|
||||
if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -375,7 +375,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
}
|
||||
sqlite3DbFree(v->db, sIter.apSub);
|
||||
|
||||
/* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
|
||||
/* Return true if hasAbort==mayAbort. Or if a malloc failure occurred.
|
||||
** If malloc failed, then the while() loop above may not have iterated
|
||||
** through all opcodes and hasAbort may be set incorrectly. Return
|
||||
** true for this case to prevent the assert() in the callers frame
|
||||
@@ -2007,7 +2007,7 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
|
||||
|
||||
/* If p->iStatement is greater than zero, then this Vdbe opened a
|
||||
** statement transaction that should be closed here. The only exception
|
||||
** is that an IO error may have occured, causing an emergency rollback.
|
||||
** is that an IO error may have occurred, causing an emergency rollback.
|
||||
** In this case (db->nStatement==0), and there is nothing to do.
|
||||
*/
|
||||
if( db->nStatement && p->iStatement ){
|
||||
@@ -2143,7 +2143,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
**
|
||||
** Even if the statement is read-only, it is important to perform
|
||||
** a statement or transaction rollback operation. If the error
|
||||
** occured while writing to the journal, sub-journal or database
|
||||
** occurred while writing to the journal, sub-journal or database
|
||||
** file as part of an effort to free up cache space (see function
|
||||
** pagerStress() in pager.c), the rollback is required to restore
|
||||
** the pager to a consistent state.
|
||||
@@ -2557,7 +2557,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
|
||||
** the blob of data that it corresponds to. In a table record, all serial
|
||||
** types are stored at the start of the record, and the blobs of data at
|
||||
** the end. Hence these functions allow the caller to handle the
|
||||
** serial-type and data blob seperately.
|
||||
** serial-type and data blob separately.
|
||||
**
|
||||
** The following table describes the various storage classes for data:
|
||||
**
|
||||
|
||||
+1
-1
@@ -313,7 +313,7 @@ int sqlite3_blob_open(
|
||||
}
|
||||
sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
|
||||
rc = blobSeekToRow(pBlob, iRow, &zErr);
|
||||
} while( (++nAttempt)<5 && rc==SQLITE_SCHEMA );
|
||||
} while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
|
||||
|
||||
blob_open_out:
|
||||
if( rc==SQLITE_OK && db->mallocFailed==0 ){
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
** between formats.
|
||||
*/
|
||||
int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
int rc;
|
||||
#endif
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|
||||
|| desiredEnc==SQLITE_UTF16BE );
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "sqliteInt.h"
|
||||
#include "vdbeInt.h"
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
|
||||
typedef struct VdbeSorterIter VdbeSorterIter;
|
||||
typedef struct SorterRecord SorterRecord;
|
||||
@@ -1037,5 +1036,3 @@ int sqlite3VdbeSorterCompare(
|
||||
vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#endif /* #ifndef SQLITE_OMIT_MERGE_SORT */
|
||||
|
||||
+32
-8
@@ -53,6 +53,11 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
|
||||
** then the returned string holds a copy of zRawSql with "-- " prepended
|
||||
** to each line of text.
|
||||
**
|
||||
** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then
|
||||
** then long strings and blobs are truncated to that many bytes. This
|
||||
** can be used to prevent unreasonably large trace strings when dealing
|
||||
** with large (multi-megabyte) strings and blobs.
|
||||
**
|
||||
** The calling function is responsible for making sure the memory returned
|
||||
** is eventually freed.
|
||||
**
|
||||
@@ -123,30 +128,49 @@ char *sqlite3VdbeExpandSql(
|
||||
}else if( pVar->flags & MEM_Real ){
|
||||
sqlite3XPrintf(&out, "%!.15g", pVar->r);
|
||||
}else if( pVar->flags & MEM_Str ){
|
||||
int n; /* Number of bytes of the string text to include in output */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
u8 enc = ENC(db);
|
||||
Mem utf8;
|
||||
if( enc!=SQLITE_UTF8 ){
|
||||
Mem utf8;
|
||||
memset(&utf8, 0, sizeof(utf8));
|
||||
utf8.db = db;
|
||||
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
|
||||
sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
|
||||
sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
|
||||
sqlite3VdbeMemRelease(&utf8);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
|
||||
pVar = &utf8;
|
||||
}
|
||||
#endif
|
||||
n = pVar->n;
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( n>SQLITE_TRACE_SIZE_LIMIT ){
|
||||
n = SQLITE_TRACE_SIZE_LIMIT;
|
||||
while( n<pVar->n && (pVar->z[n]&0xc0)==0x80 ){ n++; }
|
||||
}
|
||||
#endif
|
||||
sqlite3XPrintf(&out, "'%.*q'", n, pVar->z);
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( n<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n);
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
|
||||
#endif
|
||||
}else if( pVar->flags & MEM_Zero ){
|
||||
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
|
||||
}else{
|
||||
int n; /* Number of bytes of the blob to include in output */
|
||||
assert( pVar->flags & MEM_Blob );
|
||||
sqlite3StrAccumAppend(&out, "x'", 2);
|
||||
for(i=0; i<pVar->n; i++){
|
||||
n = pVar->n;
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( n>SQLITE_TRACE_SIZE_LIMIT ) n = SQLITE_TRACE_SIZE_LIMIT;
|
||||
#endif
|
||||
for(i=0; i<n; i++){
|
||||
sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
|
||||
}
|
||||
sqlite3StrAccumAppend(&out, "'", 1);
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( n<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1207,8 +1207,9 @@ finished:
|
||||
** checkpointing the log file.
|
||||
*/
|
||||
if( pWal->hdr.nPage ){
|
||||
sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
|
||||
pWal->hdr.nPage, pWal->zWalName
|
||||
sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
|
||||
"recovered %d frames from WAL file %s",
|
||||
pWal->hdr.mxFrame, pWal->zWalName
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1722,8 +1723,8 @@ static int walCheckpoint(
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
|
||||
/* If the database file may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
/* If the database may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nReq = ((i64)mxPage * szPage);
|
||||
@@ -1733,6 +1734,7 @@ static int walCheckpoint(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Iterate through the contents of the WAL, copying data to the db file. */
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
@@ -2287,19 +2289,17 @@ void sqlite3WalEndReadTransaction(Wal *pWal){
|
||||
}
|
||||
|
||||
/*
|
||||
** Read a page from the WAL, if it is present in the WAL and if the
|
||||
** current read transaction is configured to use the WAL.
|
||||
** Search the wal file for page pgno. If found, set *piRead to the frame that
|
||||
** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
|
||||
** to zero.
|
||||
**
|
||||
** The *pInWal is set to 1 if the requested page is in the WAL and
|
||||
** has been loaded. Or *pInWal is set to 0 if the page was not in
|
||||
** the WAL and needs to be read out of the database.
|
||||
** Return SQLITE_OK if successful, or an error code if an error occurs. If an
|
||||
** error does occur, the final value of *piRead is undefined.
|
||||
*/
|
||||
int sqlite3WalRead(
|
||||
int sqlite3WalFindFrame(
|
||||
Wal *pWal, /* WAL handle */
|
||||
Pgno pgno, /* Database page number to read data for */
|
||||
int *pInWal, /* OUT: True if data is read from WAL */
|
||||
int nOut, /* Size of buffer pOut in bytes */
|
||||
u8 *pOut /* Buffer to write page data to */
|
||||
u32 *piRead /* OUT: Frame number (or zero) */
|
||||
){
|
||||
u32 iRead = 0; /* If !=0, WAL frame to return data from */
|
||||
u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */
|
||||
@@ -2315,7 +2315,7 @@ int sqlite3WalRead(
|
||||
** WAL were empty.
|
||||
*/
|
||||
if( iLast==0 || pWal->readLock==0 ){
|
||||
*pInWal = 0;
|
||||
*piRead = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -2386,26 +2386,31 @@ int sqlite3WalRead(
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If iRead is non-zero, then it is the log frame number that contains the
|
||||
** required page. Read and return data from the log file.
|
||||
*/
|
||||
if( iRead ){
|
||||
int sz;
|
||||
i64 iOffset;
|
||||
sz = pWal->hdr.szPage;
|
||||
sz = (sz&0xfe00) + ((sz&0x0001)<<16);
|
||||
testcase( sz<=32768 );
|
||||
testcase( sz>=65536 );
|
||||
iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
|
||||
*pInWal = 1;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
|
||||
return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
|
||||
}
|
||||
|
||||
*pInWal = 0;
|
||||
*piRead = iRead;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the contents of frame iRead from the wal file into buffer pOut
|
||||
** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
|
||||
** error code otherwise.
|
||||
*/
|
||||
int sqlite3WalReadFrame(
|
||||
Wal *pWal, /* WAL handle */
|
||||
u32 iRead, /* Frame to read */
|
||||
int nOut, /* Size of buffer pOut in bytes */
|
||||
u8 *pOut /* Buffer to write page data to */
|
||||
){
|
||||
int sz;
|
||||
i64 iOffset;
|
||||
sz = pWal->hdr.szPage;
|
||||
sz = (sz&0xfe00) + ((sz&0x0001)<<16);
|
||||
testcase( sz<=32768 );
|
||||
testcase( sz>=65536 );
|
||||
iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
|
||||
return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the size of the database in pages (or zero, if unknown).
|
||||
@@ -2952,6 +2957,9 @@ int sqlite3WalCheckpoint(
|
||||
/* Read the wal-index header. */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = walIndexReadHdr(pWal, &isChanged);
|
||||
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
|
||||
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy data from the log to the database file. */
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
# define sqlite3WalClose(w,x,y,z) 0
|
||||
# define sqlite3WalBeginReadTransaction(y,z) 0
|
||||
# define sqlite3WalEndReadTransaction(z)
|
||||
# define sqlite3WalRead(v,w,x,y,z) 0
|
||||
# define sqlite3WalDbsize(y) 0
|
||||
# define sqlite3WalBeginWriteTransaction(y) 0
|
||||
# define sqlite3WalEndWriteTransaction(x) 0
|
||||
@@ -71,7 +70,8 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
|
||||
void sqlite3WalEndReadTransaction(Wal *pWal);
|
||||
|
||||
/* Read a page from the write-ahead log, if it is present. */
|
||||
int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
|
||||
int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
|
||||
int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
|
||||
|
||||
/* If the WAL is not empty, return the size of the database. */
|
||||
Pgno sqlite3WalDbsize(Wal *pWal);
|
||||
|
||||
+65
-19
@@ -262,6 +262,8 @@ struct WhereCost {
|
||||
#define WHERE_REVERSE 0x01000000 /* Scan in reverse order */
|
||||
#define WHERE_UNIQUE 0x02000000 /* Selects no more than one row */
|
||||
#define WHERE_ALL_UNIQUE 0x04000000 /* This and all prior have one row */
|
||||
#define WHERE_OB_UNIQUE 0x00004000 /* Values in ORDER BY columns are
|
||||
** different for every output row */
|
||||
#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
|
||||
#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */
|
||||
#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */
|
||||
@@ -562,7 +564,7 @@ static int allowedOp(int op){
|
||||
** Commute a comparison operator. Expressions of the form "X op Y"
|
||||
** are converted into "Y op X".
|
||||
**
|
||||
** If left/right precendence rules come into play when determining the
|
||||
** If left/right precedence rules come into play when determining the
|
||||
** collating
|
||||
** side of the comparison, it remains associated with the same side after
|
||||
** the commutation. So "Y collate NOCASE op X" becomes
|
||||
@@ -643,9 +645,8 @@ static u16 operatorMask(int op){
|
||||
** then try for the one with no dependencies on <expr> - in other words where
|
||||
** <expr> is a constant expression of some kind. Only return entries of
|
||||
** the form "X <op> Y" where Y is a column in another table if no terms of
|
||||
** the form "X <op> <const-expr>" exist. Other than this priority, if there
|
||||
** are two or more terms that match, then the choice of which term to return
|
||||
** is arbitrary.
|
||||
** the form "X <op> <const-expr>" exist. If no terms with a constant RHS
|
||||
** exist, try to return a term that does not use WO_EQUIV.
|
||||
*/
|
||||
static WhereTerm *findTerm(
|
||||
WhereClause *pWC, /* The WHERE clause to be searched */
|
||||
@@ -704,8 +705,12 @@ static WhereTerm *findTerm(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pResult = pTerm;
|
||||
if( pTerm->prereqRight==0 ) goto findTerm_success;
|
||||
if( pTerm->prereqRight==0 ){
|
||||
pResult = pTerm;
|
||||
goto findTerm_success;
|
||||
}else if( pResult==0 ){
|
||||
pResult = pTerm;
|
||||
}
|
||||
}
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
&& nEquiv<ArraySize(aEquiv)
|
||||
@@ -2900,7 +2905,8 @@ static int isSortingIndex(
|
||||
WhereBestIdx *p, /* Best index search context */
|
||||
Index *pIdx, /* The index we are testing */
|
||||
int base, /* Cursor number for the table to be sorted */
|
||||
int *pbRev /* Set to 1 for reverse-order scan of pIdx */
|
||||
int *pbRev, /* Set to 1 for reverse-order scan of pIdx */
|
||||
int *pbObUnique /* ORDER BY column values will different in every row */
|
||||
){
|
||||
int i; /* Number of pIdx terms used */
|
||||
int j; /* Number of ORDER BY terms satisfied */
|
||||
@@ -2914,12 +2920,16 @@ static int isSortingIndex(
|
||||
int nPriorSat; /* ORDER BY terms satisfied by outer loops */
|
||||
int seenRowid = 0; /* True if an ORDER BY rowid term is seen */
|
||||
int uniqueNotNull; /* pIdx is UNIQUE with all terms are NOT NULL */
|
||||
int outerObUnique; /* Outer loops generate different values in
|
||||
** every row for the ORDER BY columns */
|
||||
|
||||
if( p->i==0 ){
|
||||
nPriorSat = 0;
|
||||
outerObUnique = 1;
|
||||
}else{
|
||||
u32 wsFlags = p->aLevel[p->i-1].plan.wsFlags;
|
||||
nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
|
||||
if( (p->aLevel[p->i-1].plan.wsFlags & WHERE_ORDERED)==0 ){
|
||||
if( (wsFlags & WHERE_ORDERED)==0 ){
|
||||
/* This loop cannot be ordered unless the next outer loop is
|
||||
** also ordered */
|
||||
return nPriorSat;
|
||||
@@ -2929,6 +2939,9 @@ static int isSortingIndex(
|
||||
** optimization is disabled */
|
||||
return nPriorSat;
|
||||
}
|
||||
testcase( wsFlags & WHERE_OB_UNIQUE );
|
||||
testcase( wsFlags & WHERE_ALL_UNIQUE );
|
||||
outerObUnique = (wsFlags & (WHERE_OB_UNIQUE|WHERE_ALL_UNIQUE))!=0;
|
||||
}
|
||||
pOrderBy = p->pOrderBy;
|
||||
assert( pOrderBy!=0 );
|
||||
@@ -3070,11 +3083,26 @@ static int isSortingIndex(
|
||||
uniqueNotNull = 0;
|
||||
}
|
||||
}
|
||||
if( seenRowid ){
|
||||
uniqueNotNull = 1;
|
||||
}else if( uniqueNotNull==0 || i<pIdx->nColumn ){
|
||||
uniqueNotNull = 0;
|
||||
}
|
||||
|
||||
/* If we have not found at least one ORDER BY term that matches the
|
||||
** index, then show no progress. */
|
||||
if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat;
|
||||
|
||||
/* Either the outer queries must generate rows where there are no two
|
||||
** rows with the same values in all ORDER BY columns, or else this
|
||||
** loop must generate just a single row of output. Example: Suppose
|
||||
** the outer loops generate A=1 and A=1, and this loop generates B=3
|
||||
** and B=4. Then without the following test, ORDER BY A,B would
|
||||
** generate the wrong order output: 1,3 1,4 1,3 1,4
|
||||
*/
|
||||
if( outerObUnique==0 && uniqueNotNull==0 ) return nPriorSat;
|
||||
*pbObUnique = uniqueNotNull;
|
||||
|
||||
/* Return the necessary scan order back to the caller */
|
||||
*pbRev = sortOrder & 1;
|
||||
|
||||
@@ -3082,7 +3110,7 @@ static int isSortingIndex(
|
||||
** possible for a single row from this table to match, then skip over
|
||||
** any additional ORDER BY terms dealing with this table.
|
||||
*/
|
||||
if( seenRowid || (uniqueNotNull && i>=pIdx->nColumn) ){
|
||||
if( uniqueNotNull ){
|
||||
/* Advance j over additional ORDER BY terms associated with base */
|
||||
WhereMaskSet *pMS = p->pWC->pMaskSet;
|
||||
Bitmask m = ~getMask(pMS, base);
|
||||
@@ -3366,12 +3394,14 @@ static void bestBtreeIndex(WhereBestIdx *p){
|
||||
** variable. */
|
||||
if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
|
||||
int bRev = 2;
|
||||
WHERETRACE((" --> before isSortingIndex: nPriorSat=%d\n",nPriorSat));
|
||||
pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
|
||||
WHERETRACE((" --> after isSortingIndex: bRev=%d nOBSat=%d\n",
|
||||
bRev, pc.plan.nOBSat));
|
||||
int bObUnique = 0;
|
||||
WHERETRACE((" --> before isSortIndex: nPriorSat=%d\n",nPriorSat));
|
||||
pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev, &bObUnique);
|
||||
WHERETRACE((" --> after isSortIndex: bRev=%d bObU=%d nOBSat=%d\n",
|
||||
bRev, bObUnique, pc.plan.nOBSat));
|
||||
if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
|
||||
pc.plan.wsFlags |= WHERE_ORDERED;
|
||||
if( bObUnique ) pc.plan.wsFlags |= WHERE_OB_UNIQUE;
|
||||
}
|
||||
if( nOrderBy==pc.plan.nOBSat ){
|
||||
bSort = 0;
|
||||
@@ -3465,7 +3495,8 @@ static void bestBtreeIndex(WhereBestIdx *p){
|
||||
** So this computation assumes table records are about twice as big
|
||||
** as index records
|
||||
*/
|
||||
if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED))==WHERE_IDX_ONLY
|
||||
if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED|WHERE_OB_UNIQUE))
|
||||
==WHERE_IDX_ONLY
|
||||
&& (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
|
||||
&& sqlite3GlobalConfig.bUseCis
|
||||
&& OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
|
||||
@@ -3625,7 +3656,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
|
||||
/* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
|
||||
** is set, then reverse the order that the index will be scanned
|
||||
** in. This is used for application testing, to help find cases
|
||||
** where application behaviour depends on the (undefined) order that
|
||||
** where application behavior depends on the (undefined) order that
|
||||
** SQLite outputs rows in in the absence of an ORDER BY clause. */
|
||||
if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
|
||||
p->cost.plan.wsFlags |= WHERE_REVERSE;
|
||||
@@ -3772,7 +3803,8 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
|
||||
static int codeEqualityTerm(
|
||||
Parse *pParse, /* The parsing context */
|
||||
WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
|
||||
WhereLevel *pLevel, /* When level of the FROM clause we are working on */
|
||||
WhereLevel *pLevel, /* The level of the FROM clause we are working on */
|
||||
int iEq, /* Index of the equality term within this level */
|
||||
int iTarget /* Attempt to leave results in this register */
|
||||
){
|
||||
Expr *pX = pTerm->pExpr;
|
||||
@@ -3792,9 +3824,22 @@ static int codeEqualityTerm(
|
||||
struct InLoop *pIn;
|
||||
u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
|
||||
|
||||
if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0
|
||||
&& pLevel->plan.u.pIdx->aSortOrder[iEq]
|
||||
){
|
||||
testcase( iEq==0 );
|
||||
testcase( iEq==pLevel->plan.u.pIdx->nColumn-1 );
|
||||
testcase( iEq>0 && iEq+1<pLevel->plan.u.pIdx->nColumn );
|
||||
testcase( bRev );
|
||||
bRev = !bRev;
|
||||
}
|
||||
assert( pX->op==TK_IN );
|
||||
iReg = iTarget;
|
||||
eType = sqlite3FindInIndex(pParse, pX, 0);
|
||||
if( eType==IN_INDEX_INDEX_DESC ){
|
||||
testcase( bRev );
|
||||
bRev = !bRev;
|
||||
}
|
||||
iTab = pX->iTable;
|
||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
|
||||
assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
|
||||
@@ -3909,7 +3954,7 @@ static int codeAllEqualityTerms(
|
||||
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
|
||||
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
|
||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
||||
r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
|
||||
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, regBase+j);
|
||||
if( r1!=regBase+j ){
|
||||
if( nReg==1 ){
|
||||
sqlite3ReleaseTempReg(pParse, regBase);
|
||||
@@ -4186,7 +4231,7 @@ static Bitmask codeOneLoopStart(
|
||||
int iTarget = iReg+j+1;
|
||||
pTerm = &pWC->a[aConstraint[k].iTermOffset];
|
||||
if( pTerm->eOperator & WO_IN ){
|
||||
codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
|
||||
codeEqualityTerm(pParse, pTerm, pLevel, k, iTarget);
|
||||
addrNotFound = pLevel->addrNxt;
|
||||
}else{
|
||||
sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
|
||||
@@ -4227,10 +4272,11 @@ static Bitmask codeOneLoopStart(
|
||||
assert( pTerm->pExpr!=0 );
|
||||
assert( omitTable==0 );
|
||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
||||
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg);
|
||||
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, iReleaseReg);
|
||||
addrNxt = pLevel->addrNxt;
|
||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
|
||||
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
|
||||
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
||||
VdbeComment((v, "pk"));
|
||||
pLevel->op = OP_Noop;
|
||||
|
||||
+6
-2
@@ -2262,7 +2262,9 @@ do_test auth-4.3 {
|
||||
SQLITE_SELECT {} {} {} v1 \
|
||||
SQLITE_READ t2 a main v1 \
|
||||
SQLITE_READ t2 b main v1 \
|
||||
SQLITE_SELECT {} {} {} {} \
|
||||
SQLITE_READ v1 x main v1 \
|
||||
SQLITE_READ v1 x main v1 \
|
||||
SQLITE_SELECT {} {} {} v1 \
|
||||
SQLITE_READ v1 x main v1 \
|
||||
SQLITE_INSERT v1chng {} main r2 \
|
||||
SQLITE_READ v1 x main r2 \
|
||||
@@ -2288,7 +2290,9 @@ do_test auth-4.5 {
|
||||
SQLITE_SELECT {} {} {} v1 \
|
||||
SQLITE_READ t2 a main v1 \
|
||||
SQLITE_READ t2 b main v1 \
|
||||
SQLITE_SELECT {} {} {} {} \
|
||||
SQLITE_READ v1 x main v1 \
|
||||
SQLITE_READ v1 x main v1 \
|
||||
SQLITE_SELECT {} {} {} v1 \
|
||||
SQLITE_READ v1 x main v1 \
|
||||
SQLITE_INSERT v1chng {} main r3 \
|
||||
SQLITE_READ v1 x main r3 \
|
||||
|
||||
@@ -115,7 +115,7 @@ proc clear_ioerr_simulation {} {
|
||||
# reported, then the backup process is concluded with a call to
|
||||
# backup_finish().
|
||||
#
|
||||
# Test that if an IO error occurs, or if one occured while updating
|
||||
# Test that if an IO error occurs, or if one occurred while updating
|
||||
# the backup database during step 4, then the conditions listed
|
||||
# under step 3 are all true.
|
||||
#
|
||||
@@ -214,7 +214,7 @@ for {set iError 1} {$bStop == 0} {incr iError} {
|
||||
set rc [catchsql { UPDATE t1 SET b = randstr(1000,1000) WHERE a < 50 } sdb]
|
||||
|
||||
if {[lindex $rc 0] && $::sqlite_io_error_persist==0} {
|
||||
# The IO error occured while updating the source database. In this
|
||||
# The IO error occurred while updating the source database. In this
|
||||
# case the backup should be able to continue.
|
||||
set rc [B step 5000]
|
||||
if { $rc != "SQLITE_IOERR_UNLOCK" } {
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# 2013 April 02
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file contains fault injection tests designed to test the btree.c
|
||||
# module.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix btreefault
|
||||
|
||||
do_test 1-pre1 {
|
||||
execsql {
|
||||
PRAGMA auto_vacuum = incremental;
|
||||
PRAGMA journal_mode = DELETE;
|
||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(randomblob(1000), randomblob(100));
|
||||
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
|
||||
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
|
||||
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
|
||||
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
|
||||
DELETE FROM t1 WHERE rowid%2;
|
||||
}
|
||||
faultsim_save_and_close
|
||||
} {}
|
||||
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY a" -1 DUMMY]
|
||||
sqlite3_step $::STMT
|
||||
sqlite3_step $::STMT
|
||||
} -body {
|
||||
execsql { PRAGMA incremental_vacuum = 10 }
|
||||
} -test {
|
||||
sqlite3_finalize $::STMT
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ do_test cache-1.2 {
|
||||
# leaked, but would not be reused until the pager-cache was full (i.e.
|
||||
# 2000 pages by default).
|
||||
#
|
||||
# This tests that once the pager-cache is initialised, it can be locked
|
||||
# This tests that once the pager-cache is initialized, it can be locked
|
||||
# and unlocked repeatedly without internally allocating any new pages.
|
||||
#
|
||||
set cache_size [pager_cache_size db]
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ proc cksort {sql} {
|
||||
#
|
||||
# Because these tests also exercise all the different ways indices
|
||||
# can be created, they also serve to verify that indices are correctly
|
||||
# initialised with user-defined collation sequences when they are
|
||||
# initialized with user-defined collation sequences when they are
|
||||
# created.
|
||||
#
|
||||
# Tests named collate4-1.1.* use indices with a single column. Tests
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ for {set ii 0} {$ii < 10} {incr ii} {
|
||||
# puts "$n $msg ac=[sqlite3_get_autocommit db]"
|
||||
|
||||
# If the transaction is still active (it may not be if the malloc()
|
||||
# failure occured in the OS layer), write to the database. Make sure
|
||||
# failure occurred in the OS layer), write to the database. Make sure
|
||||
# page 4 is among those written.
|
||||
#
|
||||
if {![sqlite3_get_autocommit db]} {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user