Compare commits

..

65 Commits

Author SHA1 Message Date
drh 35a0379a05 Change the unix VFS so that it refuses to open a database file using
a file descriptor less than 3.

FossilOrigin-Name: 66dddda06898abbf97fe0ac6a10ce1527ca8605e
2013-08-29 23:34:53 +00:00
drh 0c9a8e345e Never leave an open file descriptor pointing into the middle of the
database file if the file descriptor number is 2 or less.

FossilOrigin-Name: 3426673e4659eb68dbd14a3e41d4620d748432db
2013-08-29 21:26:26 +00:00
dan 8bff07a55f Restore fix [f15591f802], which was accidentally clobbered by the stat4 merge.
FossilOrigin-Name: d4b6ad3333cc3bad500c2ebf7a6ea552b6762b69
2013-08-29 14:56:14 +00:00
dan cd40abb297 Candidate fix for [9f2eb3abac]: Have the whereShortCut() planner ignore indexes with more than four columns.
FossilOrigin-Name: c1152bdcbb5ac185f743015fff63769effa81b4b
2013-08-29 10:46:05 +00:00
mistachkin 1d406e0dfd Small enhancements to unit testing infrastructure.
FossilOrigin-Name: 9229aeb361f9805894321327d05aba855b8799f3
2013-08-29 01:09:14 +00:00
mistachkin 8bcd3fa75a Enable finer control of optimizations when compiling with the MSVC makefile. Also, several modularity enhancements to the MSVC makefile.
FossilOrigin-Name: 6c709338bc77fbed24a2597eabd88dd8c29b38d7
2013-08-29 01:03:38 +00:00
dan 1d2b70e3d2 Re-enable test file wild001.test.
FossilOrigin-Name: 4f182ddc36944fa54f1a34c1f0527db0ebb39c96
2013-08-28 19:01:07 +00:00
drh e4f9b9b7c0 Add the win32-longpath VFS allowing windows filenames up to 32K characters in
length.  Remove unused code when -DSQLITE_MAX_MMAP_SIZE=0.  Fix some
compiler warnings on windows.

FossilOrigin-Name: 12d0a8859de0a9d823997cfeccc77bd572cb6d13
2013-08-28 18:18:12 +00:00
mistachkin fe27b08934 Update list of supported Tcl shells to include 8.6. Remove stray OS2 references.
FossilOrigin-Name: ecd52ccf650ce2a4ab93c7c482289c1bc4768eeb
2013-08-28 18:06:26 +00:00
mistachkin 3259fe7910 Fix a couple comments.
FossilOrigin-Name: 945cb89ecb92a6c2075b3e58ce1ba3d419b1b6ca
2013-08-28 17:59:38 +00:00
drh d41d39f24d In the query optimizer, when converting BETWEEN and LIKE/GLOB expressions
into simpler forms for processing, be sure to transfer the LEFT JOIN markings.
Fix for ticket [bc878246eafe0f52c].

FossilOrigin-Name: caab361ebee5f5c3fdafd9b1abe3d1ab7c5b4db9
2013-08-28 16:27:01 +00:00
drh 38e587779d Increase the version number to 3.8.1 due to the addition of STAT4 support.
FossilOrigin-Name: 41c089e2a21f52b3d6d850eccba60be17010c9fe
2013-08-28 13:46:09 +00:00
drh 868ccf2679 Fix an off-by-one error that causes a quoted empty string at the end of
a CRNL-terminated line of CSV input to be misread by the shell.

FossilOrigin-Name: b5617e4fdadc4cded93c985008e90982dd48bc3b
2013-08-28 13:33:40 +00:00
drh f7f8de5fb2 Add a test case for empty quoted field in CSV import in the shell.
FossilOrigin-Name: 3df56e849164811117f9ac8ee2aee1eee188bb96
2013-08-28 11:57:52 +00:00
drh 6d57bbfe25 Label a certain branch as NEVER() only for non-STAT3/4 builds.
FossilOrigin-Name: b5ccf6e995ac2fe010f49d46d40b487ddbd28e5a
2013-08-28 11:43:49 +00:00
mistachkin 70e9ffa3bb In the win32longpath test, move the journal mode change down where it was intended to be.
FossilOrigin-Name: 5cead293bbbcddd7d0976db41133e40704efcc99
2013-08-28 07:42:43 +00:00
mistachkin 3741827ea1 Support database file names longer than 260 characters using the new 'win32-longpath' VFS variant.
FossilOrigin-Name: 37e85e444cde18f061049437980b965d4485f43c
2013-08-28 05:49:39 +00:00
mistachkin b324bc79e9 Make names of private functions in the Win32 VFS consistent. Fix comment typo in Win32 mutex implementation.
FossilOrigin-Name: c3b82c5bf97cfb35544c5b1fbcdf7b9c4827d1cf
2013-08-28 02:37:29 +00:00
mistachkin 533fb6de5b Remove hard-coding of the directory separator in the Win32 VFS. Fixes to OSTRACE macros.
FossilOrigin-Name: fc98092f4bd42d64059024f09547904c1d70a517
2013-08-28 02:26:48 +00:00
mistachkin f64188910d Fix several harmless compiler warnings. Fix a couple compiler issues with the shell.
FossilOrigin-Name: 8917e9f9a0802cbfb6f33e2ab1c2f98e4df5babd
2013-08-28 01:54:12 +00:00
drh 1435a9a126 Adjust ANALYZE for improved test coverage. Use the SQLITE_ENABLE_STAT3_OR_STAT4
macro (created in sqliteInt.h) to conditionally include code, instead of 
a boolean specifying both macros separately.

FossilOrigin-Name: 67a9a392edd62ef5a5a1ad3010b20a39b285793d
2013-08-27 23:15:44 +00:00
drh 9fecc546cb Reduce the amount of code run and memory used for ANALYZE in the common case
where neither STAT3 and STAT4 are enabled.

FossilOrigin-Name: 9d1424c91a21ed740aca53e437b8f7c1f0823c03
2013-08-27 20:16:48 +00:00
dan 0dd8b87955 Update sqlite3.pc.in to use @PACKAGE_VERSION@ instead of @RELEASE@.
FossilOrigin-Name: 2460dfd8825d251e622e866e8dc1c0bf7fe7ec9f
2013-08-27 15:41:09 +00:00
drh 59b08dd449 In the ANALYZE command implementation make statInit() a 2-value function
since the 3rd parameter was always the same constant.

FossilOrigin-Name: 959bb5acdc3b4e2b481e3c38f20867131bfc9dbc
2013-08-27 14:14:14 +00:00
mistachkin 4496a2329a Preparation for further Windows path name handling changes.
FossilOrigin-Name: ec99224b0c9cf1ccd64b3dc93252556d888e93a3
2013-08-26 23:18:57 +00:00
drh 2f53b90665 Merge the STAT4 capability into trunk.
FossilOrigin-Name: a32af0abe5fa6d570604fa3534e8230d5b6042fc
2013-08-26 23:18:06 +00:00
mistachkin 31706a2d94 Change MAX_PATH related defines to use character lengths where WCHARs are used.
FossilOrigin-Name: 0a497083e915520c0807cb6611264b1a35ff62b7
2013-08-26 20:45:50 +00:00
mistachkin 09b404419a Merge updates from trunk.
FossilOrigin-Name: 9d6860098f96efc7ea60e2d6116fb7d0e2685a55
2013-08-26 19:36:18 +00:00
dan 4dd5144366 Fix for builds with both SQLITE_OMIT_WAL and SQLITE_MAX_MMAP_SIZE=0 defined.
FossilOrigin-Name: edd5dbdc3239fc88799b822941603fcc828ecbb6
2013-08-26 14:30:25 +00:00
drh f68060839c Version 3.8.0
FossilOrigin-Name: f64cd21e2e23ed7cff48f7dafa5e76adde9321c2
2013-08-26 04:50:08 +00:00
mistachkin e49d98fb0a Several modifications to the use of the MAX_PATH macro on Windows to improve consistency.
FossilOrigin-Name: bda4c47df8e80b4cc9e8aac8fd74482869f96107
2013-08-24 23:55:01 +00:00
mistachkin b5ca3cbcd3 Fix a couple compilation issues on Unix.
FossilOrigin-Name: 25b029d8f32440a94ef8af45153423f6702d7431
2013-08-24 01:12:03 +00:00
mistachkin e98844f723 Unify the result of PRAGMA mmap_size when mmap support is disabled.
FossilOrigin-Name: 032c31593d6f569842830cac6222362be68b2084
2013-08-24 00:59:24 +00:00
drh feb56e0e17 Adjust #ifdefs to get SQLITE_OMIT_AUTOMATIC_INDEX and SQLITE_OMIT_PAGER_PRAGMAS
to build.

FossilOrigin-Name: ed310201628cf79c0f57674ae7478ee6738b1c6e
2013-08-23 17:33:46 +00:00
drh 1efd81f7cf Fix a requirements comment in a test case. No changes to the testcase
itself nor to any code.

FossilOrigin-Name: 3ad1f998e5db044849b528c31c4a7e1f3d527320
2013-08-23 16:47:40 +00:00
dan 7dd8d0a87b Modify script mkautoconfamal.sh to use the download.html naming convention for the tar.gz it creates.
FossilOrigin-Name: 375b4e3db0e0c9e83034d1c33d7c57aca48e87b6
2013-08-23 12:04:52 +00:00
drh cc04afdad0 Defer the creation of automatic indices until the index is actually used.
FossilOrigin-Name: 0775501acf152dcbf4dd039f4511f3d8c4330d85
2013-08-22 02:56:28 +00:00
drh b00fc3b14e Simplify the btreeGetPage() routine so that it uses a single flag parameter
in place of two boolean parameters.

FossilOrigin-Name: 617e23ec283d3147fc3fd29c474ccedf4915cdc7
2013-08-21 23:42:32 +00:00
drh 9d1ab0794e Minor performance tweaks to the pager.
FossilOrigin-Name: 9ae1f9ce7ea6beaeddc3711080b3796e05acc4f8
2013-08-21 22:54:55 +00:00
drh cf5ff12105 Refactor the sqlite3_randomness() implementation for improved performance.
FossilOrigin-Name: 4144dffb57b5ed791d7a6d2f26fab5e7dc77fbd1
2013-08-21 22:09:25 +00:00
drh b49bc86a1a Simplification to the StrAccum object and the sqlite3StrAccumAppend()
method that also results in slightly better performance.

FossilOrigin-Name: 700dbbea8647e0fdaee6d0aba3d3dd8ebfbac04a
2013-08-21 21:12:10 +00:00
dan c63e880bdb Minor fixes for test cases. No code changes.
FossilOrigin-Name: ef2a6a37366f91889dc2f1ba9cb6d1257d9b05db
2013-08-21 20:04:54 +00:00
mistachkin 47b2995983 Fix typo in test.
FossilOrigin-Name: f9859fe93bcecb4be7c1034291018523124c4a5c
2013-08-21 19:59:14 +00:00
drh e7ecdfabd2 Update sqlite3MemCompare() to try common cases first, for a modest speed
improvement.

FossilOrigin-Name: b25bac79191975149d88fe34618c74354de62c5e
2013-08-21 19:13:53 +00:00
dan 016f7811f2 If a virtual table xSync() returns an error message, copy it into a buffer allocated by sqlite3DbMalloc() before transfering it to Vdbe.zErrMsg.
FossilOrigin-Name: 854ba3049005adf033e07e6740a36e63f2a56758
2013-08-21 17:35:48 +00:00
drh 13c77bf86b Performance enhancement in btreeParseCellPtr().
FossilOrigin-Name: a17190a2296e8cd5e59524ff5914fc5ea3560697
2013-08-21 15:52:22 +00:00
dan 2505a5fee2 Fix an FTS4 problem introduced by [361084e1eb].
FossilOrigin-Name: 5f35c8cb8f8b67121c70f98c02c4aa7c25327690
2013-08-21 15:45:27 +00:00
dan 36e78309de Candidate fix for [d666d600a6].
FossilOrigin-Name: 781592f32c8e1dcd59954c17211cf61349d1c0b1
2013-08-21 12:04:32 +00:00
dan 22c745a9c9 Fix a minor problem in progress.test. No code changes.
FossilOrigin-Name: a95ae93b32a9ad2ae017124ed0881802c3c741c0
2013-08-21 07:25:03 +00:00
dan c3c16cbd61 Fix a couple of test scripts to work with DEFAULT_AUTOVACUUM and OMIT_VIRTUALTABLE.
FossilOrigin-Name: 356c6c59311eaf7d5633476f635e94a12b8b3924
2013-08-20 20:25:03 +00:00
dan e934e633a5 Fix an invalid assert() in where.c. Also a crash that can occur in the EXPLAIN QUERY PLAN code under obscure circumstances.
FossilOrigin-Name: ef192abb82c2fc31135f875d7a19908d67c076b0
2013-08-20 17:14:57 +00:00
drh d0aa2f3afd Ignore IS NOT NULL and NOT NULL constraints on NOT NULL columns.
FossilOrigin-Name: e476408e3c5ba5f3ba5e98ff264167c163d72e3f
2013-08-20 17:00:55 +00:00
dan 4044906210 Test script changes to support testing sqlite3_interrupt().
FossilOrigin-Name: 0cede9f898bcd13dab51b25cb0e72213d988d3d2
2013-08-20 16:08:39 +00:00
drh 9b47ee3f09 Performance optimizations in the VDBE and especially to the OP_Next and
related opcodes and in the sqlite3BtreeNext() and sqlite3BtreePrevious()
routines.  This is a cherrypick of [6f99b54aedeb], [d2efea1682a7], and
[d78c5d89de4b].

FossilOrigin-Name: 7f72fc4f47445a2c01910b268335873de9f75059
2013-08-20 03:13:51 +00:00
drh f66f26a311 Performance improvement in sqlite3BtreeNext() and sqlite3BtreePrevious()
for the common case of a valid cursor.

FossilOrigin-Name: dc65ad8c4c67b21e3b042b8df6580d02b634a90b
2013-08-19 20:04:10 +00:00
dan 2c18788ffa Initialize a variable in fts3_write.c on the grounds that the argument required to show that it does not require initialization with is complicated. Add an assert() to where.c to silence a clang scan-build warning.
FossilOrigin-Name: d6c4d48a002a6d7057fccc30064ce0b049678f0c
2013-08-19 19:29:50 +00:00
dan e704713cb8 Fix test script pragma2.test so that it works with ENABLE_MEMORY_MANAGEMENT.
FossilOrigin-Name: 6acf728100ff339e4451bcefd3a20fd5c3cfd662
2013-08-19 18:37:18 +00:00
dan 290703091e Add some extra assert() statements to silence a few clang warnings.
FossilOrigin-Name: 1c63e9515b5f5cb9169928b108d002dcd18ad4fd
2013-08-19 18:17:03 +00:00
drh 4ccc419b3c Remove unused variables from the command-line shell sources.
FossilOrigin-Name: 753a402e90f3c9f675155ea96ee048dbe7a68700
2013-08-19 14:23:31 +00:00
drh 9e48788e9d Fix a potential reference off the end of an array in the query planner.
FossilOrigin-Name: f15591f80212dd6d4ed8e0f14be691cd578d4cdf
2013-08-19 14:19:00 +00:00
drh 77dfd5bb44 Fixes for harmless compiler warnings.
FossilOrigin-Name: a0d9ca4f07f1dc3a189864f8ed9cdb0b1d791b1a
2013-08-19 11:15:48 +00:00
drh 45e3215db0 Add the cache_spill pragma. Change the fullfsync and checkpoint_fullfsync
pragmas to apply to all attached databases.

FossilOrigin-Name: 65a85a156f3c827890e9f1fd22484a2f875c3b6f
2013-08-17 16:37:04 +00:00
drh d3605a4f20 The fullfsync, checkpoint_fullfsync, and cache_spill pragmas apply to all
files of a database connection, including those opened by future ATTACH
statements.

FossilOrigin-Name: d07c4331a28d44deca1ece8a34118f5b121b3ee2
2013-08-17 15:42:29 +00:00
drh d4b5c60eca Test cases for the cache_spill pragma.
FossilOrigin-Name: b85c9ec5e02c1b92faa8eeb9e56e02a576a43a96
2013-08-17 00:25:07 +00:00
drh 40c3941cfa Add the cache_spill pragma.
FossilOrigin-Name: cdb181c04fa99c6c29f23eb68ccb5475e7f6bf9c
2013-08-16 20:42:20 +00:00
60 changed files with 1782 additions and 807 deletions
+34 -7
View File
@@ -94,6 +94,14 @@ WIN32HEAP = 0
DEBUG = 0
!ENDIF
# Enable use of available compiler optimizations? Normally, this should be
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
#
!IFNDEF OPTIMIZATIONS
OPTIMIZATIONS = 2
!ENDIF
# Check for the predefined command macro CC. This should point to the compiler
# binary for the target platform. If it is not defined, simply define it to
# the legacy default value 'cl.exe'.
@@ -343,11 +351,15 @@ TCLSH_CMD = tclsh85
# Compiler options needed for programs that use the readline() library.
#
!IFNDEF READLINE_FLAGS
READLINE_FLAGS = -DHAVE_READLINE=0
!ENDIF
# The library that programs using readline() must link against.
#
!IFNDEF LIBREADLINE
LIBREADLINE =
!ENDIF
# Should the database engine be compiled threadsafe
#
@@ -397,17 +409,30 @@ RCC = $(RCC) $(OPT_FEATURE_FLAGS)
TCC = $(TCC) $(OPTS)
RCC = $(RCC) $(OPTS)
# If symbols are enabled, enable PDBs.
# If debugging is enabled, disable all optimizations and enable PDBs.
# If compiling for debugging, add some defines.
!IF $(DEBUG)>0
TCC = $(TCC) -Od -D_DEBUG
BCC = $(BCC) -Od -D_DEBUG
TCC = $(TCC) -D_DEBUG
BCC = $(BCC) -D_DEBUG
RCC = $(RCC) -D_DEBUG
!ELSE
TCC = $(TCC) -O2
BCC = $(BCC) -O2
!ENDIF
# If optimizations are enabled or disabled (either implicitly or
# explicitly), add the necessary flags.
!IF $(DEBUG)>0 || $(OPTIMIZATIONS)==0
TCC = $(TCC) -Od
BCC = $(BCC) -Od
!ELSEIF $(OPTIMIZATIONS)>=3
TCC = $(TCC) -Ox
BCC = $(BCC) -Ox
!ELSEIF $(OPTIMIZATIONS)==2
TCC = $(TCC) -O2
BCC = $(BCC) -O2
!ELSEIF $(OPTIMIZATIONS)==1
TCC = $(TCC) -O1
BCC = $(BCC) -O1
!ENDIF
# If symbols are enabled (or compiling for debugging), enable PDBs.
!IF $(DEBUG)>0 || $(SYMBOLS)!=0
TCC = $(TCC) -Zi
BCC = $(BCC) -Zi
@@ -465,7 +490,9 @@ LTLIBS = $(LTLIBS) $(LIBICU)
!ENDIF
# nawk compatible awk.
!IFNDEF NAWK
NAWK = gawk.exe
!ENDIF
# You should not have to change anything below this line
###############################################################################
+1 -1
View File
@@ -1 +1 @@
3.8.0
3.8.1
Vendored
+27 -38
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.0.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.1.
#
# 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.8.0'
PACKAGE_STRING='sqlite 3.8.0'
PACKAGE_VERSION='3.8.1'
PACKAGE_STRING='sqlite 3.8.1'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -874,7 +874,6 @@ TEMP_STORE
BUILD_EXEEXT
SQLITE_OS_UNIX
SQLITE_OS_WIN
SQLITE_OS_OS2
TARGET_EXEEXT
TCL_VERSION
TCL_BIN_DIR
@@ -1484,7 +1483,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.8.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.8.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1549,7 +1548,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.0:";;
short | recursive ) echo "Configuration of sqlite 3.8.1:";;
esac
cat <<\_ACEOF
@@ -1665,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.8.0
sqlite configure 3.8.1
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1679,7 +1678,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.8.0, which was
It was created by sqlite $as_me 3.8.1, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -3733,13 +3732,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:3736: $ac_compile\"" >&5)
(eval echo "\"\$as_me:3735: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
(eval echo "\"\$as_me:3739: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval echo "\"\$as_me:3738: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
(eval echo "\"\$as_me:3742: output\"" >&5)
(eval echo "\"\$as_me:3741: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -4961,7 +4960,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 4964 "configure"' > conftest.$ac_ext
echo '#line 4963 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -6830,11 +6829,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6833: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6832: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6837: \$? = $ac_status" >&5
echo "$as_me:6836: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7169,11 +7168,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7172: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7171: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7176: \$? = $ac_status" >&5
echo "$as_me:7175: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7274,11 +7273,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7277: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7276: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7281: \$? = $ac_status" >&5
echo "$as_me:7280: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7329,11 +7328,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7332: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7331: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7336: \$? = $ac_status" >&5
echo "$as_me:7335: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -10142,7 +10141,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 10145 "configure"
#line 10144 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10238,7 +10237,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 10241 "configure"
#line 10240 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12257,7 +12256,7 @@ USE_AMALGAMATION=1
# if not, then we fall back to plain tclsh.
# TODO: try other versions before falling back?
#
for ac_prog in tclsh8.5 tclsh
for ac_prog in tclsh8.6 tclsh8.5 tclsh
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@@ -12713,21 +12712,12 @@ else
TARGET_EXEEXT=$config_TARGET_EXEEXT
fi
if test "$TARGET_EXEEXT" = ".exe"; then
if test $OS2_SHELL ; then
SQLITE_OS_UNIX=0
SQLITE_OS_WIN=0
SQLITE_OS_OS2=1
CFLAGS="$CFLAGS -DSQLITE_OS_OS2=1"
else
SQLITE_OS_UNIX=0
SQLITE_OS_WIN=1
SQLITE_OS_OS2=0
CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1"
fi
SQLITE_OS_UNIX=0
SQLITE_OS_WIN=1
CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1"
else
SQLITE_OS_UNIX=1
SQLITE_OS_WIN=0
SQLITE_OS_OS2=0
CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1"
fi
@@ -12736,7 +12726,6 @@ fi
##########
# Figure out all the parameters needed to compile against Tcl.
#
@@ -14032,7 +14021,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.8.0, which was
This file was extended by sqlite $as_me 3.8.1, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14085,7 +14074,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.8.0
sqlite config.status 3.8.1
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+4 -14
View File
@@ -139,7 +139,7 @@ USE_AMALGAMATION=1
# if not, then we fall back to plain tclsh.
# TODO: try other versions before falling back?
#
AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.5 tclsh], none)
AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh8.5 tclsh], none)
if test "$TCLSH_CMD" = "none"; then
# If we can't find a local tclsh, then building the amalgamation will fail.
# We act as though --disable-amalgamation has been used.
@@ -340,28 +340,18 @@ else
TARGET_EXEEXT=$config_TARGET_EXEEXT
fi
if test "$TARGET_EXEEXT" = ".exe"; then
if test $OS2_SHELL ; then
SQLITE_OS_UNIX=0
SQLITE_OS_WIN=0
SQLITE_OS_OS2=1
CFLAGS="$CFLAGS -DSQLITE_OS_OS2=1"
else
SQLITE_OS_UNIX=0
SQLITE_OS_WIN=1
SQLITE_OS_OS2=0
CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1"
fi
SQLITE_OS_UNIX=0
SQLITE_OS_WIN=1
CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1"
else
SQLITE_OS_UNIX=1
SQLITE_OS_WIN=0
SQLITE_OS_OS2=0
CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1"
fi
AC_SUBST(BUILD_EXEEXT)
AC_SUBST(SQLITE_OS_UNIX)
AC_SUBST(SQLITE_OS_WIN)
AC_SUBST(SQLITE_OS_OS2)
AC_SUBST(TARGET_EXEEXT)
##########
+1
View File
@@ -504,6 +504,7 @@ static int fts3StringAppend(
pStr->z = zNew;
pStr->nAlloc = nAlloc;
}
assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) );
/* Append the data to the string buffer. */
memcpy(&pStr->z[pStr->n], zAppend, nAppend);
+7 -7
View File
@@ -1461,7 +1461,7 @@ static int fts3SegReaderNextDocid(
/* The following line of code (and the "p++" below the while() loop) is
** normally all that is required to move pointer p to the desired
** position. The exception is if this node is being loaded from disk
** incrementally and pointer "p" now points to the first byte passed
** incrementally and pointer "p" now points to the first byte past
** the populated part of pReader->aNode[].
*/
while( *p | c ) c = *p++ & 0x80;
@@ -2848,8 +2848,8 @@ int sqlite3Fts3SegReaderStep(
fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
while( apSegment[0]->pOffsetList ){
int j; /* Number of segments that share a docid */
char *pList;
int nList;
char *pList = 0;
int nList = 0;
int nByte;
sqlite3_int64 iDocid = apSegment[0]->iDocid;
fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
@@ -5135,11 +5135,11 @@ int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
if( pTC ) pModule->xClose(pTC);
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
}
}
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
if( pDef->pList ){
rc = fts3PendingListAppendVarint(&pDef->pList, 0);
}
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
if( pDef->pList ){
rc = fts3PendingListAppendVarint(&pDef->pList, 0);
}
}
}
+63 -61
View File
@@ -1,12 +1,12 @@
C Adjustments\sto\s#ifdefs\sin\sanalyze.c\sto\sall\sa\sclean\scompile\swith\sno\nextra\scode\swith\sboth\sENABLE_STAT3\sand\sENABLE_STAT4\sand\swith\sneither.
D 2013-08-17T18:57:15.775
C Change\sthe\sunix\sVFS\sso\sthat\sit\srefuses\sto\sopen\sa\sdatabase\sfile\susing\na\sfile\sdescriptor\sless\sthan\s3.
D 2013-08-29T23:34:53.402
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc e9f41f89111627baaabd95cab4988b8d1c3e47c9
F Makefile.msc a97163524522cd829cb91bcf900d07608e025502
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION f135b651727f978b7191bd6fa12c7fc1e13e13ac
F VERSION a8d1f6839521130dc73c5408cdd24bcfd791df34
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -38,8 +38,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 27e9279a219b652bd1c53439353a5e5be70214b2 x
F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444
F configure d9bb8485d40dd905e09c895692a0699628abace8 x
F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
@@ -87,7 +87,7 @@ F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
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 5fcfcafff46a2a3a63b8e59fcb51987d01c74695
F ext/fts3/fts3_snippet.c e8ee8c101dd9cfbc9568d134e869d2bd2f7f6d4d
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
F ext/fts3/fts3_test.c f9a1a1702db1bfad3e2d0064746eeb808f125489
F ext/fts3/fts3_tokenize_vtab.c 011170fe9eba5ff062f1a31d3188e00267716706
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9
F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d
F ext/fts3/fts3_write.c cd264daa4f92b8eb6d61245333d0e3b147e8fd80
F ext/fts3/fts3_write.c ce45c3ea578464f26b0293ea8e54a39694f18b64
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
@@ -155,27 +155,27 @@ F mptest/multiwrite01.test 499ad0310da8dff8e8f98d2e272fc2a8aa741b2e
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c 10a4f1cda87aec6c56760c66e5feaaf1cdc9a641
F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
F src/analyze.c 7f869a251f3d58d3b95883eeae425d4ee17a66bd
F src/attach.c fea00cab11c854646a27641a263f5876569a51f9
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 15ea4e980ba5edeb9b495f001e86a0688f46ee2c
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
F src/build.c c2e4d057c833b616c6e32e690c29c03ba949b571
F src/btree.c b9b57df546df2636294bfb21a986f5707b417df2
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
F src/btreeInt.h 51cf220a9b9223354770883e93a859dc377aa27f
F src/build.c f63e8929c7f89c0074fbc74929bc946ea117b2f8
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94
F src/expr.c 0bbb44462a19169189b2709fbbd800950521b5ae
F src/expr.c 4d89bd03a04fcdb5ff71d86b4e0cc7d3230797b8
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
F src/func.c 78c371ddfb0bb2d4c4356e8d7336b582d4ca96a9
F src/func.c 5b064acd303b3e74f019ab551d423ff6cace4023
F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
@@ -185,11 +185,11 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c 4e4cd5c2ee09db496c0dde79b507bba6b8bcbdcb
F src/main.c dc02c7c118d58049e0cccc6c9c47c0a4d3e2bcda
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
F src/mem2.c e243acb034f91e75e4c06aed5d3d960025c62d1f
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 0025308a93838022bd5696cf9627ff4e40b19918
F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785
@@ -197,36 +197,36 @@ F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
F src/mutex_w32.c 32a9b3841e2d757355f0012b860b1bc5e01eafa0
F src/mutex_w32.c 6108c88e1cb38d8fbb3534b170793815cbedbf97
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
F src/os_unix.c 45d425550a86e6464b494574df43b6e2efc98003
F src/os_win.c 26d752736dff0c7e4e384ab65b353cce1e7e19c5
F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8
F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
F src/pragma.c 590c75750d93ec5a1f903e4bb0dc6d2a0845bf8b
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
F src/pragma.c 3aa3d8c8623b7b71c5b1bfb72dcc31fb0c25665f
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
F src/resolve.c 9d53899cc6e1f4ec0b4632d07e97d57827bf63b9
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 8b148eb851f384412aea57091659d14b369918ca
F src/shell.c 128eb16ccec68509a4a2f1948f2483819bf63425
F src/shell.c dbe064d404bb497acd8a44c066cd6b8460a71236
F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 85cc797544e30cf585507b2127b4a3f60478c849
F src/sqliteInt.h 600086a5082e2291b0aeeefcfbb546f2bbda67b2
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 659dad8ef30b54831306a244b43e37af4725a444
F src/test1.c 870fc648a48cb6d6808393174f7ebe82b8c840fa
F src/test1.c 26226cfd2b6dc3f77d2eb27f07ffcf236b4e728b
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -250,7 +250,7 @@ F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c a105801222c0514f8befa2a1712a95505cce099a
F src/test_malloc.c eba4e1c5847cc98e7edc98f62265cd2abafba7a6
F src/test_multiplex.c 5d691eeb6cb6aa7888da28eba5e62a9a857d3c0f
F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
@@ -277,20 +277,20 @@ F src/update.c 7d9d38e4f341ada7d79035ea969cdefb8b9014d1
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
F src/vdbe.c c9488a255843c815a4bbb58ca7ad2fa871150d69
F src/vdbe.c 2b1cd2c7e3d74e6aa99ce2f538bfdd07a00dc2f1
F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
F src/vdbeaux.c a6ea36a9dc714e1128a0173249a0532ddcab0489
F src/vdbeInt.h cbe71b8b36d8b3bba5709cc3f436c7e3b47b7b08
F src/vdbeapi.c 96b24b946cf21894f63d9393e821baa2f0a80979
F src/vdbeaux.c c7fe2695e256dbf254113c4fe90d3ec9aabe3bbe
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
F src/vdbemem.c 466784a5626d9cf45ed28a187ef809471b8a5675
F src/vdbemem.c 4511e1d2304a7d7916d14be20080036331740fcf
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
F src/vtab.c 165ce0e797c2cd23badb104c9f2ae9042d6d942c
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
F src/where.c 9be69c42a02376c46d44907b38edd70f8a2cea7a
F src/where.c cad6497f79307c2c94aaf72e64866bb33cf99d59
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -369,7 +369,7 @@ F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test b709989e6e6ff6e1d2bd64231c2c1d8146846c9e
F test/collate2.test 285cef1b58ce2b3cf074a386f763ce753c81c97f
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f
F test/collate4.test 031f7265c13308b724ba3c49f41cc04612bd92b1
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
@@ -397,7 +397,7 @@ F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb
F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f
F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018
F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993
F test/corruptG.test d18ee5169e10a76bccb7b115e551bc31087a525e
F test/corruptG.test c67fd860e9e3943bc90b856a3049c9a28827167e
F test/count.test 454e1ce985c94d13efeac405ce54439f49336163
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
@@ -432,7 +432,7 @@ F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
F test/e_expr.test d5cdda0e4ffb17760858ed4c7c4ece07efc40f71
F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test ea84688f3b27a6a3728e4ae7a7d9ad342579d7a4
F test/e_insert.test 291e056e1a442a5e5166a989a8a03a46e38225ca
F test/e_reindex.test e175794fc41f8e8aef34772e87a7d7b7a9251dd3
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test f2358d074bd82240bc79a8348f284a2a8909dc1f
@@ -537,7 +537,7 @@ F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
F test/fts3matchinfo.test 3f297e14e3f0d5be8595246f5fcd426625cc5881
F test/fts3matchinfo.test ff423e73faab8fc6d7adeefedf74dd8e2b0b14e0
F test/fts3near.test 12895557870b0f9af7cc0be81a0171abb2d12f12
F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
@@ -592,8 +592,8 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
F test/index6.test d84c03a7c16222b874877e8f4efb2bb7fed5d29e
F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c
F test/index6.test e96324d8c1ade4b30a4c6cee14b1fc2e5a367cda
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 489aa12a027c83d291f5034a83c8c32e6be1dca2
@@ -646,7 +646,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@@ -663,7 +663,7 @@ 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 9a98856549bfb3fab205edbc1317216edc52e70d
F test/malloc_common.tcl 58e54229c4132ef882a11fab6419ec4cd3073589
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test db5260330676de007be8530d6ecc7c9ab2b06ad3
@@ -718,9 +718,9 @@ F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
F test/permutations.test c5e7ae8a18cb8a0ced38dbbc9e2463536c1de45b
F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
F test/pragma2.test 224f0381f9411a78ae685cac24c13656a62021b7
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/progress.test 552dc1edc37333a8d3098b8c26a2b7f06f5799d7
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
@@ -784,7 +784,7 @@ F test/shell1.test 928547277d385038c696428e9d791cbbad098974
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
F test/shell5.test 946e620a41b64f90d45dcf91c36e8d408d435cfd
F test/shell5.test bfa21ecc173adcbc15db2c075baa468778f67f88
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
@@ -817,7 +817,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
F test/tester.tcl 63b24679c75a952c51f924de2802b2b57cddd22d
F test/tester.tcl 5e97d1fe08f45fa3cc2320cee437e315c75ce995
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -859,6 +859,7 @@ F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
F test/tkt-b1d3a2e531.test 610ef582413171b379652663111b1f996d9f8f78
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
@@ -1041,24 +1042,25 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test da54153a4c1571ea1b95659e5bec8119edf786aa
F test/where2.test b1830f762f837153a4c9743adaab90a5761f73e7
F test/where3.test a0682ba3dc8c8f46ffcc95a3d9f58c4327fc129f
F test/where2.test 76d5346f7edb2a6a0442dcf3e9d088ac6903e0b5
F test/where3.test d28c51f257e60be30f74308fa385ceeddfb54a6e
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
F test/where8.test 6f95896633cf2d307b5263145b942b7d33e837c6
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
F test/where9.test 74245dea86592a744b758dff2e7daf0a07bade7d
F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 136a7301512d72a08a272806c8767066311b7bc1
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/wild001.test 384db4b30fbe82eaaefe8921f8a702c09e26db27
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
F tool/build-all-msvc.bat c55f64ca200308fb5fa5c1ee751ea95a13977b5a x
@@ -1072,7 +1074,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c 680980c7935bfa1edec20c804c9e5ba4b1dd96f5
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/mkautoconfamal.sh 9ef9ad69bc3021a6fd2dac53a2e8cf5b97e0df05
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1107,7 +1109,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 5c591104813a7e55e59f4f557cbb3e500fa817c2
R fed6486268a39dfc52589cfac215691e
P 3426673e4659eb68dbd14a3e41d4620d748432db
R fe0bcec8f0ab9128b1355459470b05e0
U drh
Z ee5235686bd18f87bb4458ce74357891
Z 4edcc0d4a963da6c4b3d4505d80b9383
+1 -1
View File
@@ -1 +1 @@
f86b75b6c7290ee6ddb3636090b00e99fc68c45e
66dddda06898abbf97fe0ac6a10ce1527ca8605e
+1 -1
View File
@@ -7,7 +7,7 @@ includedir=@includedir@
Name: SQLite
Description: SQL database engine
Version: @RELEASE@
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lsqlite3
Libs.private: @LIBS@
Cflags: -I${includedir}
+151 -119
View File
@@ -1,5 +1,5 @@
/*
** 2005 July 8
** 2005-07-08
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -31,7 +31,9 @@
** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3
** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced
** version of sqlite_stat3 and is only available when compiled with
** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later.
** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is
** not possible to enable both STAT3 and STAT4 at the same time. If they
** are both enabled, then STAT4 is precedence.
**
** For most applications, sqlite_stat1 provides all the statisics required
** for the query planner to make good choices.
@@ -143,32 +145,29 @@
#if defined(SQLITE_ENABLE_STAT4)
# define IsStat4 1
# define IsStat3 0
# define SQLITE_ENABLE_STAT34 1
#elif defined(SQLITE_ENABLE_STAT3)
# define IsStat4 0
# define IsStat3 1
# define SQLITE_ENABLE_STAT34 1
#else
# define IsStat4 0
# define IsStat3 0
# undef SQLITE_ENABLE_STAT34
# undef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 1
#endif
#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */
/*
** This routine generates code that opens the sqlite_stat1 table for
** writing with cursor iStatCur. If the library was built with the
** SQLITE_ENABLE_STAT4 macro defined, then the sqlite_stat4 table is
** opened for writing using cursor (iStatCur+1)
** This routine generates code that opens the sqlite_statN tables.
** The sqlite_stat1 table is always relevant. sqlite_stat2 is now
** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when
** appropriate compile-time options are provided.
**
** If the sqlite_stat1 tables does not previously exist, it is created.
** Similarly, if the sqlite_stat4 table does not exist and the library
** is compiled with SQLITE_ENABLE_STAT4 defined, it is created.
** If the sqlite_statN tables do not previously exist, it is created.
**
** Argument zWhere may be a pointer to a buffer containing a table name,
** or it may be a NULL pointer. If it is not NULL, then all entries in
** the sqlite_stat1 and (if applicable) sqlite_stat4 tables associated
** with the named table are deleted. If zWhere==0, then code is generated
** to delete all stat table entries.
** the sqlite_statN tables associated with the named table are deleted.
** If zWhere==0, then code is generated to delete all stat table entries.
*/
static void openStatTable(
Parse *pParse, /* Parsing context */
@@ -188,16 +187,18 @@ static void openStatTable(
#elif defined(SQLITE_ENABLE_STAT3)
{ "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
{ "sqlite_stat4", 0 },
#else
{ "sqlite_stat3", 0 },
{ "sqlite_stat4", 0 },
#endif
};
int aRoot[] = {0, 0};
u8 aCreateTbl[] = {0, 0};
int i;
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
int aRoot[ArraySize(aTable)];
u8 aCreateTbl[ArraySize(aTable)];
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3VdbeDb(v)==db );
@@ -211,7 +212,7 @@ static void openStatTable(
Table *pStat;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
if( aTable[i].zCols ){
/* The sqlite_stat[12] table does not exist. Create it. Note that a
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
@@ -226,10 +227,12 @@ static void openStatTable(
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zName, zTab, zWhereType, zWhere
);
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
@@ -239,11 +242,11 @@ static void openStatTable(
}
/* Open the sqlite_stat[134] tables for writing. */
for(i=0; i<ArraySize(aRoot); i++){
for(i=0; aTable[i].zCols; i++){
assert( i<ArraySize(aTable) );
sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
if( !IsStat3 && !IsStat4 ) break;
}
}
@@ -262,13 +265,15 @@ static void openStatTable(
typedef struct Stat4Accum Stat4Accum;
typedef struct Stat4Sample Stat4Sample;
struct Stat4Sample {
i64 iRowid; /* Rowid in main table of the key */
tRowcnt *anEq; /* sqlite_stat4.nEq */
tRowcnt *anLt; /* sqlite_stat4.nLt */
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
tRowcnt *anLt; /* sqlite_stat4.nLt */
i64 iRowid; /* Rowid in main table of the key */
u8 isPSample; /* True if a periodic sample */
int iCol; /* If !isPSample, the reason for inclusion */
u32 iHash; /* Tiebreaker hash */
#endif
};
struct Stat4Accum {
tRowcnt nRow; /* Number of rows in the entire table */
@@ -285,9 +290,9 @@ struct Stat4Accum {
};
/*
** Implementation of the stat_init(C,N,S) SQL function. The three parameters
** are the number of rows in the table or index (C), the number of columns
** in the index (N) and the number of samples to accumulate (S).
** Implementation of the stat_init(N,C) SQL function. The two parameters
** are the number of rows in the table or index (C) and the number of columns
** in the index (N). The second argument (C) is only used for STAT3 and STAT4.
**
** This routine allocates the Stat4Accum object in heap memory. The return
** value is a pointer to the the Stat4Accum object encoded as a blob (i.e.
@@ -299,64 +304,73 @@ static void statInit(
sqlite3_value **argv
){
Stat4Accum *p;
u8 *pSpace; /* Allocated space not yet assigned */
tRowcnt nRow; /* Number of rows in table (C) */
int mxSample; /* Maximum number of samples collected */
int nCol; /* Number of columns in index being sampled */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
int i; /* Used to iterate through p->aSample[] */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int mxSample = SQLITE_STAT4_SAMPLES;
#endif
/* Decode the three function arguments */
UNUSED_PARAMETER(argc);
nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
mxSample = sqlite3_value_int(argv[2]);
nCol = sqlite3_value_int(argv[1]);
nCol = sqlite3_value_int(argv[0]);
assert( nCol>1 ); /* >1 because it includes the rowid column */
nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
/* Allocate the space required for the Stat4Accum object */
n = sizeof(*p)
+ sizeof(tRowcnt)*nCol /* Stat4Accum.anEq */
+ sizeof(tRowcnt)*nCol /* Stat4Accum.anLt */
+ sizeof(tRowcnt)*nCol /* Stat4Accum.anDLt */
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nCol*(nCol+mxSample);
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
#endif
;
p = sqlite3MallocZero(n);
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
p->nRow = nRow;
p->nRow = 0;
p->nCol = nCol;
p->mxSample = mxSample;
p->nPSample = p->nRow/(mxSample/3+1) + 1;
p->iGet = -1;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nCol];
p->current.anLt = &p->current.anEq[nCol];
sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
p->current.anEq = &p->current.anDLt[nColUp];
/* Set up the Stat4Accum.a[] and aBest[] arrays */
p->a = (struct Stat4Sample*)&p->current.anLt[nCol];
p->aBest = &p->a[mxSample];
pSpace = (u8*)(&p->a[mxSample+nCol]);
for(i=0; i<(mxSample+nCol); i++){
p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
}
assert( (pSpace - (u8*)p)==n );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
for(i=0; i<nCol; i++){
p->aBest[i].iCol = i;
p->iGet = -1;
p->mxSample = mxSample;
p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1;
p->current.anLt = &p->current.anEq[nColUp];
sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
/* Set up the Stat4Accum.a[] and aBest[] arrays */
p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
p->aBest = &p->a[mxSample];
pSpace = (u8*)(&p->a[mxSample+nCol]);
for(i=0; i<(mxSample+nCol); i++){
p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
}
assert( (pSpace - (u8*)p)==n );
for(i=0; i<nCol; i++){
p->aBest[i].iCol = i;
}
}
#endif
/* Return a pointer to the allocated object to the caller */
sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
}
static const FuncDef statInitFuncdef = {
3, /* nArg */
1+IsStat34, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
@@ -369,7 +383,7 @@ static const FuncDef statInitFuncdef = {
0 /* pDestructor */
};
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Return true if pNew is to be preferred over pOld.
*/
@@ -491,7 +505,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
p->iMin = iMin;
}
}
#endif /* SQLITE_ENABLE_STAT34 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** Field iChng of the index being scanned has changed. So at this point
@@ -544,11 +558,16 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
}
/*
** Implementation of the stat_push SQL function.
** Implementation of the stat_push SQL function: stat_push(P,R,C)
** Arguments:
**
** stat_push(P,R,C)
** P Pointer to the Stat4Accum object created by stat_init()
** C Index of left-most column to differ from previous row
** R Rowid for the current row
**
** The return value is always NULL.
** The SQL function always returns NULL.
**
** The R parameter is only used for STAT3 and STAT4.
*/
static void statPush(
sqlite3_context *context,
@@ -559,15 +578,17 @@ static void statPush(
/* The three function arguments */
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
i64 rowid = sqlite3_value_int64(argv[1]);
int iChng = sqlite3_value_int(argv[2]);
int iChng = sqlite3_value_int(argv[1]);
assert( p->nCol>1 ); /* Includes rowid field */
assert( iChng<p->nCol );
/* p->current.anEq[0] is false the first time this function is called. */
if( p->current.anEq[0] ){
if( p->nRow==0 ){
/* anEq[0] is only zero for the very first call to this function. Do
** appropriate initialization */
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}else{
/* Second and subsequent calls get processed here */
samplePushPrevious(p, iChng);
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
@@ -577,18 +598,17 @@ static void statPush(
}
for(i=iChng; i<p->nCol; i++){
p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
}
}else{
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}
if( IsStat4 || IsStat3 ){
p->current.iRowid = rowid;
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
}
p->nRow++;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
p->current.iRowid = sqlite3_value_int64(argv[2]);
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
#endif
#ifdef SQLITE_ENABLE_STAT4
{
@@ -613,7 +633,7 @@ static void statPush(
#endif
}
static const FuncDef statPushFuncdef = {
3, /* nArg */
2+IsStat34, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
@@ -648,7 +668,7 @@ static void statGet(
sqlite3_value **argv
){
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* STAT3 and STAT4 have a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]);
assert( argc==2 );
@@ -704,7 +724,7 @@ static void statGet(
sqlite3_result_text(context, zRet, -1, sqlite3_free);
}
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
else if( eCall==STAT_GET_ROWID ){
if( p->iGet<0 ){
samplePushPrevious(p, 0);
@@ -746,10 +766,10 @@ static void statGet(
}
}
}
#endif /* SQLITE_ENABLE_STAT34 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}
static const FuncDef statGetFuncdef = {
2, /* nArg */
1+IsStat34, /* nArg */
SQLITE_UTF8, /* iPrefEnc */
0, /* flags */
0, /* pUserData */
@@ -764,14 +784,14 @@ static const FuncDef statGetFuncdef = {
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
assert( regOut!=regStat4 && regOut!=regStat4+1 );
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
#else
assert( iParam==STAT_GET_STAT1 );
#endif
sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut);
sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, 1 + IsStat3 + IsStat4);
sqlite3VdbeChangeP5(v, 1 + IsStat34);
}
/*
@@ -797,8 +817,10 @@ static void analyzeOneTable(
u8 needTableCnt = 1; /* True to count the table */
int regNewRowid = iMem++; /* Rowid for the inserted record */
int regStat4 = iMem++; /* Register to hold Stat4Accum object */
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
int regChng = iMem++; /* Index of changed index field */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
#endif
int regTemp = iMem++; /* Temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
@@ -884,7 +906,7 @@ static void analyzeOneTable(
**
** chng_addr_N:
** regRowid = idx(rowid)
** stat_push(P, regRowid, regChng)
** stat_push(P, regChng, regRowid)
** Next csr
** if !eof(csr) goto next_row;
**
@@ -905,16 +927,18 @@ static void analyzeOneTable(
/* Invoke the stat_init() function. The arguments are:
**
** * the number of rows in the index,
** * the number of columns in the index including the rowid,
** * the recommended number of samples for the stat3/stat4 table.
** (1) the number of columns in the index including the rowid,
** (2) the number of rows in the index,
**
** The second argument is only used for STAT3 and STAT4
*/
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+1);
sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+2);
sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT4_SAMPLES, regStat4+3);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
#endif
sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, 3);
sqlite3VdbeChangeP5(v, 1+IsStat34);
/* Implementation of the following:
**
@@ -965,17 +989,20 @@ static void analyzeOneTable(
/*
** chng_addr_N:
** regRowid = idx(rowid)
** stat_push(P, regRowid, regChng)
** regRowid = idx(rowid) // STAT34 only
** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only
** Next csr
** if !eof(csr) goto next_row;
*/
sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
assert( regRowid==(regStat4+2) );
#endif
assert( regChng==(regStat4+1) );
sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, 3);
assert( regRowid==(regStat4+1) && regChng==(regStat4+2) );
sqlite3VdbeChangeP5(v, 2+IsStat34);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
/* Add the entry to the stat1 table. */
@@ -986,7 +1013,8 @@ static void analyzeOneTable(
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat3 or stat4 table. */
if( IsStat3 || IsStat4 ){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{
int regEq = regStat1;
int regLt = regStat1+1;
int regDLt = regStat1+2;
@@ -1005,25 +1033,25 @@ static void analyzeOneTable(
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid);
if( IsStat3 ){
int iCol = pIdx->aiColumn[0];
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regSample);
}else{
for(i=0; i<nCol; i++){
int iCol = pIdx->aiColumn[i];
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
#ifdef SQLITE_ENABLE_STAT3
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pIdx->aiColumn[0], regSample);
#else
for(i=0; i<nCol; i++){
int iCol = pIdx->aiColumn[i];
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
#endif
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
sqlite3VdbeJumpHere(v, addrIsNull);
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* Jump here if the index is empty */
/* End of analysis */
sqlite3VdbeJumpHere(v, addrRewind);
sqlite3DbFree(db, aGotoChng);
}
@@ -1202,8 +1230,12 @@ static void decodeIntArray(
tRowcnt v;
assert( pbUnordered==0 || *pbUnordered==0 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( z==0 ) z = "";
#else
if( NEVER(z==0) ) z = "";
#endif
for(i=0; *z && i<nOut; i++){
v = 0;
while( (c=z[0])>='0' && c<='9' ){
@@ -1254,7 +1286,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
if( pIndex ){
int bUnordered = 0;
decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst, &bUnordered);
decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
pIndex->bUnordered = bUnordered;
}else{
@@ -1269,7 +1301,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
** and its contents.
*/
void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pIdx->aSample ){
int j;
for(j=0; j<pIdx->nSample; j++){
@@ -1285,10 +1317,10 @@ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pIdx);
#endif /* SQLITE_ENABLE_STAT34 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Populate the pIdx->aAvgEq[] array based on the samples currently
** stored in pIdx->aSample[].
@@ -1482,7 +1514,7 @@ static int loadStat4(sqlite3 *db, const char *zDb){
return rc;
}
#endif /* SQLITE_ENABLE_STAT34 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
@@ -1518,7 +1550,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3DefaultRowEst(pIdx);
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
@@ -1543,7 +1575,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT34
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( rc==SQLITE_OK ){
int lookasideEnabled = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
+3
View File
@@ -158,6 +158,9 @@ static void attachFunc(
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
sqlite3BtreeSecureDelete(aNew->pBt,
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
#endif
}
aNew->safety_level = 3;
aNew->zName = sqlite3DbStrDup(db, zName);
+1 -1
View File
@@ -392,7 +392,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
DbPage *pSrcPg; /* Source page object */
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
PAGER_ACQUIRE_READONLY);
PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
+91 -67
View File
@@ -724,6 +724,9 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
pCur->eState = CURSOR_SKIPNEXT;
}
}
return rc;
}
@@ -749,7 +752,7 @@ int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
*pHasMoved = 1;
return rc;
}
if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
*pHasMoved = 1;
}else{
*pHasMoved = 0;
@@ -937,7 +940,8 @@ static void btreeParseCellPtr(
assert( n==4-4*pPage->leaf );
if( pPage->intKey ){
if( pPage->hasData ){
n += getVarint32(&pCell[n], nPayload);
assert( n==0 );
n = getVarint32(pCell, nPayload);
}else{
nPayload = 0;
}
@@ -1581,15 +1585,12 @@ 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 bReadonly /* True if a read-only (mmap) page is ok */
int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
){
int rc;
DbPage *pDbPage;
int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0)
| (bReadonly ? PAGER_ACQUIRE_READONLY : 0);
assert( noContent==0 || bReadonly==0 );
assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
assert( sqlite3_mutex_held(pBt->mutex) );
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
if( rc ) return rc;
@@ -1637,15 +1638,16 @@ static int getAndInitPage(
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 bReadonly /* PAGER_GET_READONLY or 0 */
){
int rc;
assert( sqlite3_mutex_held(pBt->mutex) );
assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 );
if( pgno>btreePagecount(pBt) ){
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
if( rc==SQLITE_OK ){
rc = btreeInitPage(*ppPage);
if( rc!=SQLITE_OK ){
@@ -2165,17 +2167,14 @@ int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(
int sqlite3BtreeSetPagerFlags(
Btree *p, /* The btree to set the safety level on */
int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
int fullSync, /* PRAGMA fullfsync. */
int ckptFullSync /* PRAGMA checkpoint_fullfync */
unsigned pgFlags /* Various PAGER_* flags */
){
BtShared *pBt = p->pBt;
assert( sqlite3_mutex_held(p->db->mutex) );
assert( level>=1 && level<=3 );
sqlite3BtreeEnter(p);
sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
sqlite3PagerSetFlags(pBt->pPager, pgFlags);
sqlite3BtreeLeave(p);
return SQLITE_OK;
}
@@ -2381,7 +2380,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, 0);
rc = btreeGetPage(pBt, 1, &pPage1, 0);
if( rc!=SQLITE_OK ) return rc;
/* Do some checking to help insure the file we opened really is
@@ -2964,7 +2963,7 @@ static int relocatePage(
** iPtrPage.
*/
if( eType!=PTRMAP_ROOTPAGE ){
rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -3048,7 +3047,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -3447,7 +3446,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, 0)==SQLITE_OK ){
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
int nPage = get4byte(28+(u8*)pPage1->aData);
testcase( nPage==0 );
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
@@ -3882,7 +3881,7 @@ static int getOverflowPage(
assert( next==0 || rc==SQLITE_DONE );
if( rc==SQLITE_OK ){
rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0);
assert( rc==SQLITE_OK || pPage==0 );
if( rc==SQLITE_OK ){
next = get4byte(pPage->aData);
@@ -4104,7 +4103,7 @@ static int accessPayload(
{
DbPage *pDbPage;
rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
(eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
(eOp==0 ? PAGER_GET_READONLY : 0)
);
if( rc==SQLITE_OK ){
aPayload = sqlite3PagerGetData(pDbPage);
@@ -4288,7 +4287,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
return SQLITE_CORRUPT_BKPT;
}
rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));
rc = getAndInitPage(pBt, newPgno, &pNewPage,
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
if( rc ) return rc;
pCur->apPage[i+1] = pNewPage;
pCur->aiIdx[i+1] = 0;
@@ -4405,7 +4405,8 @@ static int moveToRoot(BtCursor *pCur){
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}else{
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0],
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
return rc;
@@ -4800,21 +4801,29 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
rc = restoreCursorPosition(pCur);
if( rc!=SQLITE_OK ){
return rc;
}
assert( pRes!=0 );
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
if( pCur->eState!=CURSOR_VALID ){
rc = restoreCursorPosition(pCur);
if( rc!=SQLITE_OK ){
*pRes = 0;
return rc;
}
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
if( pCur->skipNext ){
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
pCur->eState = CURSOR_VALID;
if( pCur->skipNext>0 ){
pCur->skipNext = 0;
*pRes = 0;
return SQLITE_OK;
}
pCur->skipNext = 0;
}
}
if( pCur->skipNext>0 ){
pCur->skipNext = 0;
*pRes = 0;
return SQLITE_OK;
}
pCur->skipNext = 0;
pPage = pCur->apPage[pCur->iPage];
idx = ++pCur->aiIdx[pCur->iPage];
@@ -4832,7 +4841,10 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
if( idx>=pPage->nCell ){
if( !pPage->leaf ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
if( rc ) return rc;
if( rc ){
*pRes = 0;
return rc;
}
rc = moveToLeftmost(pCur);
*pRes = 0;
return rc;
@@ -4874,21 +4886,32 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
rc = restoreCursorPosition(pCur);
if( rc!=SQLITE_OK ){
return rc;
}
assert( pRes!=0 );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
pCur->atLast = 0;
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
if( pCur->eState!=CURSOR_VALID ){
if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
rc = btreeRestoreCursorPosition(pCur);
if( rc!=SQLITE_OK ){
*pRes = 0;
return rc;
}
}
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
if( pCur->skipNext ){
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
pCur->eState = CURSOR_VALID;
if( pCur->skipNext<0 ){
pCur->skipNext = 0;
*pRes = 0;
return SQLITE_OK;
}
pCur->skipNext = 0;
}
}
if( pCur->skipNext<0 ){
pCur->skipNext = 0;
*pRes = 0;
return SQLITE_OK;
}
pCur->skipNext = 0;
pPage = pCur->apPage[pCur->iPage];
assert( pPage->isInit );
@@ -4896,6 +4919,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
int idx = pCur->aiIdx[pCur->iPage];
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ){
*pRes = 0;
return rc;
}
rc = moveToRightmost(pCur);
@@ -5019,7 +5043,7 @@ static int allocateBtreePage(
if( iTrunk>mxPage ){
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
}
if( rc ){
pTrunk = 0;
@@ -5083,7 +5107,7 @@ static int allocateBtreePage(
goto end_allocate_page;
}
testcase( iNewTrunk==mxPage );
rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
if( rc!=SQLITE_OK ){
goto end_allocate_page;
}
@@ -5162,8 +5186,8 @@ static int allocateBtreePage(
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
}
put4byte(&aData[4], k-1);
noContent = !btreeGetHasContent(pBt, *pPgno);
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
@@ -5195,7 +5219,7 @@ static int allocateBtreePage(
** 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));
int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( rc ) return rc;
@@ -5211,7 +5235,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, bNoContent, 0);
rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPg->pDbPage);
releasePage(pPg);
@@ -5225,7 +5249,7 @@ static int allocateBtreePage(
*pPgno = pBt->nPage;
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
if( rc ) return rc;
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
@@ -5293,7 +5317,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))!=0) )
if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
|| ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
){
goto freepage_out;
@@ -5320,7 +5344,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, 0);
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
if( rc!=SQLITE_OK ){
goto freepage_out;
}
@@ -5366,7 +5390,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, 0)) ){
if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
goto freepage_out;
}
rc = sqlite3PagerWrite(pPage->pDbPage);
@@ -7265,7 +7289,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
}
/* Move the page currently at pgnoRoot to pgnoMove. */
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -7286,7 +7310,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
if( rc!=SQLITE_OK ){
return rc;
}
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -7464,7 +7488,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
return SQLITE_LOCKED_SHAREDCACHE;
}
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
if( rc ) return rc;
rc = sqlite3BtreeClearTable(p, iTable, 0);
if( rc ){
@@ -7499,7 +7523,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
*/
MemPage *pMove;
releasePage(pPage);
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -7509,7 +7533,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
return rc;
}
pMove = 0;
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
freePage(pMove, &rc);
releasePage(pMove);
if( rc!=SQLITE_OK ){
@@ -7724,7 +7748,7 @@ static void checkAppendMsg(
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
va_end(ap);
if( pCheck->errMsg.mallocFailed ){
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
pCheck->mallocFailed = 1;
}
}
@@ -7921,7 +7945,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))!=0 ){
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
checkAppendMsg(pCheck, zContext,
"unable to get the page. error code=%d", rc);
return 0;
+1 -1
View File
@@ -64,7 +64,7 @@ int sqlite3BtreeOpen(
int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
int sqlite3BtreeGetPageSize(Btree*);
+11 -5
View File
@@ -520,14 +520,19 @@ struct BtCursor {
/*
** Potential values for BtCursor.eState.
**
** CURSOR_VALID:
** Cursor points to a valid entry. getPayload() etc. may be called.
**
** CURSOR_INVALID:
** Cursor does not point to a valid entry. This can happen (for example)
** because the table is empty or because BtreeCursorFirst() has not been
** called.
**
** CURSOR_VALID:
** Cursor points to a valid entry. getPayload() etc. may be called.
**
** CURSOR_SKIPNEXT:
** Cursor is valid except that the Cursor.skipNext field is non-zero
** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
** operation should be a no-op.
**
** CURSOR_REQUIRESEEK:
** The table that this cursor was opened on still exists, but has been
** modified since the cursor was last used. The cursor position is saved
@@ -544,8 +549,9 @@ struct BtCursor {
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
#define CURSOR_REQUIRESEEK 2
#define CURSOR_FAULT 3
#define CURSOR_SKIPNEXT 2
#define CURSOR_REQUIRESEEK 3
#define CURSOR_FAULT 4
/*
** The database page the PENDING_BYTE occupies. This page is never used.
+1 -1
View File
@@ -2866,7 +2866,7 @@ Index *sqlite3CreateIndex(
** the zStmt variable
*/
if( pStart ){
int n = (pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
if( pName->z[n-1]==';' ) n--;
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
+3 -2
View File
@@ -114,8 +114,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
p = p->pLeft;
continue;
}
assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
if( op==TK_COLLATE ){
if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
@@ -1279,6 +1278,7 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){
case TK_UMINUS: {
int v;
if( sqlite3ExprIsInteger(p->pLeft, &v) ){
assert( v!=(-2147483647-1) );
*pValue = -v;
rc = 1;
}
@@ -3504,6 +3504,7 @@ static void exprCodeBetween(
compRight.pLeft = &exprX;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
exprX.op2 = exprX.op;
exprX.op = TK_REGISTER;
if( jumpIfTrue ){
sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
+2 -2
View File
@@ -1522,9 +1522,9 @@ static void groupConcatFinalize(sqlite3_context *context){
StrAccum *pAccum;
pAccum = sqlite3_aggregate_context(context, 0);
if( pAccum ){
if( pAccum->tooBig ){
if( pAccum->accError==STRACCUM_TOOBIG ){
sqlite3_result_error_toobig(context);
}else if( pAccum->mallocFailed ){
}else if( pAccum->accError==STRACCUM_NOMEM ){
sqlite3_result_error_nomem(context);
}else{
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
+1 -1
View File
@@ -2461,7 +2461,7 @@ static int openDatabase(
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
+7 -7
View File
@@ -179,7 +179,7 @@ static int sqlite3MemSize(void *p){
return 0;
}
pHdr = sqlite3MemsysGetHeader(p);
return pHdr->iSize;
return (int)pHdr->iSize;
}
/*
@@ -221,7 +221,7 @@ static void randomFill(char *pBuf, int nByte){
x = SQLITE_PTR_TO_INT(pBuf);
y = nByte | 1;
while( nByte >= 4 ){
x = (x>>1) ^ (-(x&1) & 0xd0000001);
x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(int*)pBuf = r;
@@ -229,7 +229,7 @@ static void randomFill(char *pBuf, int nByte){
nByte -= 4;
}
while( nByte-- > 0 ){
x = (x>>1) ^ (-(x&1) & 0xd0000001);
x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(pBuf++) = r & 0xff;
@@ -324,9 +324,9 @@ static void sqlite3MemFree(void *pPrior){
}
z = (char*)pBt;
z -= pHdr->nTitle;
adjustStats(pHdr->iSize, -1);
adjustStats((int)pHdr->iSize, -1);
randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
pHdr->iSize + sizeof(int) + pHdr->nTitle);
(int)pHdr->iSize + sizeof(int) + pHdr->nTitle);
free(z);
sqlite3_mutex_leave(mem.mutex);
}
@@ -350,7 +350,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
if( pNew ){
memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
if( nByte>pOldHdr->iSize ){
randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize);
}
sqlite3MemFree(pPrior);
}
@@ -465,7 +465,7 @@ void sqlite3MemdebugSync(){
for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
void **pBt = (void**)pHdr;
pBt -= pHdr->nBacktraceSlots;
mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
}
}
+2 -2
View File
@@ -69,7 +69,7 @@ struct sqlite3_mutex {
}
return osType==2;
}
#endif /* SQLITE_OS_WINCE */
#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */
#endif
#ifdef SQLITE_DEBUG
@@ -107,7 +107,7 @@ static int winMutex_isInit = 0;
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;
static LONG winMutex_lock = 0;
void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+48 -9
View File
@@ -218,11 +218,13 @@ struct unixFile {
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
#if SQLITE_MAX_MMAP_SIZE>0
int nFetchOut; /* Number of outstanding xFetch refs */
sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */
sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
void *pMapRegion; /* Memory mapped region */
#endif
#ifdef __QNXNTO__
int sectorSize; /* Device sector size */
int deviceCharacteristics; /* Precomputed device characteristics */
@@ -449,6 +451,7 @@ static struct unix_syscall {
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
@@ -461,6 +464,7 @@ static struct unix_syscall {
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
#endif
}; /* End of the overrideable system calls */
@@ -547,6 +551,31 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
return 0;
}
/*
** If fd is a file descriptor that would be dangerous to use for an
** ordinary file, the close it, reopen it as /dev/null to get it out
** of the way, then return true.
**
** If fd is safe, return 0.
**
** It is dangerous to have a database file open of file descriptors 1 or
** 2 because those normally mean standard output and standard error. Other
** components of the system might write directly to those file descriptors
** and overwrite parts of the database file. Something like this happened
** on 2013-08-29 to the canonical Fossil repository when some error caused
** the database file to be opened on file descriptor 2 and later an assert()
** fired and wrote error message text into file descriptor 2, corrupting
** the repository.
*/
static int isReservedFd(int fd, const char *z, int f, int m){
if( fd<0 || fd>2 ) return 0;
sqlite3_log(SQLITE_WARNING,
"attempt to open \"%s\" as file descriptor %d", z, fd);
osClose(fd);
(void)osOpen("/dev/null",f,m);
return 1;
}
/*
** Invoke open(). Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
@@ -573,7 +602,7 @@ static int robust_open(const char *z, int f, mode_t m){
#else
fd = osOpen(z,f,m2);
#endif
}while( fd<0 && errno==EINTR );
}while( (fd<0 && errno==EINTR) || isReservedFd(fd,z,f,m2) );
if( fd>=0 ){
if( m!=0 ){
struct stat statbuf;
@@ -1871,8 +1900,10 @@ static int unixUnlock(sqlite3_file *id, int eFileLock){
return posixUnlock(id, eFileLock, 0);
}
#if SQLITE_MAX_MMAP_SIZE>0
static int unixMapfile(unixFile *pFd, i64 nByte);
static void unixUnmapfile(unixFile *pFd);
#endif
/*
** This function performs the parts of the "close file" operation
@@ -1886,7 +1917,9 @@ static void unixUnmapfile(unixFile *pFd);
*/
static int closeUnixFile(sqlite3_file *id){
unixFile *pFile = (unixFile*)id;
#if SQLITE_MAX_MMAP_SIZE>0
unixUnmapfile(pFile);
#endif
if( pFile->h>=0 ){
robust_close(pFile, pFile->h, __LINE__);
pFile->h = -1;
@@ -3091,6 +3124,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
#endif
TIMER_START;
assert( cnt==(cnt&0x1ffff) );
assert( id->h>2 );
cnt &= 0x1ffff;
do{
#if defined(USE_PREAD)
@@ -3205,6 +3239,7 @@ static int seekAndWriteFd(
int rc = 0; /* Value returned by system call */
assert( nBuf==(nBuf&0x1ffff) );
assert( fd>2 );
nBuf &= 0x1ffff;
TIMER_START;
@@ -3590,6 +3625,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
}
#endif
#if SQLITE_MAX_MMAP_SIZE>0
/* 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.
@@ -3597,6 +3633,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
if( nByte<pFile->mmapSize ){
pFile->mmapSize = nByte;
}
#endif
return SQLITE_OK;
}
@@ -3686,6 +3723,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
}
}
#if SQLITE_MAX_MMAP_SIZE>0
if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
int rc;
if( pFile->szChunk<=0 ){
@@ -3698,6 +3736,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
rc = unixMapfile(pFile, nByte);
return rc;
}
#endif
return SQLITE_OK;
}
@@ -3766,6 +3805,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
int rc = SQLITE_OK;
@@ -3782,6 +3822,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
return rc;
}
#endif
#ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
@@ -4592,22 +4633,20 @@ static int unixShmUnmap(
# define unixShmUnmap 0
#endif /* #ifndef SQLITE_OMIT_WAL */
#if SQLITE_MAX_MMAP_SIZE>0
/*
** If it is currently memory mapped, unmap file pFd.
*/
static void unixUnmapfile(unixFile *pFd){
assert( pFd->nFetchOut==0 );
#if SQLITE_MAX_MMAP_SIZE>0
if( pFd->pMapRegion ){
osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
pFd->pMapRegion = 0;
pFd->mmapSize = 0;
pFd->mmapSizeActual = 0;
}
#endif
}
#if SQLITE_MAX_MMAP_SIZE>0
/*
** Return the system page size.
*/
@@ -4620,9 +4659,7 @@ static int unixGetPagesize(void){
return (int)sysconf(_SC_PAGESIZE);
#endif
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
#if SQLITE_MAX_MMAP_SIZE>0
/*
** Attempt to set the size of the memory mapping maintained by file
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
@@ -4707,7 +4744,6 @@ static void unixRemapfile(
pFd->pMapRegion = (void *)pNew;
pFd->mmapSize = pFd->mmapSizeActual = nNew;
}
#endif
/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
@@ -4726,7 +4762,6 @@ static void unixRemapfile(
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
#if SQLITE_MAX_MMAP_SIZE>0
i64 nMap = nByte;
int rc;
@@ -4752,10 +4787,10 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
unixUnmapfile(pFd);
}
}
#endif
return SQLITE_OK;
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
/*
** If possible, return a pointer to a mapping of file fd starting at offset
@@ -4804,6 +4839,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
UNUSED_PARAMETER(iOff);
#if SQLITE_MAX_MMAP_SIZE>0
/* 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. */
@@ -4819,6 +4855,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
}
assert( pFd->nFetchOut>=0 );
#endif
return SQLITE_OK;
}
@@ -5150,7 +5187,9 @@ static int fillInUnixFile(
pNew->pVfs = pVfs;
pNew->zPath = zFilename;
pNew->ctrlFlags = (u8)ctrlFlags;
#if SQLITE_MAX_MMAP_SIZE>0
pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
"psow", SQLITE_POWERSAFE_OVERWRITE) ){
pNew->ctrlFlags |= UNIXFILE_PSOW;
+271 -150
View File
File diff suppressed because it is too large Load Diff
+65 -46
View File
@@ -453,6 +453,13 @@ struct PagerSavepoint {
#endif
};
/*
** Bits of the Pager.doNotSpill flag. See further description below.
*/
#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */
#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */
#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */
/*
** A open page cache is an instance of struct Pager. A description of
** some of the more important member variables follows:
@@ -519,19 +526,21 @@ struct PagerSavepoint {
** journal file from being successfully finalized, the setMaster flag
** is cleared anyway (and the pager will move to ERROR state).
**
** doNotSpill, doNotSyncSpill
** doNotSpill
**
** 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).
** This 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).
**
** When doNotSpill is non-zero, writing to the database from pagerStress()
** is disabled altogether. This is done in a very obscure case that
** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
** writing to the database from pagerStress() is disabled altogether.
** The SPILLFLAG_ROLLBACK case is done in a very obscure case that
** comes up during savepoint rollback that requires the pcache module
** to allocate a new page to prevent the journal file from being written
** while it is being traversed by code in pager_playback().
** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF
** case is a user preference.
**
** If doNotSyncSpill is non-zero, writing to the database from pagerStress()
** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
** is permitted, but syncing the journal file is not. This flag is set
** by sqlite3PagerWrite() when the file-system sector-size is larger than
** the database page-size in order to prevent a journal sync from happening
@@ -635,7 +644,6 @@ struct Pager {
u8 changeCountDone; /* Set after incrementing the change-counter */
u8 setMaster; /* True if a m-j name has been written to jrnl */
u8 doNotSpill; /* Do not spill the cache when non-zero */
u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */
u8 subjInMemory; /* True to use in-memory sub-journals */
Pgno dbSize; /* Number of pages in the database */
Pgno dbOrigSize; /* dbSize before the current transaction */
@@ -1014,13 +1022,17 @@ static char *print_pager_state(Pager *p){
** PagerSavepoint.pInSavepoint.
*/
static int subjRequiresPage(PgHdr *pPg){
Pgno pgno = pPg->pgno;
Pager *pPager = pPg->pPager;
PagerSavepoint *p;
Pgno pgno;
int i;
for(i=0; i<pPager->nSavepoint; i++){
PagerSavepoint *p = &pPager->aSavepoint[i];
if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
return 1;
if( pPager->nSavepoint ){
pgno = pPg->pgno;
for(i=0; i<pPager->nSavepoint; i++){
p = &pPager->aSavepoint[i];
if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
return 1;
}
}
}
return 0;
@@ -2295,11 +2307,11 @@ static int pager_playback_one_page(
** requiring a journal-sync before it is written.
*/
assert( isSavepnt );
assert( pPager->doNotSpill==0 );
pPager->doNotSpill++;
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
assert( pPager->doNotSpill==1 );
pPager->doNotSpill--;
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
if( rc!=SQLITE_OK ) return rc;
pPg->flags &= ~PGHDR_NEED_READ;
sqlite3PcacheMakeDirty(pPg);
@@ -2866,12 +2878,6 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
assert( pPager->eState>=PAGER_READER && !MEMDB );
assert( isOpen(pPager->fd) );
if( NEVER(!isOpen(pPager->fd)) ){
assert( pPager->tempFile );
memset(pPg->pData, 0, pPager->pageSize);
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_WAL
if( iFrame ){
/* Try to pull the page from the write-ahead log. */
@@ -3404,9 +3410,12 @@ void sqlite3PagerShrink(Pager *pPager){
}
/*
** Adjust the robustness of the database to damage due to OS crashes
** or power failures by changing the number of syncs()s when writing
** the rollback journal. There are three levels:
** Adjust settings of the pager to those specified in the pgFlags parameter.
**
** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
** of the database to damage due to OS crashes or power failures by
** changing the number of syncs()s when writing the journals.
** There are three levels:
**
** OFF sqlite3OsSync() is never called. This is the default
** for temporary and transient files.
@@ -3447,22 +3456,21 @@ void sqlite3PagerShrink(Pager *pPager){
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
void sqlite3PagerSetSafetyLevel(
void sqlite3PagerSetFlags(
Pager *pPager, /* The pager to set safety level for */
int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
int bFullFsync, /* PRAGMA fullfsync */
int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */
unsigned pgFlags /* Various flags */
){
unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
assert( level>=1 && level<=3 );
pPager->noSync = (level==1 || pPager->tempFile) ?1:0;
pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
if( pPager->noSync ){
pPager->syncFlags = 0;
pPager->ckptSyncFlags = 0;
}else if( bFullFsync ){
}else if( pgFlags & PAGER_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_FULL;
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
}else if( bCkptFullFsync ){
}else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_NORMAL;
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
}else{
@@ -3473,6 +3481,11 @@ void sqlite3PagerSetSafetyLevel(
if( pPager->fullSync ){
pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
}
if( pgFlags & PAGER_CACHESPILL ){
pPager->doNotSpill &= ~SPILLFLAG_OFF;
}else{
pPager->doNotSpill |= SPILLFLAG_OFF;
}
}
#endif
@@ -4373,13 +4386,14 @@ static int pagerStress(void *p, PgHdr *pPg){
assert( pPg->pPager==pPager );
assert( pPg->flags&PGHDR_DIRTY );
/* The doNotSyncSpill flag is set during times when doing a sync of
/* The doNotSpill NOSYNC bit is set during times when doing a sync of
** journal (and adding a new header) is not allowed. This occurs
** during calls to sqlite3PagerWrite() while trying to journal multiple
** pages belonging to the same sector.
**
** The doNotSpill flag inhibits all cache spilling regardless of whether
** or not a sync is required. This is set during a rollback.
** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
** regardless of whether or not a sync is required. This is set during
** a rollback or by user request, respectively.
**
** Spilling is also prohibited when in an error state since that could
** lead to database corruption. In the current implementaton it
@@ -4389,8 +4403,13 @@ static int pagerStress(void *p, PgHdr *pPg){
** test for the error state as a safeguard against future changes.
*/
if( NEVER(pPager->errCode) ) return SQLITE_OK;
if( pPager->doNotSpill ) return SQLITE_OK;
if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
testcase( pPager->doNotSpill & SPILLFLAG_OFF );
testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
if( pPager->doNotSpill
&& ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
|| (pPg->flags & PGHDR_NEED_SYNC)!=0)
){
return SQLITE_OK;
}
@@ -5212,19 +5231,19 @@ 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 flags /* PAGER_ACQUIRE_XXX flags */
int flags /* PAGER_GET_XXX flags */
){
int rc = SQLITE_OK;
PgHdr *pPg = 0;
u32 iFrame = 0; /* Frame to read from WAL file */
const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
const int noContent = (flags & PAGER_GET_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))
&& (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
#ifdef SQLITE_HAS_CODEC
&& pPager->xCodec==0
#endif
@@ -5744,13 +5763,13 @@ int sqlite3PagerWrite(DbPage *pDbPage){
int ii; /* Loop counter */
int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
/* Set the doNotSyncSpill flag to 1. This is because we cannot allow
/* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
** a journal header to be written between the pages journaled by
** this function.
*/
assert( !MEMDB );
assert( pPager->doNotSyncSpill==0 );
pPager->doNotSyncSpill++;
assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
pPager->doNotSpill |= SPILLFLAG_NOSYNC;
/* This trick assumes that both the page-size and sector-size are
** an integer power of 2. It sets variable pg1 to the identifier
@@ -5809,8 +5828,8 @@ int sqlite3PagerWrite(DbPage *pDbPage){
}
}
assert( pPager->doNotSyncSpill==1 );
pPager->doNotSyncSpill--;
assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
}else{
rc = pager_write(pDbPage);
}
+15 -3
View File
@@ -81,8 +81,20 @@ typedef struct PgHdr DbPage;
/*
** 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 */
#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
/*
** Flags for sqlite3PagerSetFlags()
*/
#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */
#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */
#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */
#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */
#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */
#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */
#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */
#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */
/*
** The remainder of this file contains the declarations of the functions
@@ -110,7 +122,7 @@ int sqlite3PagerMaxPageCount(Pager*, int);
void sqlite3PagerSetCachesize(Pager*, int);
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
void sqlite3PagerShrink(Pager*);
void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
void sqlite3PagerSetFlags(Pager*,unsigned);
int sqlite3PagerLockingMode(Pager *, int);
int sqlite3PagerSetJournalMode(Pager *, int);
int sqlite3PagerGetJournalMode(Pager*);
+1
View File
@@ -765,6 +765,7 @@ static sqlite3_pcache_page *pcache1Fetch(
if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
goto fetch_out;
}
assert( pCache->nHash>0 && pCache->apHash );
/* Step 4. Try to recycle a page. */
if( pCache->bPurgeable && pGroup->pLruTail && (
+38 -16
View File
@@ -158,6 +158,36 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
}
/*
** Set the safety_level and pager flags for pager iDb. Or if iDb<0
** set these values for all pagers.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
static void setAllPagerFlags(sqlite3 *db){
if( db->autoCommit ){
Db *pDb = db->aDb;
int n = db->nDb;
assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
== PAGER_FLAGS_MASK );
assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
while( (n--) > 0 ){
if( pDb->pBt ){
sqlite3BtreeSetPagerFlags(pDb->pBt,
pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
}
pDb++;
}
}
}
#else
# define setAllPagerFlags(X) /* no-op */
#endif
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
/*
** Check to see if zRight and zLeft refer to a pragma that queries
@@ -176,6 +206,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
{ "legacy_file_format", SQLITE_LegacyFileFmt },
{ "fullfsync", SQLITE_FullFSync },
{ "checkpoint_fullfsync", SQLITE_CkptFullFSync },
{ "cache_spill", SQLITE_CacheSpill },
{ "reverse_unordered_selects", SQLITE_ReverseOrder },
{ "query_only", SQLITE_QueryOnly },
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -630,7 +661,7 @@ void sqlite3Pragma(
Pager *pPager = sqlite3BtreePager(pDb->pBt);
i64 iLimit = -2;
if( zRight ){
sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8);
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
@@ -764,10 +795,11 @@ void sqlite3Pragma(
*/
if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){
sqlite3_int64 sz;
#if SQLITE_MAX_MMAP_SIZE>0
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( zRight ){
int ii;
sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8);
sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8);
if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
if( pId2->n==0 ) db->szMmap = sz;
for(ii=db->nDb-1; ii>=0; ii--){
@@ -778,8 +810,9 @@ void sqlite3Pragma(
}
sz = -1;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
#if SQLITE_MAX_MMAP_SIZE==0
#else
sz = 0;
rc = SQLITE_OK;
#endif
if( rc==SQLITE_OK ){
returnSingleInt(pParse, "mmap_size", sz);
@@ -966,6 +999,7 @@ void sqlite3Pragma(
"Safety level may not be changed inside a transaction");
}else{
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
setAllPagerFlags(db);
}
}
}else
@@ -973,8 +1007,7 @@ void sqlite3Pragma(
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
if( flagPragma(pParse, zLeft, zRight) ){
/* The flagPragma() subroutine also generates any necessary code
** there is nothing more to do here */
setAllPagerFlags(db);
}else
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
@@ -1805,17 +1838,6 @@ void sqlite3Pragma(
{/* Empty ELSE clause */}
/*
** Reset the safety level, in case the fullfsync flag or synchronous
** setting changed.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
if( db->autoCommit ){
sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
(db->flags&SQLITE_FullFSync)!=0,
(db->flags&SQLITE_CkptFullFSync)!=0);
}
#endif
pragma_out:
sqlite3DbFree(db, zLeft);
sqlite3DbFree(db, zRight);
+14 -17
View File
@@ -359,7 +359,7 @@ void sqlite3VXPrintf(
nOut = precision + 10;
zOut = zExtra = sqlite3Malloc( nOut );
if( zOut==0 ){
pAccum->mallocFailed = 1;
pAccum->accError = STRACCUM_NOMEM;
return;
}
}
@@ -471,7 +471,7 @@ void sqlite3VXPrintf(
if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
if( bufpt==0 ){
pAccum->mallocFailed = 1;
pAccum->accError = STRACCUM_NOMEM;
return;
}
}
@@ -606,7 +606,7 @@ void sqlite3VXPrintf(
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
pAccum->mallocFailed = 1;
pAccum->accError = STRACCUM_NOMEM;
return;
}
}else{
@@ -684,22 +684,20 @@ void sqlite3VXPrintf(
*/
void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 || N==0 );
if( p->tooBig | p->mallocFailed ){
testcase(p->tooBig);
testcase(p->mallocFailed);
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return;
}
assert( p->zText!=0 || p->nChar==0 );
if( N<0 ){
if( N<=0 ){
if( N==0 || z[0]==0 ) return;
N = sqlite3Strlen30(z);
}
if( N==0 || NEVER(z==0) ){
return;
}
if( p->nChar+N >= p->nAlloc ){
char *zNew;
if( !p->useMalloc ){
p->tooBig = 1;
p->accError = STRACCUM_TOOBIG;
N = p->nAlloc - p->nChar - 1;
if( N<=0 ){
return;
@@ -710,7 +708,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
p->tooBig = 1;
p->accError = STRACCUM_TOOBIG;
return;
}else{
p->nAlloc = (int)szNew;
@@ -724,7 +722,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
p->mallocFailed = 1;
p->accError = STRACCUM_NOMEM;
sqlite3StrAccumReset(p);
return;
}
@@ -752,7 +750,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
p->mallocFailed = 1;
p->accError = STRACCUM_NOMEM;
}
}
}
@@ -783,8 +781,7 @@ void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
p->nAlloc = n;
p->mxAlloc = mx;
p->useMalloc = 1;
p->tooBig = 0;
p->mallocFailed = 0;
p->accError = 0;
}
/*
@@ -801,7 +798,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
acc.db = db;
sqlite3VXPrintf(&acc, 1, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.mallocFailed ){
if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
}
return z;
+14 -37
View File
@@ -28,24 +28,11 @@ static SQLITE_WSD struct sqlite3PrngType {
} sqlite3Prng;
/*
** Get a single 8-bit random value from the RC4 PRNG. The Mutex
** must be held while executing this routine.
**
** Why not just use a library random generator like lrand48() for this?
** Because the OP_NewRowid opcode in the VDBE depends on having a very
** good source of random numbers. The lrand48() library function may
** well be good enough. But maybe not. Or maybe lrand48() has some
** subtle problems on some systems that could cause problems. It is hard
** to know. To minimize the risk of problems due to bad lrand48()
** implementations, SQLite uses this random number generator based
** on RC4, which we know works very well.
**
** (Later): Actually, OP_NewRowid does not depend on a good source of
** randomness any more. But we will leave this code in all the same.
** Return N random bytes.
*/
static u8 randomByte(void){
void sqlite3_randomness(int N, void *pBuf){
unsigned char t;
unsigned char *zBuf = pBuf;
/* The "wsdPrng" macro will resolve to the pseudo-random number generator
** state vector. If writable static data is unsupported on the target,
@@ -60,6 +47,10 @@ static u8 randomByte(void){
# define wsdPrng sqlite3Prng
#endif
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
sqlite3_mutex_enter(mutex);
#endif
/* Initialize the state of the random number generator once,
** the first time this routine is called. The seed value does
@@ -88,28 +79,14 @@ static u8 randomByte(void){
wsdPrng.isInit = 1;
}
/* Generate and return single random byte
*/
wsdPrng.i++;
t = wsdPrng.s[wsdPrng.i];
wsdPrng.j += t;
wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
wsdPrng.s[wsdPrng.j] = t;
t += wsdPrng.s[wsdPrng.i];
return wsdPrng.s[t];
}
/*
** Return N random bytes.
*/
void sqlite3_randomness(int N, void *pBuf){
unsigned char *zBuf = pBuf;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
#endif
sqlite3_mutex_enter(mutex);
while( N-- ){
*(zBuf++) = randomByte();
wsdPrng.i++;
t = wsdPrng.s[wsdPrng.i];
wsdPrng.j += t;
wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
wsdPrng.s[wsdPrng.j] = t;
t += wsdPrng.s[wsdPrng.i];
*(zBuf++) = wsdPrng.s[t];
}
sqlite3_mutex_leave(mutex);
}
+6 -6
View File
@@ -71,12 +71,12 @@
/* Make sure isatty() has a prototype.
*/
extern int isatty(int);
#endif
/* popen and pclose are not C89 functions and so are sometimes omitted from
** the <stdio.h> header */
FILE *popen(const char*,const char*);
int pclose(FILE*);
extern FILE *popen(const char*,const char*);
extern int pclose(FILE*);
#endif
#if defined(_WIN32_WCE)
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
@@ -554,7 +554,7 @@ static void output_c_string(FILE *out, const char *z){
}else if( c=='\r' ){
fputc('\\', out);
fputc('r', out);
}else if( !isprint(c) ){
}else if( !isprint(c&0xff) ){
fprintf(out, "\\%03o", c&0xff);
}else{
fputc(c, out);
@@ -1717,7 +1717,7 @@ static char *csv_read_one_field(CSVReader *p){
}
if( (c==cSep && pc==cQuote)
|| (c=='\n' && pc==cQuote)
|| (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
|| (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
|| (c==EOF && pc==cQuote)
){
do{ p->n--; }while( p->z[p->n]!=cQuote );
@@ -2902,6 +2902,7 @@ static int process_input(struct callback_data *p, FILE *in){
if( nSql==0 ){
int i;
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
assert( nAlloc>0 && zSql!=0 );
memcpy(zSql, zLine+i, nLine+1-i);
startline = lineno;
nSql = nLine-i;
@@ -3187,7 +3188,6 @@ int main(int argc, char **argv){
stdin_is_interactive = 0;
}else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
int j, c;
const char *zSize;
sqlite3_int64 szHeap;
+47 -28
View File
@@ -568,6 +568,20 @@ extern const int sqlite3one;
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif
/*
** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also
** define SQLITE_ENABLE_STAT3_OR_STAT4
*/
#ifdef SQLITE_ENABLE_STAT4
# undef SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3_OR_STAT4
# undef SQLITE_ENABLE_STAT3_OR_STAT4
#endif
/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
@@ -972,32 +986,33 @@ struct sqlite3 {
*/
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
#define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */
#define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */
#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
/* result set is empty */
#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
#define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
#define SQLITE_DeferFKs 0x00800000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x01000000 /* Disable database changes */
#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
/*
@@ -1549,7 +1564,7 @@ struct Index {
unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
unsigned bUnordered:1; /* Use this index for == or IN queries only */
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
@@ -2420,10 +2435,11 @@ struct StrAccum {
int nChar; /* Length of the string so far */
int nAlloc; /* Amount of space allocated in zText */
int mxAlloc; /* Maximum allowed string length */
u8 mallocFailed; /* Becomes true if any memory allocation fails */
u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
u8 tooBig; /* Becomes true if string size exceeds limits */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
};
#define STRACCUM_NOMEM 1
#define STRACCUM_TOOBIG 2
/*
** A pointer to this structure is used to communicate information
@@ -3054,7 +3070,6 @@ extern int sqlite3PendingByte;
void sqlite3RootPageMoved(sqlite3*, int, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AnalyzeFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
@@ -3105,8 +3120,11 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
void sqlite3BackupRestart(sqlite3_backup *);
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
void sqlite3AnalyzeFunctions(void);
int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
void sqlite3Stat4ProbeFree(UnpackedRecord*);
#endif
/*
** The interface to the LEMON-generated parser
@@ -3149,13 +3167,14 @@ void sqlite3AutoLoadExtensions(sqlite3*);
#else
void sqlite3VtabClear(sqlite3 *db, Table*);
void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
int sqlite3VtabSync(sqlite3 *db, char **);
int sqlite3VtabSync(sqlite3 *db, Vdbe*);
int sqlite3VtabRollback(sqlite3 *db);
int sqlite3VtabCommit(sqlite3 *db);
void sqlite3VtabLock(VTable *);
void sqlite3VtabUnlock(VTable *);
void sqlite3VtabUnlockList(sqlite3*);
int sqlite3VtabSavepoint(sqlite3 *, int, int);
void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
VTable *sqlite3GetVTable(sqlite3*, Table*);
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
+144
View File
@@ -5934,6 +5934,145 @@ static int win32_file_lock(
CloseHandle(ev);
return TCL_OK;
}
/*
** exists_win32_path PATH
**
** Returns non-zero if the specified path exists, whose fully qualified name
** may exceed 260 characters if it is prefixed with "\\?\".
*/
static int win32_exists_path(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "PATH");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
GetFileAttributesW( Tcl_GetUnicode(objv[1]))!=INVALID_FILE_ATTRIBUTES ));
return TCL_OK;
}
/*
** find_win32_file PATTERN
**
** Returns a list of entries in a directory that match the specified pattern,
** whose fully qualified name may exceed 248 characters if it is prefixed with
** "\\?\".
*/
static int win32_find_file(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
HANDLE hFindFile = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAW findData;
Tcl_Obj *listObj;
DWORD lastErrno;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "PATTERN");
return TCL_ERROR;
}
hFindFile = FindFirstFileW(Tcl_GetUnicode(objv[1]), &findData);
if( hFindFile==INVALID_HANDLE_VALUE ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
return TCL_ERROR;
}
listObj = Tcl_NewObj();
Tcl_IncrRefCount(listObj);
do {
Tcl_ListObjAppendElement(interp, listObj, Tcl_NewUnicodeObj(
findData.cFileName, -1));
Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(
findData.dwFileAttributes));
} while( FindNextFileW(hFindFile, &findData) );
lastErrno = GetLastError();
if( lastErrno!=NO_ERROR && lastErrno!=ERROR_NO_MORE_FILES ){
FindClose(hFindFile);
Tcl_DecrRefCount(listObj);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
return TCL_ERROR;
}
FindClose(hFindFile);
Tcl_SetObjResult(interp, listObj);
return TCL_OK;
}
/*
** delete_win32_file FILENAME
**
** Deletes the specified file, whose fully qualified name may exceed 260
** characters if it is prefixed with "\\?\".
*/
static int win32_delete_file(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
return TCL_ERROR;
}
if( !DeleteFileW(Tcl_GetUnicode(objv[1])) ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
return TCL_ERROR;
}
Tcl_ResetResult(interp);
return TCL_OK;
}
/*
** make_win32_dir DIRECTORY
**
** Creates the specified directory, whose fully qualified name may exceed 248
** characters if it is prefixed with "\\?\".
*/
static int win32_mkdir(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
return TCL_ERROR;
}
if( !CreateDirectoryW(Tcl_GetUnicode(objv[1]), NULL) ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
return TCL_ERROR;
}
Tcl_ResetResult(interp);
return TCL_OK;
}
/*
** remove_win32_dir DIRECTORY
**
** Removes the specified directory, whose fully qualified name may exceed 248
** characters if it is prefixed with "\\?\".
*/
static int win32_rmdir(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
return TCL_ERROR;
}
if( !RemoveDirectoryW(Tcl_GetUnicode(objv[1])) ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
return TCL_ERROR;
}
Tcl_ResetResult(interp);
return TCL_OK;
}
#endif
@@ -6193,6 +6332,11 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "optimization_control", optimization_control,0},
#if SQLITE_OS_WIN
{ "lock_win32_file", win32_file_lock, 0 },
{ "exists_win32_path", win32_exists_path, 0 },
{ "find_win32_file", win32_find_file, 0 },
{ "delete_win32_file", win32_delete_file, 0 },
{ "make_win32_dir", win32_mkdir, 0 },
{ "remove_win32_dir", win32_rmdir, 0 },
#endif
{ "tcl_objproc", runAsObjProc, 0 },
+1 -1
View File
@@ -749,7 +749,7 @@ static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
int isNew;
int aKey[MALLOC_LOG_KEYINTS];
int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
unsigned int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
memset(aKey, 0, nKey);
if( (sizeof(void*)*nFrame)<nKey ){
+25 -39
View File
@@ -497,19 +497,6 @@ static int checkSavepointCount(sqlite3 *db){
}
#endif
/*
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
** in memory obtained from sqlite3DbMalloc).
*/
static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
sqlite3 *db = p->db;
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
}
/*
** Execute as much of a VDBE program as we can then return.
@@ -588,7 +575,7 @@ int sqlite3VdbeExec(
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){
assert( 0 < db->nProgressOps );
nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1];
nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
if( nProgressLimit==0 ){
nProgressLimit = db->nProgressOps;
}else{
@@ -1449,7 +1436,7 @@ case OP_Function: {
sqlite3VdbeMemMove(&ctx.s, pOut);
MemSetTypeFlag(&ctx.s, MEM_Null);
ctx.isError = 0;
ctx.fErrorOrAux = 0;
if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
@@ -1460,11 +1447,6 @@ case OP_Function: {
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
/* If any auxiliary data functions have been called by this user function,
** immediately call the destructor for any non-static values.
*/
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
** user function may have called an sqlite3_result_XXX() function
@@ -1476,9 +1458,12 @@ case OP_Function: {
}
/* If the function returned an error, throw an exception */
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
rc = ctx.isError;
if( ctx.fErrorOrAux ){
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
rc = ctx.isError;
}
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
}
/* Copy the result of the function into register P3 */
@@ -1850,12 +1835,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
*/
if( pOp->p5 & SQLITE_STOREP2 ){
if( pOp->p5 & SQLITE_JUMPIFNULL ){
pc = pOp->p2-1;
}else if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else if( pOp->p5 & SQLITE_JUMPIFNULL ){
pc = pOp->p2-1;
}
break;
}
@@ -4352,7 +4337,7 @@ case OP_Rowid: { /* out2-prerelease */
pModule = pVtab->pModule;
assert( pModule->xRowid );
rc = pModule->xRowid(pC->pVtabCursor, &v);
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
assert( pC->pCursor!=0 );
@@ -4440,7 +4425,7 @@ case OP_Sort: { /* jump */
sqlite3_sort_count++;
sqlite3_search_count--;
#endif
p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
p->aCounter[SQLITE_STMTSTATUS_SORT]++;
/* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
@@ -4519,7 +4504,7 @@ case OP_Next: { /* jump */
int res;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p5<=ArraySize(p->aCounter) );
assert( pOp->p5<ArraySize(p->aCounter) );
pC = p->apCsr[pOp->p1];
if( pC==0 ){
break; /* See ticket #2273 */
@@ -4529,7 +4514,7 @@ case OP_Next: { /* jump */
assert( pOp->opcode==OP_SorterNext );
rc = sqlite3VdbeSorterNext(db, pC, &res);
}else{
res = 1;
/* res = 1; // Always initialized by the xAdvance() call */
assert( pC->deferredMoveto==0 );
assert( pC->pCursor );
assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
@@ -4540,7 +4525,7 @@ case OP_Next: { /* jump */
pC->cacheStatus = CACHE_STALE;
if( res==0 ){
pc = pOp->p2 - 1;
if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
@@ -5746,7 +5731,7 @@ case OP_VBegin: {
VTable *pVTab;
pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVTab);
if( pVTab ) importVtabErrMsg(p, pVTab->pVtab);
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -5797,7 +5782,7 @@ case OP_VOpen: {
pModule = (sqlite3_module *)pVtab->pModule;
assert(pVtab && pModule);
rc = pModule->xOpen(pVtab, &pVtabCursor);
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
pVtabCursor->pVtab = pVtab;
@@ -5875,7 +5860,7 @@ case OP_VFilter: { /* jump */
p->inVtabMethod = 1;
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
p->inVtabMethod = 0;
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pVtabCursor);
}
@@ -5926,7 +5911,7 @@ case OP_VColumn: {
MemSetTypeFlag(&sContext.s, MEM_Null);
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
if( sContext.isError ){
rc = sContext.isError;
}
@@ -5979,7 +5964,7 @@ case OP_VNext: { /* jump */
p->inVtabMethod = 1;
rc = pModule->xNext(pCur->pVtabCursor);
p->inVtabMethod = 0;
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pCur->pVtabCursor);
}
@@ -6016,7 +6001,7 @@ case OP_VRename: {
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
if( rc==SQLITE_OK ){
rc = pVtab->pModule->xRename(pVtab, pName->z);
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
}
break;
@@ -6078,7 +6063,7 @@ case OP_VUpdate: {
db->vtabOnConflict = pOp->p5;
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
db->vtabOnConflict = vtabOnConflict;
importVtabErrMsg(p, pVtab);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
db->lastRowid = lastRowid = rowid;
@@ -6243,7 +6228,8 @@ vdbe_error_halt:
** top. */
vdbe_return:
db->lastRowid = lastRowid;
p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1] += (int)nVmStep;
testcase( nVmStep>0 );
p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
return rc;
+5 -4
View File
@@ -266,10 +266,11 @@ struct sqlite3_context {
Mem s; /* The return value is stored here */
Mem *pMem; /* Memory cell used to store aggregate context */
CollSeq *pColl; /* Collating sequence */
int isError; /* Error code returned by the function. */
int skipFlag; /* Skip skip accumulator loading if true */
int iOp; /* Instruction number of OP_Function */
Vdbe *pVdbe; /* The VM that owns this context */
int iOp; /* Instruction number of OP_Function */
int isError; /* Error code returned by the function. */
u8 skipFlag; /* Skip skip accumulator loading if true */
u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
};
/*
@@ -345,7 +346,7 @@ struct Vdbe {
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
int iStatement; /* Statement number (or 0 if has not opened stmt) */
int aCounter[4]; /* Counters used by sqlite3_stmt_status() */
u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
+12 -3
View File
@@ -211,12 +211,14 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
@@ -280,6 +282,7 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
}
void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
if( pCtx->s.flags & MEM_Null ){
sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
@@ -290,6 +293,7 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
@@ -299,6 +303,7 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
sqlite3VdbeMemSetNull(&pCtx->s);
pCtx->isError = SQLITE_NOMEM;
pCtx->fErrorOrAux = 1;
pCtx->s.db->mallocFailed = 1;
}
@@ -621,6 +626,10 @@ void sqlite3_set_auxdata(
pAuxData->iArg = iArg;
pAuxData->pNext = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
if( pCtx->fErrorOrAux==0 ){
pCtx->isError = 0;
pCtx->fErrorOrAux = 1;
}
}else if( pAuxData->xDelete ){
pAuxData->xDelete(pAuxData->pAux);
}
@@ -1289,7 +1298,7 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
*/
int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
int v = pVdbe->aCounter[op-1];
if( resetFlag ) pVdbe->aCounter[op-1] = 0;
return v;
u32 v = pVdbe->aCounter[op];
if( resetFlag ) pVdbe->aCounter[op] = 0;
return (int)v;
}
+16 -1
View File
@@ -1765,7 +1765,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** required, as an xSync() callback may add an attached database
** to the transaction.
*/
rc = sqlite3VtabSync(db, &p->zErrMsg);
rc = sqlite3VtabSync(db, p);
/* This loop determines (a) if the commit hook should be invoked and
** (b) how many database files have open write transactions, not
@@ -3304,3 +3304,18 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
v->expmask |= ((u32)1 << (iVar-1));
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
** in memory obtained from sqlite3DbMalloc).
*/
void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
sqlite3 *db = p->db;
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+26 -27
View File
@@ -799,34 +799,29 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
** if both values are integers.
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
if( !(f1&(MEM_Int|MEM_Real)) ){
return 1;
}
if( !(f2&(MEM_Int|MEM_Real)) ){
return -1;
}
if( (f1 & f2 & MEM_Int)==0 ){
double r1, r2;
if( (f1&MEM_Real)==0 ){
r1 = (double)pMem1->u.i;
}else{
r1 = pMem1->r;
}
if( (f2&MEM_Real)==0 ){
r2 = (double)pMem2->u.i;
}else{
r2 = pMem2->r;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
}else{
assert( f1&MEM_Int );
assert( f2&MEM_Int );
double r1, r2;
if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
return 0;
}
if( (f1&MEM_Real)!=0 ){
r1 = pMem1->r;
}else if( (f1&MEM_Int)!=0 ){
r1 = (double)pMem1->u.i;
}else{
return 1;
}
if( (f2&MEM_Real)!=0 ){
r2 = pMem2->r;
}else if( (f2&MEM_Int)!=0 ){
r2 = (double)pMem2->u.i;
}else{
return -1;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
}
/* If one value is a string and the other is a blob, the string is less.
@@ -1028,7 +1023,7 @@ struct ValueNewStat4Ctx {
** an sqlite3_value within the UnpackedRecord.a[] array.
*/
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( p ){
UnpackedRecord *pRec = p->ppRec[0];
@@ -1103,7 +1098,7 @@ int valueFromExpr(
** The ifdef here is to enable us to achieve 100% branch test coverage even
** when SQLITE_ENABLE_STAT4 is omitted.
*/
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( op==TK_REGISTER ) op = pExpr->op2;
#else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
@@ -1185,7 +1180,11 @@ no_mem:
db->mallocFailed = 1;
sqlite3DbFree(db, zVal);
assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pCtx==0 ) sqlite3ValueFree(pVal);
#else
assert( pCtx==0 ); sqlite3ValueFree(pVal);
#endif
return SQLITE_NOMEM;
}
@@ -1209,7 +1208,7 @@ int sqlite3ValueFromExpr(
return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
}
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** The implementation of the sqlite_record() function. This function accepts
** a single argument of any type. The return value is a formatted database
+3 -6
View File
@@ -810,10 +810,9 @@ static void callFinaliser(sqlite3 *db, int offset){
** array. Return the error code for the first error that occurs, or
** SQLITE_OK if all xSync operations are successful.
**
** Set *pzErrmsg to point to a buffer that should be released using
** sqlite3DbFree() containing an error message, if one is available.
** If an error message is available, leave it in p->zErrMsg.
*/
int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
int i;
int rc = SQLITE_OK;
VTable **aVTrans = db->aVTrans;
@@ -824,9 +823,7 @@ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
rc = x(pVtab);
sqlite3DbFree(db, *pzErrmsg);
*pzErrmsg = pVtab->zErrMsg;
pVtab->zErrMsg = 0;
sqlite3VtabImportErrmsg(p, pVtab);
}
}
db->aVTrans = aVTrans;
+52 -32
View File
@@ -90,6 +90,7 @@ struct WhereLevel {
int addrNxt; /* Jump here to start the next IN combination */
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to ends the loop */
@@ -285,7 +286,7 @@ struct WhereTerm {
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
#else
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
@@ -391,7 +392,7 @@ struct WhereLoopBuilder {
ExprList *pOrderBy; /* ORDER BY clause */
WhereLoop *pNew; /* Template WhereLoop */
WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */
#endif
@@ -1208,8 +1209,10 @@ static int isMatchOfColumn(
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
pDerived->flags |= pBase->flags & EP_FromJoin;
pDerived->iRightJoinTable = pBase->iRightJoinTable;
if( pDerived ){
pDerived->flags |= pBase->flags & EP_FromJoin;
pDerived->iRightJoinTable = pBase->iRightJoinTable;
}
}
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -1666,6 +1669,7 @@ static void exprAnalyze(
pNewExpr = sqlite3PExpr(pParse, ops[i],
sqlite3ExprDup(db, pExpr->pLeft, 0),
sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
transferJoinMarkings(pNewExpr, pExpr);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
@@ -1733,6 +1737,7 @@ static void exprAnalyze(
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
pStr1, 0);
transferJoinMarkings(pNewExpr1, pExpr);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
@@ -1740,6 +1745,7 @@ static void exprAnalyze(
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
pStr2, 0);
transferJoinMarkings(pNewExpr2, pExpr);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2);
@@ -1789,7 +1795,7 @@ static void exprAnalyze(
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* When sqlite_stat3 histogram data is available an operator of the
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
@@ -1829,7 +1835,7 @@ static void exprAnalyze(
pNewTerm->prereqAll = pTerm->prereqAll;
}
}
#endif /* SQLITE_ENABLE_STAT */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join.
@@ -2397,7 +2403,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
** index. Store the results in aStat as follows:
@@ -2484,7 +2490,7 @@ static void whereKeyStats(
aStat[0] = iLower + iGap;
}
}
#endif /* SQLITE_ENABLE_STAT4 */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** This function is used to estimate the number of rows that will be visited
@@ -2536,7 +2542,7 @@ static int whereRangeScanEst(
int rc = SQLITE_OK;
int nOut = (int)*pnOut;
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
Index *p = pBuilder->pNew->u.btree.pIndex;
int nEq = pBuilder->pNew->u.btree.nEq;
@@ -2644,7 +2650,7 @@ static int whereRangeScanEst(
return rc;
}
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
@@ -2708,9 +2714,9 @@ static int whereEqualScanEst(
return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT4) */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
@@ -2756,7 +2762,7 @@ static int whereInScanEst(
assert( pBuilder->nRecValid==nRecValid );
return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT4) */
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** Disable a term in the WHERE clause. Except, do not disable the term
@@ -2994,7 +3000,7 @@ static int codeAllEqualityTerms(
/* Evaluate the equality constraints
*/
assert( pIdx->nColumn>=nEq );
assert( zAff==0 || (int)strlen(zAff)>=nEq );
for(j=0; j<nEq; j++){
int r1;
pTerm = pLoop->aLTerm[j];
@@ -3086,7 +3092,8 @@ static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
txt.db = db;
sqlite3StrAccumAppend(&txt, " (", 2);
for(i=0; i<nEq; i++){
explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
char *z = (i==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[i]].zName;
explainAppendTerm(&txt, i, z, "=");
}
j = i;
@@ -4300,13 +4307,14 @@ static int whereLoopAddBtreeIndex(
rLogSize = estLog(whereCost(pProbe->aiRowEst[0]));
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0;
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nRecValid = pBuilder->nRecValid;
assert( pNew->nOut==saved_nOut );
if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){
continue; /* skip IS NOT NULL constraints on a NOT NULL column */
}
#endif
if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
&& (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
){
continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
}
if( pTerm->prereqRight & pNew->maskSelf ) continue;
assert( pNew->nOut==saved_nOut );
@@ -4370,7 +4378,7 @@ static int whereLoopAddBtreeIndex(
assert( pNew->nOut==saved_nOut );
whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut);
}
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( nInMul==0
&& pProbe->nSample
&& pNew->u.btree.nEq<=pProbe->nSampleCol
@@ -4408,7 +4416,7 @@ static int whereLoopAddBtreeIndex(
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
}
pNew->nOut = saved_nOut;
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
pBuilder->nRecValid = nRecValid;
#endif
}
@@ -4459,6 +4467,7 @@ static Bitmask columnsInIndex(Index *pIdx){
int j;
for(j=pIdx->nColumn-1; j>=0; j--){
int x = pIdx->aiColumn[j];
assert( x>=0 );
testcase( x==BMS-1 );
testcase( x==BMS-2 );
if( x<BMS-1 ) m |= MASKBIT(x);
@@ -4537,6 +4546,7 @@ static int whereLoopAddBtree(
rSize = whereCost(pSrc->pTab->nRowEst);
rLogSize = estLog(rSize);
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/* Automatic indexes */
if( !pBuilder->pOrSet
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
@@ -4571,6 +4581,7 @@ static int whereLoopAddBtree(
}
}
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
/* Loop over all indices
*/
@@ -4639,7 +4650,7 @@ static int whereLoopAddBtree(
}
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec);
pBuilder->nRecValid = 0;
pBuilder->pRec = 0;
@@ -4840,6 +4851,7 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
pWCEnd = pWC->a + pWC->nTerm;
pNew = pBuilder->pNew;
memset(&sSum, 0, sizeof(sSum));
for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
if( (pTerm->eOperator & WO_OR)!=0
@@ -5525,11 +5537,15 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
pLoop->rRun = 33; /* 33==whereCost(10) */
}else{
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None || pIdx->pPartIdxWhere!=0 ) continue;
assert( pLoop->aLTermSpace==pLoop->aLTerm );
assert( ArraySize(pLoop->aLTermSpace)==4 );
if( pIdx->onError==OE_None
|| pIdx->pPartIdxWhere!=0
|| pIdx->nColumn>ArraySize(pLoop->aLTermSpace)
) continue;
for(j=0; j<pIdx->nColumn; j++){
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
if( pTerm==0 ) break;
whereLoopResize(pWInfo->pParse->db, pLoop, j);
pLoop->aLTerm[j] = pTerm;
}
if( j!=pIdx->nColumn ) continue;
@@ -5966,11 +5982,6 @@ WhereInfo *sqlite3WhereBegin(
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
}else
#endif
if( pLoop->wsFlags & WHERE_INDEXED ){
Index *pIx = pLoop->u.btree.pIndex;
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
@@ -5995,7 +6006,15 @@ WhereInfo *sqlite3WhereBegin(
notReady = ~(Bitmask)0;
for(ii=0; ii<nTabList; ii++){
pLevel = &pWInfo->a[ii];
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
constructAutomaticIndex(pParse, &pWInfo->sWC,
&pTabList->a[pLevel->iFrom], notReady, pLevel);
if( db->mallocFailed ) goto whereBeginError;
}
#endif
explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
notReady = codeOneLoopStart(pWInfo, ii, notReady);
pWInfo->iContinue = pLevel->addrCont;
}
@@ -6115,9 +6134,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
int k, j, last;
VdbeOp *pOp;
pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
last = sqlite3VdbeCurrentAddr(v);
for(k=pWInfo->iTop; k<last; k++, pOp++){
k = pLevel->addrBody;
pOp = sqlite3VdbeGetOp(v, k);
for(; k<last; k++, pOp++){
if( pOp->p1!=pLevel->iTabCur ) continue;
if( pOp->opcode==OP_Column ){
for(j=0; j<pIdx->nColumn; j++){
+28
View File
@@ -17,6 +17,8 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix collate2
#
# Tests are organised as follows:
#
@@ -693,4 +695,30 @@ do_test collate2-5.5 {
}
} {aa aa}
do_execsql_test 6.1 {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('b');
INSERT INTO t1 VALUES('B');
}
do_execsql_test 6.2 {
SELECT * FROM t1 WHERE x COLLATE nocase BETWEEN 'a' AND 'c';
} {b B}
do_execsql_test 6.3 {
SELECT * FROM t1 WHERE x BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
} {b B}
do_execsql_test 6.4 {
SELECT * FROM t1
WHERE x COLLATE nocase BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
} {b B}
do_execsql_test 6.5 {
SELECT * FROM t1 WHERE +x COLLATE nocase BETWEEN 'a' AND 'c';
} {b B}
do_execsql_test 6.6 {
SELECT * FROM t1 WHERE +x BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
} {b B}
do_execsql_test 6.7 {
SELECT * FROM t1
WHERE +x COLLATE nocase BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
} {b B}
finish_test
+4 -2
View File
@@ -31,9 +31,11 @@ do_execsql_test 1.1 {
CREATE INDEX t1abc ON t1(a,b,c);
}
set idxroot [db one {SELECT rootpage FROM sqlite_master WHERE name = 't1abc'}]
# Corrupt the file
db close
hexio_write test.db [expr {3*512 - 15}] 888080807f
hexio_write test.db [expr {$idxroot*512 - 15}] 888080807f
sqlite3 db test.db
# Try to use the file.
@@ -58,7 +60,7 @@ do_test 1.4 {
# such that the payload begins in allocated space but overflows the buffer.
#
db close
hexio_write test.db [expr {3*512-15}] 0513ff7f01
hexio_write test.db [expr {$idxroot*512-15}] 0513ff7f01
sqlite3 db test.db
do_test 2.1 {
+2 -2
View File
@@ -191,8 +191,8 @@ do_insert_tests e_insert-1.3 {
3b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {2 x y}
}
# EVIDENCE-OF: R-44710-64652 If a column-list is specified, then the
# number of values in each term of the VALUS list must match the number
# EVIDENCE-OF: R-09234-17933 If a column-list is specified, then the
# number of values in each term of the VALUE list must match the number
# of specified columns.
#
do_insert_tests e_insert-1.4 -error {
+7
View File
@@ -426,4 +426,11 @@ do_execsql_test 8.3 {
{0 3 2 0 3 2 1 4 3} {1 3 2 1 3 2 1 4 3} {2 3 2 2 3 2 2 4 3}
}
do_execsql_test 9.1 {
CREATE VIRTUAL TABLE ft2 USING fts4;
INSERT INTO ft2 VALUES('a b c d e');
INSERT INTO ft2 VALUES('f a b c d');
SELECT snippet(ft2, '[', ']', '', -1, 1) FROM ft2 WHERE ft2 MATCH 'c';
} {{[c]} {[c]}}
finish_test
+5
View File
@@ -16,6 +16,11 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !vtab {
finish_test
return
}
load_static_extension db wholenumber;
do_test index6-1.1 {
# Able to parse and manage partial indices
+47
View File
@@ -13,6 +13,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix indexedby
# Create a schema with some indexes.
#
@@ -274,4 +275,50 @@ do_test indexedby-10.3 {
}
} {1}
#-------------------------------------------------------------------------
# Ensure that the rowid at the end of each index entry may be used
# for equality constraints in the same way as other indexed fields.
#
do_execsql_test 11.1 {
CREATE TABLE x1(a, b TEXT);
CREATE INDEX x1i ON x1(a, b);
INSERT INTO x1 VALUES(1, 1);
INSERT INTO x1 VALUES(1, 1);
INSERT INTO x1 VALUES(1, 1);
INSERT INTO x1 VALUES(1, 1);
}
do_execsql_test 11.2 {
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid=3;
} {1 1 3}
do_execsql_test 11.3 {
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3';
} {1 1 3}
do_execsql_test 11.4 {
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
} {1 1 3}
do_eqp_test 11.5 {
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
} {0 0 0 {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}}
do_execsql_test 11.6 {
CREATE TABLE x2(c INTEGER PRIMARY KEY, a, b TEXT);
CREATE INDEX x2i ON x2(a, b);
INSERT INTO x2 VALUES(1, 1, 1);
INSERT INTO x2 VALUES(2, 1, 1);
INSERT INTO x2 VALUES(3, 1, 1);
INSERT INTO x2 VALUES(4, 1, 1);
}
do_execsql_test 11.7 {
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c=3;
} {1 1 3}
do_execsql_test 11.8 {
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3';
} {1 1 3}
do_execsql_test 11.9 {
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
} {1 1 3}
do_eqp_test 11.10 {
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
} {0 0 0 {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}}
finish_test
+2
View File
@@ -205,6 +205,7 @@ do_test malloc5-4.1 {
execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');"
}
execsql {COMMIT;}
db cache flush
sqlite3_release_memory
sqlite3_memory_highwater 1
execsql {SELECT * FROM abc}
@@ -213,6 +214,7 @@ do_test malloc5-4.1 {
expr $nMaxBytes > 1000000
} {1}
do_test malloc5-4.2 {
db cache flush
sqlite3_release_memory
sqlite3_soft_heap_limit 100000
sqlite3_memory_highwater 1
+27 -1
View File
@@ -93,6 +93,14 @@ set FAULTSIM(cantopen-persistent) [list \
-injectuninstall cantopen_injectuninstall \
]
set FAULTSIM(interrupt) [list \
-injectinstall interrupt_injectinstall \
-injectstart interrupt_injectstart \
-injectstop interrupt_injectstop \
-injecterrlist {{1 interrupted} {1 interrupt}} \
-injectuninstall interrupt_injectuninstall \
]
#--------------------------------------------------------------------------
@@ -113,7 +121,9 @@ set FAULTSIM(cantopen-persistent) [list \
proc do_faultsim_test {name args} {
global FAULTSIM
set DEFAULT(-faults) [array names FAULTSIM]
foreach n [array names FAULTSIM] {
if {$n != "interrupt"} {lappend DEFAULT(-faults) $n}
}
set DEFAULT(-prep) ""
set DEFAULT(-body) ""
set DEFAULT(-test) ""
@@ -255,6 +265,22 @@ proc cantopen_injectstop {} {
shmfault cantopen
}
# The following procs are used as [do_one_faultsim_test] callbacks
# when injecting SQLITE_INTERRUPT error faults into test cases.
#
proc interrupt_injectinstall {} {
}
proc interrupt_injectuninstall {} {
}
proc interrupt_injectstart {iFail} {
set ::sqlite_interrupt_count $iFail
}
proc interrupt_injectstop {} {
set res [expr $::sqlite_interrupt_count<=0]
set ::sqlite_interrupt_count 0
set res
}
# This command is not called directly. It is used by the
# [faultsim_test_result] command created by [do_faultsim_test] and used
# by -test scripts.
+79
View File
@@ -22,6 +22,7 @@ source $testdir/tester.tcl
# pragma2-1.*: Test freelist_count pragma on the main database.
# pragma2-2.*: Test freelist_count pragma on an attached database.
# pragma2-3.*: Test trying to write to the freelist_count is a no-op.
# pragma2-4.*: Tests for PRAGMA cache_spill
#
ifcapable !pragma||!schema_pragmas {
@@ -116,4 +117,82 @@ ifcapable attach {
} {9 9}
}
# Default setting of PRAGMA cache_spill is always ON
#
db close
delete_file test.db test.db-journal
delete_file test2.db test2.db-journal
sqlite3 db test.db
do_execsql_test pragma2-4.1 {
PRAGMA cache_spill;
PRAGMA main.cache_spill;
PRAGMA temp.cache_spill;
} {1 1 1}
do_execsql_test pragma2-4.2 {
PRAGMA cache_spill=OFF;
PRAGMA cache_spill;
PRAGMA main.cache_spill;
PRAGMA temp.cache_spill;
} {0 0 0}
do_execsql_test pragma2-4.3 {
PRAGMA page_size=1024;
PRAGMA cache_size=50;
BEGIN;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
INSERT INTO t1 VALUES(1, randomblob(400), 1, randomblob(400));
INSERT INTO t1 SELECT a+1, randomblob(400), a+1, randomblob(400) FROM t1;
INSERT INTO t1 SELECT a+2, randomblob(400), a+2, randomblob(400) FROM t1;
INSERT INTO t1 SELECT a+4, randomblob(400), a+4, randomblob(400) FROM t1;
INSERT INTO t1 SELECT a+8, randomblob(400), a+8, randomblob(400) FROM t1;
INSERT INTO t1 SELECT a+16, randomblob(400), a+16, randomblob(400) FROM t1;
INSERT INTO t1 SELECT a+32, randomblob(400), a+32, randomblob(400) FROM t1;
INSERT INTO t1 SELECT a+64, randomblob(400), a+64, randomblob(400) FROM t1;
COMMIT;
ATTACH 'test2.db' AS aux1;
CREATE TABLE aux1.t2(a INTEGER PRIMARY KEY, b, c, d);
INSERT INTO t2 SELECT * FROM t1;
DETACH aux1;
PRAGMA cache_spill=ON;
} {}
sqlite3_release_memory
do_test pragma2-4.4 {
db eval {
BEGIN;
UPDATE t1 SET c=c+1;
PRAGMA lock_status;
}
} {main exclusive temp unknown} ;# EXCLUSIVE lock due to cache spill
do_test pragma2-4.5 {
db eval {
COMMIT;
PRAGMA cache_spill=OFF;
BEGIN;
UPDATE t1 SET c=c-1;
PRAGMA lock_status;
}
} {main reserved temp unknown} ;# No cache spill, so no exclusive lock
# Verify that newly attached databases inherit the cache_spill=OFF
# setting.
#
do_execsql_test pragma2-4.6 {
COMMIT;
ATTACH 'test2.db' AS aux1;
PRAGMA aux1.cache_size=50;
BEGIN;
UPDATE t2 SET c=c+1;
PRAGMA lock_status;
} {main unlocked temp unknown aux1 reserved}
do_execsql_test pragma2-4.7 {
COMMIT;
}
sqlite3_release_memory
do_execsql_test pragma2-4.8 {
PRAGMA cache_spill=ON; -- Applies to all databases
BEGIN;
UPDATE t2 SET c=c-1;
PRAGMA lock_status;
} {main unlocked temp unknown aux1 exclusive}
finish_test
+2
View File
@@ -164,10 +164,12 @@ do_test progress-1.7 {
}
set ::res [list]
explain {SELECT a, b, c FROM abc}
db eval {SELECT a, b, c FROM abc} {
lappend ::res $a $b $c
db progress 5 "expr 1"
catch {db eval {SELECT a, b, c FROM abc} { }} msg
db progress 5 "expr 0"
lappend ::res $msg
}
+26
View File
@@ -242,4 +242,30 @@ SELECT * FROM t1;}
5,"this is 5"}}
}
# Import columns containing quoted strings
do_test shell5-1.9 {
set out [open shell5.csv w]
puts $out {1,"",11}
puts $out {2,"x",22}
puts $out {3,"""",33}
puts $out {4,"hello",44}
puts $out "5,55,\"\"\r"
puts $out {6,66,"x"}
puts $out {7,77,""""}
puts $out {8,88,"hello"}
puts $out {"",9,99}
puts $out {"x",10,110}
puts $out {"""",11,121}
puts $out {"hello",12,132}
close $out
file delete -force test.db
catchcmd test.db {.mode csv
CREATE TABLE t1(a,b,c);
.import shell5.csv t1
}
sqlite3 db test.db
db eval {SELECT *, '|' FROM t1 ORDER BY rowid}
} {1 {} 11 | 2 x 22 | 3 {"} 33 | 4 hello 44 | 5 55 {} | 6 66 x | 7 77 {"} | 8 88 hello | {} 9 99 | x 10 110 | {"} 11 121 | hello 12 132 |}
db close
finish_test
+104 -34
View File
@@ -14,7 +14,7 @@
# $Id: tester.tcl,v 1.143 2009/04/09 01:23:49 drh Exp $
#-------------------------------------------------------------------------
# The commands provided by the code in this file to help with creating
# The commands provided by the code in this file to help with creating
# test cases are as follows:
#
# Commands to manipulate the db and the file-system at a high level:
@@ -42,6 +42,7 @@
#
# Commands to execute/explain SQL statements:
#
# memdbsql SQL
# stepsql DB SQL
# execsql2 SQL
# explain_no_trace SQL
@@ -80,7 +81,7 @@
# presql
#
# Set the precision of FP arithmatic used by the interpreter. And
# Set the precision of FP arithmatic used by the interpreter. And
# configure SQLite to take database file locks on the page that begins
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
@@ -90,7 +91,7 @@ set tcl_precision 15
sqlite3_test_control_pending_byte 0x0010000
# If the pager codec is available, create a wrapper for the [sqlite3]
# If the pager codec is available, create a wrapper for the [sqlite3]
# command that appends "-key {xyzzy}" to the command line. i.e. this:
#
# sqlite3 db test.db
@@ -122,7 +123,7 @@ if {[info command sqlite_orig]==""} {
}
set res
} else {
# This command is not opening a new database connection. Pass the
# This command is not opening a new database connection. Pass the
# arguments through to the C implementation as the are.
#
uplevel 1 sqlite_orig $args
@@ -291,6 +292,66 @@ proc do_delete_file {force args} {
}
}
if {$::tcl_platform(platform) eq "windows"} {
proc do_remove_win32_dir {args} {
set nRetry [getFileRetries] ;# Maximum number of retries.
set nDelay [getFileRetryDelay] ;# Delay in ms before retrying.
foreach dirName $args {
# On windows, sometimes even a [remove_win32_dir] can fail just after
# a directory is emptied. The cause is usually "tag-alongs" - programs
# like anti-virus software, automatic backup tools and various explorer
# extensions that keep a file open a little longer than we expect,
# causing the delete to fail.
#
# The solution is to wait a short amount of time before retrying the
# removal.
#
if {$nRetry > 0} {
for {set i 0} {$i < $nRetry} {incr i} {
set rc [catch {
remove_win32_dir $dirName
} msg]
if {$rc == 0} break
if {$nDelay > 0} { after $nDelay }
}
if {$rc} { error $msg }
} else {
remove_win32_dir $dirName
}
}
}
proc do_delete_win32_file {args} {
set nRetry [getFileRetries] ;# Maximum number of retries.
set nDelay [getFileRetryDelay] ;# Delay in ms before retrying.
foreach fileName $args {
# On windows, sometimes even a [delete_win32_file] can fail just after
# a file is closed. The cause is usually "tag-alongs" - programs like
# anti-virus software, automatic backup tools and various explorer
# extensions that keep a file open a little longer than we expect,
# causing the delete to fail.
#
# The solution is to wait a short amount of time before retrying the
# delete.
#
if {$nRetry > 0} {
for {set i 0} {$i < $nRetry} {incr i} {
set rc [catch {
delete_win32_file $fileName
} msg]
if {$rc == 0} break
if {$nDelay > 0} { after $nDelay }
}
if {$rc} { error $msg }
} else {
delete_win32_file $fileName
}
}
}
}
proc execpresql {handle args} {
trace remove execution $handle enter [list execpresql $handle]
if {[info exists ::G(perm:presql)]} {
@@ -312,8 +373,8 @@ proc do_not_use_codec {} {
#
if {[info exists cmdlinearg]==0} {
# Parse any options specified in the $argv array. This script accepts the
# following options:
# Parse any options specified in the $argv array. This script accepts the
# following options:
#
# --pause
# --soft-heap-limit=NN
@@ -342,7 +403,7 @@ if {[info exists cmdlinearg]==0} {
foreach a $argv {
switch -regexp -- $a {
{^-+pause$} {
# Wait for user input before continuing. This is to give the user an
# Wait for user input before continuing. This is to give the user an
# opportunity to connect profiling tools to the process.
puts -nonewline "Press RETURN to begin..."
flush stdout
@@ -405,8 +466,8 @@ if {[info exists cmdlinearg]==0} {
# Install the malloc layer used to inject OOM errors. And the 'automatic'
# extensions. This only needs to be done once for the process.
#
sqlite3_shutdown
install_malloc_faultsim 1
sqlite3_shutdown
install_malloc_faultsim 1
sqlite3_initialize
autoinstall_test_functions
@@ -516,7 +577,7 @@ proc incr_ntest {} {
}
# Invoke the do_test procedure to run a single test
# Invoke the do_test procedure to run a single test
#
proc do_test {name cmd expected} {
global argv cmdlinearg
@@ -525,7 +586,7 @@ proc do_test {name cmd expected} {
sqlite3_memdebug_settitle $name
# if {[llength $argv]==0} {
# if {[llength $argv]==0} {
# set go 1
# } else {
# set go 0
@@ -628,13 +689,13 @@ proc do_realnum_test {name cmd expected} {
proc fix_testname {varname} {
upvar $varname testname
if {[info exists ::testprefix]
if {[info exists ::testprefix]
&& [string is digit [string range $testname 0 0]]
} {
set testname "${::testprefix}-$testname"
}
}
proc do_execsql_test {testname sql {result {}}} {
fix_testname testname
uplevel do_test [list $testname] [list "execsql {$sql}"] [list [list {*}$result]]
@@ -720,7 +781,7 @@ proc delete_all_data {} {
}
}
# Run an SQL script.
# Run an SQL script.
# Return the number of microseconds per statement.
#
proc speed_trial {name numstmt units sql} {
@@ -984,6 +1045,15 @@ proc execsql2 {sql} {
return $result
}
# Use a temporary in-memory database to execute SQL statements
#
proc memdbsql {sql} {
sqlite3 memdb :memory:
set result [memdb eval $sql]
memdb close
return $result
}
# Use the non-callback API to execute multiple SQL statements
#
proc stepsql {dbptr sql} {
@@ -1098,7 +1168,7 @@ proc crashsql {args} {
set crashfile ""
set dc ""
set sql [lindex $args end]
for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
set z [lindex $args $ii]
set n [string length $z]
@@ -1117,7 +1187,7 @@ proc crashsql {args} {
error "Compulsory option -file missing"
}
# $crashfile gets compared to the native filename in
# $crashfile gets compared to the native filename in
# cfSync(), which can be different then what TCL uses by
# default, so here we force it to the "nativename" format.
set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]
@@ -1152,7 +1222,7 @@ proc crashsql {args} {
set r [catch {
exec [info nameofexec] crash.tcl >@stdout
} msg]
# Windows/ActiveState TCL returns a slightly different
# error message. We map that to the expected message
# so that we don't have to change all of the test
@@ -1162,7 +1232,7 @@ proc crashsql {args} {
set msg "child process exited abnormally"
}
}
lappend r $msg
}
@@ -1188,7 +1258,7 @@ proc run_ioerr_prep {} {
# Usage: do_ioerr_test <test number> <options...>
#
# This proc is used to implement test cases that check that IO errors
# are correctly handled. The first argument, <test number>, is an integer
# are correctly handled. The first argument, <test number>, is an integer
# used to name the tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
@@ -1217,7 +1287,7 @@ proc do_ioerr_test {testname args} {
# TEMPORARY: For 3.5.9, disable testing of extended result codes. There are
# a couple of obscure IO errors that do not return them.
set ::ioerropts(-erc) 0
# Create a single TCL script from the TCL and SQL specified
# as the body of the test.
set ::ioerrorbody {}
@@ -1241,7 +1311,7 @@ proc do_ioerr_test {testname args} {
set ::TN $n
incr ::ioerropts(-count) -1
if {$::ioerropts(-count)<0} break
# Skip this IO error if it was specified with the "-exclude" option.
if {[info exists ::ioerropts(-exclude)]} {
if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue
@@ -1250,7 +1320,7 @@ proc do_ioerr_test {testname args} {
restore_prng_state
}
# Delete the files test.db and test2.db, then execute the TCL and
# Delete the files test.db and test2.db, then execute the TCL and
# SQL (in that order) to prepare for the test case.
do_test $testname.$n.1 {
run_ioerr_prep
@@ -1268,7 +1338,7 @@ proc do_ioerr_test {testname args} {
}] $n
# Execute the TCL script created for the body of this test. If
# at least N IO operations performed by SQLite as a result of
# at least N IO operations performed by SQLite as a result of
# the script, the Nth will fail.
do_test $testname.$n.3 {
set ::sqlite_io_error_hit 0
@@ -1322,12 +1392,12 @@ proc do_ioerr_test {testname args} {
set ::sqlite_io_error_hit 0
set ::sqlite_io_error_pending 0
# Check that no page references were leaked. There should be
# a single reference if there is still an active transaction,
# Check that no page references were leaked. There should be
# a single reference if there is still an active transaction,
# or zero otherwise.
#
# UPDATE: If the IO error occurs after a 'BEGIN' but before any
# locks are established on database files (i.e. if the error
# locks are established on database files (i.e. if the error
# occurs while attempting to detect a hot-journal file), then
# there may 0 page references and an active transaction according
# to [sqlite3_get_autocommit].
@@ -1343,7 +1413,7 @@ proc do_ioerr_test {testname args} {
} {1}
}
# If there is an open database handle and no open transaction,
# If there is an open database handle and no open transaction,
# and the pager is not running in exclusive-locking mode,
# check that the pager is in "unlocked" state. Theoretically,
# if a call to xUnlock() failed due to an IO error the underlying
@@ -1447,7 +1517,7 @@ proc allcksum {{db db}} {
}
# Generate a checksum based on the contents of a single database with
# a database connection. The name of the database is $dbname.
# a database connection. The name of the database is $dbname.
# Examples of $dbname are "temp" or "main".
#
proc dbcksum {db dbname} {
@@ -1541,8 +1611,8 @@ proc drop_all_tables {{db db}} {
#-------------------------------------------------------------------------
# If a test script is executed with global variable $::G(perm:name) set to
# "wal", then the tests are run in WAL mode. Otherwise, they should be run
# in rollback mode. The following Tcl procs are used to make this less
# "wal", then the tests are run in WAL mode. Otherwise, they should be run
# in rollback mode. The following Tcl procs are used to make this less
# intrusive:
#
# wal_set_journal_mode ?DB?
@@ -1557,9 +1627,9 @@ proc drop_all_tables {{db db}} {
# Otherwise (if not running a WAL permutation) this is a no-op.
#
# wal_is_wal_mode
#
#
# Returns true if this test should be run in WAL mode. False otherwise.
#
#
proc wal_is_wal_mode {} {
expr {[permutation] eq "wal"}
}
@@ -1660,10 +1730,10 @@ proc slave_test_file {zFile} {
}
set ::sqlite_open_file_count 0
# Test that the global "shared-cache" setting was not altered by
# Test that the global "shared-cache" setting was not altered by
# the test script.
#
ifcapable shared_cache {
ifcapable shared_cache {
set res [expr {[sqlite3_enable_shared_cache] == $scs}]
do_test ${tail}-sharedcachesetting [list set {} $res] 1
}
+79
View File
@@ -0,0 +1,79 @@
# 2013 August 29
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix tkt-9f2eb3abac
do_execsql_test 1.1 {
CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,d,e));
SELECT * FROM t1 WHERE a=? AND b=? AND c=? AND d=? AND e=?;
} {}
do_execsql_test 1.2 {
CREATE TABLE "a" (
"b" integer NOT NULL,
"c" integer NOT NULL,
PRIMARY KEY ("b", "c")
);
CREATE TABLE "d" (
"e" integer NOT NULL,
"g" integer NOT NULL,
"f" integer NOT NULL,
"h" integer NOT NULL,
"i" character(10) NOT NULL,
"j" int,
PRIMARY KEY ("e", "g", "f", "h")
);
CREATE TABLE "d_to_a" (
"f_e" integer NOT NULL,
"f_g" integer NOT NULL,
"f_f" integer NOT NULL,
"f_h" integer NOT NULL,
"t_b" integer NOT NULL,
"t_c" integer NOT NULL,
"r" character NOT NULL,
"s" integer,
PRIMARY KEY ("f_e", "f_g", "f_f", "f_h", "t_b", "t_c")
);
INSERT INTO d (g, e, h, f, j, i) VALUES ( 1, 1, 1, 1, 1, 1 );
INSERT INTO a (b, c) VALUES ( 1, 1 );
INSERT INTO d_to_a VALUES (1, 1, 1, 1, 1, 1, 1, 1);
DELETE FROM d_to_a
WHERE f_g = 1 AND f_e = 1 AND f_h = 1 AND f_f = 1 AND t_b = 1 AND t_c = 1;
SELECT * FROM d_to_a;
} {}
faultsim_delete_and_reopen
do_execsql_test 2.0 { CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,d,e)) }
do_execsql_test 2.1 { CREATE TABLE t2(x) }
faultsim_save_and_close
do_faultsim_test 3 -faults oom* -prep {
faultsim_restore_and_reopen
execsql { SELECT 1 FROM sqlite_master }
} -body {
execsql { SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=? AND e=? }
} -test {
faultsim_test_result {0 {}}
}
finish_test
+2
View File
@@ -701,6 +701,7 @@ do_test where2-11.4 {
# Verify that the OR clause is used in an outer loop even when
# the OR clause scores slightly better on an inner loop.
if {[permutation] != "no_optimization"} {
do_execsql_test where2-12.1 {
CREATE TABLE t12(x INTEGER PRIMARY KEY, y);
CREATE INDEX t12y ON t12(y);
@@ -709,6 +710,7 @@ do_execsql_test where2-12.1 {
FROM t12 AS a JOIN t12 AS b ON a.y=b.x
WHERE (b.x=$abc OR b.y=$abc);
} {/.*SEARCH TABLE t12 AS b .*SEARCH TABLE t12 AS b .*/}
}
finish_test
+6
View File
@@ -246,6 +246,12 @@ do_execsql_test where3-3.1 {
0 0 1 {SCAN TABLE t302}
0 1 0 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
}
do_execsql_test where3-3.2 {
SELECT * FROM t301 WHERE c=3 AND a IS NULL;
} {}
do_execsql_test where3-3.3 {
SELECT * FROM t301 WHERE c=3 AND a IS NOT NULL;
} {1 2 3}
if 0 { # Query planner no longer does this
# Verify that when there are multiple tables in a join which must be
+24
View File
@@ -956,4 +956,28 @@ do_test where9-9.1 {
}
} {1 2 3 4 8 9}
# Fix for ticket [bc878246eafe0f52c519e29049b2fe4a99491b27]
# Incorrect result when OR is used in a join to the right of a LEFT JOIN
#
do_test where9-10.1 {
db eval {
CREATE TABLE t101 (id INTEGER PRIMARY KEY);
INSERT INTO t101 VALUES (1);
SELECT * FROM t101 AS t0
LEFT JOIN t101 AS t1 ON t1.id BETWEEN 10 AND 20
JOIN t101 AS t2 ON (t2.id = t0.id OR (t2.id<>555 AND t2.id=t1.id));
}
} {1 {} 1}
do_test where9-10.2 {
db eval {
CREATE TABLE t102 (id TEXT UNIQUE NOT NULL);
INSERT INTO t102 VALUES ('1');
SELECT * FROM t102 AS t0
LEFT JOIN t102 AS t1 ON t1.id GLOB 'abc%'
JOIN t102 AS t2 ON (t2.id = t0.id OR (t2.id<>555 AND t2.id=t1.id));
}
} {1 {} 1}
finish_test
+6
View File
@@ -68,6 +68,12 @@ do_test whereA-1.7 {
SELECT * FROM t1;
}
} {3 4.53 {} 2 hello world 1 2 3}
do_execsql_test whereA-1.8 {
SELECT * FROM t1 WHERE b=2 AND a IS NULL;
} {}
do_execsql_test whereA-1.9 {
SELECT * FROM t1 WHERE b=2 AND a IS NOT NULL;
} {1 2 3}
do_test whereA-2.1 {
db eval {
-4
View File
@@ -42,10 +42,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# TODO: Reenable this test.
finish_test
return
ifcapable !stat3 {
finish_test
return
+102
View File
@@ -0,0 +1,102 @@
# 2013 August 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the file name handling provided
# by the "win32-longpath" VFS.
#
if {$tcl_platform(platform)!="windows"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix win32longpath
db close
set path [file nativename [get_pwd]]
sqlite3 db [file join $path test.db] -vfs win32-longpath
do_test 1.1 {
db eval {
BEGIN EXCLUSIVE;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(4);
SELECT x FROM t1 ORDER BY x;
COMMIT;
}
} {1 2 3 4}
set longPath(1) \\\\?\\$path\\[pid]
make_win32_dir $longPath(1)
set longPath(2) $longPath(1)\\[string repeat X 255]
make_win32_dir $longPath(2)
set longPath(3) $longPath(2)\\[string repeat Y 255]
make_win32_dir $longPath(3)
set fileName $longPath(3)\\test.db
do_test 1.2 {
list [catch {sqlite3 db2 [string range $fileName 4 end]} msg] $msg
} {1 {unable to open database file}}
sqlite3 db3 $fileName -vfs win32-longpath
do_test 1.3 {
db3 eval {
BEGIN EXCLUSIVE;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(5);
INSERT INTO t1 VALUES(6);
INSERT INTO t1 VALUES(7);
INSERT INTO t1 VALUES(8);
SELECT x FROM t1 ORDER BY x;
COMMIT;
}
} {5 6 7 8}
db3 close
# puts " Database exists \{[exists_win32_path $fileName]\}"
sqlite3 db3 $fileName -vfs win32-longpath
do_test 1.4 {
db3 eval {
PRAGMA journal_mode = WAL;
}
} {wal}
do_test 1.5 {
db3 eval {
BEGIN EXCLUSIVE;
INSERT INTO t1 VALUES(9);
INSERT INTO t1 VALUES(10);
INSERT INTO t1 VALUES(11);
INSERT INTO t1 VALUES(12);
SELECT x FROM t1 ORDER BY x;
COMMIT;
}
} {5 6 7 8 9 10 11 12}
db3 close
# puts " Database exists \{[exists_win32_path $fileName]\}"
do_delete_win32_file $fileName
# puts " Files remaining \{[find_win32_file $longPath(3)\\*]\}"
do_remove_win32_dir $longPath(3)
do_remove_win32_dir $longPath(2)
do_remove_win32_dir $longPath(1)
finish_test
+14 -1
View File
@@ -23,6 +23,16 @@ set -u
TMPSPACE=./mkpkg_tmp_dir
VERSION=`cat $TOP/VERSION`
# Set global variable $ARTIFACT to the "3xxyyzz" string incorporated
# into artifact filenames. And $VERSION2 to the "3.x.y[.z]" form.
xx=`echo $VERSION|sed 's/3\.\([0-9]*\)\..*/\1/'`
yy=`echo $VERSION|sed 's/3\.[^.]*\.\([0-9]*\).*/\1/'`
zz=0
set +e
zz=`echo $VERSION|sed 's/3\.[^.]*\.[^.]*\.\([0-9]*\).*/\1/'|grep -v '\.'`
set -e
ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz`
rm -rf $TMPSPACE
cp -R $TOP/autoconf $TMPSPACE
@@ -66,5 +76,8 @@ rm -rf autom4te.cache
cd ../
./configure && make dist
mv sqlite-$VERSION.tar.gz ../sqlite-amalgamation-$VERSION.tar.gz
tar -xzf sqlite-$VERSION.tar.gz
mv sqlite-$VERSION sqlite-autoconf-$ARTIFACT
tar -czf sqlite-autoconf-$ARTIFACT.tar.gz sqlite-autoconf-$ARTIFACT
mv sqlite-autoconf-$ARTIFACT.tar.gz ..