Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f533dbea5f |
+7
-83
@@ -15,22 +15,18 @@
|
||||
# The toplevel directory of the source tree. This is the directory
|
||||
# that contains this "Makefile.in" and the "configure.in" script.
|
||||
#
|
||||
TOP = @abs_srcdir@
|
||||
TOP = @srcdir@
|
||||
|
||||
# C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
BCC = @BUILD_CC@ @BUILD_CFLAGS@
|
||||
|
||||
# TCC is the C Compile and options for use in building executables that
|
||||
# C Compile and options for use in building executables that
|
||||
# will run on the target platform. (BCC and TCC are usually the
|
||||
# same unless your are cross-compiling.) Separate CC and CFLAGS macros
|
||||
# are provide so that these aspects of the build process can be changed
|
||||
# on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined"
|
||||
# same unless your are cross-compiling.)
|
||||
#
|
||||
CC = @CC@
|
||||
CFLAGS = @CPPFLAGS@ @CFLAGS@
|
||||
TCC = $(CC) $(CFLAGS) -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/fts3
|
||||
TCC = @CC@ @CPPFLAGS@ @CFLAGS@ -I. -I${TOP}/src -I${TOP}/ext/rtree
|
||||
|
||||
# Define this for the autoconf-based build, so that the code knows it can
|
||||
# include the generated config.h
|
||||
@@ -41,7 +37,7 @@ TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
|
||||
# Omitting the define will cause extra debugging code to be inserted and
|
||||
# includes extra comments when "EXPLAIN stmt" is used.
|
||||
#
|
||||
TCC += @TARGET_DEBUG@
|
||||
TCC += @TARGET_DEBUG@ @XTHREADCONNECT@
|
||||
|
||||
# Compiler options needed for programs that use the TCL library.
|
||||
#
|
||||
@@ -234,7 +230,6 @@ SRC = \
|
||||
$(TOP)/src/mem3.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/memjournal.c \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.c \
|
||||
$(TOP)/src/mutex.h \
|
||||
$(TOP)/src/mutex_noop.c \
|
||||
@@ -255,7 +250,6 @@ SRC = \
|
||||
$(TOP)/src/pcache.h \
|
||||
$(TOP)/src/pcache1.c \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/pragma.h \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
$(TOP)/src/random.c \
|
||||
@@ -287,7 +281,6 @@ SRC = \
|
||||
$(TOP)/src/vdbetrace.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/wal.c \
|
||||
$(TOP)/src/wal.h \
|
||||
$(TOP)/src/walker.c \
|
||||
@@ -366,7 +359,6 @@ TESTSRC = \
|
||||
$(TOP)/src/test_autoext.c \
|
||||
$(TOP)/src/test_async.c \
|
||||
$(TOP)/src/test_backup.c \
|
||||
$(TOP)/src/test_blob.c \
|
||||
$(TOP)/src/test_btree.c \
|
||||
$(TOP)/src/test_config.c \
|
||||
$(TOP)/src/test_demovfs.c \
|
||||
@@ -402,7 +394,6 @@ TESTSRC = \
|
||||
TESTSRC += \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/fuzzer.c \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
@@ -466,7 +457,6 @@ HDR = \
|
||||
$(TOP)/src/hash.h \
|
||||
$(TOP)/src/hwtime.h \
|
||||
keywordhash.h \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.h \
|
||||
opcodes.h \
|
||||
$(TOP)/src/os.h \
|
||||
@@ -476,14 +466,12 @@ HDR = \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/pcache.h \
|
||||
parse.h \
|
||||
$(TOP)/src/pragma.h \
|
||||
sqlite3.h \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/sqliteLimit.h \
|
||||
$(TOP)/src/vdbe.h \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/whereInt.h \
|
||||
config.h
|
||||
|
||||
@@ -540,19 +528,6 @@ mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
|
||||
MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
|
||||
mptest: mptester$(EXE)
|
||||
rm -f mptest.db
|
||||
$(MPTEST1) --journalmode DELETE
|
||||
$(MPTEST2) --journalmode WAL
|
||||
$(MPTEST1) --journalmode WAL
|
||||
$(MPTEST2) --journalmode PERSIST
|
||||
$(MPTEST1) --journalmode PERSIST
|
||||
$(MPTEST2) --journalmode TRUNCATE
|
||||
$(MPTEST1) --journalmode TRUNCATE
|
||||
$(MPTEST2) --journalmode DELETE
|
||||
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
@@ -944,37 +919,19 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
|
||||
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
||||
|
||||
# A very detailed test running most or all test cases
|
||||
|
||||
fulltest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test
|
||||
|
||||
# Really really long testing
|
||||
soaktest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
|
||||
|
||||
# Do extra testing but not aeverything.
|
||||
fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/full.test
|
||||
|
||||
# This is the common case. Run many tests but not those that take
|
||||
# a really long time.
|
||||
#
|
||||
test: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind
|
||||
|
||||
# A very fast test that checks basic sanity. The name comes from
|
||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||
# comes out."
|
||||
#
|
||||
smoketest: testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
echo "#define TCLSH 2" > $@
|
||||
cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@
|
||||
@@ -1007,42 +964,9 @@ LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h
|
||||
wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.c
|
||||
$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.c $(TLIBS)
|
||||
|
||||
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.lo
|
||||
speedtest1$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS)
|
||||
|
||||
# This target will fail if the SQLite amalgamation contains any exported
|
||||
# symbols that do not begin with "sqlite3_". It is run as part of the
|
||||
# releasetest.tcl script.
|
||||
#
|
||||
checksymbols: sqlite3.lo
|
||||
nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0
|
||||
echo '0 errors out of 1 tests'
|
||||
|
||||
# Build the amalgamation-autoconf package.
|
||||
#
|
||||
amalgamation-tarball: sqlite3.c
|
||||
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh
|
||||
|
||||
# The next two rules are used to support the "threadtest" target. Building
|
||||
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||
# target is invoked by the releasetest.tcl script.
|
||||
#
|
||||
THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
|
||||
$(TOP)/test/tt3_checkpoint.c \
|
||||
$(TOP)/test/tt3_index.c \
|
||||
$(TOP)/test/tt3_vacuum.c \
|
||||
$(TOP)/test/tt3_stress.c \
|
||||
$(TOP)/test/tt3_lookaside1.c
|
||||
|
||||
threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
|
||||
$(LTLINK) $(TOP)/test/threadtest3.c sqlite3.lo -o $@ $(TLIBS)
|
||||
|
||||
threadtest: threadtest3$(TEXE)
|
||||
./threadtest3$(TEXE)
|
||||
|
||||
releasetest:
|
||||
$(TCLSH_CMD) $(TOP)/test/releasetest.tcl
|
||||
|
||||
# Standard install and cleanup targets
|
||||
#
|
||||
lib_install: libsqlite3.la
|
||||
|
||||
+183
-358
File diff suppressed because it is too large
Load Diff
@@ -253,7 +253,6 @@ SRC = \
|
||||
$(TOP)/src/mem3.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/memjournal.c \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.c \
|
||||
$(TOP)/src/mutex.h \
|
||||
$(TOP)/src/mutex_noop.c \
|
||||
@@ -415,7 +414,6 @@ HDR = \
|
||||
$(TOP)/src/hash.h \
|
||||
$(TOP)/src/hwtime.h \
|
||||
keywordhash.h \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.h \
|
||||
opcodes.h \
|
||||
$(TOP)/src/os.h \
|
||||
|
||||
@@ -53,10 +53,10 @@ to the "sqlite3.dll" command line above. When debugging into the SQLite
|
||||
code, adding the "DEBUG=1" argument to one of the above command lines is
|
||||
recommended.
|
||||
|
||||
SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation
|
||||
is required by the makefiles (including those for MSVC). SQLite contains
|
||||
a lot of generated code and Tcl is used to do much of that code generation.
|
||||
The makefiles also require AWK.
|
||||
SQLite does not require Tcl to run, but a Tcl installation is required
|
||||
by the makefiles (including those for MSVC). SQLite contains a lot of
|
||||
generated code and Tcl is used to do much of that code generation. The
|
||||
makefiles also require AWK.
|
||||
|
||||
## Source Code Tour
|
||||
|
||||
@@ -95,14 +95,14 @@ manually-edited files and automatically-generated files.
|
||||
|
||||
The SQLite interface is defined by the **sqlite3.h** header file, which is
|
||||
generated from src/sqlite.h.in, ./manifest.uuid, and ./VERSION. The
|
||||
[Tcl script](http://www.tcl.tk) at tool/mksqlite3h.tcl does the conversion.
|
||||
The manifest.uuid file contains the SHA1 hash of the particular check-in
|
||||
and is used to generate the SQLITE\_SOURCE\_ID macro. The VERSION file
|
||||
contains the current SQLite version number. The sqlite3.h header is really
|
||||
just a copy of src/sqlite.h.in with the source-id and version number inserted
|
||||
at just the right spots. Note that comment text in the sqlite3.h file is
|
||||
used to generate much of the SQLite API documentation. The Tcl scripts
|
||||
used to generate that documentation are in a separate source repository.
|
||||
Tcl script at tool/mksqlite3h.tcl does the conversion. The manifest.uuid
|
||||
file contains the SHA1 hash of the particular check-in and is used to generate
|
||||
the SQLITE_SOURCE_ID macro. The VERSION file contains the current SQLite
|
||||
version number. The sqlite3.h header is really just a copy of src/sqlite.h.in
|
||||
with the source-id and version number inserted at just the right spots.
|
||||
Note that comment text in the sqlite3.h file is used to generate much of
|
||||
the SQLite API documentation. The Tcl scripts used to generate that
|
||||
documentation are in a separate source repository.
|
||||
|
||||
The SQL language parser is **parse.c** which is generate from a grammar in
|
||||
the src/parse.y file. The conversion of "parse.y" into "parse.c" is done
|
||||
|
||||
+54
-8
@@ -1,11 +1,57 @@
|
||||
This directory contains components use to build an autoconf-ready package
|
||||
of the SQLite amalgamation: sqlite-autoconf-30XXXXXX.tar.gz
|
||||
|
||||
To build the autoconf amalgamation, run from the top-level:
|
||||
This file describes how to use the files in this directory to create a new
|
||||
version of the "autoconf-amalgamation" package.
|
||||
|
||||
1. The following files should have executable permission:
|
||||
|
||||
chmod 755 install-sh
|
||||
chmod 755 missing
|
||||
chmod 755 depcomp
|
||||
chmod 755 config.sub
|
||||
chmod 755 config.guess
|
||||
|
||||
2. Copy new versions of the following SQLite files into this directory:
|
||||
|
||||
sqlite3.c
|
||||
sqlite3.h
|
||||
sqlite3ext.h
|
||||
sqlite3.1
|
||||
sqlite3.pc.in
|
||||
shell.c
|
||||
|
||||
3. Update the SQLite version number in the AC_INIT macro in file
|
||||
configure.ac:
|
||||
|
||||
AC_INIT(sqlite, 3.6.3, http://www.sqlite.org)
|
||||
|
||||
4. Run the following commands to push the version number change through
|
||||
to the generated files.
|
||||
|
||||
aclocal
|
||||
autoconf
|
||||
automake
|
||||
|
||||
5. Create the tclsqlite3.c file in the tea/generic directory. As follows:
|
||||
|
||||
mkdir -p tea/generic
|
||||
echo "#ifdef USE_SYSTEM_SQLITE" > tea/generic/tclsqlite3.c
|
||||
echo "# include <sqlite3.h>" >> tea/generic/tclsqlite3.c
|
||||
echo "#else" >> tea/generic/tclsqlite3.c
|
||||
echo "#include \"../../sqlite3.c\"" >> tea/generic/tclsqlite3.c
|
||||
echo "#endif" >> tea/generic/tclsqlite3.c
|
||||
cat ../src/tclsqlite.c >> tea/generic/tclsqlite3.c
|
||||
|
||||
6. Update the SQLite version in the AC_INIT macro in file tea/configure.in:
|
||||
|
||||
AC_INIT([sqlite], [3.6.3])
|
||||
|
||||
7. From the 'tea' directory, run the following commands:
|
||||
|
||||
autoconf
|
||||
rm -rf autom4te.cache
|
||||
|
||||
8. Run "./configure && make dist". This builds a distribution package
|
||||
named something like "sqlite-3.6.3.tar.gz". Rename to
|
||||
"sqlite-amalgamation-3.6.3.tar.gz" and use.
|
||||
|
||||
./configure
|
||||
make amalgamation-tarball
|
||||
|
||||
The amalgamation-tarball target (also available in "main.mk") runs the
|
||||
script tool/mkautoconfamal.sh which does the work. Refer to that script
|
||||
for details.
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `isnan' function. */
|
||||
#undef HAVE_ISNAN
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
@@ -51,9 +48,6 @@
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the strchrnul() function */
|
||||
#undef HAVE_STRCHRNUL
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
|
||||
@@ -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.9.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.7.
|
||||
#
|
||||
# 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.9'
|
||||
PACKAGE_STRING='sqlite 3.8.9'
|
||||
PACKAGE_VERSION='3.8.7'
|
||||
PACKAGE_STRING='sqlite 3.8.7'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@@ -868,6 +868,7 @@ RELEASE
|
||||
VERSION_NUMBER
|
||||
BUILD_CC
|
||||
SQLITE_THREADSAFE
|
||||
XTHREADCONNECT
|
||||
ALLOWRELEASE
|
||||
TEMP_STORE
|
||||
BUILD_EXEEXT
|
||||
@@ -905,7 +906,9 @@ enable_fast_install
|
||||
with_gnu_ld
|
||||
enable_libtool_lock
|
||||
enable_largefile
|
||||
with_hints
|
||||
enable_threadsafe
|
||||
enable_cross_thread_connections
|
||||
enable_releasemode
|
||||
enable_tempstore
|
||||
enable_tcl
|
||||
@@ -1480,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.9 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.8.7 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1545,7 +1548,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.9:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.7:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1559,7 +1562,9 @@ Optional Features:
|
||||
optimize for fast installation [default=yes]
|
||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--disable-largefile omit support for large files
|
||||
--disable-threadsafe Disable mutexing
|
||||
--enable-threadsafe Support threadsafe operation
|
||||
--enable-cross-thread-connections
|
||||
Allow connection sharing across threads
|
||||
--enable-releasemode Support libtool link to release mode
|
||||
--enable-tempstore Use an in-ram database for temporary tables
|
||||
(never,no,yes,always)
|
||||
@@ -1568,8 +1573,7 @@ Optional Features:
|
||||
--enable-debug enable debugging & verbose explain
|
||||
--disable-amalgamation Disable the amalgamation and instead build all files
|
||||
separately
|
||||
--disable-load-extension
|
||||
Disable loading of external extensions
|
||||
--enable-load-extension Enable loading of external extensions
|
||||
--enable-gcov Enable coverage testing using gcov
|
||||
|
||||
Optional Packages:
|
||||
@@ -1578,6 +1582,7 @@ Optional Packages:
|
||||
--with-pic try to use only PIC/non-PIC objects [default=use
|
||||
both]
|
||||
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
|
||||
--with-hints=FILE Read configuration options from FILE
|
||||
--with-tcl=DIR directory containing tcl configuration
|
||||
(tclConfig.sh)
|
||||
--with-readline-lib specify readline library
|
||||
@@ -1659,7 +1664,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.8.9
|
||||
sqlite configure 3.8.7
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
@@ -1673,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.9, which was
|
||||
It was created by sqlite $as_me 3.8.7, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2053,6 +2058,9 @@ please regen with autoconf" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
# The following RCS revision string applies to configure.in
|
||||
# $Revision: 1.56 $
|
||||
|
||||
#########
|
||||
# Programs needed
|
||||
#
|
||||
@@ -3724,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:3727: $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:3730: $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:3733: 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"
|
||||
@@ -4952,7 +4960,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 4955 "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=$?
|
||||
@@ -6821,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:6824: $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:6828: \$? = $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.
|
||||
@@ -7160,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:7163: $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:7167: \$? = $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.
|
||||
@@ -7265,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:7268: $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:7272: \$? = $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
|
||||
@@ -7320,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:7323: $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:7327: \$? = $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
|
||||
@@ -10133,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 10136 "configure"
|
||||
#line 10144 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -10229,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 10232 "configure"
|
||||
#line 10240 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -12138,9 +12146,7 @@ done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime
|
||||
for ac_func in usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size
|
||||
do
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
@@ -12336,6 +12342,45 @@ VERSION_NUMBER=`cat $srcdir/VERSION \
|
||||
$as_echo "$as_me: Version number set to $VERSION_NUMBER" >&6;}
|
||||
|
||||
|
||||
#########
|
||||
# Check to see if the --with-hints=FILE option is used. If there is none,
|
||||
# then check for a files named "$host.hints" and ../$hosts.hints where
|
||||
# $host is the hostname of the build system. If still no hints are
|
||||
# found, try looking in $system.hints and ../$system.hints where
|
||||
# $system is the result of uname -s.
|
||||
#
|
||||
|
||||
# Check whether --with-hints was given.
|
||||
if test "${with_hints+set}" = set; then
|
||||
withval=$with_hints; hints=$withval
|
||||
fi
|
||||
|
||||
if test "$hints" = ""; then
|
||||
host=`hostname | sed 's/\..*//'`
|
||||
if test -r $host.hints; then
|
||||
hints=$host.hints
|
||||
else
|
||||
if test -r ../$host.hints; then
|
||||
hints=../$host.hints
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$hints" = ""; then
|
||||
sys=`uname -s`
|
||||
if test -r $sys.hints; then
|
||||
hints=$sys.hints
|
||||
else
|
||||
if test -r ../$sys.hints; then
|
||||
hints=../$sys.hints
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$hints" != ""; then
|
||||
{ $as_echo "$as_me:$LINENO: result: reading hints from $hints" >&5
|
||||
$as_echo "reading hints from $hints" >&6; }
|
||||
. $hints
|
||||
fi
|
||||
|
||||
#########
|
||||
# Locate a compiler for the build machine. This compiler should
|
||||
# generate command-line programs that run on the build machine.
|
||||
@@ -12507,6 +12552,31 @@ fi
|
||||
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to allow a connection created in one thread to be used
|
||||
# in another thread. This does not work on many Linux systems (ex: RedHat 9)
|
||||
# due to bugs in the threading implementations. This is thus off by default.
|
||||
#
|
||||
# Check whether --enable-cross-thread-connections was given.
|
||||
if test "${enable_cross_thread_connections+set}" = set; then
|
||||
enableval=$enable_cross_thread_connections;
|
||||
else
|
||||
enable_xthreadconnect=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:$LINENO: checking whether to allow connections to be shared across threads" >&5
|
||||
$as_echo_n "checking whether to allow connections to be shared across threads... " >&6; }
|
||||
if test "$enable_xthreadconnect" = "no"; then
|
||||
XTHREADCONNECT=''
|
||||
{ $as_echo "$as_me:$LINENO: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
XTHREADCONNECT='-DSQLITE_ALLOW_XTHREAD_CONNECT=1'
|
||||
{ $as_echo "$as_me:$LINENO: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
# Do we want to support release
|
||||
#
|
||||
@@ -13357,7 +13427,7 @@ fi
|
||||
if test "${enable_load_extension+set}" = set; then
|
||||
enableval=$enable_load_extension; use_loadextension=$enableval
|
||||
else
|
||||
use_loadextension=yes
|
||||
use_loadextension=no
|
||||
fi
|
||||
|
||||
if test "${use_loadextension}" = "yes" ; then
|
||||
@@ -13951,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.9, which was
|
||||
This file was extended by sqlite $as_me 3.8.7, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -14004,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.9
|
||||
sqlite config.status 3.8.7
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
||||
+75
-5
@@ -69,6 +69,19 @@
|
||||
# The filename extension for executables on the
|
||||
# target platform. "" for Unix and ".exe" for windows.
|
||||
#
|
||||
# The generated configure script will make an attempt to guess
|
||||
# at all of the above parameters. You can override any of
|
||||
# the guesses by setting the environment variable named
|
||||
# "config_AAAA" where "AAAA" is the name of the parameter
|
||||
# described above. (Exception: srcdir cannot be set this way.)
|
||||
# If you have a file that sets one or more of these environment
|
||||
# variables, you can invoke configure as follows:
|
||||
#
|
||||
# configure --with-hints=FILE
|
||||
#
|
||||
# where FILE is the name of the file that sets the environment
|
||||
# variables. FILE should be an absolute pathname.
|
||||
#
|
||||
# This configure.in file is easy to reuse on other projects. Just
|
||||
# change the argument to AC_INIT(). And disable any features that
|
||||
# you don't need (for example BLT) by erasing or commenting out
|
||||
@@ -85,6 +98,11 @@ AC_MSG_ERROR([configure script is out of date:
|
||||
please regen with autoconf])
|
||||
fi
|
||||
|
||||
dnl Put the RCS revision string after AC_INIT so that it will also
|
||||
dnl show in in configure.
|
||||
# The following RCS revision string applies to configure.in
|
||||
# $Revision: 1.56 $
|
||||
|
||||
#########
|
||||
# Programs needed
|
||||
#
|
||||
@@ -109,7 +127,7 @@ AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h malloc.h])
|
||||
#########
|
||||
# Figure out whether or not we have these functions
|
||||
#
|
||||
AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime])
|
||||
AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size])
|
||||
|
||||
#########
|
||||
# By default, we use the amalgamation (this may be changed below...)
|
||||
@@ -162,6 +180,41 @@ VERSION_NUMBER=[`cat $srcdir/VERSION \
|
||||
AC_MSG_NOTICE(Version number set to $VERSION_NUMBER)
|
||||
AC_SUBST(VERSION_NUMBER)
|
||||
|
||||
#########
|
||||
# Check to see if the --with-hints=FILE option is used. If there is none,
|
||||
# then check for a files named "$host.hints" and ../$hosts.hints where
|
||||
# $host is the hostname of the build system. If still no hints are
|
||||
# found, try looking in $system.hints and ../$system.hints where
|
||||
# $system is the result of uname -s.
|
||||
#
|
||||
AC_ARG_WITH(hints,
|
||||
AC_HELP_STRING([--with-hints=FILE],[Read configuration options from FILE]),
|
||||
hints=$withval)
|
||||
if test "$hints" = ""; then
|
||||
host=`hostname | sed 's/\..*//'`
|
||||
if test -r $host.hints; then
|
||||
hints=$host.hints
|
||||
else
|
||||
if test -r ../$host.hints; then
|
||||
hints=../$host.hints
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$hints" = ""; then
|
||||
sys=`uname -s`
|
||||
if test -r $sys.hints; then
|
||||
hints=$sys.hints
|
||||
else
|
||||
if test -r ../$sys.hints; then
|
||||
hints=../$sys.hints
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$hints" != ""; then
|
||||
AC_MSG_RESULT(reading hints from $hints)
|
||||
. $hints
|
||||
fi
|
||||
|
||||
#########
|
||||
# Locate a compiler for the build machine. This compiler should
|
||||
# generate command-line programs that run on the build machine.
|
||||
@@ -183,7 +236,7 @@ AC_SUBST(BUILD_CC)
|
||||
# Do we want to support multithreaded use of sqlite
|
||||
#
|
||||
AC_ARG_ENABLE(threadsafe,
|
||||
AC_HELP_STRING([--disable-threadsafe],[Disable mutexing]),,enable_threadsafe=yes)
|
||||
AC_HELP_STRING([--enable-threadsafe],[Support threadsafe operation]),,enable_threadsafe=yes)
|
||||
AC_MSG_CHECKING([whether to support threadsafe operation])
|
||||
if test "$enable_threadsafe" = "no"; then
|
||||
SQLITE_THREADSAFE=0
|
||||
@@ -198,6 +251,23 @@ if test "$SQLITE_THREADSAFE" = "1"; then
|
||||
AC_SEARCH_LIBS(pthread_create, pthread)
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to allow a connection created in one thread to be used
|
||||
# in another thread. This does not work on many Linux systems (ex: RedHat 9)
|
||||
# due to bugs in the threading implementations. This is thus off by default.
|
||||
#
|
||||
AC_ARG_ENABLE(cross-thread-connections,
|
||||
AC_HELP_STRING([--enable-cross-thread-connections],[Allow connection sharing across threads]),,enable_xthreadconnect=no)
|
||||
AC_MSG_CHECKING([whether to allow connections to be shared across threads])
|
||||
if test "$enable_xthreadconnect" = "no"; then
|
||||
XTHREADCONNECT=''
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
XTHREADCONNECT='-DSQLITE_ALLOW_XTHREAD_CONNECT=1'
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
AC_SUBST(XTHREADCONNECT)
|
||||
|
||||
##########
|
||||
# Do we want to support release
|
||||
#
|
||||
@@ -535,9 +605,9 @@ AC_SUBST(USE_AMALGAMATION)
|
||||
|
||||
#########
|
||||
# See whether we should allow loadable extensions
|
||||
AC_ARG_ENABLE(load-extension, AC_HELP_STRING([--disable-load-extension],
|
||||
[Disable loading of external extensions]),
|
||||
[use_loadextension=$enableval],[use_loadextension=yes])
|
||||
AC_ARG_ENABLE(load-extension, AC_HELP_STRING([--enable-load-extension],
|
||||
[Enable loading of external extensions]),
|
||||
[use_loadextension=$enableval],[use_loadextension=no])
|
||||
if test "${use_loadextension}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS=""
|
||||
AC_SEARCH_LIBS(dlopen, dl)
|
||||
|
||||
+70
-79
@@ -910,16 +910,11 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
|
||||
** This function is used when parsing the "prefix=" FTS4 parameter.
|
||||
*/
|
||||
static int fts3GobbleInt(const char **pp, int *pnOut){
|
||||
const int MAX_NPREFIX = 10000000;
|
||||
const char *p; /* Iterator pointer */
|
||||
int nInt = 0; /* Output value */
|
||||
|
||||
for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
|
||||
nInt = nInt * 10 + (p[0] - '0');
|
||||
if( nInt>MAX_NPREFIX ){
|
||||
nInt = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( p==*pp ) return SQLITE_ERROR;
|
||||
*pnOut = nInt;
|
||||
@@ -962,6 +957,7 @@ static int fts3PrefixParameter(
|
||||
|
||||
aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
|
||||
*apIndex = aIndex;
|
||||
*pnIndex = nIndex;
|
||||
if( !aIndex ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -971,20 +967,13 @@ static int fts3PrefixParameter(
|
||||
const char *p = zParam;
|
||||
int i;
|
||||
for(i=1; i<nIndex; i++){
|
||||
int nPrefix = 0;
|
||||
int nPrefix;
|
||||
if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR;
|
||||
assert( nPrefix>=0 );
|
||||
if( nPrefix==0 ){
|
||||
nIndex--;
|
||||
i--;
|
||||
}else{
|
||||
aIndex[i].nPrefix = nPrefix;
|
||||
}
|
||||
aIndex[i].nPrefix = nPrefix;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
*pnIndex = nIndex;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1864,7 +1853,7 @@ static int fts3SelectLeaf(
|
||||
sqlite3_int64 *piLeaf, /* Selected leaf node */
|
||||
sqlite3_int64 *piLeaf2 /* Selected leaf node */
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int rc; /* Return code */
|
||||
int iHeight; /* Height of this node in tree */
|
||||
|
||||
assert( piLeaf || piLeaf2 );
|
||||
@@ -1875,7 +1864,7 @@ static int fts3SelectLeaf(
|
||||
|
||||
if( rc==SQLITE_OK && iHeight>1 ){
|
||||
char *zBlob = 0; /* Blob read from %_segments table */
|
||||
int nBlob = 0; /* Size of zBlob in bytes */
|
||||
int nBlob; /* Size of zBlob in bytes */
|
||||
|
||||
if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
|
||||
rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0);
|
||||
@@ -3097,7 +3086,7 @@ static int fts3FilterMethod(
|
||||
int nVal, /* Number of elements in apVal */
|
||||
sqlite3_value **apVal /* Arguments for the indexing scheme */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int rc;
|
||||
char *zSql; /* SQL statement used to access %_content */
|
||||
int eSearch;
|
||||
Fts3Table *p = (Fts3Table *)pCursor->pVtab;
|
||||
@@ -3175,17 +3164,10 @@ static int fts3FilterMethod(
|
||||
** row by docid.
|
||||
*/
|
||||
if( eSearch==FTS3_FULLSCAN_SEARCH ){
|
||||
if( pDocidGe || pDocidLe ){
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s",
|
||||
p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid,
|
||||
(pCsr->bDesc ? "DESC" : "ASC")
|
||||
);
|
||||
}else{
|
||||
zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s",
|
||||
p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
|
||||
);
|
||||
}
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT %s ORDER BY rowid %s",
|
||||
p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
|
||||
);
|
||||
if( zSql ){
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
@@ -5038,22 +5020,6 @@ static void fts3EvalNextRow(
|
||||
}
|
||||
pExpr->iDocid = pLeft->iDocid;
|
||||
pExpr->bEof = (pLeft->bEof || pRight->bEof);
|
||||
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
|
||||
if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
|
||||
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
|
||||
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
|
||||
memset(pDl->pList, 0, pDl->nList);
|
||||
fts3EvalNextRow(pCsr, pRight, pRc);
|
||||
}
|
||||
}
|
||||
if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){
|
||||
Fts3Doclist *pDl = &pLeft->pPhrase->doclist;
|
||||
while( *pRc==SQLITE_OK && pLeft->bEof==0 ){
|
||||
memset(pDl->pList, 0, pDl->nList);
|
||||
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -5426,7 +5392,6 @@ static void fts3EvalRestart(
|
||||
}
|
||||
pPhrase->doclist.pNextDocid = 0;
|
||||
pPhrase->doclist.iDocid = 0;
|
||||
pPhrase->pOrPoslist = 0;
|
||||
}
|
||||
|
||||
pExpr->iDocid = 0;
|
||||
@@ -5672,8 +5637,8 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
iDocid = pExpr->iDocid;
|
||||
pIter = pPhrase->doclist.pList;
|
||||
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
|
||||
int rc = SQLITE_OK;
|
||||
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
|
||||
int iMul; /* +1 if csr dir matches index dir, else -1 */
|
||||
int bOr = 0;
|
||||
u8 bEof = 0;
|
||||
u8 bTreeEof = 0;
|
||||
@@ -5697,43 +5662,72 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
** an incremental phrase. Load the entire doclist for the phrase
|
||||
** into memory in this case. */
|
||||
if( pPhrase->bIncr ){
|
||||
int bEofSave = pNear->bEof;
|
||||
fts3EvalRestart(pCsr, pNear, &rc);
|
||||
while( rc==SQLITE_OK && !pNear->bEof ){
|
||||
fts3EvalNextRow(pCsr, pNear, &rc);
|
||||
if( bEofSave==0 && pNear->iDocid==iDocid ) break;
|
||||
int rc = SQLITE_OK;
|
||||
int bEofSave = pExpr->bEof;
|
||||
fts3EvalRestart(pCsr, pExpr, &rc);
|
||||
while( rc==SQLITE_OK && !pExpr->bEof ){
|
||||
fts3EvalNextRow(pCsr, pExpr, &rc);
|
||||
if( bEofSave==0 && pExpr->iDocid==iDocid ) break;
|
||||
}
|
||||
pIter = pPhrase->doclist.pList;
|
||||
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
if( bTreeEof ){
|
||||
while( rc==SQLITE_OK && !pNear->bEof ){
|
||||
fts3EvalNextRow(pCsr, pNear, &rc);
|
||||
}
|
||||
|
||||
iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1);
|
||||
while( bTreeEof==1
|
||||
&& pNear->bEof==0
|
||||
&& (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
fts3EvalNextRow(pCsr, pExpr, &rc);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
iDocid = pExpr->iDocid;
|
||||
pIter = pPhrase->doclist.pList;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
pIter = pPhrase->pOrPoslist;
|
||||
iDocid = pPhrase->iOrDocid;
|
||||
if( pCsr->bDesc==bDescDoclist ){
|
||||
bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistNext(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &bEof
|
||||
);
|
||||
}
|
||||
}else{
|
||||
bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll);
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
|
||||
bEof = (pPhrase->doclist.nAll==0);
|
||||
assert( bDescDoclist==0 || bDescDoclist==1 );
|
||||
assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
|
||||
|
||||
if( bEof==0 ){
|
||||
if( pCsr->bDesc==bDescDoclist ){
|
||||
int dummy;
|
||||
sqlite3Fts3DoclistPrev(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &dummy, &bEof
|
||||
);
|
||||
if( pNear->bEof ){
|
||||
/* This expression is already at EOF. So position it to point to the
|
||||
** last entry in the doclist at pPhrase->doclist.aAll[]. Variable
|
||||
** iDocid is already set for this entry, so all that is required is
|
||||
** to set pIter to point to the first byte of the last position-list
|
||||
** in the doclist.
|
||||
**
|
||||
** It would also be correct to set pIter and iDocid to zero. In
|
||||
** this case, the first call to sqltie3Fts4DoclistPrev() below
|
||||
** would also move the iterator to point to the last entry in the
|
||||
** doclist. However, this is expensive, as to do so it has to
|
||||
** iterate through the entire doclist from start to finish (since
|
||||
** it does not know the docid for the last entry). */
|
||||
pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1];
|
||||
fts3ReversePoslist(pPhrase->doclist.aAll, &pIter);
|
||||
}
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistPrev(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &dummy, &bEof
|
||||
);
|
||||
}
|
||||
}else{
|
||||
if( pNear->bEof ){
|
||||
pIter = 0;
|
||||
iDocid = 0;
|
||||
}
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistNext(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &bEof
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
pPhrase->pOrPoslist = pIter;
|
||||
pPhrase->iOrDocid = iDocid;
|
||||
|
||||
if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
|
||||
}
|
||||
@@ -5747,13 +5741,10 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
}
|
||||
while( iThis<iCol ){
|
||||
fts3ColumnlistCopy(0, &pIter);
|
||||
if( *pIter==0x00 ) return SQLITE_OK;
|
||||
if( *pIter==0x00 ) return 0;
|
||||
pIter++;
|
||||
pIter += fts3GetVarint32(pIter, &iThis);
|
||||
}
|
||||
if( *pIter==0x00 ){
|
||||
pIter = 0;
|
||||
}
|
||||
|
||||
*ppOut = ((iCol==iThis)?pIter:0);
|
||||
return SQLITE_OK;
|
||||
|
||||
@@ -375,11 +375,6 @@ struct Fts3Phrase {
|
||||
int bIncr; /* True if doclist is loaded incrementally */
|
||||
int iDoclistToken;
|
||||
|
||||
/* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an
|
||||
** OR condition. */
|
||||
char *pOrPoslist;
|
||||
i64 iOrDocid;
|
||||
|
||||
/* Variables below this point are populated by fts3_expr.c when parsing
|
||||
** a MATCH expression. Everything above is part of the evaluation phase.
|
||||
*/
|
||||
|
||||
@@ -183,7 +183,7 @@ static int isVowel(const char *z){
|
||||
** by a consonant.
|
||||
**
|
||||
** In this routine z[] is in reverse order. So we are really looking
|
||||
** for an instance of a consonant followed by a vowel.
|
||||
** for an instance of of a consonant followed by a vowel.
|
||||
*/
|
||||
static int m_gt_0(const char *z){
|
||||
while( isVowel(z) ){ z++; }
|
||||
|
||||
+30
-36
@@ -442,39 +442,37 @@ static int fts3BestSnippet(
|
||||
sIter.nSnippet = nSnippet;
|
||||
sIter.nPhrase = nList;
|
||||
sIter.iCurrent = -1;
|
||||
rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
|
||||
if( rc==SQLITE_OK ){
|
||||
(void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
|
||||
|
||||
/* Set the *pmSeen output variable. */
|
||||
for(i=0; i<nList; i++){
|
||||
if( sIter.aPhrase[i].pHead ){
|
||||
*pmSeen |= (u64)1 << i;
|
||||
}
|
||||
/* Set the *pmSeen output variable. */
|
||||
for(i=0; i<nList; i++){
|
||||
if( sIter.aPhrase[i].pHead ){
|
||||
*pmSeen |= (u64)1 << i;
|
||||
}
|
||||
|
||||
/* Loop through all candidate snippets. Store the best snippet in
|
||||
** *pFragment. Store its associated 'score' in iBestScore.
|
||||
*/
|
||||
pFragment->iCol = iCol;
|
||||
while( !fts3SnippetNextCandidate(&sIter) ){
|
||||
int iPos;
|
||||
int iScore;
|
||||
u64 mCover;
|
||||
u64 mHighlite;
|
||||
fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite);
|
||||
assert( iScore>=0 );
|
||||
if( iScore>iBestScore ){
|
||||
pFragment->iPos = iPos;
|
||||
pFragment->hlmask = mHighlite;
|
||||
pFragment->covered = mCover;
|
||||
iBestScore = iScore;
|
||||
}
|
||||
}
|
||||
|
||||
*piScore = iBestScore;
|
||||
}
|
||||
|
||||
/* Loop through all candidate snippets. Store the best snippet in
|
||||
** *pFragment. Store its associated 'score' in iBestScore.
|
||||
*/
|
||||
pFragment->iCol = iCol;
|
||||
while( !fts3SnippetNextCandidate(&sIter) ){
|
||||
int iPos;
|
||||
int iScore;
|
||||
u64 mCover;
|
||||
u64 mHighlight;
|
||||
fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover, &mHighlight);
|
||||
assert( iScore>=0 );
|
||||
if( iScore>iBestScore ){
|
||||
pFragment->iPos = iPos;
|
||||
pFragment->hlmask = mHighlight;
|
||||
pFragment->covered = mCover;
|
||||
iBestScore = iScore;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_free(sIter.aPhrase);
|
||||
return rc;
|
||||
*piScore = iBestScore;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -682,12 +680,8 @@ static int fts3SnippetText(
|
||||
** required. They are required if (a) this is not the first fragment,
|
||||
** or (b) this fragment does not begin at position 0 of its column.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
if( iPos>0 || iFragment>0 ){
|
||||
rc = fts3StringAppend(pOut, zEllipsis, -1);
|
||||
}else if( iBegin ){
|
||||
rc = fts3StringAppend(pOut, zDoc, iBegin);
|
||||
}
|
||||
if( rc==SQLITE_OK && (iPos>0 || iFragment>0) ){
|
||||
rc = fts3StringAppend(pOut, zEllipsis, -1);
|
||||
}
|
||||
if( rc!=SQLITE_OK || iCurrent<iPos ) continue;
|
||||
}
|
||||
@@ -1253,7 +1247,7 @@ void sqlite3Fts3Snippet(
|
||||
*/
|
||||
for(iRead=0; iRead<pTab->nColumn; iRead++){
|
||||
SnippetFragment sF = {0, 0, 0, 0};
|
||||
int iS = 0;
|
||||
int iS;
|
||||
if( iCol>=0 && iRead!=iCol ) continue;
|
||||
|
||||
/* Find the best snippet of nFToken tokens in column iRead. */
|
||||
|
||||
@@ -163,7 +163,7 @@ static int fts3tokConnectMethod(
|
||||
sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
|
||||
char **pzErr /* OUT: sqlite3_malloc'd error message */
|
||||
){
|
||||
Fts3tokTable *pTab = 0;
|
||||
Fts3tokTable *pTab;
|
||||
const sqlite3_tokenizer_module *pMod = 0;
|
||||
sqlite3_tokenizer *pTok = 0;
|
||||
int rc;
|
||||
|
||||
@@ -69,7 +69,7 @@ static void scalarFunc(
|
||||
if( argc==2 ){
|
||||
void *pOld;
|
||||
int n = sqlite3_value_bytes(argv[1]);
|
||||
if( zName==0 || n!=sizeof(pPtr) ){
|
||||
if( n!=sizeof(pPtr) ){
|
||||
sqlite3_result_error(context, "argument type mismatch", -1);
|
||||
return;
|
||||
}
|
||||
@@ -80,9 +80,7 @@ static void scalarFunc(
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if( zName ){
|
||||
pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
|
||||
}
|
||||
pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
|
||||
if( !pPtr ){
|
||||
char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
@@ -163,10 +161,6 @@ int sqlite3Fts3InitTokenizer(
|
||||
zEnd = &zCopy[strlen(zCopy)];
|
||||
|
||||
z = (char *)sqlite3Fts3NextToken(zCopy, &n);
|
||||
if( z==0 ){
|
||||
assert( n==0 );
|
||||
z = zCopy;
|
||||
}
|
||||
z[n] = '\0';
|
||||
sqlite3Fts3Dequote(z);
|
||||
|
||||
|
||||
@@ -1625,10 +1625,7 @@ int sqlite3Fts3SegReaderNew(
|
||||
** an array of pending terms by term. This occurs as part of flushing
|
||||
** the contents of the pending-terms hash table to the database.
|
||||
*/
|
||||
static int SQLITE_CDECL fts3CompareElemByTerm(
|
||||
const void *lhs,
|
||||
const void *rhs
|
||||
){
|
||||
static int fts3CompareElemByTerm(const void *lhs, const void *rhs){
|
||||
char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
|
||||
char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
|
||||
int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
|
||||
@@ -3085,8 +3082,8 @@ static int fts3PromoteSegments(
|
||||
|
||||
if( bOk ){
|
||||
int iIdx = 0;
|
||||
sqlite3_stmt *pUpdate1 = 0;
|
||||
sqlite3_stmt *pUpdate2 = 0;
|
||||
sqlite3_stmt *pUpdate1;
|
||||
sqlite3_stmt *pUpdate2;
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0);
|
||||
|
||||
@@ -504,7 +504,7 @@ static void showSegdirMap(sqlite3 *db, const char *zTab){
|
||||
sqlite3_column_int64(pStmt,5));
|
||||
printf(" root %9s\n", rtag);
|
||||
if( iLEnd>iStart ){
|
||||
sqlite3_int64 iLower, iPrev = 0, iX;
|
||||
sqlite3_int64 iLower, iPrev, iX;
|
||||
if( iLEnd+1<=iEnd ){
|
||||
sqlite3_bind_int64(pStmt2, 1, iLEnd+1);
|
||||
sqlite3_bind_int64(pStmt2, 2, iEnd);
|
||||
@@ -548,7 +548,7 @@ static void decodeSegment(
|
||||
const unsigned char *aData, /* Content to print */
|
||||
int nData /* Number of bytes of content */
|
||||
){
|
||||
sqlite3_int64 iChild = 0;
|
||||
sqlite3_int64 iChild;
|
||||
sqlite3_int64 iPrefix;
|
||||
sqlite3_int64 nTerm;
|
||||
sqlite3_int64 n;
|
||||
|
||||
+6
-24
@@ -398,7 +398,7 @@ static amatch_avl *amatchAvlInsert(amatch_avl **ppHead, amatch_avl *pNew){
|
||||
*/
|
||||
static void amatchAvlRemove(amatch_avl **ppHead, amatch_avl *pOld){
|
||||
amatch_avl **ppParent;
|
||||
amatch_avl *pBalance = 0;
|
||||
amatch_avl *pBalance;
|
||||
/* assert( amatchAvlSearch(*ppHead, pOld->zKey)==pOld ); */
|
||||
ppParent = amatchAvlFromPtr(pOld, ppHead);
|
||||
if( pOld->pBefore==0 && pOld->pAfter==0 ){
|
||||
@@ -998,23 +998,6 @@ static void amatchWriteCost(amatch_word *pWord){
|
||||
pWord->zCost[8] = 0;
|
||||
}
|
||||
|
||||
/* Circumvent compiler warnings about the use of strcpy() by supplying
|
||||
** our own implementation.
|
||||
*/
|
||||
#if defined(__OpenBSD__)
|
||||
static void amatchStrcpy(char *dest, const char *src){
|
||||
while( (*(dest++) = *(src++))!=0 ){}
|
||||
}
|
||||
static void amatchStrcat(char *dest, const char *src){
|
||||
while( *dest ) dest++;
|
||||
amatchStrcpy(dest, src);
|
||||
}
|
||||
#else
|
||||
# define amatchStrcpy strcpy
|
||||
# define amatchStrcat strcat
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Add a new amatch_word object to the queue.
|
||||
**
|
||||
@@ -1090,7 +1073,7 @@ static void amatchAddWord(
|
||||
assert( pOther==0 ); (void)pOther;
|
||||
pWord->sWord.zKey = pWord->zWord;
|
||||
pWord->sWord.pWord = pWord;
|
||||
amatchStrcpy(pWord->zWord, pCur->zBuf);
|
||||
strcpy(pWord->zWord, pCur->zBuf);
|
||||
pOther = amatchAvlInsert(&pCur->pWord, &pWord->sWord);
|
||||
assert( pOther==0 ); (void)pOther;
|
||||
#ifdef AMATCH_TRACE_1
|
||||
@@ -1100,7 +1083,6 @@ static void amatchAddWord(
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Advance a cursor to its next row of output
|
||||
*/
|
||||
@@ -1166,7 +1148,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
zBuf = sqlite3_realloc(zBuf, nBuf);
|
||||
if( zBuf==0 ) return SQLITE_NOMEM;
|
||||
}
|
||||
amatchStrcpy(zBuf, pWord->zWord+2);
|
||||
strcpy(zBuf, pWord->zWord+2);
|
||||
zNext[0] = 0;
|
||||
zNextIn[0] = pCur->zInput[pWord->nMatch];
|
||||
if( zNextIn[0] ){
|
||||
@@ -1181,7 +1163,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
|
||||
if( zNextIn[0] && zNextIn[0]!='*' ){
|
||||
sqlite3_reset(p->pVCheck);
|
||||
amatchStrcat(zBuf, zNextIn);
|
||||
strcat(zBuf, zNextIn);
|
||||
sqlite3_bind_text(p->pVCheck, 1, zBuf, nWord+nNextIn, SQLITE_STATIC);
|
||||
rc = sqlite3_step(p->pVCheck);
|
||||
if( rc==SQLITE_ROW ){
|
||||
@@ -1194,13 +1176,13 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
}
|
||||
|
||||
while( 1 ){
|
||||
amatchStrcpy(zBuf+nWord, zNext);
|
||||
strcpy(zBuf+nWord, zNext);
|
||||
sqlite3_reset(p->pVCheck);
|
||||
sqlite3_bind_text(p->pVCheck, 1, zBuf, -1, SQLITE_TRANSIENT);
|
||||
rc = sqlite3_step(p->pVCheck);
|
||||
if( rc!=SQLITE_ROW ) break;
|
||||
zW = (const char*)sqlite3_column_text(p->pVCheck, 0);
|
||||
amatchStrcpy(zBuf+nWord, zNext);
|
||||
strcpy(zBuf+nWord, zNext);
|
||||
if( strncmp(zW, zBuf, nWord)!=0 ) break;
|
||||
if( (zNextIn[0]=='*' && zNextIn[1]==0)
|
||||
|| (zNextIn[0]==0 && zW[nWord]==0)
|
||||
|
||||
+2
-9
@@ -38,7 +38,6 @@ static void compressFunc(
|
||||
unsigned int nIn;
|
||||
unsigned long int nOut;
|
||||
unsigned char x[8];
|
||||
int rc;
|
||||
int i, j;
|
||||
|
||||
pIn = sqlite3_value_blob(argv[0]);
|
||||
@@ -51,12 +50,8 @@ static void compressFunc(
|
||||
for(i=0; i<4 && x[i]==0; i++){}
|
||||
for(j=0; i<=4; i++, j++) pOut[j] = x[i];
|
||||
pOut[j-1] |= 0x80;
|
||||
rc = compress(&pOut[j], &nOut, pIn, nIn);
|
||||
if( rc==Z_OK ){
|
||||
sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pOut);
|
||||
}
|
||||
compress(&pOut[j], &nOut, pIn, nIn);
|
||||
sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -87,8 +82,6 @@ static void uncompressFunc(
|
||||
rc = uncompress(pOut, &nOut, &pIn[i], nIn-i);
|
||||
if( rc==Z_OK ){
|
||||
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
** 2014-11-10
|
||||
**
|
||||
** 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 SQLite extension implements SQL function eval() which runs
|
||||
** SQL statements recursively.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** Structure used to accumulate the output
|
||||
*/
|
||||
struct EvalResult {
|
||||
char *z; /* Accumulated output */
|
||||
const char *zSep; /* Separator */
|
||||
int szSep; /* Size of the separator string */
|
||||
sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */
|
||||
sqlite3_int64 nUsed; /* Number of bytes of z[] actually used */
|
||||
};
|
||||
|
||||
/*
|
||||
** Callback from sqlite_exec() for the eval() function.
|
||||
*/
|
||||
static int callback(void *pCtx, int argc, char **argv, char **colnames){
|
||||
struct EvalResult *p = (struct EvalResult*)pCtx;
|
||||
int i;
|
||||
for(i=0; i<argc; i++){
|
||||
const char *z = argv[i] ? argv[i] : "";
|
||||
size_t sz = strlen(z);
|
||||
if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){
|
||||
char *zNew;
|
||||
p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
|
||||
/* Using sqlite3_realloc64() would be better, but it is a recent
|
||||
** addition and will cause a segfault if loaded by an older version
|
||||
** of SQLite. */
|
||||
zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
|
||||
if( zNew==0 ){
|
||||
sqlite3_free(p->z);
|
||||
memset(p, 0, sizeof(*p));
|
||||
return 1;
|
||||
}
|
||||
p->z = zNew;
|
||||
}
|
||||
if( p->nUsed>0 ){
|
||||
memcpy(&p->z[p->nUsed], p->zSep, p->szSep);
|
||||
p->nUsed += p->szSep;
|
||||
}
|
||||
memcpy(&p->z[p->nUsed], z, sz);
|
||||
p->nUsed += sz;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the eval(X) and eval(X,Y) SQL functions.
|
||||
**
|
||||
** Evaluate the SQL text in X. Return the results, using string
|
||||
** Y as the separator. If Y is omitted, use a single space character.
|
||||
*/
|
||||
static void sqlEvalFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const char *zSql;
|
||||
sqlite3 *db;
|
||||
char *zErr = 0;
|
||||
int rc;
|
||||
struct EvalResult x;
|
||||
|
||||
memset(&x, 0, sizeof(x));
|
||||
x.zSep = " ";
|
||||
zSql = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zSql==0 ) return;
|
||||
if( argc>1 ){
|
||||
x.zSep = (const char*)sqlite3_value_text(argv[1]);
|
||||
if( x.zSep==0 ) return;
|
||||
}
|
||||
x.szSep = (int)strlen(x.zSep);
|
||||
db = sqlite3_context_db_handle(context);
|
||||
rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
}else if( x.zSep==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
sqlite3_free(x.z);
|
||||
}else{
|
||||
sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_eval_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
(void)pzErrMsg; /* Unused parameter */
|
||||
rc = sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0,
|
||||
sqlEvalFunc, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0,
|
||||
sqlEvalFunc, 0, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
+1
-2
@@ -342,8 +342,7 @@ static int fuzzerLoadOneRule(
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pRule, 0, sizeof(*pRule));
|
||||
pRule->zFrom = pRule->zTo;
|
||||
pRule->zFrom += nTo + 1;
|
||||
pRule->zFrom = &pRule->zTo[nTo+1];
|
||||
pRule->nFrom = nFrom;
|
||||
memcpy(pRule->zFrom, zFrom, nFrom+1);
|
||||
memcpy(pRule->zTo, zTo, nTo+1);
|
||||
|
||||
+1
-1
@@ -356,7 +356,7 @@ static int substituteCost(char cPrev, char cFrom, char cTo){
|
||||
static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
int nA, nB; /* Number of characters in zA[] and zB[] */
|
||||
int xA, xB; /* Loop counters for zA[] and zB[] */
|
||||
char cA = 0, cB; /* Current character of zA and zB */
|
||||
char cA, cB; /* Current character of zA and zB */
|
||||
char cAprev, cBprev; /* Previous character of zA and zB */
|
||||
char cAnext, cBnext; /* Next character in zA and zB */
|
||||
int d; /* North-west cost value */
|
||||
|
||||
+8
-8
@@ -369,12 +369,13 @@ static int readInt16(u8 *p){
|
||||
return (p[0]<<8) + p[1];
|
||||
}
|
||||
static void readCoord(u8 *p, RtreeCoord *pCoord){
|
||||
pCoord->u = (
|
||||
u32 i = (
|
||||
(((u32)p[0]) << 24) +
|
||||
(((u32)p[1]) << 16) +
|
||||
(((u32)p[2]) << 8) +
|
||||
(((u32)p[3]) << 0)
|
||||
);
|
||||
*(u32 *)pCoord = i;
|
||||
}
|
||||
static i64 readInt64(u8 *p){
|
||||
return (
|
||||
@@ -403,7 +404,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
|
||||
u32 i;
|
||||
assert( sizeof(RtreeCoord)==4 );
|
||||
assert( sizeof(u32)==4 );
|
||||
i = pCoord->u;
|
||||
i = *(u32 *)pCoord;
|
||||
p[0] = (i>>24)&0xFF;
|
||||
p[1] = (i>>16)&0xFF;
|
||||
p[2] = (i>> 8)&0xFF;
|
||||
@@ -734,13 +735,14 @@ static void nodeGetCell(
|
||||
RtreeCell *pCell /* OUT: Write the cell contents here */
|
||||
){
|
||||
u8 *pData;
|
||||
u8 *pEnd;
|
||||
RtreeCoord *pCoord;
|
||||
int ii;
|
||||
pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
|
||||
pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
|
||||
pEnd = pData + pRtree->nDim*8;
|
||||
pCoord = pCell->aCoord;
|
||||
for(ii=0; ii<pRtree->nDim*2; ii++){
|
||||
readCoord(&pData[ii*4], &pCoord[ii]);
|
||||
for(; pData<pEnd; pData+=4, pCoord++){
|
||||
readCoord(pData, pCoord);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,7 +1182,7 @@ static RtreeSearchPoint *rtreeEnqueue(
|
||||
pNew = pCur->aPoint + i;
|
||||
pNew->rScore = rScore;
|
||||
pNew->iLevel = iLevel;
|
||||
assert( iLevel<=RTREE_MAX_DEPTH );
|
||||
assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH );
|
||||
while( i>0 ){
|
||||
RtreeSearchPoint *pParent;
|
||||
j = (i-1)/2;
|
||||
@@ -2804,8 +2806,6 @@ static int rtreeUpdate(
|
||||
rtreeReference(pRtree);
|
||||
assert(nData>=1);
|
||||
|
||||
cell.iRowid = 0; /* Used only to suppress a compiler warning */
|
||||
|
||||
/* Constraint handling. A write operation on an r-tree table may return
|
||||
** SQLITE_CONSTRAINT for two reasons:
|
||||
**
|
||||
|
||||
@@ -102,7 +102,7 @@ do_eqp_test rtree6.2.4.2 {
|
||||
SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1}
|
||||
0 1 1 {SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)}
|
||||
0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)}
|
||||
}
|
||||
|
||||
do_eqp_test rtree6.2.5 {
|
||||
|
||||
@@ -112,7 +112,6 @@ SRC = \
|
||||
$(TOP)/src/mem3.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/memjournal.c \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.c \
|
||||
$(TOP)/src/mutex.h \
|
||||
$(TOP)/src/mutex_noop.c \
|
||||
@@ -133,7 +132,6 @@ SRC = \
|
||||
$(TOP)/src/pcache.h \
|
||||
$(TOP)/src/pcache1.c \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/pragma.h \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
$(TOP)/src/random.c \
|
||||
@@ -165,7 +163,6 @@ SRC = \
|
||||
$(TOP)/src/vdbetrace.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/wal.c \
|
||||
$(TOP)/src/wal.h \
|
||||
$(TOP)/src/walker.c \
|
||||
@@ -249,7 +246,6 @@ TESTSRC = \
|
||||
$(TOP)/src/test_autoext.c \
|
||||
$(TOP)/src/test_async.c \
|
||||
$(TOP)/src/test_backup.c \
|
||||
$(TOP)/src/test_blob.c \
|
||||
$(TOP)/src/test_btree.c \
|
||||
$(TOP)/src/test_config.c \
|
||||
$(TOP)/src/test_demovfs.c \
|
||||
@@ -284,7 +280,6 @@ TESTSRC = \
|
||||
TESTSRC += \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/fuzzer.c \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
@@ -348,7 +343,6 @@ HDR = \
|
||||
$(TOP)/src/hash.h \
|
||||
$(TOP)/src/hwtime.h \
|
||||
keywordhash.h \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.h \
|
||||
opcodes.h \
|
||||
$(TOP)/src/os.h \
|
||||
@@ -358,14 +352,12 @@ HDR = \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/pcache.h \
|
||||
parse.h \
|
||||
$(TOP)/src/pragma.h \
|
||||
sqlite3.h \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/sqliteLimit.h \
|
||||
$(TOP)/src/vdbe.h \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/whereInt.h
|
||||
|
||||
# Header files used by extensions
|
||||
@@ -631,15 +623,9 @@ test: testfixture$(EXE) sqlite3$(EXE)
|
||||
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||
# target is invoked by the releasetest.tcl script.
|
||||
#
|
||||
THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
|
||||
$(TOP)/test/tt3_checkpoint.c \
|
||||
$(TOP)/test/tt3_index.c \
|
||||
$(TOP)/test/tt3_vacuum.c \
|
||||
$(TOP)/test/tt3_stress.c \
|
||||
$(TOP)/test/tt3_lookaside1.c
|
||||
|
||||
threadtest3$(EXE): sqlite3.o $(THREADTEST3_SRC)
|
||||
$(TCCX) $(TOP)/test/threadtest3.c sqlite3.o -o $@ $(THREADLIB)
|
||||
threadtest3$(EXE): sqlite3.o $(TOP)/test/threadtest3.c $(TOP)/test/tt3_checkpoint.c
|
||||
$(TCCX) -O2 sqlite3.o $(TOP)/test/threadtest3.c \
|
||||
-o threadtest3$(EXE) $(THREADLIB)
|
||||
|
||||
threadtest: threadtest3$(EXE)
|
||||
./threadtest3$(EXE)
|
||||
@@ -694,7 +680,7 @@ checksymbols: sqlite3.o
|
||||
|
||||
# Build the amalgamation-autoconf package.
|
||||
#
|
||||
amalgamation-tarball: sqlite3.c
|
||||
dist: sqlite3.c
|
||||
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
e826cd7db6b3ab010533d81a759794c2470343d2
|
||||
c6a5b67ae1fb31120a40d2885b848ec2dab15c4e
|
||||
@@ -32,7 +32,6 @@
|
||||
--end
|
||||
--wait 1
|
||||
--task 2
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t2 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
@@ -47,7 +46,6 @@
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 3
|
||||
DROP TABLE IF EXISTS t3;
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t3 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
@@ -62,7 +60,6 @@
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 4
|
||||
DROP TABLE IF EXISTS t4;
|
||||
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t4 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
@@ -77,7 +74,6 @@
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 5
|
||||
DROP TABLE IF EXISTS t5;
|
||||
CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t5 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
|
||||
+6
-19
@@ -1252,7 +1252,7 @@ static void unrecognizedArguments(
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int SQLITE_CDECL main(int argc, char **argv){
|
||||
int main(int argc, char **argv){
|
||||
const char *zClient;
|
||||
int iClient;
|
||||
int n, i;
|
||||
@@ -1262,9 +1262,6 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
int taskId;
|
||||
const char *zTrace;
|
||||
const char *zCOption;
|
||||
const char *zJMode;
|
||||
const char *zNRep;
|
||||
int nRep = 1, iRep;
|
||||
|
||||
g.argv0 = argv[0];
|
||||
g.iTrace = 1;
|
||||
@@ -1280,10 +1277,6 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
}
|
||||
n = argc-2;
|
||||
sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID());
|
||||
zJMode = findOption(argv+2, &n, "journalmode", 1);
|
||||
zNRep = findOption(argv+2, &n, "repeat", 1);
|
||||
if( zNRep ) nRep = atoi(zNRep);
|
||||
if( nRep<1 ) nRep = 1;
|
||||
g.zVfs = findOption(argv+2, &n, "vfs", 1);
|
||||
zClient = findOption(argv+2, &n, "client", 1);
|
||||
g.zErrLog = findOption(argv+2, &n, "errlog", 1);
|
||||
@@ -1355,11 +1348,7 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
fatalError("missing script filename");
|
||||
}
|
||||
if( n>1 ) unrecognizedArguments(argv[0], n, argv+2);
|
||||
if( zJMode ) runSql("PRAGMA journal_mode=%Q;", zJMode);
|
||||
runSql(
|
||||
"DROP TABLE IF EXISTS task;\n"
|
||||
"DROP TABLE IF EXISTS counters;\n"
|
||||
"DROP TABLE IF EXISTS client;\n"
|
||||
"CREATE TABLE task(\n"
|
||||
" id INTEGER PRIMARY KEY,\n"
|
||||
" name TEXT,\n"
|
||||
@@ -1375,12 +1364,10 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
"CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n"
|
||||
);
|
||||
zScript = readFile(argv[2]);
|
||||
for(iRep=1; iRep<=nRep; iRep++){
|
||||
if( g.iTrace ) logMessage("begin script [%s] cycle %d\n", argv[2], iRep);
|
||||
runScript(0, 0, zScript, argv[2]);
|
||||
if( g.iTrace ) logMessage("end script [%s] cycle %d\n", argv[2], iRep);
|
||||
}
|
||||
if( g.iTrace ) logMessage("begin script [%s]\n", argv[2]);
|
||||
runScript(0, 0, zScript, argv[2]);
|
||||
sqlite3_free(zScript);
|
||||
if( g.iTrace ) logMessage("end script [%s]\n", argv[2]);
|
||||
waitForClient(0, 2000, "during shutdown...\n");
|
||||
trySql("UPDATE client SET wantHalt=1");
|
||||
sqlite3_sleep(10);
|
||||
@@ -1404,11 +1391,11 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
sqlite3_close(g.db);
|
||||
sqlite3_close(g.db);
|
||||
maybeClose(g.pLog);
|
||||
maybeClose(g.pErrLog);
|
||||
if( iClient==0 ){
|
||||
printf("Summary: %d errors out of %d tests\n", g.nError, g.nTest);
|
||||
printf("Summary: %d errors in %d tests\n", g.nError, g.nTest);
|
||||
}
|
||||
return g.nError>0;
|
||||
}
|
||||
|
||||
@@ -361,8 +361,6 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 5
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -373,8 +371,6 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 3
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -385,8 +381,6 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 2
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -397,8 +391,6 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 4
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -409,7 +401,5 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--wait all
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH SQLITE3 1 "Fri Oct 31 10:41:31 EDT 2014"
|
||||
.TH SQLITE3 1 "Mon Jan 31 11:14:00 2014"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@@ -49,7 +49,7 @@ a table named "memos" and insert a couple of records into that table:
|
||||
$
|
||||
.B sqlite3 mydata.db
|
||||
.br
|
||||
SQLite version 3.8.8
|
||||
SQLite version 3.8.3
|
||||
.br
|
||||
Enter ".help" for instructions
|
||||
.br
|
||||
@@ -107,29 +107,26 @@ the '.help' command. For example:
|
||||
sqlite>
|
||||
.B .help
|
||||
.nf
|
||||
.tr %.
|
||||
%backup ?DB? FILE Backup DB (default "main") to FILE
|
||||
%bail on|off Stop after hitting an error. Default OFF
|
||||
%clone NEWDB Clone data into NEWDB from the existing database
|
||||
%databases List names and files of attached databases
|
||||
%dump ?TABLE? ... Dump the database in an SQL text format
|
||||
.cc |
|
||||
.backup ?DB? FILE Backup DB (default "main") to FILE
|
||||
.bail ON|OFF Stop after hitting an error. Default OFF
|
||||
.databases List names and files of attached databases
|
||||
.dump ?TABLE? ... Dump the database in an SQL text format
|
||||
If TABLE specified, only dump tables matching
|
||||
LIKE pattern TABLE.
|
||||
%echo on|off Turn command echo on or off
|
||||
%eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN
|
||||
%exit Exit this program
|
||||
%explain ?on|off? Turn output mode suitable for EXPLAIN on or off.
|
||||
.echo ON|OFF Turn command echo on or off
|
||||
.exit Exit this program
|
||||
.explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.
|
||||
With no args, it turns EXPLAIN on.
|
||||
%fullschema Show schema and the content of sqlite_stat tables
|
||||
%headers on|off Turn display of headers on or off
|
||||
%help Show this message
|
||||
%import FILE TABLE Import data from FILE into TABLE
|
||||
%indices ?TABLE? Show names of all indices
|
||||
.header(s) ON|OFF Turn display of headers on or off
|
||||
.help Show this message
|
||||
.import FILE TABLE Import data from FILE into TABLE
|
||||
.indices ?TABLE? Show names of all indices
|
||||
If TABLE specified, only show indices for tables
|
||||
matching LIKE pattern TABLE.
|
||||
%load FILE ?ENTRY? Load an extension library
|
||||
%log FILE|off Turn logging on or off. FILE can be stderr/stdout
|
||||
%mode MODE ?TABLE? Set output mode where MODE is one of:
|
||||
.load FILE ?ENTRY? Load an extension library
|
||||
.log FILE|off Turn logging on or off. FILE can be stderr/stdout
|
||||
.mode MODE ?TABLE? Set output mode where MODE is one of:
|
||||
csv Comma-separated values
|
||||
column Left-aligned columns. (See .width)
|
||||
html HTML <table> code
|
||||
@@ -138,35 +135,31 @@ sqlite>
|
||||
list Values delimited by .separator string
|
||||
tabs Tab-separated values
|
||||
tcl TCL list elements
|
||||
%nullvalue STRING Use STRING in place of NULL values
|
||||
%once FILENAME Output for the next SQL command only to FILENAME
|
||||
%open ?FILENAME? Close existing database and reopen FILENAME
|
||||
%output ?FILENAME? Send output to FILENAME or stdout
|
||||
%print STRING... Print literal STRING
|
||||
%prompt MAIN CONTINUE Replace the standard prompts
|
||||
%quit Exit this program
|
||||
%read FILENAME Execute SQL in FILENAME
|
||||
%restore ?DB? FILE Restore content of DB (default "main") from FILE
|
||||
%save FILE Write in-memory database into FILE
|
||||
%schema ?TABLE? Show the CREATE statements
|
||||
.nullvalue STRING Use STRING in place of NULL values
|
||||
.open ?FILENAME? Close existing database and reopen FILENAME
|
||||
.output FILENAME Send output to FILENAME
|
||||
.output stdout Send output to the screen
|
||||
.print STRING... Print literal STRING
|
||||
.prompt MAIN CONTINUE Replace the standard prompts
|
||||
.quit Exit this program
|
||||
.read FILENAME Execute SQL in FILENAME
|
||||
.restore ?DB? FILE Restore content of DB (default "main") from FILE
|
||||
.schema ?TABLE? Show the CREATE statements
|
||||
If TABLE specified, only show tables matching
|
||||
LIKE pattern TABLE.
|
||||
%separator STRING ?NL? Change separator used by output mode and .import
|
||||
NL is the end-of-line mark for CSV
|
||||
%shell CMD ARGS... Run CMD ARGS... in a system shell
|
||||
%show Show the current values for various settings
|
||||
%stats on|off Turn stats on or off
|
||||
%system CMD ARGS... Run CMD ARGS... in a system shell
|
||||
%tables ?TABLE? List names of tables
|
||||
.separator STRING Change separator used by output mode and .import
|
||||
.show Show the current values for various settings
|
||||
.stats ON|OFF Turn stats on or off
|
||||
.tables ?TABLE? List names of tables
|
||||
If TABLE specified, only list tables matching
|
||||
LIKE pattern TABLE.
|
||||
%timeout MS Try opening locked tables for MS milliseconds
|
||||
%timer on|off Turn SQL timer on or off
|
||||
%trace FILE|off Output each SQL statement as it is run
|
||||
%vfsname ?AUX? Print the name of the VFS stack
|
||||
%width NUM1 NUM2 ... Set column widths for "column" mode
|
||||
Negative values right-justify
|
||||
.timeout MS Try opening locked tables for MS milliseconds
|
||||
.trace FILE|off Output each SQL statement as it is run
|
||||
.vfsname ?AUX? Print the name of the VFS stack
|
||||
.width NUM1 NUM2 ... Set column widths for "column" mode
|
||||
.timer ON|OFF Turn the CPU timer measurement on or off
|
||||
sqlite>
|
||||
|cc .
|
||||
.sp
|
||||
.fi
|
||||
.SH OPTIONS
|
||||
@@ -276,7 +269,7 @@ o If the -init option is present, the specified file is processed.
|
||||
o All other command line options are processed.
|
||||
|
||||
.SH SEE ALSO
|
||||
http://www.sqlite.org/cli.html
|
||||
http://www.sqlite.org/
|
||||
.br
|
||||
The sqlite3-doc package.
|
||||
.SH AUTHOR
|
||||
|
||||
+1
-4
@@ -690,10 +690,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
*/
|
||||
if( pDflt ){
|
||||
sqlite3_value *pVal = 0;
|
||||
int rc;
|
||||
rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal);
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
|
||||
db->mallocFailed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
+17
-22
@@ -448,7 +448,7 @@ static void statInit(
|
||||
p->mxSample = mxSample;
|
||||
p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
|
||||
p->current.anLt = &p->current.anEq[nColUp];
|
||||
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
|
||||
p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565;
|
||||
|
||||
/* Set up the Stat4Accum.a[] and aBest[] arrays */
|
||||
p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
|
||||
@@ -1457,28 +1457,23 @@ static void decodeIntArray(
|
||||
if( *z==' ' ) z++;
|
||||
}
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
assert( pIndex!=0 ); {
|
||||
assert( pIndex!=0 );
|
||||
#else
|
||||
if( pIndex ){
|
||||
if( pIndex )
|
||||
#endif
|
||||
pIndex->bUnordered = 0;
|
||||
pIndex->noSkipScan = 0;
|
||||
while( z[0] ){
|
||||
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
|
||||
pIndex->noSkipScan = 1;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_COSTMULT
|
||||
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
|
||||
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
|
||||
}
|
||||
#endif
|
||||
while( z[0]!=0 && z[0]!=' ' ) z++;
|
||||
while( z[0]==' ' ) z++;
|
||||
while( z[0] ){
|
||||
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_COSTMULT
|
||||
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
|
||||
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
|
||||
}
|
||||
#endif
|
||||
while( z[0]!=0 && z[0]!=' ' ) z++;
|
||||
while( z[0]==' ' ) z++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1596,7 +1591,7 @@ static void initAvgEq(Index *pIdx){
|
||||
i64 nSum100 = 0; /* Number of terms contributing to sumEq */
|
||||
i64 nDist100; /* Number of distinct values in index */
|
||||
|
||||
if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
|
||||
if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
|
||||
nRow = pFinal->anLt[iCol];
|
||||
nDist100 = (i64)100 * pFinal->anDLt[iCol];
|
||||
nSample--;
|
||||
@@ -1866,7 +1861,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
|
||||
/* Load the statistics from the sqlite_stat4 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
|
||||
if( rc==SQLITE_OK ){
|
||||
int lookasideEnabled = db->lookaside.bEnabled;
|
||||
db->lookaside.bEnabled = 0;
|
||||
rc = loadStat4(db, sInfo.zDatabase);
|
||||
|
||||
+1
-3
@@ -150,7 +150,6 @@ static void attachFunc(
|
||||
"attached databases must use the same text encoding as main database");
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
sqlite3BtreeEnter(aNew->pBt);
|
||||
pPager = sqlite3BtreePager(aNew->pBt);
|
||||
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
|
||||
sqlite3BtreeSecureDelete(aNew->pBt,
|
||||
@@ -158,7 +157,6 @@ static void attachFunc(
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
|
||||
#endif
|
||||
sqlite3BtreeLeave(aNew->pBt);
|
||||
}
|
||||
aNew->safety_level = 3;
|
||||
aNew->zName = sqlite3DbStrDup(db, zName);
|
||||
@@ -191,7 +189,7 @@ static void attachFunc(
|
||||
case SQLITE_NULL:
|
||||
/* No key specified. Use the key from the main database */
|
||||
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
|
||||
if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
|
||||
if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
|
||||
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -72,9 +72,6 @@ int sqlite3_set_authorizer(
|
||||
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
|
||||
void *pArg
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->xAuth = (sqlite3_xauth)xAuth;
|
||||
db->pAuthArg = pArg;
|
||||
|
||||
+7
-46
@@ -122,20 +122,6 @@ static int setDestPgsz(sqlite3_backup *p){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check that there is no open read-transaction on the b-tree passed as the
|
||||
** second argument. If there is not, return SQLITE_OK. Otherwise, if there
|
||||
** is an open read-transaction, return SQLITE_ERROR and leave an error
|
||||
** message in database handle db.
|
||||
*/
|
||||
static int checkReadTransaction(sqlite3 *db, Btree *p){
|
||||
if( sqlite3BtreeIsInReadTrans(p) ){
|
||||
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create an sqlite3_backup process to copy the contents of zSrcDb from
|
||||
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
|
||||
@@ -152,13 +138,6 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
){
|
||||
sqlite3_backup *p; /* Value to return */
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Lock the source database handle. The destination database
|
||||
** handle is not locked in this routine, but it is locked in
|
||||
** sqlite3_backup_step(). The user is required to ensure that no
|
||||
@@ -195,15 +174,12 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
p->iNext = 1;
|
||||
p->isAttached = 0;
|
||||
|
||||
if( 0==p->pSrc || 0==p->pDest
|
||||
|| setDestPgsz(p)==SQLITE_NOMEM
|
||||
|| checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK
|
||||
){
|
||||
if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
|
||||
/* One (or both) of the named databases did not exist or an OOM
|
||||
** error was hit. Or there is a transaction open on the destination
|
||||
** database. The error has already been written into the pDestDb
|
||||
** handle. All that is left to do here is free the sqlite3_backup
|
||||
** structure. */
|
||||
** error was hit. The error has already been written into the
|
||||
** pDestDb handle. All that is left to do here is free the
|
||||
** sqlite3_backup structure.
|
||||
*/
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
}
|
||||
@@ -247,7 +223,7 @@ static int backupOnePage(
|
||||
** guaranteed that the shared-mutex is held by this thread, handle
|
||||
** p->pSrc may not actually be the owner. */
|
||||
int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
|
||||
int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
|
||||
int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
|
||||
#endif
|
||||
int rc = SQLITE_OK;
|
||||
i64 iOff;
|
||||
@@ -358,9 +334,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
int pgszSrc = 0; /* Source page size */
|
||||
int pgszDest = 0; /* Destination page size */
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( p==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
sqlite3_mutex_enter(p->pSrcDb->mutex);
|
||||
sqlite3BtreeEnter(p->pSrc);
|
||||
if( p->pDestDb ){
|
||||
@@ -624,7 +597,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
}
|
||||
|
||||
/* If a transaction is still open on the Btree, roll it back. */
|
||||
sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
|
||||
sqlite3BtreeRollback(p->pDest, SQLITE_OK);
|
||||
|
||||
/* Set the error code of the destination database handle. */
|
||||
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
|
||||
@@ -650,12 +623,6 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
** call to sqlite3_backup_step().
|
||||
*/
|
||||
int sqlite3_backup_remaining(sqlite3_backup *p){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( p==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return p->nRemaining;
|
||||
}
|
||||
|
||||
@@ -664,12 +631,6 @@ int sqlite3_backup_remaining(sqlite3_backup *p){
|
||||
** recent call to sqlite3_backup_step().
|
||||
*/
|
||||
int sqlite3_backup_pagecount(sqlite3_backup *p){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( p==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return p->nPagecount;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,6 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){
|
||||
** Exit the recursive mutex on a Btree.
|
||||
*/
|
||||
void sqlite3BtreeLeave(Btree *p){
|
||||
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||
if( p->sharable ){
|
||||
assert( p->wantToLock>0 );
|
||||
p->wantToLock--;
|
||||
|
||||
+398
-888
File diff suppressed because it is too large
Load Diff
+7
-25
@@ -19,7 +19,7 @@
|
||||
/* TODO: This definition is just included so other modules compile. It
|
||||
** needs to be revisited.
|
||||
*/
|
||||
#define SQLITE_N_BTREE_META 16
|
||||
#define SQLITE_N_BTREE_META 10
|
||||
|
||||
/*
|
||||
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
|
||||
@@ -73,15 +73,17 @@ int sqlite3BtreeGetPageSize(Btree*);
|
||||
int sqlite3BtreeMaxPageCount(Btree*,int);
|
||||
u32 sqlite3BtreeLastPage(Btree*);
|
||||
int sqlite3BtreeSecureDelete(Btree*,int);
|
||||
int sqlite3BtreeGetOptimalReserve(Btree*);
|
||||
int sqlite3BtreeGetReserve(Btree*);
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
||||
#endif
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
int sqlite3BtreeBeginTrans(Btree*,int);
|
||||
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
|
||||
int sqlite3BtreeCommitPhaseTwo(Btree*, int);
|
||||
int sqlite3BtreeCommit(Btree*);
|
||||
int sqlite3BtreeRollback(Btree*,int,int);
|
||||
int sqlite3BtreeRollback(Btree*,int);
|
||||
int sqlite3BtreeBeginStmt(Btree*,int);
|
||||
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
|
||||
int sqlite3BtreeIsInTrans(Btree*);
|
||||
@@ -114,7 +116,7 @@ int sqlite3BtreeIncrVacuum(Btree *);
|
||||
int sqlite3BtreeDropTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTableOfCursor(BtCursor*);
|
||||
int sqlite3BtreeTripAllCursors(Btree*, int, int);
|
||||
void sqlite3BtreeTripAllCursors(Btree*, int);
|
||||
|
||||
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
|
||||
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
||||
@@ -132,11 +134,6 @@ int sqlite3BtreeNewDb(Btree *p);
|
||||
** For example, the free-page-count field is located at byte offset 36 of
|
||||
** the database file header. The incr-vacuum-flag field is located at
|
||||
** byte offset 64 (== 36+4*7).
|
||||
**
|
||||
** The BTREE_DATA_VERSION value is not really a value stored in the header.
|
||||
** It is a read-only number computed by the pager. But we merge it with
|
||||
** the header value access routines since its access pattern is the same.
|
||||
** Call it a "virtual meta value".
|
||||
*/
|
||||
#define BTREE_FREE_PAGE_COUNT 0
|
||||
#define BTREE_SCHEMA_VERSION 1
|
||||
@@ -147,23 +144,12 @@ int sqlite3BtreeNewDb(Btree *p);
|
||||
#define BTREE_USER_VERSION 6
|
||||
#define BTREE_INCR_VACUUM 7
|
||||
#define BTREE_APPLICATION_ID 8
|
||||
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
|
||||
|
||||
/*
|
||||
** Values that may be OR'd together to form the second argument of an
|
||||
** sqlite3BtreeCursorHints() call.
|
||||
**
|
||||
** The BTREE_BULKLOAD flag is set on index cursors when the index is going
|
||||
** to be filled with content that is already in sorted order.
|
||||
**
|
||||
** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or
|
||||
** OP_SeekLE opcodes for a range search, but where the range of entries
|
||||
** selected will all have the same key. In other words, the cursor will
|
||||
** be used only for equality key searches.
|
||||
**
|
||||
*/
|
||||
#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */
|
||||
#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */
|
||||
#define BTREE_BULKLOAD 0x00000001
|
||||
|
||||
int sqlite3BtreeCursor(
|
||||
Btree*, /* BTree containing table to open */
|
||||
@@ -209,11 +195,7 @@ void sqlite3BtreeIncrblobCursor(BtCursor *);
|
||||
void sqlite3BtreeClearCursor(BtCursor *);
|
||||
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
|
||||
void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
|
||||
#endif
|
||||
int sqlite3BtreeIsReadonly(Btree *pBt);
|
||||
int sqlite3HeaderSizeBtree(void);
|
||||
|
||||
#ifndef NDEBUG
|
||||
int sqlite3BtreeCursorIsValid(BtCursor*);
|
||||
|
||||
+2
-12
@@ -351,7 +351,6 @@ struct Btree {
|
||||
u8 locked; /* True if db currently has pBt locked */
|
||||
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
|
||||
int nBackup; /* Number of backup operations reading this btree */
|
||||
u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
|
||||
Btree *pNext; /* List of other sharable Btrees from the same db */
|
||||
Btree *pPrev; /* Back pointer of the same list */
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
@@ -418,9 +417,6 @@ struct BtShared {
|
||||
#endif
|
||||
u8 inTransaction; /* Transaction state */
|
||||
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
u8 optimalReserve; /* Desired amount of reserved space per page */
|
||||
#endif
|
||||
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
|
||||
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
|
||||
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
||||
@@ -493,11 +489,6 @@ struct CellInfo {
|
||||
**
|
||||
** Fields in this structure are accessed under the BtShared.mutex
|
||||
** found at self->pBt->mutex.
|
||||
**
|
||||
** skipNext meaning:
|
||||
** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
|
||||
** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
|
||||
** eState==FAULT: Cursor fault with skipNext as error code.
|
||||
*/
|
||||
struct BtCursor {
|
||||
Btree *pBtree; /* The Btree to which this cursor belongs */
|
||||
@@ -510,8 +501,7 @@ struct BtCursor {
|
||||
void *pKey; /* Saved key that was cursor last known position */
|
||||
Pgno pgnoRoot; /* The root page of this tree */
|
||||
int nOvflAlloc; /* Allocated size of aOverflow[] array */
|
||||
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
|
||||
** Error code if eState==CURSOR_FAULT */
|
||||
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
|
||||
u8 curFlags; /* zero or more BTCF_* flags defined below */
|
||||
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
||||
u8 hints; /* As configured by CursorSetHints() */
|
||||
@@ -557,7 +547,7 @@ struct BtCursor {
|
||||
** on a different connection that shares the BtShared cache with this
|
||||
** cursor. The error has left the cache in an inconsistent state.
|
||||
** Do nothing else with this cursor. Any attempt to use the cursor
|
||||
** should return the error code stored in BtCursor.skipNext
|
||||
** should return the error code stored in BtCursor.skip
|
||||
*/
|
||||
#define CURSOR_INVALID 0
|
||||
#define CURSOR_VALID 1
|
||||
|
||||
+35
-42
@@ -307,7 +307,7 @@ int sqlite3UserAuthTable(const char *zTable){
|
||||
Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
Table *p = 0;
|
||||
int i;
|
||||
|
||||
assert( zName!=0 );
|
||||
/* All mutexes are required for schema access. Make sure we hold them. */
|
||||
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
@@ -431,6 +431,7 @@ static void freeIndex(sqlite3 *db, Index *p){
|
||||
#ifndef SQLITE_OMIT_ANALYZE
|
||||
sqlite3DeleteIndexSamples(db, p);
|
||||
#endif
|
||||
if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
|
||||
sqlite3ExprDelete(db, p->pPartIdxWhere);
|
||||
sqlite3DbFree(db, p->zColAff);
|
||||
if( p->isResized ) sqlite3DbFree(db, p->azColl);
|
||||
@@ -1709,32 +1710,16 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
pTab->iPKey = -1;
|
||||
}else{
|
||||
pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
/*
|
||||
** Remove all redundant columns from the PRIMARY KEY. For example, change
|
||||
** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
|
||||
** code assumes the PRIMARY KEY contains no repeated columns.
|
||||
*/
|
||||
for(i=j=1; i<pPk->nKeyCol; i++){
|
||||
if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
|
||||
pPk->nColumn--;
|
||||
}else{
|
||||
pPk->aiColumn[j++] = pPk->aiColumn[i];
|
||||
}
|
||||
}
|
||||
pPk->nKeyCol = j;
|
||||
}
|
||||
pPk->isCovering = 1;
|
||||
assert( pPk!=0 );
|
||||
nPk = pPk->nKeyCol;
|
||||
|
||||
/* Make sure every column of the PRIMARY KEY is NOT NULL. (Except,
|
||||
** do not enforce this for imposter tables.) */
|
||||
if( !db->init.imposterTable ){
|
||||
for(i=0; i<nPk; i++){
|
||||
pTab->aCol[pPk->aiColumn[i]].notNull = 1;
|
||||
}
|
||||
pPk->uniqNotNull = 1;
|
||||
/* Make sure every column of the PRIMARY KEY is NOT NULL */
|
||||
for(i=0; i<nPk; i++){
|
||||
pTab->aCol[pPk->aiColumn[i]].notNull = 1;
|
||||
}
|
||||
pPk->uniqNotNull = 1;
|
||||
|
||||
/* The root page of the PRIMARY KEY is the table root page */
|
||||
pPk->tnum = pTab->tnum;
|
||||
@@ -3183,7 +3168,6 @@ Index *sqlite3CreateIndex(
|
||||
pIdx->onError = pIndex->onError;
|
||||
}
|
||||
}
|
||||
pRet = pIdx;
|
||||
goto exit_create_index;
|
||||
}
|
||||
}
|
||||
@@ -4202,31 +4186,40 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
|
||||
** when it has finished using it.
|
||||
*/
|
||||
KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
||||
int i;
|
||||
int nCol = pIdx->nColumn;
|
||||
int nKey = pIdx->nKeyCol;
|
||||
KeyInfo *pKey;
|
||||
if( pParse->nErr ) return 0;
|
||||
if( pIdx->uniqNotNull ){
|
||||
pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
|
||||
}else{
|
||||
pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
if( pIdx->pKeyInfo && pIdx->pKeyInfo->db!=pParse->db ){
|
||||
sqlite3KeyInfoUnref(pIdx->pKeyInfo);
|
||||
pIdx->pKeyInfo = 0;
|
||||
}
|
||||
if( pKey ){
|
||||
assert( sqlite3KeyInfoIsWriteable(pKey) );
|
||||
for(i=0; i<nCol; i++){
|
||||
char *zColl = pIdx->azColl[i];
|
||||
assert( zColl!=0 );
|
||||
pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
|
||||
sqlite3LocateCollSeq(pParse, zColl);
|
||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||
#endif
|
||||
if( pIdx->pKeyInfo==0 ){
|
||||
int i;
|
||||
int nCol = pIdx->nColumn;
|
||||
int nKey = pIdx->nKeyCol;
|
||||
KeyInfo *pKey;
|
||||
if( pIdx->uniqNotNull ){
|
||||
pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
|
||||
}else{
|
||||
pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
|
||||
}
|
||||
if( pParse->nErr ){
|
||||
sqlite3KeyInfoUnref(pKey);
|
||||
pKey = 0;
|
||||
if( pKey ){
|
||||
assert( sqlite3KeyInfoIsWriteable(pKey) );
|
||||
for(i=0; i<nCol; i++){
|
||||
char *zColl = pIdx->azColl[i];
|
||||
assert( zColl!=0 );
|
||||
pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
|
||||
sqlite3LocateCollSeq(pParse, zColl);
|
||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||
}
|
||||
if( pParse->nErr ){
|
||||
sqlite3KeyInfoUnref(pKey);
|
||||
}else{
|
||||
pIdx->pKeyInfo = pKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pKey;
|
||||
return sqlite3KeyInfoRef(pIdx->pKeyInfo);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_CTE
|
||||
|
||||
@@ -134,13 +134,6 @@ int sqlite3_complete(const char *zSql){
|
||||
};
|
||||
#endif /* SQLITE_OMIT_TRIGGER */
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zSql==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
while( *zSql ){
|
||||
switch( *zSql ){
|
||||
case ';': { /* A semicolon */
|
||||
|
||||
+107
-117
@@ -33,91 +33,88 @@ static const char * const azCompileOpt[] = {
|
||||
#define CTIMEOPT_VAL_(opt) #opt
|
||||
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
|
||||
|
||||
#if SQLITE_32BIT_ROWID
|
||||
#ifdef SQLITE_32BIT_ROWID
|
||||
"32BIT_ROWID",
|
||||
#endif
|
||||
#if SQLITE_4_BYTE_ALIGNED_MALLOC
|
||||
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
|
||||
"4_BYTE_ALIGNED_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_CASE_SENSITIVE_LIKE
|
||||
#ifdef SQLITE_CASE_SENSITIVE_LIKE
|
||||
"CASE_SENSITIVE_LIKE",
|
||||
#endif
|
||||
#if SQLITE_CHECK_PAGES
|
||||
#ifdef SQLITE_CHECK_PAGES
|
||||
"CHECK_PAGES",
|
||||
#endif
|
||||
#if SQLITE_COVERAGE_TEST
|
||||
#ifdef SQLITE_COVERAGE_TEST
|
||||
"COVERAGE_TEST",
|
||||
#endif
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
"DEBUG",
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_LOCKING_MODE
|
||||
#ifdef SQLITE_DEFAULT_LOCKING_MODE
|
||||
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
|
||||
#endif
|
||||
#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
|
||||
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
|
||||
#endif
|
||||
#if SQLITE_DISABLE_DIRSYNC
|
||||
#ifdef SQLITE_DISABLE_DIRSYNC
|
||||
"DISABLE_DIRSYNC",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_LFS
|
||||
#ifdef SQLITE_DISABLE_LFS
|
||||
"DISABLE_LFS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
"ENABLE_API_ARMOR",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_ATOMIC_WRITE
|
||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
||||
"ENABLE_ATOMIC_WRITE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_CEROD
|
||||
#ifdef SQLITE_ENABLE_CEROD
|
||||
"ENABLE_CEROD",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_COLUMN_METADATA
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
"ENABLE_COLUMN_METADATA",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
"ENABLE_EXPENSIVE_ASSERT",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS1
|
||||
#ifdef SQLITE_ENABLE_FTS1
|
||||
"ENABLE_FTS1",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS2
|
||||
#ifdef SQLITE_ENABLE_FTS2
|
||||
"ENABLE_FTS2",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS3
|
||||
#ifdef SQLITE_ENABLE_FTS3
|
||||
"ENABLE_FTS3",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
"ENABLE_FTS3_PARENTHESIS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS4
|
||||
#ifdef SQLITE_ENABLE_FTS4
|
||||
"ENABLE_FTS4",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_ICU
|
||||
#ifdef SQLITE_ENABLE_ICU
|
||||
"ENABLE_ICU",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_IOTRACE
|
||||
#ifdef SQLITE_ENABLE_IOTRACE
|
||||
"ENABLE_IOTRACE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_LOAD_EXTENSION
|
||||
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
|
||||
"ENABLE_LOAD_EXTENSION",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
||||
"ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
"ENABLE_MEMORY_MANAGEMENT",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_MEMSYS3
|
||||
#ifdef SQLITE_ENABLE_MEMSYS3
|
||||
"ENABLE_MEMSYS3",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_MEMSYS5
|
||||
#ifdef SQLITE_ENABLE_MEMSYS5
|
||||
"ENABLE_MEMSYS5",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
"ENABLE_OVERSIZE_CELL_CHECK",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_RTREE
|
||||
#ifdef SQLITE_ENABLE_RTREE
|
||||
"ENABLE_RTREE",
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
@@ -125,31 +122,31 @@ static const char * const azCompileOpt[] = {
|
||||
#elif defined(SQLITE_ENABLE_STAT3)
|
||||
"ENABLE_STAT3",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
"ENABLE_UNLOCK_NOTIFY",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
|
||||
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
|
||||
"ENABLE_UPDATE_DELETE_LIMIT",
|
||||
#endif
|
||||
#if SQLITE_HAS_CODEC
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
"HAS_CODEC",
|
||||
#endif
|
||||
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
|
||||
#ifdef SQLITE_HAVE_ISNAN
|
||||
"HAVE_ISNAN",
|
||||
#endif
|
||||
#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
|
||||
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
|
||||
"HOMEGROWN_RECURSIVE_MUTEX",
|
||||
#endif
|
||||
#if SQLITE_IGNORE_AFP_LOCK_ERRORS
|
||||
#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
|
||||
"IGNORE_AFP_LOCK_ERRORS",
|
||||
#endif
|
||||
#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
|
||||
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
|
||||
"IGNORE_FLOCK_LOCK_ERRORS",
|
||||
#endif
|
||||
#ifdef SQLITE_INT64_TYPE
|
||||
"INT64_TYPE",
|
||||
#endif
|
||||
#if SQLITE_LOCK_TRACE
|
||||
#ifdef SQLITE_LOCK_TRACE
|
||||
"LOCK_TRACE",
|
||||
#endif
|
||||
#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
|
||||
@@ -158,226 +155,226 @@ static const char * const azCompileOpt[] = {
|
||||
#ifdef SQLITE_MAX_SCHEMA_RETRY
|
||||
"MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
|
||||
#endif
|
||||
#if SQLITE_MEMDEBUG
|
||||
#ifdef SQLITE_MEMDEBUG
|
||||
"MEMDEBUG",
|
||||
#endif
|
||||
#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
|
||||
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
|
||||
"MIXED_ENDIAN_64BIT_FLOAT",
|
||||
#endif
|
||||
#if SQLITE_NO_SYNC
|
||||
#ifdef SQLITE_NO_SYNC
|
||||
"NO_SYNC",
|
||||
#endif
|
||||
#if SQLITE_OMIT_ALTERTABLE
|
||||
#ifdef SQLITE_OMIT_ALTERTABLE
|
||||
"OMIT_ALTERTABLE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_ANALYZE
|
||||
#ifdef SQLITE_OMIT_ANALYZE
|
||||
"OMIT_ANALYZE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_ATTACH
|
||||
#ifdef SQLITE_OMIT_ATTACH
|
||||
"OMIT_ATTACH",
|
||||
#endif
|
||||
#if SQLITE_OMIT_AUTHORIZATION
|
||||
#ifdef SQLITE_OMIT_AUTHORIZATION
|
||||
"OMIT_AUTHORIZATION",
|
||||
#endif
|
||||
#if SQLITE_OMIT_AUTOINCREMENT
|
||||
#ifdef SQLITE_OMIT_AUTOINCREMENT
|
||||
"OMIT_AUTOINCREMENT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_AUTOINIT
|
||||
#ifdef SQLITE_OMIT_AUTOINIT
|
||||
"OMIT_AUTOINIT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
"OMIT_AUTOMATIC_INDEX",
|
||||
#endif
|
||||
#if SQLITE_OMIT_AUTORESET
|
||||
#ifdef SQLITE_OMIT_AUTORESET
|
||||
"OMIT_AUTORESET",
|
||||
#endif
|
||||
#if SQLITE_OMIT_AUTOVACUUM
|
||||
#ifdef SQLITE_OMIT_AUTOVACUUM
|
||||
"OMIT_AUTOVACUUM",
|
||||
#endif
|
||||
#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
|
||||
#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
|
||||
"OMIT_BETWEEN_OPTIMIZATION",
|
||||
#endif
|
||||
#if SQLITE_OMIT_BLOB_LITERAL
|
||||
#ifdef SQLITE_OMIT_BLOB_LITERAL
|
||||
"OMIT_BLOB_LITERAL",
|
||||
#endif
|
||||
#if SQLITE_OMIT_BTREECOUNT
|
||||
#ifdef SQLITE_OMIT_BTREECOUNT
|
||||
"OMIT_BTREECOUNT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_BUILTIN_TEST
|
||||
#ifdef SQLITE_OMIT_BUILTIN_TEST
|
||||
"OMIT_BUILTIN_TEST",
|
||||
#endif
|
||||
#if SQLITE_OMIT_CAST
|
||||
#ifdef SQLITE_OMIT_CAST
|
||||
"OMIT_CAST",
|
||||
#endif
|
||||
#if SQLITE_OMIT_CHECK
|
||||
#ifdef SQLITE_OMIT_CHECK
|
||||
"OMIT_CHECK",
|
||||
#endif
|
||||
#if SQLITE_OMIT_COMPLETE
|
||||
#ifdef SQLITE_OMIT_COMPLETE
|
||||
"OMIT_COMPLETE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_COMPOUND_SELECT
|
||||
#ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
"OMIT_COMPOUND_SELECT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_CTE
|
||||
#ifdef SQLITE_OMIT_CTE
|
||||
"OMIT_CTE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DATETIME_FUNCS
|
||||
#ifdef SQLITE_OMIT_DATETIME_FUNCS
|
||||
"OMIT_DATETIME_FUNCS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DECLTYPE
|
||||
#ifdef SQLITE_OMIT_DECLTYPE
|
||||
"OMIT_DECLTYPE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DEPRECATED
|
||||
#ifdef SQLITE_OMIT_DEPRECATED
|
||||
"OMIT_DEPRECATED",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DISKIO
|
||||
#ifdef SQLITE_OMIT_DISKIO
|
||||
"OMIT_DISKIO",
|
||||
#endif
|
||||
#if SQLITE_OMIT_EXPLAIN
|
||||
#ifdef SQLITE_OMIT_EXPLAIN
|
||||
"OMIT_EXPLAIN",
|
||||
#endif
|
||||
#if SQLITE_OMIT_FLAG_PRAGMAS
|
||||
#ifdef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
"OMIT_FLAG_PRAGMAS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_FLOATING_POINT
|
||||
#ifdef SQLITE_OMIT_FLOATING_POINT
|
||||
"OMIT_FLOATING_POINT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_FOREIGN_KEY
|
||||
#ifdef SQLITE_OMIT_FOREIGN_KEY
|
||||
"OMIT_FOREIGN_KEY",
|
||||
#endif
|
||||
#if SQLITE_OMIT_GET_TABLE
|
||||
#ifdef SQLITE_OMIT_GET_TABLE
|
||||
"OMIT_GET_TABLE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_INCRBLOB
|
||||
#ifdef SQLITE_OMIT_INCRBLOB
|
||||
"OMIT_INCRBLOB",
|
||||
#endif
|
||||
#if SQLITE_OMIT_INTEGRITY_CHECK
|
||||
#ifdef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
"OMIT_INTEGRITY_CHECK",
|
||||
#endif
|
||||
#if SQLITE_OMIT_LIKE_OPTIMIZATION
|
||||
#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
|
||||
"OMIT_LIKE_OPTIMIZATION",
|
||||
#endif
|
||||
#if SQLITE_OMIT_LOAD_EXTENSION
|
||||
#ifdef SQLITE_OMIT_LOAD_EXTENSION
|
||||
"OMIT_LOAD_EXTENSION",
|
||||
#endif
|
||||
#if SQLITE_OMIT_LOCALTIME
|
||||
#ifdef SQLITE_OMIT_LOCALTIME
|
||||
"OMIT_LOCALTIME",
|
||||
#endif
|
||||
#if SQLITE_OMIT_LOOKASIDE
|
||||
#ifdef SQLITE_OMIT_LOOKASIDE
|
||||
"OMIT_LOOKASIDE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_MEMORYDB
|
||||
#ifdef SQLITE_OMIT_MEMORYDB
|
||||
"OMIT_MEMORYDB",
|
||||
#endif
|
||||
#if SQLITE_OMIT_OR_OPTIMIZATION
|
||||
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
|
||||
"OMIT_OR_OPTIMIZATION",
|
||||
#endif
|
||||
#if SQLITE_OMIT_PAGER_PRAGMAS
|
||||
#ifdef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
"OMIT_PAGER_PRAGMAS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_PRAGMA
|
||||
#ifdef SQLITE_OMIT_PRAGMA
|
||||
"OMIT_PRAGMA",
|
||||
#endif
|
||||
#if SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
"OMIT_PROGRESS_CALLBACK",
|
||||
#endif
|
||||
#if SQLITE_OMIT_QUICKBALANCE
|
||||
#ifdef SQLITE_OMIT_QUICKBALANCE
|
||||
"OMIT_QUICKBALANCE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_REINDEX
|
||||
#ifdef SQLITE_OMIT_REINDEX
|
||||
"OMIT_REINDEX",
|
||||
#endif
|
||||
#if SQLITE_OMIT_SCHEMA_PRAGMAS
|
||||
#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
|
||||
"OMIT_SCHEMA_PRAGMAS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
|
||||
#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
|
||||
"OMIT_SCHEMA_VERSION_PRAGMAS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_SHARED_CACHE
|
||||
#ifdef SQLITE_OMIT_SHARED_CACHE
|
||||
"OMIT_SHARED_CACHE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_SUBQUERY
|
||||
#ifdef SQLITE_OMIT_SUBQUERY
|
||||
"OMIT_SUBQUERY",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TCL_VARIABLE
|
||||
#ifdef SQLITE_OMIT_TCL_VARIABLE
|
||||
"OMIT_TCL_VARIABLE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TEMPDB
|
||||
#ifdef SQLITE_OMIT_TEMPDB
|
||||
"OMIT_TEMPDB",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TRACE
|
||||
#ifdef SQLITE_OMIT_TRACE
|
||||
"OMIT_TRACE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TRIGGER
|
||||
#ifdef SQLITE_OMIT_TRIGGER
|
||||
"OMIT_TRIGGER",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
|
||||
#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
|
||||
"OMIT_TRUNCATE_OPTIMIZATION",
|
||||
#endif
|
||||
#if SQLITE_OMIT_UTF16
|
||||
#ifdef SQLITE_OMIT_UTF16
|
||||
"OMIT_UTF16",
|
||||
#endif
|
||||
#if SQLITE_OMIT_VACUUM
|
||||
#ifdef SQLITE_OMIT_VACUUM
|
||||
"OMIT_VACUUM",
|
||||
#endif
|
||||
#if SQLITE_OMIT_VIEW
|
||||
#ifdef SQLITE_OMIT_VIEW
|
||||
"OMIT_VIEW",
|
||||
#endif
|
||||
#if SQLITE_OMIT_VIRTUALTABLE
|
||||
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
||||
"OMIT_VIRTUALTABLE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_WAL
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
"OMIT_WAL",
|
||||
#endif
|
||||
#if SQLITE_OMIT_WSD
|
||||
#ifdef SQLITE_OMIT_WSD
|
||||
"OMIT_WSD",
|
||||
#endif
|
||||
#if SQLITE_OMIT_XFER_OPT
|
||||
#ifdef SQLITE_OMIT_XFER_OPT
|
||||
"OMIT_XFER_OPT",
|
||||
#endif
|
||||
#if SQLITE_PERFORMANCE_TRACE
|
||||
#ifdef SQLITE_PERFORMANCE_TRACE
|
||||
"PERFORMANCE_TRACE",
|
||||
#endif
|
||||
#if SQLITE_PROXY_DEBUG
|
||||
#ifdef SQLITE_PROXY_DEBUG
|
||||
"PROXY_DEBUG",
|
||||
#endif
|
||||
#if SQLITE_RTREE_INT_ONLY
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
"RTREE_INT_ONLY",
|
||||
#endif
|
||||
#if SQLITE_SECURE_DELETE
|
||||
#ifdef SQLITE_SECURE_DELETE
|
||||
"SECURE_DELETE",
|
||||
#endif
|
||||
#if SQLITE_SMALL_STACK
|
||||
#ifdef SQLITE_SMALL_STACK
|
||||
"SMALL_STACK",
|
||||
#endif
|
||||
#if SQLITE_SOUNDEX
|
||||
#ifdef SQLITE_SOUNDEX
|
||||
"SOUNDEX",
|
||||
#endif
|
||||
#if SQLITE_SYSTEM_MALLOC
|
||||
#ifdef SQLITE_SYSTEM_MALLOC
|
||||
"SYSTEM_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_TCL
|
||||
#ifdef SQLITE_TCL
|
||||
"TCL",
|
||||
#endif
|
||||
#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
|
||||
"TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
|
||||
#endif
|
||||
#if SQLITE_TEST
|
||||
#ifdef SQLITE_TEST
|
||||
"TEST",
|
||||
#endif
|
||||
#if defined(SQLITE_THREADSAFE)
|
||||
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
|
||||
#endif
|
||||
#if SQLITE_USE_ALLOCA
|
||||
#ifdef SQLITE_USE_ALLOCA
|
||||
"USE_ALLOCA",
|
||||
#endif
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
"USER_AUTHENTICATION",
|
||||
#endif
|
||||
#if SQLITE_WIN32_MALLOC
|
||||
#ifdef SQLITE_WIN32_MALLOC
|
||||
"WIN32_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_ZERO_MALLOC
|
||||
#ifdef SQLITE_ZERO_MALLOC
|
||||
"ZERO_MALLOC"
|
||||
#endif
|
||||
};
|
||||
@@ -391,13 +388,6 @@ static const char * const azCompileOpt[] = {
|
||||
*/
|
||||
int sqlite3_compileoption_used(const char *zOptName){
|
||||
int i, n;
|
||||
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
if( zOptName==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
|
||||
n = sqlite3Strlen30(zOptName);
|
||||
|
||||
|
||||
+11
-13
@@ -16,7 +16,7 @@
|
||||
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
**
|
||||
** SQLite processes all times and dates as julian day numbers. The
|
||||
** SQLite processes all times and dates as Julian Day numbers. The
|
||||
** dates and times are stored as the number of days since noon
|
||||
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
|
||||
** calendar system.
|
||||
@@ -31,7 +31,7 @@
|
||||
**
|
||||
** The Gregorian calendar system is used for all dates and times,
|
||||
** even those that predate the Gregorian calendar. Historians usually
|
||||
** use the julian calendar for dates prior to 1582-10-15 and for some
|
||||
** use the Julian calendar for dates prior to 1582-10-15 and for some
|
||||
** dates afterwards, depending on locale. Beware of this difference.
|
||||
**
|
||||
** The conversion algorithms are implemented based on descriptions
|
||||
@@ -304,7 +304,7 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to parse the given string into a julian day number. Return
|
||||
** Attempt to parse the given string into a Julian Day Number. Return
|
||||
** the number of errors.
|
||||
**
|
||||
** The following are acceptable forms for the input string:
|
||||
@@ -412,9 +412,8 @@ static void clearYMD_HMS_TZ(DateTime *p){
|
||||
** already, check for an MSVC build environment that provides
|
||||
** localtime_s().
|
||||
*/
|
||||
#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
|
||||
&& defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
|
||||
#undef HAVE_LOCALTIME_S
|
||||
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
|
||||
defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
|
||||
#define HAVE_LOCALTIME_S 1
|
||||
#endif
|
||||
|
||||
@@ -434,7 +433,8 @@ static void clearYMD_HMS_TZ(DateTime *p){
|
||||
*/
|
||||
static int osLocaltime(time_t *t, struct tm *pTm){
|
||||
int rc;
|
||||
#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
|
||||
#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
|
||||
&& (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
|
||||
struct tm *pX;
|
||||
#if SQLITE_THREADSAFE>0
|
||||
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
||||
@@ -451,7 +451,7 @@ static int osLocaltime(time_t *t, struct tm *pTm){
|
||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
|
||||
#endif
|
||||
#if HAVE_LOCALTIME_R
|
||||
#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
|
||||
rc = localtime_r(t, pTm)==0;
|
||||
#else
|
||||
rc = localtime_s(pTm, t);
|
||||
@@ -875,7 +875,7 @@ static void dateFunc(
|
||||
** %f ** fractional seconds SS.SSS
|
||||
** %H hour 00-24
|
||||
** %j day of year 000-366
|
||||
** %J ** julian day number
|
||||
** %J ** Julian day number
|
||||
** %m month 01-12
|
||||
** %M minute 00-59
|
||||
** %s seconds since 1970-01-01
|
||||
@@ -895,10 +895,8 @@ static void strftimeFunc(
|
||||
size_t i,j;
|
||||
char *z;
|
||||
sqlite3 *db;
|
||||
const char *zFmt;
|
||||
const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
|
||||
char zBuf[100];
|
||||
if( argc==0 ) return;
|
||||
zFmt = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
|
||||
db = sqlite3_context_db_handle(context);
|
||||
for(i=0, n=1; zFmt[i]; i++, n++){
|
||||
@@ -1092,7 +1090,7 @@ static void currentTimeFunc(
|
||||
iT = sqlite3StmtCurrentTime(context);
|
||||
if( iT<=0 ) return;
|
||||
t = iT/1000 - 10000*(sqlite3_int64)21086676;
|
||||
#if HAVE_GMTIME_R
|
||||
#ifdef HAVE_GMTIME_R
|
||||
pTm = gmtime_r(&t, &sNow);
|
||||
#else
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
|
||||
+4
-4
@@ -189,7 +189,7 @@ Expr *sqlite3LimitWhere(
|
||||
|
||||
pInClause->x.pSelect = pSelect;
|
||||
pInClause->flags |= EP_xIsSelect;
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pInClause);
|
||||
sqlite3ExprSetHeight(pParse, pInClause);
|
||||
return pInClause;
|
||||
|
||||
/* something went wrong. clean up anything allocated. */
|
||||
@@ -226,8 +226,8 @@ void sqlite3DeleteFrom(
|
||||
WhereInfo *pWInfo; /* Information about the WHERE clause */
|
||||
Index *pIdx; /* For looping over indices of the table */
|
||||
int iTabCur; /* Cursor number for the table */
|
||||
int iDataCur = 0; /* VDBE cursor for the canonical data source */
|
||||
int iIdxCur = 0; /* Cursor number of the first index */
|
||||
int iDataCur; /* VDBE cursor for the canonical data source */
|
||||
int iIdxCur; /* Cursor number of the first index */
|
||||
int nIdx; /* Number of indices */
|
||||
sqlite3 *db; /* Main database structure */
|
||||
AuthContext sContext; /* Authorization context */
|
||||
@@ -481,7 +481,7 @@ void sqlite3DeleteFrom(
|
||||
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
|
||||
assert( !IsVirtual(pTab) );
|
||||
if( aToOpen[iDataCur-iTabCur] ){
|
||||
assert( pPk!=0 || pTab->pSelect!=0 );
|
||||
assert( pPk!=0 );
|
||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
|
||||
+53
-127
@@ -69,11 +69,10 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
||||
Expr *sqlite3ExprAddCollateToken(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pExpr, /* Add the "COLLATE" clause to this expression */
|
||||
const Token *pCollName, /* Name of collating sequence */
|
||||
int dequote /* True to dequote pCollName */
|
||||
const Token *pCollName /* Name of collating sequence */
|
||||
){
|
||||
if( pCollName->n>0 ){
|
||||
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
|
||||
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
|
||||
if( pNew ){
|
||||
pNew->pLeft = pExpr;
|
||||
pNew->flags |= EP_Collate|EP_Skip;
|
||||
@@ -87,7 +86,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||
assert( zC!=0 );
|
||||
s.z = zC;
|
||||
s.n = sqlite3Strlen30(s.z);
|
||||
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
|
||||
return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -133,9 +132,9 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
|
||||
break;
|
||||
}
|
||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN
|
||||
if( p->pTab!=0
|
||||
&& (op==TK_AGG_COLUMN || op==TK_COLUMN
|
||||
|| op==TK_REGISTER || op==TK_TRIGGER)
|
||||
&& p->pTab!=0
|
||||
){
|
||||
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
|
||||
** a TK_COLUMN but was previously evaluated and cached in a register */
|
||||
@@ -147,25 +146,10 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
break;
|
||||
}
|
||||
if( p->flags & EP_Collate ){
|
||||
if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
|
||||
if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
|
||||
p = p->pLeft;
|
||||
}else{
|
||||
Expr *pNext = p->pRight;
|
||||
/* The Expr.x union is never used at the same time as Expr.pRight */
|
||||
assert( p->x.pList==0 || p->pRight==0 );
|
||||
/* p->flags holds EP_Collate and p->pLeft->flags does not. And
|
||||
** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
|
||||
** least one EP_Collate. Thus the following two ALWAYS. */
|
||||
if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
|
||||
int i;
|
||||
for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
|
||||
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
|
||||
pNext = p->x.pList->a[i].pExpr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
p = pNext;
|
||||
p = p->pRight;
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
@@ -371,9 +355,6 @@ static void heightOfSelect(Select *p, int *pnHeight){
|
||||
** Expr.pSelect member has a height of 1. Any other expression
|
||||
** has a height equal to the maximum height of any other
|
||||
** referenced Expr plus one.
|
||||
**
|
||||
** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
|
||||
** if appropriate.
|
||||
*/
|
||||
static void exprSetHeight(Expr *p){
|
||||
int nHeight = 0;
|
||||
@@ -381,9 +362,8 @@ static void exprSetHeight(Expr *p){
|
||||
heightOfExpr(p->pRight, &nHeight);
|
||||
if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
heightOfSelect(p->x.pSelect, &nHeight);
|
||||
}else if( p->x.pList ){
|
||||
}else{
|
||||
heightOfExprList(p->x.pList, &nHeight);
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
p->nHeight = nHeight + 1;
|
||||
}
|
||||
@@ -392,12 +372,8 @@ static void exprSetHeight(Expr *p){
|
||||
** Set the Expr.nHeight variable using the exprSetHeight() function. If
|
||||
** the height is greater than the maximum allowed expression depth,
|
||||
** leave an error in pParse.
|
||||
**
|
||||
** Also propagate all EP_Propagate flags from the Expr.x.pList into
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
if( pParse->nErr ) return;
|
||||
void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
|
||||
exprSetHeight(p);
|
||||
sqlite3ExprCheckHeight(pParse, p->nHeight);
|
||||
}
|
||||
@@ -411,17 +387,8 @@ int sqlite3SelectExprHeight(Select *p){
|
||||
heightOfSelect(p, &nHeight);
|
||||
return nHeight;
|
||||
}
|
||||
#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */
|
||||
/*
|
||||
** Propagate all EP_Propagate flags from the Expr.x.pList into
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
}
|
||||
#define exprSetHeight(y)
|
||||
#else
|
||||
#define exprSetHeight(y)
|
||||
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
||||
|
||||
/*
|
||||
@@ -523,11 +490,11 @@ void sqlite3ExprAttachSubtrees(
|
||||
}else{
|
||||
if( pRight ){
|
||||
pRoot->pRight = pRight;
|
||||
pRoot->flags |= EP_Propagate & pRight->flags;
|
||||
pRoot->flags |= EP_Collate & pRight->flags;
|
||||
}
|
||||
if( pLeft ){
|
||||
pRoot->pLeft = pLeft;
|
||||
pRoot->flags |= EP_Propagate & pLeft->flags;
|
||||
pRoot->flags |= EP_Collate & pLeft->flags;
|
||||
}
|
||||
exprSetHeight(pRoot);
|
||||
}
|
||||
@@ -548,7 +515,7 @@ Expr *sqlite3PExpr(
|
||||
const Token *pToken /* Argument token */
|
||||
){
|
||||
Expr *p;
|
||||
if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){
|
||||
if( op==TK_AND && pLeft && pRight ){
|
||||
/* Take advantage of short-circuit false optimization for AND */
|
||||
p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
|
||||
}else{
|
||||
@@ -627,7 +594,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
||||
}
|
||||
pNew->x.pList = pList;
|
||||
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pNew);
|
||||
sqlite3ExprSetHeight(pParse, pNew);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
@@ -1243,39 +1210,20 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the bitwise-OR of all Expr.flags fields in the given
|
||||
** ExprList.
|
||||
*/
|
||||
u32 sqlite3ExprListFlags(const ExprList *pList){
|
||||
int i;
|
||||
u32 m = 0;
|
||||
if( pList ){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
m |= pList->a[i].pExpr->flags;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
** These routines are Walker callbacks used to check expressions to
|
||||
** see if they are "constant" for some definition of constant. The
|
||||
** Walker.eCode value determines the type of "constant" we are looking
|
||||
** for.
|
||||
** These routines are Walker callbacks. Walker.u.pi is a pointer
|
||||
** to an integer. These routines are checking an expression to see
|
||||
** if it is a constant. Set *Walker.u.i to 0 if the expression is
|
||||
** not constant.
|
||||
**
|
||||
** These callback routines are used to implement the following:
|
||||
**
|
||||
** sqlite3ExprIsConstant() pWalker->eCode==1
|
||||
** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2
|
||||
** sqlite3ExprRefOneTableOnly() pWalker->eCode==3
|
||||
** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5
|
||||
**
|
||||
** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
|
||||
** is found to not be a constant.
|
||||
** sqlite3ExprIsConstant() pWalker->u.i==1
|
||||
** sqlite3ExprIsConstantNotJoin() pWalker->u.i==2
|
||||
** sqlite3ExprIsConstantOrFunction() pWalker->u.i==3 or 4
|
||||
**
|
||||
** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
|
||||
** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing
|
||||
** an existing schema and 4 when processing a new statement. A bound
|
||||
** in a CREATE TABLE statement. The Walker.u.i value is 4 when parsing
|
||||
** an existing schema and 3 when processing a new statement. A bound
|
||||
** parameter raises an error for new statements, but is silently converted
|
||||
** to NULL for existing schemas. This allows sqlite_master tables that
|
||||
** contain a bound parameter because they were generated by older versions
|
||||
@@ -1284,25 +1232,23 @@ u32 sqlite3ExprListFlags(const ExprList *pList){
|
||||
*/
|
||||
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
|
||||
/* If pWalker->eCode is 2 then any term of the expression that comes from
|
||||
** the ON or USING clauses of a left join disqualifies the expression
|
||||
/* If pWalker->u.i is 2 then any term of the expression that comes from
|
||||
** the ON or USING clauses of a join disqualifies the expression
|
||||
** from being considered constant. */
|
||||
if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
pWalker->eCode = 0;
|
||||
if( pWalker->u.i==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
pWalker->u.i = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
|
||||
switch( pExpr->op ){
|
||||
/* Consider functions to be constant if all their arguments are constant
|
||||
** and either pWalker->eCode==4 or 5 or the function has the
|
||||
** SQLITE_FUNC_CONST flag. */
|
||||
** and either pWalker->u.i==3 or 4 or the function as the SQLITE_FUNC_CONST
|
||||
** flag. */
|
||||
case TK_FUNCTION:
|
||||
if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
|
||||
if( pWalker->u.i>=3 || ExprHasProperty(pExpr,EP_Constant) ){
|
||||
return WRC_Continue;
|
||||
}else{
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
/* Fall through */
|
||||
case TK_ID:
|
||||
case TK_COLUMN:
|
||||
case TK_AGG_FUNCTION:
|
||||
@@ -1311,22 +1257,18 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pExpr->op==TK_COLUMN );
|
||||
testcase( pExpr->op==TK_AGG_FUNCTION );
|
||||
testcase( pExpr->op==TK_AGG_COLUMN );
|
||||
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
|
||||
return WRC_Continue;
|
||||
}else{
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
pWalker->u.i = 0;
|
||||
return WRC_Abort;
|
||||
case TK_VARIABLE:
|
||||
if( pWalker->eCode==5 ){
|
||||
if( pWalker->u.i==4 ){
|
||||
/* Silently convert bound parameters that appear inside of CREATE
|
||||
** statements into a NULL when parsing the CREATE statement text out
|
||||
** of the sqlite_master table */
|
||||
pExpr->op = TK_NULL;
|
||||
}else if( pWalker->eCode==4 ){
|
||||
}else if( pWalker->u.i==3 ){
|
||||
/* A bound parameter in a CREATE statement that originates from
|
||||
** sqlite3_prepare() causes an error */
|
||||
pWalker->eCode = 0;
|
||||
pWalker->u.i = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
/* Fall through */
|
||||
@@ -1338,22 +1280,21 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
pWalker->eCode = 0;
|
||||
pWalker->u.i = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
static int exprIsConst(Expr *p, int initFlag, int iCur){
|
||||
static int exprIsConst(Expr *p, int initFlag){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.eCode = initFlag;
|
||||
w.u.i = initFlag;
|
||||
w.xExprCallback = exprNodeIsConstant;
|
||||
w.xSelectCallback = selectNodeIsConstant;
|
||||
w.u.iCur = iCur;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode;
|
||||
return w.u.i;
|
||||
}
|
||||
|
||||
/*
|
||||
** Walk an expression tree. Return non-zero if the expression is constant
|
||||
** Walk an expression tree. Return 1 if the expression is constant
|
||||
** and 0 if it involves variables or function calls.
|
||||
**
|
||||
** For the purposes of this function, a double-quoted string (ex: "abc")
|
||||
@@ -1361,31 +1302,21 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){
|
||||
** a constant.
|
||||
*/
|
||||
int sqlite3ExprIsConstant(Expr *p){
|
||||
return exprIsConst(p, 1, 0);
|
||||
return exprIsConst(p, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Walk an expression tree. Return non-zero if the expression is constant
|
||||
** Walk an expression tree. Return 1 if the expression is constant
|
||||
** that does no originate from the ON or USING clauses of a join.
|
||||
** Return 0 if it involves variables or function calls or terms from
|
||||
** an ON or USING clause.
|
||||
*/
|
||||
int sqlite3ExprIsConstantNotJoin(Expr *p){
|
||||
return exprIsConst(p, 2, 0);
|
||||
return exprIsConst(p, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
** Walk an expression tree. Return non-zero if the expression constant
|
||||
** for any single row of the table with cursor iCur. In other words, the
|
||||
** expression must not refer to any non-deterministic function nor any
|
||||
** table other than iCur.
|
||||
*/
|
||||
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
return exprIsConst(p, 3, iCur);
|
||||
}
|
||||
|
||||
/*
|
||||
** Walk an expression tree. Return non-zero if the expression is constant
|
||||
** Walk an expression tree. Return 1 if the expression is constant
|
||||
** or a function call with constant arguments. Return and 0 if there
|
||||
** are any variables.
|
||||
**
|
||||
@@ -1395,7 +1326,7 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
*/
|
||||
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
|
||||
assert( isInit==0 || isInit==1 );
|
||||
return exprIsConst(p, 4+isInit, 0);
|
||||
return exprIsConst(p, 3+isInit);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1462,8 +1393,7 @@ int sqlite3ExprCanBeNull(const Expr *p){
|
||||
return 0;
|
||||
case TK_COLUMN:
|
||||
assert( p->pTab!=0 );
|
||||
return ExprHasProperty(p, EP_CanBeNull) ||
|
||||
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
|
||||
return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
@@ -1906,6 +1836,7 @@ int sqlite3CodeSubselect(
|
||||
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
||||
pSelect->iLimit = 0;
|
||||
testcase( pSelect->selFlags & SF_Distinct );
|
||||
pSelect->selFlags &= ~SF_Distinct;
|
||||
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
|
||||
if( sqlite3Select(pParse, pSelect, &dest) ){
|
||||
sqlite3KeyInfoUnref(pKeyInfo);
|
||||
@@ -2304,8 +2235,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
||||
int idxLru;
|
||||
struct yColCache *p;
|
||||
|
||||
/* Unless an error has occurred, register numbers are always positive. */
|
||||
assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
|
||||
assert( iReg>0 ); /* Register numbers are always positive */
|
||||
assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
|
||||
|
||||
/* The SQLITE_ColumnCache flag disables the column cache. This is used
|
||||
@@ -3053,10 +2983,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
/* If the column has REAL affinity, it may currently be stored as an
|
||||
** integer. Use OP_RealAffinity to make sure it is really real.
|
||||
**
|
||||
** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
|
||||
** floating point when extracting it from the record. */
|
||||
** integer. Use OP_RealAffinity to make sure it is really real. */
|
||||
if( pExpr->iColumn>=0
|
||||
&& pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
|
||||
){
|
||||
@@ -4118,11 +4045,10 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
|
||||
int i;
|
||||
struct SrcCount *p = pWalker->u.pSrcCount;
|
||||
SrcList *pSrc = p->pSrc;
|
||||
int nSrc = pSrc ? pSrc->nSrc : 0;
|
||||
for(i=0; i<nSrc; i++){
|
||||
for(i=0; i<pSrc->nSrc; i++){
|
||||
if( pExpr->iTable==pSrc->a[i].iCursor ) break;
|
||||
}
|
||||
if( i<nSrc ){
|
||||
if( i<pSrc->nSrc ){
|
||||
p->nThis++;
|
||||
}else{
|
||||
p->nOther++;
|
||||
|
||||
+21
-60
@@ -437,7 +437,7 @@ static void fkLookupParent(
|
||||
OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
|
||||
}else{
|
||||
if( nIncr>0 && pFKey->isDeferred==0 ){
|
||||
sqlite3MayAbort(pParse);
|
||||
sqlite3ParseToplevel(pParse)->mayAbort = 1;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
}
|
||||
@@ -509,10 +509,6 @@ static Expr *exprTableColumn(
|
||||
** code for an SQL UPDATE operation, this function may be called twice -
|
||||
** once to "delete" the old row and once to "insert" the new row.
|
||||
**
|
||||
** Parameter nIncr is passed -1 when inserting a row (as this may decrease
|
||||
** the number of FK violations in the db) or +1 when deleting one (as this
|
||||
** may increase the number of FK constraint problems).
|
||||
**
|
||||
** The code generated by this function scans through the rows in the child
|
||||
** table that correspond to the parent table row being deleted or inserted.
|
||||
** For each child row found, one of the following actions is taken:
|
||||
@@ -629,9 +625,13 @@ static void fkScanChildren(
|
||||
sqlite3ResolveExprNames(&sNameContext, pWhere);
|
||||
|
||||
/* Create VDBE to loop through the entries in pSrc that match the WHERE
|
||||
** clause. For each row found, increment either the deferred or immediate
|
||||
** foreign key constraint counter. */
|
||||
** clause. If the constraint is not deferred, throw an exception for
|
||||
** each row found. Otherwise, for deferred constraints, increment the
|
||||
** deferred constraint counter by nIncr for each row selected. */
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
|
||||
if( nIncr>0 && pFKey->isDeferred==0 ){
|
||||
sqlite3ParseToplevel(pParse)->mayAbort = 1;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
if( pWInfo ){
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
@@ -810,24 +810,6 @@ static int fkParentIsModified(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the parser passed as the first argument is being
|
||||
** used to code a trigger that is really a "SET NULL" action belonging
|
||||
** to trigger pFKey.
|
||||
*/
|
||||
static int isSetNullAction(Parse *pParse, FKey *pFKey){
|
||||
Parse *pTop = sqlite3ParseToplevel(pParse);
|
||||
if( pTop->pTriggerPrg ){
|
||||
Trigger *p = pTop->pTriggerPrg->pTrigger;
|
||||
if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
|
||||
|| (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called when inserting, deleting or updating a row of
|
||||
** table pTab to generate VDBE code to perform foreign key constraint
|
||||
@@ -880,7 +862,7 @@ void sqlite3FkCheck(
|
||||
int *aiCol;
|
||||
int iCol;
|
||||
int i;
|
||||
int bIgnore = 0;
|
||||
int isIgnore = 0;
|
||||
|
||||
if( aChange
|
||||
&& sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
|
||||
@@ -939,7 +921,7 @@ void sqlite3FkCheck(
|
||||
int rcauth;
|
||||
char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
|
||||
rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
|
||||
bIgnore = (rcauth==SQLITE_IGNORE);
|
||||
isIgnore = (rcauth==SQLITE_IGNORE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -954,18 +936,12 @@ void sqlite3FkCheck(
|
||||
/* A row is being removed from the child table. Search for the parent.
|
||||
** If the parent does not exist, removing the child row resolves an
|
||||
** outstanding foreign key constraint violation. */
|
||||
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
|
||||
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
|
||||
}
|
||||
if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
|
||||
if( regNew!=0 ){
|
||||
/* A row is being added to the child table. If a parent row cannot
|
||||
** be found, adding the child row has violated the FK constraint.
|
||||
**
|
||||
** If this operation is being performed as part of a trigger program
|
||||
** that is actually a "SET NULL" action belonging to this very
|
||||
** foreign key, then omit this scan altogether. As all child key
|
||||
** values are guaranteed to be NULL, it is not possible for adding
|
||||
** this row to cause an FK violation. */
|
||||
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
|
||||
** be found, adding the child row has violated the FK constraint. */
|
||||
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
|
||||
}
|
||||
|
||||
sqlite3DbFree(db, aiFree);
|
||||
@@ -986,8 +962,8 @@ void sqlite3FkCheck(
|
||||
&& !pParse->pToplevel && !pParse->isMultiWrite
|
||||
){
|
||||
assert( regOld==0 && regNew!=0 );
|
||||
/* Inserting a single row into a parent table cannot cause (or fix)
|
||||
** an immediate foreign key violation. So do nothing in this case. */
|
||||
/* Inserting a single row into a parent table cannot cause an immediate
|
||||
** foreign key violation. So do nothing in this case. */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1011,28 +987,13 @@ void sqlite3FkCheck(
|
||||
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
|
||||
}
|
||||
if( regOld!=0 ){
|
||||
int eAction = pFKey->aAction[aChange!=0];
|
||||
/* If there is a RESTRICT action configured for the current operation
|
||||
** on the parent table of this FK, then throw an exception
|
||||
** immediately if the FK constraint is violated, even if this is a
|
||||
** deferred trigger. That's what RESTRICT means. To defer checking
|
||||
** the constraint, the FK should specify NO ACTION (represented
|
||||
** using OE_None). NO ACTION is the default. */
|
||||
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
|
||||
/* If this is a deferred FK constraint, or a CASCADE or SET NULL
|
||||
** action applies, then any foreign key violations caused by
|
||||
** removing the parent key will be rectified by the action trigger.
|
||||
** So do not set the "may-abort" flag in this case.
|
||||
**
|
||||
** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
|
||||
** may-abort flag will eventually be set on this statement anyway
|
||||
** (when this function is called as part of processing the UPDATE
|
||||
** within the action trigger).
|
||||
**
|
||||
** Note 2: At first glance it may seem like SQLite could simply omit
|
||||
** all OP_FkCounter related scans when either CASCADE or SET NULL
|
||||
** applies. The trouble starts if the CASCADE or SET NULL action
|
||||
** trigger causes other triggers or action rules attached to the
|
||||
** child table to fire. In these cases the fk constraint counters
|
||||
** might be set incorrectly if any OP_FkCounter related scans are
|
||||
** omitted. */
|
||||
if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
|
||||
sqlite3MayAbort(pParse);
|
||||
}
|
||||
}
|
||||
pItem->zName = 0;
|
||||
sqlite3SrcListDelete(db, pSrc);
|
||||
|
||||
+3
-18
@@ -22,9 +22,7 @@
|
||||
** Return the collating function associated with a function.
|
||||
*/
|
||||
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
|
||||
VdbeOp *pOp;
|
||||
assert( context->pVdbe!=0 );
|
||||
pOp = &context->pVdbe->aOp[context->iOp-1];
|
||||
VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
|
||||
assert( pOp->opcode==OP_CollSeq );
|
||||
assert( pOp->p4type==P4_COLLSEQ );
|
||||
return pOp->p4.pColl;
|
||||
@@ -159,8 +157,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||
default: {
|
||||
/* Because sqlite3_value_double() returns 0.0 if the argument is not
|
||||
** something that can be converted into a number, we have:
|
||||
** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
|
||||
** that cannot be converted to a numeric value.
|
||||
** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
|
||||
** cannot be converted to a numeric value.
|
||||
*/
|
||||
double rVal = sqlite3_value_double(argv[0]);
|
||||
if( rVal<0 ) rVal = -rVal;
|
||||
@@ -293,14 +291,6 @@ static void substrFunc(
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef SQLITE_SUBSTR_COMPATIBILITY
|
||||
/* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
|
||||
** as substr(X,1,N) - it returns the first N characters of X. This
|
||||
** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
|
||||
** from 2009-02-02 for compatibility of applications that exploited the
|
||||
** old buggy behavior. */
|
||||
if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
|
||||
#endif
|
||||
if( argc==3 ){
|
||||
p2 = sqlite3_value_int(argv[2]);
|
||||
if( p2<0 ){
|
||||
@@ -1652,11 +1642,6 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
||||
** then set aWc[0] through aWc[2] to the wildcard characters and
|
||||
** return TRUE. If the function is not a LIKE-style function then
|
||||
** return FALSE.
|
||||
**
|
||||
** *pIsNocase is set to true if uppercase and lowercase are equivalent for
|
||||
** the function (default for LIKE). If the function makes the distinction
|
||||
** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
|
||||
** false.
|
||||
*/
|
||||
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||
FuncDef *pDef;
|
||||
|
||||
+7
-23
@@ -46,16 +46,16 @@ const unsigned char sqlite3UpperToLower[] = {
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
|
||||
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
|
||||
96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
|
||||
112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
|
||||
192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
|
||||
208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
|
||||
224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
|
||||
224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
|
||||
239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -135,30 +135,15 @@ const unsigned char sqlite3CtypeMap[256] = {
|
||||
**
|
||||
** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
|
||||
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
|
||||
**
|
||||
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
|
||||
** disabled. The default value may be changed by compiling with the
|
||||
** SQLITE_USE_URI symbol defined.
|
||||
*/
|
||||
#ifndef SQLITE_USE_URI
|
||||
# define SQLITE_USE_URI 0
|
||||
#endif
|
||||
|
||||
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
|
||||
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
|
||||
** that compile-time option is omitted.
|
||||
*/
|
||||
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
|
||||
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
|
||||
#endif
|
||||
|
||||
/* The minimum PMA size is set to this value multiplied by the database
|
||||
** page size in bytes.
|
||||
*/
|
||||
#ifndef SQLITE_SORTER_PMASZ
|
||||
# define SQLITE_SORTER_PMASZ 250
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The following singleton contains the global configuration for
|
||||
** the SQLite library.
|
||||
@@ -189,7 +174,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
0, /* nPage */
|
||||
0, /* mxParserStack */
|
||||
0, /* sharedCacheEnabled */
|
||||
SQLITE_SORTER_PMASZ, /* szPma */
|
||||
/* All the rest should always be initialized to zero */
|
||||
0, /* isInit */
|
||||
0, /* inProgress */
|
||||
@@ -245,8 +229,8 @@ const Token sqlite3IntTokens[] = {
|
||||
**
|
||||
** IMPORTANT: Changing the pending byte to any value other than
|
||||
** 0x40000000 results in an incompatible database file format!
|
||||
** Changing the pending byte during operation will result in undefined
|
||||
** and incorrect behavior.
|
||||
** Changing the pending byte during operating results in undefined
|
||||
** and dileterious behavior.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
int sqlite3PendingByte = 0x40000000;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
# define sqlite3_column_table_name16 0
|
||||
# define sqlite3_column_origin_name 0
|
||||
# define sqlite3_column_origin_name16 0
|
||||
# define sqlite3_table_column_metadata 0
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_AUTHORIZATION
|
||||
|
||||
+99
-394
File diff suppressed because it is too large
Load Diff
+26
-34
@@ -75,13 +75,6 @@ static SQLITE_WSD struct Mem0Global {
|
||||
|
||||
#define mem0 GLOBAL(struct Mem0Global, mem0)
|
||||
|
||||
/*
|
||||
** Return the memory allocator mutex. sqlite3_status() needs it.
|
||||
*/
|
||||
sqlite3_mutex *sqlite3MallocMutex(void){
|
||||
return mem0.mutex;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine runs when the memory allocator sees that the
|
||||
** total memory allocation is about to exceed the soft heap
|
||||
@@ -104,7 +97,7 @@ static int sqlite3MemoryAlarm(
|
||||
void *pArg,
|
||||
sqlite3_int64 iThreshold
|
||||
){
|
||||
sqlite3_int64 nUsed;
|
||||
int nUsed;
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
mem0.alarmCallback = xCallback;
|
||||
mem0.alarmArg = pArg;
|
||||
@@ -273,7 +266,7 @@ static int mallocWithAlarm(int n, void **pp){
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmCallback!=0 ){
|
||||
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
if( nUsed >= mem0.alarmThreshold - nFull ){
|
||||
mem0.nearlyFull = 1;
|
||||
sqlite3MallocAlarm(nFull);
|
||||
@@ -290,8 +283,8 @@ static int mallocWithAlarm(int n, void **pp){
|
||||
#endif
|
||||
if( p ){
|
||||
nFull = sqlite3MallocSize(p);
|
||||
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull);
|
||||
sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
|
||||
}
|
||||
*pp = p;
|
||||
return nFull;
|
||||
@@ -368,14 +361,14 @@ void *sqlite3ScratchMalloc(int n){
|
||||
p = mem0.pScratchFree;
|
||||
mem0.pScratchFree = mem0.pScratchFree->pNext;
|
||||
mem0.nScratchFree--;
|
||||
sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
p = sqlite3Malloc(n);
|
||||
if( sqlite3GlobalConfig.bMemstat && p ){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
|
||||
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
|
||||
@@ -384,12 +377,11 @@ void *sqlite3ScratchMalloc(int n){
|
||||
|
||||
|
||||
#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
|
||||
/* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
|
||||
** buffers per thread.
|
||||
**
|
||||
** This can only be checked in single-threaded mode.
|
||||
*/
|
||||
assert( scratchAllocOut==0 );
|
||||
/* Verify that no more than two scratch allocations per thread
|
||||
** are outstanding at one time. (This is only checked in the
|
||||
** single-threaded case since checking in the multi-threaded case
|
||||
** would be much more complicated.) */
|
||||
assert( scratchAllocOut<=1 );
|
||||
if( p ) scratchAllocOut++;
|
||||
#endif
|
||||
|
||||
@@ -416,19 +408,19 @@ void sqlite3ScratchFree(void *p){
|
||||
mem0.pScratchFree = pSlot;
|
||||
mem0.nScratchFree++;
|
||||
assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
|
||||
sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
/* Release memory back to the heap */
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
|
||||
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) );
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
if( sqlite3GlobalConfig.bMemstat ){
|
||||
int iSize = sqlite3MallocSize(p);
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
|
||||
sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
|
||||
sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
|
||||
sqlite3GlobalConfig.m.xFree(p);
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
@@ -459,7 +451,7 @@ int sqlite3MallocSize(void *p){
|
||||
}
|
||||
int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
if( db==0 ){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
return sqlite3MallocSize(p);
|
||||
}else{
|
||||
@@ -468,13 +460,13 @@ int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
return db->lookaside.sz;
|
||||
}else{
|
||||
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
return sqlite3GlobalConfig.m.xSize(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_uint64 sqlite3_msize(void *p){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
|
||||
}
|
||||
@@ -485,11 +477,11 @@ sqlite3_uint64 sqlite3_msize(void *p){
|
||||
void sqlite3_free(void *p){
|
||||
if( p==0 ) return; /* IMP: R-49053-54554 */
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
|
||||
if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
|
||||
sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
|
||||
sqlite3GlobalConfig.m.xFree(p);
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
@@ -530,7 +522,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
}
|
||||
}
|
||||
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
sqlite3_free(p);
|
||||
@@ -543,7 +535,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
|
||||
int nOld, nNew, nDiff;
|
||||
void *pNew;
|
||||
assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
|
||||
if( pOld==0 ){
|
||||
return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
|
||||
}
|
||||
@@ -577,7 +569,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
|
||||
}
|
||||
if( pNew ){
|
||||
nNew = sqlite3MallocSize(pNew);
|
||||
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
|
||||
}
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
@@ -710,7 +702,7 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
|
||||
}
|
||||
}else{
|
||||
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
pNew = sqlite3_realloc64(p, n);
|
||||
if( !pNew ){
|
||||
|
||||
+3
-3
@@ -79,9 +79,9 @@ static malloc_zone_t* _sqliteZone_;
|
||||
** The malloc.h header file is needed for malloc_usable_size() function
|
||||
** on some systems (e.g. Linux).
|
||||
*/
|
||||
#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE
|
||||
# define SQLITE_USE_MALLOC_H 1
|
||||
# define SQLITE_USE_MALLOC_USABLE_SIZE 1
|
||||
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE)
|
||||
# define SQLITE_USE_MALLOC_H
|
||||
# define SQLITE_USE_MALLOC_USABLE_SIZE
|
||||
/*
|
||||
** The MSVCRT has malloc_usable_size(), but it is called _msize(). The
|
||||
** use of _msize() is automatic, but can be disabled by compiling with
|
||||
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
** 2015 January 12
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This file contains code that is specific to MSVC.
|
||||
*/
|
||||
#ifndef _MSVC_H_
|
||||
#define _MSVC_H_
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4054)
|
||||
#pragma warning(disable : 4055)
|
||||
#pragma warning(disable : 4100)
|
||||
#pragma warning(disable : 4127)
|
||||
#pragma warning(disable : 4152)
|
||||
#pragma warning(disable : 4189)
|
||||
#pragma warning(disable : 4206)
|
||||
#pragma warning(disable : 4210)
|
||||
#pragma warning(disable : 4232)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#pragma warning(disable : 4306)
|
||||
#pragma warning(disable : 4702)
|
||||
#pragma warning(disable : 4706)
|
||||
#endif /* defined(_MSC_VER) */
|
||||
|
||||
#endif /* _MSVC_H_ */
|
||||
@@ -82,7 +82,6 @@ int sqlite3MutexEnd(void){
|
||||
sqlite3_mutex *sqlite3_mutex_alloc(int id){
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
|
||||
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
|
||||
#endif
|
||||
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
|
||||
}
|
||||
|
||||
+4
-13
@@ -120,12 +120,8 @@ static sqlite3_mutex *debugMutexAlloc(int id){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( id-2<0 || id-2>=ArraySize(aStatic) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
assert( id-2 >= 0 );
|
||||
assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
|
||||
pNew = &aStatic[id-2];
|
||||
pNew->id = id;
|
||||
break;
|
||||
@@ -140,13 +136,8 @@ static sqlite3_mutex *debugMutexAlloc(int id){
|
||||
static void debugMutexFree(sqlite3_mutex *pX){
|
||||
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
|
||||
assert( p->cnt==0 );
|
||||
if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
}
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+15
-24
@@ -40,10 +40,8 @@
|
||||
*/
|
||||
struct sqlite3_mutex {
|
||||
pthread_mutex_t mutex; /* Mutex controlling the lock */
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
int id; /* Mutex type */
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
int id; /* Mutex type */
|
||||
volatile int nRef; /* Number of entrances */
|
||||
volatile pthread_t owner; /* Thread that is within this mutex */
|
||||
int trace; /* True to trace changes */
|
||||
@@ -159,6 +157,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&p->mutex, &recursiveAttr);
|
||||
pthread_mutexattr_destroy(&recursiveAttr);
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -166,24 +167,23 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
case SQLITE_MUTEX_FAST: {
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
pthread_mutex_init(&p->mutex, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
assert( iType-2 >= 0 );
|
||||
assert( iType-2 < ArraySize(staticMutexes) );
|
||||
p = &staticMutexes[iType-2];
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
if( p ) p->id = iType;
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -195,18 +195,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
*/
|
||||
static void pthreadMutexFree(sqlite3_mutex *p){
|
||||
assert( p->nRef==0 );
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE )
|
||||
#endif
|
||||
{
|
||||
pthread_mutex_destroy(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
else{
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
pthread_mutex_destroy(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+10
-15
@@ -194,8 +194,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
case SQLITE_MUTEX_RECURSIVE: {
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
|
||||
p->trace = 1;
|
||||
#endif
|
||||
@@ -209,15 +209,12 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
assert( iType-2 >= 0 );
|
||||
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
|
||||
assert( winMutex_isInit==1 );
|
||||
p = &winMutex_staticMutexes[iType-2];
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
|
||||
p->trace = 1;
|
||||
#endif
|
||||
@@ -236,15 +233,13 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
*/
|
||||
static void winMutexFree(sqlite3_mutex *p){
|
||||
assert( p );
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( p->nRef==0 && p->owner==0 );
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
#endif
|
||||
}
|
||||
assert( winMutex_isInit==1 );
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -361,10 +361,6 @@ int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
|
||||
int rc = sqlite3_initialize();
|
||||
if( rc ) return rc;
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
|
||||
MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
|
||||
sqlite3_mutex_enter(mutex);
|
||||
vfsUnlink(pVfs);
|
||||
|
||||
+171
-192
File diff suppressed because it is too large
Load Diff
+24
-64
@@ -34,11 +34,6 @@
|
||||
with SQLITE_OMIT_WAL."
|
||||
#endif
|
||||
|
||||
#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
|
||||
# error "Memory mapped files require support from the Windows NT kernel,\
|
||||
compile with SQLITE_MAX_MMAP_SIZE=0."
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
|
||||
** based on the sub-platform)?
|
||||
@@ -168,11 +163,10 @@
|
||||
|
||||
/*
|
||||
** Do we need to manually define the Win32 file mapping APIs for use with WAL
|
||||
** mode or memory mapped files (e.g. these APIs are available in the Windows
|
||||
** CE SDK; however, they are not present in the header file)?
|
||||
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
|
||||
** are not present in the header file)?
|
||||
*/
|
||||
#if SQLITE_WIN32_FILEMAPPING_API && \
|
||||
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
|
||||
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
|
||||
/*
|
||||
** Two of the file mapping APIs are different under WinRT. Figure out which
|
||||
** set we need.
|
||||
@@ -200,7 +194,7 @@ WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||
** This file mapping API is common to both Win32 and WinRT.
|
||||
*/
|
||||
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
|
||||
#endif /* SQLITE_WIN32_FILEMAPPING_API */
|
||||
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
|
||||
|
||||
/*
|
||||
** Some Microsoft compilers lack this definition.
|
||||
@@ -493,7 +487,7 @@ static struct win_syscall {
|
||||
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
|
||||
|
||||
#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
|
||||
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
|
||||
!defined(SQLITE_OMIT_WAL))
|
||||
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
|
||||
#else
|
||||
{ "CreateFileMappingA", (SYSCALL)0, 0 },
|
||||
@@ -503,7 +497,7 @@ static struct win_syscall {
|
||||
DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
|
||||
|
||||
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
|
||||
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
|
||||
!defined(SQLITE_OMIT_WAL))
|
||||
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
|
||||
#else
|
||||
{ "CreateFileMappingW", (SYSCALL)0, 0 },
|
||||
@@ -843,8 +837,7 @@ static struct win_syscall {
|
||||
LPOVERLAPPED))aSyscall[48].pCurrent)
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
|
||||
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
|
||||
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
|
||||
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
|
||||
#else
|
||||
{ "MapViewOfFile", (SYSCALL)0, 0 },
|
||||
@@ -914,7 +907,7 @@ static struct win_syscall {
|
||||
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
|
||||
LPOVERLAPPED))aSyscall[58].pCurrent)
|
||||
|
||||
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
||||
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
|
||||
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
|
||||
#else
|
||||
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
|
||||
@@ -977,7 +970,7 @@ static struct win_syscall {
|
||||
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
|
||||
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
|
||||
|
||||
#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
|
||||
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
|
||||
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
|
||||
#else
|
||||
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
|
||||
@@ -1041,7 +1034,7 @@ static struct win_syscall {
|
||||
|
||||
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
|
||||
|
||||
#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
|
||||
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
|
||||
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
|
||||
#else
|
||||
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },
|
||||
@@ -1066,23 +1059,6 @@ static struct win_syscall {
|
||||
SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
|
||||
#endif /* defined(InterlockedCompareExchange) */
|
||||
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
|
||||
{ "UuidCreate", (SYSCALL)UuidCreate, 0 },
|
||||
#else
|
||||
{ "UuidCreate", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
|
||||
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
|
||||
{ "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 },
|
||||
#else
|
||||
{ "UuidCreateSequential", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define osUuidCreateSequential \
|
||||
((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
/*
|
||||
@@ -1220,8 +1196,8 @@ int sqlite3_win32_reset_heap(){
|
||||
int rc;
|
||||
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
|
||||
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
|
||||
MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
|
||||
MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
|
||||
MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
|
||||
MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
|
||||
sqlite3_mutex_enter(pMaster);
|
||||
sqlite3_mutex_enter(pMem);
|
||||
winMemAssertMagic();
|
||||
@@ -2496,7 +2472,7 @@ static int winRead(
|
||||
int amt, /* Number of bytes to read */
|
||||
sqlite3_int64 offset /* Begin reading at this offset */
|
||||
){
|
||||
#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if !SQLITE_OS_WINCE
|
||||
OVERLAPPED overlapped; /* The offset for ReadFile. */
|
||||
#endif
|
||||
winFile *pFile = (winFile*)id; /* file handle */
|
||||
@@ -2528,7 +2504,7 @@ static int winRead(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if SQLITE_OS_WINCE
|
||||
if( winSeekFile(pFile, offset) ){
|
||||
OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
|
||||
return SQLITE_FULL;
|
||||
@@ -2600,13 +2576,13 @@ static int winWrite(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if SQLITE_OS_WINCE
|
||||
rc = winSeekFile(pFile, offset);
|
||||
if( rc==0 ){
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if !SQLITE_OS_WINCE
|
||||
OVERLAPPED overlapped; /* The offset for WriteFile. */
|
||||
#endif
|
||||
u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
|
||||
@@ -2614,14 +2590,14 @@ static int winWrite(
|
||||
DWORD nWrite; /* Bytes written by each WriteFile() call */
|
||||
DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */
|
||||
|
||||
#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if !SQLITE_OS_WINCE
|
||||
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
||||
overlapped.Offset = (LONG)(offset & 0xffffffff);
|
||||
overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
|
||||
#endif
|
||||
|
||||
while( nRem>0 ){
|
||||
#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if SQLITE_OS_WINCE
|
||||
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
|
||||
#else
|
||||
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
|
||||
@@ -2634,7 +2610,7 @@ static int winWrite(
|
||||
lastErrno = osGetLastError();
|
||||
break;
|
||||
}
|
||||
#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
|
||||
#if !SQLITE_OS_WINCE
|
||||
offset += nWrite;
|
||||
overlapped.Offset = (LONG)(offset & 0xffffffff);
|
||||
overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
|
||||
@@ -3831,16 +3807,16 @@ static int winShmMap(
|
||||
void volatile **pp /* OUT: Mapped memory */
|
||||
){
|
||||
winFile *pDbFd = (winFile*)fd;
|
||||
winShm *pShm = pDbFd->pShm;
|
||||
winShm *p = pDbFd->pShm;
|
||||
winShmNode *pShmNode;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( !pShm ){
|
||||
if( !p ){
|
||||
rc = winOpenSharedMemory(pDbFd);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
pShm = pDbFd->pShm;
|
||||
p = pDbFd->pShm;
|
||||
}
|
||||
pShmNode = pShm->pShmNode;
|
||||
pShmNode = p->pShmNode;
|
||||
|
||||
sqlite3_mutex_enter(pShmNode->mutex);
|
||||
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
|
||||
@@ -5361,22 +5337,6 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
memcpy(&zBuf[n], &i, sizeof(i));
|
||||
n += sizeof(i);
|
||||
}
|
||||
#endif
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
|
||||
if( sizeof(UUID)<=nBuf-n ){
|
||||
UUID id;
|
||||
memset(&id, 0, sizeof(UUID));
|
||||
osUuidCreate(&id);
|
||||
memcpy(zBuf, &id, sizeof(UUID));
|
||||
n += sizeof(UUID);
|
||||
}
|
||||
if( sizeof(UUID)<=nBuf-n ){
|
||||
UUID id;
|
||||
memset(&id, 0, sizeof(UUID));
|
||||
osUuidCreateSequential(&id);
|
||||
memcpy(zBuf, &id, sizeof(UUID));
|
||||
n += sizeof(UUID);
|
||||
}
|
||||
#endif
|
||||
return n;
|
||||
}
|
||||
@@ -5555,7 +5515,7 @@ int sqlite3_os_init(void){
|
||||
|
||||
/* Double-check that the aSyscall[] array has been constructed
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==79 );
|
||||
assert( ArraySize(aSyscall)==77 );
|
||||
|
||||
/* get memory map allocation granularity */
|
||||
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
|
||||
|
||||
@@ -74,15 +74,4 @@
|
||||
# define SQLITE_WIN32_VOLATILE volatile
|
||||
#endif
|
||||
|
||||
/*
|
||||
** For some Windows sub-platforms, the _beginthreadex() / _endthreadex()
|
||||
** functions are not available (e.g. those not using MSVC, Cygwin, etc).
|
||||
*/
|
||||
#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
|
||||
SQLITE_THREADSAFE>0 && !defined(__CYGWIN__)
|
||||
# define SQLITE_OS_WIN_THREADS 1
|
||||
#else
|
||||
# define SQLITE_OS_WIN_THREADS 0
|
||||
#endif
|
||||
|
||||
#endif /* _OS_WIN_H_ */
|
||||
|
||||
+14
-38
@@ -646,8 +646,6 @@ struct Pager {
|
||||
u8 setMaster; /* True if a m-j name has been written to jrnl */
|
||||
u8 doNotSpill; /* Do not spill the cache when non-zero */
|
||||
u8 subjInMemory; /* True to use in-memory sub-journals */
|
||||
u8 bUseFetch; /* True to use xFetch() */
|
||||
u8 hasBeenUsed; /* True if any content previously read from this pager*/
|
||||
Pgno dbSize; /* Number of pages in the database */
|
||||
Pgno dbOrigSize; /* dbSize before the current transaction */
|
||||
Pgno dbFileSize; /* Number of pages in the database file */
|
||||
@@ -665,9 +663,9 @@ struct Pager {
|
||||
sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
|
||||
PagerSavepoint *aSavepoint; /* Array of active savepoints */
|
||||
int nSavepoint; /* Number of elements in aSavepoint[] */
|
||||
u32 iDataVersion; /* Changes whenever database content changes */
|
||||
char dbFileVers[16]; /* Changes whenever database file changes */
|
||||
|
||||
u8 bUseFetch; /* True to use xFetch() */
|
||||
int nMmapOut; /* Number of mmap pages currently outstanding */
|
||||
sqlite3_int64 szMmap; /* Desired maximum mmap size */
|
||||
PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
|
||||
@@ -1683,19 +1681,10 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
|
||||
** Discard the entire contents of the in-memory page-cache.
|
||||
*/
|
||||
static void pager_reset(Pager *pPager){
|
||||
pPager->iDataVersion++;
|
||||
sqlite3BackupRestart(pPager->pBackup);
|
||||
sqlite3PcacheClear(pPager->pPCache);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the pPager->iDataVersion value
|
||||
*/
|
||||
u32 sqlite3PagerDataVersion(Pager *pPager){
|
||||
assert( pPager->eState>PAGER_OPEN );
|
||||
return pPager->iDataVersion;
|
||||
}
|
||||
|
||||
/*
|
||||
** Free all structures in the Pager.aSavepoint[] array and set both
|
||||
** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
|
||||
@@ -2910,7 +2899,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
|
||||
**
|
||||
** For an encrypted database, the situation is more complex: bytes
|
||||
** 24..39 of the database are white noise. But the probability of
|
||||
** white noise equaling 16 bytes of 0xff is vanishingly small so
|
||||
** white noising equaling 16 bytes of 0xff is vanishingly small so
|
||||
** we should still be ok.
|
||||
*/
|
||||
memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
|
||||
@@ -3898,7 +3887,7 @@ static int pagerAcquireMapPage(
|
||||
PgHdr **ppPage /* OUT: Acquired page object */
|
||||
){
|
||||
PgHdr *p; /* Memory mapped page to return */
|
||||
|
||||
|
||||
if( pPager->pMmapFreelist ){
|
||||
*ppPage = p = pPager->pMmapFreelist;
|
||||
pPager->pMmapFreelist = p->pDirty;
|
||||
@@ -5129,12 +5118,16 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
);
|
||||
}
|
||||
|
||||
if( !pPager->tempFile && pPager->hasBeenUsed ){
|
||||
/* The shared-lock has just been acquired then check to
|
||||
** see if the database has been modified. If the database has changed,
|
||||
** flush the cache. The pPager->hasBeenUsed flag prevents this from
|
||||
** occurring on the very first access to a file, in order to save a
|
||||
** single unnecessary sqlite3OsRead() call at the start-up.
|
||||
if( !pPager->tempFile && (
|
||||
pPager->pBackup
|
||||
|| sqlite3PcachePagecount(pPager->pPCache)>0
|
||||
|| USEFETCH(pPager)
|
||||
)){
|
||||
/* The shared-lock has just been acquired on the database file
|
||||
** and there are already pages in the cache (from a previous
|
||||
** read or write transaction). Check to see if the database
|
||||
** has been modified. If the database has changed, flush the
|
||||
** cache.
|
||||
**
|
||||
** Database changes is detected by looking at 15 bytes beginning
|
||||
** at offset 24 into the file. The first 4 of these 16 bytes are
|
||||
@@ -5299,7 +5292,6 @@ int sqlite3PagerAcquire(
|
||||
if( pgno==0 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
pPager->hasBeenUsed = 1;
|
||||
|
||||
/* If the pager is in the error state, return an error immediately.
|
||||
** Otherwise, request the page from the PCache layer. */
|
||||
@@ -5449,7 +5441,6 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
|
||||
assert( pgno!=0 );
|
||||
assert( pPager->pPCache!=0 );
|
||||
pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
|
||||
assert( pPage==0 || pPager->hasBeenUsed );
|
||||
return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
|
||||
}
|
||||
|
||||
@@ -6316,7 +6307,6 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){
|
||||
}
|
||||
|
||||
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
|
||||
pPager->iDataVersion++;
|
||||
rc = pager_end_transaction(pPager, pPager->setMaster, 1);
|
||||
return pager_error(pPager, rc);
|
||||
}
|
||||
@@ -6857,18 +6847,6 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The page handle passed as the first argument refers to a dirty page
|
||||
** with a page number other than iNew. This function changes the page's
|
||||
** page number to iNew and sets the value of the PgHdr.flags field to
|
||||
** the value passed as the third parameter.
|
||||
*/
|
||||
void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
|
||||
assert( pPg->pgno!=iNew );
|
||||
pPg->flags = flags;
|
||||
sqlite3PcacheMove(pPg, iNew);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the data for the specified page.
|
||||
*/
|
||||
@@ -7085,8 +7063,7 @@ int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->pWal ){
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
|
||||
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
|
||||
pPager->pBusyHandlerArg,
|
||||
pPager->xBusyHandler, pPager->pBusyHandlerArg,
|
||||
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
|
||||
pnLog, pnCkpt
|
||||
);
|
||||
@@ -7268,5 +7245,4 @@ int sqlite3PagerWalFramesize(Pager *pPager){
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* SQLITE_OMIT_DISKIO */
|
||||
|
||||
@@ -172,7 +172,6 @@ int sqlite3PagerSharedLock(Pager *pPager);
|
||||
|
||||
/* Functions used to query pager state and configuration. */
|
||||
u8 sqlite3PagerIsreadonly(Pager*);
|
||||
u32 sqlite3PagerDataVersion(Pager*);
|
||||
int sqlite3PagerRefcount(Pager*);
|
||||
int sqlite3PagerMemUsed(Pager*);
|
||||
const char *sqlite3PagerFilename(Pager*, int);
|
||||
@@ -189,8 +188,6 @@ int sqlite3SectorSize(sqlite3_file *);
|
||||
/* Functions used to truncate the database file. */
|
||||
void sqlite3PagerTruncateImage(Pager*,Pgno);
|
||||
|
||||
void sqlite3PagerRekey(DbPage*, Pgno, u16);
|
||||
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
|
||||
void *sqlite3PagerCodec(DbPage *);
|
||||
#endif
|
||||
|
||||
+15
-21
@@ -415,19 +415,13 @@ select(A) ::= with(W) selectnowith(X). {
|
||||
int cnt = 0, mxSelect;
|
||||
p->pWith = W;
|
||||
if( p->pPrior ){
|
||||
u16 allValues = SF_Values;
|
||||
pNext = 0;
|
||||
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
|
||||
pLoop->pNext = pNext;
|
||||
pLoop->selFlags |= SF_Compound;
|
||||
allValues &= pLoop->selFlags;
|
||||
}
|
||||
if( allValues ){
|
||||
p->selFlags |= SF_AllValues;
|
||||
}else if(
|
||||
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
|
||||
&& cnt>mxSelect
|
||||
){
|
||||
mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
|
||||
if( mxSelect && cnt>mxSelect ){
|
||||
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
|
||||
}
|
||||
}
|
||||
@@ -860,7 +854,7 @@ expr(A) ::= VARIABLE(X). {
|
||||
spanSet(&A, &X, &X);
|
||||
}
|
||||
expr(A) ::= expr(E) COLLATE ids(C). {
|
||||
A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1);
|
||||
A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C);
|
||||
A.zStart = E.zStart;
|
||||
A.zEnd = &C.z[C.n];
|
||||
}
|
||||
@@ -1078,7 +1072,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pList = Y;
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
}
|
||||
@@ -1091,8 +1085,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = X;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
}
|
||||
@@ -1103,8 +1097,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = Y;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
@@ -1117,8 +1111,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SrcListDelete(pParse->db, pSrc);
|
||||
}
|
||||
@@ -1130,8 +1124,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
|
||||
if( p ){
|
||||
p->x.pSelect = Y;
|
||||
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, p);
|
||||
ExprSetProperty(p, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, p);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
@@ -1145,7 +1139,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
sqlite3ExprDelete(pParse->db, Z);
|
||||
@@ -1206,14 +1200,14 @@ uniqueflag(A) ::= . {A = OE_None;}
|
||||
idxlist_opt(A) ::= . {A = 0;}
|
||||
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
|
||||
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
|
||||
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
||||
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
|
||||
A = sqlite3ExprListAppend(pParse,X, p);
|
||||
sqlite3ExprListSetName(pParse,A,&Y,1);
|
||||
sqlite3ExprListCheckLength(pParse, A, "index");
|
||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
||||
}
|
||||
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
||||
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
||||
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
|
||||
A = sqlite3ExprListAppend(pParse,0, p);
|
||||
sqlite3ExprListSetName(pParse, A, &Y, 1);
|
||||
sqlite3ExprListCheckLength(pParse, A, "index");
|
||||
|
||||
+14
-18
@@ -31,6 +31,18 @@ struct PCache {
|
||||
PgHdr *pPage1; /* Reference to page 1 */
|
||||
};
|
||||
|
||||
/*
|
||||
** Some of the assert() macros in this code are too expensive to run
|
||||
** even during normal debugging. Use them only rarely on long-running
|
||||
** tests. Enable the expensive asserts using the
|
||||
** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
# define expensive_assert(X) assert(X)
|
||||
#else
|
||||
# define expensive_assert(X)
|
||||
#endif
|
||||
|
||||
/********************************** Linked List Management ********************/
|
||||
|
||||
/* Allowed values for second argument to pcacheManageDirtyList() */
|
||||
@@ -114,20 +126,12 @@ static void pcacheUnpin(PgHdr *p){
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute the number of pages of cache requested. p->szCache is the
|
||||
** cache size requested by the "PRAGMA cache_size" statement.
|
||||
**
|
||||
**
|
||||
** Compute the number of pages of cache requested.
|
||||
*/
|
||||
static int numberOfCachePages(PCache *p){
|
||||
if( p->szCache>=0 ){
|
||||
/* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
|
||||
** suggested cache size is set to N. */
|
||||
return p->szCache;
|
||||
}else{
|
||||
/* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
|
||||
** the number of cache pages is adjusted to use approximately abs(N*1024)
|
||||
** bytes of memory. */
|
||||
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
|
||||
}
|
||||
}
|
||||
@@ -192,8 +196,7 @@ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
|
||||
if( pCache->szPage ){
|
||||
sqlite3_pcache *pNew;
|
||||
pNew = sqlite3GlobalConfig.pcache2.xCreate(
|
||||
szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
|
||||
pCache->bPurgeable
|
||||
szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
|
||||
);
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
|
||||
@@ -648,13 +651,6 @@ void sqlite3PcacheShrink(PCache *pCache){
|
||||
sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the size of the header added by this middleware layer
|
||||
** in the page-cache hierarchy.
|
||||
*/
|
||||
int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
|
||||
|
||||
|
||||
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
|
||||
/*
|
||||
** For all dirty pages currently in the cache, invoke the specified
|
||||
|
||||
@@ -160,8 +160,4 @@ void sqlite3PcacheStats(int*,int*,int*,int*);
|
||||
|
||||
void sqlite3PCacheSetDefault(void);
|
||||
|
||||
/* Return the header size */
|
||||
int sqlite3HeaderSizePcache(void);
|
||||
int sqlite3HeaderSizePcache1(void);
|
||||
|
||||
#endif /* _PCACHE_H_ */
|
||||
|
||||
+6
-20
@@ -195,6 +195,7 @@ void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
|
||||
static void *pcache1Alloc(int nByte){
|
||||
void *p = 0;
|
||||
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
|
||||
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
if( nByte<=pcache1.szSlot ){
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
p = (PgHdr1 *)pcache1.pFree;
|
||||
@@ -203,8 +204,7 @@ static void *pcache1Alloc(int nByte){
|
||||
pcache1.nFreeSlot--;
|
||||
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
|
||||
assert( pcache1.nFreeSlot>=0 );
|
||||
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
|
||||
}
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
}
|
||||
@@ -217,8 +217,7 @@ static void *pcache1Alloc(int nByte){
|
||||
if( p ){
|
||||
int sz = sqlite3MallocSize(p);
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
}
|
||||
#endif
|
||||
@@ -236,7 +235,7 @@ static int pcache1Free(void *p){
|
||||
if( p>=pcache1.pStart && p<pcache1.pEnd ){
|
||||
PgFreeslot *pSlot;
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
|
||||
pSlot = (PgFreeslot*)p;
|
||||
pSlot->pNext = pcache1.pFree;
|
||||
pcache1.pFree = pSlot;
|
||||
@@ -250,7 +249,7 @@ static int pcache1Free(void *p){
|
||||
nFreed = sqlite3MallocSize(p);
|
||||
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
#endif
|
||||
sqlite3_free(p);
|
||||
@@ -297,7 +296,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||
pPg = 0;
|
||||
}
|
||||
#else
|
||||
pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
|
||||
pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
|
||||
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
|
||||
#endif
|
||||
pcache1EnterMutex(pCache->pGroup);
|
||||
@@ -982,19 +981,6 @@ void sqlite3PCacheSetDefault(void){
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the size of the header on each page of this PCACHE implementation.
|
||||
*/
|
||||
int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
|
||||
|
||||
/*
|
||||
** Return the global mutex used by this PCACHE implementation. The
|
||||
** sqlite3_status() routine needs access to this mutex.
|
||||
*/
|
||||
sqlite3_mutex *sqlite3Pcache1Mutex(void){
|
||||
return pcache1.mutex;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
/*
|
||||
** This function is called to free superfluous dynamically allocated memory
|
||||
|
||||
+490
-78
@@ -22,13 +22,457 @@
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
** The "pragma.h" include file is an automatically generated file that
|
||||
** that includes the PragType_XXXX macro definitions and the aPragmaName[]
|
||||
** object. This ensures that the aPragmaName[] table is arranged in
|
||||
** lexicographical order to facility a binary search of the pragma name.
|
||||
** Do not edit pragma.h directly. Edit and rerun the script in at
|
||||
** ../tool/mkpragmatab.tcl. */
|
||||
#include "pragma.h"
|
||||
** The next block of code, including the PragTyp_XXXX macro definitions and
|
||||
** the aPragmaName[] object is composed of generated code. DO NOT EDIT.
|
||||
**
|
||||
** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun
|
||||
** that script. Then copy/paste the output in place of the following:
|
||||
*/
|
||||
#define PragTyp_HEADER_VALUE 0
|
||||
#define PragTyp_AUTO_VACUUM 1
|
||||
#define PragTyp_FLAG 2
|
||||
#define PragTyp_BUSY_TIMEOUT 3
|
||||
#define PragTyp_CACHE_SIZE 4
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 5
|
||||
#define PragTyp_COLLATION_LIST 6
|
||||
#define PragTyp_COMPILE_OPTIONS 7
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 8
|
||||
#define PragTyp_DATABASE_LIST 9
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 10
|
||||
#define PragTyp_ENCODING 11
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 12
|
||||
#define PragTyp_FOREIGN_KEY_LIST 13
|
||||
#define PragTyp_INCREMENTAL_VACUUM 14
|
||||
#define PragTyp_INDEX_INFO 15
|
||||
#define PragTyp_INDEX_LIST 16
|
||||
#define PragTyp_INTEGRITY_CHECK 17
|
||||
#define PragTyp_JOURNAL_MODE 18
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 19
|
||||
#define PragTyp_LOCK_PROXY_FILE 20
|
||||
#define PragTyp_LOCKING_MODE 21
|
||||
#define PragTyp_PAGE_COUNT 22
|
||||
#define PragTyp_MMAP_SIZE 23
|
||||
#define PragTyp_PAGE_SIZE 24
|
||||
#define PragTyp_SECURE_DELETE 25
|
||||
#define PragTyp_SHRINK_MEMORY 26
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 27
|
||||
#define PragTyp_STATS 28
|
||||
#define PragTyp_SYNCHRONOUS 29
|
||||
#define PragTyp_TABLE_INFO 30
|
||||
#define PragTyp_TEMP_STORE 31
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 32
|
||||
#define PragTyp_THREADS 33
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 34
|
||||
#define PragTyp_WAL_CHECKPOINT 35
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 36
|
||||
#define PragTyp_HEXKEY 37
|
||||
#define PragTyp_KEY 38
|
||||
#define PragTyp_REKEY 39
|
||||
#define PragTyp_LOCK_STATUS 40
|
||||
#define PragTyp_PARSER_TRACE 41
|
||||
#define PragFlag_NeedSchema 0x01
|
||||
static const struct sPragmaNames {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
|
||||
u32 iArg; /* Extra argument */
|
||||
} aPragmaNames[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
{ /* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
||||
{ /* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
#endif
|
||||
#endif
|
||||
{ /* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CacheSpill },
|
||||
#endif
|
||||
{ /* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
{ /* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
|
||||
{ /* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{ /* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_UTF16)
|
||||
{ /* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{ /* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{ /* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
{ /* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ /* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
{ /* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{ /* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
#endif
|
||||
{ /* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{ /* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{ /* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{ /* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{ /* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
{ /* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 57 on by default, 70 total. */
|
||||
/* End of the automatically generated pragma table.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
** Interpret the given string as a safety level. Return 0 for OFF,
|
||||
@@ -276,12 +720,11 @@ void sqlite3Pragma(
|
||||
Token *pId; /* Pointer to <id> token */
|
||||
char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */
|
||||
int iDb; /* Database index for <database> */
|
||||
int lwr, upr, mid = 0; /* Binary search bounds */
|
||||
int lwr, upr, mid; /* Binary search bounds */
|
||||
int rc; /* return value form SQLITE_FCNTL_PRAGMA */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
Db *pDb; /* The specific database being pragmaed */
|
||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
|
||||
const struct sPragmaNames *pPragma;
|
||||
|
||||
if( v==0 ) return;
|
||||
sqlite3VdbeRunOnlyOnce(v);
|
||||
@@ -317,17 +760,6 @@ void sqlite3Pragma(
|
||||
/* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
|
||||
** connection. If it returns SQLITE_OK, then assume that the VFS
|
||||
** handled the pragma and generate a no-op prepared statement.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed,
|
||||
** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file
|
||||
** object corresponding to the database file to which the pragma
|
||||
** statement refers.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
|
||||
** file control is an array of pointers to strings (char**) in which the
|
||||
** second element of the array is the name of the pragma and the third
|
||||
** element is the argument to the pragma or NULL if the pragma has no
|
||||
** argument.
|
||||
*/
|
||||
aFcntl[0] = 0;
|
||||
aFcntl[1] = zLeft;
|
||||
@@ -370,15 +802,14 @@ void sqlite3Pragma(
|
||||
}
|
||||
}
|
||||
if( lwr>upr ) goto pragma_out;
|
||||
pPragma = &aPragmaNames[mid];
|
||||
|
||||
/* Make sure the database schema is loaded if the pragma requires that */
|
||||
if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
|
||||
if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
}
|
||||
|
||||
/* Jump to the appropriate pragma handler */
|
||||
switch( pPragma->ePragTyp ){
|
||||
switch( aPragmaNames[mid].ePragTyp ){
|
||||
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
/*
|
||||
@@ -957,9 +1388,10 @@ void sqlite3Pragma(
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
case PragTyp_FLAG: {
|
||||
if( zRight==0 ){
|
||||
returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
|
||||
returnSingleInt(pParse, aPragmaNames[mid].zName,
|
||||
(db->flags & aPragmaNames[mid].iArg)!=0 );
|
||||
}else{
|
||||
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
|
||||
int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */
|
||||
if( db->autoCommit==0 ){
|
||||
/* Foreign key support may not be enabled or disabled while not
|
||||
** in auto-commit mode. */
|
||||
@@ -1088,42 +1520,20 @@ void sqlite3Pragma(
|
||||
pIdx = sqlite3FindIndex(db, zRight, zDb);
|
||||
if( pIdx ){
|
||||
int i;
|
||||
int mx;
|
||||
if( pPragma->iArg ){
|
||||
/* PRAGMA index_xinfo (newer version with more rows and columns) */
|
||||
mx = pIdx->nColumn;
|
||||
pParse->nMem = 6;
|
||||
}else{
|
||||
/* PRAGMA index_info (legacy version) */
|
||||
mx = pIdx->nKeyCol;
|
||||
pParse->nMem = 3;
|
||||
}
|
||||
pTab = pIdx->pTable;
|
||||
sqlite3VdbeSetNumCols(v, pParse->nMem);
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
pParse->nMem = 3;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
if( pPragma->iArg ){
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
|
||||
}
|
||||
for(i=0; i<mx; i++){
|
||||
for(i=0; i<pIdx->nKeyCol; i++){
|
||||
i16 cnum = pIdx->aiColumn[i];
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
|
||||
if( cnum<0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
|
||||
}else{
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
|
||||
}
|
||||
if( pPragma->iArg ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
|
||||
assert( pTab->nCol>cnum );
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1136,22 +1546,17 @@ void sqlite3Pragma(
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 5);
|
||||
pParse->nMem = 5;
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
pParse->nMem = 3;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
|
||||
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
|
||||
const char *azOrigin[] = { "c", "u", "pk" };
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1675,8 +2080,7 @@ void sqlite3Pragma(
|
||||
){
|
||||
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
||||
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
|
||||
SCHEMA_ENC(db) = ENC(db) =
|
||||
pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
|
||||
ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1721,9 +2125,24 @@ void sqlite3Pragma(
|
||||
** applications for any purpose.
|
||||
*/
|
||||
case PragTyp_HEADER_VALUE: {
|
||||
int iCookie = pPragma->iArg; /* Which cookie to read or write */
|
||||
int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
|
||||
switch( zLeft[0] ){
|
||||
case 'a': case 'A':
|
||||
iCookie = BTREE_APPLICATION_ID;
|
||||
break;
|
||||
case 'f': case 'F':
|
||||
iCookie = BTREE_FREE_PAGE_COUNT;
|
||||
break;
|
||||
case 's': case 'S':
|
||||
iCookie = BTREE_SCHEMA_VERSION;
|
||||
break;
|
||||
default:
|
||||
iCookie = BTREE_USER_VERSION;
|
||||
break;
|
||||
}
|
||||
|
||||
if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
|
||||
/* Write the specified cookie value */
|
||||
static const VdbeOpList setCookie[] = {
|
||||
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
||||
@@ -1776,7 +2195,7 @@ void sqlite3Pragma(
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
|
||||
** PRAGMA [database.]wal_checkpoint = passive|full|restart
|
||||
**
|
||||
** Checkpoint the database.
|
||||
*/
|
||||
@@ -1788,8 +2207,6 @@ void sqlite3Pragma(
|
||||
eMode = SQLITE_CHECKPOINT_FULL;
|
||||
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
|
||||
eMode = SQLITE_CHECKPOINT_RESTART;
|
||||
}else if( sqlite3StrICmp(zRight, "truncate")==0 ){
|
||||
eMode = SQLITE_CHECKPOINT_TRUNCATE;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
@@ -1825,9 +2242,8 @@ void sqlite3Pragma(
|
||||
/*
|
||||
** PRAGMA shrink_memory
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database
|
||||
** connection on which it is invoked to free up as much memory as it
|
||||
** can, by calling sqlite3_db_release_memory().
|
||||
** This pragma attempts to free as much memory as possible from the
|
||||
** current database connection.
|
||||
*/
|
||||
case PragTyp_SHRINK_MEMORY: {
|
||||
sqlite3_db_release_memory(db);
|
||||
@@ -1844,7 +2260,7 @@ void sqlite3Pragma(
|
||||
** disables the timeout.
|
||||
*/
|
||||
/*case PragTyp_BUSY_TIMEOUT*/ default: {
|
||||
assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
|
||||
assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT );
|
||||
if( zRight ){
|
||||
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
|
||||
}
|
||||
@@ -1856,12 +2272,8 @@ void sqlite3Pragma(
|
||||
** PRAGMA soft_heap_limit
|
||||
** PRAGMA soft_heap_limit = N
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the
|
||||
** sqlite3_soft_heap_limit64() interface with the argument N, if N is
|
||||
** specified and is a non-negative integer.
|
||||
** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always
|
||||
** returns the same integer that would be returned by the
|
||||
** sqlite3_soft_heap_limit64(-1) C-language function.
|
||||
** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted,
|
||||
** use -1.
|
||||
*/
|
||||
case PragTyp_SOFT_HEAP_LIMIT: {
|
||||
sqlite3_int64 N;
|
||||
|
||||
-459
@@ -1,459 +0,0 @@
|
||||
/* DO NOT EDIT!
|
||||
** This file is automatically generated by the script at
|
||||
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
||||
** that script and rerun it.
|
||||
*/
|
||||
#define PragTyp_HEADER_VALUE 0
|
||||
#define PragTyp_AUTO_VACUUM 1
|
||||
#define PragTyp_FLAG 2
|
||||
#define PragTyp_BUSY_TIMEOUT 3
|
||||
#define PragTyp_CACHE_SIZE 4
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 5
|
||||
#define PragTyp_COLLATION_LIST 6
|
||||
#define PragTyp_COMPILE_OPTIONS 7
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 8
|
||||
#define PragTyp_DATABASE_LIST 9
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 10
|
||||
#define PragTyp_ENCODING 11
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 12
|
||||
#define PragTyp_FOREIGN_KEY_LIST 13
|
||||
#define PragTyp_INCREMENTAL_VACUUM 14
|
||||
#define PragTyp_INDEX_INFO 15
|
||||
#define PragTyp_INDEX_LIST 16
|
||||
#define PragTyp_INTEGRITY_CHECK 17
|
||||
#define PragTyp_JOURNAL_MODE 18
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 19
|
||||
#define PragTyp_LOCK_PROXY_FILE 20
|
||||
#define PragTyp_LOCKING_MODE 21
|
||||
#define PragTyp_PAGE_COUNT 22
|
||||
#define PragTyp_MMAP_SIZE 23
|
||||
#define PragTyp_PAGE_SIZE 24
|
||||
#define PragTyp_SECURE_DELETE 25
|
||||
#define PragTyp_SHRINK_MEMORY 26
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 27
|
||||
#define PragTyp_STATS 28
|
||||
#define PragTyp_SYNCHRONOUS 29
|
||||
#define PragTyp_TABLE_INFO 30
|
||||
#define PragTyp_TEMP_STORE 31
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 32
|
||||
#define PragTyp_THREADS 33
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 34
|
||||
#define PragTyp_WAL_CHECKPOINT 35
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 36
|
||||
#define PragTyp_HEXKEY 37
|
||||
#define PragTyp_KEY 38
|
||||
#define PragTyp_REKEY 39
|
||||
#define PragTyp_LOCK_STATUS 40
|
||||
#define PragTyp_PARSER_TRACE 41
|
||||
#define PragFlag_NeedSchema 0x01
|
||||
#define PragFlag_ReadOnly 0x02
|
||||
static const struct sPragmaNames {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
|
||||
u32 iArg; /* Extra argument */
|
||||
} aPragmaNames[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
{ /* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_APPLICATION_ID },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
||||
{ /* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
#endif
|
||||
#endif
|
||||
{ /* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CacheSpill },
|
||||
#endif
|
||||
{ /* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
{ /* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
|
||||
{ /* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "data_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_DATA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{ /* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_UTF16)
|
||||
{ /* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{ /* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_FREE_PAGE_COUNT },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{ /* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
{ /* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 1 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ /* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
{ /* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{ /* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_SCHEMA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
#endif
|
||||
{ /* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_USER_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{ /* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{ /* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{ /* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{ /* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
{ /* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 59 on by default, 72 total. */
|
||||
+4
-11
@@ -394,11 +394,9 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){
|
||||
int commit_internal = !(db->flags&SQLITE_InternChanges);
|
||||
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
|
||||
assert( db->init.busy==0 );
|
||||
rc = SQLITE_OK;
|
||||
db->init.busy = 1;
|
||||
ENC(db) = SCHEMA_ENC(db);
|
||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
|
||||
rc = sqlite3InitOne(db, i, pzErrMsg);
|
||||
@@ -711,12 +709,9 @@ static int sqlite3LockAndPrepare(
|
||||
const char **pzTail /* OUT: End of parsed string */
|
||||
){
|
||||
int rc;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( ppStmt!=0 );
|
||||
*ppStmt = 0;
|
||||
if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
@@ -823,11 +818,9 @@ static int sqlite3Prepare16(
|
||||
const char *zTail8 = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( ppStmt );
|
||||
*ppStmt = 0;
|
||||
if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
if( nBytes>=0 ){
|
||||
|
||||
+29
-39
@@ -14,6 +14,21 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** If the strchrnul() library function is available, then set
|
||||
** HAVE_STRCHRNUL. If that routine is not available, this module
|
||||
** will supply its own. The built-in version is slower than
|
||||
** the glibc version so the glibc version is definitely preferred.
|
||||
*/
|
||||
#if !defined(HAVE_STRCHRNUL)
|
||||
# if defined(linux)
|
||||
# define HAVE_STRCHRNUL 1
|
||||
# else
|
||||
# define HAVE_STRCHRNUL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Conversion types fall into various categories as defined by the
|
||||
** following enumeration.
|
||||
@@ -201,7 +216,7 @@ void sqlite3VXPrintf(
|
||||
const et_info *infop; /* Pointer to the appropriate info structure */
|
||||
char *zOut; /* Rendering buffer */
|
||||
int nOut; /* Size of the rendering buffer */
|
||||
char *zExtra = 0; /* Malloced memory used by some conversion */
|
||||
char *zExtra; /* Malloced memory used by some conversion */
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
int exp, e2; /* exponent of real numbers */
|
||||
int nsd; /* Number of significant digits returned */
|
||||
@@ -318,6 +333,7 @@ void sqlite3VXPrintf(
|
||||
break;
|
||||
}
|
||||
}
|
||||
zExtra = 0;
|
||||
|
||||
/*
|
||||
** At this point, variables are initialized as follows:
|
||||
@@ -608,16 +624,13 @@ void sqlite3VXPrintf(
|
||||
}else{
|
||||
c = va_arg(ap,int);
|
||||
}
|
||||
if( precision>1 ){
|
||||
width -= precision-1;
|
||||
if( width>1 && !flag_leftjustify ){
|
||||
sqlite3AppendChar(pAccum, width-1, ' ');
|
||||
width = 0;
|
||||
}
|
||||
sqlite3AppendChar(pAccum, precision-1, c);
|
||||
buf[0] = (char)c;
|
||||
if( precision>=0 ){
|
||||
for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
|
||||
length = precision;
|
||||
}else{
|
||||
length =1;
|
||||
}
|
||||
length = 1;
|
||||
buf[0] = c;
|
||||
bufpt = buf;
|
||||
break;
|
||||
case etSTRING:
|
||||
@@ -718,14 +731,11 @@ void sqlite3VXPrintf(
|
||||
** the output.
|
||||
*/
|
||||
width -= length;
|
||||
if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
||||
if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
|
||||
sqlite3StrAccumAppend(pAccum, bufpt, length);
|
||||
if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
||||
if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
|
||||
|
||||
if( zExtra ){
|
||||
sqlite3_free(zExtra);
|
||||
zExtra = 0;
|
||||
}
|
||||
if( zExtra ) sqlite3_free(zExtra);
|
||||
}/* End for loop over the format string */
|
||||
} /* End of function */
|
||||
|
||||
@@ -752,11 +762,6 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
|
||||
i64 szNew = p->nChar;
|
||||
szNew += N + 1;
|
||||
if( szNew+p->nChar<=p->mxAlloc ){
|
||||
/* Force exponential buffer size growth as long as it does not overflow,
|
||||
** to avoid having to call this routine too often */
|
||||
szNew += p->nChar;
|
||||
}
|
||||
if( szNew > p->mxAlloc ){
|
||||
sqlite3StrAccumReset(p);
|
||||
setStrAccumError(p, STRACCUM_TOOBIG);
|
||||
@@ -773,7 +778,6 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
assert( p->zText!=0 || p->nChar==0 );
|
||||
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
|
||||
p->zText = zNew;
|
||||
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
|
||||
}else{
|
||||
sqlite3StrAccumReset(p);
|
||||
setStrAccumError(p, STRACCUM_NOMEM);
|
||||
@@ -784,11 +788,11 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
}
|
||||
|
||||
/*
|
||||
** Append N copies of character c to the given string buffer.
|
||||
** Append N space characters to the given string buffer.
|
||||
*/
|
||||
void sqlite3AppendChar(StrAccum *p, int N, char c){
|
||||
void sqlite3AppendSpace(StrAccum *p, int N){
|
||||
if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
|
||||
while( (N--)>0 ) p->zText[p->nChar++] = c;
|
||||
while( (N--)>0 ) p->zText[p->nChar++] = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -943,13 +947,6 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
|
||||
char *z;
|
||||
char zBase[SQLITE_PRINT_BUF_SIZE];
|
||||
StrAccum acc;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zFormat==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
@@ -992,13 +989,6 @@ char *sqlite3_mprintf(const char *zFormat, ...){
|
||||
char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
StrAccum acc;
|
||||
if( n<=0 ) return zBuf;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zBuf==0 || zFormat==0 ) {
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
if( zBuf ) zBuf[0] = 0;
|
||||
return zBuf;
|
||||
}
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, zBuf, n, 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
|
||||
+4
-12
@@ -48,19 +48,11 @@ void sqlite3_randomness(int N, void *pBuf){
|
||||
#endif
|
||||
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex;
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return;
|
||||
#endif
|
||||
|
||||
#if SQLITE_THREADSAFE
|
||||
mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
|
||||
#endif
|
||||
|
||||
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
|
||||
sqlite3_mutex_enter(mutex);
|
||||
if( N<=0 || pBuf==0 ){
|
||||
#endif
|
||||
|
||||
if( N<=0 ){
|
||||
wsdPrng.isInit = 0;
|
||||
sqlite3_mutex_leave(mutex);
|
||||
return;
|
||||
|
||||
+20
-31
@@ -28,7 +28,7 @@
|
||||
** is a helper function - a callback for the tree walker.
|
||||
*/
|
||||
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
|
||||
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
|
||||
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
|
||||
return WRC_Continue;
|
||||
}
|
||||
static void incrAggFunctionDepth(Expr *pExpr, int N){
|
||||
@@ -36,7 +36,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = incrAggDepth;
|
||||
w.u.n = N;
|
||||
w.u.i = N;
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
}
|
||||
}
|
||||
@@ -247,10 +247,9 @@ static int lookupName(
|
||||
testcase( pNC->ncFlags & NC_PartIdx );
|
||||
testcase( pNC->ncFlags & NC_IsCheck );
|
||||
if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
|
||||
/* Silently ignore database qualifiers inside CHECK constraints and
|
||||
** partial indices. Do not raise errors because that might break
|
||||
** legacy and because it does not hurt anything to just ignore the
|
||||
** database name. */
|
||||
/* Silently ignore database qualifiers inside CHECK constraints and partial
|
||||
** indices. Do not raise errors because that might break legacy and
|
||||
** because it does not hurt anything to just ignore the database name. */
|
||||
zDb = 0;
|
||||
}else{
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -321,11 +320,6 @@ static int lookupName(
|
||||
if( pMatch ){
|
||||
pExpr->iTable = pMatch->iCursor;
|
||||
pExpr->pTab = pMatch->pTab;
|
||||
/* RIGHT JOIN not (yet) supported */
|
||||
assert( (pMatch->jointype & JT_RIGHT)==0 );
|
||||
if( (pMatch->jointype & JT_LEFT)!=0 ){
|
||||
ExprSetProperty(pExpr, EP_CanBeNull);
|
||||
}
|
||||
pSchema = pExpr->pTab->pSchema;
|
||||
}
|
||||
} /* if( pSrcList ) */
|
||||
@@ -590,7 +584,7 @@ static int exprProbability(Expr *p){
|
||||
sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
|
||||
assert( r>=0.0 );
|
||||
if( r>1.0 ) return -1;
|
||||
return (int)(r*134217728.0);
|
||||
return (int)(r*1000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -643,8 +637,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
break;
|
||||
}
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
|
||||
&& !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
|
||||
/* A lone identifier is the name of a column.
|
||||
*/
|
||||
@@ -709,22 +702,21 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
if( n==2 ){
|
||||
pExpr->iTable = exprProbability(pList->a[1].pExpr);
|
||||
if( pExpr->iTable<0 ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
pNC->nErr++;
|
||||
}
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
|
||||
** equivalent to likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
|
||||
** short-hand for likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
|
||||
** for likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
|
||||
** to likelihood(X,0.9375). */
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
|
||||
** likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
|
||||
** likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
|
||||
** likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
|
||||
** likelihood(X,0.9375). */
|
||||
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
|
||||
pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
|
||||
pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
@@ -739,9 +731,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Prune;
|
||||
}
|
||||
#endif
|
||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
|
||||
ExprSetProperty(pExpr,EP_ConstFunc);
|
||||
}
|
||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
|
||||
}
|
||||
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
|
||||
@@ -1052,8 +1042,7 @@ int sqlite3ResolveOrderGroupBy(
|
||||
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
|
||||
return 1;
|
||||
}
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
|
||||
zType,0);
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
+51
-135
@@ -58,25 +58,20 @@ struct SortCtx {
|
||||
#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */
|
||||
|
||||
/*
|
||||
** Delete all the content of a Select structure. Deallocate the structure
|
||||
** itself only if bFree is true.
|
||||
** Delete all the content of a Select structure but do not deallocate
|
||||
** the select structure itself.
|
||||
*/
|
||||
static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
while( p ){
|
||||
Select *pPrior = p->pPrior;
|
||||
sqlite3ExprListDelete(db, p->pEList);
|
||||
sqlite3SrcListDelete(db, p->pSrc);
|
||||
sqlite3ExprDelete(db, p->pWhere);
|
||||
sqlite3ExprListDelete(db, p->pGroupBy);
|
||||
sqlite3ExprDelete(db, p->pHaving);
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
sqlite3ExprDelete(db, p->pOffset);
|
||||
sqlite3WithDelete(db, p->pWith);
|
||||
if( bFree ) sqlite3DbFree(db, p);
|
||||
p = pPrior;
|
||||
bFree = 1;
|
||||
}
|
||||
static void clearSelect(sqlite3 *db, Select *p){
|
||||
sqlite3ExprListDelete(db, p->pEList);
|
||||
sqlite3SrcListDelete(db, p->pSrc);
|
||||
sqlite3ExprDelete(db, p->pWhere);
|
||||
sqlite3ExprListDelete(db, p->pGroupBy);
|
||||
sqlite3ExprDelete(db, p->pHaving);
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
sqlite3SelectDelete(db, p->pPrior);
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
sqlite3ExprDelete(db, p->pOffset);
|
||||
sqlite3WithDelete(db, p->pWith);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -135,7 +130,8 @@ Select *sqlite3SelectNew(
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
if( db->mallocFailed ) {
|
||||
clearSelect(db, pNew, pNew!=&standin);
|
||||
clearSelect(db, pNew);
|
||||
if( pNew!=&standin ) sqlite3DbFree(db, pNew);
|
||||
pNew = 0;
|
||||
}else{
|
||||
assert( pNew->pSrc!=0 || pParse->nErr>0 );
|
||||
@@ -160,7 +156,10 @@ void sqlite3SelectSetName(Select *p, const char *zName){
|
||||
** Delete the given Select structure and all of its substructures.
|
||||
*/
|
||||
void sqlite3SelectDelete(sqlite3 *db, Select *p){
|
||||
clearSelect(db, p, 1);
|
||||
if( p ){
|
||||
clearSelect(db, p);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -543,9 +542,7 @@ static void pushOntoSorter(
|
||||
pKI = pOp->p4.pKeyInfo;
|
||||
memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
|
||||
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
|
||||
testcase( pKI->nXField>2 );
|
||||
pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
|
||||
pKI->nXField-1);
|
||||
pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1);
|
||||
addrJmp = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
|
||||
pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
|
||||
@@ -563,17 +560,20 @@ static void pushOntoSorter(
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
|
||||
if( pSelect->iLimit ){
|
||||
int addr;
|
||||
int addr1, addr2;
|
||||
int iLimit;
|
||||
if( pSelect->iOffset ){
|
||||
iLimit = pSelect->iOffset+1;
|
||||
}else{
|
||||
iLimit = pSelect->iLimit;
|
||||
}
|
||||
addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
|
||||
addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
|
||||
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
|
||||
sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3VdbeJumpHere(v, addr2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -970,7 +970,7 @@ static void selectInnerLoop(
|
||||
** the output for us.
|
||||
*/
|
||||
if( pSort==0 && p->iLimit ){
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,7 +1053,7 @@ static KeyInfo *keyInfoFromExprList(
|
||||
int i;
|
||||
|
||||
nExpr = pList->nExpr;
|
||||
pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1);
|
||||
pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra-iStart, 1);
|
||||
if( pInfo ){
|
||||
assert( sqlite3KeyInfoIsWriteable(pInfo) );
|
||||
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
|
||||
@@ -1823,7 +1823,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
||||
sqlite3ExprCode(pParse, p->pLimit, iLimit);
|
||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
|
||||
VdbeComment((v, "LIMIT counter"));
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v);
|
||||
}
|
||||
if( p->pOffset ){
|
||||
p->iOffset = iOffset = ++pParse->nMem;
|
||||
@@ -2042,7 +2042,7 @@ static void generateWithRecursiveQuery(
|
||||
selectInnerLoop(pParse, p, p->pEList, iCurrent,
|
||||
0, 0, pDest, addrCont, addrBreak);
|
||||
if( regLimit ){
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
|
||||
sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, addrCont);
|
||||
@@ -2075,66 +2075,6 @@ static int multiSelectOrderBy(
|
||||
SelectDest *pDest /* What to do with query results */
|
||||
);
|
||||
|
||||
/*
|
||||
** Error message for when two or more terms of a compound select have different
|
||||
** size result sets.
|
||||
*/
|
||||
static void selectWrongNumTermsError(Parse *pParse, Select *p){
|
||||
if( p->selFlags & SF_Values ){
|
||||
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
|
||||
" do not have the same number of result columns", selectOpName(p->op));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Handle the special case of a compound-select that originates from a
|
||||
** VALUES clause. By handling this as a special case, we avoid deep
|
||||
** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
|
||||
** on a VALUES clause.
|
||||
**
|
||||
** Because the Select object originates from a VALUES clause:
|
||||
** (1) It has no LIMIT or OFFSET
|
||||
** (2) All terms are UNION ALL
|
||||
** (3) There is no ORDER BY clause
|
||||
*/
|
||||
static int multiSelectValues(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Select *p, /* The right-most of SELECTs to be coded */
|
||||
SelectDest *pDest /* What to do with query results */
|
||||
){
|
||||
Select *pPrior;
|
||||
int nExpr = p->pEList->nExpr;
|
||||
int nRow = 1;
|
||||
int rc = 0;
|
||||
assert( p->pNext==0 );
|
||||
assert( p->selFlags & SF_AllValues );
|
||||
do{
|
||||
assert( p->selFlags & SF_Values );
|
||||
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
|
||||
assert( p->pLimit==0 );
|
||||
assert( p->pOffset==0 );
|
||||
if( p->pEList->nExpr!=nExpr ){
|
||||
selectWrongNumTermsError(pParse, p);
|
||||
return 1;
|
||||
}
|
||||
if( p->pPrior==0 ) break;
|
||||
assert( p->pPrior->pNext==p );
|
||||
p = p->pPrior;
|
||||
nRow++;
|
||||
}while(1);
|
||||
while( p ){
|
||||
pPrior = p->pPrior;
|
||||
p->pPrior = 0;
|
||||
rc = sqlite3Select(pParse, p, pDest);
|
||||
p->pPrior = pPrior;
|
||||
if( rc ) break;
|
||||
p->nSelectRow = nRow;
|
||||
p = p->pNext;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called to process a compound query form from
|
||||
@@ -2216,19 +2156,17 @@ static int multiSelect(
|
||||
dest.eDest = SRT_Table;
|
||||
}
|
||||
|
||||
/* Special handling for a compound-select that originates as a VALUES clause.
|
||||
*/
|
||||
if( p->selFlags & SF_AllValues ){
|
||||
rc = multiSelectValues(pParse, p, &dest);
|
||||
goto multi_select_end;
|
||||
}
|
||||
|
||||
/* Make sure all SELECTs in the statement have the same number of elements
|
||||
** in their result sets.
|
||||
*/
|
||||
assert( p->pEList && pPrior->pEList );
|
||||
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
|
||||
selectWrongNumTermsError(pParse, p);
|
||||
if( p->selFlags & SF_Values ){
|
||||
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
|
||||
" do not have the same number of result columns", selectOpName(p->op));
|
||||
}
|
||||
rc = 1;
|
||||
goto multi_select_end;
|
||||
}
|
||||
@@ -2267,7 +2205,7 @@ static int multiSelect(
|
||||
p->iLimit = pPrior->iLimit;
|
||||
p->iOffset = pPrior->iOffset;
|
||||
if( p->iLimit ){
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v);
|
||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||
}
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
@@ -2668,7 +2606,7 @@ static int generateOutputSubroutine(
|
||||
/* Jump to the end of the loop if the LIMIT is reached.
|
||||
*/
|
||||
if( p->iLimit ){
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
|
||||
}
|
||||
|
||||
/* Generate the subroutine return
|
||||
@@ -3191,10 +3129,7 @@ static void substSelect(
|
||||
**
|
||||
** (1) The subquery and the outer query do not both use aggregates.
|
||||
**
|
||||
** (2) The subquery is not an aggregate or (2a) the outer query is not a join
|
||||
** and (2b) the outer query does not use subqueries other than the one
|
||||
** FROM-clause subquery that is a candidate for flattening. (2b is
|
||||
** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
|
||||
** (2) The subquery is not an aggregate or the outer query is not a join.
|
||||
**
|
||||
** (3) The subquery is not the right operand of a left outer join
|
||||
** (Originally ticket #306. Strengthened by ticket #3300)
|
||||
@@ -3331,17 +3266,8 @@ static int flattenSubquery(
|
||||
iParent = pSubitem->iCursor;
|
||||
pSub = pSubitem->pSelect;
|
||||
assert( pSub!=0 );
|
||||
if( subqueryIsAgg ){
|
||||
if( isAgg ) return 0; /* Restriction (1) */
|
||||
if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
|
||||
if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
|
||||
|| (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
|
||||
|| (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
|
||||
){
|
||||
return 0; /* Restriction (2b) */
|
||||
}
|
||||
}
|
||||
|
||||
if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
|
||||
if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
|
||||
pSubSrc = pSub->pSrc;
|
||||
assert( pSubSrc );
|
||||
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
|
||||
@@ -4035,7 +3961,7 @@ static int withExpand(
|
||||
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
|
||||
pEList = pLeft->pEList;
|
||||
if( pCte->pCols ){
|
||||
if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
|
||||
if( pEList->nExpr!=pCte->pCols->nExpr ){
|
||||
sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
|
||||
pCte->zName, pEList->nExpr, pCte->pCols->nExpr
|
||||
);
|
||||
@@ -4126,9 +4052,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
}
|
||||
pTabList = p->pSrc;
|
||||
pEList = p->pEList;
|
||||
if( pWalker->xSelectCallback2==selectPopWith ){
|
||||
sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
|
||||
}
|
||||
sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
|
||||
|
||||
/* Make sure cursor numbers have been assigned to all entries in
|
||||
** the FROM clause of the SELECT statement.
|
||||
@@ -4162,7 +4086,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
/* A sub-query in the FROM clause of a SELECT */
|
||||
assert( pSel!=0 );
|
||||
assert( pFrom->pTab==0 );
|
||||
if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
|
||||
sqlite3WalkSelect(pWalker, pSel);
|
||||
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
|
||||
if( pTab==0 ) return WRC_Abort;
|
||||
pTab->nRef = 1;
|
||||
@@ -4419,9 +4343,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
w.xSelectCallback = selectExpander;
|
||||
if( (pSelect->selFlags & SF_AllValues)==0 ){
|
||||
w.xSelectCallback2 = selectPopWith;
|
||||
}
|
||||
w.xSelectCallback2 = selectPopWith;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
|
||||
@@ -4761,13 +4683,6 @@ int sqlite3Select(
|
||||
}
|
||||
isAgg = (p->selFlags & SF_Aggregate)!=0;
|
||||
assert( pEList!=0 );
|
||||
#if SELECTTRACE_ENABLED
|
||||
if( sqlite3SelectTrace & 0x100 ){
|
||||
SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Begin generating code.
|
||||
*/
|
||||
@@ -4914,7 +4829,7 @@ int sqlite3Select(
|
||||
**
|
||||
** is transformed to:
|
||||
**
|
||||
** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
|
||||
** SELECT xyz FROM ... GROUP BY xyz
|
||||
**
|
||||
** The second form is preferred as a single index (or temp-table) may be
|
||||
** used for both the ORDER BY and DISTINCT processing. As originally
|
||||
@@ -4927,6 +4842,7 @@ int sqlite3Select(
|
||||
p->selFlags &= ~SF_Distinct;
|
||||
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
|
||||
pGroupBy = p->pGroupBy;
|
||||
sSort.pOrderBy = 0;
|
||||
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
|
||||
** the sDistinct.isTnct is still set. Hence, isTnct represents the
|
||||
** original setting of the SF_Distinct flag, not the current setting */
|
||||
@@ -4942,7 +4858,7 @@ int sqlite3Select(
|
||||
*/
|
||||
if( sSort.pOrderBy ){
|
||||
KeyInfo *pKeyInfo;
|
||||
pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
|
||||
pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0);
|
||||
sSort.iECursor = pParse->nTab++;
|
||||
sSort.addrSortIndex =
|
||||
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
|
||||
@@ -5116,7 +5032,7 @@ int sqlite3Select(
|
||||
** will be converted into a Noop.
|
||||
*/
|
||||
sAggInfo.sortingIdx = pParse->nTab++;
|
||||
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
|
||||
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, 0);
|
||||
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
|
||||
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
|
||||
0, (char*)pKeyInfo, P4_KEYINFO);
|
||||
@@ -5513,9 +5429,9 @@ select_end:
|
||||
void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
int n = 0;
|
||||
pView = sqlite3TreeViewPush(pView, moreToFollow);
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
|
||||
);
|
||||
if( p->pSrc && p->pSrc->nSrc ) n++;
|
||||
if( p->pWhere ) n++;
|
||||
|
||||
+278
-680
File diff suppressed because it is too large
Load Diff
+382
-576
File diff suppressed because it is too large
Load Diff
+22
-69
@@ -15,19 +15,6 @@
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
|
||||
/*
|
||||
** Include the header file used to customize the compiler options for MSVC.
|
||||
** This should be done first so that it can successfully prevent spurious
|
||||
** compiler warnings due to subsequent content in this file and other files
|
||||
** that are included by this file.
|
||||
*/
|
||||
#include "msvc.h"
|
||||
|
||||
/*
|
||||
** Special setup for VxWorks
|
||||
*/
|
||||
#include "vxworks.h"
|
||||
|
||||
/*
|
||||
** These #defines should enable >2GB file support on POSIX if the
|
||||
** underlying operating system supports it. If the OS lacks
|
||||
@@ -206,9 +193,10 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by
|
||||
** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in
|
||||
** which case memory allocation statistics are disabled by default.
|
||||
** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
|
||||
** It determines whether or not the features related to
|
||||
** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
|
||||
** be overridden at runtime using the sqlite3_config() API.
|
||||
*/
|
||||
#if !defined(SQLITE_DEFAULT_MEMSTATUS)
|
||||
# define SQLITE_DEFAULT_MEMSTATUS 1
|
||||
@@ -575,7 +563,7 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
|
||||
** gives a possible range of values of approximately 1.0e986 to 1e-986.
|
||||
** But the allowed values are "grainy". Not every value is representable.
|
||||
** For example, quantities 16 and 17 are both represented by a LogEst
|
||||
** of 40. However, since LogEst quantities are suppose to be estimates,
|
||||
** of 40. However, since LogEst quantaties are suppose to be estimates,
|
||||
** not exact values, this imprecision is not a problem.
|
||||
**
|
||||
** "LogEst" is short for "Logarithmic Estimate".
|
||||
@@ -594,20 +582,6 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
|
||||
*/
|
||||
typedef INT16_TYPE LogEst;
|
||||
|
||||
/*
|
||||
** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer
|
||||
*/
|
||||
#ifndef SQLITE_PTRSIZE
|
||||
# if defined(__SIZEOF_POINTER__)
|
||||
# define SQLITE_PTRSIZE __SIZEOF_POINTER__
|
||||
# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(_M_ARM) || defined(__arm__) || defined(__x86)
|
||||
# define SQLITE_PTRSIZE 4
|
||||
# else
|
||||
# define SQLITE_PTRSIZE 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macros to determine whether the machine is big or little endian,
|
||||
** and whether or not that determination is run-time or compile-time.
|
||||
@@ -1086,7 +1060,6 @@ struct sqlite3 {
|
||||
int errCode; /* Most recent error code (SQLITE_*) */
|
||||
int errMask; /* & result codes with this before returning */
|
||||
u16 dbOptFlags; /* Flags to enable/disable optimizations */
|
||||
u8 enc; /* Text encoding */
|
||||
u8 autoCommit; /* The auto-commit flag. */
|
||||
u8 temp_store; /* 1: file 2: memory 0: default */
|
||||
u8 mallocFailed; /* True if we have seen a malloc failure */
|
||||
@@ -1106,13 +1079,11 @@ struct sqlite3 {
|
||||
u8 iDb; /* Which db file is being initialized */
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
|
||||
u8 imposterTable; /* Building an imposter table */
|
||||
} init;
|
||||
int nVdbeActive; /* Number of VDBEs currently running */
|
||||
int nVdbeRead; /* Number of active VDBEs that read or write */
|
||||
int nVdbeWrite; /* Number of active VDBEs that read and write */
|
||||
int nVdbeExec; /* Number of nested calls to VdbeExec() */
|
||||
int nVDestroy; /* Number of active OP_VDestroy operations */
|
||||
int nExtension; /* Number of loaded extensions */
|
||||
void **aExtension; /* Array of shared library handles */
|
||||
void (*xTrace)(void*,const char*); /* Trace function */
|
||||
@@ -1190,8 +1161,7 @@ struct sqlite3 {
|
||||
/*
|
||||
** A macro to discover the encoding of a database.
|
||||
*/
|
||||
#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
|
||||
#define ENC(db) ((db)->enc)
|
||||
#define ENC(db) ((db)->aDb[0].pSchema->enc)
|
||||
|
||||
/*
|
||||
** Possible values for the sqlite3.flags.
|
||||
@@ -1244,7 +1214,7 @@ struct sqlite3 {
|
||||
#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
|
||||
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
|
||||
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
|
||||
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
|
||||
#define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */
|
||||
#define SQLITE_AllOpts 0xffff /* All optimizations */
|
||||
|
||||
/*
|
||||
@@ -1815,6 +1785,7 @@ struct Index {
|
||||
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
|
||||
char **azColl; /* Array of collation sequence names for index */
|
||||
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
|
||||
KeyInfo *pKeyInfo; /* A KeyInfo object suitable for this index */
|
||||
int tnum; /* DB Page containing root of this index */
|
||||
LogEst szIdxRow; /* Estimated average row size in bytes */
|
||||
u16 nKeyCol; /* Number of columns forming the key */
|
||||
@@ -1825,7 +1796,6 @@ struct Index {
|
||||
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
|
||||
unsigned isResized:1; /* True if resizeIndexObject() has been called */
|
||||
unsigned isCovering:1; /* True if this is a covering index */
|
||||
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
int nSample; /* Number of elements in aSample[] */
|
||||
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
|
||||
@@ -2030,7 +2000,7 @@ struct Expr {
|
||||
int iTable; /* TK_COLUMN: cursor number of table holding column
|
||||
** TK_REGISTER: register number
|
||||
** TK_TRIGGER: 1 -> new, 0 -> old
|
||||
** EP_Unlikely: 134217728 times likelihood */
|
||||
** EP_Unlikely: 1000 times likelihood */
|
||||
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
|
||||
** TK_VARIABLE: variable number (always >= 1). */
|
||||
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
|
||||
@@ -2045,7 +2015,7 @@ struct Expr {
|
||||
/*
|
||||
** The following are the meanings of bits in the Expr.flags field.
|
||||
*/
|
||||
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
|
||||
#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
|
||||
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
|
||||
#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
|
||||
#define EP_Error 0x000008 /* Expression contains one or more errors */
|
||||
@@ -2064,14 +2034,7 @@ struct Expr {
|
||||
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
|
||||
|
||||
/*
|
||||
** Combinations of two or more EP_* flags
|
||||
*/
|
||||
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
|
||||
#define EP_Constant 0x080000 /* Node is a constant */
|
||||
|
||||
/*
|
||||
** These macros can be used to test, set, or clear bits in the
|
||||
@@ -2270,7 +2233,7 @@ struct SrcList {
|
||||
#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
|
||||
#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
|
||||
#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
|
||||
#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */
|
||||
/* 0x0080 // not currently used */
|
||||
#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
|
||||
#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
|
||||
#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
|
||||
@@ -2384,7 +2347,7 @@ struct Select {
|
||||
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
|
||||
#define SF_Compound 0x0040 /* Part of a compound query */
|
||||
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
||||
#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
|
||||
/* 0x0100 NOT USED */
|
||||
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
||||
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
|
||||
@@ -2707,8 +2670,7 @@ struct AuthContext {
|
||||
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
|
||||
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
|
||||
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
|
||||
#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */
|
||||
#define OPFLAG_P2ISREG 0x04 /* P2 to OP_Open** is a register number */
|
||||
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
|
||||
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
|
||||
|
||||
/*
|
||||
@@ -2875,7 +2837,6 @@ struct Sqlite3Config {
|
||||
int nPage; /* Number of pages in pPage[] */
|
||||
int mxParserStack; /* maximum depth of the parser stack */
|
||||
int sharedCacheEnabled; /* true if shared-cache mode enabled */
|
||||
u32 szPma; /* Maximum Sorter PMA size */
|
||||
/* The above might be initialized to non-zero. The following need to always
|
||||
** initially be zero, however. */
|
||||
int isInit; /* True after initialization has finished */
|
||||
@@ -2931,11 +2892,9 @@ struct Walker {
|
||||
void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
|
||||
Parse *pParse; /* Parser context. */
|
||||
int walkerDepth; /* Number of subqueries */
|
||||
u8 eCode; /* A small processing code */
|
||||
union { /* Extra data for callback */
|
||||
NameContext *pNC; /* Naming context */
|
||||
int n; /* A counter */
|
||||
int iCur; /* A cursor number */
|
||||
int i; /* Integer value */
|
||||
SrcList *pSrcList; /* FROM clause */
|
||||
struct SrcCount *pSrcCount; /* Counting column references */
|
||||
} u;
|
||||
@@ -3013,7 +2972,7 @@ int sqlite3CantopenError(int);
|
||||
** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3.
|
||||
*/
|
||||
#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
|
||||
# define SQLITE_ENABLE_FTS3 1
|
||||
# define SQLITE_ENABLE_FTS3
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3112,15 +3071,10 @@ const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
|
||||
int sqlite3MutexEnd(void);
|
||||
#endif
|
||||
|
||||
sqlite3_int64 sqlite3StatusValue(int);
|
||||
void sqlite3StatusUp(int, int);
|
||||
void sqlite3StatusDown(int, int);
|
||||
int sqlite3StatusValue(int);
|
||||
void sqlite3StatusAdd(int, int);
|
||||
void sqlite3StatusSet(int, int);
|
||||
|
||||
/* Access to mutexes used by sqlite3_status() */
|
||||
sqlite3_mutex *sqlite3Pcache1Mutex(void);
|
||||
sqlite3_mutex *sqlite3MallocMutex(void);
|
||||
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
int sqlite3IsNaN(double);
|
||||
#else
|
||||
@@ -3185,7 +3139,6 @@ ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
||||
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
||||
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
|
||||
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
u32 sqlite3ExprListFlags(const ExprList*);
|
||||
int sqlite3Init(sqlite3*, char**);
|
||||
int sqlite3InitCallback(void*, int, char**, char**);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
||||
@@ -3342,7 +3295,6 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
|
||||
int sqlite3ExprIsConstant(Expr*);
|
||||
int sqlite3ExprIsConstantNotJoin(Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
int sqlite3ExprIsTableConstant(Expr*,int);
|
||||
int sqlite3ExprIsInteger(Expr*, int*);
|
||||
int sqlite3ExprCanBeNull(const Expr*);
|
||||
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
|
||||
@@ -3500,7 +3452,7 @@ int sqlite3ReadSchema(Parse *pParse);
|
||||
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
|
||||
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
|
||||
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
|
||||
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
|
||||
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*);
|
||||
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
|
||||
Expr *sqlite3ExprSkipCollate(Expr*);
|
||||
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
||||
@@ -3588,7 +3540,7 @@ int sqlite3OpenTempDatabase(Parse *);
|
||||
void sqlite3StrAccumInit(StrAccum*, char*, int, int);
|
||||
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
|
||||
void sqlite3StrAccumAppendAll(StrAccum*,const char*);
|
||||
void sqlite3AppendChar(StrAccum*,int,char);
|
||||
void sqlite3AppendSpace(StrAccum*,int);
|
||||
char *sqlite3StrAccumFinish(StrAccum*);
|
||||
void sqlite3StrAccumReset(StrAccum*);
|
||||
void sqlite3SelectDestInit(SelectDest*,int,int);
|
||||
@@ -3769,11 +3721,12 @@ void sqlite3MemJournalOpen(sqlite3_file *);
|
||||
int sqlite3MemJournalSize(void);
|
||||
int sqlite3IsMemJournal(sqlite3_file *);
|
||||
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
|
||||
int sqlite3SelectExprHeight(Select *);
|
||||
int sqlite3ExprCheckHeight(Parse*, int);
|
||||
#else
|
||||
#define sqlite3ExprSetHeight(x,y)
|
||||
#define sqlite3SelectExprHeight(x) 0
|
||||
#define sqlite3ExprCheckHeight(x,y)
|
||||
#endif
|
||||
|
||||
+5
-7
@@ -98,17 +98,15 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The suggested maximum number of in-memory pages to use for
|
||||
** the main database table and for temporary tables.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
|
||||
** is 2000 pages.
|
||||
** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
|
||||
** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
|
||||
** The maximum number of in-memory pages to use for the main database
|
||||
** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_CACHE_SIZE
|
||||
# define SQLITE_DEFAULT_CACHE_SIZE 2000
|
||||
#endif
|
||||
#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
|
||||
# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The default number of frames to accumulate in the log file before
|
||||
|
||||
+13
-89
@@ -21,32 +21,10 @@
|
||||
*/
|
||||
typedef struct sqlite3StatType sqlite3StatType;
|
||||
static SQLITE_WSD struct sqlite3StatType {
|
||||
#if SQLITE_PTRSIZE>4
|
||||
sqlite3_int64 nowValue[10]; /* Current value */
|
||||
sqlite3_int64 mxValue[10]; /* Maximum value */
|
||||
#else
|
||||
u32 nowValue[10]; /* Current value */
|
||||
u32 mxValue[10]; /* Maximum value */
|
||||
#endif
|
||||
int nowValue[10]; /* Current value */
|
||||
int mxValue[10]; /* Maximum value */
|
||||
} sqlite3Stat = { {0,}, {0,} };
|
||||
|
||||
/*
|
||||
** Elements of sqlite3Stat[] are protected by either the memory allocator
|
||||
** mutex, or by the pcache1 mutex. The following array determines which.
|
||||
*/
|
||||
static const char statMutex[] = {
|
||||
0, /* SQLITE_STATUS_MEMORY_USED */
|
||||
1, /* SQLITE_STATUS_PAGECACHE_USED */
|
||||
1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
|
||||
0, /* SQLITE_STATUS_SCRATCH_USED */
|
||||
0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */
|
||||
0, /* SQLITE_STATUS_MALLOC_SIZE */
|
||||
0, /* SQLITE_STATUS_PARSER_STACK */
|
||||
1, /* SQLITE_STATUS_PAGECACHE_SIZE */
|
||||
0, /* SQLITE_STATUS_SCRATCH_SIZE */
|
||||
0, /* SQLITE_STATUS_MALLOC_COUNT */
|
||||
};
|
||||
|
||||
|
||||
/* The "wsdStat" macro will resolve to the status information
|
||||
** state vector. If writable static data is unsupported on the target,
|
||||
@@ -63,60 +41,33 @@ static const char statMutex[] = {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the current value of a status parameter. The caller must
|
||||
** be holding the appropriate mutex.
|
||||
** Return the current value of a status parameter.
|
||||
*/
|
||||
sqlite3_int64 sqlite3StatusValue(int op){
|
||||
int sqlite3StatusValue(int op){
|
||||
wsdStatInit;
|
||||
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
|
||||
assert( op>=0 && op<ArraySize(statMutex) );
|
||||
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
|
||||
: sqlite3MallocMutex()) );
|
||||
return wsdStat.nowValue[op];
|
||||
}
|
||||
|
||||
/*
|
||||
** Add N to the value of a status record. The caller must hold the
|
||||
** appropriate mutex. (Locking is checked by assert()).
|
||||
**
|
||||
** The StatusUp() routine can accept positive or negative values for N.
|
||||
** The value of N is added to the current status value and the high-water
|
||||
** mark is adjusted if necessary.
|
||||
**
|
||||
** The StatusDown() routine lowers the current value by N. The highwater
|
||||
** mark is unchanged. N must be non-negative for StatusDown().
|
||||
** Add N to the value of a status record. It is assumed that the
|
||||
** caller holds appropriate locks.
|
||||
*/
|
||||
void sqlite3StatusUp(int op, int N){
|
||||
void sqlite3StatusAdd(int op, int N){
|
||||
wsdStatInit;
|
||||
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
|
||||
assert( op>=0 && op<ArraySize(statMutex) );
|
||||
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
|
||||
: sqlite3MallocMutex()) );
|
||||
wsdStat.nowValue[op] += N;
|
||||
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
|
||||
wsdStat.mxValue[op] = wsdStat.nowValue[op];
|
||||
}
|
||||
}
|
||||
void sqlite3StatusDown(int op, int N){
|
||||
wsdStatInit;
|
||||
assert( N>=0 );
|
||||
assert( op>=0 && op<ArraySize(statMutex) );
|
||||
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
|
||||
: sqlite3MallocMutex()) );
|
||||
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
|
||||
wsdStat.nowValue[op] -= N;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the value of a status to X. The highwater mark is adjusted if
|
||||
** necessary. The caller must hold the appropriate mutex.
|
||||
** Set the value of a status to X.
|
||||
*/
|
||||
void sqlite3StatusSet(int op, int X){
|
||||
wsdStatInit;
|
||||
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
|
||||
assert( op>=0 && op<ArraySize(statMutex) );
|
||||
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
|
||||
: sqlite3MallocMutex()) );
|
||||
wsdStat.nowValue[op] = X;
|
||||
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
|
||||
wsdStat.mxValue[op] = wsdStat.nowValue[op];
|
||||
@@ -125,45 +76,23 @@ void sqlite3StatusSet(int op, int X){
|
||||
|
||||
/*
|
||||
** Query status information.
|
||||
**
|
||||
** This implementation assumes that reading or writing an aligned
|
||||
** 32-bit integer is an atomic operation. If that assumption is not true,
|
||||
** then this routine is not threadsafe.
|
||||
*/
|
||||
int sqlite3_status64(
|
||||
int op,
|
||||
sqlite3_int64 *pCurrent,
|
||||
sqlite3_int64 *pHighwater,
|
||||
int resetFlag
|
||||
){
|
||||
sqlite3_mutex *pMutex;
|
||||
int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
|
||||
wsdStatInit;
|
||||
if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
|
||||
sqlite3_mutex_enter(pMutex);
|
||||
*pCurrent = wsdStat.nowValue[op];
|
||||
*pHighwater = wsdStat.mxValue[op];
|
||||
if( resetFlag ){
|
||||
wsdStat.mxValue[op] = wsdStat.nowValue[op];
|
||||
}
|
||||
sqlite3_mutex_leave(pMutex);
|
||||
(void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
|
||||
sqlite3_int64 iCur, iHwtr;
|
||||
int rc;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
|
||||
if( rc==0 ){
|
||||
*pCurrent = (int)iCur;
|
||||
*pHighwater = (int)iHwtr;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Query status information for a single database connection
|
||||
@@ -176,11 +105,6 @@ int sqlite3_db_status(
|
||||
int resetFlag /* Reset high-water mark if true */
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
switch( op ){
|
||||
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
|
||||
|
||||
@@ -126,9 +126,6 @@ int sqlite3_get_table(
|
||||
int rc;
|
||||
TabResult res;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
*pazResult = 0;
|
||||
if( pnColumn ) *pnColumn = 0;
|
||||
if( pnRow ) *pnRow = 0;
|
||||
|
||||
+17
-101
@@ -25,14 +25,6 @@
|
||||
** hundreds of new commands used for testing
|
||||
** SQLite. This option implies -DSQLITE_TCLMD5.
|
||||
*/
|
||||
|
||||
/*
|
||||
** If requested, include the SQLite compiler options file for MSVC.
|
||||
*/
|
||||
#if defined(INCLUDE_MSVC_H)
|
||||
#include "msvc.h"
|
||||
#endif
|
||||
|
||||
#include "tcl.h"
|
||||
#include <errno.h>
|
||||
|
||||
@@ -643,7 +635,6 @@ static int DbWalHandler(
|
||||
Tcl_Interp *interp = pDb->interp;
|
||||
assert(pDb->pWalHook);
|
||||
|
||||
assert( db==pDb->db );
|
||||
p = Tcl_DuplicateObj(pDb->pWalHook);
|
||||
Tcl_IncrRefCount(p);
|
||||
Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
|
||||
@@ -661,9 +652,9 @@ static int DbWalHandler(
|
||||
#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
|
||||
static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
|
||||
char zBuf[64];
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg);
|
||||
sprintf(zBuf, "%d", iArg);
|
||||
Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg);
|
||||
sprintf(zBuf, "%d", nArg);
|
||||
Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
|
||||
}
|
||||
#else
|
||||
@@ -1093,10 +1084,10 @@ static int dbPrepareAndBind(
|
||||
SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */
|
||||
){
|
||||
const char *zSql = zIn; /* Pointer to first SQL statement in zIn */
|
||||
sqlite3_stmt *pStmt = 0; /* Prepared statement object */
|
||||
sqlite3_stmt *pStmt; /* Prepared statement object */
|
||||
SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */
|
||||
int nSql; /* Length of zSql in bytes */
|
||||
int nVar = 0; /* Number of variables in statement */
|
||||
int nVar; /* Number of variables in statement */
|
||||
int iParm = 0; /* Next free entry in apParm */
|
||||
char c;
|
||||
int i;
|
||||
@@ -2320,49 +2311,34 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
|
||||
/*
|
||||
** $db function NAME [-argcount N] [-deterministic] SCRIPT
|
||||
** $db function NAME [-argcount N] SCRIPT
|
||||
**
|
||||
** Create a new SQL function called NAME. Whenever that function is
|
||||
** called, invoke SCRIPT to evaluate the function.
|
||||
*/
|
||||
case DB_FUNCTION: {
|
||||
int flags = SQLITE_UTF8;
|
||||
SqlFunc *pFunc;
|
||||
Tcl_Obj *pScript;
|
||||
char *zName;
|
||||
int nArg = -1;
|
||||
int i;
|
||||
if( objc<4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for(i=3; i<(objc-1); i++){
|
||||
const char *z = Tcl_GetString(objv[i]);
|
||||
if( objc==6 ){
|
||||
const char *z = Tcl_GetString(objv[3]);
|
||||
int n = strlen30(z);
|
||||
if( n>2 && strncmp(z, "-argcount",n)==0 ){
|
||||
if( i==(objc-2) ){
|
||||
Tcl_AppendResult(interp, "option requires an argument: ", z, 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &nArg) ) return TCL_ERROR;
|
||||
if( nArg<0 ){
|
||||
Tcl_AppendResult(interp, "number of arguments must be non-negative",
|
||||
(char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
i++;
|
||||
}else
|
||||
if( n>2 && strncmp(z, "-deterministic",n)==0 ){
|
||||
flags |= SQLITE_DETERMINISTIC;
|
||||
}else{
|
||||
Tcl_AppendResult(interp, "bad option \"", z,
|
||||
"\": must be -argcount or -deterministic", 0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pScript = objv[5];
|
||||
}else if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT");
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
pScript = objv[3];
|
||||
}
|
||||
|
||||
pScript = objv[objc-1];
|
||||
zName = Tcl_GetStringFromObj(objv[2], 0);
|
||||
pFunc = findSqlFunc(pDb, zName);
|
||||
if( pFunc==0 ) return TCL_ERROR;
|
||||
@@ -2372,7 +2348,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
pFunc->pScript = pScript;
|
||||
Tcl_IncrRefCount(pScript);
|
||||
pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
|
||||
rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
|
||||
rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8,
|
||||
pFunc, tclSqlFunc, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = TCL_ERROR;
|
||||
@@ -3125,7 +3101,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
** The EXTERN macros are required by TCL in order to work on windows.
|
||||
*/
|
||||
EXTERN int Sqlite3_Init(Tcl_Interp *interp){
|
||||
int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
|
||||
int rc = Tcl_InitStubs(interp, "8.4", 0)==0 ? TCL_ERROR : TCL_OK;
|
||||
if( rc==TCL_OK ){
|
||||
Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
|
||||
#ifndef SQLITE_3_SUFFIX_ONLY
|
||||
@@ -3444,7 +3420,7 @@ static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
|
||||
for(i=j=0; i<16; i+=2){
|
||||
x = digest[i]*256 + digest[i+1];
|
||||
if( i>0 ) zDigest[j++] = '-';
|
||||
sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
|
||||
sprintf(&zDigest[j], "%05u", x);
|
||||
j += 5;
|
||||
}
|
||||
zDigest[j] = 0;
|
||||
@@ -3665,45 +3641,6 @@ static int db_use_legacy_prepare_cmd(
|
||||
Tcl_ResetResult(interp);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: db_last_stmt_ptr DB
|
||||
**
|
||||
** If the statement cache associated with database DB is not empty,
|
||||
** return the text representation of the most recently used statement
|
||||
** handle.
|
||||
*/
|
||||
static int db_last_stmt_ptr(
|
||||
ClientData cd,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
|
||||
Tcl_CmdInfo cmdInfo;
|
||||
SqliteDb *pDb;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char zBuf[100];
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
|
||||
Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pDb = (SqliteDb*)cmdInfo.objClientData;
|
||||
|
||||
if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt;
|
||||
if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3749,7 +3686,6 @@ static void init_all(Tcl_Interp *interp){
|
||||
extern int Sqlitetest9_Init(Tcl_Interp*);
|
||||
extern int Sqlitetestasync_Init(Tcl_Interp*);
|
||||
extern int Sqlitetest_autoext_Init(Tcl_Interp*);
|
||||
extern int Sqlitetest_blob_Init(Tcl_Interp*);
|
||||
extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
|
||||
extern int Sqlitetest_func_Init(Tcl_Interp*);
|
||||
extern int Sqlitetest_hexio_Init(Tcl_Interp*);
|
||||
@@ -3793,7 +3729,6 @@ static void init_all(Tcl_Interp *interp){
|
||||
Sqlitetest9_Init(interp);
|
||||
Sqlitetestasync_Init(interp);
|
||||
Sqlitetest_autoext_Init(interp);
|
||||
Sqlitetest_blob_Init(interp);
|
||||
Sqlitetest_demovfs_Init(interp);
|
||||
Sqlitetest_func_Init(interp);
|
||||
Sqlitetest_hexio_Init(interp);
|
||||
@@ -3825,9 +3760,6 @@ static void init_all(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(
|
||||
interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
|
||||
);
|
||||
Tcl_CreateObjCommand(
|
||||
interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
|
||||
);
|
||||
|
||||
#ifdef SQLITE_SSE
|
||||
Sqlitetestsse_Init(interp);
|
||||
@@ -3836,11 +3768,6 @@ static void init_all(Tcl_Interp *interp){
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Needed for the setrlimit() system call on unix */
|
||||
#if defined(unix)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#define TCLSH_MAIN main /* Needed to fake out mktclapp */
|
||||
int TCLSH_MAIN(int argc, char **argv){
|
||||
Tcl_Interp *interp;
|
||||
@@ -3854,17 +3781,6 @@ int TCLSH_MAIN(int argc, char **argv){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Since the primary use case for this binary is testing of SQLite,
|
||||
** be sure to generate core files if we crash */
|
||||
#if defined(SQLITE_TEST) && defined(unix)
|
||||
{ struct rlimit x;
|
||||
getrlimit(RLIMIT_CORE, &x);
|
||||
x.rlim_cur = x.rlim_max;
|
||||
setrlimit(RLIMIT_CORE, &x);
|
||||
}
|
||||
#endif /* SQLITE_TEST && unix */
|
||||
|
||||
|
||||
/* Call sqlite3_shutdown() once before doing anything else. This is to
|
||||
** test that sqlite3_shutdown() can be safely called by a process before
|
||||
** sqlite3_initialize() is. */
|
||||
|
||||
+192
-251
@@ -94,7 +94,10 @@ static int get_sqlite_pointer(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p = (struct SqliteDb*)cmdInfo.objClientData;
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p->db);
|
||||
sprintf(zBuf, "%p", p->db);
|
||||
if( strncmp(zBuf,"0x",2) ){
|
||||
sprintf(zBuf, "0x%p", p->db);
|
||||
}
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -142,8 +145,7 @@ int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
|
||||
&& sqlite3_errcode(db)!=rc ){
|
||||
char zBuf[200];
|
||||
int r2 = sqlite3_errcode(db);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf,
|
||||
"error code %s (%d) does not match sqlite3_errcode %s (%d)",
|
||||
sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
|
||||
t1ErrorName(rc), rc, t1ErrorName(r2), r2);
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
@@ -259,8 +261,6 @@ static int test_io_trace(
|
||||
**
|
||||
** Returns true if the program was compiled using clang with the
|
||||
** -fsanitize=address switch on the command line. False otherwise.
|
||||
**
|
||||
** Also return true if the OMIT_MISUSE environment variable exists.
|
||||
*/
|
||||
static int clang_sanitize_address(
|
||||
void *NotUsed,
|
||||
@@ -274,7 +274,6 @@ static int clang_sanitize_address(
|
||||
res = 1;
|
||||
# endif
|
||||
#endif
|
||||
if( res==0 && getenv("OMIT_MISUSE")!=0 ) res = 1;
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -308,7 +307,7 @@ static int test_exec_printf(
|
||||
zSql = sqlite3_mprintf(argv[2], argv[3]);
|
||||
rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
|
||||
sqlite3_free(zSql);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
|
||||
sprintf(zBuf, "%d", rc);
|
||||
Tcl_AppendElement(interp, zBuf);
|
||||
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
|
||||
Tcl_DStringFree(&str);
|
||||
@@ -355,7 +354,7 @@ static int test_exec_hex(
|
||||
zSql[i] = 0;
|
||||
Tcl_DStringInit(&str);
|
||||
rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
|
||||
sprintf(zBuf, "%d", rc);
|
||||
Tcl_AppendElement(interp, zBuf);
|
||||
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
|
||||
Tcl_DStringFree(&str);
|
||||
@@ -440,7 +439,7 @@ static int test_exec(
|
||||
zSql[j] = 0;
|
||||
rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
|
||||
sqlite3_free(zSql);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
|
||||
sprintf(zBuf, "%d", rc);
|
||||
Tcl_AppendElement(interp, zBuf);
|
||||
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
|
||||
Tcl_DStringFree(&str);
|
||||
@@ -565,7 +564,7 @@ static int test_get_table_printf(
|
||||
Tcl_DString str;
|
||||
int rc;
|
||||
char *zErr = 0;
|
||||
int nRow = 0, nCol = 0;
|
||||
int nRow, nCol;
|
||||
char **aResult;
|
||||
int i;
|
||||
char zBuf[30];
|
||||
@@ -589,13 +588,13 @@ static int test_get_table_printf(
|
||||
resCount = (nRow+1)*nCol;
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
|
||||
sprintf(zBuf, "%d", rc);
|
||||
Tcl_AppendElement(interp, zBuf);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( argc==4 ){
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nRow);
|
||||
sprintf(zBuf, "%d", nRow);
|
||||
Tcl_AppendElement(interp, zBuf);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nCol);
|
||||
sprintf(zBuf, "%d", nCol);
|
||||
Tcl_AppendElement(interp, zBuf);
|
||||
}
|
||||
for(i=0; i<resCount; i++){
|
||||
@@ -632,7 +631,7 @@ static int test_last_rowid(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", sqlite3_last_insert_rowid(db));
|
||||
sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -772,7 +771,7 @@ static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){
|
||||
char zBuf[200];
|
||||
z = sqlite3_value_text(argv[0]);
|
||||
for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){
|
||||
sqlite3_snprintf(sizeof(zBuf)-i*2, &zBuf[i*2], "%02x", z[i]);
|
||||
sprintf(&zBuf[i*2], "%02x", z[i]&0xff);
|
||||
}
|
||||
zBuf[i*2] = 0;
|
||||
sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
|
||||
@@ -784,7 +783,7 @@ static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){
|
||||
char zBuf[400];
|
||||
z = sqlite3_value_text16(argv[0]);
|
||||
for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){
|
||||
sqlite3_snprintf(sizeof(zBuf)-i*4, &zBuf[i*4],"%04x", z[i]&0xff);
|
||||
sprintf(&zBuf[i*4], "%04x", z[i]&0xff);
|
||||
}
|
||||
zBuf[i*4] = 0;
|
||||
sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
|
||||
@@ -1570,6 +1569,7 @@ static int test_libversion_number(
|
||||
** Usage: sqlite3_table_column_metadata DB dbname tblname colname
|
||||
**
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
static int test_table_column_metadata(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
@@ -1589,14 +1589,14 @@ static int test_table_column_metadata(
|
||||
int primarykey;
|
||||
int autoincrement;
|
||||
|
||||
if( objc!=5 && objc!=4 ){
|
||||
if( objc!=5 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB dbname tblname colname");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zDb = Tcl_GetString(objv[2]);
|
||||
zTbl = Tcl_GetString(objv[3]);
|
||||
zCol = objc==5 ? Tcl_GetString(objv[4]) : 0;
|
||||
zCol = Tcl_GetString(objv[4]);
|
||||
|
||||
if( strlen(zDb)==0 ) zDb = 0;
|
||||
|
||||
@@ -1618,6 +1618,7 @@ static int test_table_column_metadata(
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
|
||||
@@ -1650,6 +1651,154 @@ static int blobHandleFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_bytes CHANNEL
|
||||
*/
|
||||
static int test_blob_bytes(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int nByte;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
nByte = sqlite3_blob_bytes(pBlob);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte));
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_close CHANNEL
|
||||
*/
|
||||
static int test_blob_close(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
sqlite3_blob_close(pBlob);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_read CHANNEL OFFSET N
|
||||
**
|
||||
** This command is used to test the sqlite3_blob_read() in ways that
|
||||
** the Tcl channel interface does not. The first argument should
|
||||
** be the name of a valid channel created by the [incrblob] method
|
||||
** of a database handle. This function calls sqlite3_blob_read()
|
||||
** to read N bytes from offset OFFSET from the underlying SQLite
|
||||
** blob handle.
|
||||
**
|
||||
** On success, a byte-array object containing the read data is
|
||||
** returned. On failure, the interpreter result is set to the
|
||||
** text representation of the returned error code (i.e. "SQLITE_NOMEM")
|
||||
** and a Tcl exception is thrown.
|
||||
*/
|
||||
static int test_blob_read(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int nByte;
|
||||
int iOffset;
|
||||
unsigned char *zBuf = 0;
|
||||
int rc;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
|
||||
|| TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte)
|
||||
){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( nByte>0 ){
|
||||
zBuf = (unsigned char *)Tcl_Alloc(nByte);
|
||||
}
|
||||
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
|
||||
if( rc==SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte));
|
||||
}else{
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
}
|
||||
Tcl_Free((char *)zBuf);
|
||||
|
||||
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA?
|
||||
**
|
||||
** This command is used to test the sqlite3_blob_write() in ways that
|
||||
** the Tcl channel interface does not. The first argument should
|
||||
** be the name of a valid channel created by the [incrblob] method
|
||||
** of a database handle. This function calls sqlite3_blob_write()
|
||||
** to write the DATA byte-array to the underlying SQLite blob handle.
|
||||
** at offset OFFSET.
|
||||
**
|
||||
** On success, an empty string is returned. On failure, the interpreter
|
||||
** result is set to the text representation of the returned error code
|
||||
** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown.
|
||||
*/
|
||||
static int test_blob_write(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int iOffset;
|
||||
int rc;
|
||||
|
||||
unsigned char *zBuf;
|
||||
int nBuf;
|
||||
|
||||
if( objc!=4 && objc!=5 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
|
||||
if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
}
|
||||
|
||||
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
|
||||
}
|
||||
|
||||
static int test_blob_reopen(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
@@ -2118,7 +2267,7 @@ static int test_stmt_status(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int iValue;
|
||||
int i, op = 0, resetFlag;
|
||||
int i, op, resetFlag;
|
||||
const char *zOpName;
|
||||
sqlite3_stmt *pStmt;
|
||||
|
||||
@@ -2152,77 +2301,6 @@ static int test_stmt_status(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
/*
|
||||
** Usage: sqlite3_stmt_scanstatus STMT IDX
|
||||
*/
|
||||
static int test_stmt_scanstatus(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt; /* First argument */
|
||||
int idx; /* Second argument */
|
||||
|
||||
const char *zName;
|
||||
const char *zExplain;
|
||||
sqlite3_int64 nLoop;
|
||||
sqlite3_int64 nVisit;
|
||||
double rEst;
|
||||
int res;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||
|
||||
res = sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop);
|
||||
if( res==0 ){
|
||||
Tcl_Obj *pRet = Tcl_NewObj();
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nLoop", -1));
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nLoop));
|
||||
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nVisit", -1));
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nVisit));
|
||||
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EST, (void*)&rEst);
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nEst", -1));
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewDoubleObj(rEst));
|
||||
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NAME, (void*)&zName);
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zName", -1));
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zName, -1));
|
||||
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zExplain", -1));
|
||||
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zExplain, -1));
|
||||
Tcl_SetObjResult(interp, pRet);
|
||||
}else{
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_stmt_scanstatus_reset STMT
|
||||
*/
|
||||
static int test_stmt_scanstatus_reset(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt; /* First argument */
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
sqlite3_stmt_scanstatus_reset(pStmt);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_next_stmt DB STMT
|
||||
**
|
||||
@@ -2495,7 +2573,7 @@ static int test_bind(
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc ){
|
||||
char zBuf[50];
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
|
||||
sprintf(zBuf, "(%d) ", rc);
|
||||
Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3096,7 +3174,7 @@ static int test_bind_double(
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int idx;
|
||||
double value = 0;
|
||||
double value;
|
||||
int rc;
|
||||
const char *zVal;
|
||||
int i;
|
||||
@@ -3609,7 +3687,7 @@ static int test_prepare(
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pStmt==0 );
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
|
||||
sprintf(zBuf, "(%d) ", rc);
|
||||
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3637,7 +3715,6 @@ static int test_prepare_v2(
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zSql;
|
||||
char *zCopy = 0; /* malloc() copy of zSql */
|
||||
int bytes;
|
||||
const char *zTail = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
@@ -3653,25 +3730,11 @@ static int test_prepare_v2(
|
||||
zSql = Tcl_GetString(objv[2]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
|
||||
|
||||
/* Instead of using zSql directly, make a copy into a buffer obtained
|
||||
** directly from malloc(). The idea is to make it easier for valgrind
|
||||
** to spot buffer overreads. */
|
||||
if( bytes>=0 ){
|
||||
zCopy = malloc(bytes);
|
||||
memcpy(zCopy, zSql, bytes);
|
||||
}else{
|
||||
int n = (int)strlen(zSql) + 1;
|
||||
zCopy = malloc(n);
|
||||
memcpy(zCopy, zSql, n);
|
||||
}
|
||||
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
|
||||
free(zCopy);
|
||||
zTail = &zSql[(zTail - zCopy)];
|
||||
|
||||
rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
|
||||
assert(rc==SQLITE_OK || pStmt==0);
|
||||
Tcl_ResetResult(interp);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
if( rc==SQLITE_OK && zTail && objc>=5 ){
|
||||
if( zTail && objc>=5 ){
|
||||
if( bytes>=0 ){
|
||||
bytes = bytes - (int)(zTail-zSql);
|
||||
}
|
||||
@@ -3679,7 +3742,7 @@ static int test_prepare_v2(
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pStmt==0 );
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
|
||||
sprintf(zBuf, "(%d) ", rc);
|
||||
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3720,7 +3783,7 @@ static int test_prepare_tkt3134(
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pStmt==0 );
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
|
||||
sprintf(zBuf, "(%d) ", rc);
|
||||
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -4535,7 +4598,7 @@ static int get_autocommit(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3_get_autocommit(db));
|
||||
sprintf(zBuf, "%d", sqlite3_get_autocommit(db));
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -5171,7 +5234,7 @@ static int file_control_lockproxy_test(
|
||||
Tcl_AppendResult(interp, "PWD too big", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_snprintf(sizeof(proxyPath), proxyPath, "%s/test.proxy", zPwd);
|
||||
sprintf(proxyPath, "%s/test.proxy", zPwd);
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
||||
if( rc ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
@@ -5456,7 +5519,7 @@ static int test_limit(
|
||||
{ "SQLITE_LIMIT_TOOSMALL", -1, },
|
||||
{ "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_WORKER_THREADS+1 },
|
||||
};
|
||||
int i, id = 0;
|
||||
int i, id;
|
||||
int val;
|
||||
const char *zId;
|
||||
|
||||
@@ -5689,11 +5752,10 @@ static int test_wal_checkpoint_v2(
|
||||
int nCkpt = -555;
|
||||
Tcl_Obj *pRet;
|
||||
|
||||
const char * aMode[] = { "passive", "full", "restart", "truncate", 0 };
|
||||
const char * aMode[] = { "passive", "full", "restart", 0 };
|
||||
assert( SQLITE_CHECKPOINT_PASSIVE==0 );
|
||||
assert( SQLITE_CHECKPOINT_FULL==1 );
|
||||
assert( SQLITE_CHECKPOINT_RESTART==2 );
|
||||
assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
|
||||
|
||||
if( objc!=3 && objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
|
||||
@@ -5703,18 +5765,15 @@ static int test_wal_checkpoint_v2(
|
||||
if( objc==4 ){
|
||||
zDb = Tcl_GetString(objv[3]);
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) || (
|
||||
TCL_OK!=Tcl_GetIntFromObj(0, objv[2], &eMode)
|
||||
&& TCL_OK!=Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode)
|
||||
)){
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
|
||||
|| Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode)
|
||||
){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = sqlite3_wal_checkpoint_v2(db, zDb, eMode, &nLog, &nCkpt);
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
|
||||
const char *zErrCode = sqlite3ErrName(rc);
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, zErrCode, " - ", (char *)sqlite3_errmsg(db), 0);
|
||||
Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -5727,43 +5786,6 @@ static int test_wal_checkpoint_v2(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite3_wal_autocheckpoint db VALUE
|
||||
*/
|
||||
static int test_wal_autocheckpoint(
|
||||
ClientData clientData, /* Unused */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
int iVal;
|
||||
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB VALUE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
|
||||
|| Tcl_GetIntFromObj(0, objv[2], &iVal)
|
||||
){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = sqlite3_wal_autocheckpoint(db, iVal);
|
||||
Tcl_ResetResult(interp);
|
||||
if( rc!=SQLITE_OK ){
|
||||
const char *zErrCode = sqlite3ErrName(rc);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(zErrCode, -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** tclcmd: test_sqlite3_log ?SCRIPT?
|
||||
*/
|
||||
@@ -5914,8 +5936,7 @@ static int test_test_control(
|
||||
int i;
|
||||
} aVerb[] = {
|
||||
{ "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
|
||||
{ "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
|
||||
{ "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER },
|
||||
{ "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
|
||||
};
|
||||
int iVerb;
|
||||
int iFlag;
|
||||
@@ -5956,22 +5977,6 @@ static int test_test_control(
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val);
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_TESTCTRL_IMPOSTER: {
|
||||
int onOff, tnum;
|
||||
const char *zDbName;
|
||||
sqlite3 *db;
|
||||
if( objc!=6 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
|
||||
zDbName = Tcl_GetString(objv[3]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR;
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
@@ -5993,8 +5998,7 @@ static int test_getrusage(
|
||||
memset(&r, 0, sizeof(r));
|
||||
getrusage(RUSAGE_SELF, &r);
|
||||
|
||||
sqlite3_snprintf(sizeof(buf), buf,
|
||||
"ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
|
||||
sprintf(buf, "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
|
||||
(int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec,
|
||||
(int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec,
|
||||
(int)r.ru_minflt, (int)r.ru_majflt
|
||||
@@ -6289,8 +6293,7 @@ static int optimization_control(
|
||||
{ "transitive", SQLITE_Transitive },
|
||||
{ "subquery-coroutine", SQLITE_SubqCoroutine },
|
||||
{ "omit-noop-join", SQLITE_OmitNoopJoin },
|
||||
{ "stat3", SQLITE_Stat34 },
|
||||
{ "stat4", SQLITE_Stat34 },
|
||||
{ "stat3", SQLITE_Stat3 },
|
||||
};
|
||||
|
||||
if( objc!=4 ){
|
||||
@@ -6333,7 +6336,6 @@ static int tclLoadStaticExtensionCmd(
|
||||
){
|
||||
extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
@@ -6349,7 +6351,6 @@ static int tclLoadStaticExtensionCmd(
|
||||
} aExtension[] = {
|
||||
{ "amatch", sqlite3_amatch_init },
|
||||
{ "closure", sqlite3_closure_init },
|
||||
{ "eval", sqlite3_eval_init },
|
||||
{ "fileio", sqlite3_fileio_init },
|
||||
{ "fuzzer", sqlite3_fuzzer_init },
|
||||
{ "ieee754", sqlite3_ieee_init },
|
||||
@@ -6623,65 +6624,6 @@ static int test_user_delete(
|
||||
}
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
||||
|
||||
/*
|
||||
** tclcmd: bad_behavior TYPE
|
||||
**
|
||||
** Do some things that should trigger a valgrind or -fsanitize=undefined
|
||||
** warning. This is used to verify that errors and warnings output by those
|
||||
** tools are detected by the test scripts.
|
||||
**
|
||||
** TYPE BEHAVIOR
|
||||
** 1 Overflow a signed integer
|
||||
** 2 Jump based on an uninitialized variable
|
||||
** 3 Read after free
|
||||
** 4 Panic
|
||||
*/
|
||||
static int test_bad_behavior(
|
||||
ClientData clientData, /* Pointer to an integer containing zero */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
int iType;
|
||||
int xyz;
|
||||
int i = *(int*)clientData;
|
||||
int j;
|
||||
int w[10];
|
||||
int *a;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "TYPE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[1], &iType) ) return TCL_ERROR;
|
||||
switch( iType ){
|
||||
case 1: {
|
||||
xyz = 0x7fffff00 - i;
|
||||
xyz += 0x100;
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(xyz));
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
w[1] = 5;
|
||||
if( w[i]>0 ) w[1]++;
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(w[1]));
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
a = malloc( sizeof(int)*10 );
|
||||
for(j=0; j<10; j++) a[j] = j;
|
||||
free(a);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(a[i]));
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
Tcl_Panic("Deliberate panic");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
*/
|
||||
@@ -6698,7 +6640,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
extern int sqlite3_max_blobsize;
|
||||
extern int sqlite3BtreeSharedCacheReport(void*,
|
||||
Tcl_Interp*,int,Tcl_Obj*CONST*);
|
||||
static int iZero = 0;
|
||||
static struct {
|
||||
char *zName;
|
||||
Tcl_CmdProc *xProc;
|
||||
@@ -6751,7 +6692,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
Tcl_ObjCmdProc *xProc;
|
||||
void *clientData;
|
||||
} aObjCmd[] = {
|
||||
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
|
||||
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
|
||||
{ "sqlite3_bind_int", test_bind_int, 0 },
|
||||
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },
|
||||
@@ -6894,9 +6834,15 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0},
|
||||
#endif
|
||||
{ "sqlite3_libversion_number", test_libversion_number, 0 },
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
{ "sqlite3_table_column_metadata", test_table_column_metadata, 0 },
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
{ "sqlite3_blob_read", test_blob_read, 0 },
|
||||
{ "sqlite3_blob_write", test_blob_write, 0 },
|
||||
{ "sqlite3_blob_reopen", test_blob_reopen, 0 },
|
||||
{ "sqlite3_blob_bytes", test_blob_bytes, 0 },
|
||||
{ "sqlite3_blob_close", test_blob_close, 0 },
|
||||
#endif
|
||||
{ "pcache_stats", test_pcache_stats, 0 },
|
||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
@@ -6904,7 +6850,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
#endif
|
||||
{ "sqlite3_wal_checkpoint", test_wal_checkpoint, 0 },
|
||||
{ "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0 },
|
||||
{ "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0 },
|
||||
{ "test_sqlite3_log", test_sqlite3_log, 0 },
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
{ "print_explain_query_plan", test_print_eqp, 0 },
|
||||
@@ -6922,10 +6867,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_user_change", test_user_change, 0 },
|
||||
{ "sqlite3_user_delete", test_user_delete, 0 },
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
{ "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 },
|
||||
{ "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 },
|
||||
#endif
|
||||
|
||||
};
|
||||
static int bitmask_size = sizeof(Bitmask)*8;
|
||||
|
||||
+1
-1
@@ -310,7 +310,7 @@ static int page_get(
|
||||
){
|
||||
Pager *pPager;
|
||||
char zBuf[100];
|
||||
DbPage *pPage = 0;
|
||||
DbPage *pPage;
|
||||
int pgno;
|
||||
int rc;
|
||||
if( argc!=3 ){
|
||||
|
||||
+5
-10
@@ -445,21 +445,18 @@ static int btree_varint_test(
|
||||
char zErr[200];
|
||||
n1 = putVarint(zBuf, in);
|
||||
if( n1>9 || n1<1 ){
|
||||
sqlite3_snprintf(sizeof(zErr), zErr,
|
||||
"putVarint returned %d - should be between 1 and 9", n1);
|
||||
sprintf(zErr, "putVarint returned %d - should be between 1 and 9", n1);
|
||||
Tcl_AppendResult(interp, zErr, 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
n2 = getVarint(zBuf, &out);
|
||||
if( n1!=n2 ){
|
||||
sqlite3_snprintf(sizeof(zErr), zErr,
|
||||
"putVarint returned %d and getVarint returned %d", n1, n2);
|
||||
sprintf(zErr, "putVarint returned %d and getVarint returned %d", n1, n2);
|
||||
Tcl_AppendResult(interp, zErr, 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( in!=out ){
|
||||
sqlite3_snprintf(sizeof(zErr), zErr,
|
||||
"Wrote 0x%016llx and got back 0x%016llx", in, out);
|
||||
sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx", in, out);
|
||||
Tcl_AppendResult(interp, zErr, 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -468,15 +465,13 @@ static int btree_varint_test(
|
||||
n2 = getVarint32(zBuf, out32);
|
||||
out = out32;
|
||||
if( n1!=n2 ){
|
||||
sqlite3_snprintf(sizeof(zErr), zErr,
|
||||
"putVarint returned %d and GetVarint32 returned %d",
|
||||
sprintf(zErr, "putVarint returned %d and GetVarint32 returned %d",
|
||||
n1, n2);
|
||||
Tcl_AppendResult(interp, zErr, 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( in!=out ){
|
||||
sqlite3_snprintf(sizeof(zErr), zErr,
|
||||
"Wrote 0x%016llx and got back 0x%016llx from GetVarint32",
|
||||
sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx from GetVarint32",
|
||||
in, out);
|
||||
Tcl_AppendResult(interp, zErr, 0);
|
||||
return TCL_ERROR;
|
||||
|
||||
+1
-1
@@ -270,7 +270,7 @@ static int tcl_thread_argc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
thread_wait(&threadset[i]);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", threadset[i].argc);
|
||||
sprintf(zBuf, "%d", threadset[i].argc);
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+1
-1
@@ -315,7 +315,7 @@ static int tcl_client_argc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
client_wait(&threadset[i]);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", threadset[i].argc);
|
||||
sprintf(zBuf, "%d", threadset[i].argc);
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+7
-7
@@ -206,8 +206,8 @@ static int getColumnNames(
|
||||
zSpace = (char *)(&aCol[nCol]);
|
||||
for(ii=0; ii<nCol; ii++){
|
||||
aCol[ii] = zSpace;
|
||||
sqlite3_snprintf(nBytes, zSpace, "%s", sqlite3_column_name(pStmt,ii));
|
||||
zSpace += (int)strlen(zSpace) + 1;
|
||||
zSpace += sprintf(zSpace, "%s", sqlite3_column_name(pStmt, ii));
|
||||
zSpace++;
|
||||
}
|
||||
assert( (zSpace-nBytes)==(char *)aCol );
|
||||
}
|
||||
@@ -648,12 +648,12 @@ static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
** indeed the hash of the supplied idxStr.
|
||||
*/
|
||||
static int hashString(const char *zString){
|
||||
u32 val = 0;
|
||||
int val = 0;
|
||||
int ii;
|
||||
for(ii=0; zString[ii]; ii++){
|
||||
val = (val << 3) + (int)zString[ii];
|
||||
}
|
||||
return (int)(val&0x7fffffff);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -777,11 +777,11 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
Tcl_Interp *interp = pVtab->interp;
|
||||
|
||||
int nRow = 0;
|
||||
int nRow;
|
||||
int useIdx = 0;
|
||||
int rc = SQLITE_OK;
|
||||
int useCost = 0;
|
||||
double cost = 0;
|
||||
double cost;
|
||||
int isIgnoreUsable = 0;
|
||||
if( Tcl_GetVar(interp, "echo_module_ignore_usable", TCL_GLOBAL_ONLY) ){
|
||||
isIgnoreUsable = 1;
|
||||
@@ -927,7 +927,7 @@ int echoUpdate(
|
||||
sqlite3 *db = pVtab->db;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
sqlite3_stmt *pStmt;
|
||||
char *z = 0; /* SQL statement to execute */
|
||||
int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */
|
||||
int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "tcl.h"
|
||||
#include "sqlite3.h"
|
||||
#include <sqlite3.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* These functions are implemented in main.c. */
|
||||
|
||||
-319
@@ -1,319 +0,0 @@
|
||||
/*
|
||||
** 2014 October 30
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* These functions are implemented in main.c. */
|
||||
extern const char *sqlite3ErrName(int);
|
||||
|
||||
/* From test1.c: */
|
||||
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
|
||||
extern void *sqlite3TestTextToPtr(const char *z);
|
||||
|
||||
/*
|
||||
** Return a pointer to a buffer containing a text representation of the
|
||||
** pointer passed as the only argument. The original pointer may be extracted
|
||||
** from the text using sqlite3TestTextToPtr().
|
||||
*/
|
||||
static char *ptrToText(void *p){
|
||||
static char buf[100];
|
||||
sqlite3_snprintf(sizeof(buf)-1, buf, "%p", p);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to extract a blob handle (type sqlite3_blob*) from the Tcl
|
||||
** object passed as the second argument. If successful, set *ppBlob to
|
||||
** point to the blob handle and return TCL_OK. Otherwise, store an error
|
||||
** message in the tcl interpreter and return TCL_ERROR. The final value
|
||||
** of *ppBlob is undefined in this case.
|
||||
**
|
||||
** If the object contains a string that begins with "incrblob_", then it
|
||||
** is assumed to be the name of a Tcl channel opened using the [db incrblob]
|
||||
** command (see tclsqlite.c). Otherwise, it is assumed to be a pointer
|
||||
** encoded using the ptrToText() routine or similar.
|
||||
*/
|
||||
static int blobHandleFromObj(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *pObj,
|
||||
sqlite3_blob **ppBlob
|
||||
){
|
||||
char *z;
|
||||
int n;
|
||||
|
||||
z = Tcl_GetStringFromObj(pObj, &n);
|
||||
if( n==0 ){
|
||||
*ppBlob = 0;
|
||||
}else if( n>9 && 0==memcmp("incrblob_", z, 9) ){
|
||||
int notUsed;
|
||||
Tcl_Channel channel;
|
||||
ClientData instanceData;
|
||||
|
||||
channel = Tcl_GetChannel(interp, z, ¬Used);
|
||||
if( !channel ) return TCL_ERROR;
|
||||
|
||||
Tcl_Flush(channel);
|
||||
Tcl_Seek(channel, 0, SEEK_SET);
|
||||
|
||||
instanceData = Tcl_GetChannelInstanceData(channel);
|
||||
*ppBlob = *((sqlite3_blob **)instanceData);
|
||||
}else{
|
||||
*ppBlob = (sqlite3_blob*)sqlite3TestTextToPtr(z);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Like Tcl_GetString(), except that if the string is 0 bytes in size, a
|
||||
** NULL Pointer is returned.
|
||||
*/
|
||||
static char *blobStringFromObj(Tcl_Obj *pObj){
|
||||
int n;
|
||||
char *z;
|
||||
z = Tcl_GetStringFromObj(pObj, &n);
|
||||
return (n ? z : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_open DB DATABASE TABLE COLUMN ROWID FLAGS VARNAME
|
||||
**
|
||||
** Tcl test harness for the sqlite3_blob_open() function.
|
||||
*/
|
||||
static int test_blob_open(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* Calling TCL interpreter */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zDb;
|
||||
const char *zTable;
|
||||
const char *zColumn;
|
||||
sqlite_int64 iRowid;
|
||||
int flags;
|
||||
const char *zVarname;
|
||||
int nVarname;
|
||||
|
||||
sqlite3_blob *pBlob = (sqlite3_blob*)0xFFFFFFFF;
|
||||
int rc;
|
||||
|
||||
if( objc!=8 ){
|
||||
const char *zUsage = "DB DATABASE TABLE COLUMN ROWID FLAGS VARNAME";
|
||||
Tcl_WrongNumArgs(interp, 1, objv, zUsage);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zDb = Tcl_GetString(objv[2]);
|
||||
zTable = blobStringFromObj(objv[3]);
|
||||
zColumn = Tcl_GetString(objv[4]);
|
||||
if( Tcl_GetWideIntFromObj(interp, objv[5], &iRowid) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[6], &flags) ) return TCL_ERROR;
|
||||
zVarname = Tcl_GetStringFromObj(objv[7], &nVarname);
|
||||
|
||||
if( nVarname>0 ){
|
||||
rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRowid, flags, &pBlob);
|
||||
Tcl_SetVar(interp, zVarname, ptrToText(pBlob), 0);
|
||||
}else{
|
||||
rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRowid, flags, 0);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
Tcl_ResetResult(interp);
|
||||
}else{
|
||||
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** sqlite3_blob_close HANDLE
|
||||
*/
|
||||
static int test_blob_close(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int rc;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
rc = sqlite3_blob_close(pBlob);
|
||||
|
||||
if( rc ){
|
||||
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
}else{
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_bytes HANDLE
|
||||
*/
|
||||
static int test_blob_bytes(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int nByte;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
nByte = sqlite3_blob_bytes(pBlob);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte));
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_read CHANNEL OFFSET N
|
||||
**
|
||||
** This command is used to test the sqlite3_blob_read() in ways that
|
||||
** the Tcl channel interface does not. The first argument should
|
||||
** be the name of a valid channel created by the [incrblob] method
|
||||
** of a database handle. This function calls sqlite3_blob_read()
|
||||
** to read N bytes from offset OFFSET from the underlying SQLite
|
||||
** blob handle.
|
||||
**
|
||||
** On success, a byte-array object containing the read data is
|
||||
** returned. On failure, the interpreter result is set to the
|
||||
** text representation of the returned error code (i.e. "SQLITE_NOMEM")
|
||||
** and a Tcl exception is thrown.
|
||||
*/
|
||||
static int test_blob_read(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int nByte;
|
||||
int iOffset;
|
||||
unsigned char *zBuf = 0;
|
||||
int rc;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
|
||||
|| TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte)
|
||||
){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( nByte>0 ){
|
||||
zBuf = (unsigned char *)Tcl_Alloc(nByte);
|
||||
}
|
||||
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
|
||||
if( rc==SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte));
|
||||
}else{
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
}
|
||||
Tcl_Free((char *)zBuf);
|
||||
|
||||
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_blob_write HANDLE OFFSET DATA ?NDATA?
|
||||
**
|
||||
** This command is used to test the sqlite3_blob_write() in ways that
|
||||
** the Tcl channel interface does not. The first argument should
|
||||
** be the name of a valid channel created by the [incrblob] method
|
||||
** of a database handle. This function calls sqlite3_blob_write()
|
||||
** to write the DATA byte-array to the underlying SQLite blob handle.
|
||||
** at offset OFFSET.
|
||||
**
|
||||
** On success, an empty string is returned. On failure, the interpreter
|
||||
** result is set to the text representation of the returned error code
|
||||
** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown.
|
||||
*/
|
||||
static int test_blob_write(
|
||||
ClientData clientData, /* Not used */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_blob *pBlob;
|
||||
int iOffset;
|
||||
int rc;
|
||||
|
||||
unsigned char *zBuf;
|
||||
int nBuf;
|
||||
|
||||
if( objc!=4 && objc!=5 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET DATA ?NDATA?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
|
||||
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
|
||||
if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
}
|
||||
|
||||
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
*/
|
||||
int Sqlitetest_blob_Init(Tcl_Interp *interp){
|
||||
static struct {
|
||||
char *zName;
|
||||
Tcl_ObjCmdProc *xProc;
|
||||
} aObjCmd[] = {
|
||||
{ "sqlite3_blob_open", test_blob_open },
|
||||
{ "sqlite3_blob_close", test_blob_close },
|
||||
{ "sqlite3_blob_bytes", test_blob_bytes },
|
||||
{ "sqlite3_blob_read", test_blob_read },
|
||||
{ "sqlite3_blob_write", test_blob_write },
|
||||
};
|
||||
int i;
|
||||
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
+2
-13
@@ -41,7 +41,7 @@
|
||||
** procedures use this to determine when tests should be omitted.
|
||||
*/
|
||||
static void set_options(Tcl_Interp *interp){
|
||||
#if HAVE_MALLOC_USABLE_SIZE
|
||||
#ifdef HAVE_MALLOC_USABLE_SIZE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "1",
|
||||
TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -155,12 +155,6 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
Tcl_SetVar2(interp, "sqlite_options", "api_armor", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "api_armor", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "atomicwrite", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -490,12 +484,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
Tcl_SetVar2(interp, "sqlite_options", "scanstatus", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "scanstatus", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
|
||||
# if defined(__APPLE__)
|
||||
# define SQLITE_ENABLE_LOCKING_STYLE 1
|
||||
@@ -650,6 +638,7 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
LINKVAR( MAX_PAGE_COUNT );
|
||||
LINKVAR( MAX_LIKE_PATTERN_LENGTH );
|
||||
LINKVAR( MAX_TRIGGER_DEPTH );
|
||||
LINKVAR( DEFAULT_TEMP_CACHE_SIZE );
|
||||
LINKVAR( DEFAULT_CACHE_SIZE );
|
||||
LINKVAR( DEFAULT_PAGE_SIZE );
|
||||
LINKVAR( DEFAULT_FILE_FORMAT );
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@
|
||||
|
||||
#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
+1
-16
@@ -600,26 +600,12 @@ static void test_decode(
|
||||
Tcl_DecrRefCount(pRet);
|
||||
}
|
||||
|
||||
/*
|
||||
** The implementation of scalar SQL function "test_zeroblob()". This is
|
||||
** similar to the built-in zeroblob() function, except that it does not
|
||||
** check that the integer parameter is within range before passing it
|
||||
** to sqlite3_result_zeroblob().
|
||||
*/
|
||||
static void test_zeroblob(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
int nZero = sqlite3_value_int(argv[0]);
|
||||
sqlite3_result_zeroblob(context, nZero);
|
||||
}
|
||||
|
||||
static int registerTestFunctions(sqlite3 *db){
|
||||
static const struct {
|
||||
char *zName;
|
||||
signed char nArg;
|
||||
unsigned int eTextRep; /* 1: UTF-16. 0: UTF-8 */
|
||||
unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
|
||||
} aFuncs[] = {
|
||||
{ "randstr", 2, SQLITE_UTF8, randStr },
|
||||
@@ -640,7 +626,6 @@ static int registerTestFunctions(sqlite3 *db){
|
||||
{ "real2hex", 1, SQLITE_UTF8, real2hex},
|
||||
{ "test_decode", 1, SQLITE_UTF8, test_decode},
|
||||
{ "test_extract", 2, SQLITE_UTF8, test_extract},
|
||||
{ "test_zeroblob", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
+2
-5
@@ -409,9 +409,7 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){
|
||||
if( iOff==PENDING_BYTE ) continue;
|
||||
rc = sqlite3OsRead(pMain->pReal, aData, pMain->nPagesize, iOff);
|
||||
pMain->aCksum[ii] = genCksum(aData, pMain->nPagesize);
|
||||
if( ii+1==(int)pMain->nPage && rc==SQLITE_IOERR_SHORT_READ ){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
if( ii+1==pMain->nPage && rc==SQLITE_IOERR_SHORT_READ ) rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,8 +550,7 @@ static int jtWrite(
|
||||
*/
|
||||
}else{
|
||||
u32 pgno = (u32)(iOfst/p->nPagesize + 1);
|
||||
assert( (iAmt==1||iAmt==(int)p->nPagesize) &&
|
||||
((iOfst+iAmt)%p->nPagesize)==0 );
|
||||
assert( (iAmt==1||iAmt==p->nPagesize) && ((iOfst+iAmt)%p->nPagesize)==0 );
|
||||
assert( pgno<=p->nPage || p->nSync>0 );
|
||||
assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) );
|
||||
}
|
||||
|
||||
+2
-31
@@ -1260,34 +1260,6 @@ static int test_config_cis(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_config_pmasz INTEGER
|
||||
**
|
||||
** Set the minimum PMA size.
|
||||
*/
|
||||
static int test_config_pmasz(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc;
|
||||
int iPmaSz;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[1], &iPmaSz) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = sqlite3_config(SQLITE_CONFIG_PMASZ, iPmaSz);
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_dump_memsys3 FILENAME
|
||||
@@ -1338,7 +1310,7 @@ static int test_status(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc, iValue, mxValue;
|
||||
int i, op = 0, resetFlag;
|
||||
int i, op, resetFlag;
|
||||
const char *zOpName;
|
||||
static const struct {
|
||||
const char *zName;
|
||||
@@ -1395,7 +1367,7 @@ static int test_db_status(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc, iValue, mxValue;
|
||||
int i, op = 0, resetFlag;
|
||||
int i, op, resetFlag;
|
||||
const char *zOpName;
|
||||
sqlite3 *db;
|
||||
extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
|
||||
@@ -1542,7 +1514,6 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_config_error", test_config_error ,0 },
|
||||
{ "sqlite3_config_uri", test_config_uri ,0 },
|
||||
{ "sqlite3_config_cis", test_config_cis ,0 },
|
||||
{ "sqlite3_config_pmasz", test_config_pmasz ,0 },
|
||||
{ "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
|
||||
{ "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
|
||||
{ "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },
|
||||
|
||||
+2
-18
@@ -406,7 +406,7 @@ static void multiplexControlFunc(
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
int op = 0;
|
||||
int op;
|
||||
int iVal;
|
||||
|
||||
if( !db || argc!=2 ){
|
||||
@@ -535,7 +535,7 @@ static int multiplexOpen(
|
||||
/* assign pointers to extra space allocated */
|
||||
memset(pGroup, 0, sz);
|
||||
pMultiplexOpen->pGroup = pGroup;
|
||||
pGroup->bEnabled = (unsigned char)-1;
|
||||
pGroup->bEnabled = -1;
|
||||
pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate",
|
||||
(flags & SQLITE_OPEN_MAIN_DB)==0);
|
||||
pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
|
||||
@@ -573,9 +573,6 @@ static int multiplexOpen(
|
||||
rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
|
||||
if( rc==SQLITE_OK && zName ){
|
||||
int bExists;
|
||||
if( flags & SQLITE_OPEN_MASTER_JOURNAL ){
|
||||
pGroup->bEnabled = 0;
|
||||
}else
|
||||
if( sz==0 ){
|
||||
if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
|
||||
/* If opening a main journal file and the first chunk is zero
|
||||
@@ -1007,13 +1004,6 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|
||||
break;
|
||||
case SQLITE_FCNTL_PRAGMA: {
|
||||
char **aFcntl = (char**)pArg;
|
||||
/*
|
||||
** EVIDENCE-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
|
||||
** file control is an array of pointers to strings (char**) in which the
|
||||
** second element of the array is the name of the pragma and the third
|
||||
** element is the argument to the pragma or NULL if the pragma has no
|
||||
** argument.
|
||||
*/
|
||||
if( aFcntl[1] && sqlite3_stricmp(aFcntl[1],"multiplex_truncate")==0 ){
|
||||
if( aFcntl[2] && aFcntl[2][0] ){
|
||||
if( sqlite3_stricmp(aFcntl[2], "on")==0
|
||||
@@ -1025,12 +1015,6 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|
||||
pGroup->bTruncate = 0;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-27806-26076 The handler for an SQLITE_FCNTL_PRAGMA
|
||||
** file control can optionally make the first element of the char**
|
||||
** argument point to a string obtained from sqlite3_mprintf() or the
|
||||
** equivalent and that string will become the result of the pragma
|
||||
** or the error message if the pragma fails.
|
||||
*/
|
||||
aFcntl[0] = sqlite3_mprintf(pGroup->bTruncate ? "on" : "off");
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -889,7 +889,7 @@ int sqlite3_quota_set(
|
||||
** management, update its size.
|
||||
*/
|
||||
int sqlite3_quota_file(const char *zFilename){
|
||||
char *zFull = 0;
|
||||
char *zFull;
|
||||
sqlite3_file *fd;
|
||||
int rc;
|
||||
int outFlags = 0;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library.
|
||||
*/
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <sqlite3.h>
|
||||
#include <tcl.h>
|
||||
|
||||
/* Solely for the UNUSED_PARAMETER() macro. */
|
||||
|
||||
+2
-4
@@ -365,10 +365,8 @@ static void sqllogOpenlog(struct SLConn *p){
|
||||
FILE *fd;
|
||||
char *zVar = getenv(ENVIRONMENT_VARIABLE1_NAME);
|
||||
if( zVar==0 || strlen(zVar)+10>=(sizeof(sqllogglobal.zPrefix)) ) return;
|
||||
sqlite3_snprintf(sizeof(sqllogglobal.zPrefix), sqllogglobal.zPrefix,
|
||||
"%s/sqllog_%d", zVar, getProcessId());
|
||||
sqlite3_snprintf(sizeof(sqllogglobal.zIdx), sqllogglobal.zIdx,
|
||||
"%s.idx", sqllogglobal.zPrefix);
|
||||
sprintf(sqllogglobal.zPrefix, "%s/sqllog_%d", zVar, getProcessId());
|
||||
sprintf(sqllogglobal.zIdx, "%s.idx", sqllogglobal.zPrefix);
|
||||
if( getenv(ENVIRONMENT_VARIABLE2_NAME) ){
|
||||
sqllogglobal.bReuse = atoi(getenv(ENVIRONMENT_VARIABLE2_NAME));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user