Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 653b4f6078 | |||
| b67fd17b5f | |||
| e4b1eb90b7 | |||
| 5bc4851d00 | |||
| 77f136a4a4 | |||
| 4195437504 | |||
| 75d1119500 | |||
| ca446b3ccd | |||
| d4c1fdafd3 | |||
| 30b281b5dc | |||
| 579e80cd2f | |||
| 8f25fe573b | |||
| aaec593fbc | |||
| ccc6551307 | |||
| 25f801305a | |||
| 01191f66f5 |
+19
-45
@@ -22,7 +22,7 @@ TOP = @abs_srcdir@
|
||||
#
|
||||
BCC = @BUILD_CC@ @BUILD_CFLAGS@
|
||||
|
||||
# TCC is the C Compile and options for use in building executables that
|
||||
# TCC is the 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
|
||||
@@ -35,7 +35,7 @@ TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
|
||||
|
||||
# Define this for the autoconf-based build, so that the code knows it can
|
||||
# include the generated config.h
|
||||
#
|
||||
#
|
||||
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
|
||||
|
||||
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
||||
@@ -66,7 +66,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
|
||||
TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
|
||||
|
||||
# Any target libraries which libsqlite must be linked against
|
||||
#
|
||||
#
|
||||
TLIBS = @LIBS@ $(LIBS)
|
||||
|
||||
# Flags controlling use of the in memory btree implementation
|
||||
@@ -78,8 +78,8 @@ TLIBS = @LIBS@ $(LIBS)
|
||||
TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@
|
||||
|
||||
# Enable/disable loadable extensions, and other optional features
|
||||
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
|
||||
# The same set of OMIT and ENABLE flags should be passed to the
|
||||
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
|
||||
# The same set of OMIT and ENABLE flags should be passed to the
|
||||
# LEMON parser generator and the mkkeywordhash tool as well.
|
||||
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
|
||||
|
||||
@@ -126,8 +126,8 @@ SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
|
||||
# If gcov support was enabled by the configure script, add the appropriate
|
||||
# flags here. It's not always as easy as just having the user add the right
|
||||
# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which
|
||||
# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.
|
||||
# Supposedly GCC does the right thing if you use --coverage, but in
|
||||
# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.
|
||||
# Supposedly GCC does the right thing if you use --coverage, but in
|
||||
# practice it still fails. See:
|
||||
#
|
||||
# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html
|
||||
@@ -425,7 +425,7 @@ TESTSRC = \
|
||||
$(TOP)/ext/fts3/fts3_term.c \
|
||||
$(TOP)/ext/fts3/fts3_test.c \
|
||||
$(TOP)/ext/session/test_session.c \
|
||||
$(TOP)/ext/rbu/test_rbu.c
|
||||
$(TOP)/ext/rbu/test_rbu.c
|
||||
|
||||
# Statically linked extensions
|
||||
#
|
||||
@@ -437,7 +437,6 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/csv.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
$(TOP)/ext/misc/explain.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/fuzzer.c \
|
||||
$(TOP)/ext/fts5/fts5_tcl.c \
|
||||
@@ -507,7 +506,7 @@ TESTSRC2 = \
|
||||
$(TOP)/ext/fts3/fts3_write.c \
|
||||
$(TOP)/ext/async/sqlite3async.c \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/misc/stmt.c
|
||||
$(TOP)/ext/misc/stmt.c
|
||||
|
||||
# Header files used by all library source files.
|
||||
#
|
||||
@@ -579,8 +578,7 @@ FUZZDATA = \
|
||||
$(TOP)/test/fuzzdata3.db \
|
||||
$(TOP)/test/fuzzdata4.db \
|
||||
$(TOP)/test/fuzzdata5.db \
|
||||
$(TOP)/test/fuzzdata6.db \
|
||||
$(TOP)/test/fuzzdata7.db
|
||||
$(TOP)/test/fuzzdata6.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
@@ -597,14 +595,13 @@ SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
|
||||
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
|
||||
DBFUZZ_OPT =
|
||||
DBFUZZ_OPT =
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
@@ -666,22 +663,6 @@ sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
|
||||
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
DBFUZZ2_OPTS = \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_ENABLE_DESERIALIZE \
|
||||
-DSQLITE_DEBUG \
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB \
|
||||
-DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_ENABLE_FTS4 \
|
||||
-DSQLITE_EANBLE_FTS5
|
||||
|
||||
dbfuzz2: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
|
||||
clang-6.0 -I. -g -O0 -fsanitize=fuzzer,undefined -o dbfuzz2 \
|
||||
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c
|
||||
mkdir -p dbfuzz2-dir
|
||||
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
|
||||
|
||||
mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
@@ -1145,7 +1126,7 @@ FTS5_SRC = \
|
||||
$(TOP)/ext/fts5/fts5_varint.c \
|
||||
$(TOP)/ext/fts5/fts5_vocab.c \
|
||||
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||
cp $(TOP)/ext/fts5/fts5parse.y .
|
||||
rm -f fts5parse.h
|
||||
./lemon$(BEXE) $(OPTS) fts5parse.y
|
||||
@@ -1172,7 +1153,7 @@ sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
|
||||
#
|
||||
TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
||||
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||
TESTFIXTURE_FLAGS += -DBUILD_sqlite
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
@@ -1188,10 +1169,6 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
|
||||
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
||||
|
||||
coretestprogs: $(TESTPROGS)
|
||||
|
||||
testprogs: coretestprogs srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE)
|
||||
|
||||
# A very detailed test running most or all test cases
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS)
|
||||
@@ -1251,7 +1228,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $
|
||||
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
||||
$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
|
||||
|
||||
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
|
||||
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
|
||||
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
|
||||
|
||||
sqltclsh$(TEXE): sqltclsh.c
|
||||
@@ -1298,9 +1275,6 @@ showshm$(TEXE): $(TOP)/tool/showshm.c
|
||||
changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS)
|
||||
|
||||
changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS)
|
||||
|
||||
rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS)
|
||||
|
||||
@@ -1321,7 +1295,7 @@ KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
|
||||
$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)
|
||||
|
||||
loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
|
||||
@@ -1349,7 +1323,7 @@ snapshot-tarball: sqlite3.c
|
||||
# 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 \
|
||||
@@ -1363,7 +1337,7 @@ threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
|
||||
threadtest: threadtest3$(TEXE)
|
||||
./threadtest3$(TEXE)
|
||||
|
||||
releasetest:
|
||||
releasetest:
|
||||
$(TCLSH_CMD) $(TOP)/test/releasetest.tcl
|
||||
|
||||
# Standard install and cleanup targets
|
||||
@@ -1371,7 +1345,7 @@ releasetest:
|
||||
lib_install: libsqlite3.la
|
||||
$(INSTALL) -d $(DESTDIR)$(libdir)
|
||||
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
|
||||
|
||||
|
||||
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
|
||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
|
||||
@@ -1389,7 +1363,7 @@ tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl
|
||||
rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
|
||||
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
|
||||
|
||||
clean:
|
||||
clean:
|
||||
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
|
||||
rm -f sqlite3.h opcodes.*
|
||||
rm -rf .libs .deps
|
||||
|
||||
+1
-13
@@ -1515,7 +1515,6 @@ TESTEXT = \
|
||||
$(TOP)\ext\misc\closure.c \
|
||||
$(TOP)\ext\misc\csv.c \
|
||||
$(TOP)\ext\misc\eval.c \
|
||||
$(TOP)\ext\misc\explain.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\fuzzer.c \
|
||||
$(TOP)\ext\fts5\fts5_tcl.c \
|
||||
@@ -1623,8 +1622,7 @@ FUZZDATA = \
|
||||
$(TOP)\test\fuzzdata3.db \
|
||||
$(TOP)\test\fuzzdata4.db \
|
||||
$(TOP)\test\fuzzdata5.db \
|
||||
$(TOP)\test\fuzzdata6.db \
|
||||
$(TOP)\test\fuzzdata7.db
|
||||
$(TOP)\test\fuzzdata6.db
|
||||
# <</mark>>
|
||||
|
||||
# Additional compiler options for the shell. These are only effective
|
||||
@@ -1634,7 +1632,6 @@ FUZZDATA = \
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
@@ -2337,10 +2334,6 @@ extensiontest: testfixture.exe testloadext.dll
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
|
||||
|
||||
coretestprogs: $(TESTPROGS)
|
||||
|
||||
testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe
|
||||
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
|
||||
@@ -2448,11 +2441,6 @@ changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
|
||||
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
|
||||
$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
changesetfuzz.exe: $(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
|
||||
$(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.25.2.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.26.0'
|
||||
PACKAGE_STRING='sqlite 3.26.0'
|
||||
PACKAGE_VERSION='3.25.2'
|
||||
PACKAGE_STRING='sqlite 3.25.2'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1466,7 +1466,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.26.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.25.2 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1531,7 +1531,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.26.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.25.2:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1657,7 +1657,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.26.0
|
||||
sqlite configure 3.25.2
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2076,7 +2076,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.26.0, which was
|
||||
It was created by sqlite $as_me 3.25.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -12232,7 +12232,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.26.0, which was
|
||||
This file was extended by sqlite $as_me 3.25.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12298,7 +12298,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.26.0
|
||||
sqlite config.status 3.25.2
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+5
-5
@@ -1821,7 +1821,7 @@ static int fts3ScanInteriorNode(
|
||||
const char *zCsr = zNode; /* Cursor to iterate through node */
|
||||
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
|
||||
char *zBuffer = 0; /* Buffer to load terms into */
|
||||
i64 nAlloc = 0; /* Size of allocated buffer */
|
||||
int nAlloc = 0; /* Size of allocated buffer */
|
||||
int isFirstTerm = 1; /* True when processing first term on page */
|
||||
sqlite3_int64 iChild; /* Block id of child node to descend to */
|
||||
|
||||
@@ -1859,14 +1859,14 @@ static int fts3ScanInteriorNode(
|
||||
zCsr += fts3GetVarint32(zCsr, &nSuffix);
|
||||
|
||||
assert( nPrefix>=0 && nSuffix>=0 );
|
||||
if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
|
||||
if( &zCsr[nSuffix]>zEnd ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
goto finish_scan;
|
||||
}
|
||||
if( (i64)nPrefix+nSuffix>nAlloc ){
|
||||
if( nPrefix+nSuffix>nAlloc ){
|
||||
char *zNew;
|
||||
nAlloc = ((i64)nPrefix+nSuffix) * 2;
|
||||
zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
|
||||
nAlloc = (nPrefix+nSuffix) * 2;
|
||||
zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
|
||||
if( !zNew ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto finish_scan;
|
||||
|
||||
+7
-16
@@ -1374,19 +1374,15 @@ static int fts3SegReaderNext(
|
||||
** safe (no risk of overread) even if the node data is corrupted. */
|
||||
pNext += fts3GetVarint32(pNext, &nPrefix);
|
||||
pNext += fts3GetVarint32(pNext, &nSuffix);
|
||||
if( nSuffix<=0
|
||||
|| (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
|
||||
|| nPrefix>pReader->nTermAlloc
|
||||
if( nPrefix<0 || nSuffix<=0
|
||||
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
|
||||
){
|
||||
return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
|
||||
/* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
|
||||
** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
|
||||
** overflow - hence the (i64) casts. */
|
||||
if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
|
||||
i64 nNew = ((i64)nPrefix+nSuffix)*2;
|
||||
char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
|
||||
if( nPrefix+nSuffix>pReader->nTermAlloc ){
|
||||
int nNew = (nPrefix+nSuffix)*2;
|
||||
char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
|
||||
if( !zNew ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -1408,7 +1404,7 @@ static int fts3SegReaderNext(
|
||||
** b-tree node. And that the final byte of the doclist is 0x00. If either
|
||||
** of these statements is untrue, then the data structure is corrupt.
|
||||
*/
|
||||
if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
|
||||
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
|
||||
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
|
||||
){
|
||||
return FTS_CORRUPT_VTAB;
|
||||
@@ -3734,9 +3730,6 @@ static int nodeReaderNext(NodeReader *p){
|
||||
}
|
||||
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
|
||||
|
||||
if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
|
||||
return SQLITE_CORRUPT_VTAB;
|
||||
}
|
||||
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
|
||||
@@ -3744,9 +3737,6 @@ static int nodeReaderNext(NodeReader *p){
|
||||
p->iOff += nSuffix;
|
||||
if( p->iChild==0 ){
|
||||
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
|
||||
if( (p->nNode-p->iOff)<p->nDoclist ){
|
||||
return SQLITE_CORRUPT_VTAB;
|
||||
}
|
||||
p->aDoclist = &p->aNode[p->iOff];
|
||||
p->iOff += p->nDoclist;
|
||||
}
|
||||
@@ -3754,6 +3744,7 @@ static int nodeReaderNext(NodeReader *p){
|
||||
}
|
||||
|
||||
assert( p->iOff<=p->nNode );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
** 2018-09-16
|
||||
**
|
||||
** 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 demonstrates an eponymous virtual table that returns the
|
||||
** EXPLAIN output from an SQL statement.
|
||||
**
|
||||
** Usage example:
|
||||
**
|
||||
** .load ./explain
|
||||
** SELECT p2 FROM explain('SELECT * FROM sqlite_master')
|
||||
** WHERE opcode='OpenRead';
|
||||
*/
|
||||
#if !defined(SQLITEINT_H)
|
||||
#include "sqlite3ext.h"
|
||||
#endif
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/* explain_vtab is a subclass of sqlite3_vtab which will
|
||||
** serve as the underlying representation of a explain virtual table
|
||||
*/
|
||||
typedef struct explain_vtab explain_vtab;
|
||||
struct explain_vtab {
|
||||
sqlite3_vtab base; /* Base class - must be first */
|
||||
sqlite3 *db; /* Database connection for this explain vtab */
|
||||
};
|
||||
|
||||
/* explain_cursor is a subclass of sqlite3_vtab_cursor which will
|
||||
** serve as the underlying representation of a cursor that scans
|
||||
** over rows of the result from an EXPLAIN operation.
|
||||
*/
|
||||
typedef struct explain_cursor explain_cursor;
|
||||
struct explain_cursor {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
sqlite3 *db; /* Database connection for this cursor */
|
||||
char *zSql; /* Value for the EXPLN_COLUMN_SQL column */
|
||||
sqlite3_stmt *pExplain; /* Statement being explained */
|
||||
int rc; /* Result of last sqlite3_step() on pExplain */
|
||||
};
|
||||
|
||||
/*
|
||||
** The explainConnect() method is invoked to create a new
|
||||
** explain_vtab that describes the explain virtual table.
|
||||
**
|
||||
** Think of this routine as the constructor for explain_vtab objects.
|
||||
**
|
||||
** All this routine needs to do is:
|
||||
**
|
||||
** (1) Allocate the explain_vtab object and initialize all fields.
|
||||
**
|
||||
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
|
||||
** result set of queries against explain will look like.
|
||||
*/
|
||||
static int explainConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc, const char *const*argv,
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
explain_vtab *pNew;
|
||||
int rc;
|
||||
|
||||
/* Column numbers */
|
||||
#define EXPLN_COLUMN_ADDR 0 /* Instruction address */
|
||||
#define EXPLN_COLUMN_OPCODE 1 /* Opcode */
|
||||
#define EXPLN_COLUMN_P1 2 /* Operand 1 */
|
||||
#define EXPLN_COLUMN_P2 3 /* Operand 2 */
|
||||
#define EXPLN_COLUMN_P3 4 /* Operand 3 */
|
||||
#define EXPLN_COLUMN_P4 5 /* Operand 4 */
|
||||
#define EXPLN_COLUMN_P5 6 /* Operand 5 */
|
||||
#define EXPLN_COLUMN_COMMENT 7 /* Comment */
|
||||
#define EXPLN_COLUMN_SQL 8 /* SQL that is being explained */
|
||||
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(addr,opcode,p1,p2,p3,p4,p5,comment,sql HIDDEN)");
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) );
|
||||
*ppVtab = (sqlite3_vtab*)pNew;
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
pNew->db = db;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is the destructor for explain_cursor objects.
|
||||
*/
|
||||
static int explainDisconnect(sqlite3_vtab *pVtab){
|
||||
sqlite3_free(pVtab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Constructor for a new explain_cursor object.
|
||||
*/
|
||||
static int explainOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||
explain_cursor *pCur;
|
||||
pCur = sqlite3_malloc( sizeof(*pCur) );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, sizeof(*pCur));
|
||||
pCur->db = ((explain_vtab*)p)->db;
|
||||
*ppCursor = &pCur->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destructor for a explain_cursor.
|
||||
*/
|
||||
static int explainClose(sqlite3_vtab_cursor *cur){
|
||||
explain_cursor *pCur = (explain_cursor*)cur;
|
||||
sqlite3_finalize(pCur->pExplain);
|
||||
sqlite3_free(pCur->zSql);
|
||||
sqlite3_free(pCur);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Advance a explain_cursor to its next row of output.
|
||||
*/
|
||||
static int explainNext(sqlite3_vtab_cursor *cur){
|
||||
explain_cursor *pCur = (explain_cursor*)cur;
|
||||
pCur->rc = sqlite3_step(pCur->pExplain);
|
||||
if( pCur->rc!=SQLITE_DONE && pCur->rc!=SQLITE_ROW ) return pCur->rc;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return values of columns for the row at which the explain_cursor
|
||||
** is currently pointing.
|
||||
*/
|
||||
static int explainColumn(
|
||||
sqlite3_vtab_cursor *cur, /* The cursor */
|
||||
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
|
||||
int i /* Which column to return */
|
||||
){
|
||||
explain_cursor *pCur = (explain_cursor*)cur;
|
||||
if( i==EXPLN_COLUMN_SQL ){
|
||||
sqlite3_result_text(ctx, pCur->zSql, -1, SQLITE_TRANSIENT);
|
||||
}else{
|
||||
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pExplain, i));
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the rowid for the current row. In this implementation, the
|
||||
** rowid is the same as the output value.
|
||||
*/
|
||||
static int explainRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
explain_cursor *pCur = (explain_cursor*)cur;
|
||||
*pRowid = sqlite3_column_int64(pCur->pExplain, 0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the cursor has been moved off of the last
|
||||
** row of output.
|
||||
*/
|
||||
static int explainEof(sqlite3_vtab_cursor *cur){
|
||||
explain_cursor *pCur = (explain_cursor*)cur;
|
||||
return pCur->rc!=SQLITE_ROW;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is called to "rewind" the explain_cursor object back
|
||||
** to the first row of output. This method is always called at least
|
||||
** once prior to any call to explainColumn() or explainRowid() or
|
||||
** explainEof().
|
||||
**
|
||||
** The argv[0] is the SQL statement that is to be explained.
|
||||
*/
|
||||
static int explainFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
explain_cursor *pCur = (explain_cursor *)pVtabCursor;
|
||||
char *zSql = 0;
|
||||
int rc;
|
||||
sqlite3_finalize(pCur->pExplain);
|
||||
pCur->pExplain = 0;
|
||||
if( sqlite3_value_type(argv[0])!=SQLITE_TEXT ){
|
||||
pCur->rc = SQLITE_DONE;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
sqlite3_free(pCur->zSql);
|
||||
pCur->zSql = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
|
||||
if( pCur->zSql ){
|
||||
zSql = sqlite3_mprintf("EXPLAIN %s", pCur->zSql);
|
||||
}
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pExplain, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( rc ){
|
||||
sqlite3_finalize(pCur->pExplain);
|
||||
pCur->pExplain = 0;
|
||||
sqlite3_free(pCur->zSql);
|
||||
pCur->zSql = 0;
|
||||
}else{
|
||||
pCur->rc = sqlite3_step(pCur->pExplain);
|
||||
rc = (pCur->rc==SQLITE_DONE || pCur->rc==SQLITE_ROW) ? SQLITE_OK : pCur->rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** SQLite will invoke this method one or more times while planning a query
|
||||
** that uses the explain virtual table. This routine needs to create
|
||||
** a query plan for each invocation and compute an estimated cost for that
|
||||
** plan.
|
||||
*/
|
||||
static int explainBestIndex(
|
||||
sqlite3_vtab *tab,
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
int i;
|
||||
|
||||
pIdxInfo->estimatedCost = (double)1000000;
|
||||
pIdxInfo->estimatedRows = 500;
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
|
||||
if( p->usable
|
||||
&& p->iColumn==EXPLN_COLUMN_SQL
|
||||
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ
|
||||
){
|
||||
pIdxInfo->estimatedCost = 10.0;
|
||||
pIdxInfo->idxNum = 1;
|
||||
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
|
||||
pIdxInfo->aConstraintUsage[i].omit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This following structure defines all the methods for the
|
||||
** explain virtual table.
|
||||
*/
|
||||
static sqlite3_module explainModule = {
|
||||
0, /* iVersion */
|
||||
0, /* xCreate */
|
||||
explainConnect, /* xConnect */
|
||||
explainBestIndex, /* xBestIndex */
|
||||
explainDisconnect, /* xDisconnect */
|
||||
0, /* xDestroy */
|
||||
explainOpen, /* xOpen - open a cursor */
|
||||
explainClose, /* xClose - close a cursor */
|
||||
explainFilter, /* xFilter - configure scan constraints */
|
||||
explainNext, /* xNext - advance a cursor */
|
||||
explainEof, /* xEof - check for end of scan */
|
||||
explainColumn, /* xColumn - read data */
|
||||
explainRowid, /* xRowid - read data */
|
||||
0, /* xUpdate */
|
||||
0, /* xBegin */
|
||||
0, /* xSync */
|
||||
0, /* xCommit */
|
||||
0, /* xRollback */
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
};
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
int sqlite3ExplainVtabInit(sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
rc = sqlite3_create_module(db, "explain", &explainModule, 0);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_explain_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
rc = sqlite3ExplainVtabInit(db);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
@@ -1,427 +0,0 @@
|
||||
/*
|
||||
** 2018-09-27
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This file demonstrates an eponymous virtual table that returns information
|
||||
** from sqlite3_status64() and sqlite3_db_status().
|
||||
**
|
||||
** Usage example:
|
||||
**
|
||||
** .load ./memstat
|
||||
** .mode quote
|
||||
** .header on
|
||||
** SELECT * FROM memstat;
|
||||
*/
|
||||
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB)
|
||||
#if !defined(SQLITEINT_H)
|
||||
#include "sqlite3ext.h"
|
||||
#endif
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/* memstat_vtab is a subclass of sqlite3_vtab which will
|
||||
** serve as the underlying representation of a memstat virtual table
|
||||
*/
|
||||
typedef struct memstat_vtab memstat_vtab;
|
||||
struct memstat_vtab {
|
||||
sqlite3_vtab base; /* Base class - must be first */
|
||||
sqlite3 *db; /* Database connection for this memstat vtab */
|
||||
};
|
||||
|
||||
/* memstat_cursor is a subclass of sqlite3_vtab_cursor which will
|
||||
** serve as the underlying representation of a cursor that scans
|
||||
** over rows of the result
|
||||
*/
|
||||
typedef struct memstat_cursor memstat_cursor;
|
||||
struct memstat_cursor {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
sqlite3 *db; /* Database connection for this cursor */
|
||||
int iRowid; /* Current row in aMemstatColumn[] */
|
||||
int iDb; /* Which schema we are looking at */
|
||||
int nDb; /* Number of schemas */
|
||||
char **azDb; /* Names of all schemas */
|
||||
sqlite3_int64 aVal[2]; /* Result values */
|
||||
};
|
||||
|
||||
/*
|
||||
** The memstatConnect() method is invoked to create a new
|
||||
** memstat_vtab that describes the memstat virtual table.
|
||||
**
|
||||
** Think of this routine as the constructor for memstat_vtab objects.
|
||||
**
|
||||
** All this routine needs to do is:
|
||||
**
|
||||
** (1) Allocate the memstat_vtab object and initialize all fields.
|
||||
**
|
||||
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
|
||||
** result set of queries against memstat will look like.
|
||||
*/
|
||||
static int memstatConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc, const char *const*argv,
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
memstat_vtab *pNew;
|
||||
int rc;
|
||||
|
||||
/* Column numbers */
|
||||
#define MSV_COLUMN_NAME 0 /* Name of quantity being measured */
|
||||
#define MSV_COLUMN_SCHEMA 1 /* schema name */
|
||||
#define MSV_COLUMN_VALUE 2 /* Current value */
|
||||
#define MSV_COLUMN_HIWTR 3 /* Highwater mark */
|
||||
|
||||
rc = sqlite3_declare_vtab(db,"CREATE TABLE x(name,schema,value,hiwtr)");
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) );
|
||||
*ppVtab = (sqlite3_vtab*)pNew;
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
pNew->db = db;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is the destructor for memstat_cursor objects.
|
||||
*/
|
||||
static int memstatDisconnect(sqlite3_vtab *pVtab){
|
||||
sqlite3_free(pVtab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Constructor for a new memstat_cursor object.
|
||||
*/
|
||||
static int memstatOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||
memstat_cursor *pCur;
|
||||
pCur = sqlite3_malloc( sizeof(*pCur) );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, sizeof(*pCur));
|
||||
pCur->db = ((memstat_vtab*)p)->db;
|
||||
*ppCursor = &pCur->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Clear all the schema names from a cursor
|
||||
*/
|
||||
static void memstatClearSchema(memstat_cursor *pCur){
|
||||
int i;
|
||||
if( pCur->azDb==0 ) return;
|
||||
for(i=0; i<pCur->nDb; i++){
|
||||
sqlite3_free(pCur->azDb[i]);
|
||||
}
|
||||
sqlite3_free(pCur->azDb);
|
||||
pCur->azDb = 0;
|
||||
pCur->nDb = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Fill in the azDb[] array for the cursor.
|
||||
*/
|
||||
static int memstatFindSchemas(memstat_cursor *pCur){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int rc;
|
||||
if( pCur->nDb ) return SQLITE_OK;
|
||||
rc = sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pStmt, 0);
|
||||
if( rc ){
|
||||
sqlite3_finalize(pStmt);
|
||||
return rc;
|
||||
}
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
char **az, *z;
|
||||
az = sqlite3_realloc(pCur->azDb, sizeof(char*)*(pCur->nDb+1));
|
||||
if( az==0 ){
|
||||
memstatClearSchema(pCur);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pCur->azDb = az;
|
||||
z = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
|
||||
if( z==0 ){
|
||||
memstatClearSchema(pCur);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pCur->azDb[pCur->nDb] = z;
|
||||
pCur->nDb++;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Destructor for a memstat_cursor.
|
||||
*/
|
||||
static int memstatClose(sqlite3_vtab_cursor *cur){
|
||||
memstat_cursor *pCur = (memstat_cursor*)cur;
|
||||
memstatClearSchema(pCur);
|
||||
sqlite3_free(cur);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Allowed values for aMemstatColumn[].eType
|
||||
*/
|
||||
#define MSV_GSTAT 0 /* sqlite3_status64() information */
|
||||
#define MSV_DB 1 /* sqlite3_db_status() information */
|
||||
#define MSV_ZIPVFS 2 /* ZIPVFS file-control with 64-bit return */
|
||||
|
||||
/*
|
||||
** An array of quantities that can be measured and reported by
|
||||
** this virtual table
|
||||
*/
|
||||
static const struct MemstatColumns {
|
||||
const char *zName; /* Symbolic name */
|
||||
unsigned char eType; /* Type of interface */
|
||||
unsigned char mNull; /* Bitmask of which columns are NULL */
|
||||
/* 2: dbname, 4: current, 8: hiwtr */
|
||||
int eOp; /* Opcode */
|
||||
} aMemstatColumn[] = {
|
||||
{"MEMORY_USED", MSV_GSTAT, 2, SQLITE_STATUS_MEMORY_USED },
|
||||
{"MALLOC_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_MALLOC_SIZE },
|
||||
{"MALLOC_COUNT", MSV_GSTAT, 2, SQLITE_STATUS_MALLOC_COUNT },
|
||||
{"PAGECACHE_USED", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_USED },
|
||||
{"PAGECACHE_OVERFLOW", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_OVERFLOW },
|
||||
{"PAGECACHE_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_PAGECACHE_SIZE },
|
||||
{"PARSER_STACK", MSV_GSTAT, 6, SQLITE_STATUS_PARSER_STACK },
|
||||
{"DB_LOOKASIDE_USED", MSV_DB, 2, SQLITE_DBSTATUS_LOOKASIDE_USED },
|
||||
{"DB_LOOKASIDE_HIT", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_HIT },
|
||||
{"DB_LOOKASIDE_MISS_SIZE", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE},
|
||||
{"DB_LOOKASIDE_MISS_FULL", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL},
|
||||
{"DB_CACHE_USED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED },
|
||||
#if SQLITE_VERSION_NUMBER >= 3140000
|
||||
{"DB_CACHE_USED_SHARED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED_SHARED },
|
||||
#endif
|
||||
{"DB_SCHEMA_USED", MSV_DB, 10, SQLITE_DBSTATUS_SCHEMA_USED },
|
||||
{"DB_STMT_USED", MSV_DB, 10, SQLITE_DBSTATUS_STMT_USED },
|
||||
{"DB_CACHE_HIT", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_HIT },
|
||||
{"DB_CACHE_MISS", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_MISS },
|
||||
{"DB_CACHE_WRITE", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_WRITE },
|
||||
#if SQLITE_VERSION_NUMBER >= 3230000
|
||||
{"DB_CACHE_SPILL", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_SPILL },
|
||||
#endif
|
||||
{"DB_DEFERRED_FKS", MSV_DB, 10, SQLITE_DBSTATUS_DEFERRED_FKS },
|
||||
#ifdef SQLITE_ENABLE_ZIPVFS
|
||||
{"ZIPVFS_CACHE_USED", MSV_ZIPVFS, 8, 231454 },
|
||||
{"ZIPVFS_CACHE_HIT", MSV_ZIPVFS, 8, 231455 },
|
||||
{"ZIPVFS_CACHE_MISS", MSV_ZIPVFS, 8, 231456 },
|
||||
{"ZIPVFS_CACHE_WRITE", MSV_ZIPVFS, 8, 231457 },
|
||||
{"ZIPVFS_DIRECT_READ", MSV_ZIPVFS, 8, 231458 },
|
||||
{"ZIPVFS_DIRECT_BYTES", MSV_ZIPVFS, 8, 231459 },
|
||||
#endif /* SQLITE_ENABLE_ZIPVFS */
|
||||
};
|
||||
#define MSV_NROW (sizeof(aMemstatColumn)/sizeof(aMemstatColumn[0]))
|
||||
|
||||
/*
|
||||
** Advance a memstat_cursor to its next row of output.
|
||||
*/
|
||||
static int memstatNext(sqlite3_vtab_cursor *cur){
|
||||
memstat_cursor *pCur = (memstat_cursor*)cur;
|
||||
int i;
|
||||
assert( pCur->iRowid<=MSV_NROW );
|
||||
while(1){
|
||||
i = (int)pCur->iRowid - 1;
|
||||
if( i<0 || (aMemstatColumn[i].mNull & 2)!=0 || (++pCur->iDb)>=pCur->nDb ){
|
||||
pCur->iRowid++;
|
||||
if( pCur->iRowid>MSV_NROW ) return SQLITE_OK; /* End of the table */
|
||||
pCur->iDb = 0;
|
||||
i++;
|
||||
}
|
||||
pCur->aVal[0] = 0;
|
||||
pCur->aVal[1] = 0;
|
||||
switch( aMemstatColumn[i].eType ){
|
||||
case MSV_GSTAT: {
|
||||
if( sqlite3_libversion_number()>=3010000 ){
|
||||
sqlite3_status64(aMemstatColumn[i].eOp,
|
||||
&pCur->aVal[0], &pCur->aVal[1],0);
|
||||
}else{
|
||||
int xCur, xHiwtr;
|
||||
sqlite3_status(aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0);
|
||||
pCur->aVal[0] = xCur;
|
||||
pCur->aVal[1] = xHiwtr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSV_DB: {
|
||||
int xCur, xHiwtr;
|
||||
sqlite3_db_status(pCur->db, aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0);
|
||||
pCur->aVal[0] = xCur;
|
||||
pCur->aVal[1] = xHiwtr;
|
||||
break;
|
||||
}
|
||||
case MSV_ZIPVFS: {
|
||||
int rc;
|
||||
rc = sqlite3_file_control(pCur->db, pCur->azDb[pCur->iDb],
|
||||
aMemstatColumn[i].eOp, (void*)&pCur->aVal[0]);
|
||||
if( rc!=SQLITE_OK ) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Return values of columns for the row at which the memstat_cursor
|
||||
** is currently pointing.
|
||||
*/
|
||||
static int memstatColumn(
|
||||
sqlite3_vtab_cursor *cur, /* The cursor */
|
||||
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
|
||||
int iCol /* Which column to return */
|
||||
){
|
||||
memstat_cursor *pCur = (memstat_cursor*)cur;
|
||||
int i;
|
||||
assert( pCur->iRowid>0 && pCur->iRowid<=MSV_NROW );
|
||||
i = (int)pCur->iRowid - 1;
|
||||
if( (aMemstatColumn[i].mNull & (1<<iCol))!=0 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
switch( iCol ){
|
||||
case MSV_COLUMN_NAME: {
|
||||
sqlite3_result_text(ctx, aMemstatColumn[i].zName, -1, SQLITE_STATIC);
|
||||
break;
|
||||
}
|
||||
case MSV_COLUMN_SCHEMA: {
|
||||
sqlite3_result_text(ctx, pCur->azDb[pCur->iDb], -1, 0);
|
||||
break;
|
||||
}
|
||||
case MSV_COLUMN_VALUE: {
|
||||
sqlite3_result_int64(ctx, pCur->aVal[0]);
|
||||
break;
|
||||
}
|
||||
case MSV_COLUMN_HIWTR: {
|
||||
sqlite3_result_int64(ctx, pCur->aVal[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the rowid for the current row. In this implementation, the
|
||||
** rowid is the same as the output value.
|
||||
*/
|
||||
static int memstatRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
memstat_cursor *pCur = (memstat_cursor*)cur;
|
||||
*pRowid = pCur->iRowid*1000 + pCur->iDb;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the cursor has been moved off of the last
|
||||
** row of output.
|
||||
*/
|
||||
static int memstatEof(sqlite3_vtab_cursor *cur){
|
||||
memstat_cursor *pCur = (memstat_cursor*)cur;
|
||||
return pCur->iRowid>MSV_NROW;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is called to "rewind" the memstat_cursor object back
|
||||
** to the first row of output. This method is always called at least
|
||||
** once prior to any call to memstatColumn() or memstatRowid() or
|
||||
** memstatEof().
|
||||
*/
|
||||
static int memstatFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
memstat_cursor *pCur = (memstat_cursor *)pVtabCursor;
|
||||
int rc = memstatFindSchemas(pCur);
|
||||
if( rc ) return rc;
|
||||
pCur->iRowid = 0;
|
||||
pCur->iDb = 0;
|
||||
return memstatNext(pVtabCursor);
|
||||
}
|
||||
|
||||
/*
|
||||
** SQLite will invoke this method one or more times while planning a query
|
||||
** that uses the memstat virtual table. This routine needs to create
|
||||
** a query plan for each invocation and compute an estimated cost for that
|
||||
** plan.
|
||||
*/
|
||||
static int memstatBestIndex(
|
||||
sqlite3_vtab *tab,
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
pIdxInfo->estimatedCost = (double)500;
|
||||
pIdxInfo->estimatedRows = 500;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This following structure defines all the methods for the
|
||||
** memstat virtual table.
|
||||
*/
|
||||
static sqlite3_module memstatModule = {
|
||||
0, /* iVersion */
|
||||
0, /* xCreate */
|
||||
memstatConnect, /* xConnect */
|
||||
memstatBestIndex, /* xBestIndex */
|
||||
memstatDisconnect, /* xDisconnect */
|
||||
0, /* xDestroy */
|
||||
memstatOpen, /* xOpen - open a cursor */
|
||||
memstatClose, /* xClose - close a cursor */
|
||||
memstatFilter, /* xFilter - configure scan constraints */
|
||||
memstatNext, /* xNext - advance a cursor */
|
||||
memstatEof, /* xEof - check for end of scan */
|
||||
memstatColumn, /* xColumn - read data */
|
||||
memstatRowid, /* xRowid - read data */
|
||||
0, /* xUpdate */
|
||||
0, /* xBegin */
|
||||
0, /* xSync */
|
||||
0, /* xCommit */
|
||||
0, /* xRollback */
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
};
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
int sqlite3MemstatVtabInit(sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
rc = sqlite3_create_module(db, "sqlite_memstat", &memstatModule, 0);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_CORE
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_memstat_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
rc = sqlite3MemstatVtabInit(db);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_CORE */
|
||||
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB) */
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This SQLite extension implements functions that compute SHA1 hashes.
|
||||
** This SQLite extension implements a functions that compute SHA1 hashes.
|
||||
** Two SQL functions are implemented:
|
||||
**
|
||||
** sha1(X)
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This SQLite extension implements functions that compute SHA3 hashes.
|
||||
** This SQLite extension implements a functions that compute SHA1 hashes.
|
||||
** Two SQL functions are implemented:
|
||||
**
|
||||
** sha3(X,SIZE)
|
||||
|
||||
@@ -1295,9 +1295,6 @@ typedef struct Transliteration Transliteration;
|
||||
struct Transliteration {
|
||||
unsigned short int cFrom;
|
||||
unsigned char cTo0, cTo1, cTo2, cTo3;
|
||||
#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS
|
||||
unsigned char cTo4;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1711,11 +1708,7 @@ static const Transliteration *spellfixFindTranslit(int c, int *pxTop){
|
||||
** should be freed by the caller.
|
||||
*/
|
||||
static unsigned char *transliterate(const unsigned char *zIn, int nIn){
|
||||
#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS
|
||||
unsigned char *zOut = sqlite3_malloc64( nIn*5 + 1 );
|
||||
#else
|
||||
unsigned char *zOut = sqlite3_malloc64( nIn*4 + 1 );
|
||||
#endif
|
||||
int c, sz, nOut;
|
||||
if( zOut==0 ) return 0;
|
||||
nOut = 0;
|
||||
@@ -1739,11 +1732,6 @@ static unsigned char *transliterate(const unsigned char *zIn, int nIn){
|
||||
zOut[nOut++] = tbl[x].cTo2;
|
||||
if( tbl[x].cTo3 ){
|
||||
zOut[nOut++] = tbl[x].cTo3;
|
||||
#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS
|
||||
if( tbl[x].cTo4 ){
|
||||
zOut[nOut++] = tbl[x].cTo4;
|
||||
}
|
||||
#endif /* SQLITE_SPELLFIX_5BYTE_MAPPINGS */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-74
@@ -405,8 +405,7 @@ struct rbu_vfs {
|
||||
sqlite3_vfs *pRealVfs; /* Underlying VFS */
|
||||
sqlite3_mutex *mutex; /* Mutex to protect pMain */
|
||||
sqlite3rbu *pRbu; /* Owner RBU object */
|
||||
rbu_file *pMain; /* List of main db files */
|
||||
rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
|
||||
rbu_file *pMain; /* Linked list of main db files */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -435,7 +434,6 @@ struct rbu_file {
|
||||
const char *zWal; /* Wal filename for this main db file */
|
||||
rbu_file *pWalFd; /* Wal file descriptor for this main db */
|
||||
rbu_file *pMainNext; /* Next MAIN_DB file */
|
||||
rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -4032,69 +4030,6 @@ static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add an item to the main-db lists, if it is not already present.
|
||||
**
|
||||
** There are two main-db lists. One for all file descriptors, and one
|
||||
** for all file descriptors with rbu_file.pDb!=0. If the argument has
|
||||
** rbu_file.pDb!=0, then it is assumed to already be present on the
|
||||
** main list and is only added to the pDb!=0 list.
|
||||
*/
|
||||
static void rbuMainlistAdd(rbu_file *p){
|
||||
rbu_vfs *pRbuVfs = p->pRbuVfs;
|
||||
rbu_file *pIter;
|
||||
assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
|
||||
sqlite3_mutex_enter(pRbuVfs->mutex);
|
||||
if( p->pRbu==0 ){
|
||||
for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
|
||||
p->pMainNext = pRbuVfs->pMain;
|
||||
pRbuVfs->pMain = p;
|
||||
}else{
|
||||
for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
|
||||
if( pIter==0 ){
|
||||
p->pMainRbuNext = pRbuVfs->pMainRbu;
|
||||
pRbuVfs->pMainRbu = p;
|
||||
}
|
||||
}
|
||||
sqlite3_mutex_leave(pRbuVfs->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
** Remove an item from the main-db lists.
|
||||
*/
|
||||
static void rbuMainlistRemove(rbu_file *p){
|
||||
rbu_file **pp;
|
||||
sqlite3_mutex_enter(p->pRbuVfs->mutex);
|
||||
for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
|
||||
if( *pp ) *pp = p->pMainNext;
|
||||
p->pMainNext = 0;
|
||||
for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
|
||||
if( *pp ) *pp = p->pMainRbuNext;
|
||||
p->pMainRbuNext = 0;
|
||||
sqlite3_mutex_leave(p->pRbuVfs->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
** Given that zWal points to a buffer containing a wal file name passed to
|
||||
** either the xOpen() or xAccess() VFS method, search the main-db list for
|
||||
** a file-handle opened by the same database connection on the corresponding
|
||||
** database file.
|
||||
**
|
||||
** If parameter bRbu is true, only search for file-descriptors with
|
||||
** rbu_file.pDb!=0.
|
||||
*/
|
||||
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
|
||||
rbu_file *pDb;
|
||||
sqlite3_mutex_enter(pRbuVfs->mutex);
|
||||
if( bRbu ){
|
||||
for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
|
||||
}else{
|
||||
for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
|
||||
}
|
||||
sqlite3_mutex_leave(pRbuVfs->mutex);
|
||||
return pDb;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close an rbu file.
|
||||
*/
|
||||
@@ -4112,14 +4047,17 @@ static int rbuVfsClose(sqlite3_file *pFile){
|
||||
sqlite3_free(p->zDel);
|
||||
|
||||
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
|
||||
rbuMainlistRemove(p);
|
||||
rbu_file **pp;
|
||||
sqlite3_mutex_enter(p->pRbuVfs->mutex);
|
||||
for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
|
||||
*pp = p->pMainNext;
|
||||
sqlite3_mutex_leave(p->pRbuVfs->mutex);
|
||||
rbuUnlockShm(p);
|
||||
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
|
||||
}
|
||||
else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
|
||||
rbuUpdateTempSize(p, 0);
|
||||
}
|
||||
assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
|
||||
|
||||
/* Close the underlying file handle */
|
||||
rc = p->pReal->pMethods->xClose(p->pReal);
|
||||
@@ -4378,9 +4316,6 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||
}else if( rc==SQLITE_NOTFOUND ){
|
||||
pRbu->pTargetFd = p;
|
||||
p->pRbu = pRbu;
|
||||
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
|
||||
rbuMainlistAdd(p);
|
||||
}
|
||||
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
@@ -4542,6 +4477,20 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Given that zWal points to a buffer containing a wal file name passed to
|
||||
** either the xOpen() or xAccess() VFS method, return a pointer to the
|
||||
** file-handle opened by the same database connection on the corresponding
|
||||
** database file.
|
||||
*/
|
||||
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
|
||||
rbu_file *pDb;
|
||||
sqlite3_mutex_enter(pRbuVfs->mutex);
|
||||
for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
|
||||
sqlite3_mutex_leave(pRbuVfs->mutex);
|
||||
return pDb;
|
||||
}
|
||||
|
||||
/*
|
||||
** A main database named zName has just been opened. The following
|
||||
** function returns a pointer to a buffer owned by SQLite that contains
|
||||
@@ -4620,7 +4569,7 @@ static int rbuVfsOpen(
|
||||
pFd->zWal = rbuMainToWal(zName, flags);
|
||||
}
|
||||
else if( flags & SQLITE_OPEN_WAL ){
|
||||
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
|
||||
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
|
||||
if( pDb ){
|
||||
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
|
||||
/* This call is to open a *-wal file. Intead, open the *-oal. This
|
||||
@@ -4672,7 +4621,10 @@ static int rbuVfsOpen(
|
||||
** mutex protected linked list of all such files. */
|
||||
pFile->pMethods = &rbuvfs_io_methods;
|
||||
if( flags & SQLITE_OPEN_MAIN_DB ){
|
||||
rbuMainlistAdd(pFd);
|
||||
sqlite3_mutex_enter(pRbuVfs->mutex);
|
||||
pFd->pMainNext = pRbuVfs->pMain;
|
||||
pRbuVfs->pMain = pFd;
|
||||
sqlite3_mutex_leave(pRbuVfs->mutex);
|
||||
}
|
||||
}else{
|
||||
sqlite3_free(pFd->zDel);
|
||||
@@ -4720,7 +4672,7 @@ static int rbuVfsAccess(
|
||||
** file opened instead.
|
||||
*/
|
||||
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
|
||||
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
|
||||
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
|
||||
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
|
||||
if( *pResOut ){
|
||||
rc = SQLITE_CANTOPEN;
|
||||
|
||||
+31
-168
@@ -106,24 +106,14 @@ typedef float GeoCoord;
|
||||
**
|
||||
** encoding (1 byte) 0=big-endian, 1=little-endian
|
||||
** nvertex (3 bytes) Number of vertexes as a big-endian integer
|
||||
**
|
||||
** Enough space is allocated for 4 coordinates, to work around over-zealous
|
||||
** warnings coming from some compiler (notably, clang). In reality, the size
|
||||
** of each GeoPoly memory allocate is adjusted as necessary so that the
|
||||
** GeoPoly.a[] array at the end is the appropriate size.
|
||||
*/
|
||||
typedef struct GeoPoly GeoPoly;
|
||||
struct GeoPoly {
|
||||
int nVertex; /* Number of vertexes */
|
||||
unsigned char hdr[4]; /* Header for on-disk representation */
|
||||
GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */
|
||||
GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */
|
||||
};
|
||||
|
||||
/* The size of a memory allocation needed for a GeoPoly object sufficient
|
||||
** to hold N coordinate pairs.
|
||||
*/
|
||||
#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
|
||||
|
||||
/*
|
||||
** State of a parse of a GeoJSON input.
|
||||
*/
|
||||
@@ -148,7 +138,7 @@ static void geopolySwab32(unsigned char *a){
|
||||
|
||||
/* Skip whitespace. Return the next non-whitespace character. */
|
||||
static char geopolySkipSpace(GeoParse *p){
|
||||
while( safe_isspace(p->z[0]) ) p->z++;
|
||||
while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
|
||||
return p->z[0];
|
||||
}
|
||||
|
||||
@@ -168,7 +158,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
|
||||
if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
|
||||
for(;; j++){
|
||||
c = z[j];
|
||||
if( safe_isdigit(c) ) continue;
|
||||
if( c>='0' && c<='9' ) continue;
|
||||
if( c=='.' ){
|
||||
if( z[j-1]=='-' ) return 0;
|
||||
if( seenDP ) return 0;
|
||||
@@ -190,17 +180,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
|
||||
break;
|
||||
}
|
||||
if( z[j-1]<'0' ) return 0;
|
||||
if( pVal ){
|
||||
#ifdef SQLITE_AMALGAMATION
|
||||
/* The sqlite3AtoF() routine is much much faster than atof(), if it
|
||||
** is available */
|
||||
double r;
|
||||
(void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
|
||||
*pVal = r;
|
||||
#else
|
||||
*pVal = (GeoCoord)atof((const char*)p->z);
|
||||
#endif
|
||||
}
|
||||
if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
|
||||
p->z += j;
|
||||
return 1;
|
||||
}
|
||||
@@ -258,10 +238,12 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
|
||||
&& s.a[1]==s.a[s.nVertex*2-1]
|
||||
&& (s.z++, geopolySkipSpace(&s)==0)
|
||||
){
|
||||
int nByte;
|
||||
GeoPoly *pOut;
|
||||
int x = 1;
|
||||
s.nVertex--; /* Remove the redundant vertex at the end */
|
||||
pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
|
||||
nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
|
||||
pOut = sqlite3_malloc64( nByte );
|
||||
x = 1;
|
||||
if( pOut==0 ) goto parse_json_err;
|
||||
pOut->nVertex = s.nVertex;
|
||||
@@ -464,27 +446,6 @@ static void geopolyXformFunc(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute the area enclosed by the polygon.
|
||||
**
|
||||
** This routine can also be used to detect polygons that rotate in
|
||||
** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
|
||||
** This routine returns a negative value for clockwise (CW) polygons.
|
||||
*/
|
||||
static double geopolyArea(GeoPoly *p){
|
||||
double rArea = 0.0;
|
||||
int ii;
|
||||
for(ii=0; ii<p->nVertex-1; ii++){
|
||||
rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
|
||||
* (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
|
||||
* 0.5;
|
||||
}
|
||||
rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
|
||||
* (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
|
||||
* 0.5;
|
||||
return rArea;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the geopoly_area(X) function.
|
||||
**
|
||||
@@ -500,106 +461,21 @@ static void geopolyAreaFunc(
|
||||
){
|
||||
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
|
||||
if( p ){
|
||||
sqlite3_result_double(context, geopolyArea(p));
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the geopoly_ccw(X) function.
|
||||
**
|
||||
** If the rotation of polygon X is clockwise (incorrect) instead of
|
||||
** counter-clockwise (the correct winding order according to RFC7946)
|
||||
** then reverse the order of the vertexes in polygon X.
|
||||
**
|
||||
** In other words, this routine returns a CCW polygon regardless of the
|
||||
** winding order of its input.
|
||||
**
|
||||
** Use this routine to sanitize historical inputs that that sometimes
|
||||
** contain polygons that wind in the wrong direction.
|
||||
*/
|
||||
static void geopolyCcwFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
|
||||
if( p ){
|
||||
if( geopolyArea(p)<0.0 ){
|
||||
int ii, jj;
|
||||
for(ii=2, jj=p->nVertex*2 - 4; ii<jj; ii+=2, jj-=2){
|
||||
GeoCoord t = p->a[ii];
|
||||
p->a[ii] = p->a[jj];
|
||||
p->a[jj] = t;
|
||||
t = p->a[ii+1];
|
||||
p->a[ii+1] = p->a[jj+1];
|
||||
p->a[jj+1] = t;
|
||||
}
|
||||
double rArea = 0.0;
|
||||
int ii;
|
||||
for(ii=0; ii<p->nVertex-1; ii++){
|
||||
rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
|
||||
* (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
|
||||
* 0.5;
|
||||
}
|
||||
sqlite3_result_blob(context, p->hdr,
|
||||
4+8*p->nVertex, SQLITE_TRANSIENT);
|
||||
rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
|
||||
* (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
|
||||
* 0.5;
|
||||
sqlite3_result_double(context, rArea);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
#define GEOPOLY_PI 3.1415926535897932385
|
||||
|
||||
/* Fast approximation for cosine(X) for X between -0.5*pi and 2*pi
|
||||
*/
|
||||
static double geopolyCosine(double r){
|
||||
assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
|
||||
if( r>=1.5*GEOPOLY_PI ){
|
||||
r -= 2.0*GEOPOLY_PI;
|
||||
}
|
||||
if( r>=0.5*GEOPOLY_PI ){
|
||||
return -geopolyCosine(r-GEOPOLY_PI);
|
||||
}else{
|
||||
double r2 = r*r;
|
||||
double r3 = r2*r;
|
||||
double r5 = r3*r2;
|
||||
return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Function: geopoly_regular(X,Y,R,N)
|
||||
**
|
||||
** Construct a simple, convex, regular polygon centered at X, Y
|
||||
** with circumradius R and with N sides.
|
||||
*/
|
||||
static void geopolyRegularFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
double x = sqlite3_value_double(argv[0]);
|
||||
double y = sqlite3_value_double(argv[1]);
|
||||
double r = sqlite3_value_double(argv[2]);
|
||||
int n = sqlite3_value_int(argv[3]);
|
||||
int i;
|
||||
GeoPoly *p;
|
||||
|
||||
if( n<3 || r<=0.0 ) return;
|
||||
if( n>1000 ) n = 1000;
|
||||
p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
|
||||
if( p==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
}
|
||||
i = 1;
|
||||
p->hdr[0] = *(unsigned char*)&i;
|
||||
p->hdr[1] = 0;
|
||||
p->hdr[2] = (n>>8)&0xff;
|
||||
p->hdr[3] = n&0xff;
|
||||
for(i=0; i<n; i++){
|
||||
double rAngle = 2.0*GEOPOLY_PI*i/n;
|
||||
p->a[i*2] = x - r*geopolyCosine(rAngle-0.5*GEOPOLY_PI);
|
||||
p->a[i*2+1] = y + r*geopolyCosine(rAngle);
|
||||
}
|
||||
sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** If pPoly is a polygon, compute its bounding box. Then:
|
||||
**
|
||||
@@ -644,7 +520,7 @@ static GeoPoly *geopolyBBox(
|
||||
if( pRc ) *pRc = SQLITE_OK;
|
||||
if( aCoord==0 ){
|
||||
geopolyBboxFill:
|
||||
pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
|
||||
pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
|
||||
if( pOut==0 ){
|
||||
sqlite3_free(p);
|
||||
if( context ) sqlite3_result_error_nomem(context);
|
||||
@@ -1672,16 +1548,7 @@ static int geopolyUpdate(
|
||||
if( sqlite3_value_nochange(aData[2]) ){
|
||||
sqlite3_bind_null(pUp, 2);
|
||||
}else{
|
||||
GeoPoly *p = 0;
|
||||
if( sqlite3_value_type(aData[2])==SQLITE_TEXT
|
||||
&& (p = geopolyFuncParam(0, aData[2], &rc))!=0
|
||||
&& rc==SQLITE_OK
|
||||
){
|
||||
sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
|
||||
}else{
|
||||
sqlite3_bind_value(pUp, 2, aData[2]);
|
||||
}
|
||||
sqlite3_free(p);
|
||||
sqlite3_bind_value(pUp, 2, aData[2]);
|
||||
nChange = 1;
|
||||
}
|
||||
for(jj=1; jj<pRtree->nAux; jj++){
|
||||
@@ -1754,22 +1621,19 @@ static int sqlite3_geopoly_init(sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
static const struct {
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
|
||||
signed char nArg;
|
||||
unsigned char bPure;
|
||||
int nArg;
|
||||
const char *zName;
|
||||
} aFunc[] = {
|
||||
{ geopolyAreaFunc, 1, 1, "geopoly_area" },
|
||||
{ geopolyBlobFunc, 1, 1, "geopoly_blob" },
|
||||
{ geopolyJsonFunc, 1, 1, "geopoly_json" },
|
||||
{ geopolySvgFunc, -1, 1, "geopoly_svg" },
|
||||
{ geopolyWithinFunc, 2, 1, "geopoly_within" },
|
||||
{ geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
|
||||
{ geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
|
||||
{ geopolyDebugFunc, 1, 0, "geopoly_debug" },
|
||||
{ geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
|
||||
{ geopolyXformFunc, 7, 1, "geopoly_xform" },
|
||||
{ geopolyRegularFunc, 4, 1, "geopoly_regular" },
|
||||
{ geopolyCcwFunc, 1, 1, "geopoly_ccw" },
|
||||
{ geopolyAreaFunc, 1, "geopoly_area" },
|
||||
{ geopolyBlobFunc, 1, "geopoly_blob" },
|
||||
{ geopolyJsonFunc, 1, "geopoly_json" },
|
||||
{ geopolySvgFunc, -1, "geopoly_svg" },
|
||||
{ geopolyWithinFunc, 2, "geopoly_within" },
|
||||
{ geopolyContainsPointFunc, 3, "geopoly_contains_point" },
|
||||
{ geopolyOverlapFunc, 2, "geopoly_overlap" },
|
||||
{ geopolyDebugFunc, 1, "geopoly_debug" },
|
||||
{ geopolyBBoxFunc, 1, "geopoly_bbox" },
|
||||
{ geopolyXformFunc, 7, "geopoly_xform" },
|
||||
};
|
||||
static const struct {
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
|
||||
@@ -1780,9 +1644,8 @@ static int sqlite3_geopoly_init(sqlite3 *db){
|
||||
};
|
||||
int i;
|
||||
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
|
||||
int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
|
||||
rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
|
||||
enc, 0,
|
||||
SQLITE_UTF8, 0,
|
||||
aFunc[i].xFunc, 0, 0);
|
||||
}
|
||||
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
|
||||
|
||||
@@ -586,17 +586,4 @@ SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"')
|
||||
ROLLBACK;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Regular Polygons</h1>'
|
||||
.print '<svg width="1000" height="200" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(geopoly_regular(100,100,40,3),'style="fill:none;stroke:red;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(200,100,40,4),'style="fill:none;stroke:orange;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(300,100,40,5),'style="fill:none;stroke:green;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(400,100,40,6),'style="fill:none;stroke:blue;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(500,100,40,7),'style="fill:none;stroke:purple;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(600,100,40,8),'style="fill:none;stroke:red;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(700,100,40,10),'style="fill:none;stroke:orange;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(800,100,40,20),'style="fill:none;stroke:green;stroke-width:1"');
|
||||
SELECT geopoly_svg(geopoly_regular(900,100,40,30),'style="fill:none;stroke:blue;stroke-width:1"');
|
||||
.print '</svg>'
|
||||
|
||||
.print '</html>'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
# 2018 November 08
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
set testprefix changesetfuzz1
|
||||
|
||||
|
||||
set CF [test_find_binary changesetfuzz]
|
||||
if {$CF==""} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc writefile {zFile data} {
|
||||
set fd [open $zFile w]
|
||||
fconfigure $fd -translation binary -encoding binary
|
||||
puts -nonewline $fd $data
|
||||
close $fd
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c, d, PRIMARY KEY(c, d));
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
|
||||
|
||||
INSERT INTO t1 VALUES ('one', 'two', 'three', 'four'),
|
||||
('five', 'six', 'seven', 'eight'),
|
||||
('nine', 'ten', 'eleven', 'twelve');
|
||||
INSERT INTO t2 VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);
|
||||
}
|
||||
|
||||
set C [changeset_from_sql {
|
||||
INSERT INTO t2 VALUES(10, 11, 12);
|
||||
DELETE FROM t2 WHERE a=1;
|
||||
UPDATE t1 SET b='forty-five' WHERE a='one';
|
||||
UPDATE t1 SET a='twenty-nine', b='seventy' WHERE a='five';
|
||||
}]
|
||||
writefile c1.changeset $C
|
||||
|
||||
do_test 1.1 {
|
||||
for {set j 0} {$j < 200} {incr j} {
|
||||
forcecopy c1.changeset input.changeset
|
||||
for {set i 0} {$i < 6} {incr i} {
|
||||
exec $CF input.changeset $i 1
|
||||
exec $CF input.changeset-0
|
||||
forcecopy input.changeset-0 input.changeset
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
set P [patchset_from_sql {
|
||||
INSERT INTO t2 VALUES(13, 14, 15);
|
||||
DELETE FROM t2 WHERE a=4;
|
||||
UPDATE t1 SET b='thirteen' WHERE a='one';
|
||||
UPDATE t1 SET a='ninety-seven', b='twenty' WHERE a='five';
|
||||
}]
|
||||
writefile p1.patchset $P
|
||||
do_test 1.2 {
|
||||
for {set j 0} {$j < 200} {incr j} {
|
||||
forcecopy p1.patchset input.patchset
|
||||
for {set i 0} {$i < 6} {incr i} {
|
||||
exec $CF input.patchset $i 1
|
||||
exec $CF input.patchset-0
|
||||
forcecopy input.patchset-0 input.patchset
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -655,13 +655,6 @@ do_test $tn.13.3 {
|
||||
} {1 one 2 two 3 iii}
|
||||
execsql ROLLBACK
|
||||
|
||||
do_test $tn.14.1 { sqlite3session_config strm_size -1 } 64
|
||||
do_test $tn.14.2 { sqlite3session_config strm_size 65536 } 65536
|
||||
do_test $tn.14.3 { sqlite3session_config strm_size 64 } 64
|
||||
do_test $tn.14.4 {
|
||||
list [catch {sqlite3session_config invalid 123} msg] $msg
|
||||
} {1 SQLITE_MISUSE}
|
||||
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@@ -95,23 +95,6 @@ proc changeset_from_sql {sql {dbname main}} {
|
||||
return $changeset
|
||||
}
|
||||
|
||||
proc patchset_from_sql {sql {dbname main}} {
|
||||
set rc [catch {
|
||||
sqlite3session S db $dbname
|
||||
db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" {
|
||||
S attach $name
|
||||
}
|
||||
db eval $sql
|
||||
S patchset
|
||||
} patchset]
|
||||
catch { S delete }
|
||||
|
||||
if {$rc} {
|
||||
error $patchset
|
||||
}
|
||||
return $patchset
|
||||
}
|
||||
|
||||
proc do_then_apply_sql {sql {dbname main}} {
|
||||
proc xConflict args { return "OMIT" }
|
||||
set rc [catch {
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
# 2018 October 18
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix sessioninvert
|
||||
|
||||
proc iter_invert {C} {
|
||||
set x [list]
|
||||
sqlite3session_foreach -invert c $C { lappend x $c }
|
||||
set x
|
||||
}
|
||||
|
||||
proc do_invert_test {tn sql {iter {}}} {
|
||||
|
||||
forcecopy test.db test.db2
|
||||
sqlite3 db2 test.db2
|
||||
|
||||
set C [changeset_from_sql $sql]
|
||||
|
||||
forcecopy test.db test.db3
|
||||
sqlite3 db3 test.db3
|
||||
uplevel [list do_test $tn.1 [list compare_db db db3] {}]
|
||||
|
||||
set I [sqlite3changeset_invert $C]
|
||||
sqlite3changeset_apply db $I {}
|
||||
uplevel [list do_test $tn.2 [list compare_db db db2] {}]
|
||||
|
||||
sqlite3changeset_apply_v2 -invert db3 $C {}
|
||||
uplevel [list do_test $tn.3 [list compare_db db db3] {}]
|
||||
|
||||
if {$iter!=""} {
|
||||
uplevel [list do_test $tn.4 [list iter_invert $C] [list {*}$iter]]
|
||||
}
|
||||
|
||||
catch { db2 close }
|
||||
catch { db3 close }
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b, c);
|
||||
CREATE TABLE t2(d, e, f, PRIMARY KEY(e, f));
|
||||
|
||||
INSERT INTO t1 VALUES(1, 'one', 'i');
|
||||
INSERT INTO t1 VALUES(2, 'two', 'ii');
|
||||
INSERT INTO t1 VALUES(3, 'three', 'iii');
|
||||
INSERT INTO t1 VALUES(4, 'four', 'iv');
|
||||
INSERT INTO t1 VALUES(5, 'five', 'v');
|
||||
INSERT INTO t1 VALUES(6, 'six', 'vi');
|
||||
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
}
|
||||
|
||||
do_invert_test 1.1 {
|
||||
INSERT INTO t1 VALUES(7, 'seven', 'vii');
|
||||
} {
|
||||
{DELETE t1 0 X.. {i 7 t seven t vii} {}}
|
||||
}
|
||||
|
||||
do_invert_test 1.2 {
|
||||
DELETE FROM t1 WHERE a<4;
|
||||
} {
|
||||
{INSERT t1 0 X.. {} {i 1 t one t i}}
|
||||
{INSERT t1 0 X.. {} {i 2 t two t ii}}
|
||||
{INSERT t1 0 X.. {} {i 3 t three t iii}}
|
||||
}
|
||||
|
||||
do_invert_test 1.3 {
|
||||
UPDATE t1 SET c=5;
|
||||
} {
|
||||
{UPDATE t1 0 X.. {i 1 {} {} i 5} {{} {} {} {} t i}}
|
||||
{UPDATE t1 0 X.. {i 2 {} {} i 5} {{} {} {} {} t ii}}
|
||||
{UPDATE t1 0 X.. {i 3 {} {} i 5} {{} {} {} {} t iii}}
|
||||
{UPDATE t1 0 X.. {i 4 {} {} i 5} {{} {} {} {} t iv}}
|
||||
{UPDATE t1 0 X.. {i 5 {} {} i 5} {{} {} {} {} t v}}
|
||||
{UPDATE t1 0 X.. {i 6 {} {} i 5} {{} {} {} {} t vi}}
|
||||
}
|
||||
|
||||
do_invert_test 1.4 {
|
||||
UPDATE t1 SET b = a+1 WHERE a%2;
|
||||
DELETE FROM t2;
|
||||
INSERT INTO t1 VALUES(10, 'ten', NULL);
|
||||
}
|
||||
|
||||
do_invert_test 1.5 {
|
||||
UPDATE t2 SET d = d-1;
|
||||
} {
|
||||
{UPDATE t2 0 .XX {i 2 t three t iii} {i 3 {} {} {} {}}}
|
||||
{UPDATE t2 0 .XX {i 1 t two t ii} {i 2 {} {} {} {}}}
|
||||
{UPDATE t2 0 .XX {i 5 t six t vi} {i 6 {} {} {} {}}}
|
||||
{UPDATE t2 0 .XX {i 3 t four t iv} {i 4 {} {} {} {}}}
|
||||
{UPDATE t2 0 .XX {i 0 t one t i} {i 1 {} {} {} {}}}
|
||||
{UPDATE t2 0 .XX {i 4 t five t v} {i 5 {} {} {} {}}}
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
ANALYZE;
|
||||
PRAGMA writable_schema = 1;
|
||||
DROP TABLE IF EXISTS sqlite_stat4;
|
||||
SELECT * FROM sqlite_stat1;
|
||||
} {
|
||||
t2 sqlite_autoindex_t2_1 {6 1 1}
|
||||
t1 sqlite_autoindex_t1_1 {6 1}
|
||||
}
|
||||
|
||||
do_invert_test 2.1 {
|
||||
INSERT INTO sqlite_stat1 VALUES('t3', 'idx2', '1 2 3');
|
||||
} {
|
||||
{DELETE sqlite_stat1 0 XX. {t t3 t idx2 t {1 2 3}} {}}
|
||||
}
|
||||
|
||||
do_invert_test 2.2 {
|
||||
DELETE FROM sqlite_stat1;
|
||||
} {
|
||||
{INSERT sqlite_stat1 0 XX. {} {t t1 t sqlite_autoindex_t1_1 t {6 1}}}
|
||||
{INSERT sqlite_stat1 0 XX. {} {t t2 t sqlite_autoindex_t2_1 t {6 1 1}}}
|
||||
}
|
||||
|
||||
do_invert_test 2.3 {
|
||||
UPDATE sqlite_stat1 SET stat = 'hello world';
|
||||
}
|
||||
|
||||
do_test 3.0 {
|
||||
forcecopy test.db test.db2
|
||||
sqlite3 db2 test.db2
|
||||
set P [patchset_from_sql {
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
DELETE FROM t2 WHERE d = 3;
|
||||
}]
|
||||
|
||||
list [catch { sqlite3changeset_apply_v2 -invert db2 $P {} } msg] $msg
|
||||
} {1 SQLITE_CORRUPT}
|
||||
|
||||
do_test 3.1 {
|
||||
list [catch { sqlite3session_foreach -invert db2 $P {} } msg] $msg
|
||||
} {1 SQLITE_CORRUPT}
|
||||
|
||||
do_test 3.2 {
|
||||
sqlite3changeset_apply_v2 db2 $P {}
|
||||
compare_db db db2
|
||||
} {}
|
||||
|
||||
|
||||
finish_test
|
||||
+56
-147
@@ -25,8 +25,6 @@ typedef struct SessionInput SessionInput;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
|
||||
|
||||
typedef struct SessionHook SessionHook;
|
||||
struct SessionHook {
|
||||
void *pCtx;
|
||||
@@ -89,7 +87,6 @@ struct sqlite3_changeset_iter {
|
||||
SessionInput in; /* Input buffer or stream */
|
||||
SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
|
||||
int bPatchset; /* True if this is a patchset */
|
||||
int bInvert; /* True to invert changeset */
|
||||
int rc; /* Iterator error code */
|
||||
sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
|
||||
char *zTab; /* Current table */
|
||||
@@ -246,42 +243,6 @@ struct SessionTable {
|
||||
** The records associated with INSERT changes are in the same format as for
|
||||
** changesets. It is not possible for a record associated with an INSERT
|
||||
** change to contain a field set to "undefined".
|
||||
**
|
||||
** REBASE BLOB FORMAT:
|
||||
**
|
||||
** A rebase blob may be output by sqlite3changeset_apply_v2() and its
|
||||
** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
|
||||
** existing changesets. A rebase blob contains one entry for each conflict
|
||||
** resolved using either the OMIT or REPLACE strategies within the apply_v2()
|
||||
** call.
|
||||
**
|
||||
** The format used for a rebase blob is very similar to that used for
|
||||
** changesets. All entries related to a single table are grouped together.
|
||||
**
|
||||
** Each group of entries begins with a table header in changeset format:
|
||||
**
|
||||
** 1 byte: Constant 0x54 (capital 'T')
|
||||
** Varint: Number of columns in the table.
|
||||
** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
|
||||
** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
|
||||
**
|
||||
** Followed by one or more entries associated with the table.
|
||||
**
|
||||
** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
|
||||
** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
|
||||
** record: (in the record format defined above).
|
||||
**
|
||||
** In a rebase blob, the first field is set to SQLITE_INSERT if the change
|
||||
** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
|
||||
** it was a DELETE. The second field is set to 0x01 if the conflict
|
||||
** resolution strategy was REPLACE, or 0x00 if it was OMIT.
|
||||
**
|
||||
** If the change that caused the conflict was a DELETE, then the single
|
||||
** record is a copy of the old.* record from the original changeset. If it
|
||||
** was an INSERT, then the single record is a copy of the new.* record. If
|
||||
** the conflicting change was an UPDATE, then the single record is a copy
|
||||
** of the new.* record with the PK fields filled in based on the original
|
||||
** old.* record.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -1832,12 +1793,12 @@ int sqlite3session_attach(
|
||||
static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
|
||||
if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
|
||||
u8 *aNew;
|
||||
i64 nNew = p->nAlloc ? p->nAlloc : 128;
|
||||
int nNew = p->nAlloc ? p->nAlloc : 128;
|
||||
do {
|
||||
nNew = nNew*2;
|
||||
}while( (nNew-p->nBuf)<nByte );
|
||||
}while( nNew<(p->nBuf+nByte) );
|
||||
|
||||
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
|
||||
aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
|
||||
if( 0==aNew ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -2435,12 +2396,12 @@ static int sessionGenerateChangeset(
|
||||
rc = sqlite3_reset(pSel);
|
||||
}
|
||||
|
||||
/* If the buffer is now larger than sessions_strm_chunk_size, pass
|
||||
/* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
|
||||
** its contents to the xOutput() callback. */
|
||||
if( xOutput
|
||||
&& rc==SQLITE_OK
|
||||
&& buf.nBuf>nNoop
|
||||
&& buf.nBuf>sessions_strm_chunk_size
|
||||
&& buf.nBuf>SESSIONS_STRM_CHUNK_SIZE
|
||||
){
|
||||
rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
|
||||
nNoop = -1;
|
||||
@@ -2579,8 +2540,7 @@ static int sessionChangesetStart(
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn,
|
||||
int nChangeset, /* Size of buffer pChangeset in bytes */
|
||||
void *pChangeset, /* Pointer to buffer containing changeset */
|
||||
int bInvert /* True to invert changeset */
|
||||
void *pChangeset /* Pointer to buffer containing changeset */
|
||||
){
|
||||
sqlite3_changeset_iter *pRet; /* Iterator to return */
|
||||
int nByte; /* Number of bytes to allocate for iterator */
|
||||
@@ -2600,7 +2560,6 @@ static int sessionChangesetStart(
|
||||
pRet->in.xInput = xInput;
|
||||
pRet->in.pIn = pIn;
|
||||
pRet->in.bEof = (xInput ? 0 : 1);
|
||||
pRet->bInvert = bInvert;
|
||||
|
||||
/* Populate the output variable and return success. */
|
||||
*pp = pRet;
|
||||
@@ -2615,16 +2574,7 @@ int sqlite3changeset_start(
|
||||
int nChangeset, /* Size of buffer pChangeset in bytes */
|
||||
void *pChangeset /* Pointer to buffer containing changeset */
|
||||
){
|
||||
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
|
||||
}
|
||||
int sqlite3changeset_start_v2(
|
||||
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
|
||||
int nChangeset, /* Size of buffer pChangeset in bytes */
|
||||
void *pChangeset, /* Pointer to buffer containing changeset */
|
||||
int flags
|
||||
){
|
||||
int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
|
||||
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
|
||||
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2635,16 +2585,7 @@ int sqlite3changeset_start_strm(
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn
|
||||
){
|
||||
return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
|
||||
}
|
||||
int sqlite3changeset_start_v2_strm(
|
||||
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn,
|
||||
int flags
|
||||
){
|
||||
int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
|
||||
return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
|
||||
return sessionChangesetStart(pp, xInput, pIn, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2652,7 +2593,7 @@ int sqlite3changeset_start_v2_strm(
|
||||
** object and the buffer is full, discard some data to free up space.
|
||||
*/
|
||||
static void sessionDiscardData(SessionInput *pIn){
|
||||
if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
|
||||
if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
|
||||
int nMove = pIn->buf.nBuf - pIn->iNext;
|
||||
assert( nMove>=0 );
|
||||
if( nMove>0 ){
|
||||
@@ -2675,7 +2616,7 @@ static int sessionInputBuffer(SessionInput *pIn, int nByte){
|
||||
int rc = SQLITE_OK;
|
||||
if( pIn->xInput ){
|
||||
while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
|
||||
int nNew = sessions_strm_chunk_size;
|
||||
int nNew = SESSIONS_STRM_CHUNK_SIZE;
|
||||
|
||||
if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
|
||||
if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
|
||||
@@ -3023,10 +2964,10 @@ static int sessionChangesetNext(
|
||||
op = p->in.aData[p->in.iNext++];
|
||||
}
|
||||
|
||||
if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
|
||||
if( p->zTab==0 ){
|
||||
/* The first record in the changeset is not a table header. Must be a
|
||||
** corrupt changeset. */
|
||||
assert( p->in.iNext==1 || p->zTab );
|
||||
assert( p->in.iNext==1 );
|
||||
return (p->rc = SQLITE_CORRUPT_BKPT);
|
||||
}
|
||||
|
||||
@@ -3051,39 +2992,33 @@ static int sessionChangesetNext(
|
||||
*paRec = &p->in.aData[p->in.iNext];
|
||||
p->in.iNext += *pnRec;
|
||||
}else{
|
||||
sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
|
||||
sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
|
||||
|
||||
/* If this is an UPDATE or DELETE, read the old.* record. */
|
||||
if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
|
||||
u8 *abPK = p->bPatchset ? p->abPK : 0;
|
||||
p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
|
||||
p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
|
||||
if( p->rc!=SQLITE_OK ) return p->rc;
|
||||
}
|
||||
|
||||
/* If this is an INSERT or UPDATE, read the new.* record. */
|
||||
if( p->op!=SQLITE_DELETE ){
|
||||
p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
|
||||
p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
|
||||
if( p->rc!=SQLITE_OK ) return p->rc;
|
||||
}
|
||||
|
||||
if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
|
||||
if( p->bPatchset && p->op==SQLITE_UPDATE ){
|
||||
/* If this is an UPDATE that is part of a patchset, then all PK and
|
||||
** modified fields are present in the new.* record. The old.* record
|
||||
** is currently completely empty. This block shifts the PK fields from
|
||||
** new.* to old.*, to accommodate the code that reads these arrays. */
|
||||
for(i=0; i<p->nCol; i++){
|
||||
assert( p->bPatchset==0 || p->apValue[i]==0 );
|
||||
assert( p->apValue[i]==0 );
|
||||
if( p->abPK[i] ){
|
||||
assert( p->apValue[i]==0 );
|
||||
p->apValue[i] = p->apValue[i+p->nCol];
|
||||
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
|
||||
p->apValue[i+p->nCol] = 0;
|
||||
}
|
||||
}
|
||||
}else if( p->bInvert ){
|
||||
if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
|
||||
else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3400,7 +3335,7 @@ static int sessionChangesetInvert(
|
||||
}
|
||||
|
||||
assert( rc==SQLITE_OK );
|
||||
if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
|
||||
if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
|
||||
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
|
||||
sOut.nBuf = 0;
|
||||
if( rc!=SQLITE_OK ) goto finished_invert;
|
||||
@@ -3479,8 +3414,7 @@ struct SessionApplyCtx {
|
||||
int bDeferConstraints; /* True to defer constraints */
|
||||
SessionBuffer constraints; /* Deferred constraints are stored here */
|
||||
SessionBuffer rebase; /* Rebase information (if any) here */
|
||||
u8 bRebaseStarted; /* If table header is already in rebase */
|
||||
u8 bRebase; /* True to collect rebase information */
|
||||
int bRebaseStarted; /* If table header is already in rebase */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3877,36 +3811,35 @@ static int sessionRebaseAdd(
|
||||
sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->bRebase ){
|
||||
int i;
|
||||
int eOp = pIter->op;
|
||||
if( p->bRebaseStarted==0 ){
|
||||
/* Append a table-header to the rebase buffer */
|
||||
const char *zTab = pIter->zTab;
|
||||
sessionAppendByte(&p->rebase, 'T', &rc);
|
||||
sessionAppendVarint(&p->rebase, p->nCol, &rc);
|
||||
sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
|
||||
sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
|
||||
p->bRebaseStarted = 1;
|
||||
}
|
||||
|
||||
assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
|
||||
assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
|
||||
|
||||
sessionAppendByte(&p->rebase,
|
||||
(eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
|
||||
);
|
||||
sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
|
||||
for(i=0; i<p->nCol; i++){
|
||||
sqlite3_value *pVal = 0;
|
||||
if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
|
||||
sqlite3changeset_old(pIter, i, &pVal);
|
||||
}else{
|
||||
sqlite3changeset_new(pIter, i, &pVal);
|
||||
}
|
||||
sessionAppendValue(&p->rebase, pVal, &rc);
|
||||
}
|
||||
int i;
|
||||
int eOp = pIter->op;
|
||||
if( p->bRebaseStarted==0 ){
|
||||
/* Append a table-header to the rebase buffer */
|
||||
const char *zTab = pIter->zTab;
|
||||
sessionAppendByte(&p->rebase, 'T', &rc);
|
||||
sessionAppendVarint(&p->rebase, p->nCol, &rc);
|
||||
sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
|
||||
sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
|
||||
p->bRebaseStarted = 1;
|
||||
}
|
||||
|
||||
assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
|
||||
assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
|
||||
|
||||
sessionAppendByte(&p->rebase,
|
||||
(eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
|
||||
);
|
||||
sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
|
||||
for(i=0; i<p->nCol; i++){
|
||||
sqlite3_value *pVal = 0;
|
||||
if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
|
||||
sqlite3changeset_old(pIter, i, &pVal);
|
||||
}else{
|
||||
sqlite3changeset_new(pIter, i, &pVal);
|
||||
}
|
||||
sessionAppendValue(&p->rebase, pVal, &rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -4249,7 +4182,7 @@ static int sessionRetryConstraints(
|
||||
SessionBuffer cons = pApply->constraints;
|
||||
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
|
||||
|
||||
rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
|
||||
rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
|
||||
if( rc==SQLITE_OK ){
|
||||
int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
|
||||
int rc2;
|
||||
@@ -4315,7 +4248,6 @@ static int sessionChangesetApply(
|
||||
|
||||
pIter->in.bNoDiscard = 1;
|
||||
memset(&sApply, 0, sizeof(sApply));
|
||||
sApply.bRebase = (ppRebase && pnRebase);
|
||||
sqlite3_mutex_enter(sqlite3_db_mutex(db));
|
||||
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
|
||||
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
|
||||
@@ -4466,8 +4398,7 @@ static int sessionChangesetApply(
|
||||
}
|
||||
}
|
||||
|
||||
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
|
||||
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
|
||||
if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
|
||||
*ppRebase = (void*)sApply.rebase.aBuf;
|
||||
*pnRebase = sApply.rebase.nBuf;
|
||||
sApply.rebase.aBuf = 0;
|
||||
@@ -4505,8 +4436,7 @@ int sqlite3changeset_apply_v2(
|
||||
int flags
|
||||
){
|
||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
|
||||
int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
|
||||
int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetApply(
|
||||
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
|
||||
@@ -4563,8 +4493,7 @@ int sqlite3changeset_apply_v2_strm(
|
||||
int flags
|
||||
){
|
||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
|
||||
int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
|
||||
int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetApply(
|
||||
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
|
||||
@@ -4937,12 +4866,13 @@ static int sessionChangegroupOutput(
|
||||
sessionAppendByte(&buf, p->op, &rc);
|
||||
sessionAppendByte(&buf, p->bIndirect, &rc);
|
||||
sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
|
||||
if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
|
||||
rc = xOutput(pOut, buf.aBuf, buf.nBuf);
|
||||
buf.nBuf = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
|
||||
rc = xOutput(pOut, buf.aBuf, buf.nBuf);
|
||||
buf.nBuf = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -5333,7 +5263,7 @@ static int sessionRebase(
|
||||
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
|
||||
sessionAppendBlob(&sOut, aRec, nRec, &rc);
|
||||
}
|
||||
if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
|
||||
if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
|
||||
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
|
||||
sOut.nBuf = 0;
|
||||
}
|
||||
@@ -5444,25 +5374,4 @@ void sqlite3rebaser_delete(sqlite3_rebaser *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Global configuration
|
||||
*/
|
||||
int sqlite3session_config(int op, void *pArg){
|
||||
int rc = SQLITE_OK;
|
||||
switch( op ){
|
||||
case SQLITE_SESSION_CONFIG_STRMSIZE: {
|
||||
int *pInt = (int*)pArg;
|
||||
if( *pInt>0 ){
|
||||
sessions_strm_chunk_size = *pInt;
|
||||
}
|
||||
*pInt = sessions_strm_chunk_size;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = SQLITE_MISUSE;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
@@ -473,38 +473,12 @@ int sqlite3session_isempty(sqlite3_session *pSession);
|
||||
** consecutively. There is no chance that the iterator will visit a change
|
||||
** the applies to table X, then one for table Y, and then later on visit
|
||||
** another change for table X.
|
||||
**
|
||||
** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
|
||||
** may be modified by passing a combination of
|
||||
** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
|
||||
**
|
||||
** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
|
||||
** and therefore subject to change.
|
||||
*/
|
||||
int sqlite3changeset_start(
|
||||
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
|
||||
int nChangeset, /* Size of changeset blob in bytes */
|
||||
void *pChangeset /* Pointer to blob containing changeset */
|
||||
);
|
||||
int sqlite3changeset_start_v2(
|
||||
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
|
||||
int nChangeset, /* Size of changeset blob in bytes */
|
||||
void *pChangeset, /* Pointer to blob containing changeset */
|
||||
int flags /* SESSION_CHANGESETSTART_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for sqlite3changeset_start_v2
|
||||
**
|
||||
** The following flags may passed via the 4th parameter to
|
||||
** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
|
||||
**
|
||||
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
|
||||
** Invert the changeset while iterating through it. This is equivalent to
|
||||
** inverting a changeset using sqlite3changeset_invert() before applying it.
|
||||
** It is an error to specify this flag with a patchset.
|
||||
*/
|
||||
#define SQLITE_CHANGESETSTART_INVERT 0x0002
|
||||
|
||||
|
||||
/*
|
||||
@@ -1159,7 +1133,7 @@ int sqlite3changeset_apply_v2(
|
||||
),
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
||||
int flags /* SESSION_CHANGESETAPPLY_* flags */
|
||||
int flags /* Combination of SESSION_APPLY_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -1177,14 +1151,8 @@ int sqlite3changeset_apply_v2(
|
||||
** causes the sessions module to omit this savepoint. In this case, if the
|
||||
** caller has an open transaction or savepoint when apply_v2() is called,
|
||||
** it may revert the partially applied changeset by rolling it back.
|
||||
**
|
||||
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
|
||||
** Invert the changeset before applying it. This is equivalent to inverting
|
||||
** a changeset using sqlite3changeset_invert() before applying it. It is
|
||||
** an error to specify this flag with a patchset.
|
||||
*/
|
||||
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
|
||||
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
|
||||
|
||||
/*
|
||||
** CAPI3REF: Constants Passed To The Conflict Handler
|
||||
@@ -1578,12 +1546,6 @@ int sqlite3changeset_start_strm(
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn
|
||||
);
|
||||
int sqlite3changeset_start_v2_strm(
|
||||
sqlite3_changeset_iter **pp,
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn,
|
||||
int flags
|
||||
);
|
||||
int sqlite3session_changeset_strm(
|
||||
sqlite3_session *pSession,
|
||||
int (*xOutput)(void *pOut, const void *pData, int nData),
|
||||
@@ -1610,45 +1572,6 @@ int sqlite3rebaser_rebase_strm(
|
||||
void *pOut
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Configure global parameters
|
||||
**
|
||||
** The sqlite3session_config() interface is used to make global configuration
|
||||
** changes to the sessions module in order to tune it to the specific needs
|
||||
** of the application.
|
||||
**
|
||||
** The sqlite3session_config() interface is not threadsafe. If it is invoked
|
||||
** while any other thread is inside any other sessions method then the
|
||||
** results are undefined. Furthermore, if it is invoked after any sessions
|
||||
** related objects have been created, the results are also undefined.
|
||||
**
|
||||
** The first argument to the sqlite3session_config() function must be one
|
||||
** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
|
||||
** interpretation of the (void*) value passed as the second parameter and
|
||||
** the effect of calling this function depends on the value of the first
|
||||
** parameter.
|
||||
**
|
||||
** <dl>
|
||||
** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
|
||||
** By default, the sessions module streaming interfaces attempt to input
|
||||
** and output data in approximately 1 KiB chunks. This operand may be used
|
||||
** to set and query the value of this configuration setting. The pointer
|
||||
** passed as the second argument must point to a value of type (int).
|
||||
** If this value is greater than 0, it is used as the new streaming data
|
||||
** chunk size for both input and output. Before returning, the (int) value
|
||||
** pointed to by pArg is set to the final value of the streaming interface
|
||||
** chunk size.
|
||||
** </dl>
|
||||
**
|
||||
** This function returns SQLITE_OK if successful, or an SQLite error code
|
||||
** otherwise.
|
||||
*/
|
||||
int sqlite3session_config(int op, void *pArg);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Values for sqlite3session_config().
|
||||
*/
|
||||
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
|
||||
|
||||
/*
|
||||
** Make sure we can call this stuff from C++.
|
||||
|
||||
+20
-97
@@ -737,32 +737,20 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
|
||||
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
|
||||
|
||||
/* Check for the -nosavepoint flag */
|
||||
if( bV2 ){
|
||||
if( objc>1 ){
|
||||
const char *z1 = Tcl_GetString(objv[1]);
|
||||
int n = strlen(z1);
|
||||
if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
|
||||
flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
|
||||
objc--;
|
||||
objv++;
|
||||
}
|
||||
}
|
||||
if( objc>1 ){
|
||||
const char *z1 = Tcl_GetString(objv[1]);
|
||||
int n = strlen(z1);
|
||||
if( n>1 && n<=7 && 0==sqlite3_strnicmp("-invert", z1, n) ){
|
||||
flags |= SQLITE_CHANGESETAPPLY_INVERT;
|
||||
objc--;
|
||||
objv++;
|
||||
}
|
||||
if( bV2 && objc>1 ){
|
||||
const char *z1 = Tcl_GetString(objv[1]);
|
||||
int n = strlen(z1);
|
||||
if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
|
||||
flags = SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
|
||||
objc--;
|
||||
objv++;
|
||||
}
|
||||
}
|
||||
|
||||
if( objc!=4 && objc!=5 ){
|
||||
const char *zMsg;
|
||||
if( bV2 ){
|
||||
zMsg = "?-nosavepoint? ?-inverse? "
|
||||
"DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
|
||||
zMsg = "?-nosavepoint? DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
|
||||
}else{
|
||||
zMsg = "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
|
||||
}
|
||||
@@ -981,56 +969,31 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach(
|
||||
Tcl_Obj *pCS;
|
||||
Tcl_Obj *pScript;
|
||||
int isCheckNext = 0;
|
||||
int isInvert = 0;
|
||||
|
||||
TestStreamInput sStr;
|
||||
memset(&sStr, 0, sizeof(sStr));
|
||||
|
||||
while( objc>1 ){
|
||||
if( objc>1 ){
|
||||
char *zOpt = Tcl_GetString(objv[1]);
|
||||
int nOpt = strlen(zOpt);
|
||||
if( zOpt[0]!='-' ) break;
|
||||
if( nOpt<=7 && 0==sqlite3_strnicmp(zOpt, "-invert", nOpt) ){
|
||||
isInvert = 1;
|
||||
}else
|
||||
if( nOpt<=5 && 0==sqlite3_strnicmp(zOpt, "-next", nOpt) ){
|
||||
isCheckNext = 1;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
objv++;
|
||||
objc--;
|
||||
isCheckNext = (strcmp(zOpt, "-next")==0);
|
||||
}
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(
|
||||
interp, 1, objv, "?-next? ?-invert? VARNAME CHANGESET SCRIPT");
|
||||
if( objc!=4+isCheckNext ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?-next? VARNAME CHANGESET SCRIPT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
pVarname = objv[1];
|
||||
pCS = objv[2];
|
||||
pScript = objv[3];
|
||||
pVarname = objv[1+isCheckNext];
|
||||
pCS = objv[2+isCheckNext];
|
||||
pScript = objv[3+isCheckNext];
|
||||
|
||||
pChangeset = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeset);
|
||||
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
|
||||
if( isInvert ){
|
||||
int f = SQLITE_CHANGESETSTART_INVERT;
|
||||
if( sStr.nStream==0 ){
|
||||
rc = sqlite3changeset_start_v2(&pIter, nChangeset, pChangeset, f);
|
||||
}else{
|
||||
void *pCtx = (void*)&sStr;
|
||||
sStr.aData = (unsigned char*)pChangeset;
|
||||
sStr.nData = nChangeset;
|
||||
rc = sqlite3changeset_start_v2_strm(&pIter, testStreamInput, pCtx, f);
|
||||
}
|
||||
if( sStr.nStream==0 ){
|
||||
rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
|
||||
}else{
|
||||
if( sStr.nStream==0 ){
|
||||
rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
|
||||
}else{
|
||||
sStr.aData = (unsigned char*)pChangeset;
|
||||
sStr.nData = nChangeset;
|
||||
rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr);
|
||||
}
|
||||
sStr.aData = (unsigned char*)pChangeset;
|
||||
sStr.nData = nChangeset;
|
||||
rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
return test_session_error(interp, rc, 0);
|
||||
@@ -1239,45 +1202,6 @@ static int SQLITE_TCLAPI test_sqlite3rebaser_create(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite3rebaser_configure OP VALUE
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_sqlite3session_config(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
struct ConfigOpt {
|
||||
const char *zSub;
|
||||
int op;
|
||||
} aSub[] = {
|
||||
{ "strm_size", SQLITE_SESSION_CONFIG_STRMSIZE },
|
||||
{ "invalid", 0 },
|
||||
{ 0 }
|
||||
};
|
||||
int rc;
|
||||
int iSub;
|
||||
int iVal;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "OP VALUE");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
rc = Tcl_GetIndexFromObjStruct(interp,
|
||||
objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
|
||||
);
|
||||
if( rc!=TCL_OK ) return rc;
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3session_config(aSub[iSub].op, (void*)&iVal);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return test_session_error(interp, rc, 0);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int TestSession_Init(Tcl_Interp *interp){
|
||||
struct Cmd {
|
||||
const char *zCmd;
|
||||
@@ -1293,7 +1217,6 @@ int TestSession_Init(Tcl_Interp *interp){
|
||||
test_sqlite3changeset_apply_replace_all },
|
||||
{ "sql_exec_changeset", test_sql_exec_changeset },
|
||||
{ "sqlite3rebaser_create", test_sqlite3rebaser_create },
|
||||
{ "sqlite3session_config", test_sqlite3session_config },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# EXE The suffix to add to executable files. ".exe" for windows
|
||||
# and "" for Unix.
|
||||
#
|
||||
# TCC C Compiler and options for use in building executables that
|
||||
# TCC C Compiler and options for use in building executables that
|
||||
# will run on the target platform. This is usually the same
|
||||
# as BCC, unless you are cross-compiling.
|
||||
#
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
# This is how we compile
|
||||
#
|
||||
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
|
||||
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
|
||||
TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
|
||||
TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth
|
||||
TCCX += -I$(TOP)/ext/session
|
||||
@@ -236,7 +236,7 @@ SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
SRC += \
|
||||
$(TOP)/ext/userauth/userauth.c \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
SRC += \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.c \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.h
|
||||
@@ -251,7 +251,7 @@ FTS5_HDR = \
|
||||
$(TOP)/ext/fts5/fts5.h \
|
||||
$(TOP)/ext/fts5/fts5Int.h \
|
||||
fts5parse.h
|
||||
|
||||
|
||||
FTS5_SRC = \
|
||||
$(TOP)/ext/fts5/fts5_aux.c \
|
||||
$(TOP)/ext/fts5/fts5_buffer.c \
|
||||
@@ -361,7 +361,6 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/csv.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
$(TOP)/ext/misc/explain.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/fuzzer.c \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
@@ -431,7 +430,7 @@ TESTSRC2 = \
|
||||
$(TOP)/ext/async/sqlite3async.c \
|
||||
$(TOP)/ext/misc/stmt.c \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/test_session.c
|
||||
$(TOP)/ext/session/test_session.c
|
||||
|
||||
# Header files used by all library source files.
|
||||
#
|
||||
@@ -484,7 +483,7 @@ EXTHDR += \
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts5/fts5Int.h \
|
||||
fts5parse.h \
|
||||
$(TOP)/ext/fts5/fts5.h
|
||||
$(TOP)/ext/fts5/fts5.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
|
||||
@@ -507,8 +506,7 @@ FUZZDATA = \
|
||||
$(TOP)/test/fuzzdata3.db \
|
||||
$(TOP)/test/fuzzdata4.db \
|
||||
$(TOP)/test/fuzzdata5.db \
|
||||
$(TOP)/test/fuzzdata6.db \
|
||||
$(TOP)/test/fuzzdata7.db
|
||||
$(TOP)/test/fuzzdata6.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
@@ -801,7 +799,7 @@ rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
|
||||
|
||||
|
||||
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||
cp $(TOP)/ext/fts5/fts5parse.y .
|
||||
rm -f fts5parse.h
|
||||
./lemon $(OPTS) fts5parse.y
|
||||
@@ -835,13 +833,13 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $
|
||||
tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
|
||||
|
||||
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
|
||||
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
|
||||
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
|
||||
|
||||
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl
|
||||
tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
|
||||
|
||||
sqltclsh$(EXE): sqltclsh.c
|
||||
$(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB)
|
||||
$(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB)
|
||||
|
||||
sqlite3_expert$(EXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c
|
||||
$(TCCX) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert$(EXE) $(THREADLIB)
|
||||
@@ -894,10 +892,6 @@ fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||
|
||||
coretestprogs: $(TESTPROGS)
|
||||
|
||||
testprogs: coretestprogs srcck1$(EXE) fuzzcheck$(EXE) sessionfuzz$(EXE)
|
||||
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/all.test $(TESTOPTS)
|
||||
|
||||
@@ -954,7 +948,7 @@ smoketest: $(TESTPROGS) fuzzcheck$(EXE)
|
||||
# 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 \
|
||||
@@ -998,10 +992,6 @@ changeset$(EXE): $(TOP)/ext/session/changeset.c sqlite3.o
|
||||
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changeset$(EXE) \
|
||||
$(TOP)/ext/session/changeset.c sqlite3.o $(THREADLIB)
|
||||
|
||||
changesetfuzz$(EXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o
|
||||
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changesetfuzz$(EXE) \
|
||||
$(TOP)/ext/session/changesetfuzz.c sqlite3.o $(THREADLIB)
|
||||
|
||||
fts3view$(EXE): $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o
|
||||
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o fts3view$(EXE) \
|
||||
$(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(THREADLIB)
|
||||
@@ -1022,12 +1012,12 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c
|
||||
$(TOP)/test/wordcount.c sqlite3.c
|
||||
|
||||
speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c
|
||||
$(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB)
|
||||
$(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB)
|
||||
|
||||
kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
|
||||
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
|
||||
$(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \
|
||||
$(THREADLIB)
|
||||
|
||||
@@ -1059,7 +1049,7 @@ install: sqlite3 libsqlite3.a sqlite3.h
|
||||
mv libsqlite3.a /usr/lib
|
||||
mv sqlite3.h /usr/include
|
||||
|
||||
clean:
|
||||
clean:
|
||||
rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.*
|
||||
rm -f lemon lemon.exe lempar.c parse.* sqlite*.tar.gz
|
||||
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
|
||||
@@ -1087,7 +1077,7 @@ clean:
|
||||
rm -f sqlite3rc.h
|
||||
rm -f shell.c sqlite3ext.h
|
||||
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
|
||||
rm -f sqlite3_expert sqlite3_expert.exe
|
||||
rm -f sqlite3_expert sqlite3_expert.exe
|
||||
rm -f sqlite-*-output.vsix
|
||||
rm -f mptester mptester.exe
|
||||
rm -f fuzzershell fuzzershell.exe
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C Merge\slatest\strunk\schanges.
|
||||
D 2018-11-10T17:36:55.425
|
||||
C Version\s3.25.2
|
||||
D 2018-09-25T19:08:10.988
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in d298b31769d4c737887102462cd45684786b09f2a626a80b3e413790fb436219
|
||||
F Makefile.in 6b650013511fd9d8b094203ac268af9220d292cc7d4e1bc9fbca15aacd8c7995
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 071853dfc2148aadaeb7a153b9986cc9d71b7f256874f79b119f97a4c89453f5
|
||||
F Makefile.msc a889c6981a222d639f8a548adcfb3183ac07871e27452ace4d810735750f216a
|
||||
F README.md 377233394b905d3b2e2b33741289e093bc93f2e7adbe00923b2c5958c9a9edee
|
||||
F VERSION 654da1d4053fb09ffc33a3910e6d427182a7dcdc67e934fa83de2849ac83fccb
|
||||
F VERSION 8d89a0e3dbf2fe06a028ad03f03d38e30295290cf2ef425a877547b193acaa58
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
@@ -33,7 +33,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 5811ffcd4866902d1706dcf8e0527f89165ec52859659942c9649bb1d3e4cc7b x
|
||||
F configure 6876c95d54c96d8675f0e39838b6b557eb5fc7ce619ba014e31e0e261dff1f25 x
|
||||
F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
@@ -80,7 +80,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 012384f01df28345a8d0d0c7fe465ab211598a91d78a7331b3664533756ed9fa
|
||||
F ext/fts3/fts3.c 53020b61dac31c167668f098ec83c0387ecd65b9e89ba3659f2f8d3e76efdf1e
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 3378157f383540857a466420b8279626204434c3eb0dc948ad9bcd3991fc41f5
|
||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||
@@ -98,7 +98,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 525a3bd9a7564603c5c061b7de55403a565307758a94600e8a2f6b00d1c40d9d
|
||||
F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75b9cf966029c
|
||||
F ext/fts3/fts3_write.c a85bc4885fde7f1b44c9de013b62f7cd3332dc59e208053d878729b1d04745bc
|
||||
F ext/fts3/fts3_write.c b583dede85eb0c3c3026f8d7ccb781ea4e845ae583754fecb2ca425b5907d87d
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
@@ -281,12 +281,10 @@ F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f0
|
||||
F ext/misc/csv.c 65297bcce8d5acd5aadef42acbe739aef5a2ef5e74c7b73361ca19f3e21de657
|
||||
F ext/misc/dbdump.c 12389a10c410fadf1e68eeb382def92d5a7fa9ce7cce4fb86a736fa2bac1000a
|
||||
F ext/misc/eval.c 6ea9b22a5fa0dd973b67ca4e53555be177bc0b7b263aadf1024429457c82c0e3
|
||||
F ext/misc/explain.c 5851a1a4a1bba6e078da4103fcafc84aa54adfd8edbba419f5cf1eba9f000d50
|
||||
F ext/misc/fileio.c 7317d825fab6a3c48f6e3822a00a6a22e08e55af31700ac96f16a523f83069fd
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c 276f87dc8365b34b0fffb7ef32481dd07fac6fdb3224e2822396a48377ac8363
|
||||
F ext/misc/memstat.c 7542ff1dd1d926e63dab904070e689cd5b47e4dd19498ad31947c42b207f5363
|
||||
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
|
||||
F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
@@ -297,10 +295,10 @@ F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6
|
||||
F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77
|
||||
F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad
|
||||
F ext/misc/series.c c7197db304f7009b08d6459a9de02e7f51ad0e1a3fdacbc1ebf5252a9a346959
|
||||
F ext/misc/sha1.c df0a667211baa2c0612d8486acbf6331b9f8633fd4d605c17c7cccd26d59c6bd
|
||||
F ext/misc/shathree.c 22ba7ca84a433d6466a7d05dcc876910b435a715da8cc462517db9351412b8c8
|
||||
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
|
||||
F ext/misc/shathree.c 9e960ba50483214c6a7a4b1517f8d8cef799e9db381195178c3fd3ad207e10c0
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0f5e484
|
||||
F ext/misc/spellfix.c 54d650f44f3a69a851814791bd4d304575cdbbf78d96d4f0801b44a8f31a58c5
|
||||
F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74
|
||||
F ext/misc/stmt.c 6f16443abb3551e3f5813bb13ba19a30e7032830015b0f92fe0c0453045c0a11
|
||||
F ext/misc/templatevtab.c 8251b31011dd00fc38e739c78c234c930be42b3b274bbe0493b79cd40db02a9e
|
||||
@@ -348,7 +346,7 @@ F ext/rbu/rbusplit.test 69271c790732b28bd465551d80b0a9a3f074e189896ee8490ce56d22
|
||||
F ext/rbu/rbutemplimit.test cd553a9288d515d0b5f87d277e76fd18c4aa740b761e7880fab11ce986ea18d1
|
||||
F ext/rbu/rbuvacuum.test ff357e9b556ca7ad4673da0ff7f244def919ff858e0f9f350d3e30fdd83a62a8
|
||||
F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
|
||||
F ext/rbu/sqlite3rbu.c 71f8c09948d09ec9c5a8dbe7127e8ef61ef0853e698b2650be2485ac7b9c75c8
|
||||
F ext/rbu/sqlite3rbu.c f438fea899d15d13ff3e3133242b9e378c37b5a3d76add8c342c68bdd65c6819
|
||||
F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
|
||||
F ext/rbu/test_rbu.c baa23eb28457580673d2175e5f0c29ced0cd320ee819b13ad362398c53b96e90
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
@@ -361,7 +359,7 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
|
||||
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/geopoly.c 2464b3325fcc2878ed08458efeb995f830f4eef28bbf3da9757c4bd95e6f9549
|
||||
F ext/rtree/geopoly.c 415a8ca5dfab54eea779e0bf31a859afb0b869a5147a726df4aec4b57c1bad57
|
||||
F ext/rtree/rtree.c 6cc2e673cf1e9ea1619f13ab990f12389dfb951b131acbc2fbe164cee8992a20
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349
|
||||
@@ -389,11 +387,9 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1d2f94ac66
|
||||
F ext/rtree/visual01.txt 17c3afefc208c375607aa82242e97fa79c316e539bcd0b7b3e59344c69445d05
|
||||
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
F ext/session/changesetfuzz.c 255826ee367781ec4c29a36c7c63e9ee6387dc03a8346cf240feb8d597958b0e
|
||||
F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a
|
||||
F ext/session/session1.test 0b2f88995832ea040ae8e83a1ad4afa99c00b85c779d213da73a95ea4113233e
|
||||
F ext/session/session1.test 4532116484f525110eb4cfff7030c59354c0cde9def4d109466b0df2b35ad5cc
|
||||
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
|
||||
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
|
||||
F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40
|
||||
@@ -409,26 +405,25 @@ F ext/session/sessionE.test 0a616c4ad8fd2c05f23217ebb6212ef80b7fef30f5f086a6633a
|
||||
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
||||
F ext/session/sessionG.test 3edde849c4071078d92bd682c836186f6e4e5a3fb6bcf3fc1de1a7caa5e4427d
|
||||
F ext/session/sessionH.test 332b60e4c2e0a680105e11936201cabe378216f307e2747803cea56fa7d9ebae
|
||||
F ext/session/session_common.tcl 29ec9910aca1e996ca1c8531b8cecabf96eb576aa53de65a8ff03d848b9a2a8b
|
||||
F ext/session/session_common.tcl ee925e0d233677e45e395fb1f559b84068ce7baa8aa1034441739d3e87ee249c
|
||||
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
|
||||
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
|
||||
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
|
||||
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test 555a8504de03d59b369ef20209585da5aeb2671dedabc4584e9ffe6269689185
|
||||
F ext/session/sessioninvert.test ae1a003a9ab1f8d64227dbb5c3a4c97e65b561b01e7b2953cf48683fb2724169
|
||||
F ext/session/sessionrebase.test 4e1bcfd26fd8ed8ac571746f56cceeb45184f4d65490ea0d405227cfc8a9cba8
|
||||
F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e
|
||||
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
|
||||
F ext/session/sqlite3session.c dbd6f7a89c1236d8e7b58f4e217391670ce91b9e6f85c16ba02832674ef0cf3c
|
||||
F ext/session/sqlite3session.h 05351d2f50a1203fdffbeb590fdbbc796c9a6bfcd0c9b26cf6db3854e3eb4294
|
||||
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
|
||||
F ext/session/sqlite3session.c 2d29bbd888599b94b2c8b31ff433675e008273a4d225b336508b18e6187fec1d
|
||||
F ext/session/sqlite3session.h c01820d5b6e73e86d88008f4d1c1c7dfb83422963018292b864028a0400ceccf
|
||||
F ext/session/test_session.c dba36c6c0153b22501112d3e8882b5c946cf617c955153b6712bd2f8ba1428c0
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e629edbe2648
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk ddb6616776c53dfc06bb3f8396df8721c8b699294271fd0c3d110dd278d9c723
|
||||
F main.mk 1db6df4bff24ed6684917e3fe311ce28f5924d6417c698fe4326f7cadf02df31
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -440,37 +435,37 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 61c1ace40a9e39c45a975cb6c57a1a283a262ea21bbe3fb5b473708b790a8d43
|
||||
F src/alter.c 70dd115eb1f949f69f61773733dc89d6494915ec6a736f259c7a7de4aeb51726
|
||||
F src/analyze.c 3dc6b98cf007b005af89df165c966baaa48e8124f38c87b4d2b276fe7f0b9eb9
|
||||
F src/attach.c 4bd5b92633671d3e8ce431153ebb1893b50335818423b5373f3f27969f79769a
|
||||
F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
|
||||
F src/auth.c 32a5bbe3b755169ab6c66311c5225a3cd4f75a46c041f7fb117e0cbb68055114
|
||||
F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 3ef104ecae8b1b5f0458be1f5fa7c1ecf25fdc322a9d63bb8151f89eb32d381e
|
||||
F src/btree.c 3f5e1a03db871e627bf5da21092bf7434ecfc5c5980bbd7d45eba13341340173
|
||||
F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
|
||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||
F src/build.c a614b226b9af1e49ec6d0ffbf3aa0d38a73123336a7f78930005db939d038253
|
||||
F src/callback.c 789bd33d188146f66c0dd8306472a72d1c05f71924b24a91caf6bd45cf9aba73
|
||||
F src/build.c 0b3d422770877d74ee6d54f4c122d82c48f7d04ee3bfb91702e402de7f5c45ac
|
||||
F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
|
||||
F src/ctime.c b157b01081f92442f8b0218ddb93ddce8ebddad36dbddeecfdd771561dd4f387
|
||||
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c ada9bc6964bb68e4c128df70cb0938faaa214e1a0e1d730ea6b13c5e1fde9a45
|
||||
F src/dbstat.c e042b0e7833fdacf2d5ea92c6b536962fea6aeed8b7287ca87ddfa3412bd9564
|
||||
F src/delete.c e1ac11c062a4a2ed29a9e9a63f4cbc7f0330291ae276d768b26fb2c5152cc3b4
|
||||
F src/expr.c 9aacc0b72348ba90010b672dcbbbe2fa56e1182043bc917a3a147b2bc57a5497
|
||||
F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3
|
||||
F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
|
||||
F src/delete.c 107e28d3ef8bd72fd11953374ca9107cd74e8b09c3ded076a6048742d26ce7d2
|
||||
F src/expr.c d8da79a5cb19bbded56181337a221ead5f4ad3cbf0fbcb5da2156abefab566cd
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 972a4ba14296bef2303a0abbad1e3d82bc3c61f9e6ce4e8e9528bdee68748812
|
||||
F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a
|
||||
F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f
|
||||
F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128
|
||||
F src/hash.c 931ec82d7e070654a8facb42549bbb3a25720171d73ba94c3d3160580d01ef1f
|
||||
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 6b81aae27b196925d8ff78824f4bbd435d6a40cd38dc324685e21735bb402109
|
||||
F src/insert.c c723716f0de7aa0a679300f7d3541c89645f4a9882161cecdb3093fc07f8cc4b
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c 448eab53ecdb566a1259ee2d45ebff9c0bc4a2cf393774488775c33e4fbe89bf
|
||||
F src/main.c 03204aa22720654f0bc128b6d25626a89f9faca17e10ffdf738036d5453b13b3
|
||||
F src/loadext.c 30b140d0e5031924c56f802760506c0a235ced0dff9f3d95119aa86df12856e2
|
||||
F src/main.c 6275ece0699a957c4709a7ebe29476f132adbe459d18a6b497e234e4669abf91
|
||||
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@@ -490,33 +485,33 @@ F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c f6e91b8fd82af7afbfd073c4974ad6cdb8e62d9f65ceddb45167835a0567fdc0
|
||||
F src/os_unix.c 7cfd67db0e2f926243f646db7ec1caa33ca9bee45799b0160ddfcd6ccfc175d2
|
||||
F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c f803ffcd8440b5249549ea103158a1c659bf060961b2389f9fede66a3a352d0b
|
||||
F src/pager.c a0d8f686ef64549ad5b356fd30429bd9ee7a06dd42b4d6faa096352ff26b1c5b
|
||||
F src/pager.h ecc554a55bc55d1c4ba5e17137b72e238e00bd81e72ff2662d8b9c8c10ae3963
|
||||
F src/parse.y 6840fe7c0b5eb4dd25ee5d075213bc8255ed4c0678d71bfb6744d0520d91c179
|
||||
F src/pcache.c 4196eb6ed3bbf00b80596c8e0b4f50e57eb7d890c19fb27a7354306abb7f983d
|
||||
F src/parse.y 4118dbf9c37c410e5c4775c033b1aaf67ac8ff7965df7a4bb429dd5db2dbe374
|
||||
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
|
||||
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
|
||||
F src/pragma.c 0bb05b1788d7af5fdc7f40f5655a79a140dece8fd2523402eb2103925e4739c2
|
||||
F src/pragma.h fdd03d78a7497f74a3f652909f945328480089189526841ae829ce7313d98d13
|
||||
F src/prepare.c f81f8d707e583192c28fea0b2e19385415b7d188123b23f49b038076408d7a69
|
||||
F src/pragma.c 79abc65c08d2754048efee3ba99fe91863dfeab0ba699a4439fa5053ec87cf36
|
||||
F src/pragma.h fb46b1e663128f6827979ad8ebddb55be2a0276ea923c47adeac02144207a682
|
||||
F src/prepare.c f8e260d940a0e08494c0f30744521b2f832d7263eca9d02b050cea0ba144b097
|
||||
F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c bc8c79e56439b111e7d9415e44940951f7087e9466c3a9d664558ef0faf31073
|
||||
F src/resolve.c 352c6af1a99441206ff62a6f7429dbf537827f42c428639695220b9c8639e33b
|
||||
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
|
||||
F src/select.c 61e867a906f140b73baf4ce7a201ad6dcba30820969f5618ee40e9a0d32c6f5f
|
||||
F src/shell.c.in 060ccc327959bdc85c895015eb382017fd0cd000ebd47b7e8dda42f8aab0b66f
|
||||
F src/sqlite.h.in 1383b2fbce61bd3634caeafb2513205326a297e988ea749d4f6dec7da7a281c9
|
||||
F src/select.c 8afcc2b56a6ef76717bb59b6109cd3de0f6fae2803894d6f806640c0aa24dfac
|
||||
F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1f
|
||||
F src/sqlite.h.in 4b4c2f2daeeed4412ba9d81bc78092c69831fe6eda4f0ae5bf951da51a8dccec
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
|
||||
F src/sqliteInt.h cad10b3a482bd5b11f586df9877ff5f637ce14534291a438430d1f1a2b882296
|
||||
F src/sqlite3ext.h 305adca1b5da4a33ce2db5bd236935768e951d5651bfe5560ed55cfcdbce6a63
|
||||
F src/sqliteInt.h 10d7835f2a1ae736a468c38a413b754933051fc97255aa2f4ac2df2ad349e863
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c e72862a271348d779672b45a730c33fd0c535e630ff927e8ce4a0c908d1d28c6
|
||||
F src/test1.c b95363b0bc9e1ecc61964ca5a22c137422af4808a54a7bbb1a4f7d6d6257f704
|
||||
F src/test1.c 31c491ccb536bd9916a084e732ffe783b3c8973f2586d5a56aed0e3a9701dfff
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
@@ -531,7 +526,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
|
||||
F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
|
||||
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c 5ebafbcd5c75ac1c16bb0c8fe926dc325cc03e780943a88ca50e0d9a4fc4d2f5
|
||||
F src/test_config.c 6c3f341ece48020c4ddbce055643a91c653283b3a6853c46ea18d22e5c72847d
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e
|
||||
F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2
|
||||
@@ -539,8 +534,8 @@ F src/test_fs.c 35a2f7dd8a915900873386331386d9ba1ae1b5026d74fd20c2807bc76221f291
|
||||
F src/test_func.c d12d805953bcb3bb19f71d29cdc93383b7b7a3369504d2b7e398a1bd77376294
|
||||
F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d
|
||||
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
|
||||
F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71
|
||||
F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7
|
||||
F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
|
||||
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
|
||||
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242
|
||||
@@ -548,7 +543,7 @@ F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8
|
||||
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
|
||||
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
||||
F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a
|
||||
F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4
|
||||
F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f
|
||||
F src/test_osinst.c 98ef31ff03d55497829ca0f6c74a9f4e1aa48690
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 6cb9297115b551f433a9ad1741817a9831abed99
|
||||
@@ -569,33 +564,33 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 9e781e1ca80eefe7b5d6a9e2cd5c678c847da55fd6f093781fad7950934d4c83
|
||||
F src/treeview.c 7b12ac059de54c939b6eb0dbffc9410c29c80d2470cee5cbe07d5ff9ea2d9253
|
||||
F src/tokenize.c 9f55961518f77793edd56eee860ecf035d4370ebbb0726ad2f6cada6637fd16b
|
||||
F src/treeview.c e7a7f90552bb418533cdd0309b5eb71d4effa50165b880fc8c2001e613577e5f
|
||||
F src/trigger.c d3d78568f37fb2e6cdcc2d1e7b60156f15b0b600adec55b83c5d42f6cad250bd
|
||||
F src/update.c 1816d56c1bca1ba4e0ef98cac2f49be62858e9df1dc08844c7067eb41cc44274
|
||||
F src/update.c 345ce35eb1332eb4829857aa8b1f65a614b07dae91d0346c0dc2baacafbcc51b
|
||||
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
|
||||
F src/vdbe.c 005e691ea4c7d51e6c1a69d9389aeb34700884c85f51681817ddea3fdc2fc39b
|
||||
F src/vdbe.c 7433ac76608b80b745f57b8544416dc0178db52ce2cc806a10353309e5f781fb
|
||||
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
|
||||
F src/vdbeInt.h 8a52b8db3d20f9755a965d864b8653052c7ef1ccadceb2e057047cd421f6336e
|
||||
F src/vdbeapi.c ecccfce6f614c33a95952efeec969d163e8349eac314ee2b7b163eda921b5eb0
|
||||
F src/vdbeaux.c f547901b1aa9e2d81c63f06893f633648e434180666a827aacb547d7d6c8a601
|
||||
F src/vdbeInt.h f1f35f70460698d8f5a2bdef1001114babf318e2983a067804e2ae077d8e9827
|
||||
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
|
||||
F src/vdbeaux.c c3c397274380f13db702baa3506ba87379446a4d71135a1177b624f73dd3c830
|
||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||
F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9
|
||||
F src/vdbemem.c 81329ab760e4ec0162119d9cd10193e0303c45c5935bb20c7ae9139d44dd6641
|
||||
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
|
||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||
F src/vtab.c 70188a745dc4e57d26e942681ff4b2912b7c8249ad5de3f60f0677b4337bcfaa
|
||||
F src/vtab.c 8665561f244c137a2d17b5c3e5910d7303054fe841c5d510e53f23beb0089594
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f
|
||||
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c fb94aadc9099ff9c6506d0a8b88d51266005bcaa265403f3d7caf732a562eb66
|
||||
F src/where.c f5da1079f084c569aa70fd4ada6b7e45b356e19708f1e5307493cc65857ec9e4
|
||||
F src/whereInt.h f125f29fca80890768e0b2caa14f95db74b2dacd3a122a168f97aa7b64d6968f
|
||||
F src/wherecode.c c45f03aefc2266b990df0fc4d7acc4e27f56f881f4fc0fc355b7cbc4d7189da5
|
||||
F src/whereexpr.c 491f0894ad9903750cdecb7894437a0cabdffdd88f574d2b1c9ac85d14fe4b9c
|
||||
F src/window.c 6550e2850ebced51100ef83d49b00a1cf03f81a482dafedafb0320df647ed8fc
|
||||
F src/walker.c ba7225773931760cf60bf22f34d0cce2588df7ce5ce0f215a52eb88234b55ac4
|
||||
F src/where.c 2019126801437944c38cc62a99491e98591460b7cc07ab57eb66165f710a289b
|
||||
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
|
||||
F src/wherecode.c 4f88f5b39ad4aeb5bdd47a546d74149bb902ef49ca9f02a45b2a5bd2dd70b6bd
|
||||
F src/whereexpr.c eb462ebe085f6cbb6bdda797a041fbd7e3724586203344043d1088a2117d8e44
|
||||
F src/window.c 4b503da928dace3e845b891381a4d98eeb8c5744313ae3643df8d8d21fdcca65
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -608,13 +603,12 @@ F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
|
||||
F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3
|
||||
F test/alter4.test 7e93a21fe131e1dfeb317e90056856f96b10381fc7fe3a05e765569a23400433
|
||||
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
|
||||
F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499
|
||||
F test/altercol.test 53fb5e218c9296afc160f2c4fcbeaf42bd0604815d9b3896a7d2eec583ad8704
|
||||
F test/alterlegacy.test e7c07d605c2a85e7d1696c89e6bf64dfc932fc6d9320fe8708c8f5fc0b524d41
|
||||
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
|
||||
F test/altertab.test fb8a9a2ab6deb5f860d27675f6213d14ab79b705e0d6350eead4ef3a3f73bf3e
|
||||
F test/altertab2.test 7b3f4a6ca0dd833b75b889477a3e291e2799b4af25db908fe6930e39a353b1eb
|
||||
F test/altertab.test 3b830144c18ae00abd2a27e3d2851c8bb1ee8fe655fa16d8a5971066dc71b58a
|
||||
F test/altertab2.test 159fd5f7b23ddc841fe678f579f9b1b8e69f44296f3ff75d1b4c155d37a59832
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df
|
||||
F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8
|
||||
@@ -640,11 +634,11 @@ F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd
|
||||
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
|
||||
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
|
||||
F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed
|
||||
F test/attach.test dff436fd94d4c7ffd7f0a8831d50193595f3b94a9428b3ddd41d24b897bae729
|
||||
F test/attach.test f4b8918ba2f3e88e6883b8452340545f10a1388af808343c37fc5c577be8281c
|
||||
F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce
|
||||
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attachmalloc.test 12c4f028e570acf9e0a4b0b7fe6f536e21f3d5ebddcece423603d0569beaf438
|
||||
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test 3310d9c08e928beca42d3eadaaf53cef619d9d275f598565a3758a21ce63138e
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
|
||||
@@ -654,7 +648,7 @@ F test/autoindex1.test a09958fa756129af10b6582bcbf3cbdf11e305e027b393f393caef801
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autoindex5.test 4a0eb6c7c7ae456d97a2061d4c8d6380946272c5c91d91507c1feb1af3dc7cce
|
||||
F test/autoindex5.test 5f0135dc3b266277b8c1904624439097d8e8020dd7197eda13fda23c35c21a05
|
||||
F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
|
||||
@@ -671,7 +665,7 @@ F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
|
||||
F test/bestindex1.test 852170bddbb21daa121fabcc274640ff83d7d8705912e8b5fe7ed2c5a9a9224a
|
||||
F test/bestindex2.test 9a0ccd320b6525eec3a706aae6cdab7e1b7b5abca75027e39f39f755e76e5928
|
||||
F test/bestindex3.test 001788a114ad96d81d5154fe77c7f1e26e84b3a2b5635ca29e4f96f6decc534e
|
||||
F test/bestindex4.test 210eac9323ef88881212d6ae90c84dad86ec14d82c6f4fc9a9ee24c76a8f2014
|
||||
F test/bestindex4.test 4cb5ff7dbaebadb87d366f51969271778423b455
|
||||
F test/bestindex5.test 412b42f8036b28d8b2f3534d89389ad946a4b1a65a12263f51936f7424296f1b
|
||||
F test/bestindex6.test d856a9bb63d927493575823eed44053bc36251e241aa364e54d0f2a2d302e1d4
|
||||
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
@@ -700,9 +694,9 @@ F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9
|
||||
F test/capi2.test 34a1a9a96d543a2ec2c209696b11b164444f57253b1f2cba1c2e53fadede6c7b
|
||||
F test/capi3.test b299c89d80891c6c9b7f0e4b199df002b8b9f11c19f07d4a6eb7b325f1244de0
|
||||
F test/capi3.test 36f5c859c91a9bb0075d6ddcfcf2476cad629b09f7bfd135776fb94b06c04706
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test e853c6c1f9a596e0bc58153be08706813bf5795d479d6f81581e3bda3f9d0909
|
||||
F test/capi3c.test 7ebed1d8fa2f3190149d556fe8cff5a006be62af437c5c4640db614470126098
|
||||
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 5ceb920718d280b61163500a7d29e0e0a86458b1cbd92d96f962c9d970aa3857
|
||||
@@ -756,7 +750,7 @@ F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
|
||||
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
|
||||
F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
|
||||
F test/crash5.test f14ff37eddc41991be4eb63568f86caa306fd9962a0ae3750db8836777bb7aae
|
||||
F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219
|
||||
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
|
||||
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
|
||||
F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100
|
||||
@@ -772,10 +766,8 @@ F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
|
||||
F test/dbfuzz2.c 652f85bac1770e927da139db513234a3eba308f72ac2f8b32f0093d7d19def70
|
||||
F test/dbpage.test dbf50a4d361f9e45a979432c727506065113124478a7d2db12074fa655e65d6c
|
||||
F test/dbstatus.test cd83aa623b8aab477269bc94cf8aa90c1e195a144561dd04a1620770aaa8524e
|
||||
F test/dbstatus.test c15fa97f743dac7ce996814c84b56317e138895ee15ce27f15b608aa6924c90a
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0
|
||||
@@ -907,7 +899,6 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
|
||||
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
|
||||
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
|
||||
F test/fts3corrupt3.test 56e0ee83e90b57f5f3644cb7d1b36a067b7b8b19cdf0dedce45e5e13cf752f65
|
||||
F test/fts3corrupt4.test 98022cbacbd6ddc4708f210768f5684f041f50ce330c461f2631752492611d96
|
||||
F test/fts3cov.test 9c3681325b9a850bca8dd75cc29dde73e9a87972bb75204e97d826f13c7181f9
|
||||
F test/fts3d.test d3e9c8fb75135ada06bf3bab4f9666224965d708
|
||||
F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
|
||||
@@ -969,7 +960,7 @@ F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
|
||||
F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzz_malloc.test 5b257a7652d8ee90b22e9cf80d9dbea31a4f3e6fed1d33de57b24b1bdb211d79
|
||||
F test/fuzzcheck.c 8074a35ed4ec3735a5e144b7e0e9123d9821a92281756c1a40d43e302dd79243
|
||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
@@ -977,7 +968,6 @@ F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db 829cbab68b8fa5223405f4bf0d4775b05391a8ff670790d09154a56dd22a8d1e
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
@@ -1001,14 +991,14 @@ F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba
|
||||
F test/incrblob_err.test 89372a28f1d98254f03fed705f9efcd34ef61a674df16d2dbb4726944a2de5e9
|
||||
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
|
||||
F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758
|
||||
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
||||
F test/incrvacuum.test b729aab1d4983037da57e66c20dfd7458561a85626dcf824f60175e35f4ce152
|
||||
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
|
||||
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test 5131c0106a6d0c892c5f438f0630e1b4361370c393ba8a000dd0dcaa2b3bf1de
|
||||
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
|
||||
F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
@@ -1019,7 +1009,7 @@ F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
|
||||
F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e
|
||||
F test/indexexpr2.test d8f56b6cf4e5663486129bc18c6bde4cef9f8876942b001bfdd692a2b1a42668
|
||||
F test/indexexpr2.test 08551aa8956a91582979e17b6d369f321a5cb6ed6d3e952925a3e54e9e7de216
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 5604b1ff5675cc84c34a5b315792b958f48c32edccc0dafcc81d3b776270b70a
|
||||
@@ -1029,7 +1019,7 @@ F test/insert4.test 46bead5f39e181850ee56adcf49d3a3157c460c52249211714612ac89fe3
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
|
||||
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
|
||||
F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c53fb7
|
||||
F test/intarray.test 46d95b457916638c5d8b1af21fb174804b3acf8b
|
||||
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
|
||||
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
|
||||
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
|
||||
@@ -1063,7 +1053,7 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/like3.test 430691e6057e11a59e934be74c06b85605b80061d45af5714d52886a811efeb7
|
||||
F test/like3.test cf0ff2d06c9d8456283aeff405b911642298441206306aeaeaa93973233b1195
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
|
||||
F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9
|
||||
@@ -1102,7 +1092,6 @@ F test/mallocK.test 1f4b5efbf61715ab79b20b38739ff4b3d110ceb53f54e5db6da1f01c0837
|
||||
F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc
|
||||
F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134
|
||||
F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
|
||||
F test/malloctraceviewer.tcl b7a54595270c1d201abf1c3f3d461f27eaf24cdef623ad08a0fe5e411264c8a9
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
|
||||
@@ -1139,7 +1128,7 @@ F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
||||
F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1
|
||||
F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a
|
||||
F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e
|
||||
F test/normalize.test 6a80564d2000702b5919ed2c1069fef0f95762142bc96a71b4c124a845165713
|
||||
F test/normalize.test 1dedf653ca33b0b55fd0c7967d2861a51f1801a7aa899a02d4c0d7adfcd5acdc
|
||||
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
|
||||
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
@@ -1178,15 +1167,15 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test cf0b4e498db1d0143c19641d4420df7cc27fab2c95ed0abd2c7c5753beab25b8
|
||||
F test/permutations.test fdcb2d733fc21396e0300206023795463ba0d0ee5eda2042863b044933391da3
|
||||
F test/pg_common.tcl 301ac19c1a52fd55166d26db929b3b89165c634d52b5f8ad76ea8cb06960db30
|
||||
F test/pragma.test 7c8cfc328a1717a95663cf8edb06c52ddfeaf97bb0aee69ae7457132e8d39e7d
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
|
||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||
F test/pragma4.test 3046501bee2f652dc2a4f9c87781e2741361d6864439c8381aba6c3b774b335c
|
||||
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/printf.test a3e559bc9d922e7fe44e9d05c6965fee34fe3bc28300a4248c6a063425246ffd
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test 30b5dd0b4b992dc5626496846ecce17ff592cacbcb11c3e589f3ac4d7e129dae
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
@@ -1213,7 +1202,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
|
||||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
|
||||
F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51
|
||||
F test/rowvalue.test ef851a80f7e6de93b51caca9e4b6b7d2dcd540bbcca7d51860e80435b8b4c0de
|
||||
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
|
||||
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
|
||||
F test/rowvalue4.test 2b20468da3775aba971caf3158e9696a4d99c69a7623fb495f332a596daebbee
|
||||
@@ -1262,7 +1251,7 @@ F test/server1.test c2b00864514a68a0e6fd518659dc95d0050307a357a08969872bef027d78
|
||||
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
|
||||
F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb
|
||||
F test/sessionfuzz.c b0fcdcf757451957e17396a3af5171f1fdf9b2babc81da9fa35675df46c4729a
|
||||
F test/shared.test 1826673eb5eb745fb91a3bdac99a7737057742ae38dcb0fe076a384d6727578b
|
||||
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38
|
||||
F test/shared4.test c75f476804e76e26bf6fa0e7b421fb0ca7d07558
|
||||
@@ -1274,7 +1263,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test d2bf5daeb6f449f0169c9ef3094db17a16a02199c5dcf1a635a3e79b07eb0edd
|
||||
F test/shell1.test 707c03fbd07ac506cfb6fa09da4ee22e2b50453c3db2f404694116eb990168f3
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
@@ -1342,9 +1331,9 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309
|
||||
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
|
||||
F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test 54300134f76db817685194d2f0e63e3fbf7380b45e0d426e00a9aee752497cfb
|
||||
F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b969a51
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test dca8aa30d84175e7d8c8fc43d3ffa11fa56e23fbdac2679d03833a0f326edf34
|
||||
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
|
||||
@@ -1354,7 +1343,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl fa5656391e3b477508abe12b3b81f019b2e71397399ab38a2f32d8d7f3bf8e56
|
||||
F test/tester.tcl d5138d226cc2aaacb6934cdd79acaa5edd17cad862482895b833bbf62c49aca0
|
||||
F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1527,7 +1516,7 @@ F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
|
||||
F test/trigger7.test 93cfa9b48ab9104b2b3d87bc544ac8021405643e36f23ee84635fbfaf9b8fef5
|
||||
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
|
||||
F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d3650e9d
|
||||
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
|
||||
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
|
||||
F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092
|
||||
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
|
||||
@@ -1587,7 +1576,7 @@ F test/vtabH.test 3cf9aa1c1c4381b3b3ac33f933376f06fbb99d2294a83c79b7562d3ed87be4
|
||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f
|
||||
F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
|
||||
F test/vtab_err.test 1c476cac24c9c730f83cd7c8bf66482a30151be08d36a2283f87fc38a2dacbb1
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
|
||||
F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
|
||||
F test/wal2.test 155b9efa999bdb38ce1cd729b9a4fcdbffd6b88be27f039bad1d2929d287d918
|
||||
@@ -1595,7 +1584,7 @@ F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9
|
||||
F test/wal6.test b602704e4b066199bc89d91ca9000f335dcf4572
|
||||
F test/wal64k.test 2a525c0f45d709bae3765c71045ccec5df7d100ccbd3a7860fdba46c9addb965
|
||||
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8
|
||||
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
||||
@@ -1622,7 +1611,7 @@ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cf
|
||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
F test/where.test 8215d220633f08da331781cf9ede7fb7aed50eb113473c10acd39a643fd258ba
|
||||
F test/where.test 480cfc1758ac9df3f70c6a2541ff586f6a4833354d5ecb548f643e30e31fddc8
|
||||
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
|
||||
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
@@ -1642,7 +1631,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test b7769ee8dbefd987fb266715fee887f05f9ff180016b06fca7fa402df739193b
|
||||
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
|
||||
F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b
|
||||
F test/whereL.test 0a19fc44cd1122040f56c934f1b14d0ca85bde28f270268a428dd9796ea0634c
|
||||
F test/whereL.test 84de61afe4b8e5a3ff7d741c990d85cb44b3ce798cd8412d5603930f3f75014f
|
||||
F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864
|
||||
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
|
||||
F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0
|
||||
@@ -1652,7 +1641,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/window1.test 02e481ac48c445b43bab7b3cf1e4115165b5127a1aa29e14f5372922c836f1a4
|
||||
F test/window1.test 474bef1a6ac291755e51d1f9458dc11117c1870ac5e08b4d3938649b215f8334
|
||||
F test/window2.tcl 9bfa842d8a62b0d36dc8c1b5972206393c43847433c6d75940b87fec93ce3143
|
||||
F test/window2.test 8e6d2a1b9f54dfebee1cde961c8590cd87b4db45c50f44947a211e1b63c2a05e
|
||||
F test/window3.tcl 577a3b1ff913208e5248c04dab9df17fd760ce159a752789e26d0cb4a5f91823
|
||||
@@ -1660,9 +1649,9 @@ F test/window3.test e274b7f8952ca4ed25996e0e45c047192b066e0aaff2a822d4293c8c4f1d
|
||||
F test/window4.tcl 511425f6b0abf9b953df54cc9c7295cc7c25d78f4ed6f7a74b094eec0120eccb
|
||||
F test/window4.test c5d6bf3403e4ade2f19df2afe4c16f29fb817c392c6c1c8017edb7165c191a62
|
||||
F test/window5.test 8187f46597c90b73e8f96659e893353cbda337479cc582f7a488eab351ba08d3
|
||||
F test/window6.test 5eae4ae7a590ccf1e605880969ca0bad3955616ac91cad3031baea38748badb3
|
||||
F test/window6.test 7574778c79cae89f1781df237bf9ff5063886deca91a36efc53934315f0e7612
|
||||
F test/windowfault.test 23abad97b72c6f609002255ddd41ef5c8922408f918f9b98ad6005ab316e482f
|
||||
F test/with1.test 2465d98ffce80d00553ac7135697c18b0369275b6ecc750daa2af320b8c812ca
|
||||
F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
@@ -1711,7 +1700,7 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl a1334e70a08fdf5de32cd0093613212bb11ac8f880487540987175c536ac335f
|
||||
F tool/mkpragmatab.tcl 8b9b448b5eb7222d4e3f7afb3c678596784180d319eb4e01c842887ed8213b85
|
||||
F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
|
||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
@@ -1743,7 +1732,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c
|
||||
F tool/sqldiff.c 7b9b7238284f02131dbb8f21a4e862409bff728045c5473139d28c67ac87580e
|
||||
F tool/sqldiff.c 579d7e4e42c30a963781654c87d2868823120b55d59e16ca77b0edbab0218713
|
||||
F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968
|
||||
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
|
||||
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
|
||||
@@ -1778,7 +1767,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 09b90db56c2d5e3aceae59c6bf1eb07f9db9ef38da29d2162046b88d39e47b86 a8d65214a567eb1afd703ee4d09d398247e060a610b46097a726364db2861001
|
||||
R 3aab479e5526baa65c5716bd2f30b798
|
||||
U dan
|
||||
Z abcba01d465aa5012c21006dab111180
|
||||
P 32ac0014266706baa4e98de808eb5a6d0ffdb39dc37b4e37668f339e9e238183
|
||||
R ddde28c6e30330f60d15473895b4b263
|
||||
T +bgcolor * #d0c0ff
|
||||
T +sym-release *
|
||||
T +sym-version-3.25.2 *
|
||||
U drh
|
||||
Z 46b344691181d24f6c0596b245d11075
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
b6d549c988e765789c4a81d586170451db9f5da1973dde8aa0329445f915fbb2
|
||||
fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7
|
||||
+5
-10
@@ -803,7 +803,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
|
||||
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
|
||||
}else if( pExpr->op==TK_COLUMN
|
||||
&& pExpr->iColumn==p->iCol
|
||||
&& p->pTab==pExpr->y.pTab
|
||||
&& p->pTab==pExpr->pTab
|
||||
){
|
||||
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
|
||||
}
|
||||
@@ -1061,14 +1061,9 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
|
||||
db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
|
||||
);
|
||||
pParse->eTriggerOp = pNew->op;
|
||||
/* ALWAYS() because if the table of the trigger does not exist, the
|
||||
** error would have been hit before this point */
|
||||
if( ALWAYS(pParse->pTriggerTab) ){
|
||||
rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
|
||||
}
|
||||
|
||||
/* Resolve symbols in WHEN clause */
|
||||
if( rc==SQLITE_OK && pNew->pWhen ){
|
||||
if( pNew->pWhen ){
|
||||
rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
|
||||
}
|
||||
|
||||
@@ -1346,8 +1341,8 @@ renameColumnFunc_done:
|
||||
*/
|
||||
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
|
||||
RenameCtx *p = pWalker->u.pRename;
|
||||
if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
|
||||
renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
|
||||
if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
|
||||
renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -1444,7 +1439,7 @@ static void renameTableFunc(
|
||||
}else{
|
||||
/* Modify any FK definitions to point to the new table. */
|
||||
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
||||
if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
|
||||
if( db->flags & SQLITE_ForeignKeys ){
|
||||
FKey *pFKey;
|
||||
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
|
||||
if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
|
||||
|
||||
@@ -151,7 +151,6 @@ void sqlite3AuthRead(
|
||||
int iCol; /* Index of column in table */
|
||||
|
||||
assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
|
||||
assert( !IN_RENAME_OBJECT || db->xAuth==0 );
|
||||
if( db->xAuth==0 ) return;
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
|
||||
if( iDb<0 ){
|
||||
@@ -208,7 +207,6 @@ int sqlite3AuthCheck(
|
||||
/* Don't do any authorization checks if the database is initialising
|
||||
** or if the parser is being invoked from within sqlite3_declare_vtab.
|
||||
*/
|
||||
assert( !IN_RENAME_OBJECT || db->xAuth==0 );
|
||||
if( db->init.busy || IN_SPECIAL_PARSE ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
+1
-2
@@ -3112,7 +3112,7 @@ static int lockBtree(BtShared *pBt){
|
||||
pageSize-usableSize);
|
||||
return rc;
|
||||
}
|
||||
if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
|
||||
if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto page1_init_failed;
|
||||
}
|
||||
@@ -3586,7 +3586,6 @@ static int relocatePage(
|
||||
eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( pDbPage->pBt==pBt );
|
||||
if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
|
||||
|
||||
/* Move page iDbPage from its current location to page number iFreePage */
|
||||
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
|
||||
|
||||
+13
-31
@@ -356,15 +356,17 @@ Table *sqlite3LocateTable(
|
||||
if( p==0 ){
|
||||
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* If zName is the not the name of a table in the schema created using
|
||||
** CREATE, then check to see if it is the name of an virtual table that
|
||||
** can be an eponymous virtual table. */
|
||||
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
|
||||
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
|
||||
pMod = sqlite3PragmaVtabRegister(db, zName);
|
||||
}
|
||||
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
|
||||
return pMod->pEpoTab;
|
||||
if( sqlite3FindDbName(db, zDbase)<1 ){
|
||||
/* If zName is the not the name of a table in the schema created using
|
||||
** CREATE, then check to see if it is the name of an virtual table that
|
||||
** can be an eponymous virtual table. */
|
||||
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
|
||||
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
|
||||
pMod = sqlite3PragmaVtabRegister(db, zName);
|
||||
}
|
||||
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
|
||||
return pMod->pEpoTab;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( (flags & LOCATE_NOERR)==0 ){
|
||||
@@ -631,12 +633,6 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
|
||||
|
||||
/* Delete the Table structure itself.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
if( pTable->pColHash ){
|
||||
sqlite3HashClear(pTable->pColHash);
|
||||
sqlite3_free(pTable->pColHash);
|
||||
}
|
||||
#endif
|
||||
sqlite3DeleteColumnNames(db, pTable);
|
||||
sqlite3DbFree(db, pTable->zName);
|
||||
sqlite3DbFree(db, pTable->zColAff);
|
||||
@@ -795,20 +791,6 @@ int sqlite3TwoPartName(
|
||||
return iDb;
|
||||
}
|
||||
|
||||
/*
|
||||
** True if PRAGMA writable_schema is ON
|
||||
*/
|
||||
int sqlite3WritableSchema(sqlite3 *db){
|
||||
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
|
||||
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
|
||||
SQLITE_WriteSchema );
|
||||
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
|
||||
SQLITE_Defensive );
|
||||
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
|
||||
(SQLITE_WriteSchema|SQLITE_Defensive) );
|
||||
return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is used to check if the UTF-8 string zName is a legal
|
||||
** unqualified name for a new schema object (table, index, view or
|
||||
@@ -818,7 +800,7 @@ int sqlite3WritableSchema(sqlite3 *db){
|
||||
*/
|
||||
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
|
||||
if( !pParse->db->init.busy && pParse->nested==0
|
||||
&& sqlite3WritableSchema(pParse->db)==0
|
||||
&& (pParse->db->flags & SQLITE_WriteSchema)==0
|
||||
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
|
||||
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
|
||||
return SQLITE_ERROR;
|
||||
@@ -2440,7 +2422,7 @@ void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){
|
||||
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int r1 = sqlite3GetTempReg(pParse);
|
||||
if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
|
||||
assert( iTable>1 );
|
||||
sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
|
||||
sqlite3MayAbort(pParse);
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
|
||||
+2
-17
@@ -295,21 +295,6 @@ static FuncDef *functionSearch(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
FuncDef *sqlite3FunctionSearchN(
|
||||
int h, /* Hash of the name */
|
||||
const char *zFunc, /* Name of function */
|
||||
int nFunc /* Length of the name */
|
||||
){
|
||||
FuncDef *p;
|
||||
for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
|
||||
if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
/*
|
||||
** Insert a new FuncDef into a FuncDefHash hash table.
|
||||
@@ -323,7 +308,7 @@ void sqlite3InsertBuiltinFuncs(
|
||||
FuncDef *pOther;
|
||||
const char *zName = aDef[i].zName;
|
||||
int nName = sqlite3Strlen30(zName);
|
||||
int h = SQLITE_FUNC_HASH(zName[0], nName);
|
||||
int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
|
||||
assert( zName[0]>='a' && zName[0]<='z' );
|
||||
pOther = functionSearch(h, zName);
|
||||
if( pOther ){
|
||||
@@ -402,7 +387,7 @@ FuncDef *sqlite3FindFunction(
|
||||
*/
|
||||
if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
|
||||
bestScore = 0;
|
||||
h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
|
||||
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
|
||||
p = functionSearch(h, zName);
|
||||
while( p ){
|
||||
int score = matchQuality(p, nArg, enc);
|
||||
|
||||
@@ -235,9 +235,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_FTS5
|
||||
"ENABLE_FTS5",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_GEOPOLY
|
||||
"ENABLE_GEOPOLY",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
"ENABLE_HIDDEN_COLUMNS",
|
||||
#endif
|
||||
@@ -268,9 +265,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_MULTIPLEX
|
||||
"ENABLE_MULTIPLEX",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_NORMALIZE
|
||||
"ENABLE_NORMALIZE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_NULL_TRIM
|
||||
"ENABLE_NULL_TRIM",
|
||||
#endif
|
||||
|
||||
@@ -313,10 +313,6 @@ static int dbpageUpdate(
|
||||
Pager *pPager;
|
||||
int szPage;
|
||||
|
||||
if( pTab->db->flags & SQLITE_Defensive ){
|
||||
zErr = "read-only";
|
||||
goto update_fail;
|
||||
}
|
||||
if( argc==1 ){
|
||||
zErr = "cannot delete";
|
||||
goto update_fail;
|
||||
|
||||
+7
-30
@@ -254,7 +254,7 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static void statClearCells(StatPage *p){
|
||||
static void statClearPage(StatPage *p){
|
||||
int i;
|
||||
if( p->aCell ){
|
||||
for(i=0; i<p->nCell; i++){
|
||||
@@ -262,12 +262,6 @@ static void statClearCells(StatPage *p){
|
||||
}
|
||||
sqlite3_free(p->aCell);
|
||||
}
|
||||
p->nCell = 0;
|
||||
p->aCell = 0;
|
||||
}
|
||||
|
||||
static void statClearPage(StatPage *p){
|
||||
statClearCells(p);
|
||||
sqlite3PagerUnref(p->pPg);
|
||||
sqlite3_free(p->zPath);
|
||||
memset(p, 0, sizeof(StatPage));
|
||||
@@ -330,33 +324,22 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
|
||||
|
||||
p->flags = aHdr[0];
|
||||
if( p->flags==0x0A || p->flags==0x0D ){
|
||||
isLeaf = 1;
|
||||
nHdr = 8;
|
||||
}else if( p->flags==0x05 || p->flags==0x02 ){
|
||||
isLeaf = 0;
|
||||
nHdr = 12;
|
||||
}else{
|
||||
goto statPageIsCorrupt;
|
||||
}
|
||||
if( p->iPgno==1 ) nHdr += 100;
|
||||
p->nCell = get2byte(&aHdr[3]);
|
||||
p->nMxPayload = 0;
|
||||
szPage = sqlite3BtreeGetPageSize(pBt);
|
||||
|
||||
isLeaf = (p->flags==0x0A || p->flags==0x0D);
|
||||
nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
|
||||
|
||||
nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
|
||||
nUnused += (int)aHdr[7];
|
||||
iOff = get2byte(&aHdr[1]);
|
||||
while( iOff ){
|
||||
int iNext;
|
||||
if( iOff>=szPage ) goto statPageIsCorrupt;
|
||||
nUnused += get2byte(&aData[iOff+2]);
|
||||
iNext = get2byte(&aData[iOff]);
|
||||
if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt;
|
||||
iOff = iNext;
|
||||
iOff = get2byte(&aData[iOff]);
|
||||
}
|
||||
p->nUnused = nUnused;
|
||||
p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
|
||||
szPage = sqlite3BtreeGetPageSize(pBt);
|
||||
|
||||
if( p->nCell ){
|
||||
int i; /* Used to iterate through cells */
|
||||
@@ -373,7 +356,6 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
StatCell *pCell = &p->aCell[i];
|
||||
|
||||
iOff = get2byte(&aData[nHdr+i*2]);
|
||||
if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt;
|
||||
if( !isLeaf ){
|
||||
pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
|
||||
iOff += 4;
|
||||
@@ -390,8 +372,8 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
}
|
||||
if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
|
||||
getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
|
||||
if( nLocal<0 ) goto statPageIsCorrupt;
|
||||
pCell->nLocal = nLocal;
|
||||
assert( nLocal>=0 );
|
||||
assert( nPayload>=(u32)nLocal );
|
||||
assert( nLocal<=(nUsable-35) );
|
||||
if( nPayload>(u32)nLocal ){
|
||||
@@ -420,11 +402,6 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
|
||||
statPageIsCorrupt:
|
||||
p->flags = 0;
|
||||
statClearCells(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+2
-2
@@ -63,8 +63,8 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
|
||||
if( ( IsVirtual(pTab)
|
||||
&& sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
|
||||
|| ( (pTab->tabFlags & TF_Readonly)!=0
|
||||
&& sqlite3WritableSchema(pParse->db)==0
|
||||
&& pParse->nested==0)
|
||||
&& (pParse->db->flags & SQLITE_WriteSchema)==0
|
||||
&& pParse->nested==0 )
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
|
||||
return 1;
|
||||
|
||||
+45
-56
@@ -58,8 +58,8 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
||||
return sqlite3AffinityType(pExpr->u.zToken, 0);
|
||||
}
|
||||
#endif
|
||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
|
||||
return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
|
||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
|
||||
return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
|
||||
}
|
||||
if( op==TK_SELECT_COLUMN ){
|
||||
assert( pExpr->pLeft->flags&EP_xIsSelect );
|
||||
@@ -143,13 +143,13 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
if( p->flags & EP_Generic ) break;
|
||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN
|
||||
|| op==TK_REGISTER || op==TK_TRIGGER)
|
||||
&& p->y.pTab!=0
|
||||
&& p->pTab!=0
|
||||
){
|
||||
/* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
|
||||
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
|
||||
** a TK_COLUMN but was previously evaluated and cached in a register */
|
||||
int j = p->iColumn;
|
||||
if( j>=0 ){
|
||||
const char *zColl = p->y.pTab->aCol[j].zColl;
|
||||
const char *zColl = p->pTab->aCol[j].zColl;
|
||||
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
|
||||
}
|
||||
break;
|
||||
@@ -1052,10 +1052,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
assert( p!=0 );
|
||||
/* Sanity check: Assert that the IntValue is non-negative if it exists */
|
||||
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
|
||||
|
||||
assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
|
||||
assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
|
||||
|| p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
|
||||
assert( p->pLeft==0 );
|
||||
@@ -1074,9 +1070,8 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
}else{
|
||||
sqlite3ExprListDelete(db, p->x.pList);
|
||||
}
|
||||
if( ExprHasProperty(p, EP_WinFunc) ){
|
||||
assert( p->op==TK_FUNCTION );
|
||||
sqlite3WindowDelete(db, p->y.pWin);
|
||||
if( !ExprHasProperty(p, EP_Reduced) ){
|
||||
sqlite3WindowDelete(db, p->pWin);
|
||||
}
|
||||
}
|
||||
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
|
||||
@@ -1140,7 +1135,7 @@ static int dupedExprStructSize(Expr *p, int flags){
|
||||
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
|
||||
if( 0==flags || p->op==TK_SELECT_COLUMN
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
|| ExprHasProperty(p, EP_WinFunc)
|
||||
|| p->pWin
|
||||
#endif
|
||||
){
|
||||
nSize = EXPR_FULLSIZE;
|
||||
@@ -1167,7 +1162,7 @@ static int dupedExprStructSize(Expr *p, int flags){
|
||||
static int dupedExprNodeSize(Expr *p, int flags){
|
||||
int nByte = dupedExprStructSize(p, flags) & 0xfff;
|
||||
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
|
||||
nByte += sqlite3Strlen30NN(p->u.zToken)+1;
|
||||
nByte += sqlite3Strlen30(p->u.zToken)+1;
|
||||
}
|
||||
return ROUND8(nByte);
|
||||
}
|
||||
@@ -1270,24 +1265,22 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
|
||||
}
|
||||
|
||||
/* Fill in pNew->pLeft and pNew->pRight. */
|
||||
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
|
||||
zAlloc += dupedExprNodeSize(p, dupFlags);
|
||||
zAlloc += dupedExprNodeSize(p, dupFlags);
|
||||
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
|
||||
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
|
||||
pNew->pLeft = p->pLeft ?
|
||||
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
|
||||
pNew->pRight = p->pRight ?
|
||||
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
|
||||
}
|
||||
}else{
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(p, EP_WinFunc) ){
|
||||
pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
|
||||
assert( ExprHasProperty(pNew, EP_WinFunc) );
|
||||
if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
|
||||
pNew->pWin = 0;
|
||||
}else{
|
||||
pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||
if( pzBuffer ){
|
||||
*pzBuffer = zAlloc;
|
||||
}
|
||||
}else{
|
||||
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
|
||||
if( pNew->op==TK_SELECT_COLUMN ){
|
||||
pNew->pLeft = p->pLeft;
|
||||
@@ -1299,6 +1292,9 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
|
||||
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
|
||||
}
|
||||
}
|
||||
if( pzBuffer ){
|
||||
*pzBuffer = zAlloc;
|
||||
}
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
@@ -2093,8 +2089,8 @@ int sqlite3ExprCanBeNull(const Expr *p){
|
||||
return 0;
|
||||
case TK_COLUMN:
|
||||
return ExprHasProperty(p, EP_CanBeNull) ||
|
||||
p->y.pTab==0 || /* Reference to column of index on expression */
|
||||
(p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
|
||||
p->pTab==0 || /* Reference to column of index on expression */
|
||||
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
@@ -2149,14 +2145,6 @@ int sqlite3IsRowid(const char *z){
|
||||
if( sqlite3StrICmp(z, "OID")==0 ) return 1;
|
||||
return 0;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
int sqlite3IsRowidN(const char *z, int n){
|
||||
if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
|
||||
if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
|
||||
if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** pX is the RHS of an IN operator. If pX is a SELECT statement
|
||||
@@ -3390,7 +3378,7 @@ expr_code_doover:
|
||||
** constant.
|
||||
*/
|
||||
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
|
||||
int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
|
||||
int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
|
||||
if( aff!=SQLITE_AFF_BLOB ){
|
||||
static const char zAff[] = "B\000C\000D\000E";
|
||||
assert( SQLITE_AFF_BLOB=='A' );
|
||||
@@ -3414,7 +3402,7 @@ expr_code_doover:
|
||||
iTab = pParse->iSelfTab - 1;
|
||||
}
|
||||
}
|
||||
return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
|
||||
return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
|
||||
pExpr->iColumn, iTab, target,
|
||||
pExpr->op2);
|
||||
}
|
||||
@@ -3628,8 +3616,8 @@ expr_code_doover:
|
||||
CollSeq *pColl = 0; /* A collating sequence */
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
return pExpr->y.pWin->regResult;
|
||||
if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
|
||||
return pExpr->pWin->regResult;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3872,7 +3860,7 @@ expr_code_doover:
|
||||
** p1==1 -> old.a p1==4 -> new.a
|
||||
** p1==2 -> old.b p1==5 -> new.b
|
||||
*/
|
||||
Table *pTab = pExpr->y.pTab;
|
||||
Table *pTab = pExpr->pTab;
|
||||
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
|
||||
|
||||
assert( pExpr->iTable==0 || pExpr->iTable==1 );
|
||||
@@ -3883,7 +3871,7 @@ expr_code_doover:
|
||||
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
|
||||
VdbeComment((v, "r[%d]=%s.%s", target,
|
||||
(pExpr->iTable ? "new" : "old"),
|
||||
(pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
|
||||
(pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
|
||||
));
|
||||
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
@@ -4734,20 +4722,6 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
|
||||
if( pA->op==TK_FUNCTION ){
|
||||
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
/* Justification for the assert():
|
||||
** window functions have p->op==TK_FUNCTION but aggregate functions
|
||||
** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
|
||||
** function and a window function should have failed before reaching
|
||||
** this point. And, it is not possible to have a window function and
|
||||
** a scalar function with the same name and number of arguments. So
|
||||
** if we reach this point, either A and B both window functions or
|
||||
** neither are a window functions. */
|
||||
assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
|
||||
if( ExprHasProperty(pA,EP_WinFunc) ){
|
||||
if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
|
||||
}
|
||||
#endif
|
||||
}else if( pA->op==TK_COLLATE ){
|
||||
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
|
||||
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
|
||||
@@ -4767,6 +4741,21 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
if( pA->iTable!=pB->iTable
|
||||
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
/* Justification for the assert():
|
||||
** window functions have p->op==TK_FUNCTION but aggregate functions
|
||||
** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
|
||||
** function and a window function should have failed before reaching
|
||||
** this point. And, it is not possible to have a window function and
|
||||
** a scalar function with the same name and number of arguments. So
|
||||
** if we reach this point, either A and B both window functions or
|
||||
** neither are a window functions. */
|
||||
assert( (pA->pWin==0)==(pB->pWin==0) );
|
||||
|
||||
if( pA->pWin!=0 ){
|
||||
if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -4907,8 +4896,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pExpr->op==TK_LE );
|
||||
testcase( pExpr->op==TK_GT );
|
||||
testcase( pExpr->op==TK_GE );
|
||||
if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
|
||||
|| (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
|
||||
if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
|
||||
|| (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
|
||||
){
|
||||
return WRC_Prune;
|
||||
}
|
||||
@@ -5139,7 +5128,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
|
||||
){
|
||||
pCol = &pAggInfo->aCol[k];
|
||||
pCol->pTab = pExpr->y.pTab;
|
||||
pCol->pTab = pExpr->pTab;
|
||||
pCol->iTable = pExpr->iTable;
|
||||
pCol->iColumn = pExpr->iColumn;
|
||||
pCol->iMem = ++pParse->nMem;
|
||||
|
||||
+1
-1
@@ -502,7 +502,7 @@ static Expr *exprTableColumn(
|
||||
){
|
||||
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
|
||||
if( pExpr ){
|
||||
pExpr->y.pTab = pTab;
|
||||
pExpr->pTab = pTab;
|
||||
pExpr->iTable = iCursor;
|
||||
pExpr->iColumn = iCol;
|
||||
}
|
||||
|
||||
-56
@@ -64,20 +64,6 @@ static unsigned int strHash(const char *z){
|
||||
}
|
||||
return h;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
static unsigned int strHashN(const char *z, int n){
|
||||
unsigned int h = 0;
|
||||
int i;
|
||||
for(i=0; i<n; i++){
|
||||
/* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
|
||||
** 0x9e3779b1 is 2654435761 which is the closest prime number to
|
||||
** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
|
||||
h += sqlite3UpperToLower[z[i]];
|
||||
h *= 0x9e3779b1;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
|
||||
/* Link pNew element into the hash table pH. If pEntry!=0 then also
|
||||
@@ -189,40 +175,6 @@ static HashElem *findElementWithHash(
|
||||
}
|
||||
return &nullElement;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
static HashElem *findElementWithHashN(
|
||||
const Hash *pH, /* The pH to be searched */
|
||||
const char *pKey, /* The key we are searching for */
|
||||
int nKey, /* Number of key bytes to use */
|
||||
unsigned int *pHash /* Write the hash value here */
|
||||
){
|
||||
HashElem *elem; /* Used to loop thru the element list */
|
||||
int count; /* Number of elements left to test */
|
||||
unsigned int h; /* The computed hash */
|
||||
static HashElem nullElement = { 0, 0, 0, 0 };
|
||||
|
||||
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
struct _ht *pEntry;
|
||||
h = strHashN(pKey, nKey) % pH->htsize;
|
||||
pEntry = &pH->ht[h];
|
||||
elem = pEntry->chain;
|
||||
count = pEntry->count;
|
||||
}else{
|
||||
h = 0;
|
||||
elem = pH->first;
|
||||
count = pH->count;
|
||||
}
|
||||
if( pHash ) *pHash = h;
|
||||
while( count-- ){
|
||||
assert( elem!=0 );
|
||||
if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
|
||||
return elem;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
return &nullElement;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
/* Remove a single entry from the hash table given a pointer to that
|
||||
** element and a hash on the element's key.
|
||||
@@ -267,14 +219,6 @@ void *sqlite3HashFind(const Hash *pH, const char *pKey){
|
||||
assert( pKey!=0 );
|
||||
return findElementWithHash(pH, pKey, 0)->data;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
|
||||
assert( pH!=0 );
|
||||
assert( pKey!=0 );
|
||||
assert( nKey>=0 );
|
||||
return findElementWithHashN(pH, pKey, nKey, 0)->data;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
/* Insert an element into the hash table pH. The key is pKey
|
||||
** and the data is "data".
|
||||
|
||||
+10
-27
@@ -146,8 +146,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
|
||||
}while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
|
||||
pTab->zColAff = zColAff;
|
||||
}
|
||||
assert( zColAff!=0 );
|
||||
i = sqlite3Strlen30NN(zColAff);
|
||||
i = sqlite3Strlen30(zColAff);
|
||||
if( i ){
|
||||
if( iReg ){
|
||||
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
|
||||
@@ -1127,15 +1126,14 @@ insert_cleanup:
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Meanings of bits in of pWalker->eCode for
|
||||
** sqlite3ExprReferencesUpdatedColumn()
|
||||
** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
|
||||
*/
|
||||
#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
|
||||
#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
|
||||
|
||||
/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
|
||||
* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
|
||||
** expression node references any of the
|
||||
/* This is the Walker callback from checkConstraintUnchanged(). Set
|
||||
** bit 0x01 of pWalker->eCode if
|
||||
** pWalker->eCode to 0 if this expression node references any of the
|
||||
** columns that are being modifed by an UPDATE statement.
|
||||
*/
|
||||
static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
|
||||
@@ -1157,21 +1155,12 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
|
||||
** only columns that are modified by the UPDATE are those for which
|
||||
** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
|
||||
**
|
||||
** Return true if CHECK constraint pExpr uses any of the
|
||||
** Return true if CHECK constraint pExpr does not use any of the
|
||||
** changing columns (or the rowid if it is changing). In other words,
|
||||
** return true if this CHECK constraint must be validated for
|
||||
** return true if this CHECK constraint can be skipped when validating
|
||||
** the new row in the UPDATE statement.
|
||||
**
|
||||
** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
|
||||
** The operation of this routine is the same - return true if an only if
|
||||
** the expression uses one or more of columns identified by the second and
|
||||
** third arguments.
|
||||
*/
|
||||
int sqlite3ExprReferencesUpdatedColumn(
|
||||
Expr *pExpr, /* The expression to be checked */
|
||||
int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
|
||||
int chngRowid /* True if UPDATE changes the rowid */
|
||||
){
|
||||
static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.eCode = 0;
|
||||
@@ -1186,7 +1175,7 @@ int sqlite3ExprReferencesUpdatedColumn(
|
||||
testcase( w.eCode==CKCNSTRNT_COLUMN );
|
||||
testcase( w.eCode==CKCNSTRNT_ROWID );
|
||||
testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
|
||||
return w.eCode!=0;
|
||||
return !w.eCode;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1392,13 +1381,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
for(i=0; i<pCheck->nExpr; i++){
|
||||
int allOk;
|
||||
Expr *pExpr = pCheck->a[i].pExpr;
|
||||
if( aiChng
|
||||
&& !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
|
||||
){
|
||||
/* The check constraints do not reference any of the columns being
|
||||
** updated so there is no point it verifying the check constraint */
|
||||
continue;
|
||||
}
|
||||
if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
|
||||
allOk = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeVerifyAbortable(v, onError);
|
||||
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
|
||||
|
||||
+1
-7
@@ -451,13 +451,7 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
sqlite3_str_length,
|
||||
sqlite3_str_value,
|
||||
/* Version 3.25.0 and later */
|
||||
sqlite3_create_window_function,
|
||||
/* Version 3.26.0 and later */
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
sqlite3_normalized_sql
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
sqlite3_create_window_function
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -835,7 +835,6 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
|
||||
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
|
||||
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
|
||||
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
|
||||
};
|
||||
unsigned int i;
|
||||
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
||||
|
||||
+59
-66
@@ -136,10 +136,12 @@
|
||||
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
|
||||
|
||||
/*
|
||||
** If we are to be thread-safe, include the pthreads header.
|
||||
** If we are to be thread-safe, include the pthreads header and define
|
||||
** the SQLITE_UNIX_THREADS macro.
|
||||
*/
|
||||
#if SQLITE_THREADSAFE
|
||||
# include <pthread.h>
|
||||
# define SQLITE_UNIX_THREADS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1117,7 +1119,8 @@ struct unixFileId {
|
||||
|
||||
/*
|
||||
** An instance of the following structure is allocated for each open
|
||||
** inode.
|
||||
** inode. Or, on LinuxThreads, there is one of these structures for
|
||||
** each inode opened by each thread.
|
||||
**
|
||||
** A single inode can have multiple file descriptors, so each unixFile
|
||||
** structure contains a pointer to an instance of this object and this
|
||||
@@ -1163,16 +1166,13 @@ struct unixInodeInfo {
|
||||
|
||||
/*
|
||||
** A lists of all unixInodeInfo objects.
|
||||
**
|
||||
** Must hold unixBigLock in order to read or write this variable.
|
||||
*/
|
||||
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
|
||||
** This routine is used only within assert() to help verify correct mutex
|
||||
** usage.
|
||||
** True if the inode mutex is held, or not. Used only within assert()
|
||||
** to help verify correct mutex usage.
|
||||
*/
|
||||
int unixFileMutexHeld(unixFile *pFile){
|
||||
assert( pFile->pInode );
|
||||
@@ -1300,8 +1300,8 @@ static void closePendingFds(unixFile *pFile){
|
||||
/*
|
||||
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
|
||||
**
|
||||
** The global mutex must be held when this routine is called, but the mutex
|
||||
** on the inode being deleted must NOT be held.
|
||||
** The mutex entered using the unixEnterMutex() function must be held
|
||||
** when this function is called.
|
||||
*/
|
||||
static void releaseInodeInfo(unixFile *pFile){
|
||||
unixInodeInfo *pInode = pFile->pInode;
|
||||
@@ -1336,7 +1336,8 @@ static void releaseInodeInfo(unixFile *pFile){
|
||||
** describes that file descriptor. Create a new one if necessary. The
|
||||
** return value might be uninitialized if an error occurs.
|
||||
**
|
||||
** The global mutex must held when calling this routine.
|
||||
** The mutex entered using the unixEnterMutex() function must be held
|
||||
** when this function is called.
|
||||
**
|
||||
** Return an appropriate error code.
|
||||
*/
|
||||
@@ -1397,7 +1398,6 @@ static int findInodeInfo(
|
||||
#else
|
||||
fileId.ino = (u64)statbuf.st_ino;
|
||||
#endif
|
||||
assert( unixMutexHeld() );
|
||||
pInode = inodeList;
|
||||
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
|
||||
pInode = pInode->pNext;
|
||||
@@ -1417,7 +1417,6 @@ static int findInodeInfo(
|
||||
}
|
||||
}
|
||||
pInode->nRef = 1;
|
||||
assert( unixMutexHeld() );
|
||||
pInode->pNext = inodeList;
|
||||
pInode->pPrev = 0;
|
||||
if( inodeList ) inodeList->pPrev = pInode;
|
||||
@@ -4215,18 +4214,18 @@ static int unixGetpagesize(void){
|
||||
**
|
||||
** The following fields are read-only after the object is created:
|
||||
**
|
||||
** hShm
|
||||
** fid
|
||||
** zFilename
|
||||
**
|
||||
** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
|
||||
** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
|
||||
** unixMutexHeld() is true when reading or writing any other field
|
||||
** in this structure.
|
||||
*/
|
||||
struct unixShmNode {
|
||||
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
|
||||
sqlite3_mutex *pShmMutex; /* Mutex to access this object */
|
||||
sqlite3_mutex *mutex; /* Mutex to access this object */
|
||||
char *zFilename; /* Name of the mmapped file */
|
||||
int hShm; /* Open file descriptor */
|
||||
int h; /* Open file descriptor */
|
||||
int szRegion; /* Size of shared-memory regions */
|
||||
u16 nRegion; /* Size of array apRegion */
|
||||
u8 isReadonly; /* True if read-only */
|
||||
@@ -4248,16 +4247,16 @@ struct unixShmNode {
|
||||
** The following fields are initialized when this object is created and
|
||||
** are read-only thereafter:
|
||||
**
|
||||
** unixShm.pShmNode
|
||||
** unixShm.pFile
|
||||
** unixShm.id
|
||||
**
|
||||
** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
|
||||
** be held while accessing any read/write fields.
|
||||
** All other fields are read/write. The unixShm.pFile->mutex must be held
|
||||
** while accessing any read/write fields.
|
||||
*/
|
||||
struct unixShm {
|
||||
unixShmNode *pShmNode; /* The underlying unixShmNode object */
|
||||
unixShm *pNext; /* Next unixShm with the same unixShmNode */
|
||||
u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
|
||||
u8 hasMutex; /* True if holding the unixShmNode mutex */
|
||||
u8 id; /* Id of this connection within its unixShmNode */
|
||||
u16 sharedMask; /* Mask of shared locks held */
|
||||
u16 exclMask; /* Mask of exclusive locks held */
|
||||
@@ -4287,8 +4286,7 @@ static int unixShmSystemLock(
|
||||
|
||||
/* Access to the unixShmNode object is serialized by the caller */
|
||||
pShmNode = pFile->pInode->pShmNode;
|
||||
assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
|
||||
assert( pShmNode->nRef>0 || unixMutexHeld() );
|
||||
assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
|
||||
|
||||
/* Shared locks never span more than one byte */
|
||||
assert( n==1 || lockType!=F_RDLCK );
|
||||
@@ -4296,13 +4294,13 @@ static int unixShmSystemLock(
|
||||
/* Locks are within range */
|
||||
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
|
||||
|
||||
if( pShmNode->hShm>=0 ){
|
||||
if( pShmNode->h>=0 ){
|
||||
/* Initialize the locking parameters */
|
||||
f.l_type = lockType;
|
||||
f.l_whence = SEEK_SET;
|
||||
f.l_start = ofst;
|
||||
f.l_len = n;
|
||||
rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
|
||||
rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
|
||||
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
|
||||
}
|
||||
|
||||
@@ -4374,18 +4372,18 @@ static void unixShmPurge(unixFile *pFd){
|
||||
int nShmPerMap = unixShmRegionPerMap();
|
||||
int i;
|
||||
assert( p->pInode==pFd->pInode );
|
||||
sqlite3_mutex_free(p->pShmMutex);
|
||||
sqlite3_mutex_free(p->mutex);
|
||||
for(i=0; i<p->nRegion; i+=nShmPerMap){
|
||||
if( p->hShm>=0 ){
|
||||
if( p->h>=0 ){
|
||||
osMunmap(p->apRegion[i], p->szRegion);
|
||||
}else{
|
||||
sqlite3_free(p->apRegion[i]);
|
||||
}
|
||||
}
|
||||
sqlite3_free(p->apRegion);
|
||||
if( p->hShm>=0 ){
|
||||
robust_close(pFd, p->hShm, __LINE__);
|
||||
p->hShm = -1;
|
||||
if( p->h>=0 ){
|
||||
robust_close(pFd, p->h, __LINE__);
|
||||
p->h = -1;
|
||||
}
|
||||
p->pInode->pShmNode = 0;
|
||||
sqlite3_free(p);
|
||||
@@ -4427,7 +4425,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
|
||||
lock.l_start = UNIX_SHM_DMS;
|
||||
lock.l_len = 1;
|
||||
lock.l_type = F_WRLCK;
|
||||
if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
|
||||
if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
|
||||
rc = SQLITE_IOERR_LOCK;
|
||||
}else if( lock.l_type==F_UNLCK ){
|
||||
if( pShmNode->isReadonly ){
|
||||
@@ -4435,12 +4433,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
|
||||
rc = SQLITE_READONLY_CANTINIT;
|
||||
}else{
|
||||
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
|
||||
/* The first connection to attach must truncate the -shm file. We
|
||||
** truncate to 3 bytes (an arbitrary small number, less than the
|
||||
** -shm header size) rather than 0 as a system debugging aid, to
|
||||
** help detect if a -shm file truncation is legitimate or is the work
|
||||
** or a rogue process. */
|
||||
if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
|
||||
if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
|
||||
rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
|
||||
}
|
||||
}
|
||||
@@ -4546,12 +4539,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
|
||||
sqlite3FileSuffix3(pDbFd->zPath, zShm);
|
||||
#endif
|
||||
pShmNode->hShm = -1;
|
||||
pShmNode->h = -1;
|
||||
pDbFd->pInode->pShmNode = pShmNode;
|
||||
pShmNode->pInode = pDbFd->pInode;
|
||||
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||
pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
if( pShmNode->pShmMutex==0 ){
|
||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
if( pShmNode->mutex==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto shm_open_err;
|
||||
}
|
||||
@@ -4559,11 +4552,11 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
|
||||
if( pInode->bProcessLock==0 ){
|
||||
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
|
||||
pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
|
||||
pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
|
||||
}
|
||||
if( pShmNode->hShm<0 ){
|
||||
pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
|
||||
if( pShmNode->hShm<0 ){
|
||||
if( pShmNode->h<0 ){
|
||||
pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
|
||||
if( pShmNode->h<0 ){
|
||||
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
|
||||
goto shm_open_err;
|
||||
}
|
||||
@@ -4574,7 +4567,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
** is owned by the same user that owns the original database. Otherwise,
|
||||
** the original owner will not be able to connect.
|
||||
*/
|
||||
robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
|
||||
robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
|
||||
|
||||
rc = unixLockSharedMemory(pDbFd, pShmNode);
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
|
||||
@@ -4594,13 +4587,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
** the cover of the unixEnterMutex() mutex and the pointer from the
|
||||
** new (struct unixShm) object to the pShmNode has been set. All that is
|
||||
** left to do is to link the new object into the linked list starting
|
||||
** at pShmNode->pFirst. This must be done while holding the
|
||||
** pShmNode->pShmMutex.
|
||||
** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
|
||||
** mutex.
|
||||
*/
|
||||
sqlite3_mutex_enter(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_enter(pShmNode->mutex);
|
||||
p->pNext = pShmNode->pFirst;
|
||||
pShmNode->pFirst = p;
|
||||
sqlite3_mutex_leave(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_leave(pShmNode->mutex);
|
||||
return rc;
|
||||
|
||||
/* Jump here on any error */
|
||||
@@ -4652,7 +4645,7 @@ static int unixShmMap(
|
||||
|
||||
p = pDbFd->pShm;
|
||||
pShmNode = p->pShmNode;
|
||||
sqlite3_mutex_enter(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_enter(pShmNode->mutex);
|
||||
if( pShmNode->isUnlocked ){
|
||||
rc = unixLockSharedMemory(pDbFd, pShmNode);
|
||||
if( rc!=SQLITE_OK ) goto shmpage_out;
|
||||
@@ -4660,8 +4653,8 @@ static int unixShmMap(
|
||||
}
|
||||
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
|
||||
assert( pShmNode->pInode==pDbFd->pInode );
|
||||
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
|
||||
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
|
||||
|
||||
/* Minimum number of regions required to be mapped. */
|
||||
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
|
||||
@@ -4673,12 +4666,12 @@ static int unixShmMap(
|
||||
|
||||
pShmNode->szRegion = szRegion;
|
||||
|
||||
if( pShmNode->hShm>=0 ){
|
||||
if( pShmNode->h>=0 ){
|
||||
/* The requested region is not mapped into this processes address space.
|
||||
** Check to see if it has been allocated (i.e. if the wal-index file is
|
||||
** large enough to contain the requested region).
|
||||
*/
|
||||
if( osFstat(pShmNode->hShm, &sStat) ){
|
||||
if( osFstat(pShmNode->h, &sStat) ){
|
||||
rc = SQLITE_IOERR_SHMSIZE;
|
||||
goto shmpage_out;
|
||||
}
|
||||
@@ -4706,7 +4699,7 @@ static int unixShmMap(
|
||||
assert( (nByte % pgsz)==0 );
|
||||
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
|
||||
int x = 0;
|
||||
if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
|
||||
if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
|
||||
const char *zFile = pShmNode->zFilename;
|
||||
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
|
||||
goto shmpage_out;
|
||||
@@ -4729,22 +4722,22 @@ static int unixShmMap(
|
||||
int nMap = szRegion*nShmPerMap;
|
||||
int i;
|
||||
void *pMem;
|
||||
if( pShmNode->hShm>=0 ){
|
||||
if( pShmNode->h>=0 ){
|
||||
pMem = osMmap(0, nMap,
|
||||
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
|
||||
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
|
||||
);
|
||||
if( pMem==MAP_FAILED ){
|
||||
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
|
||||
goto shmpage_out;
|
||||
}
|
||||
}else{
|
||||
pMem = sqlite3_malloc64(nMap);
|
||||
pMem = sqlite3_malloc64(szRegion);
|
||||
if( pMem==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto shmpage_out;
|
||||
}
|
||||
memset(pMem, 0, nMap);
|
||||
memset(pMem, 0, szRegion);
|
||||
}
|
||||
|
||||
for(i=0; i<nShmPerMap; i++){
|
||||
@@ -4761,7 +4754,7 @@ shmpage_out:
|
||||
*pp = 0;
|
||||
}
|
||||
if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
|
||||
sqlite3_mutex_leave(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_leave(pShmNode->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -4795,12 +4788,12 @@ static int unixShmLock(
|
||||
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|
||||
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
|
||||
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
|
||||
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
|
||||
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
|
||||
|
||||
mask = (1<<(ofst+n)) - (1<<ofst);
|
||||
assert( n>1 || mask==(1<<ofst) );
|
||||
sqlite3_mutex_enter(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_enter(pShmNode->mutex);
|
||||
if( flags & SQLITE_SHM_UNLOCK ){
|
||||
u16 allMask = 0; /* Mask of locks held by siblings */
|
||||
|
||||
@@ -4873,7 +4866,7 @@ static int unixShmLock(
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_mutex_leave(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_leave(pShmNode->mutex);
|
||||
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
|
||||
p->id, osGetpid(0), p->sharedMask, p->exclMask));
|
||||
return rc;
|
||||
@@ -4923,14 +4916,14 @@ static int unixShmUnmap(
|
||||
|
||||
/* Remove connection p from the set of connections associated
|
||||
** with pShmNode */
|
||||
sqlite3_mutex_enter(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_enter(pShmNode->mutex);
|
||||
for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
|
||||
*pp = p->pNext;
|
||||
|
||||
/* Free the connection p */
|
||||
sqlite3_free(p);
|
||||
pDbFd->pShm = 0;
|
||||
sqlite3_mutex_leave(pShmNode->pShmMutex);
|
||||
sqlite3_mutex_leave(pShmNode->mutex);
|
||||
|
||||
/* If pShmNode->nRef has reached 0, then close the underlying
|
||||
** shared-memory file, too */
|
||||
@@ -4939,7 +4932,7 @@ static int unixShmUnmap(
|
||||
assert( pShmNode->nRef>0 );
|
||||
pShmNode->nRef--;
|
||||
if( pShmNode->nRef==0 ){
|
||||
if( deleteFlag && pShmNode->hShm>=0 ){
|
||||
if( deleteFlag && pShmNode->h>=0 ){
|
||||
osUnlink(pShmNode->zFilename);
|
||||
}
|
||||
unixShmPurge(pDbFd);
|
||||
|
||||
@@ -7021,7 +7021,6 @@ void sqlite3PagerSetCodec(
|
||||
void (*xCodecFree)(void*),
|
||||
void *pCodec
|
||||
){
|
||||
pager_reset(pPager);
|
||||
if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
|
||||
pPager->xCodec = pPager->memDb ? 0 : xCodec;
|
||||
pPager->xCodecSizeChng = xCodecSizeChng;
|
||||
|
||||
+4
-1
@@ -941,10 +941,13 @@ idlist(A) ::= nm(Y).
|
||||
p->pLeft = p->pRight = 0;
|
||||
p->x.pList = 0;
|
||||
p->pAggInfo = 0;
|
||||
p->y.pTab = 0;
|
||||
p->pTab = 0;
|
||||
p->op2 = 0;
|
||||
p->iTable = 0;
|
||||
p->iColumn = 0;
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
p->pWin = 0;
|
||||
#endif
|
||||
p->u.zToken = (char*)&p[1];
|
||||
memcpy(p->u.zToken, t.z, t.n);
|
||||
p->u.zToken[t.n] = 0;
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
** The PCache.pSynced variable is used to optimize searching for a dirty
|
||||
** page to eject from the cache mid-transaction. It is better to eject
|
||||
** a page that does not require a journal sync than one that does.
|
||||
** Therefore, pSynced is maintained so that it *almost* always points
|
||||
** Therefore, pSynced is maintained to that it *almost* always points
|
||||
** to either the oldest page in the pDirty/pDirtyTail list that has a
|
||||
** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
|
||||
** (so that the right page to eject can be found by following pDirtyPrev
|
||||
|
||||
+11
-25
@@ -1037,7 +1037,7 @@ void sqlite3Pragma(
|
||||
setPragmaResultColumnNames(v, pPragma);
|
||||
returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
|
||||
}else{
|
||||
u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
|
||||
int mask = pPragma->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. */
|
||||
@@ -1090,12 +1090,11 @@ void sqlite3Pragma(
|
||||
int nHidden = 0;
|
||||
Column *pCol;
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
pParse->nMem = 7;
|
||||
pParse->nMem = 6;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
int isHidden = IsHiddenColumn(pCol);
|
||||
if( isHidden && pPragma->iArg==0 ){
|
||||
if( IsHiddenColumn(pCol) ){
|
||||
nHidden++;
|
||||
continue;
|
||||
}
|
||||
@@ -1107,14 +1106,13 @@ void sqlite3Pragma(
|
||||
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
|
||||
}
|
||||
assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
|
||||
sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
|
||||
sqlite3VdbeMultiLoad(v, 1, "issisi",
|
||||
i-nHidden,
|
||||
pCol->zName,
|
||||
sqlite3ColumnType(pCol,""),
|
||||
pCol->notNull ? 1 : 0,
|
||||
pCol->pDflt ? pCol->pDflt->u.zToken : 0,
|
||||
k,
|
||||
isHidden);
|
||||
k);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2118,24 +2116,12 @@ void sqlite3Pragma(
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
/* Pragma iArg
|
||||
** ---------- ------
|
||||
** key 0
|
||||
** rekey 1
|
||||
** hexkey 2
|
||||
** hexrekey 3
|
||||
** textkey 4
|
||||
** textrekey 5
|
||||
*/
|
||||
case PragTyp_KEY: {
|
||||
if( zRight ){
|
||||
int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
|
||||
if( (pPragma->iArg & 1)==0 ){
|
||||
sqlite3_key_v2(db, zDb, zRight, n);
|
||||
}else{
|
||||
sqlite3_rekey_v2(db, zDb, zRight, n);
|
||||
}
|
||||
}
|
||||
if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
|
||||
break;
|
||||
}
|
||||
case PragTyp_REKEY: {
|
||||
if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
|
||||
break;
|
||||
}
|
||||
case PragTyp_HEXKEY: {
|
||||
@@ -2147,7 +2133,7 @@ void sqlite3Pragma(
|
||||
iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
|
||||
if( (i&1)!=0 ) zKey[i/2] = iByte;
|
||||
}
|
||||
if( (pPragma->iArg & 1)==0 ){
|
||||
if( (zLeft[3] & 0xf)==0xb ){
|
||||
sqlite3_key_v2(db, zDb, zKey, i/2);
|
||||
}else{
|
||||
sqlite3_rekey_v2(db, zDb, zKey, i/2);
|
||||
|
||||
+71
-86
@@ -48,9 +48,10 @@
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 40
|
||||
#define PragTyp_HEXKEY 41
|
||||
#define PragTyp_KEY 42
|
||||
#define PragTyp_LOCK_STATUS 43
|
||||
#define PragTyp_PARSER_TRACE 44
|
||||
#define PragTyp_STATS 45
|
||||
#define PragTyp_REKEY 43
|
||||
#define PragTyp_LOCK_STATUS 44
|
||||
#define PragTyp_PARSER_TRACE 45
|
||||
#define PragTyp_STATS 46
|
||||
|
||||
/* Property flags associated with various pragma. */
|
||||
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
|
||||
@@ -67,57 +68,58 @@
|
||||
** result column is different from the name of the pragma
|
||||
*/
|
||||
static const char *const pragCName[] = {
|
||||
/* 0 */ "id", /* Used by: foreign_key_list */
|
||||
/* 1 */ "seq",
|
||||
/* 2 */ "table",
|
||||
/* 3 */ "from",
|
||||
/* 4 */ "to",
|
||||
/* 5 */ "on_update",
|
||||
/* 6 */ "on_delete",
|
||||
/* 7 */ "match",
|
||||
/* 8 */ "cid", /* Used by: table_xinfo */
|
||||
/* 9 */ "name",
|
||||
/* 10 */ "type",
|
||||
/* 11 */ "notnull",
|
||||
/* 12 */ "dflt_value",
|
||||
/* 13 */ "pk",
|
||||
/* 14 */ "hidden",
|
||||
/* table_info reuses 8 */
|
||||
/* 0 */ "cache_size", /* Used by: default_cache_size */
|
||||
/* 1 */ "cid", /* Used by: table_info */
|
||||
/* 2 */ "name",
|
||||
/* 3 */ "type",
|
||||
/* 4 */ "notnull",
|
||||
/* 5 */ "dflt_value",
|
||||
/* 6 */ "pk",
|
||||
/* 7 */ "tbl", /* Used by: stats */
|
||||
/* 8 */ "idx",
|
||||
/* 9 */ "wdth",
|
||||
/* 10 */ "hght",
|
||||
/* 11 */ "flgs",
|
||||
/* 12 */ "seqno", /* Used by: index_info */
|
||||
/* 13 */ "cid",
|
||||
/* 14 */ "name",
|
||||
/* 15 */ "seqno", /* Used by: index_xinfo */
|
||||
/* 16 */ "cid",
|
||||
/* 17 */ "name",
|
||||
/* 18 */ "desc",
|
||||
/* 19 */ "coll",
|
||||
/* 20 */ "key",
|
||||
/* 21 */ "tbl", /* Used by: stats */
|
||||
/* 22 */ "idx",
|
||||
/* 23 */ "wdth",
|
||||
/* 24 */ "hght",
|
||||
/* 25 */ "flgs",
|
||||
/* 26 */ "seq", /* Used by: index_list */
|
||||
/* 21 */ "seq", /* Used by: index_list */
|
||||
/* 22 */ "name",
|
||||
/* 23 */ "unique",
|
||||
/* 24 */ "origin",
|
||||
/* 25 */ "partial",
|
||||
/* 26 */ "seq", /* Used by: database_list */
|
||||
/* 27 */ "name",
|
||||
/* 28 */ "unique",
|
||||
/* 29 */ "origin",
|
||||
/* 30 */ "partial",
|
||||
/* 31 */ "table", /* Used by: foreign_key_check */
|
||||
/* 32 */ "rowid",
|
||||
/* 33 */ "parent",
|
||||
/* 34 */ "fkid",
|
||||
/* index_info reuses 15 */
|
||||
/* 35 */ "seq", /* Used by: database_list */
|
||||
/* 36 */ "name",
|
||||
/* 37 */ "file",
|
||||
/* 38 */ "busy", /* Used by: wal_checkpoint */
|
||||
/* 39 */ "log",
|
||||
/* 40 */ "checkpointed",
|
||||
/* 41 */ "name", /* Used by: function_list */
|
||||
/* 42 */ "builtin",
|
||||
/* collation_list reuses 26 */
|
||||
/* 43 */ "database", /* Used by: lock_status */
|
||||
/* 44 */ "status",
|
||||
/* 45 */ "cache_size", /* Used by: default_cache_size */
|
||||
/* module_list pragma_list reuses 9 */
|
||||
/* 46 */ "timeout", /* Used by: busy_timeout */
|
||||
/* 28 */ "file",
|
||||
/* 29 */ "name", /* Used by: function_list */
|
||||
/* 30 */ "builtin",
|
||||
/* 31 */ "name", /* Used by: module_list pragma_list */
|
||||
/* 32 */ "seq", /* Used by: collation_list */
|
||||
/* 33 */ "name",
|
||||
/* 34 */ "id", /* Used by: foreign_key_list */
|
||||
/* 35 */ "seq",
|
||||
/* 36 */ "table",
|
||||
/* 37 */ "from",
|
||||
/* 38 */ "to",
|
||||
/* 39 */ "on_update",
|
||||
/* 40 */ "on_delete",
|
||||
/* 41 */ "match",
|
||||
/* 42 */ "table", /* Used by: foreign_key_check */
|
||||
/* 43 */ "rowid",
|
||||
/* 44 */ "parent",
|
||||
/* 45 */ "fkid",
|
||||
/* 46 */ "busy", /* Used by: wal_checkpoint */
|
||||
/* 47 */ "log",
|
||||
/* 48 */ "checkpointed",
|
||||
/* 49 */ "timeout", /* Used by: busy_timeout */
|
||||
/* 50 */ "database", /* Used by: lock_status */
|
||||
/* 51 */ "status",
|
||||
};
|
||||
|
||||
/* Definitions of all built-in pragmas */
|
||||
@@ -127,7 +129,7 @@ typedef struct PragmaName {
|
||||
u8 mPragFlg; /* Zero or more PragFlg_XXX values */
|
||||
u8 iPragCName; /* Start of column names in pragCName[] */
|
||||
u8 nPragCName; /* Num of col names. 0 means use pragma name */
|
||||
u64 iArg; /* Extra argument */
|
||||
u32 iArg; /* Extra argument */
|
||||
} PragmaName;
|
||||
static const PragmaName aPragmaName[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
@@ -163,7 +165,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 46, 1,
|
||||
/* ColNames: */ 49, 1,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{/* zName: */ "cache_size",
|
||||
@@ -200,7 +202,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 26, 2,
|
||||
/* ColNames: */ 32, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
@@ -235,14 +237,14 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
|
||||
/* ColNames: */ 35, 3,
|
||||
/* ColNames: */ 26, 3,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{/* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
|
||||
/* ColNames: */ 45, 1,
|
||||
/* ColNames: */ 0, 1,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
@@ -272,14 +274,14 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
|
||||
/* ColNames: */ 31, 4,
|
||||
/* ColNames: */ 42, 4,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{/* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 0, 8,
|
||||
/* ColNames: */ 34, 8,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
@@ -315,7 +317,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "function_list",
|
||||
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 41, 2,
|
||||
/* ColNames: */ 29, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#endif
|
||||
@@ -324,12 +326,12 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 2 },
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 3 },
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
@@ -351,12 +353,12 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 15, 3,
|
||||
/* ColNames: */ 12, 3,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 26, 5,
|
||||
/* ColNames: */ 21, 5,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
@@ -413,7 +415,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 43, 2,
|
||||
/* ColNames: */ 50, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
@@ -439,7 +441,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "module_list",
|
||||
/* ePragTyp: */ PragTyp_MODULE_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 9, 1,
|
||||
/* ColNames: */ 31, 1,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#endif
|
||||
@@ -472,7 +474,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "pragma_list",
|
||||
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 9, 1,
|
||||
/* ColNames: */ 31, 1,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
@@ -503,10 +505,10 @@ static const PragmaName aPragmaName[] = {
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{/* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 1 },
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{/* zName: */ "reverse_unordered_selects",
|
||||
@@ -559,7 +561,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 21, 5,
|
||||
/* ColNames: */ 7, 5,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
@@ -573,13 +575,8 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 8, 6,
|
||||
/* ColNames: */ 1, 6,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "table_xinfo",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 8, 7,
|
||||
/* iArg: */ 1 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{/* zName: */ "temp_store",
|
||||
@@ -592,18 +589,6 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragFlg: */ PragFlg_NoColumns1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{/* zName: */ "textkey",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 4 },
|
||||
{/* zName: */ "textrekey",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 5 },
|
||||
#endif
|
||||
{/* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
@@ -655,7 +640,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 38, 3,
|
||||
/* ColNames: */ 46, 3,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
@@ -663,7 +648,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
|
||||
/* iArg: */ SQLITE_WriteSchema },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 62 on by default, 81 total. */
|
||||
/* Number of pragmas: 61 on by default, 78 total. */
|
||||
|
||||
+2
-290
@@ -327,8 +327,8 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
|
||||
/* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
|
||||
if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
|
||||
/* Black magic: If the SQLITE_WriteSchema flag is set, then consider
|
||||
** the schema loaded, even if errors occurred. In this situation the
|
||||
** current sqlite3_prepare() operation will fail, but the following one
|
||||
** will attempt to compile the supplied statement against whatever subset
|
||||
@@ -709,294 +709,6 @@ static int sqlite3LockAndPrepare(
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
/*
|
||||
** Checks if the specified token is a table, column, or function name,
|
||||
** based on the databases associated with the statement being prepared.
|
||||
** If the function fails, zero is returned and pRc is filled with the
|
||||
** error code.
|
||||
*/
|
||||
static int shouldTreatAsIdentifier(
|
||||
sqlite3 *db, /* Database handle. */
|
||||
const char *zToken, /* Pointer to start of token to be checked */
|
||||
int nToken, /* Length of token to be checked */
|
||||
int *pRc /* Pointer to error code upon failure */
|
||||
){
|
||||
int bFound = 0; /* Non-zero if token is an identifier name. */
|
||||
int i, j; /* Database and column loop indexes. */
|
||||
Schema *pSchema; /* Schema for current database. */
|
||||
Hash *pHash; /* Hash table of tables for current database. */
|
||||
HashElem *e; /* Hash element for hash table iteration. */
|
||||
Table *pTab; /* Database table for columns being checked. */
|
||||
|
||||
if( sqlite3IsRowidN(zToken, nToken) ){
|
||||
return 1;
|
||||
}
|
||||
if( nToken>0 ){
|
||||
int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
|
||||
if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
|
||||
}
|
||||
assert( db!=0 );
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
pHash = &db->aFunc;
|
||||
if( sqlite3HashFindN(pHash, zToken, nToken) ){
|
||||
bFound = 1;
|
||||
break;
|
||||
}
|
||||
pSchema = db->aDb[i].pSchema;
|
||||
if( pSchema==0 ) continue;
|
||||
pHash = &pSchema->tblHash;
|
||||
if( sqlite3HashFindN(pHash, zToken, nToken) ){
|
||||
bFound = 1;
|
||||
break;
|
||||
}
|
||||
for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
|
||||
pTab = sqliteHashData(e);
|
||||
if( pTab==0 ) continue;
|
||||
pHash = pTab->pColHash;
|
||||
if( pHash==0 ){
|
||||
pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
|
||||
if( pHash ){
|
||||
sqlite3HashInit(pHash);
|
||||
for(j=0; j<pTab->nCol; j++){
|
||||
Column *pCol = &pTab->aCol[j];
|
||||
sqlite3HashInsert(pHash, pCol->zName, pCol);
|
||||
}
|
||||
}else{
|
||||
*pRc = SQLITE_NOMEM_BKPT;
|
||||
bFound = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
|
||||
bFound = 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return bFound;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to estimate the final output buffer size needed for the fully
|
||||
** normalized version of the specified SQL string. This should take into
|
||||
** account any potential expansion that could occur (e.g. via IN clauses
|
||||
** being expanded, etc). This size returned is the total number of bytes
|
||||
** including the NUL terminator.
|
||||
*/
|
||||
static int estimateNormalizedSize(
|
||||
const char *zSql, /* The original SQL string */
|
||||
int nSql, /* Length of original SQL string */
|
||||
u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
|
||||
){
|
||||
int nOut = nSql + 4;
|
||||
const char *z = zSql;
|
||||
while( nOut<nSql*5 ){
|
||||
while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
|
||||
if( z[0]==0 ) break;
|
||||
z++;
|
||||
if( z[0]!='N' && z[0]!='n' ) break;
|
||||
z++;
|
||||
while( sqlite3Isspace(z[0]) ){ z++; }
|
||||
if( z[0]!='(' ) break;
|
||||
z++;
|
||||
nOut += 5; /* ?,?,? */
|
||||
}
|
||||
return nOut;
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy the current token into the output buffer while dealing with quoted
|
||||
** identifiers. By default, all letters will be converted into lowercase.
|
||||
** If the bUpper flag is set, uppercase will be used. The piOut argument
|
||||
** will be used to update the target index into the output string.
|
||||
*/
|
||||
static void copyNormalizedToken(
|
||||
const char *zSql, /* The original SQL string */
|
||||
int iIn, /* Current index into the original SQL string */
|
||||
int nToken, /* Number of bytes in the current token */
|
||||
int tokenFlags, /* Flags returned by the tokenizer */
|
||||
char *zOut, /* The output string */
|
||||
int *piOut /* Pointer to target index into the output string */
|
||||
){
|
||||
int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
|
||||
int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
|
||||
int j = *piOut, k = 0;
|
||||
for(; k<nToken; k++){
|
||||
if( bQuoted ){
|
||||
if( k==0 && iIn>0 ){
|
||||
zOut[j++] = '"';
|
||||
continue;
|
||||
}else if( k==nToken-1 ){
|
||||
zOut[j++] = '"';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( bKeyword ){
|
||||
zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
|
||||
}else{
|
||||
zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
|
||||
}
|
||||
}
|
||||
*piOut = j;
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform normalization of the SQL contained in the prepared statement and
|
||||
** store the result in the zNormSql field. The schema for the associated
|
||||
** databases are consulted while performing the normalization in order to
|
||||
** determine if a token appears to be an identifier. All identifiers are
|
||||
** left intact in the normalized SQL and all literals are replaced with a
|
||||
** single '?'.
|
||||
*/
|
||||
void sqlite3Normalize(
|
||||
Vdbe *pVdbe, /* VM being reprepared */
|
||||
const char *zSql, /* The original SQL string */
|
||||
int nSql, /* Size of the input string in bytes */
|
||||
u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
|
||||
){
|
||||
sqlite3 *db; /* Database handle. */
|
||||
char *z; /* The output string */
|
||||
int nZ; /* Size of the output string in bytes */
|
||||
int i; /* Next character to read from zSql[] */
|
||||
int j; /* Next character to fill in on z[] */
|
||||
int tokenType = 0; /* Type of the next token */
|
||||
int prevTokenType = 0; /* Type of the previous token, except spaces */
|
||||
int n; /* Size of the next token */
|
||||
int nParen = 0; /* Nesting level of parenthesis */
|
||||
Hash inHash; /* Table of parenthesis levels to output index. */
|
||||
|
||||
db = sqlite3VdbeDb(pVdbe);
|
||||
assert( db!=0 );
|
||||
assert( pVdbe->zNormSql==0 );
|
||||
if( zSql==0 ) return;
|
||||
nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
|
||||
z = sqlite3DbMallocRawNN(db, nZ);
|
||||
if( z==0 ) return;
|
||||
sqlite3HashInit(&inHash);
|
||||
for(i=j=0; i<nSql && zSql[i]; i+=n){
|
||||
int flags = 0;
|
||||
if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
|
||||
n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
|
||||
switch( tokenType ){
|
||||
case TK_SPACE: {
|
||||
break;
|
||||
}
|
||||
case TK_ILLEGAL: {
|
||||
sqlite3DbFree(db, z);
|
||||
sqlite3HashClear(&inHash);
|
||||
return;
|
||||
}
|
||||
case TK_STRING:
|
||||
case TK_INTEGER:
|
||||
case TK_FLOAT:
|
||||
case TK_VARIABLE:
|
||||
case TK_BLOB: {
|
||||
z[j++] = '?';
|
||||
break;
|
||||
}
|
||||
case TK_LP:
|
||||
case TK_RP: {
|
||||
if( tokenType==TK_LP ){
|
||||
nParen++;
|
||||
if( prevTokenType==TK_IN ){
|
||||
assert( nParen<nSql );
|
||||
sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
|
||||
}
|
||||
}else{
|
||||
int jj;
|
||||
assert( nParen<nSql );
|
||||
jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
|
||||
if( jj>0 ){
|
||||
sqlite3HashInsert(&inHash, zSql+nParen, 0);
|
||||
assert( jj+6<nZ );
|
||||
memcpy(z+jj+1, "?,?,?", 5);
|
||||
j = jj+6;
|
||||
assert( nZ-1-j>=0 );
|
||||
assert( nZ-1-j<nZ );
|
||||
memset(z+j, 0, nZ-1-j);
|
||||
}
|
||||
nParen--;
|
||||
}
|
||||
assert( nParen>=0 );
|
||||
/* Fall through */
|
||||
}
|
||||
case TK_MINUS:
|
||||
case TK_SEMI:
|
||||
case TK_PLUS:
|
||||
case TK_STAR:
|
||||
case TK_SLASH:
|
||||
case TK_REM:
|
||||
case TK_EQ:
|
||||
case TK_LE:
|
||||
case TK_NE:
|
||||
case TK_LSHIFT:
|
||||
case TK_LT:
|
||||
case TK_RSHIFT:
|
||||
case TK_GT:
|
||||
case TK_GE:
|
||||
case TK_BITOR:
|
||||
case TK_CONCAT:
|
||||
case TK_COMMA:
|
||||
case TK_BITAND:
|
||||
case TK_BITNOT:
|
||||
case TK_DOT:
|
||||
case TK_IN:
|
||||
case TK_IS:
|
||||
case TK_NOT:
|
||||
case TK_NULL:
|
||||
case TK_ID: {
|
||||
if( tokenType==TK_NULL ){
|
||||
if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
|
||||
/* NULL is a keyword in this case, not a literal value */
|
||||
}else{
|
||||
/* Here the NULL is a literal value */
|
||||
z[j++] = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
|
||||
z[j++] = ' ';
|
||||
}
|
||||
if( tokenType==TK_ID ){
|
||||
int i2 = i, n2 = n, rc = SQLITE_OK;
|
||||
if( nParen>0 ){
|
||||
assert( nParen<nSql );
|
||||
sqlite3HashInsert(&inHash, zSql+nParen, 0);
|
||||
}
|
||||
if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
|
||||
if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3DbFree(db, z);
|
||||
sqlite3HashClear(&inHash);
|
||||
return;
|
||||
}
|
||||
if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
|
||||
z[j++] = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
copyNormalizedToken(zSql, i, n, flags, z, &j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert( j<nZ && "one" );
|
||||
while( j>0 && z[j-1]==' ' ){ j--; }
|
||||
if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
|
||||
z[j] = 0;
|
||||
assert( j<nZ && "two" );
|
||||
pVdbe->zNormSql = z;
|
||||
sqlite3HashClear(&inHash);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
/*
|
||||
** Rerun the compilation of a statement after a schema change.
|
||||
**
|
||||
|
||||
+29
-26
@@ -159,7 +159,7 @@ int sqlite3MatchSpanName(
|
||||
** (even if X is implied).
|
||||
** pExpr->iTable Set to the cursor number for the table obtained
|
||||
** from pSrcList.
|
||||
** pExpr->y.pTab Points to the Table structure of X.Y (even if
|
||||
** pExpr->pTab Points to the Table structure of X.Y (even if
|
||||
** X and/or Y are implied.)
|
||||
** pExpr->iColumn Set to the column number within the table.
|
||||
** pExpr->op Set to TK_COLUMN.
|
||||
@@ -203,6 +203,7 @@ static int lookupName(
|
||||
|
||||
/* Initialize the node to no-match */
|
||||
pExpr->iTable = -1;
|
||||
pExpr->pTab = 0;
|
||||
ExprSetVVAProperty(pExpr, EP_NoReduce);
|
||||
|
||||
/* Translate the schema name in zDb into a pointer to the corresponding
|
||||
@@ -264,7 +265,7 @@ static int lookupName(
|
||||
continue;
|
||||
}
|
||||
if( IN_RENAME_OBJECT && pItem->zAlias ){
|
||||
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
|
||||
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
|
||||
}
|
||||
}
|
||||
if( 0==(cntTab++) ){
|
||||
@@ -290,13 +291,13 @@ static int lookupName(
|
||||
}
|
||||
if( pMatch ){
|
||||
pExpr->iTable = pMatch->iCursor;
|
||||
pExpr->y.pTab = pMatch->pTab;
|
||||
pExpr->pTab = pMatch->pTab;
|
||||
/* RIGHT JOIN not (yet) supported */
|
||||
assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
|
||||
if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
|
||||
ExprSetProperty(pExpr, EP_CanBeNull);
|
||||
}
|
||||
pSchema = pExpr->y.pTab->pSchema;
|
||||
pSchema = pExpr->pTab->pSchema;
|
||||
}
|
||||
} /* if( pSrcList ) */
|
||||
|
||||
@@ -353,7 +354,7 @@ static int lookupName(
|
||||
testcase( iCol==(-1) );
|
||||
if( IN_RENAME_OBJECT ){
|
||||
pExpr->iColumn = iCol;
|
||||
pExpr->y.pTab = pTab;
|
||||
pExpr->pTab = pTab;
|
||||
eNewExprOp = TK_COLUMN;
|
||||
}else{
|
||||
pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
|
||||
@@ -375,7 +376,7 @@ static int lookupName(
|
||||
testcase( iCol==32 );
|
||||
pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
|
||||
}
|
||||
pExpr->y.pTab = pTab;
|
||||
pExpr->pTab = pTab;
|
||||
pExpr->iColumn = (i16)iCol;
|
||||
eNewExprOp = TK_TRIGGER;
|
||||
#endif /* SQLITE_OMIT_TRIGGER */
|
||||
@@ -475,7 +476,7 @@ static int lookupName(
|
||||
assert( pExpr->op==TK_ID );
|
||||
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
|
||||
pExpr->op = TK_STRING;
|
||||
pExpr->y.pTab = 0;
|
||||
pExpr->pTab = 0;
|
||||
return WRC_Prune;
|
||||
}
|
||||
if( sqlite3ExprIdToTrueFalse(pExpr) ){
|
||||
@@ -553,9 +554,9 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
|
||||
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
|
||||
if( p ){
|
||||
struct SrcList_item *pItem = &pSrc->a[iSrc];
|
||||
p->y.pTab = pItem->pTab;
|
||||
p->pTab = pItem->pTab;
|
||||
p->iTable = pItem->iCursor;
|
||||
if( p->y.pTab->iPKey==iCol ){
|
||||
if( p->pTab->iPKey==iCol ){
|
||||
p->iColumn = -1;
|
||||
}else{
|
||||
p->iColumn = (ynVar)iCol;
|
||||
@@ -645,7 +646,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
pItem = pSrcList->a;
|
||||
assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
|
||||
pExpr->op = TK_COLUMN;
|
||||
pExpr->y.pTab = pItem->pTab;
|
||||
pExpr->pTab = pItem->pTab;
|
||||
pExpr->iTable = pItem->iCursor;
|
||||
pExpr->iColumn = -1;
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
@@ -689,7 +690,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
zColumn = pRight->u.zToken;
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
|
||||
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
|
||||
}
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
|
||||
}
|
||||
}
|
||||
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
|
||||
@@ -779,18 +782,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
|| (pDef->xValue==0 && pDef->xInverse==0)
|
||||
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
|
||||
);
|
||||
if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( pDef && pDef->xValue==0 && pExpr->pWin ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"%.*s() may not be used as a window function", nId, zId
|
||||
);
|
||||
pNC->nErr++;
|
||||
}else if(
|
||||
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
|
||||
|| (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
|
||||
|| (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
|
||||
|| (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
|
||||
|| (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
|
||||
){
|
||||
const char *zType;
|
||||
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
|
||||
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
|
||||
zType = "window";
|
||||
}else{
|
||||
zType = "aggregate";
|
||||
@@ -820,7 +823,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
if( is_agg ){
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
|
||||
pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
|
||||
#else
|
||||
pNC->ncFlags &= ~NC_AllowAgg;
|
||||
#endif
|
||||
@@ -829,17 +832,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
sqlite3WalkExprList(pWalker, pList);
|
||||
if( is_agg ){
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( pExpr->y.pWin ){
|
||||
if( pExpr->pWin ){
|
||||
Select *pSel = pNC->pWinSelect;
|
||||
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
|
||||
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
|
||||
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
|
||||
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
|
||||
sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
|
||||
sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
|
||||
sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
|
||||
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
|
||||
if( 0==pSel->pWin
|
||||
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
|
||||
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
|
||||
){
|
||||
pExpr->y.pWin->pNextWin = pSel->pWin;
|
||||
pSel->pWin = pExpr->y.pWin;
|
||||
pExpr->pWin->pNextWin = pSel->pWin;
|
||||
pSel->pWin = pExpr->pWin;
|
||||
}
|
||||
pNC->ncFlags |= NC_AllowWin;
|
||||
}else
|
||||
@@ -1262,13 +1265,13 @@ static int resolveOrderGroupBy(
|
||||
for(j=0; j<pSelect->pEList->nExpr; j++){
|
||||
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(pE, EP_WinFunc) ){
|
||||
if( pE->pWin ){
|
||||
/* Since this window function is being changed into a reference
|
||||
** to the same window function the result set, remove the instance
|
||||
** of this window function from the Select.pWin list. */
|
||||
Window **pp;
|
||||
for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
|
||||
if( *pp==pE->y.pWin ){
|
||||
if( *pp==pE->pWin ){
|
||||
*pp = (*pp)->pNextWin;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-34
@@ -803,7 +803,7 @@ static void selectExprDefer(
|
||||
struct ExprList_item *pItem = &pEList->a[i];
|
||||
if( pItem->u.x.iOrderByCol==0 ){
|
||||
Expr *pExpr = pItem->pExpr;
|
||||
Table *pTab = pExpr->y.pTab;
|
||||
Table *pTab = pExpr->pTab;
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
|
||||
&& (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
|
||||
){
|
||||
@@ -826,12 +826,12 @@ static void selectExprDefer(
|
||||
Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
|
||||
if( pNew ){
|
||||
pNew->iTable = pExpr->iTable;
|
||||
pNew->y.pTab = pExpr->y.pTab;
|
||||
pNew->pTab = pExpr->pTab;
|
||||
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
|
||||
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
|
||||
}
|
||||
}
|
||||
pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
|
||||
pSort->aDefer[nDefer].pTab = pExpr->pTab;
|
||||
pSort->aDefer[nDefer].iCsr = pExpr->iTable;
|
||||
pSort->aDefer[nDefer].nKey = nKey;
|
||||
nDefer++;
|
||||
@@ -1680,7 +1680,7 @@ static const char *columnTypeImpl(
|
||||
break;
|
||||
}
|
||||
|
||||
assert( pTab && pExpr->y.pTab==pTab );
|
||||
assert( pTab && pExpr->pTab==pTab );
|
||||
if( pS ){
|
||||
/* The "table" is actually a sub-select or a view in the FROM clause
|
||||
** of the SELECT statement. Return the declaration type and origin
|
||||
@@ -1865,7 +1865,7 @@ static void generateColumnNames(
|
||||
|
||||
assert( p!=0 );
|
||||
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
|
||||
assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
|
||||
assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
|
||||
if( pEList->a[i].zName ){
|
||||
/* An AS clause always takes first priority */
|
||||
char *zName = pEList->a[i].zName;
|
||||
@@ -1873,7 +1873,7 @@ static void generateColumnNames(
|
||||
}else if( srcName && p->op==TK_COLUMN ){
|
||||
char *zCol;
|
||||
int iCol = p->iColumn;
|
||||
pTab = p->y.pTab;
|
||||
pTab = p->pTab;
|
||||
assert( pTab!=0 );
|
||||
if( iCol<0 ) iCol = pTab->iPKey;
|
||||
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
|
||||
@@ -1964,7 +1964,7 @@ int sqlite3ColumnsFromExprList(
|
||||
if( pColExpr->op==TK_COLUMN ){
|
||||
/* For columns use the column name name */
|
||||
int iCol = pColExpr->iColumn;
|
||||
Table *pTab = pColExpr->y.pTab;
|
||||
Table *pTab = pColExpr->pTab;
|
||||
assert( pTab!=0 );
|
||||
if( iCol<0 ) iCol = pTab->iPKey;
|
||||
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
|
||||
@@ -2318,13 +2318,6 @@ static void generateWithRecursiveQuery(
|
||||
Expr *pLimit; /* Saved LIMIT and OFFSET */
|
||||
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( p->pWin ){
|
||||
sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Obtain authorization to do a recursive query */
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
|
||||
|
||||
@@ -4074,7 +4067,7 @@ static int flattenSubquery(
|
||||
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
|
||||
|
||||
/*
|
||||
** A structure to keep track of all of the column values that are fixed to
|
||||
** A structure to keep track of all of the column values that fixed to
|
||||
** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
|
||||
*/
|
||||
typedef struct WhereConst WhereConst;
|
||||
@@ -4086,28 +4079,13 @@ struct WhereConst {
|
||||
};
|
||||
|
||||
/*
|
||||
** Add a new entry to the pConst object. Except, do not add duplicate
|
||||
** pColumn entires.
|
||||
** Add a new entry to the pConst object
|
||||
*/
|
||||
static void constInsert(
|
||||
WhereConst *pConst, /* The WhereConst into which we are inserting */
|
||||
Expr *pColumn, /* The COLUMN part of the constraint */
|
||||
Expr *pValue /* The VALUE part of the constraint */
|
||||
WhereConst *pConst,
|
||||
Expr *pColumn,
|
||||
Expr *pValue
|
||||
){
|
||||
int i;
|
||||
assert( pColumn->op==TK_COLUMN );
|
||||
|
||||
/* 2018-10-25 ticket [cf5ed20f]
|
||||
** Make sure the same pColumn is not inserted more than once */
|
||||
for(i=0; i<pConst->nConst; i++){
|
||||
const Expr *pExpr = pConst->apExpr[i*2];
|
||||
assert( pExpr->op==TK_COLUMN );
|
||||
if( pExpr->iTable==pColumn->iTable
|
||||
&& pExpr->iColumn==pColumn->iColumn
|
||||
){
|
||||
return; /* Already present. Return without doing anything. */
|
||||
}
|
||||
}
|
||||
|
||||
pConst->nConst++;
|
||||
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
|
||||
|
||||
+147
-272
@@ -1059,12 +1059,11 @@ struct ShellState {
|
||||
|
||||
/* Allowed values for ShellState.openMode
|
||||
*/
|
||||
#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
|
||||
#define SHELL_OPEN_NORMAL 1 /* Normal database file */
|
||||
#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
|
||||
#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
|
||||
#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
|
||||
#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
|
||||
#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
|
||||
#define SHELL_OPEN_NORMAL 1 /* Normal database file */
|
||||
#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
|
||||
#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
|
||||
#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
|
||||
|
||||
/*
|
||||
** These are the allowed shellFlgs values
|
||||
@@ -1274,7 +1273,7 @@ static void editFunc(
|
||||
if( bBin ){
|
||||
sqlite3_result_blob64(context, p, sz, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_int64 i, j;
|
||||
int i, j;
|
||||
if( hasCRNL ){
|
||||
/* If the original contains \r\n then do no conversions back to \n */
|
||||
j = sz;
|
||||
@@ -3336,238 +3335,137 @@ static int run_schema_dump_query(
|
||||
}
|
||||
|
||||
/*
|
||||
** Text of help messages.
|
||||
**
|
||||
** The help text for each individual command begins with a line that starts
|
||||
** with ".". Subsequent lines are supplimental information.
|
||||
**
|
||||
** There must be two or more spaces between the end of the command and the
|
||||
** start of the description of what that command does.
|
||||
** Text of a help message
|
||||
*/
|
||||
static const char *(azHelp[]) = {
|
||||
static char zHelp[] =
|
||||
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
".archive ... Manage SQL archives",
|
||||
" Each command must have exactly one of the following options:",
|
||||
" -c, --create Create a new archive",
|
||||
" -u, --update Update or add files to an existing archive",
|
||||
" -t, --list List contents of archive",
|
||||
" -x, --extract Extract files from archive",
|
||||
" Optional arguments:",
|
||||
" -v, --verbose Print each filename as it is processed",
|
||||
" -f FILE, --file FILE Operate on archive FILE (default is current db)",
|
||||
" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS",
|
||||
" -C DIR, --directory DIR Change to directory DIR to read/extract files",
|
||||
" -n, --dryrun Show the SQL that would have occurred",
|
||||
" Examples:",
|
||||
" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar",
|
||||
" .ar -tf archive.sar # List members of archive.sar",
|
||||
" .ar -xvf archive.sar # Verbosely extract files from archive.sar",
|
||||
" See also:",
|
||||
" http://sqlite.org/cli.html#sqlar_archive_support",
|
||||
".archive ... Manage SQL archives: \".archive --help\" for details\n"
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
".auth ON|OFF Show authorizer callbacks",
|
||||
".auth ON|OFF Show authorizer callbacks\n"
|
||||
#endif
|
||||
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
|
||||
" --append Use the appendvfs",
|
||||
".bail on|off Stop after hitting an error. Default OFF",
|
||||
".binary on|off Turn binary output on or off. Default OFF",
|
||||
".cd DIRECTORY Change the working directory to DIRECTORY",
|
||||
".changes on|off Show number of rows changed by SQL",
|
||||
".check GLOB Fail if output since .testcase does not match",
|
||||
".clone NEWDB Clone data into NEWDB from the existing database",
|
||||
".databases List names and files of attached databases",
|
||||
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
|
||||
".dbinfo ?DB? Show status information about the database",
|
||||
".dump ?TABLE? ... Render all database content as SQL",
|
||||
" Options:",
|
||||
" --preserve-rowids Include ROWID values in the output",
|
||||
" --newlines Allow unescaped newline characters in output",
|
||||
" TABLE is LIKE pattern for the tables to dump",
|
||||
".echo on|off Turn command echo on or off",
|
||||
".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN",
|
||||
".excel Display the output of next command in a spreadsheet",
|
||||
".exit ?CODE? Exit this program with return-code CODE",
|
||||
".expert EXPERIMENTAL. Suggest indexes for specified queries",
|
||||
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
|
||||
" Add \"--append\" to open using appendvfs.\n"
|
||||
".bail on|off Stop after hitting an error. Default OFF\n"
|
||||
".binary on|off Turn binary output on or off. Default OFF\n"
|
||||
".cd DIRECTORY Change the working directory to DIRECTORY\n"
|
||||
".changes on|off Show number of rows changed by SQL\n"
|
||||
".check GLOB Fail if output since .testcase does not match\n"
|
||||
".clone NEWDB Clone data into NEWDB from the existing database\n"
|
||||
".databases List names and files of attached databases\n"
|
||||
".dbconfig ?op? ?val? List or change sqlite3_db_config() options\n"
|
||||
".dbinfo ?DB? Show status information about the database\n"
|
||||
".dump ?TABLE? ... Dump the database in an SQL text format\n"
|
||||
" If TABLE specified, only dump tables matching\n"
|
||||
" LIKE pattern TABLE.\n"
|
||||
".echo on|off Turn command echo on or off\n"
|
||||
".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
|
||||
".excel Display the output of next command in a spreadsheet\n"
|
||||
".exit Exit this program\n"
|
||||
".expert EXPERIMENTAL. Suggest indexes for specified queries\n"
|
||||
/* Because explain mode comes on automatically now, the ".explain" mode
|
||||
** is removed from the help screen. It is still supported for legacy, however */
|
||||
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/
|
||||
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
|
||||
".headers on|off Turn display of headers on or off",
|
||||
".help ?-all? ?PATTERN? Show help text for PATTERN",
|
||||
".import FILE TABLE Import data from FILE into TABLE",
|
||||
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
|
||||
".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
|
||||
".headers on|off Turn display of headers on or off\n"
|
||||
".help Show this message\n"
|
||||
".import FILE TABLE Import data from FILE into TABLE\n"
|
||||
#ifndef SQLITE_OMIT_TEST_CONTROL
|
||||
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
|
||||
".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
|
||||
#endif
|
||||
".indexes ?TABLE? Show names of indexes",
|
||||
" If TABLE is specified, only show indexes for",
|
||||
" tables matching TABLE using the LIKE operator.",
|
||||
".indexes ?TABLE? Show names of all indexes\n"
|
||||
" If TABLE specified, only show indexes for tables\n"
|
||||
" matching LIKE pattern TABLE.\n"
|
||||
#ifdef SQLITE_ENABLE_IOTRACE
|
||||
".iotrace FILE Enable I/O diagnostic logging to FILE",
|
||||
".iotrace FILE Enable I/O diagnostic logging to FILE\n"
|
||||
#endif
|
||||
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
|
||||
".lint OPTIONS Report potential schema issues.",
|
||||
" Options:",
|
||||
" fkey-indexes Find missing foreign key indexes",
|
||||
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
|
||||
".lint OPTIONS Report potential schema issues. Options:\n"
|
||||
" fkey-indexes Find missing foreign key indexes\n"
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
".load FILE ?ENTRY? Load an extension library",
|
||||
".load FILE ?ENTRY? Load an extension library\n"
|
||||
#endif
|
||||
".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
|
||||
".mode MODE ?TABLE? Set output mode",
|
||||
" MODE is one of:",
|
||||
" ascii Columns/rows delimited by 0x1F and 0x1E",
|
||||
" csv Comma-separated values",
|
||||
" column Left-aligned columns. (See .width)",
|
||||
" html HTML <table> code",
|
||||
" insert SQL insert statements for TABLE",
|
||||
" line One value per line",
|
||||
" list Values delimited by \"|\"",
|
||||
" quote Escape answers as for SQL",
|
||||
" tabs Tab-separated values",
|
||||
" tcl TCL list elements",
|
||||
".nullvalue STRING Use STRING in place of NULL values",
|
||||
".once (-e|-x|FILE) Output for the next SQL command only to FILE",
|
||||
" If FILE begins with '|' then open as a pipe",
|
||||
" Other options:",
|
||||
" -e Invoke system text editor",
|
||||
" -x Open in a spreadsheet",
|
||||
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
|
||||
" Options:",
|
||||
" --append Use appendvfs to append database to the end of FILE",
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
" --deserialize Load into memory useing sqlite3_deserialize()",
|
||||
#endif
|
||||
" --new Initialize FILE to an empty database",
|
||||
" --readonly Open FILE readonly",
|
||||
" --zip FILE is a ZIP archive",
|
||||
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
|
||||
" If FILE begins with '|' then open it as a pipe.",
|
||||
".print STRING... Print literal STRING",
|
||||
".prompt MAIN CONTINUE Replace the standard prompts",
|
||||
".quit Exit this program",
|
||||
".read FILE Read input from FILE",
|
||||
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
|
||||
".save FILE Write in-memory database into FILE",
|
||||
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
|
||||
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
|
||||
" Options:",
|
||||
" --indent Try to pretty-print the schema",
|
||||
".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
|
||||
" Options:",
|
||||
" --init Create a new SELFTEST table",
|
||||
" -v Verbose output",
|
||||
".separator COL ?ROW? Change the column and row separators",
|
||||
".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
|
||||
".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
|
||||
" ascii Columns/rows delimited by 0x1F and 0x1E\n"
|
||||
" csv Comma-separated values\n"
|
||||
" column Left-aligned columns. (See .width)\n"
|
||||
" html HTML <table> code\n"
|
||||
" insert SQL insert statements for TABLE\n"
|
||||
" line One value per line\n"
|
||||
" list Values delimited by \"|\"\n"
|
||||
" quote Escape answers as for SQL\n"
|
||||
" tabs Tab-separated values\n"
|
||||
" tcl TCL list elements\n"
|
||||
".nullvalue STRING Use STRING in place of NULL values\n"
|
||||
".once (-e|-x|FILE) Output for the next SQL command only to FILE\n"
|
||||
" or invoke system text editor (-e) or spreadsheet (-x)\n"
|
||||
" on the output.\n"
|
||||
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
|
||||
" The --new option starts with an empty file\n"
|
||||
" Other options: --readonly --append --zip\n"
|
||||
".output ?FILE? Send output to FILE or stdout\n"
|
||||
".print STRING... Print literal STRING\n"
|
||||
".prompt MAIN CONTINUE Replace the standard prompts\n"
|
||||
".quit Exit this program\n"
|
||||
".read FILENAME Execute SQL in FILENAME\n"
|
||||
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
|
||||
".save FILE Write in-memory database into FILE\n"
|
||||
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
|
||||
".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
|
||||
" Add --indent for pretty-printing\n"
|
||||
".selftest ?--init? Run tests defined in the SELFTEST table\n"
|
||||
".separator COL ?ROW? Change the column separator and optionally the row\n"
|
||||
" separator for both the output mode and .import\n"
|
||||
#if defined(SQLITE_ENABLE_SESSION)
|
||||
".session ?NAME? CMD ... Create or control sessions",
|
||||
" Subcommands:",
|
||||
" attach TABLE Attach TABLE",
|
||||
" changeset FILE Write a changeset into FILE",
|
||||
" close Close one session",
|
||||
" enable ?BOOLEAN? Set or query the enable bit",
|
||||
" filter GLOB... Reject tables matching GLOBs",
|
||||
" indirect ?BOOLEAN? Mark or query the indirect status",
|
||||
" isempty Query whether the session is empty",
|
||||
" list List currently open session names",
|
||||
" open DB NAME Open a new session on DB",
|
||||
" patchset FILE Write a patchset into FILE",
|
||||
" If ?NAME? is omitted, the first defined session is used.",
|
||||
".session CMD ... Create or control sessions\n"
|
||||
#endif
|
||||
".sha3sum ... Compute a SHA3 hash of database content",
|
||||
" Options:",
|
||||
" --schema Also hash the sqlite_master table",
|
||||
" --sha3-224 Use the sha3-224 algorithm",
|
||||
" --sha3-256 Use the sha3-256 algorithm. This is the default.",
|
||||
" --sha3-384 Use the sha3-384 algorithm",
|
||||
" --sha3-512 Use the sha3-512 algorithm",
|
||||
" Any other argument is a LIKE pattern for tables to hash",
|
||||
".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
".shell CMD ARGS... Run CMD ARGS... in a system shell",
|
||||
".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
|
||||
#endif
|
||||
".show Show the current values for various settings",
|
||||
".stats ?on|off? Show stats or turn stats on or off",
|
||||
".show Show the current values for various settings\n"
|
||||
".stats ?on|off? Show stats or turn stats on or off\n"
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
".system CMD ARGS... Run CMD ARGS... in a system shell",
|
||||
".system CMD ARGS... Run CMD ARGS... in a system shell\n"
|
||||
#endif
|
||||
".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
|
||||
".testcase NAME Begin redirecting output to 'testcase-out.txt'",
|
||||
".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",
|
||||
".vfsinfo ?AUX? Information about the top-level VFS",
|
||||
".vfslist List all available VFSes",
|
||||
".vfsname ?AUX? Print the name of the VFS stack",
|
||||
".width NUM1 NUM2 ... Set column widths for \"column\" mode",
|
||||
" Negative values right-justify",
|
||||
};
|
||||
".tables ?TABLE? List names of tables\n"
|
||||
" If TABLE specified, only list tables matching\n"
|
||||
" LIKE pattern TABLE.\n"
|
||||
".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
|
||||
".timeout MS Try opening locked tables for MS milliseconds\n"
|
||||
".timer on|off Turn SQL timer on or off\n"
|
||||
".trace FILE|off Output each SQL statement as it is run\n"
|
||||
".vfsinfo ?AUX? Information about the top-level VFS\n"
|
||||
".vfslist List all available VFSes\n"
|
||||
".vfsname ?AUX? Print the name of the VFS stack\n"
|
||||
".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
|
||||
" Negative values right-justify\n"
|
||||
;
|
||||
|
||||
#if defined(SQLITE_ENABLE_SESSION)
|
||||
/*
|
||||
** Output help text.
|
||||
**
|
||||
** zPattern describes the set of commands for which help text is provided.
|
||||
** If zPattern is NULL, then show all commands, but only give a one-line
|
||||
** description of each.
|
||||
**
|
||||
** Return the number of matches.
|
||||
** Print help information for the ".sessions" command
|
||||
*/
|
||||
static int showHelp(FILE *out, const char *zPattern){
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int n = 0;
|
||||
char *zPat;
|
||||
if( zPattern==0
|
||||
|| zPattern[0]=='0'
|
||||
|| strcmp(zPattern,"-a")==0
|
||||
|| strcmp(zPattern,"-all")==0
|
||||
){
|
||||
/* Show all commands, but only one line per command */
|
||||
if( zPattern==0 ) zPattern = "";
|
||||
for(i=0; i<ArraySize(azHelp); i++){
|
||||
if( azHelp[i][0]=='.' || zPattern[0] ){
|
||||
utf8_printf(out, "%s\n", azHelp[i]);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
/* Look for commands that for which zPattern is an exact prefix */
|
||||
zPat = sqlite3_mprintf(".%s*", zPattern);
|
||||
for(i=0; i<ArraySize(azHelp); i++){
|
||||
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
|
||||
utf8_printf(out, "%s\n", azHelp[i]);
|
||||
j = i+1;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
sqlite3_free(zPat);
|
||||
if( n ){
|
||||
if( n==1 ){
|
||||
/* when zPattern is a prefix of exactly one command, then include the
|
||||
** details of that command, which should begin at offset j */
|
||||
while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
|
||||
utf8_printf(out, "%s\n", azHelp[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
/* Look for commands that contain zPattern anywhere. Show the complete
|
||||
** text of all commands that match. */
|
||||
zPat = sqlite3_mprintf("%%%s%%", zPattern);
|
||||
for(i=0; i<ArraySize(azHelp); i++){
|
||||
if( azHelp[i][0]=='.' ) j = i;
|
||||
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
|
||||
utf8_printf(out, "%s\n", azHelp[j]);
|
||||
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
|
||||
j++;
|
||||
utf8_printf(out, "%s\n", azHelp[j]);
|
||||
}
|
||||
i = j;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
sqlite3_free(zPat);
|
||||
}
|
||||
return n;
|
||||
void session_help(ShellState *p){
|
||||
raw_printf(p->out,
|
||||
".session ?NAME? SUBCOMMAND ?ARGS...?\n"
|
||||
"If ?NAME? is omitted, the first defined session is used.\n"
|
||||
"Subcommands:\n"
|
||||
" attach TABLE Attach TABLE\n"
|
||||
" changeset FILE Write a changeset into FILE\n"
|
||||
" close Close one session\n"
|
||||
" enable ?BOOLEAN? Set or query the enable bit\n"
|
||||
" filter GLOB... Reject tables matching GLOBs\n"
|
||||
" indirect ?BOOLEAN? Mark or query the indirect status\n"
|
||||
" isempty Query whether the session is empty\n"
|
||||
" list List currently open session names\n"
|
||||
" open DB NAME Open a new session on DB\n"
|
||||
" patchset FILE Write a patchset into FILE\n"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Forward reference */
|
||||
static int process_input(ShellState *p, FILE *in);
|
||||
@@ -3597,7 +3495,7 @@ static char *readFile(const char *zName, int *pnByte){
|
||||
nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc64( nIn+1 );
|
||||
if( pBuf==0 ){ fclose(in); return 0; }
|
||||
if( pBuf==0 ) return 0;
|
||||
nRead = fread(pBuf, nIn, 1, in);
|
||||
fclose(in);
|
||||
if( nRead!=1 ){
|
||||
@@ -3677,11 +3575,6 @@ int deduceDatabaseType(const char *zName, int dfltZip){
|
||||
return SHELL_OPEN_NORMAL;
|
||||
}
|
||||
}
|
||||
n = fread(zBuf, 16, 1, f);
|
||||
if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
|
||||
fclose(f);
|
||||
return SHELL_OPEN_NORMAL;
|
||||
}
|
||||
fseek(f, -25, SEEK_END);
|
||||
n = fread(zBuf, 25, 1, f);
|
||||
if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
|
||||
@@ -3733,10 +3626,6 @@ static void open_db(ShellState *p, int openFlags){
|
||||
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
|
||||
break;
|
||||
}
|
||||
case SHELL_OPEN_DESERIALIZE: {
|
||||
sqlite3_open(0, &p->db);
|
||||
break;
|
||||
}
|
||||
case SHELL_OPEN_ZIPFILE: {
|
||||
sqlite3_open(":memory:", &p->db);
|
||||
break;
|
||||
@@ -3786,18 +3675,6 @@ static void open_db(ShellState *p, int openFlags){
|
||||
sqlite3_exec(p->db, zSql, 0, 0, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
|
||||
int nData = 0;
|
||||
unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
|
||||
int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
|
||||
SQLITE_DESERIALIZE_RESIZEABLE |
|
||||
SQLITE_DESERIALIZE_FREEONCLOSE);
|
||||
if( rc ){
|
||||
utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5002,7 +4879,6 @@ static void shellPreparePrintf(
|
||||
char *z;
|
||||
va_start(ap, zFmt);
|
||||
z = sqlite3_vmprintf(zFmt, ap);
|
||||
va_end(ap);
|
||||
if( z==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -5065,7 +4941,32 @@ struct ArCommand {
|
||||
** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
|
||||
*/
|
||||
static int arUsage(FILE *f){
|
||||
showHelp(f,"archive");
|
||||
raw_printf(f,
|
||||
"\n"
|
||||
"Usage: .ar [OPTION...] [FILE...]\n"
|
||||
"The .ar command manages sqlar archives.\n"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar\n"
|
||||
" .ar -tf archive.sar # List members of archive.sar\n"
|
||||
" .ar -xvf archive.sar # Verbosely extract files from archive.sar\n"
|
||||
"\n"
|
||||
"Each command line must feature exactly one command option:\n"
|
||||
" -c, --create Create a new archive\n"
|
||||
" -u, --update Update or add files to an existing archive\n"
|
||||
" -t, --list List contents of archive\n"
|
||||
" -x, --extract Extract files from archive\n"
|
||||
"\n"
|
||||
"And zero or more optional options:\n"
|
||||
" -v, --verbose Print each filename as it is processed\n"
|
||||
" -f FILE, --file FILE Operate on archive FILE (default is current db)\n"
|
||||
" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS\n"
|
||||
" -C DIR, --directory DIR Change to directory DIR to read/extract files\n"
|
||||
" -n, --dryrun Show the SQL that would have occurred\n"
|
||||
"\n"
|
||||
"See also: http://sqlite.org/cli.html#sqlar_archive_support\n"
|
||||
"\n"
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
@@ -5172,7 +5073,6 @@ static int arParseCommand(
|
||||
struct ArSwitch *pEnd = &aSwitch[nSwitch];
|
||||
|
||||
if( nArg<=1 ){
|
||||
utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
|
||||
return arUsage(stderr);
|
||||
}else{
|
||||
char *z = azArg[1];
|
||||
@@ -5944,10 +5844,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
|
||||
if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
|
||||
static const struct DbConfigChoices {
|
||||
const char *zName;
|
||||
int op;
|
||||
} aDbConfig[] = {
|
||||
static const struct DbConfigChoices {const char *zName; int op;} aDbConfig[] = {
|
||||
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
@@ -5956,7 +5853,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
|
||||
{ "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
|
||||
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
|
||||
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
|
||||
};
|
||||
int ii, v;
|
||||
open_db(p, 0);
|
||||
@@ -6195,14 +6091,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
|
||||
if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
|
||||
if( nArg>=2 ){
|
||||
n = showHelp(p->out, azArg[1]);
|
||||
if( n==0 ){
|
||||
utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
|
||||
}
|
||||
}else{
|
||||
showHelp(p->out, 0);
|
||||
}
|
||||
utf8_printf(p->out, "%s", zHelp);
|
||||
}else
|
||||
|
||||
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
|
||||
@@ -6679,10 +6568,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
p->openMode = SHELL_OPEN_APPENDVFS;
|
||||
}else if( optionMatch(z, "readonly") ){
|
||||
p->openMode = SHELL_OPEN_READONLY;
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
}else if( optionMatch(z, "deserialize") ){
|
||||
p->openMode = SHELL_OPEN_DESERIALIZE;
|
||||
#endif
|
||||
}else if( z[0]=='-' ){
|
||||
utf8_printf(stderr, "unknown option: %s\n", z);
|
||||
rc = 1;
|
||||
@@ -7210,7 +7095,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
/* If no command name matches, show a syntax error */
|
||||
session_syntax_error:
|
||||
showHelp(p->out, "session");
|
||||
session_help(p);
|
||||
}else
|
||||
#endif
|
||||
|
||||
@@ -8651,10 +8536,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
#endif
|
||||
}else if( strcmp(z,"-append")==0 ){
|
||||
data.openMode = SHELL_OPEN_APPENDVFS;
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
}else if( strcmp(z,"-deserialize")==0 ){
|
||||
data.openMode = SHELL_OPEN_DESERIALIZE;
|
||||
#endif
|
||||
}else if( strcmp(z,"-readonly")==0 ){
|
||||
data.openMode = SHELL_OPEN_READONLY;
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
||||
@@ -8750,10 +8631,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
#endif
|
||||
}else if( strcmp(z,"-append")==0 ){
|
||||
data.openMode = SHELL_OPEN_APPENDVFS;
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
}else if( strcmp(z,"-deserialize")==0 ){
|
||||
data.openMode = SHELL_OPEN_DESERIALIZE;
|
||||
#endif
|
||||
}else if( strcmp(z,"-readonly")==0 ){
|
||||
data.openMode = SHELL_OPEN_READONLY;
|
||||
}else if( strcmp(z,"-ascii")==0 ){
|
||||
@@ -8898,7 +8775,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
*/
|
||||
if( stdin_is_interactive ){
|
||||
char *zHome;
|
||||
char *zHistory;
|
||||
char *zHistory = 0;
|
||||
int nHistory;
|
||||
printf(
|
||||
"SQLite version %s %.19s\n" /*extra-version-info*/
|
||||
@@ -8911,10 +8788,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
printf(".\nUse \".open FILENAME\" to reopen on a "
|
||||
"persistent database.\n");
|
||||
}
|
||||
zHistory = getenv("SQLITE_HISTORY");
|
||||
if( zHistory ){
|
||||
zHistory = strdup(zHistory);
|
||||
}else if( (zHome = find_home_dir(0))!=0 ){
|
||||
zHome = find_home_dir(0);
|
||||
if( zHome ){
|
||||
nHistory = strlen30(zHome) + 20;
|
||||
if( (zHistory = malloc(nHistory))!=0 ){
|
||||
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
|
||||
|
||||
+3
-44
@@ -2158,29 +2158,6 @@ struct sqlite3_mem_methods {
|
||||
** Because resetting a database is destructive and irreversible, the
|
||||
** process requires the use of this obscure API and multiple steps to help
|
||||
** ensure that it does not happen by accident.
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option actives or deactivates the
|
||||
** "defensive" flag for a database connection. When the defensive
|
||||
** flag is enabled, some obscure features of SQLite are disabled in order
|
||||
** to reduce the attack surface. Applications that run untrusted SQL
|
||||
** can activate this flag to reduce the risk of zero-day exploits.
|
||||
** <p>
|
||||
** Features disabled by the defensive flag include:
|
||||
** <ul>
|
||||
** <li>The [PRAGMA writable_schema=ON] statement.
|
||||
** <li>Writes to the [sqlite_dbpage] virtual table.
|
||||
** </ul>
|
||||
** New restrictions may be added in future releases.
|
||||
** <p>
|
||||
** To be clear: It should never be possible for hostile SQL to cause
|
||||
** arbitrary memory reads, memory leaks, buffer overflows, assertion
|
||||
** faults, arbitrary code execution, crashes, or other mischief, regardless
|
||||
** of the value of the defensive flag. Any occurrance of these problems
|
||||
** is considered a serious bug and will be fixed promptly. It is not
|
||||
** necessary to enable the defensive flag in order to make SQLite secure
|
||||
** against attack. The defensive flag merely provides an additional layer
|
||||
** of defense against unknown vulnerabilities.
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
@@ -2194,8 +2171,7 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
|
||||
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
|
||||
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
@@ -3633,19 +3609,9 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** on this hint by avoiding the use of [lookaside memory] so as not to
|
||||
** deplete the limited store of lookaside memory. Future versions of
|
||||
** SQLite may act on this hint differently.
|
||||
**
|
||||
** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
|
||||
** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
|
||||
** representation of the SQL statement should be calculated and then
|
||||
** associated with the prepared statement, which can be obtained via
|
||||
** the [sqlite3_normalized_sql()] interface. The semantics used to
|
||||
** normalize a SQL statement are unspecified and subject to change.
|
||||
** At a minimum, literal values will be replaced with suitable
|
||||
** placeholders.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_PREPARE_PERSISTENT 0x01
|
||||
#define SQLITE_PREPARE_NORMALIZE 0x02
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compiling An SQL Statement
|
||||
@@ -3803,11 +3769,6 @@ int sqlite3_prepare16_v3(
|
||||
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
|
||||
** string containing the SQL text of prepared statement P with
|
||||
** [bound parameters] expanded.
|
||||
** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
|
||||
** string containing the normalized SQL text of prepared statement P. The
|
||||
** semantics used to normalize a SQL statement are unspecified and subject
|
||||
** to change. At a minimum, literal values will be replaced with suitable
|
||||
** placeholders.
|
||||
**
|
||||
** ^(For example, if a prepared statement is created using the SQL
|
||||
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
|
||||
@@ -3823,16 +3784,14 @@ int sqlite3_prepare16_v3(
|
||||
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
|
||||
** option causes sqlite3_expanded_sql() to always return NULL.
|
||||
**
|
||||
** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
|
||||
** are managed by SQLite and are automatically freed when the prepared
|
||||
** statement is finalized.
|
||||
** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
|
||||
** automatically freed when the prepared statement is finalized.
|
||||
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
|
||||
** is obtained from [sqlite3_malloc()] and must be free by the application
|
||||
** by passing it to [sqlite3_free()].
|
||||
*/
|
||||
const char *sqlite3_sql(sqlite3_stmt *pStmt);
|
||||
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
|
||||
const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If An SQL Statement Writes The Database
|
||||
|
||||
@@ -310,15 +310,12 @@ struct sqlite3_api_routines {
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -606,8 +603,6 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+12
-44
@@ -1305,14 +1305,12 @@ struct LookasideSlot {
|
||||
** functions use a regular table table from hash.h.)
|
||||
**
|
||||
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
|
||||
** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
|
||||
** macro to compute a hash on the function name.
|
||||
** Collisions are on the FuncDef.u.pHash chain.
|
||||
*/
|
||||
#define SQLITE_FUNC_HASH_SZ 23
|
||||
struct FuncDefHash {
|
||||
FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
|
||||
};
|
||||
#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
|
||||
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
/*
|
||||
@@ -1373,7 +1371,7 @@ struct sqlite3 {
|
||||
Db *aDb; /* All backends */
|
||||
int nDb; /* Number of backends currently in use */
|
||||
u32 mDbFlags; /* flags recording internal state */
|
||||
u64 flags; /* flags settable by pragmas. See below */
|
||||
u32 flags; /* flags settable by pragmas. See below */
|
||||
i64 lastRowid; /* ROWID of most recent insert (see above) */
|
||||
i64 szMmap; /* Default mmap_size setting */
|
||||
u32 nSchemaLock; /* Do not reset the schema when non-zero */
|
||||
@@ -1539,17 +1537,14 @@ struct sqlite3 {
|
||||
#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
|
||||
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
|
||||
#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
|
||||
#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
|
||||
|
||||
/* Flags used only if debugging */
|
||||
#define HI(X) ((u64)(X)<<32)
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
|
||||
#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
|
||||
#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1948,9 +1943,6 @@ struct VTable {
|
||||
struct Table {
|
||||
char *zName; /* Name of the table or view */
|
||||
Column *aCol; /* Information about each column */
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
Hash *pColHash; /* All columns indexed by name */
|
||||
#endif
|
||||
Index *pIndex; /* List of SQL indexes on this table. */
|
||||
Select *pSelect; /* NULL for tables. Points to definition if a view. */
|
||||
FKey *pFKey; /* Linked list of all foreign keys in this table */
|
||||
@@ -2287,12 +2279,6 @@ struct IndexSample {
|
||||
tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
|
||||
};
|
||||
|
||||
/*
|
||||
** Possible values to use within the flags argument to sqlite3GetToken().
|
||||
*/
|
||||
#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */
|
||||
#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */
|
||||
|
||||
/*
|
||||
** Each token coming out of the lexer is an instance of
|
||||
** this structure. Tokens are also used as part of an expression.
|
||||
@@ -2474,11 +2460,11 @@ struct Expr {
|
||||
** TK_COLUMN: the value of p5 for OP_Column
|
||||
** TK_AGG_FUNCTION: nesting depth */
|
||||
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
|
||||
union {
|
||||
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
|
||||
** for a column of an index on an expression */
|
||||
Window *pWin; /* TK_FUNCTION: Window definition for the func */
|
||||
} y;
|
||||
Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
|
||||
** for a column of an index on an expression */
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
Window *pWin; /* Window definition for window functions */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2508,7 +2494,6 @@ struct Expr {
|
||||
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
|
||||
#define EP_Alias 0x400000 /* Is an alias for a result set column */
|
||||
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
|
||||
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
|
||||
|
||||
/*
|
||||
** The EP_Propagate mask is a set of properties that automatically propagate
|
||||
@@ -3194,7 +3179,6 @@ struct AuthContext {
|
||||
*/
|
||||
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
|
||||
/* Also used in P2 (not P5) of OP_Delete */
|
||||
#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
|
||||
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
|
||||
#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
|
||||
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
|
||||
@@ -3666,7 +3650,6 @@ int sqlite3IsIdChar(u8);
|
||||
*/
|
||||
int sqlite3StrICmp(const char*,const char*);
|
||||
int sqlite3Strlen30(const char*);
|
||||
#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
|
||||
char *sqlite3ColumnType(Column*,char*);
|
||||
#define sqlite3StrNICmp sqlite3_strnicmp
|
||||
|
||||
@@ -3783,7 +3766,6 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
|
||||
void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
|
||||
void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
|
||||
void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
|
||||
void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
|
||||
void sqlite3TreeViewWith(TreeView*, const With*, u8);
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
@@ -4016,15 +3998,11 @@ int sqlite3ExprIsInteger(Expr*, int*);
|
||||
int sqlite3ExprCanBeNull(const Expr*);
|
||||
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
|
||||
int sqlite3IsRowid(const char*);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
int sqlite3IsRowidN(const char*, int);
|
||||
#endif
|
||||
void sqlite3GenerateRowDelete(
|
||||
Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
|
||||
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
|
||||
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
|
||||
void sqlite3ResolvePartIdxLabel(Parse*,int);
|
||||
int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
|
||||
void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
|
||||
u8,u8,int,int*,int*,Upsert*);
|
||||
#ifdef SQLITE_ENABLE_NULL_TRIM
|
||||
@@ -4045,9 +4023,6 @@ ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
|
||||
SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
|
||||
IdList *sqlite3IdListDup(sqlite3*,IdList*);
|
||||
Select *sqlite3SelectDup(sqlite3*,Select*,int);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
FuncDef *sqlite3FunctionSearchN(int,const char*,int);
|
||||
#endif
|
||||
void sqlite3InsertBuiltinFuncs(FuncDef*,int);
|
||||
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
|
||||
void sqlite3RegisterBuiltinFunctions(void);
|
||||
@@ -4205,7 +4180,6 @@ Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
|
||||
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
|
||||
Expr *sqlite3ExprSkipCollate(Expr*);
|
||||
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
||||
int sqlite3WritableSchema(sqlite3*);
|
||||
int sqlite3CheckObjectName(Parse *, const char *);
|
||||
void sqlite3VdbeSetChanges(sqlite3 *, int);
|
||||
int sqlite3AddInt64(i64*,i64);
|
||||
@@ -4252,9 +4226,6 @@ void sqlite3AlterFunctions(void);
|
||||
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
|
||||
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
|
||||
int sqlite3GetToken(const unsigned char *, int *);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
|
||||
#endif
|
||||
void sqlite3NestedParse(Parse*, const char*, ...);
|
||||
void sqlite3ExpirePreparedStatements(sqlite3*, int);
|
||||
int sqlite3CodeSubselect(Parse*, Expr *, int, int);
|
||||
@@ -4412,9 +4383,6 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
|
||||
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
|
||||
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
|
||||
void sqlite3ParserReset(Parse*);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
void sqlite3Normalize(Vdbe*, const char*, int, u8);
|
||||
#endif
|
||||
int sqlite3Reprepare(Vdbe*);
|
||||
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
|
||||
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
|
||||
|
||||
+1
-102
@@ -4218,7 +4218,6 @@ static int SQLITE_TCLAPI test_prepare_v2(
|
||||
char *zCopy = 0; /* malloc() copy of zSql */
|
||||
int bytes;
|
||||
const char *zTail = 0;
|
||||
const char **pzTail;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char zBuf[50];
|
||||
int rc;
|
||||
@@ -4243,8 +4242,7 @@ static int SQLITE_TCLAPI test_prepare_v2(
|
||||
zCopy = malloc(n);
|
||||
memcpy(zCopy, zSql, n);
|
||||
}
|
||||
pzTail = objc>=5 ? &zTail : 0;
|
||||
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, pzTail);
|
||||
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
|
||||
free(zCopy);
|
||||
zTail = &zSql[(zTail - zCopy)];
|
||||
|
||||
@@ -4271,79 +4269,6 @@ static int SQLITE_TCLAPI test_prepare_v2(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_prepare_v3 DB sql bytes flags ?tailvar?
|
||||
**
|
||||
** Compile up to <bytes> bytes of the supplied SQL string <sql> using
|
||||
** database handle <DB> and flags <flags>. The parameter <tailval> is
|
||||
** the name of a global variable that is set to the unused portion of
|
||||
** <sql> (if any). A STMT handle is returned.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_prepare_v3(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zSql;
|
||||
char *zCopy = 0; /* malloc() copy of zSql */
|
||||
int bytes, flags;
|
||||
const char *zTail = 0;
|
||||
const char **pzTail;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char zBuf[50];
|
||||
int rc;
|
||||
|
||||
if( objc!=6 && objc!=5 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetString(objv[0]), " DB sql bytes flags tailvar", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zSql = Tcl_GetString(objv[2]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &flags) ) 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);
|
||||
}
|
||||
pzTail = objc>=6 ? &zTail : 0;
|
||||
rc = sqlite3_prepare_v3(db, zCopy, bytes, (unsigned int)flags,&pStmt,pzTail);
|
||||
free(zCopy);
|
||||
zTail = &zSql[(zTail - zCopy)];
|
||||
|
||||
assert(rc==SQLITE_OK || pStmt==0);
|
||||
Tcl_ResetResult(interp);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
if( rc==SQLITE_OK && zTail && objc>=6 ){
|
||||
if( bytes>=0 ){
|
||||
bytes = bytes - (int)(zTail-zSql);
|
||||
}
|
||||
Tcl_ObjSetVar2(interp, objv[5], 0, Tcl_NewStringObj(zTail, bytes), 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pStmt==0 );
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
|
||||
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( pStmt ){
|
||||
if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_prepare_tkt3134 DB
|
||||
**
|
||||
@@ -4751,25 +4676,6 @@ static int SQLITE_TCLAPI test_ex_sql(
|
||||
sqlite3_free(z);
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
static int SQLITE_TCLAPI test_norm_sql(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
Tcl_SetResult(interp, (char *)sqlite3_normalized_sql(pStmt), TCL_VOLATILE);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_column_count STMT
|
||||
@@ -7132,7 +7038,6 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
|
||||
extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_explain_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*);
|
||||
@@ -7157,7 +7062,6 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
|
||||
{ "closure", sqlite3_closure_init },
|
||||
{ "csv", sqlite3_csv_init },
|
||||
{ "eval", sqlite3_eval_init },
|
||||
{ "explain", sqlite3_explain_init },
|
||||
{ "fileio", sqlite3_fileio_init },
|
||||
{ "fuzzer", sqlite3_fuzzer_init },
|
||||
{ "ieee754", sqlite3_ieee_init },
|
||||
@@ -7556,7 +7460,6 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
|
||||
{ "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG },
|
||||
{ "TRIGGER_EQP", SQLITE_DBCONFIG_TRIGGER_EQP },
|
||||
{ "RESET_DB", SQLITE_DBCONFIG_RESET_DATABASE },
|
||||
{ "DEFENSIVE", SQLITE_DBCONFIG_DEFENSIVE },
|
||||
};
|
||||
int i;
|
||||
int v;
|
||||
@@ -7741,7 +7644,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_prepare", test_prepare ,0 },
|
||||
{ "sqlite3_prepare16", test_prepare16 ,0 },
|
||||
{ "sqlite3_prepare_v2", test_prepare_v2 ,0 },
|
||||
{ "sqlite3_prepare_v3", test_prepare_v3 ,0 },
|
||||
{ "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0},
|
||||
{ "sqlite3_prepare16_v2", test_prepare16_v2 ,0 },
|
||||
{ "sqlite3_finalize", test_finalize ,0 },
|
||||
@@ -7753,9 +7655,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_step", test_step ,0 },
|
||||
{ "sqlite3_sql", test_sql ,0 },
|
||||
{ "sqlite3_expanded_sql", test_ex_sql ,0 },
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
{ "sqlite3_normalized_sql", test_norm_sql ,0 },
|
||||
#endif
|
||||
{ "sqlite3_next_stmt", test_next_stmt ,0 },
|
||||
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 },
|
||||
{ "sqlite3_stmt_busy", test_stmt_busy ,0 },
|
||||
|
||||
+1
-7
@@ -124,7 +124,7 @@ static void set_options(Tcl_Interp *interp){
|
||||
STRINGVALUE(SQLITE_MAX_WORKER_THREADS), TCL_GLOBAL_ONLY
|
||||
);
|
||||
|
||||
#ifdef SQLITE_MEMDEBUG
|
||||
#if 1 /* def SQLITE_MEMDEBUG */
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
|
||||
@@ -762,12 +762,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_ENABLE_NORMALIZE)
|
||||
Tcl_SetVar2(interp, "sqlite_options", "normalize", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "normalize", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_WINDOWFUNC
|
||||
Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
||||
+1
-4
@@ -13,10 +13,6 @@
|
||||
** This file implements a read-only VIRTUAL TABLE that contains the
|
||||
** content of a C-language array of integer values. See the corresponding
|
||||
** header file for full details.
|
||||
**
|
||||
** This virtual table is used for internal testing of SQLite only. It is
|
||||
** not recommended for use in production. For a similar virtual table that
|
||||
** is production-ready, see the "carray" virtual table over in ext/misc.
|
||||
*/
|
||||
#include "test_intarray.h"
|
||||
#include <string.h>
|
||||
@@ -319,6 +315,7 @@ static int SQLITE_TCLAPI test_intarray_create(
|
||||
rc = sqlite3_intarray_create(db, zName, &pArray);
|
||||
#endif
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pArray==0 );
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+1
-8
@@ -13,10 +13,6 @@
|
||||
** This is the C-language interface definition for the "intarray" or
|
||||
** integer array virtual table for SQLite.
|
||||
**
|
||||
** This virtual table is used for internal testing of SQLite only. It is
|
||||
** not recommended for use in production. For a similar virtual table that
|
||||
** is production-ready, see the "carray" virtual table over in ext/misc.
|
||||
**
|
||||
** The intarray virtual table is designed to facilitate using an
|
||||
** array of integers as the right-hand side of an IN operator. So
|
||||
** instead of doing a prepared statement like this:
|
||||
@@ -76,10 +72,7 @@
|
||||
** virtual table is dropped. Since the virtual tables are created in the
|
||||
** TEMP database, they are automatically dropped when the database connection
|
||||
** closes so the application does not normally need to take any special
|
||||
** action to free the intarray objects. Because of the way virtual tables
|
||||
** work and the (somewhat goofy) way that the intarray virtual table is
|
||||
** implemented, it is not allowed to invoke sqlite3_intarray_create(D,N,P)
|
||||
** more than once with the same D and N values.
|
||||
** action to free the intarray objects.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#ifndef SQLITE_INTARRAY_H
|
||||
|
||||
@@ -560,7 +560,6 @@ static int fsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||
** File control method. For custom operations on an fs-file.
|
||||
*/
|
||||
static int fsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||
if( op==SQLITE_FCNTL_PRAGMA ) return SQLITE_NOTFOUND;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -545,73 +545,6 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
/*
|
||||
** Return the length (in bytes) of the token that begins at z[0].
|
||||
** Store the token type in *tokenType before returning. If flags has
|
||||
** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
|
||||
** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was
|
||||
** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags
|
||||
** if the token was recognized as a keyword; this is useful when the
|
||||
** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
|
||||
** to differentiate between a keyword being treated as an identifier
|
||||
** (for normalization purposes) and an actual identifier.
|
||||
*/
|
||||
int sqlite3GetTokenNormalized(
|
||||
const unsigned char *z,
|
||||
int *tokenType,
|
||||
int *flags
|
||||
){
|
||||
int n;
|
||||
unsigned char iClass = aiClass[*z];
|
||||
if( iClass==CC_KYWD ){
|
||||
int i;
|
||||
for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
|
||||
if( IdChar(z[i]) ){
|
||||
/* This token started out using characters that can appear in keywords,
|
||||
** but z[i] is a character not allowed within keywords, so this must
|
||||
** be an identifier instead */
|
||||
i++;
|
||||
while( IdChar(z[i]) ){ i++; }
|
||||
*tokenType = TK_ID;
|
||||
return i;
|
||||
}
|
||||
*tokenType = TK_ID;
|
||||
n = keywordCode((char*)z, i, tokenType);
|
||||
/* If the token is no longer considered to be an identifier, then it is a
|
||||
** keyword of some kind. Make the token back into an identifier and then
|
||||
** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are
|
||||
** used verbatim, including IN, IS, NOT, and NULL. */
|
||||
switch( *tokenType ){
|
||||
case TK_ID: {
|
||||
/* do nothing, handled by caller */
|
||||
break;
|
||||
}
|
||||
case TK_IN:
|
||||
case TK_IS:
|
||||
case TK_NOT:
|
||||
case TK_NULL: {
|
||||
*flags |= SQLITE_TOKEN_KEYWORD;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*tokenType = TK_ID;
|
||||
*flags |= SQLITE_TOKEN_KEYWORD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
n = sqlite3GetToken(z, tokenType);
|
||||
/* If the token is considered to be an identifier and the character class
|
||||
** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
|
||||
if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
|
||||
*flags |= SQLITE_TOKEN_QUOTED;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
/*
|
||||
** Run the parser on the given SQL string. The parser structure is
|
||||
** passed in. An SQLITE_ status code is returned. If an error occurs
|
||||
|
||||
+32
-38
@@ -121,42 +121,6 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate a human-readable description of a SrcList object.
|
||||
*/
|
||||
void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
|
||||
int i;
|
||||
for(i=0; i<pSrc->nSrc; i++){
|
||||
const struct SrcList_item *pItem = &pSrc->a[i];
|
||||
StrAccum x;
|
||||
char zLine[100];
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
}else if( pItem->zName ){
|
||||
sqlite3_str_appendf(&x, " %s", pItem->zName);
|
||||
}
|
||||
if( pItem->pTab ){
|
||||
sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
|
||||
}
|
||||
if( pItem->zAlias ){
|
||||
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
|
||||
}
|
||||
if( pItem->fg.jointype & JT_LEFT ){
|
||||
sqlite3_str_appendf(&x, " LEFT-JOIN");
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
|
||||
if( pItem->pSelect ){
|
||||
sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
|
||||
}
|
||||
if( pItem->fg.isTabFunc ){
|
||||
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
|
||||
}
|
||||
sqlite3TreeViewPop(pView);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate a human-readable description of a Select object.
|
||||
@@ -211,9 +175,39 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
}
|
||||
#endif
|
||||
if( p->pSrc && p->pSrc->nSrc ){
|
||||
int i;
|
||||
pView = sqlite3TreeViewPush(pView, (n--)>0);
|
||||
sqlite3TreeViewLine(pView, "FROM");
|
||||
sqlite3TreeViewSrcList(pView, p->pSrc);
|
||||
for(i=0; i<p->pSrc->nSrc; i++){
|
||||
struct SrcList_item *pItem = &p->pSrc->a[i];
|
||||
StrAccum x;
|
||||
char zLine[100];
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
}else if( pItem->zName ){
|
||||
sqlite3_str_appendf(&x, " %s", pItem->zName);
|
||||
}
|
||||
if( pItem->pTab ){
|
||||
sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
|
||||
}
|
||||
if( pItem->zAlias ){
|
||||
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
|
||||
}
|
||||
if( pItem->fg.jointype & JT_LEFT ){
|
||||
sqlite3_str_appendf(&x, " LEFT-JOIN");
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
|
||||
if( pItem->pSelect ){
|
||||
sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
|
||||
}
|
||||
if( pItem->fg.isTabFunc ){
|
||||
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
|
||||
}
|
||||
sqlite3TreeViewPop(pView);
|
||||
}
|
||||
sqlite3TreeViewPop(pView);
|
||||
}
|
||||
if( p->pWhere ){
|
||||
@@ -503,7 +497,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
}else{
|
||||
pFarg = pExpr->x.pList;
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
pWin = pExpr->y.pWin;
|
||||
pWin = pExpr->pWin;
|
||||
#else
|
||||
pWin = 0;
|
||||
#endif
|
||||
|
||||
+6
-56
@@ -79,57 +79,6 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if column iCol of index pIdx references any of the
|
||||
** columns defined by aXRef and chngRowid. Return true if it does
|
||||
** and false if not. This is an optimization. False-positives are a
|
||||
** performance degradation, but false-negatives can result in a corrupt
|
||||
** index and incorrect answers.
|
||||
**
|
||||
** aXRef[j] will be non-negative if column j of the original table is
|
||||
** being updated. chngRowid will be true if the rowid of the table is
|
||||
** being updated.
|
||||
*/
|
||||
static int indexColumnIsBeingUpdated(
|
||||
Index *pIdx, /* The index to check */
|
||||
int iCol, /* Which column of the index to check */
|
||||
int *aXRef, /* aXRef[j]>=0 if column j is being updated */
|
||||
int chngRowid /* true if the rowid is being updated */
|
||||
){
|
||||
i16 iIdxCol = pIdx->aiColumn[iCol];
|
||||
assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
|
||||
if( iIdxCol>=0 ){
|
||||
return aXRef[iIdxCol]>=0;
|
||||
}
|
||||
assert( iIdxCol==XN_EXPR );
|
||||
assert( pIdx->aColExpr!=0 );
|
||||
assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
|
||||
return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
|
||||
aXRef,chngRowid);
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if index pIdx is a partial index whose conditional
|
||||
** expression might change values due to an UPDATE. Return true if
|
||||
** the index is subject to change and false if the index is guaranteed
|
||||
** to be unchanged. This is an optimization. False-positives are a
|
||||
** performance degradation, but false-negatives can result in a corrupt
|
||||
** index and incorrect answers.
|
||||
**
|
||||
** aXRef[j] will be non-negative if column j of the original table is
|
||||
** being updated. chngRowid will be true if the rowid of the table is
|
||||
** being updated.
|
||||
*/
|
||||
static int indexWhereClauseMightChange(
|
||||
Index *pIdx, /* The index to check */
|
||||
int *aXRef, /* aXRef[j]>=0 if column j is being updated */
|
||||
int chngRowid /* true if the rowid is being updated */
|
||||
){
|
||||
if( pIdx->pPartIdxWhere==0 ) return 0;
|
||||
return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
|
||||
aXRef, chngRowid);
|
||||
}
|
||||
|
||||
/*
|
||||
** Process an UPDATE statement.
|
||||
**
|
||||
@@ -353,18 +302,19 @@ void sqlite3Update(
|
||||
/* There is one entry in the aRegIdx[] array for each index on the table
|
||||
** being updated. Fill in aRegIdx[] with a register number that will hold
|
||||
** the key for accessing each index.
|
||||
**
|
||||
** FIXME: Be smarter about omitting indexes that use expressions.
|
||||
*/
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
int reg;
|
||||
if( chngKey || hasFK>1 || pIdx==pPk
|
||||
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
|
||||
){
|
||||
if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
|
||||
reg = ++pParse->nMem;
|
||||
pParse->nMem += pIdx->nColumn;
|
||||
}else{
|
||||
reg = 0;
|
||||
for(i=0; i<pIdx->nKeyCol; i++){
|
||||
if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
|
||||
i16 iIdxCol = pIdx->aiColumn[i];
|
||||
if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
|
||||
reg = ++pParse->nMem;
|
||||
pParse->nMem += pIdx->nColumn;
|
||||
if( (onError==OE_Replace)
|
||||
@@ -913,7 +863,7 @@ static void updateVirtualTable(
|
||||
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
|
||||
sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
|
||||
}
|
||||
}
|
||||
if( HasRowid(pTab) ){
|
||||
|
||||
+11
-21
@@ -2894,25 +2894,17 @@ case OP_MakeRecord: {
|
||||
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
|
||||
}
|
||||
nByte = nHdr+nData;
|
||||
if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
goto too_big;
|
||||
}
|
||||
|
||||
/* Make sure the output register has a buffer large enough to store
|
||||
** the new record. The output register (pOp->p3) is not allowed to
|
||||
** be one of the input registers (because the following call to
|
||||
** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
|
||||
*/
|
||||
if( nByte+nZero<=pOut->szMalloc ){
|
||||
/* The output register is already large enough to hold the record.
|
||||
** No error checks or buffer enlargement is required */
|
||||
pOut->z = pOut->zMalloc;
|
||||
}else{
|
||||
/* Need to make sure that the output is not too big and then enlarge
|
||||
** the output register to hold the full result */
|
||||
if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
goto too_big;
|
||||
}
|
||||
if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
|
||||
goto no_mem;
|
||||
}
|
||||
if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
|
||||
goto no_mem;
|
||||
}
|
||||
zNewRecord = (u8 *)pOut->z;
|
||||
|
||||
@@ -5768,7 +5760,7 @@ case OP_ParseSchema: {
|
||||
{
|
||||
zMaster = MASTER_NAME;
|
||||
initData.db = db;
|
||||
initData.iDb = iDb;
|
||||
initData.iDb = pOp->p1;
|
||||
initData.pzErrMsg = &p->zErrMsg;
|
||||
initData.mInitFlags = 0;
|
||||
zSql = sqlite3MPrintf(db,
|
||||
@@ -6965,11 +6957,10 @@ case OP_VFilter: { /* jump */
|
||||
**
|
||||
** If the VColumn opcode is being used to fetch the value of
|
||||
** an unchanging column during an UPDATE operation, then the P5
|
||||
** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
|
||||
** function to return true inside the xColumn method of the virtual
|
||||
** table implementation. The P5 column might also contain other
|
||||
** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
|
||||
** unused by OP_VColumn.
|
||||
** value is 1. Otherwise, P5 is 0. The P5 value is returned
|
||||
** by sqlite3_vtab_nochange() routine and can be used
|
||||
** by virtual table implementations to return special "no-change"
|
||||
** marks which can be more efficient, depending on the virtual table.
|
||||
*/
|
||||
case OP_VColumn: {
|
||||
sqlite3_vtab *pVtab;
|
||||
@@ -6991,8 +6982,7 @@ case OP_VColumn: {
|
||||
assert( pModule->xColumn );
|
||||
memset(&sContext, 0, sizeof(sContext));
|
||||
sContext.pOut = pDest;
|
||||
testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
|
||||
if( pOp->p5 & OPFLAG_NOCHNG ){
|
||||
if( pOp->p5 ){
|
||||
sqlite3VdbeMemSetNull(pDest);
|
||||
pDest->flags = MEM_Null|MEM_Zero;
|
||||
pDest->u.nZero = 0;
|
||||
|
||||
@@ -406,9 +406,6 @@ struct Vdbe {
|
||||
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
|
||||
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
|
||||
char *zSql; /* Text of the SQL statement that generated this */
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
char *zNormSql; /* Normalization of the associated SQL statement */
|
||||
#endif
|
||||
void *pFree; /* Free this when deleting the vdbe */
|
||||
VdbeFrame *pFrame; /* Parent frame */
|
||||
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
|
||||
|
||||
@@ -1702,16 +1702,6 @@ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
/*
|
||||
** Return the normalized SQL associated with a prepared statement.
|
||||
*/
|
||||
const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
return p ? p->zNormSql : 0;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_NORMALIZE */
|
||||
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
/*
|
||||
** Allocate and populate an UnpackedRecord structure based on the serialized
|
||||
|
||||
+1
-18
@@ -64,13 +64,6 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
|
||||
}
|
||||
assert( p->zSql==0 );
|
||||
p->zSql = sqlite3DbStrNDup(p->db, z, n);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
assert( p->zNormSql==0 );
|
||||
if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
|
||||
sqlite3Normalize(p, p->zSql, n, prepFlags);
|
||||
assert( p->zNormSql!=0 || p->db->mallocFailed );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -92,11 +85,6 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
|
||||
zTmp = pA->zSql;
|
||||
pA->zSql = pB->zSql;
|
||||
pB->zSql = zTmp;
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
zTmp = pA->zNormSql;
|
||||
pA->zNormSql = pB->zNormSql;
|
||||
pB->zNormSql = zTmp;
|
||||
#endif
|
||||
pB->expmask = pA->expmask;
|
||||
pB->prepFlags = pA->prepFlags;
|
||||
memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
|
||||
@@ -3168,9 +3156,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
|
||||
vdbeFreeOpArray(db, p->aOp, p->nOp);
|
||||
sqlite3DbFree(db, p->aColName);
|
||||
sqlite3DbFree(db, p->zSql);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
sqlite3DbFree(db, p->zNormSql);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
{
|
||||
int i;
|
||||
@@ -4572,9 +4557,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
|
||||
(void)getVarint32((u8*)m.z, szHdr);
|
||||
testcase( szHdr==3 );
|
||||
testcase( szHdr==m.n );
|
||||
testcase( szHdr>0x7fffffff );
|
||||
assert( m.n>=0 );
|
||||
if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
|
||||
if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
|
||||
goto idx_rowid_corruption;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -377,8 +377,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
|
||||
assert( fg & MEM_Real );
|
||||
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
|
||||
}
|
||||
assert( pMem->z!=0 );
|
||||
pMem->n = sqlite3Strlen30NN(pMem->z);
|
||||
pMem->n = sqlite3Strlen30(pMem->z);
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
pMem->flags |= MEM_Str|MEM_Term;
|
||||
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
|
||||
|
||||
+4
-3
@@ -328,6 +328,7 @@ void sqlite3VtabBeginParse(
|
||||
Token *pModuleName, /* Name of the module for the virtual table */
|
||||
int ifNotExists /* No error if the table already exists */
|
||||
){
|
||||
int iDb; /* The database the table is being created in */
|
||||
Table *pTable; /* The new virtual table */
|
||||
sqlite3 *db; /* Database connection */
|
||||
|
||||
@@ -337,6 +338,8 @@ void sqlite3VtabBeginParse(
|
||||
assert( 0==pTable->pIndex );
|
||||
|
||||
db = pParse->db;
|
||||
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
|
||||
assert( iDb>=0 );
|
||||
|
||||
assert( pTable->nModuleArg==0 );
|
||||
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
|
||||
@@ -356,8 +359,6 @@ void sqlite3VtabBeginParse(
|
||||
** The second call, to obtain permission to create the table, is made now.
|
||||
*/
|
||||
if( pTable->azModuleArg ){
|
||||
int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
|
||||
assert( iDb>=0 ); /* The database the table is being created in */
|
||||
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
|
||||
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
|
||||
}
|
||||
@@ -1052,7 +1053,7 @@ FuncDef *sqlite3VtabOverloadFunction(
|
||||
/* Check to see the left operand is a column in a virtual table */
|
||||
if( NEVER(pExpr==0) ) return pDef;
|
||||
if( pExpr->op!=TK_COLUMN ) return pDef;
|
||||
pTab = pExpr->y.pTab;
|
||||
pTab = pExpr->pTab;
|
||||
if( pTab==0 ) return pDef;
|
||||
if( !IsVirtual(pTab) ) return pDef;
|
||||
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
|
||||
|
||||
+2
-2
@@ -55,8 +55,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
|
||||
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
Window *pWin = pExpr->y.pWin;
|
||||
if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
|
||||
Window *pWin = pExpr->pWin;
|
||||
if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
|
||||
if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
|
||||
if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
|
||||
|
||||
+2
-19
@@ -854,6 +854,7 @@ static void constructAutomaticIndex(
|
||||
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
|
||||
pTabItem->regResult, 1);
|
||||
sqlite3VdbeGoto(v, addrTop);
|
||||
pTabItem->fg.viaCoroutine = 0;
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
|
||||
}
|
||||
@@ -2125,14 +2126,6 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
|
||||
sqlite3 *db = pWInfo->pParse->db;
|
||||
int rc;
|
||||
|
||||
/* Stop the search once we hit the query planner search limit */
|
||||
if( pBuilder->iPlanLimit==0 ){
|
||||
WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
|
||||
if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
|
||||
return SQLITE_DONE;
|
||||
}
|
||||
pBuilder->iPlanLimit--;
|
||||
|
||||
/* If pBuilder->pOrSet is defined, then only keep track of the costs
|
||||
** and prereqs.
|
||||
*/
|
||||
@@ -3539,11 +3532,9 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
/* Loop over the tables in the join, from left to right */
|
||||
pNew = pBuilder->pNew;
|
||||
whereLoopInit(pNew);
|
||||
pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
|
||||
for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
|
||||
Bitmask mUnusable = 0;
|
||||
pNew->iTab = iTab;
|
||||
pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
|
||||
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
|
||||
if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
|
||||
/* This condition is true when pItem is the FROM clause term on the
|
||||
@@ -3569,15 +3560,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
|
||||
}
|
||||
mPrior |= pNew->maskSelf;
|
||||
if( rc || db->mallocFailed ){
|
||||
if( rc==SQLITE_DONE ){
|
||||
/* We hit the query planner search limit set by iPlanLimit */
|
||||
sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( rc || db->mallocFailed ) break;
|
||||
}
|
||||
|
||||
whereLoopClear(db, pNew);
|
||||
|
||||
@@ -402,33 +402,12 @@ struct WhereLoopBuilder {
|
||||
int nRecValid; /* Number of valid fields currently in pRec */
|
||||
#endif
|
||||
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
|
||||
unsigned int iPlanLimit; /* Search limiter */
|
||||
};
|
||||
|
||||
/* Allowed values for WhereLoopBuider.bldFlags */
|
||||
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
|
||||
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
|
||||
|
||||
/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
|
||||
** index+constraint combinations the query planner will consider for a
|
||||
** particular query. If this parameter is unlimited, then certain
|
||||
** pathological queries can spend excess time in the sqlite3WhereBegin()
|
||||
** routine. The limit is high enough that is should not impact real-world
|
||||
** queries.
|
||||
**
|
||||
** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is
|
||||
** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
|
||||
** clause is processed, so that every table in a join is guaranteed to be
|
||||
** able to propose a some index+constraint combinations even if the initial
|
||||
** baseline limit was exhausted by prior tables of the join.
|
||||
*/
|
||||
#ifndef SQLITE_QUERY_PLANNER_LIMIT
|
||||
# define SQLITE_QUERY_PLANNER_LIMIT 20000
|
||||
#endif
|
||||
#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
|
||||
# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The WHERE clause processing routine has two halves. The
|
||||
** first part does the start of the WHERE loop and the second
|
||||
|
||||
+2
-2
@@ -425,7 +425,7 @@ static Expr *removeUnindexableInClauseTerms(
|
||||
for(i=iEq; i<pLoop->nLTerm; i++){
|
||||
if( pLoop->aLTerm[i]->pExpr==pX ){
|
||||
int iField = pLoop->aLTerm[i]->iField - 1;
|
||||
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
|
||||
assert( pOrigRhs->a[iField].pExpr!=0 );
|
||||
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
|
||||
pOrigRhs->a[iField].pExpr = 0;
|
||||
assert( pOrigLhs->a[iField].pExpr!=0 );
|
||||
@@ -1117,7 +1117,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
|
||||
pExpr->op = TK_COLUMN;
|
||||
pExpr->iTable = pX->iIdxCur;
|
||||
pExpr->iColumn = pX->iIdxCol;
|
||||
pExpr->y.pTab = 0;
|
||||
pExpr->pTab = 0;
|
||||
return WRC_Prune;
|
||||
}else{
|
||||
return WRC_Continue;
|
||||
|
||||
+9
-12
@@ -281,7 +281,7 @@ static int isLikeOrGlob(
|
||||
){
|
||||
if( pLeft->op!=TK_COLUMN
|
||||
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|
||||
|| IsVirtual(pLeft->y.pTab) /* Value might be numeric */
|
||||
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
|
||||
){
|
||||
sqlite3ExprDelete(db, pPrefix);
|
||||
sqlite3ValueFree(pVal);
|
||||
@@ -382,7 +382,7 @@ static int isAuxiliaryVtabOperator(
|
||||
** MATCH(expression,vtab_column)
|
||||
*/
|
||||
pCol = pList->a[1].pExpr;
|
||||
if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
|
||||
if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
|
||||
for(i=0; i<ArraySize(aOp); i++){
|
||||
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
|
||||
*peOp2 = aOp[i].eOp2;
|
||||
@@ -404,12 +404,12 @@ static int isAuxiliaryVtabOperator(
|
||||
** with function names in an arbitrary case.
|
||||
*/
|
||||
pCol = pList->a[0].pExpr;
|
||||
if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
|
||||
if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
|
||||
sqlite3_vtab *pVtab;
|
||||
sqlite3_module *pMod;
|
||||
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
|
||||
void *pNotUsed;
|
||||
pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
|
||||
pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
|
||||
assert( pVtab!=0 );
|
||||
assert( pVtab->pModule!=0 );
|
||||
pMod = (sqlite3_module *)pVtab->pModule;
|
||||
@@ -427,10 +427,10 @@ static int isAuxiliaryVtabOperator(
|
||||
int res = 0;
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
Expr *pRight = pExpr->pRight;
|
||||
if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
|
||||
if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
|
||||
res++;
|
||||
}
|
||||
if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
|
||||
if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
|
||||
res++;
|
||||
SWAP(Expr*, pLeft, pRight);
|
||||
}
|
||||
@@ -1382,7 +1382,6 @@ static void exprAnalyze(
|
||||
if( pExpr->op==TK_NOTNULL
|
||||
&& pExpr->pLeft->op==TK_COLUMN
|
||||
&& pExpr->pLeft->iColumn>=0
|
||||
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
&& OptimizationEnabled(db, SQLITE_Stat34)
|
||||
){
|
||||
Expr *pNewExpr;
|
||||
@@ -1574,7 +1573,6 @@ void sqlite3WhereTabFuncArgs(
|
||||
pArgs = pItem->u1.pFuncArg;
|
||||
if( pArgs==0 ) return;
|
||||
for(j=k=0; j<pArgs->nExpr; j++){
|
||||
Expr *pRhs;
|
||||
while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
|
||||
if( k>=pTab->nCol ){
|
||||
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
|
||||
@@ -1585,10 +1583,9 @@ void sqlite3WhereTabFuncArgs(
|
||||
if( pColRef==0 ) return;
|
||||
pColRef->iTable = pItem->iCursor;
|
||||
pColRef->iColumn = k++;
|
||||
pColRef->y.pTab = pTab;
|
||||
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
|
||||
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
|
||||
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
|
||||
pColRef->pTab = pTab;
|
||||
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
|
||||
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
|
||||
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -624,12 +624,12 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
|
||||
switch( pExpr->op ){
|
||||
|
||||
case TK_FUNCTION:
|
||||
if( !ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( pExpr->pWin==0 ){
|
||||
break;
|
||||
}else{
|
||||
Window *pWin;
|
||||
for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
|
||||
if( pExpr->y.pWin==pWin ){
|
||||
if( pExpr->pWin==pWin ){
|
||||
assert( pWin->pOwner==pExpr );
|
||||
return WRC_Prune;
|
||||
}
|
||||
@@ -746,7 +746,7 @@ static ExprList *exprListAppendList(
|
||||
*/
|
||||
int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->pWin && p->pPrior==0 ){
|
||||
if( p->pWin ){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3 *db = pParse->db;
|
||||
Select *pSub = 0; /* The subquery */
|
||||
@@ -959,13 +959,11 @@ windowAllocErr:
|
||||
*/
|
||||
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
|
||||
if( p ){
|
||||
assert( p->op==TK_FUNCTION );
|
||||
/* This routine is only called for the parser. If pWin was not
|
||||
** allocated due to an OOM, then the parser would fail before ever
|
||||
** invoking this routine */
|
||||
if( ALWAYS(pWin) ){
|
||||
p->y.pWin = pWin;
|
||||
ExprSetProperty(p, EP_WinFunc);
|
||||
p->pWin = pWin;
|
||||
pWin->pOwner = p;
|
||||
if( p->flags & EP_Distinct ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
@@ -2128,7 +2126,7 @@ static void windowCodeDefaultStep(
|
||||
*/
|
||||
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
|
||||
Window *pNew = 0;
|
||||
if( ALWAYS(p) ){
|
||||
if( p ){
|
||||
pNew = sqlite3DbMallocZero(db, sizeof(Window));
|
||||
if( pNew ){
|
||||
pNew->zName = sqlite3DbStrDup(db, p->zName);
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# 2018 October 6
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
|
||||
ifcapable !altertable {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
set testprefix alterauth2
|
||||
|
||||
set ::auth [list]
|
||||
proc xAuth {type args} {
|
||||
lappend ::auth [concat $type [lrange $args 0 3]]
|
||||
if {$type=="SQLITE_READ" && [lindex $args 0] == "t2"} breakpoint
|
||||
return SQLITE_OK
|
||||
}
|
||||
db auth xAuth
|
||||
|
||||
proc do_auth_test {tn sql authcode} {
|
||||
set script "
|
||||
set ::auth \[list\]
|
||||
execsql {$sql}
|
||||
lsort -unique \[set ::auth\]
|
||||
"
|
||||
|
||||
set normal [list {*}$authcode]
|
||||
uplevel [list do_test $tn $script $normal]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
|
||||
DELETE FROM t1 WHERE a<new.a;
|
||||
END;
|
||||
|
||||
CREATE TEMP TRIGGER tr2 AFTER UPDATE OF a, b ON t1 BEGIN
|
||||
UPDATE t1 SET a=a+1 WHERE new.b<b;
|
||||
END;
|
||||
}
|
||||
|
||||
do_auth_test 1.1 {
|
||||
ALTER TABLE t1 RENAME TO t2;
|
||||
} {
|
||||
{SQLITE_ALTER_TABLE main t1 {} {}}
|
||||
{SQLITE_FUNCTION {} like {} {}}
|
||||
{SQLITE_FUNCTION {} sqlite_rename_table {} {}}
|
||||
{SQLITE_FUNCTION {} sqlite_rename_test {} {}}
|
||||
{SQLITE_FUNCTION {} substr {} {}}
|
||||
{SQLITE_READ sqlite_master name main {}}
|
||||
{SQLITE_READ sqlite_master sql main {}}
|
||||
{SQLITE_READ sqlite_master tbl_name main {}}
|
||||
{SQLITE_READ sqlite_master type main {}}
|
||||
{SQLITE_READ sqlite_temp_master name temp {}}
|
||||
{SQLITE_READ sqlite_temp_master sql temp {}}
|
||||
{SQLITE_READ sqlite_temp_master tbl_name temp {}}
|
||||
{SQLITE_READ sqlite_temp_master type temp {}}
|
||||
{SQLITE_SELECT {} {} {} {}}
|
||||
{SQLITE_UPDATE sqlite_master name main {}}
|
||||
{SQLITE_UPDATE sqlite_master sql main {}}
|
||||
{SQLITE_UPDATE sqlite_master tbl_name main {}}
|
||||
{SQLITE_UPDATE sqlite_temp_master sql temp {}}
|
||||
{SQLITE_UPDATE sqlite_temp_master tbl_name temp {}}
|
||||
}
|
||||
|
||||
do_auth_test 1.2 {
|
||||
ALTER TABLE t2 RENAME a TO aaa;
|
||||
} {
|
||||
{SQLITE_ALTER_TABLE main t2 {} {}}
|
||||
{SQLITE_FUNCTION {} like {} {}}
|
||||
{SQLITE_FUNCTION {} sqlite_rename_column {} {}}
|
||||
{SQLITE_FUNCTION {} sqlite_rename_test {} {}}
|
||||
{SQLITE_READ sqlite_master name main {}}
|
||||
{SQLITE_READ sqlite_master sql main {}}
|
||||
{SQLITE_READ sqlite_master tbl_name main {}}
|
||||
{SQLITE_READ sqlite_master type main {}}
|
||||
{SQLITE_READ sqlite_temp_master name temp {}}
|
||||
{SQLITE_READ sqlite_temp_master sql temp {}}
|
||||
{SQLITE_READ sqlite_temp_master type temp {}}
|
||||
{SQLITE_SELECT {} {} {} {}}
|
||||
{SQLITE_UPDATE sqlite_master sql main {}}
|
||||
{SQLITE_UPDATE sqlite_temp_master sql temp {}}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -19,7 +19,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
|
||||
ifcapable !altertable {
|
||||
ifcapable !altertable||!memdebug {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
@@ -459,49 +459,6 @@ do_execsql_test 14.6 {
|
||||
ALTER TABLE t1 RENAME TO tt1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 15.0 {
|
||||
CREATE TABLE t1(a integer NOT NULL PRIMARY KEY);
|
||||
CREATE VIEW v1 AS SELECT a FROM t1;
|
||||
CREATE TRIGGER tr1 INSTEAD OF INSERT ON v1 BEGIN
|
||||
UPDATE t1 SET a = NEW.a;
|
||||
END;
|
||||
CREATE TRIGGER tr2 INSTEAD OF INSERT ON v1 BEGIN
|
||||
SELECT new.a;
|
||||
END;
|
||||
CREATE TABLE t2 (b);
|
||||
}
|
||||
|
||||
do_execsql_test 15.1 {
|
||||
INSERT INTO v1 VALUES(1);
|
||||
ALTER TABLE t2 RENAME TO t3;
|
||||
}
|
||||
|
||||
do_execsql_test 15.2 {
|
||||
CREATE TABLE x(f1 integer NOT NULL);
|
||||
CREATE VIEW y AS SELECT f1 AS f1 FROM x;
|
||||
CREATE TRIGGER t INSTEAD OF UPDATE OF f1 ON y BEGIN
|
||||
UPDATE x SET f1 = NEW.f1;
|
||||
END;
|
||||
CREATE TABLE z (f1 integer NOT NULL PRIMARY KEY);
|
||||
ALTER TABLE z RENAME TO z2;
|
||||
}
|
||||
|
||||
do_execsql_test 15.3 {
|
||||
INSERT INTO x VALUES(1), (2), (3);
|
||||
ALTER TABLE x RENAME f1 TO f2;
|
||||
SELECT * FROM x;
|
||||
} {1 2 3}
|
||||
|
||||
do_execsql_test 15.4 {
|
||||
UPDATE y SET f1 = 'x' WHERE f1 = 1;
|
||||
SELECT * FROM x;
|
||||
} {x x x}
|
||||
|
||||
do_execsql_test 15.5 {
|
||||
SELECT sql FROM sqlite_master WHERE name = 'y';
|
||||
} {{CREATE VIEW y AS SELECT f2 AS f1 FROM x}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -41,50 +41,6 @@ ifcapable fts5 {
|
||||
} {hello world in tcl}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that table names that appear in REFERENCES clauses are updated
|
||||
# when a table is renamed unless:
|
||||
#
|
||||
# a) "PRAGMA legacy_alter_table" is true, and
|
||||
# b) "PRAGMA foreign_keys" is false.
|
||||
#
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE p1(a PRIMARY KEY, b);
|
||||
CREATE TABLE c1(x REFERENCES p1);
|
||||
CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES p1);
|
||||
CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES p1(a));
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
ALTER TABLE p1 RENAME TO p2;
|
||||
SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
|
||||
} {
|
||||
{CREATE TABLE c1(x REFERENCES "p2")}
|
||||
{CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p2")}
|
||||
{CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p2"(a))}
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
PRAGMA legacy_alter_table = 1;
|
||||
ALTER TABLE p2 RENAME TO p3;
|
||||
SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
|
||||
} {
|
||||
{CREATE TABLE c1(x REFERENCES "p2")}
|
||||
{CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p2")}
|
||||
{CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p2"(a))}
|
||||
}
|
||||
|
||||
do_execsql_test 2.3 {
|
||||
ALTER TABLE p3 RENAME TO p2;
|
||||
PRAGMA foreign_keys = 1;
|
||||
ALTER TABLE p2 RENAME TO p3;
|
||||
SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
|
||||
} {
|
||||
{CREATE TABLE c1(x REFERENCES "p3")}
|
||||
{CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p3")}
|
||||
{CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p3"(a))}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -726,31 +726,6 @@ ifcapable subquery {
|
||||
} db2
|
||||
} {1 {trigger r5 cannot reference objects in database temp}}
|
||||
} ;# endif subquery
|
||||
ifcapable json1 {
|
||||
do_test attach-5.10 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(a,b);
|
||||
CREATE TRIGGER x1 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO t2(a,b) SELECT key, value FROM json_each(NEW.x);
|
||||
END;
|
||||
INSERT INTO t1(x) VALUES('{"a":1}');
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {a 1}
|
||||
do_test attach-5.11 {
|
||||
sqlite3 db2 :memory:
|
||||
db2 eval {
|
||||
CREATE TABLE t3(y);
|
||||
ATTACH 'test.db' AS aux;
|
||||
INSERT INTO aux.t1(x) VALUES('{"b":2}');
|
||||
SELECT * FROM aux.t2;
|
||||
}
|
||||
} {a 1 b 2}
|
||||
} ;# endif json1
|
||||
} ;# endif trigger
|
||||
|
||||
# Check to make sure we get a sensible error if unable to open
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !attach {
|
||||
ifcapable !memdebug||!attach {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
@@ -123,91 +123,6 @@ do_execsql_test 2.1 {
|
||||
SELECT sum(z) FROM vvv WHERE x='aaa'
|
||||
) FROM one;
|
||||
} {8.0}
|
||||
|
||||
# Ticket https://www.sqlite.org/src/info/787fa716be3a7f65
|
||||
# Segfault due to multiple uses of the same subquery where the
|
||||
# subquery is implemented via coroutine.
|
||||
#
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test 3.0 {
|
||||
-- This is the original test case reported on the mailing list
|
||||
CREATE TABLE artists (
|
||||
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
name varchar(255)
|
||||
);
|
||||
CREATE TABLE albums (
|
||||
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
name varchar(255),
|
||||
artist_id integer REFERENCES artists
|
||||
);
|
||||
INSERT INTO artists (name) VALUES ('Ar');
|
||||
INSERT INTO albums (name, artist_id) VALUES ('Al', 1);
|
||||
SELECT artists.*
|
||||
FROM artists
|
||||
INNER JOIN artists AS 'b' ON (b.id = artists.id)
|
||||
WHERE (artists.id IN (
|
||||
SELECT albums.artist_id
|
||||
FROM albums
|
||||
WHERE ((name = 'Al')
|
||||
AND (albums.artist_id IS NOT NULL)
|
||||
AND (albums.id IN (
|
||||
SELECT id
|
||||
FROM (
|
||||
SELECT albums.id,
|
||||
row_number() OVER (
|
||||
PARTITION BY albums.artist_id
|
||||
ORDER BY name
|
||||
) AS 'x'
|
||||
FROM albums
|
||||
WHERE (name = 'Al')
|
||||
) AS 't1'
|
||||
WHERE (x = 1)
|
||||
))
|
||||
AND (albums.id IN (1, 2)))
|
||||
));
|
||||
} {1 Ar}
|
||||
# The remaining test cases were discovered (by Dan) during trouble-shooting
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test 3.1 {
|
||||
CREATE TABLE t1 (a); INSERT INTO t1 (a) VALUES (104);
|
||||
CREATE TABLE t2 (b); INSERT INTO t2 (b) VALUES (104);
|
||||
CREATE TABLE t3 (c); INSERT INTO t3 (c) VALUES (104);
|
||||
CREATE TABLE t4 (d); INSERT INTO t4 (d) VALUES (104);
|
||||
SELECT *
|
||||
FROM t1 CROSS JOIN t2 ON (t1.a = t2.b) WHERE t2.b IN (
|
||||
SELECT t3.c
|
||||
FROM t3
|
||||
WHERE t3.c IN (
|
||||
SELECT d FROM (SELECT DISTINCT d FROM t4) AS x WHERE x.d=104
|
||||
)
|
||||
);
|
||||
} {104 104}
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test 3.2 {
|
||||
CREATE TABLE t5(a, b, c, d);
|
||||
CREATE INDEX t5a ON t5(a);
|
||||
CREATE INDEX t5b ON t5(b);
|
||||
CREATE TABLE t6(e);
|
||||
INSERT INTO t6 VALUES(1);
|
||||
INSERT INTO t5 VALUES(1,1,1,1), (2,2,2,2);
|
||||
SELECT * FROM t5 WHERE (a=1 OR b=2) AND c IN (
|
||||
SELECT e FROM (SELECT DISTINCT e FROM t6) WHERE e=1
|
||||
);
|
||||
} {1 1 1 1}
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test 3.3 {
|
||||
CREATE TABLE t1(a1, a2, a3);
|
||||
CREATE INDEX t1a2 ON t1(a2, a1);
|
||||
CREATE INDEX t1a3 ON t1(a3, a1);
|
||||
CREATE TABLE t2(d);
|
||||
INSERT INTO t1 VALUES(3, 1, 1), (3, 2, 2);
|
||||
INSERT INTO t2 VALUES(3);
|
||||
SELECT *, 'x' FROM t1 WHERE (a2=1 OR a3=2) AND a1 = (
|
||||
SELECT d FROM (SELECT DISTINCT d FROM t2) WHERE d=3
|
||||
);
|
||||
} {3 1 1 x 3 2 2 x}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -117,57 +117,4 @@ for {set param1 0} {$param1<16} {incr param1} {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that a parameter passed to a table-valued function cannot be
|
||||
# used to drive an index. i.e. that in the following:
|
||||
#
|
||||
# SELECT * FROM tbl, vtab(tbl.x);
|
||||
#
|
||||
# The implicit constraint "tbl.x = vtab.hidden" is not optimized using
|
||||
# an index on tbl.x.
|
||||
#
|
||||
reset_db
|
||||
register_tcl_module db
|
||||
proc vtab_command {method args} {
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE t1(a, b, c, d HIDDEN)"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
if {[llength $clist]!=1} { error "unexpected constraint list" }
|
||||
catch { array unset C }
|
||||
array set C [lindex $clist 0]
|
||||
if {$C(usable)} {
|
||||
return [list omit 0 idxnum 555 rows 10 cost 100]
|
||||
}
|
||||
return [list cost 100000000]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
|
||||
CREATE TABLE t1 (x INT PRIMARY KEY);
|
||||
} {}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1, x1 WHERE x1.d=t1.x;
|
||||
} {
|
||||
3 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}
|
||||
7 0 0 {SEARCH TABLE t1 USING COVERING INDEX sqlite_autoindex_t1_1 (x=?)}
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1, x1(t1.x)
|
||||
} {
|
||||
3 0 0 {SCAN TABLE t1}
|
||||
5 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -811,6 +811,7 @@ foreach {code english} $code2english {
|
||||
|
||||
# Test the error message when a "real" out of memory occurs.
|
||||
if { [permutation] != "nofaultsim" } {
|
||||
ifcapable memdebug {
|
||||
do_test capi3-10-1 {
|
||||
sqlite3 db test.db
|
||||
set DB [sqlite3_connection_pointer db]
|
||||
@@ -848,6 +849,7 @@ if { [permutation] != "nofaultsim" } {
|
||||
db close
|
||||
sqlite3_memdebug_fail -1
|
||||
}
|
||||
}
|
||||
|
||||
# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
|
||||
# statement issued while there are still outstanding VMs that are part of
|
||||
|
||||
@@ -757,6 +757,7 @@ foreach {code english} $code2english {
|
||||
|
||||
# Test the error message when a "real" out of memory occurs.
|
||||
if { [permutation] != "nofaultsim" } {
|
||||
ifcapable memdebug {
|
||||
do_test capi3c-10-1 {
|
||||
sqlite3 db test.db
|
||||
set DB [sqlite3_connection_pointer db]
|
||||
@@ -776,6 +777,7 @@ if { [permutation] != "nofaultsim" } {
|
||||
db close
|
||||
sqlite3_memdebug_fail -1
|
||||
}
|
||||
}
|
||||
|
||||
# The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK
|
||||
# statement issued while there are still outstanding VMs that are part of
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ source $testdir/tester.tcl
|
||||
|
||||
# Only run these tests if memory debugging is turned on.
|
||||
#
|
||||
ifcapable !crashtest||!memorymanage {
|
||||
ifcapable !memdebug||!crashtest||!memorymanage {
|
||||
puts "Skipping crash5 tests: not compiled with -DSQLITE_MEMDEBUG..."
|
||||
finish_test
|
||||
return
|
||||
|
||||
Binary file not shown.
-138
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
** 2018-10-26
|
||||
**
|
||||
** 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 program is designed for fuzz-testing SQLite database files using
|
||||
** the -fsanitize=fuzzer option of clang.
|
||||
**
|
||||
** The -fsanitize=fuzzer option causes a main() to be inserted automatically.
|
||||
** That main() invokes LLVMFuzzerTestOneInput(D,S) to be invoked repeatedly.
|
||||
** Each D is a fuzzed database file. The code in this file runs various
|
||||
** SQL statements against that database, trying to provoke a failure.
|
||||
**
|
||||
** For best results the seed database files should have these tables:
|
||||
**
|
||||
** Table "t1" with columns "a" and "b"
|
||||
** Tables "t2" and "t3 with the same number of compatible columns
|
||||
** "t3" should have a column names "x"
|
||||
** Table "t4" with a column "x" that is compatible with t3.x.
|
||||
**
|
||||
** Any of these tables can be virtual tables, for example FTS or RTree tables.
|
||||
**
|
||||
** To run this test:
|
||||
**
|
||||
** mkdir dir
|
||||
** cp dbfuzz2-seed*.db dir
|
||||
** clang-6.0 -I. -g -O1 -fsanitize=fuzzer \
|
||||
** -DTHREADSAFE=0 -DSQLITE_ENABLE_DESERIALIZE \
|
||||
** -DSQLITE_ENABLE_DBSTAT_VTAB dbfuzz2.c sqlite3.c -ldl
|
||||
** ./a.out dir
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** This is the is the SQL that is run against the database.
|
||||
*/
|
||||
static const char *azSql[] = {
|
||||
"PRAGMA integrity_check;",
|
||||
"SELECT * FROM sqlite_master;",
|
||||
"SELECT sum(length(name)) FROM dbstat;",
|
||||
"UPDATE t1 SET b=a, a=b WHERE a<b;",
|
||||
"ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s;",
|
||||
"INSERT INTO t3 SELECT * FROM t2;",
|
||||
"DELETE FROM t3 WHERE x IN (SELECT x FROM t4);",
|
||||
"REINDEX;",
|
||||
"DROP TABLE t3;",
|
||||
"VACUUM;",
|
||||
};
|
||||
|
||||
/* Output verbosity level. 0 means complete silence */
|
||||
int eVerbosity = 0;
|
||||
|
||||
/* libFuzzer invokes this routine with fuzzed database files (in aData).
|
||||
** This routine run SQLite against the malformed database to see if it
|
||||
** can provoke a failure or malfunction.
|
||||
*/
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *aData, size_t nByte){
|
||||
unsigned char *a;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
if( eVerbosity>=1 ){
|
||||
printf("************** nByte=%d ***************\n", (int)nByte);
|
||||
fflush(stdout);
|
||||
}
|
||||
rc = sqlite3_open(0, &db);
|
||||
if( rc ) return 1;
|
||||
a = sqlite3_malloc64(nByte+1);
|
||||
if( a==0 ) return 1;
|
||||
memcpy(a, aData, nByte);
|
||||
sqlite3_deserialize(db, "main", a, nByte, nByte,
|
||||
SQLITE_DESERIALIZE_RESIZEABLE |
|
||||
SQLITE_DESERIALIZE_FREEONCLOSE);
|
||||
for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){
|
||||
if( eVerbosity>=1 ){
|
||||
printf("%s\n", azSql[i]);
|
||||
fflush(stdout);
|
||||
}
|
||||
sqlite3_exec(db, azSql[i], 0, 0, 0);
|
||||
}
|
||||
rc = sqlite3_close(db);
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stdout, "sqlite3_close() returns %d\n", rc);
|
||||
}
|
||||
if( sqlite3_memory_used()!=0 ){
|
||||
int nAlloc = 0;
|
||||
int nNotUsed = 0;
|
||||
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
|
||||
fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n",
|
||||
sqlite3_memory_used(), nAlloc);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* libFuzzer invokes this routine once when the executable starts, to
|
||||
** process the command-line arguments.
|
||||
*/
|
||||
int LLVMFuzzerInitialize(int *pArgc, char ***pArgv){
|
||||
int i, j;
|
||||
int argc = *pArgc;
|
||||
char **newArgv;
|
||||
char **argv = *pArgv;
|
||||
newArgv = malloc( sizeof(char*)*(argc+1) );
|
||||
if( newArgv==0 ) return 0;
|
||||
newArgv[0] = argv[0];
|
||||
for(i=j=1; i<argc; i++){
|
||||
char *z = argv[i];
|
||||
if( z[0]=='-' ){
|
||||
z++;
|
||||
if( z[0]=='-' ) z++;
|
||||
if( strcmp(z,"v")==0 ){
|
||||
eVerbosity++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
newArgv[j++] = argv[i];
|
||||
}
|
||||
newArgv[j] = 0;
|
||||
*pArgv = newArgv;
|
||||
*pArgc = j;
|
||||
return 0;
|
||||
}
|
||||
+2
-2
@@ -379,9 +379,9 @@ foreach ::lookaside_buffer_size {0 64 120} {
|
||||
# The following tests focus on DBSTATUS_CACHE_USED_SHARED
|
||||
#
|
||||
ifcapable shared_cache {
|
||||
if {([permutation]=="memsys3"
|
||||
if {[permutation]=="memsys3"
|
||||
|| [permutation]=="memsys5"
|
||||
|| $::tcl_platform(os)=="Linux") && ![sqlite3 -has-codec]} {
|
||||
|| $::tcl_platform(os)=="Linux"} {
|
||||
proc do_cacheused_test {tn db res} {
|
||||
set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0]
|
||||
set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0]
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
# 2006 September 9
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS3 module.
|
||||
#
|
||||
# $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts3corrupt4
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
BEGIN;
|
||||
CREATE VIRTUAL TABLE ft USING fts3;
|
||||
INSERT INTO ft VALUES('aback');
|
||||
INSERT INTO ft VALUES('abaft');
|
||||
INSERT INTO ft VALUES('abandon');
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
proc blob {a} { binary decode hex $a }
|
||||
db func blob blob
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT quote(root) FROM ft_segdir;
|
||||
} {X'0005616261636B03010200030266740302020003046E646F6E03030200'}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
UPDATE ft_segdir SET root = blob(
|
||||
'0005616261636B03010200 FFFFFFFF0702 66740302020003046E646F6E03030200'
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.3 {
|
||||
SELECT * FROM ft WHERE ft MATCH 'abandon';
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts3;
|
||||
INSERT INTO ft(ft) VALUES('nodesize=32');
|
||||
}
|
||||
do_test 2.0.1 {
|
||||
for {set i 0} {$i < 12} {incr i} {
|
||||
execsql {
|
||||
BEGIN;
|
||||
INSERT INTO ft VALUES('abc' || $i);
|
||||
INSERT INTO ft VALUES('abc' || $i || 'x' );
|
||||
INSERT INTO ft VALUES('abc' || $i || 'xx' );
|
||||
COMMIT
|
||||
}
|
||||
}
|
||||
execsql {
|
||||
SELECT count(*) FROM ft_segdir;
|
||||
SELECT count(*) FROM ft_segments;
|
||||
}
|
||||
} {12 0}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||
SELECT count(*) FROM ft_segdir;
|
||||
SELECT count(*) FROM ft_segments;
|
||||
} {12 3}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
SELECT quote(block) FROM ft_segments WHERE blockid=2
|
||||
} {X'00056162633130031F0200'}
|
||||
|
||||
db func blob blob
|
||||
do_execsql_test 2.3.1 {
|
||||
UPDATE ft_segments SET block =
|
||||
blob('00056162633130031F0200 FFFFFFFF07FF55 66740302020003046E646F6E03030200')
|
||||
WHERE blockid=2;
|
||||
} {}
|
||||
do_catchsql_test 2.3.2 {
|
||||
INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 2.4.1 {
|
||||
UPDATE ft_segments SET block =
|
||||
blob('00056162633130031F0200 02FFFFFFFF07 66740302020003046E646F6E03030200')
|
||||
WHERE blockid=2;
|
||||
} {}
|
||||
do_catchsql_test 2.4.2 {
|
||||
INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 2.5.1 {
|
||||
UPDATE ft_segments SET block =
|
||||
blob('00056162633130031F0200 0202 6674 FFFFFF070302020003046E646F6E030200')
|
||||
WHERE blockid=2;
|
||||
} {}
|
||||
do_catchsql_test 2.5.2 {
|
||||
INSERT INTO ft(ft) VALUES('merge=1,4');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts3;
|
||||
INSERT INTO ft(ft) VALUES('nodesize=32');
|
||||
}
|
||||
do_test 3.0.1 {
|
||||
execsql BEGIN
|
||||
for {set i 0} {$i < 20} {incr i} {
|
||||
execsql { INSERT INTO ft VALUES('abc' || $i) }
|
||||
}
|
||||
execsql {
|
||||
COMMIT;
|
||||
SELECT count(*) FROM ft_segdir;
|
||||
SELECT count(*) FROM ft_segments;
|
||||
}
|
||||
} {1 5}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
SELECT quote(root) FROM ft_segdir
|
||||
} {X'0101056162633132040136030132030136'}
|
||||
|
||||
db func blob blob
|
||||
do_execsql_test 3.2 {
|
||||
UPDATE ft_segdir
|
||||
SET root = blob('0101056162633132FFFFFFFF070236030132030136');
|
||||
}
|
||||
|
||||
do_catchsql_test 3.1 {
|
||||
SELECT * FROM ft WHERE ft MATCH 'abc20'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !memdebug {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/fuzz_common.tcl
|
||||
|
||||
|
||||
Binary file not shown.
@@ -16,7 +16,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix incrblob_err
|
||||
|
||||
ifcapable {!incrblob || !tclvar} {
|
||||
ifcapable {!incrblob || !memdebug || !tclvar} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
@@ -625,13 +625,6 @@ do_test index-18.1 {
|
||||
CREATE TABLE sqlite_t1(a, b, c);
|
||||
}
|
||||
} {1 {object name reserved for internal use: sqlite_t1}}
|
||||
do_test index-18.1.2 {
|
||||
sqlite3_db_config db DEFENSIVE 1
|
||||
catchsql {
|
||||
CREATE TABLE sqlite_t1(a, b, c);
|
||||
}
|
||||
} {1 {object name reserved for internal use: sqlite_t1}}
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
do_test index-18.2 {
|
||||
catchsql {
|
||||
CREATE INDEX sqlite_i1 ON t7(c);
|
||||
|
||||
@@ -159,75 +159,5 @@ do_execsql_test 3.4.6 {
|
||||
SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE binary;
|
||||
} {.ABC1 1 .ABC3 3 .abc2 2 .abc4 4}
|
||||
|
||||
# 2014-09-15: Verify that UPDATEs of columns not referenced by a
|
||||
# index on expression do not modify the index.
|
||||
#
|
||||
unset -nocomplain cnt
|
||||
set cnt 0
|
||||
proc refcnt {x} {
|
||||
global cnt
|
||||
incr cnt
|
||||
return $x
|
||||
}
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
db function refcnt -deterministic refcnt
|
||||
do_test 4.100 {
|
||||
db eval {
|
||||
CREATE TABLE t1(a,b,c,d,e,f);
|
||||
CREATE INDEX t1abc ON t1(refcnt(a+b+c));
|
||||
}
|
||||
set ::cnt
|
||||
} {0}
|
||||
do_test 4.110 {
|
||||
db eval {INSERT INTO t1 VALUES(1,2,3,4,5,6);}
|
||||
set ::cnt
|
||||
# The refcnt() function is invoked once to compute the index value
|
||||
} {1}
|
||||
do_test 4.120 {
|
||||
set ::cnt 0
|
||||
db eval {UPDATE t1 SET b=b+1;}
|
||||
set ::cnt
|
||||
# The refcnt() function is invoked twice, once to remove the old index
|
||||
# entry and a second time to insert the new one.
|
||||
} {2}
|
||||
do_test 4.130 {
|
||||
set ::cnt 0
|
||||
db eval {UPDATE t1 SET d=d+1;}
|
||||
set ::cnt
|
||||
# Refcnt() should not be invoked because that index does not change.
|
||||
} {0}
|
||||
|
||||
# Additional test cases to show that UPDATE does not modify indexes that
|
||||
# do not involve unchanged columns.
|
||||
#
|
||||
load_static_extension db explain
|
||||
do_execsql_test 4.200 {
|
||||
CREATE TABLE t2(a,b,c,d,e,f);
|
||||
INSERT INTO t2 VALUES(2,3,4,5,6,7);
|
||||
CREATE INDEX t2abc ON t2(a+b+c);
|
||||
CREATE INDEX t2cd ON t2(c*d);
|
||||
CREATE INDEX t2def ON t2(d,e+25*f);
|
||||
SELECT sqlite_master.name
|
||||
FROM sqlite_master, explain('UPDATE t2 SET b=b+1')
|
||||
WHERE explain.opcode LIKE 'Open%'
|
||||
AND sqlite_master.rootpage=explain.p2
|
||||
ORDER BY 1;
|
||||
} {t2 t2abc}
|
||||
do_execsql_test 4.210 {
|
||||
SELECT sqlite_master.name
|
||||
FROM sqlite_master, explain('UPDATE t2 SET c=c+1')
|
||||
WHERE explain.opcode LIKE 'Open%'
|
||||
AND sqlite_master.rootpage=explain.p2
|
||||
ORDER BY 1;
|
||||
} {t2 t2abc t2cd}
|
||||
do_execsql_test 4.220 {
|
||||
SELECT sqlite_master.name
|
||||
FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
|
||||
WHERE explain.opcode LIKE 'Open%'
|
||||
AND sqlite_master.rootpage=explain.p2
|
||||
ORDER BY 1;
|
||||
} {t2 t2abc t2cd t2def}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -47,13 +47,6 @@ do_test intarray-1.1 {
|
||||
}
|
||||
} {table ia1 table ia2 table ia3 table ia4}
|
||||
|
||||
# Verify the inability to DROP and recreate an intarray virtual table.
|
||||
do_test intarray-1.1b {
|
||||
db eval {DROP TABLE ia1}
|
||||
set rc [catch {sqlite3_intarray_create db ia1} msg]
|
||||
lappend rc $msg
|
||||
} {1 SQLITE_MISUSE}
|
||||
|
||||
do_test intarray-1.2 {
|
||||
db eval {
|
||||
SELECT b FROM t1 WHERE a IN ia3 ORDER BY a
|
||||
|
||||
@@ -130,14 +130,12 @@ do_eqp_test like3-5.101 {
|
||||
do_execsql_test like3-5.110 {
|
||||
SELECT x FROM t5a WHERE x LIKE '/a%';
|
||||
} {/abc}
|
||||
ifcapable !icu {
|
||||
do_eqp_test like3-5.111 {
|
||||
SELECT x FROM t5a WHERE x LIKE '/a%';
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t5a USING COVERING INDEX sqlite_autoindex_t5a_1 (x>? AND x<?)
|
||||
}
|
||||
}
|
||||
do_execsql_test like3-5.120 {
|
||||
SELECT x FROM t5a WHERE x LIKE '^12%' ESCAPE '^';
|
||||
} {123}
|
||||
|
||||
@@ -1,253 +0,0 @@
|
||||
|
||||
package require sqlite3
|
||||
package require Tk
|
||||
|
||||
#############################################################################
|
||||
# Code to set up scrollbars for widgets. This is generic, boring stuff.
|
||||
#
|
||||
namespace eval autoscroll {
|
||||
proc scrollable {widget path args} {
|
||||
::ttk::frame $path
|
||||
set w [$widget ${path}.widget {*}$args]
|
||||
set vs [::ttk::scrollbar ${path}.vs]
|
||||
set hs [::ttk::scrollbar ${path}.hs -orient horizontal]
|
||||
grid $w -row 0 -column 0 -sticky nsew
|
||||
|
||||
grid rowconfigure $path 0 -weight 1
|
||||
grid columnconfigure $path 0 -weight 1
|
||||
|
||||
set grid [list grid $vs -row 0 -column 1 -sticky nsew]
|
||||
$w configure -yscrollcommand [list ::autoscroll::scrollcommand $grid $vs]
|
||||
$vs configure -command [list $w yview]
|
||||
set grid [list grid $hs -row 1 -column 0 -sticky nsew]
|
||||
$w configure -xscrollcommand [list ::autoscroll::scrollcommand $grid $hs]
|
||||
$hs configure -command [list $w xview]
|
||||
|
||||
return $w
|
||||
}
|
||||
proc scrollcommand {grid sb args} {
|
||||
$sb set {*}$args
|
||||
set isRequired [expr {[lindex $args 0] != 0.0 || [lindex $args 1] != 1.0}]
|
||||
if {$isRequired && ![winfo ismapped $sb]} {
|
||||
{*}$grid
|
||||
}
|
||||
if {!$isRequired && [winfo ismapped $sb]} {
|
||||
grid forget $sb
|
||||
}
|
||||
}
|
||||
namespace export scrollable
|
||||
}
|
||||
namespace import ::autoscroll::*
|
||||
#############################################################################
|
||||
|
||||
proc populate_text_widget {db} {
|
||||
$::O(text) configure -state normal
|
||||
set id [lindex [$::O(tree) selection] 0]
|
||||
set frame [lindex $id end]
|
||||
|
||||
set line [$db one {SELECT line FROM frame WHERE frame = $frame}]
|
||||
if {$line ne ""} {
|
||||
foreach {file line} [split $line :] {}
|
||||
set content [$db one "SELECT content FROM file WHERE name = '$file'"]
|
||||
$::O(text) delete 0.0 end
|
||||
|
||||
set iLine 1
|
||||
foreach L [split $content "\n"] {
|
||||
if {$iLine == $line} {
|
||||
$::O(text) insert end "$L\n" highlight
|
||||
} else {
|
||||
$::O(text) insert end "$L\n"
|
||||
}
|
||||
incr iLine
|
||||
}
|
||||
$::O(text) yview -pickplace ${line}.0
|
||||
}
|
||||
$::O(text) configure -state disabled
|
||||
}
|
||||
|
||||
proc populate_index {db} {
|
||||
$::O(text) configure -state normal
|
||||
|
||||
$::O(text) delete 0.0 end
|
||||
$::O(text) insert end "\n\n"
|
||||
|
||||
set L [format " % -40s%12s%12s\n" "Test Case" "Allocations" "Bytes"]
|
||||
$::O(text) insert end $L
|
||||
$::O(text) insert end " [string repeat - 64]\n"
|
||||
|
||||
$db eval {
|
||||
SELECT 'TOTAL' AS ztest, sum(ncall) AS calls, sum(nbyte) AS bytes
|
||||
FROM malloc
|
||||
UNION ALL
|
||||
SELECT ztest AS ztest, sum(ncall) AS calls, sum(nbyte) AS bytes
|
||||
FROM malloc
|
||||
GROUP BY ztest
|
||||
|
||||
ORDER BY 3 DESC
|
||||
} {
|
||||
set tags [list $ztest]
|
||||
if {$ztest eq $::O(current)} {
|
||||
lappend tags highlight
|
||||
}
|
||||
set L [format " % -40s%12s%12s\n" $ztest $calls $bytes]
|
||||
$::O(text) insert end $L $tags
|
||||
|
||||
$::O(text) tag bind $ztest <1> [list populate_tree_widget $db $ztest]
|
||||
$::O(text) tag bind $ztest <Enter> [list $::O(text) configure -cursor hand2]
|
||||
$::O(text) tag bind $ztest <Leave> [list $::O(text) configure -cursor ""]
|
||||
}
|
||||
|
||||
$::O(text) configure -state disabled
|
||||
}
|
||||
|
||||
proc sort_tree_compare {iLeft iRight} {
|
||||
global O
|
||||
switch -- [expr (int($O(tree_sort)/2))] {
|
||||
0 {
|
||||
set left [$O(tree) item $iLeft -text]
|
||||
set right [$O(tree) item $iRight -text]
|
||||
set res [string compare $left $right]
|
||||
}
|
||||
1 {
|
||||
set left [lindex [$O(tree) item $iLeft -values] 0]
|
||||
set right [lindex [$O(tree) item $iRight -values] 0]
|
||||
set res [expr $left - $right]
|
||||
}
|
||||
2 {
|
||||
set left [lindex [$O(tree) item $iLeft -values] 1]
|
||||
set right [lindex [$O(tree) item $iRight -values] 1]
|
||||
set res [expr $left - $right]
|
||||
}
|
||||
}
|
||||
if {$O(tree_sort)&0x01} {
|
||||
set res [expr -1 * $res]
|
||||
}
|
||||
return $res
|
||||
}
|
||||
|
||||
proc sort_tree {iMode} {
|
||||
global O
|
||||
if {$O(tree_sort) == $iMode} {
|
||||
incr O(tree_sort)
|
||||
} else {
|
||||
set O(tree_sort) $iMode
|
||||
}
|
||||
set T $O(tree)
|
||||
set items [$T children {}]
|
||||
set items [lsort -command sort_tree_compare $items]
|
||||
for {set ii 0} {$ii < [llength $items]} {incr ii} {
|
||||
$T move [lindex $items $ii] {} $ii
|
||||
}
|
||||
}
|
||||
|
||||
proc trim_frames {stack} {
|
||||
while {[info exists ::O(ignore.[lindex $stack 0])]} {
|
||||
set stack [lrange $stack 1 end]
|
||||
}
|
||||
return $stack
|
||||
}
|
||||
|
||||
proc populate_tree_widget {db zTest} {
|
||||
$::O(tree) delete [$::O(tree) children {}]
|
||||
|
||||
for {set ii 0} {$ii < 15} {incr ii} {
|
||||
$db eval {
|
||||
SELECT
|
||||
sum(ncall) AS calls,
|
||||
sum(nbyte) AS bytes,
|
||||
trim_frames(lrange(lstack, 0, $ii)) AS stack
|
||||
FROM malloc
|
||||
WHERE (zTest = $zTest OR $zTest = 'TOTAL') AND llength(lstack)>$ii
|
||||
GROUP BY stack
|
||||
HAVING stack != ''
|
||||
} {
|
||||
set parent_id [lrange $stack 0 end-1]
|
||||
set frame [lindex $stack end]
|
||||
set line [$db one {SELECT line FROM frame WHERE frame = $frame}]
|
||||
set line [lindex [split $line /] end]
|
||||
set v [list $calls $bytes]
|
||||
|
||||
catch {
|
||||
$::O(tree) insert $parent_id end -id $stack -text $line -values $v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set ::O(current) $zTest
|
||||
populate_index $db
|
||||
}
|
||||
|
||||
|
||||
|
||||
set O(tree_sort) 0
|
||||
|
||||
::ttk::panedwindow .pan -orient horizontal
|
||||
set O(tree) [scrollable ::ttk::treeview .pan.tree]
|
||||
|
||||
frame .pan.right
|
||||
set O(text) [scrollable text .pan.right.text]
|
||||
button .pan.right.index -command {populate_index mddb} -text "Show Index"
|
||||
pack .pan.right.index -side top -fill x
|
||||
pack .pan.right.text -fill both -expand true
|
||||
|
||||
$O(text) tag configure highlight -background wheat
|
||||
$O(text) configure -wrap none -height 35
|
||||
|
||||
.pan add .pan.tree
|
||||
.pan add .pan.right
|
||||
|
||||
$O(tree) configure -columns {calls bytes}
|
||||
$O(tree) heading #0 -text Line -anchor w -command {sort_tree 0}
|
||||
$O(tree) heading calls -text Calls -anchor w -command {sort_tree 2}
|
||||
$O(tree) heading bytes -text Bytes -anchor w -command {sort_tree 4}
|
||||
$O(tree) column #0 -width 150
|
||||
$O(tree) column calls -width 100
|
||||
$O(tree) column bytes -width 100
|
||||
|
||||
pack .pan -fill both -expand 1
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Open the database containing the malloc data. The user specifies the
|
||||
# database to use by passing the file-name on the command line.
|
||||
#
|
||||
proc open_database {} {
|
||||
if {[info exists ::BUILTIN]} {
|
||||
sqlite3 mddb :memory:
|
||||
mddb eval $::BUILTIN
|
||||
wm title . $::argv0
|
||||
} else {
|
||||
set zFilename [lindex $::argv 0]
|
||||
if {$zFilename eq ""} {
|
||||
set zFilename mallocs.sql
|
||||
}
|
||||
set fd [open $zFilename]
|
||||
set zHdr [read $fd 15]
|
||||
if {$zHdr eq "SQLite format 3"} {
|
||||
close $fd
|
||||
sqlite3 mddb $zFilename
|
||||
} else {
|
||||
seek $fd 0
|
||||
sqlite3 mddb :memory:
|
||||
mddb eval [read $fd]
|
||||
close $fd
|
||||
}
|
||||
wm title . $zFilename
|
||||
}
|
||||
|
||||
mddb function lrange -argcount 3 lrange
|
||||
mddb function llength -argcount 1 llength
|
||||
mddb function trim_frames -argcount 1 trim_frames
|
||||
|
||||
mddb eval {
|
||||
SELECT frame FROM frame
|
||||
WHERE line LIKE '%malloc.c:%' OR line LIKE '%mem2.c:%'
|
||||
} {
|
||||
set ::O(ignore.$frame) 1
|
||||
}
|
||||
}
|
||||
|
||||
open_database
|
||||
bind $O(tree) <<TreeviewSelect>> [list populate_text_widget mddb]
|
||||
|
||||
populate_tree_widget mddb [mddb one {SELECT zTest FROM malloc LIMIT 1}]
|
||||
|
||||
@@ -72,293 +72,4 @@ foreach {tnum sql norm} {
|
||||
do_test $tnum [list sqlite3_normalize $sql] $norm
|
||||
}
|
||||
|
||||
ifcapable normalize {
|
||||
do_test 200 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a,b);
|
||||
}
|
||||
} {}
|
||||
do_test 201 {
|
||||
set STMT [sqlite3_prepare_v3 $DB \
|
||||
"SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 0 TAIL]
|
||||
|
||||
sqlite3_bind_null $STMT 1
|
||||
} {}
|
||||
do_test 202 {
|
||||
sqlite3_normalized_sql $STMT
|
||||
} {}
|
||||
do_test 203 {
|
||||
sqlite3_finalize $STMT
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_test 210 {
|
||||
set STMT [sqlite3_prepare_v3 $DB \
|
||||
"SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 2 TAIL]
|
||||
|
||||
sqlite3_bind_null $STMT 1
|
||||
} {}
|
||||
do_test 211 {
|
||||
sqlite3_normalized_sql $STMT
|
||||
} {SELECT a,b FROM t1 WHERE b=?ORDER BY a;}
|
||||
do_test 212 {
|
||||
sqlite3_finalize $STMT
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_test 220 {
|
||||
set STMT [sqlite3_prepare_v3 $DB \
|
||||
"SELECT a, b FROM t1 WHERE b = 'a' ORDER BY a;" -1 2 TAIL]
|
||||
} {/^[0-9A-Fa-f]+$/}
|
||||
do_test 221 {
|
||||
sqlite3_normalized_sql $STMT
|
||||
} {SELECT a,b FROM t1 WHERE b=?ORDER BY a;}
|
||||
do_test 222 {
|
||||
sqlite3_finalize $STMT
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_test 297 {
|
||||
execsql {
|
||||
DROP TABLE t1;
|
||||
}
|
||||
} {}
|
||||
do_test 298 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a,b,c,d,e,"col f",w,x,y,z);
|
||||
CREATE TABLE t2(x,"col y");
|
||||
}
|
||||
} {}
|
||||
do_test 299 {
|
||||
sqlite3_create_function db
|
||||
} {SQLITE_OK}
|
||||
|
||||
foreach {tnum sql flags norm} {
|
||||
300
|
||||
{SELECT * FROM t1 WHERE a IN (1) AND b=51.42}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE a IN(?,?,?)AND b=?;}}
|
||||
|
||||
310
|
||||
{SELECT a, b+15, c FROM t1 WHERE d NOT IN (SELECT x FROM t2);}
|
||||
0x2
|
||||
{0 {SELECT a,b+?,c FROM t1 WHERE d NOT IN(SELECT x FROM t2);}}
|
||||
|
||||
320
|
||||
{ SELECT NULL, b FROM t1 -- comment text
|
||||
WHERE d IN (WITH t(a) AS (VALUES(5)) /* CTE */
|
||||
SELECT a FROM t)
|
||||
OR e='hello';
|
||||
}
|
||||
0x2
|
||||
{0 {SELECT?,b FROM t1 WHERE d IN(WITH t(a)AS(VALUES(?))SELECT a FROM t)OR e=?;}}
|
||||
|
||||
321
|
||||
{/*Initial comment*/
|
||||
-- another comment line
|
||||
SELECT NULL /* comment */ , b FROM t1 -- comment text
|
||||
WHERE d IN (WITH t(a) AS (VALUES(5)) /* CTE */
|
||||
SELECT a FROM t)
|
||||
OR e='hello';
|
||||
}
|
||||
0x2
|
||||
{0 {SELECT?,b FROM t1 WHERE d IN(WITH t(a)AS(VALUES(?))SELECT a FROM t)OR e=?;}}
|
||||
|
||||
330
|
||||
{/* Query containing parameters */
|
||||
SELECT x,$::abc(15),y,@abc,z,?99,w FROM t1 /* Trailing comment */}
|
||||
0x2
|
||||
{0 {SELECT x,?,y,?,z,?,w FROM t1;}}
|
||||
|
||||
340
|
||||
{/* Long list on the RHS of IN */
|
||||
SELECT 15 IN (1,2,3,(SELECT * FROM t1),'xyz',x'abcd',22*(x+5),null);}
|
||||
0x2
|
||||
{1 {(1) no such column: x}}
|
||||
|
||||
350
|
||||
{SELECT x'abc'; -- illegal token}
|
||||
0x2
|
||||
{1 {(1) unrecognized token: "x'abc'"}}
|
||||
|
||||
360
|
||||
{SELECT a,NULL,b FROM t1 WHERE c IS NOT NULL or D is null or e=5}
|
||||
0x2
|
||||
{0 {SELECT a,?,b FROM t1 WHERE c IS NOT NULL OR d IS NULL OR e=?;}}
|
||||
|
||||
370
|
||||
{/* IN list exactly 5 bytes long */
|
||||
SELECT * FROM t1 WHERE x IN (1,2,3);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
400
|
||||
{SELECT a FROM t1 WHERE x IN (1,2,3) AND sqlite_version();}
|
||||
0x2
|
||||
{0 {SELECT a FROM t1 WHERE x IN(?,?,?)AND sqlite_version();}}
|
||||
|
||||
410
|
||||
{SELECT a FROM t1 WHERE x IN (1,2,3) AND hex8();}
|
||||
0x2
|
||||
{1 {(1) wrong number of arguments to function hex8()}}
|
||||
|
||||
420
|
||||
{SELECT a FROM t1 WHERE x IN (1,2,3) AND hex8('abc');}
|
||||
0x2
|
||||
{0 {SELECT a FROM t1 WHERE x IN(?,?,?)AND hex8(?);}}
|
||||
|
||||
430
|
||||
{SELECT "a" FROM t1 WHERE "x" IN ("1","2",'3');}
|
||||
0x2
|
||||
{0 {SELECT"a"FROM t1 WHERE"x"IN(?,?,?);}}
|
||||
|
||||
440
|
||||
{SELECT 'a' FROM t1 WHERE 'x';}
|
||||
0x2
|
||||
{0 {SELECT?FROM t1 WHERE?;}}
|
||||
|
||||
450
|
||||
{SELECT [a] FROM t1 WHERE [x];}
|
||||
0x2
|
||||
{0 {SELECT"a"FROM t1 WHERE"x";}}
|
||||
|
||||
460
|
||||
{SELECT * FROM t1 WHERE x IN (x);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(x);}}
|
||||
|
||||
470
|
||||
{SELECT * FROM t1 WHERE x IN (x,a);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(x,a);}}
|
||||
|
||||
480
|
||||
{SELECT * FROM t1 WHERE x IN ([x],"a");}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN("x","a");}}
|
||||
|
||||
500
|
||||
{SELECT * FROM t1 WHERE x IN ([x],"a",'b',sqlite_version());}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN("x","a",?,sqlite_version());}}
|
||||
|
||||
520
|
||||
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1);}}
|
||||
|
||||
540
|
||||
{SELECT * FROM t1 WHERE x IN ((SELECT x FROM t1));}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
550
|
||||
{SELECT a, a+1, a||'b', a+"b" FROM t1;}
|
||||
0x2
|
||||
{0 {SELECT a,a+?,a||?,a+"b"FROM t1;}}
|
||||
|
||||
570
|
||||
{SELECT * FROM t1 WHERE x IN (1);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
580
|
||||
{SELECT * FROM t1 WHERE x IN (1,2);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
590
|
||||
{SELECT * FROM t1 WHERE x IN (1,2,3);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
600
|
||||
{SELECT * FROM t1 WHERE x IN (1,2,3,4);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
610
|
||||
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1);}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1);}}
|
||||
|
||||
620
|
||||
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (1,2,3));}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(?,?,?));}}
|
||||
|
||||
630
|
||||
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (x));}
|
||||
0x2
|
||||
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(x));}}
|
||||
|
||||
640
|
||||
{SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
|
||||
SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
|
||||
SELECT x FROM t1 WHERE x IN (x)))));}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(x)))));}}
|
||||
|
||||
650
|
||||
{SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
|
||||
SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
|
||||
SELECT x FROM t1 WHERE x IN (1)))));}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(?,?,?)))));}}
|
||||
|
||||
660
|
||||
{SELECT x FROM t1 WHERE x IN (1) UNION ALL SELECT x FROM t1 WHERE x IN (1);}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x IN(?,?,?)UNION ALL SELECT x FROM t1 WHERE x IN(?,?,?);}}
|
||||
|
||||
670
|
||||
{SELECT "col f", [col f] FROM t1;}
|
||||
0x2
|
||||
{0 {SELECT"col f","col f"FROM t1;}}
|
||||
|
||||
680
|
||||
{SELECT a, "col f" FROM t1 LEFT OUTER JOIN t2 ON [t1].[col f] == [t2].[col y];}
|
||||
0x2
|
||||
{0 {SELECT a,"col f"FROM t1 LEFT OUTER JOIN t2 ON"t1"."col f"=="t2"."col y";}}
|
||||
|
||||
690
|
||||
{SELECT * FROM ( WITH x AS ( SELECT * FROM t1 WHERE x IN ( 1)) SELECT 10);}
|
||||
0x2
|
||||
{0 {SELECT*FROM(WITH x AS(SELECT*FROM t1 WHERE x IN(?,?,?))SELECT?);}}
|
||||
|
||||
700
|
||||
{SELECT rowid, oid, _rowid_ FROM t1;}
|
||||
0x2
|
||||
{0 {SELECT rowid,oid,_rowid_ FROM t1;}}
|
||||
|
||||
710
|
||||
{SELECT x FROM t1 WHERE x IS NULL;}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x IS NULL;}}
|
||||
|
||||
740
|
||||
{SELECT x FROM t1 WHERE x IS NOT NULL;}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x IS NOT NULL;}}
|
||||
|
||||
750
|
||||
{SELECT x FROM t1 WHERE x = NULL;}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x=?;}}
|
||||
|
||||
760
|
||||
{SELECT x FROM t1 WHERE x IN ([x] IS NOT NULL, NULL, 1, 'a', "b", x'00');}
|
||||
0x2
|
||||
{0 {SELECT x FROM t1 WHERE x IN("x"IS NOT NULL,?,?,?,"b",?);}}
|
||||
} {
|
||||
do_test $tnum {
|
||||
set code [catch {
|
||||
set STMT [sqlite3_prepare_v3 $DB $sql -1 $flags TAIL]
|
||||
sqlite3_normalized_sql $STMT
|
||||
} res]
|
||||
if {[info exists STMT]} {
|
||||
sqlite3_finalize $STMT; unset STMT
|
||||
}
|
||||
list $code $res
|
||||
} $norm
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+63
-64
@@ -255,7 +255,6 @@ test_suite "fts3" -prefix "" -description {
|
||||
fts3am.test fts3an.test fts3ao.test fts3atoken.test
|
||||
fts3auto.test fts3aux1.test fts3aux2.test fts3b.test
|
||||
fts3comp1.test fts3conf.test fts3corrupt2.test fts3corrupt.test
|
||||
fts3corrupt4.test
|
||||
fts3cov.test fts3c.test fts3defer2.test fts3defer3.test
|
||||
fts3defer.test fts3drop.test fts3d.test fts3e.test
|
||||
fts3expr2.test fts3expr3.test fts3expr4.test fts3expr5.test
|
||||
@@ -290,6 +289,12 @@ test_suite "window" -prefix "" -description {
|
||||
test_set [glob -nocomplain $::testdir/window*.test]
|
||||
]
|
||||
|
||||
test_suite "alter" -prefix "" -description {
|
||||
All ALTER function related tests .
|
||||
} -files [
|
||||
test_set [glob -nocomplain $::testdir/alter*.test]
|
||||
]
|
||||
|
||||
test_suite "lsm1" -prefix "" -description {
|
||||
All LSM1 tests.
|
||||
} -files [glob -nocomplain $::testdir/../ext/lsm1/test/*.test]
|
||||
@@ -555,12 +560,21 @@ test_suite "singlethread" -description {
|
||||
test_suite "nomutex" -description {
|
||||
Tests run with the SQLITE_OPEN_MULTITHREADED flag passed to sqlite3_open().
|
||||
} -initialize {
|
||||
set ::G(perm:sqlite3_args) [list -fullmutex 0 -nomutex 1]
|
||||
rename sqlite3 sqlite3_nomutex
|
||||
proc sqlite3 {args} {
|
||||
if {[string range [lindex $args 0] 0 0] ne "-"} {
|
||||
lappend args -fullmutex 0 -nomutex 1
|
||||
}
|
||||
uplevel [concat sqlite3_nomutex $args]
|
||||
}
|
||||
} -files {
|
||||
delete.test delete2.test insert.test rollback.test select1.test
|
||||
select2.test trans.test update.test vacuum.test types.test
|
||||
types2.test types3.test
|
||||
}
|
||||
} -shutdown {
|
||||
rename sqlite3 {}
|
||||
rename sqlite3_nomutex sqlite3
|
||||
}
|
||||
|
||||
# Run some tests in SQLITE_CONFIG_MULTITHREAD mode.
|
||||
#
|
||||
@@ -589,11 +603,20 @@ test_suite "multithread" -description {
|
||||
test_suite "fullmutex" -description {
|
||||
Tests run in SQLITE_OPEN_FULLMUTEX mode
|
||||
} -initialize {
|
||||
set ::G(perm:sqlite3_args) [list -nomutex 0 -fullmutex 1]
|
||||
rename sqlite3 sqlite3_fullmutex
|
||||
proc sqlite3 {args} {
|
||||
if {[string range [lindex $args 0] 0 0] ne "-"} {
|
||||
lappend args -nomutex 0 -fullmutex 1
|
||||
}
|
||||
uplevel [concat sqlite3_fullmutex $args]
|
||||
}
|
||||
} -files {
|
||||
delete.test delete2.test insert.test rollback.test select1.test
|
||||
select2.test trans.test update.test vacuum.test types.test
|
||||
types2.test types3.test
|
||||
} -shutdown {
|
||||
rename sqlite3 {}
|
||||
rename sqlite3_fullmutex sqlite3
|
||||
}
|
||||
|
||||
# Run some tests using the "onefile" demo.
|
||||
@@ -601,10 +624,19 @@ test_suite "fullmutex" -description {
|
||||
test_suite "onefile" -description {
|
||||
Run some tests using the "test_onefile.c" demo
|
||||
} -initialize {
|
||||
set ::G(perm:sqlite3_args) [list -vfs fs]
|
||||
rename sqlite3 sqlite3_onefile
|
||||
proc sqlite3 {args} {
|
||||
if {[string range [lindex $args 0] 0 0] ne "-"} {
|
||||
lappend args -vfs fs
|
||||
}
|
||||
uplevel [concat sqlite3_onefile $args]
|
||||
}
|
||||
} -files {
|
||||
conflict.test insert.test insert2.test insert3.test
|
||||
rollback.test select1.test select2.test select3.test
|
||||
} -shutdown {
|
||||
rename sqlite3 {}
|
||||
rename sqlite3_onefile sqlite3
|
||||
}
|
||||
|
||||
# Run some tests using UTF-16 databases.
|
||||
@@ -906,8 +938,17 @@ ifcapable threadsafe {
|
||||
test_suite "safe_append" -description {
|
||||
Run some tests on a SAFE_APPEND file-system.
|
||||
} -initialize {
|
||||
set ::G(perm:sqlite3_args) [list -vfs devsym]
|
||||
rename sqlite3 sqlite3_safeappend
|
||||
proc sqlite3 {args} {
|
||||
if {[string range [lindex $args 0] 0 0] ne "-"} {
|
||||
lappend args -vfs devsym
|
||||
}
|
||||
uplevel [concat sqlite3_safeappend $args]
|
||||
}
|
||||
sqlite3_simulate_device -char safe_append
|
||||
} -shutdown {
|
||||
rename sqlite3 {}
|
||||
rename sqlite3_shutdown sqlite3
|
||||
} -files [
|
||||
test_set $::allquicktests shared_err.test -exclude async3.test
|
||||
]
|
||||
@@ -1074,38 +1115,30 @@ test_suite "sorterref" -prefix "" -description {
|
||||
# -description TITLE
|
||||
# -initialize SCRIPT
|
||||
# -shutdown SCRIPT
|
||||
# -presql SQL
|
||||
# -files LIST-OF-FILES
|
||||
# -prefix NAME
|
||||
# -dbconfig SCRIPT
|
||||
#
|
||||
proc run_tests {name args} {
|
||||
set options(-initialize) ""
|
||||
set options(-shutdown) ""
|
||||
set options(-prefix) ""
|
||||
set options(-dbconfig) ""
|
||||
set options(-presql) ""
|
||||
|
||||
array set options $args
|
||||
|
||||
set ::G(perm:name) $name
|
||||
set ::G(perm:prefix) $options(-prefix)
|
||||
set ::G(perm:presql) $options(-presql)
|
||||
set ::G(isquick) 1
|
||||
set ::G(perm:dbconfig) $options(-dbconfig)
|
||||
set ::G(perm:presql) $options(-presql)
|
||||
|
||||
foreach file [lsort $options(-files)] {
|
||||
uplevel $options(-initialize)
|
||||
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
|
||||
slave_test_file $file
|
||||
uplevel $options(-shutdown)
|
||||
|
||||
unset -nocomplain ::G(perm:sqlite3_args)
|
||||
}
|
||||
|
||||
unset ::G(perm:name)
|
||||
unset ::G(perm:prefix)
|
||||
unset ::G(perm:dbconfig)
|
||||
unset ::G(perm:presql)
|
||||
unset ::G(perm:dbconfig)
|
||||
}
|
||||
|
||||
proc run_test_suite {name} {
|
||||
@@ -1119,29 +1152,19 @@ proc help {} {
|
||||
puts "Usage: $::argv0 TESTSUITE ?TESTFILE?"
|
||||
puts ""
|
||||
puts "Available test-suites are:"
|
||||
|
||||
set iPos 0
|
||||
foreach k $::testsuitelist {
|
||||
if {[info exists ::testspec($k)]} {
|
||||
switch $iPos {
|
||||
0 {
|
||||
puts ""
|
||||
puts -nonewline " [format %-30s $k]"
|
||||
}
|
||||
|
||||
1 {
|
||||
puts -nonewline [format %-30s $k]
|
||||
}
|
||||
|
||||
2 {
|
||||
puts -nonewline $k
|
||||
}
|
||||
}
|
||||
|
||||
set iPos [expr (($iPos+1) % 3)]
|
||||
if {[info exists ::testspec($k)]==0} {
|
||||
puts " ----------------------------------------"
|
||||
puts ""
|
||||
} else {
|
||||
array set o $::testspec($k)
|
||||
puts "Test suite: \"$k\""
|
||||
set d [string trim $o(-description)]
|
||||
set d [regsub {\n *} $d "\n "]
|
||||
puts " $d"
|
||||
puts ""
|
||||
}
|
||||
}
|
||||
puts ""
|
||||
exit -1
|
||||
}
|
||||
|
||||
@@ -1150,35 +1173,11 @@ if {[file tail $argv0] == "permutations.test"} {
|
||||
if {[llength $argv]==0} {
|
||||
help
|
||||
} else {
|
||||
|
||||
# See if the first argument is a named test-suite.
|
||||
#
|
||||
set suite [file tail [lindex $argv 0]]
|
||||
if {[info exists ::testspec($suite)]} {
|
||||
set S $::testspec($suite)
|
||||
set i 1
|
||||
} else {
|
||||
set S [list]
|
||||
set i 0
|
||||
}
|
||||
|
||||
if {[info exists ::testspec($suite)]==0} help
|
||||
set extra ""
|
||||
if {$i < [llength $argv] && [string range [lindex $argv $i] 0 0]!="-" } {
|
||||
set files [list]
|
||||
for {} {$i < [llength $argv]} {incr i} {
|
||||
set pattern [string map {% *} [lindex $argv $i]]
|
||||
if {[string range $pattern 0 0]=="-"} break
|
||||
foreach f $::alltests {
|
||||
set tail [file tail $f]
|
||||
if {[lsearch $files $f]<0 && [string match $pattern $tail]} {
|
||||
lappend files $f
|
||||
}
|
||||
}
|
||||
}
|
||||
set extra [list -files $files]
|
||||
}
|
||||
|
||||
eval run_tests $suite $S $extra
|
||||
if {[llength $argv]>1} { set extra [list -files [lrange $argv 1 end]] }
|
||||
eval run_tests $suite $::testspec($suite) $extra
|
||||
}
|
||||
}
|
||||
main $argv
|
||||
|
||||
+1
-5
@@ -15,11 +15,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
if {[sqlite3 -has-codec]} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
do_not_use_codec
|
||||
|
||||
do_execsql_test pragma3-100 {
|
||||
PRAGMA data_version;
|
||||
|
||||
+19
-17
@@ -3757,23 +3757,25 @@ do_test printf-15.3 {
|
||||
|
||||
# Now test malloc() failure within a sqlite3_mprintf():
|
||||
#
|
||||
foreach var {a b c d} {
|
||||
set $var [string repeat $var 400]
|
||||
}
|
||||
set str1 "[string repeat A 360]%d%d%s"
|
||||
set str2 [string repeat B 5000]
|
||||
set zSuccess "[string repeat A 360]11[string repeat B 5000]"
|
||||
foreach ::iRepeat {0 1} {
|
||||
set nTestNum 1
|
||||
while {1} {
|
||||
sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat
|
||||
set z [sqlite3_mprintf_str $str1 1 1 $str2]
|
||||
set nFail [sqlite3_memdebug_fail -1 -benign nBenign]
|
||||
do_test printf-malloc-$::iRepeat.$nTestNum {
|
||||
expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)}
|
||||
} {1}
|
||||
if {$nFail == 0} break
|
||||
incr nTestNum
|
||||
ifcapable memdebug {
|
||||
foreach var {a b c d} {
|
||||
set $var [string repeat $var 400]
|
||||
}
|
||||
set str1 "[string repeat A 360]%d%d%s"
|
||||
set str2 [string repeat B 5000]
|
||||
set zSuccess "[string repeat A 360]11[string repeat B 5000]"
|
||||
foreach ::iRepeat {0 1} {
|
||||
set nTestNum 1
|
||||
while {1} {
|
||||
sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat
|
||||
set z [sqlite3_mprintf_str $str1 1 1 $str2]
|
||||
set nFail [sqlite3_memdebug_fail -1 -benign nBenign]
|
||||
do_test printf-malloc-$::iRepeat.$nTestNum {
|
||||
expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)}
|
||||
} {1}
|
||||
if {$nFail == 0} break
|
||||
incr nTestNum
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user