mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Merge in the IS-operator enhancements and other recent changes from trunk.
FossilOrigin-Name: 4f9229445c293b39c80b2a662901f608c85b36ef
This commit is contained in:
27
Makefile.in
27
Makefile.in
@ -519,6 +519,15 @@ EXTHDR += \
|
|||||||
EXTHDR += \
|
EXTHDR += \
|
||||||
$(TOP)/ext/rtree/sqlite3rtree.h
|
$(TOP)/ext/rtree/sqlite3rtree.h
|
||||||
|
|
||||||
|
# executables needed for testing
|
||||||
|
#
|
||||||
|
TESTPROGS = \
|
||||||
|
testfixture$(TEXE) \
|
||||||
|
sqlite3$(TEXE) \
|
||||||
|
sqlite3_analyzer$(TEXE) \
|
||||||
|
sqldiff$(TEXE)
|
||||||
|
|
||||||
|
|
||||||
# This is the default Makefile target. The objects listed here
|
# This is the default Makefile target. The objects listed here
|
||||||
# are what get build when you type just "make" with no arguments.
|
# are what get build when you type just "make" with no arguments.
|
||||||
#
|
#
|
||||||
@ -968,15 +977,15 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
|||||||
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
||||||
|
|
||||||
# A very detailed test running most or all test cases
|
# A very detailed test running most or all test cases
|
||||||
fulltest: testfixture$(TEXE) sqlite3$(TEXE) fuzztest
|
fulltest: $(TESTPROGS) fuzztest
|
||||||
./testfixture$(TEXE) $(TOP)/test/all.test
|
./testfixture$(TEXE) $(TOP)/test/all.test
|
||||||
|
|
||||||
# Really really long testing
|
# Really really long testing
|
||||||
soaktest: testfixture$(TEXE) sqlite3$(TEXE) fuzzoomtest
|
soaktest: $(TESTPROGS) fuzzoomtest
|
||||||
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
|
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
|
||||||
|
|
||||||
# Do extra testing but not aeverything.
|
# Do extra testing but not everything.
|
||||||
fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
|
fulltestonly: $(TESTPROGS)
|
||||||
./testfixture$(TEXE) $(TOP)/test/full.test
|
./testfixture$(TEXE) $(TOP)/test/full.test
|
||||||
|
|
||||||
# Fuzz testing
|
# Fuzz testing
|
||||||
@ -989,13 +998,13 @@ fuzzoomtest: fuzzershell$(TEXE)
|
|||||||
# This is the common case. Run many tests but not those that take
|
# This is the common case. Run many tests but not those that take
|
||||||
# a really long time.
|
# a really long time.
|
||||||
#
|
#
|
||||||
test: testfixture$(TEXE) sqlite3$(TEXE) fuzztest
|
test: $(TESTPROGS) fuzztest
|
||||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test
|
./testfixture$(TEXE) $(TOP)/test/veryquick.test
|
||||||
|
|
||||||
# Run a test using valgrind. This can take a really long time
|
# Run a test using valgrind. This can take a really long time
|
||||||
# because valgrind is so much slower than a native machine.
|
# because valgrind is so much slower than a native machine.
|
||||||
#
|
#
|
||||||
valgrindtest: testfixture$(TEXE) sqlite3$(TEXE) fuzzershell$(TEXE)
|
valgrindtest: $(TESTPROGS) fuzzershell$(TEXE)
|
||||||
valgrind -v ./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt
|
valgrind -v ./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt
|
||||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind
|
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind
|
||||||
|
|
||||||
@ -1003,12 +1012,12 @@ valgrindtest: testfixture$(TEXE) sqlite3$(TEXE) fuzzershell$(TEXE)
|
|||||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||||
# comes out."
|
# comes out."
|
||||||
#
|
#
|
||||||
smoketest: testfixture$(TEXE) fuzzershell$(TEXE)
|
smoketest: $(TESTPROGS) fuzzershell$(TEXE)
|
||||||
./testfixture$(TEXE) $(TOP)/test/main.test
|
./testfixture$(TEXE) $(TOP)/test/main.test
|
||||||
|
|
||||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||||
echo "#define TCLSH 2" > $@
|
echo "#define TCLSH 2" > $@
|
||||||
echo "#define SQLITE_ENABLE_DBSTAT_VTAB" >> $@
|
echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
|
||||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
||||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
echo "static const char *tclsh_main_loop(void){" >> $@
|
||||||
echo "static const char *zMainloop = " >> $@
|
echo "static const char *zMainloop = " >> $@
|
||||||
@ -1122,6 +1131,8 @@ clean:
|
|||||||
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
|
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
|
||||||
rm -f sqlite-*-output.vsix
|
rm -f sqlite-*-output.vsix
|
||||||
rm -f mptester mptester.exe
|
rm -f mptester mptester.exe
|
||||||
|
rm -f fuzzershell fuzzershell.exe
|
||||||
|
rm -f sqldiff sqldiff.exe
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f config.log config.status libtool Makefile sqlite3.pc
|
rm -f config.log config.status libtool Makefile sqlite3.pc
|
||||||
|
47
Makefile.msc
47
Makefile.msc
@ -36,6 +36,13 @@ USE_STDCALL = 0
|
|||||||
DYNAMIC_SHELL = 0
|
DYNAMIC_SHELL = 0
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to enable extra code that attempts to detect misuse of the
|
||||||
|
# SQLite API.
|
||||||
|
#
|
||||||
|
!IFNDEF API_ARMOR
|
||||||
|
API_ARMOR = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
# If necessary, create a list of harmless compiler warnings to disable when
|
# If necessary, create a list of harmless compiler warnings to disable when
|
||||||
# compiling the various tools. For the SQLite source code itself, warnings,
|
# compiling the various tools. For the SQLite source code itself, warnings,
|
||||||
# if any, will be disabled from within it.
|
# if any, will be disabled from within it.
|
||||||
@ -493,14 +500,14 @@ BCC = $(BCC) -DNDEBUG
|
|||||||
RCC = $(RCC) -DNDEBUG
|
RCC = $(RCC) -DNDEBUG
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF $(DEBUG)>0
|
!IF $(DEBUG)>0 || $(API_ARMOR)!=0
|
||||||
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR
|
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||||
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR
|
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF $(DEBUG)>2
|
!IF $(DEBUG)>2
|
||||||
TCC = $(TCC) -DSQLITE_DEBUG
|
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||||
RCC = $(RCC) -DSQLITE_DEBUG
|
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||||
@ -509,8 +516,8 @@ RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF $(DEBUG)>5
|
!IF $(DEBUG)>5
|
||||||
TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE
|
TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE=1
|
||||||
RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE
|
RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE=1
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# Prevent warnings about "insecure" MSVC runtime library functions
|
# Prevent warnings about "insecure" MSVC runtime library functions
|
||||||
@ -1196,6 +1203,15 @@ EXTHDR = $(EXTHDR) \
|
|||||||
EXTHDR = $(EXTHDR) \
|
EXTHDR = $(EXTHDR) \
|
||||||
$(TOP)\ext\session\sqlite3session.h
|
$(TOP)\ext\session\sqlite3session.h
|
||||||
|
|
||||||
|
# executables needed for testing
|
||||||
|
#
|
||||||
|
TESTPROGS = \
|
||||||
|
testfixture.exe \
|
||||||
|
sqlite3.exe \
|
||||||
|
sqlite3_analyzer.exe \
|
||||||
|
sqldiff.exe
|
||||||
|
|
||||||
|
|
||||||
# This is the default Makefile target. The objects listed here
|
# This is the default Makefile target. The objects listed here
|
||||||
# are what get build when you type just "make" with no arguments.
|
# are what get build when you type just "make" with no arguments.
|
||||||
#
|
#
|
||||||
@ -1663,13 +1679,13 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
|||||||
extensiontest: testfixture.exe testloadext.dll
|
extensiontest: testfixture.exe testloadext.dll
|
||||||
.\testfixture.exe $(TOP)\test\loadext.test
|
.\testfixture.exe $(TOP)\test\loadext.test
|
||||||
|
|
||||||
fulltest: testfixture.exe sqlite3.exe fuzztest
|
fulltest: $(TESTPROGS) fuzztest
|
||||||
.\testfixture.exe $(TOP)\test\all.test
|
.\testfixture.exe $(TOP)\test\all.test
|
||||||
|
|
||||||
soaktest: testfixture.exe sqlite3.exe fuzzoomtest
|
soaktest: $(TESTPROGS) fuzzoomtest
|
||||||
.\testfixture.exe $(TOP)\test\all.test -soak=1
|
.\testfixture.exe $(TOP)\test\all.test -soak=1
|
||||||
|
|
||||||
fulltestonly: testfixture.exe sqlite3.exe fuzztest
|
fulltestonly: $(TESTPROGS) fuzztest
|
||||||
.\testfixture.exe $(TOP)\test\full.test
|
.\testfixture.exe $(TOP)\test\full.test
|
||||||
|
|
||||||
queryplantest: testfixture.exe sqlite3.exe
|
queryplantest: testfixture.exe sqlite3.exe
|
||||||
@ -1681,21 +1697,23 @@ fuzztest: fuzzershell.exe
|
|||||||
fuzzoomtest: fuzzershell.exe
|
fuzzoomtest: fuzzershell.exe
|
||||||
.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom
|
.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom
|
||||||
|
|
||||||
test: testfixture.exe sqlite3.exe fuzztest
|
test: $(TESTPROGS) fuzztest
|
||||||
.\testfixture.exe $(TOP)\test\veryquick.test
|
.\testfixture.exe $(TOP)\test\veryquick.test
|
||||||
|
|
||||||
smoketest: testfixture.exe
|
smoketest: $(TESTPROGS) fuzzershell.exe
|
||||||
.\testfixture.exe $(TOP)\test\main.test
|
.\testfixture.exe $(TOP)\test\main.test
|
||||||
|
|
||||||
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
||||||
copy $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
echo #define TCLSH 2 > $@
|
||||||
|
echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
|
||||||
|
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
||||||
echo static const char *tclsh_main_loop(void){ >> $@
|
echo static const char *tclsh_main_loop(void){ >> $@
|
||||||
echo static const char *zMainloop = >> $@
|
echo static const char *zMainloop = >> $@
|
||||||
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
|
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
|
||||||
echo ; return zMainloop; } >> $@
|
echo ; return zMainloop; } >> $@
|
||||||
|
|
||||||
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -DSQLITE_ENABLE_DBSTAT_VTAB -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
|
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||||
|
|
||||||
testloadext.lo: $(TOP)\src\test_loadext.c
|
testloadext.lo: $(TOP)\src\test_loadext.c
|
||||||
@ -1770,6 +1788,7 @@ clean:
|
|||||||
del /Q shell.c sqlite3ext.h 2>NUL
|
del /Q shell.c sqlite3ext.h 2>NUL
|
||||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
|
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
|
||||||
del /Q sqlite-*-output.vsix 2>NUL
|
del /Q sqlite-*-output.vsix 2>NUL
|
||||||
|
del /Q fuzzershell.exe sqldiff.exe 2>NUL
|
||||||
|
|
||||||
# Dynamic link library section.
|
# Dynamic link library section.
|
||||||
#
|
#
|
||||||
|
@ -6,8 +6,9 @@ libsqlite3_la_SOURCES = sqlite3.c
|
|||||||
libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
|
libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
|
||||||
|
|
||||||
bin_PROGRAMS = sqlite3
|
bin_PROGRAMS = sqlite3
|
||||||
sqlite3_SOURCES = shell.c sqlite3.h
|
sqlite3_SOURCES = shell.c sqlite3.c sqlite3.h
|
||||||
sqlite3_LDADD = sqlite3.$(OBJEXT) @READLINE_LIBS@
|
sqlite3_LDADD = @READLINE_LIBS@
|
||||||
|
sqlite3_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
include_HEADERS = sqlite3.h sqlite3ext.h
|
include_HEADERS = sqlite3.h sqlite3ext.h
|
||||||
|
|
||||||
|
18
configure
vendored
18
configure
vendored
@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.10.
|
# Generated by GNU Autoconf 2.62 for sqlite 3.8.10.1.
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='sqlite'
|
PACKAGE_NAME='sqlite'
|
||||||
PACKAGE_TARNAME='sqlite'
|
PACKAGE_TARNAME='sqlite'
|
||||||
PACKAGE_VERSION='3.8.10'
|
PACKAGE_VERSION='3.8.10.1'
|
||||||
PACKAGE_STRING='sqlite 3.8.10'
|
PACKAGE_STRING='sqlite 3.8.10.1'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
|
|
||||||
# Factoring default headers for most tests.
|
# Factoring default headers for most tests.
|
||||||
@ -1481,7 +1481,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# 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.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures sqlite 3.8.10 to adapt to many kinds of systems.
|
\`configure' configures sqlite 3.8.10.1 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@ -1546,7 +1546,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of sqlite 3.8.10:";;
|
short | recursive ) echo "Configuration of sqlite 3.8.10.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@ -1660,7 +1660,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
sqlite configure 3.8.10
|
sqlite configure 3.8.10.1
|
||||||
generated by GNU Autoconf 2.62
|
generated by GNU Autoconf 2.62
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
@ -1674,7 +1674,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by sqlite $as_me 3.8.10, which was
|
It was created by sqlite $as_me 3.8.10.1, which was
|
||||||
generated by GNU Autoconf 2.62. Invocation command line was
|
generated by GNU Autoconf 2.62. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@ -13953,7 +13953,7 @@ exec 6>&1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by sqlite $as_me 3.8.10, which was
|
This file was extended by sqlite $as_me 3.8.10.1, which was
|
||||||
generated by GNU Autoconf 2.62. Invocation command line was
|
generated by GNU Autoconf 2.62. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@ -14006,7 +14006,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
|||||||
_ACEOF
|
_ACEOF
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
sqlite config.status 3.8.10
|
sqlite config.status 3.8.10.1
|
||||||
configured by $0, generated by GNU Autoconf 2.62,
|
configured by $0, generated by GNU Autoconf 2.62,
|
||||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||||
|
|
||||||
|
@ -1675,7 +1675,7 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
|||||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||||
sqlite3Fts3FreeDeferredTokens(pCsr);
|
sqlite3Fts3FreeDeferredTokens(pCsr);
|
||||||
sqlite3_free(pCsr->aDoclist);
|
sqlite3_free(pCsr->aDoclist);
|
||||||
sqlite3_free(pCsr->aMatchinfo);
|
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||||
sqlite3_free(pCsr);
|
sqlite3_free(pCsr);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -3176,7 +3176,7 @@ static int fts3FilterMethod(
|
|||||||
/* In case the cursor has been used before, clear it now. */
|
/* In case the cursor has been used before, clear it now. */
|
||||||
sqlite3_finalize(pCsr->pStmt);
|
sqlite3_finalize(pCsr->pStmt);
|
||||||
sqlite3_free(pCsr->aDoclist);
|
sqlite3_free(pCsr->aDoclist);
|
||||||
sqlite3_free(pCsr->aMatchinfo);
|
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||||
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
|
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
|
||||||
|
|
||||||
|
@ -197,6 +197,8 @@ typedef struct Fts3DeferredToken Fts3DeferredToken;
|
|||||||
typedef struct Fts3SegReader Fts3SegReader;
|
typedef struct Fts3SegReader Fts3SegReader;
|
||||||
typedef struct Fts3MultiSegReader Fts3MultiSegReader;
|
typedef struct Fts3MultiSegReader Fts3MultiSegReader;
|
||||||
|
|
||||||
|
typedef struct MatchinfoBuffer MatchinfoBuffer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** A connection to a fulltext index is an instance of the following
|
** A connection to a fulltext index is an instance of the following
|
||||||
** structure. The xCreate and xConnect methods create an instance
|
** structure. The xCreate and xConnect methods create an instance
|
||||||
@ -306,9 +308,7 @@ struct Fts3Cursor {
|
|||||||
i64 iMinDocid; /* Minimum docid to return */
|
i64 iMinDocid; /* Minimum docid to return */
|
||||||
i64 iMaxDocid; /* Maximum docid to return */
|
i64 iMaxDocid; /* Maximum docid to return */
|
||||||
int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
|
int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
|
||||||
u32 *aMatchinfo; /* Information about most recent match */
|
MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */
|
||||||
int nMatchinfo; /* Number of elements in aMatchinfo[] */
|
|
||||||
char *zMatchinfo; /* Matchinfo specification */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FTS3_EVAL_FILTER 0
|
#define FTS3_EVAL_FILTER 0
|
||||||
@ -428,7 +428,9 @@ struct Fts3Expr {
|
|||||||
u8 bStart; /* True if iDocid is valid */
|
u8 bStart; /* True if iDocid is valid */
|
||||||
u8 bDeferred; /* True if this expression is entirely deferred */
|
u8 bDeferred; /* True if this expression is entirely deferred */
|
||||||
|
|
||||||
u32 *aMI;
|
/* The following are used by the fts3_snippet.c module. */
|
||||||
|
int iPhrase; /* Index of this phrase in matchinfo() results */
|
||||||
|
u32 *aMI; /* See above */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -564,6 +566,7 @@ void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
|
|||||||
const char *, const char *, int, int
|
const char *, const char *, int, int
|
||||||
);
|
);
|
||||||
void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
|
void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
|
||||||
|
void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p);
|
||||||
|
|
||||||
/* fts3_expr.c */
|
/* fts3_expr.c */
|
||||||
int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
|
int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
|
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
|
||||||
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
|
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
|
||||||
#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
|
#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
|
||||||
|
#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The default value for the second argument to matchinfo().
|
** The default value for the second argument to matchinfo().
|
||||||
@ -89,9 +90,22 @@ struct MatchInfo {
|
|||||||
int nCol; /* Number of columns in table */
|
int nCol; /* Number of columns in table */
|
||||||
int nPhrase; /* Number of matchable phrases in query */
|
int nPhrase; /* Number of matchable phrases in query */
|
||||||
sqlite3_int64 nDoc; /* Number of docs in database */
|
sqlite3_int64 nDoc; /* Number of docs in database */
|
||||||
|
char flag;
|
||||||
u32 *aMatchinfo; /* Pre-allocated buffer */
|
u32 *aMatchinfo; /* Pre-allocated buffer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** An instance of this structure is used to manage a pair of buffers, each
|
||||||
|
** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below
|
||||||
|
** for details.
|
||||||
|
*/
|
||||||
|
struct MatchinfoBuffer {
|
||||||
|
u8 aRef[3];
|
||||||
|
int nElem;
|
||||||
|
int bGlobal; /* Set if global data is loaded */
|
||||||
|
char *zMatchinfo;
|
||||||
|
u32 aMatchinfo[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -107,6 +121,97 @@ struct StrBuffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
** Start of MatchinfoBuffer code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate a two-slot MatchinfoBuffer object.
|
||||||
|
*/
|
||||||
|
static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
|
||||||
|
MatchinfoBuffer *pRet;
|
||||||
|
int nByte = sizeof(u32) * (2*nElem + 2) + sizeof(MatchinfoBuffer);
|
||||||
|
int nStr = strlen(zMatchinfo);
|
||||||
|
|
||||||
|
pRet = sqlite3_malloc(nByte + nStr+1);
|
||||||
|
if( pRet ){
|
||||||
|
memset(pRet, 0, nByte);
|
||||||
|
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
|
||||||
|
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
|
||||||
|
pRet->nElem = nElem;
|
||||||
|
pRet->zMatchinfo = ((char*)pRet) + nByte;
|
||||||
|
memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
|
||||||
|
pRet->aRef[0] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fts3MIBufferFree(void *p){
|
||||||
|
MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
|
||||||
|
|
||||||
|
assert( (u32*)p==&pBuf->aMatchinfo[1]
|
||||||
|
|| (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
|
||||||
|
);
|
||||||
|
if( (u32*)p==&pBuf->aMatchinfo[1] ){
|
||||||
|
pBuf->aRef[1] = 0;
|
||||||
|
}else{
|
||||||
|
pBuf->aRef[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){
|
||||||
|
sqlite3_free(pBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
|
||||||
|
void (*xRet)(void*) = 0;
|
||||||
|
u32 *aOut = 0;
|
||||||
|
|
||||||
|
if( p->aRef[1]==0 ){
|
||||||
|
p->aRef[1] = 1;
|
||||||
|
aOut = &p->aMatchinfo[1];
|
||||||
|
xRet = fts3MIBufferFree;
|
||||||
|
}
|
||||||
|
else if( p->aRef[2]==0 ){
|
||||||
|
p->aRef[2] = 1;
|
||||||
|
aOut = &p->aMatchinfo[p->nElem+2];
|
||||||
|
xRet = fts3MIBufferFree;
|
||||||
|
}else{
|
||||||
|
aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
|
||||||
|
if( aOut ){
|
||||||
|
xRet = sqlite3_free;
|
||||||
|
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*paOut = aOut;
|
||||||
|
return xRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
|
||||||
|
p->bGlobal = 1;
|
||||||
|
memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Free a MatchinfoBuffer object allocated using fts3MIBufferNew()
|
||||||
|
*/
|
||||||
|
void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
|
||||||
|
if( p ){
|
||||||
|
assert( p->aRef[0]==1 );
|
||||||
|
p->aRef[0] = 0;
|
||||||
|
if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){
|
||||||
|
sqlite3_free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** End of MatchinfoBuffer code.
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This function is used to help iterate through a position-list. A position
|
** This function is used to help iterate through a position-list. A position
|
||||||
** list is a list of unique integers, sorted from smallest to largest. Each
|
** list is a list of unique integers, sorted from smallest to largest. Each
|
||||||
@ -143,7 +248,7 @@ static int fts3ExprIterate2(
|
|||||||
void *pCtx /* Second argument to pass to callback */
|
void *pCtx /* Second argument to pass to callback */
|
||||||
){
|
){
|
||||||
int rc; /* Return code */
|
int rc; /* Return code */
|
||||||
int eType = pExpr->eType; /* Type of expression node pExpr */
|
int eType = pExpr->eType; /* Type of expression node pExpr */
|
||||||
|
|
||||||
if( eType!=FTSQUERY_PHRASE ){
|
if( eType!=FTSQUERY_PHRASE ){
|
||||||
assert( pExpr->pLeft && pExpr->pRight );
|
assert( pExpr->pLeft && pExpr->pRight );
|
||||||
@ -177,6 +282,7 @@ static int fts3ExprIterate(
|
|||||||
return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
|
return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This is an fts3ExprIterate() callback used while loading the doclists
|
** This is an fts3ExprIterate() callback used while loading the doclists
|
||||||
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
|
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
|
||||||
@ -221,8 +327,7 @@ static int fts3ExprLoadDoclists(
|
|||||||
|
|
||||||
static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
||||||
(*(int *)ctx)++;
|
(*(int *)ctx)++;
|
||||||
UNUSED_PARAMETER(pExpr);
|
pExpr->iPhrase = iPhrase;
|
||||||
UNUSED_PARAMETER(iPhrase);
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
static int fts3ExprPhraseCount(Fts3Expr *pExpr){
|
static int fts3ExprPhraseCount(Fts3Expr *pExpr){
|
||||||
@ -443,7 +548,7 @@ static int fts3BestSnippet(
|
|||||||
sIter.nSnippet = nSnippet;
|
sIter.nSnippet = nSnippet;
|
||||||
sIter.nPhrase = nList;
|
sIter.nPhrase = nList;
|
||||||
sIter.iCurrent = -1;
|
sIter.iCurrent = -1;
|
||||||
rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
|
rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
|
||||||
/* Set the *pmSeen output variable. */
|
/* Set the *pmSeen output variable. */
|
||||||
@ -744,6 +849,60 @@ static int fts3ColumnlistCount(char **ppCollist){
|
|||||||
return nEntry;
|
return nEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function gathers 'y' or 'b' data for a single phrase.
|
||||||
|
*/
|
||||||
|
static void fts3ExprLHits(
|
||||||
|
Fts3Expr *pExpr, /* Phrase expression node */
|
||||||
|
MatchInfo *p /* Matchinfo context */
|
||||||
|
){
|
||||||
|
Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
|
||||||
|
int iStart;
|
||||||
|
Fts3Phrase *pPhrase = pExpr->pPhrase;
|
||||||
|
char *pIter = pPhrase->doclist.pList;
|
||||||
|
int iCol = 0;
|
||||||
|
|
||||||
|
assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
|
||||||
|
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
||||||
|
iStart = pExpr->iPhrase * p->nCol;
|
||||||
|
}else{
|
||||||
|
iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
while( 1 ){
|
||||||
|
int nHit = fts3ColumnlistCount(&pIter);
|
||||||
|
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
|
||||||
|
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
||||||
|
p->aMatchinfo[iStart + iCol] = (u32)nHit;
|
||||||
|
}else if( nHit ){
|
||||||
|
p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert( *pIter==0x00 || *pIter==0x01 );
|
||||||
|
if( *pIter!=0x01 ) break;
|
||||||
|
pIter++;
|
||||||
|
pIter += fts3GetVarint32(pIter, &iCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Gather the results for matchinfo directives 'y' and 'b'.
|
||||||
|
*/
|
||||||
|
static void fts3ExprLHitGather(
|
||||||
|
Fts3Expr *pExpr,
|
||||||
|
MatchInfo *p
|
||||||
|
){
|
||||||
|
assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
|
||||||
|
if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
|
||||||
|
if( pExpr->pLeft ){
|
||||||
|
fts3ExprLHitGather(pExpr->pLeft, p);
|
||||||
|
fts3ExprLHitGather(pExpr->pRight, p);
|
||||||
|
}else{
|
||||||
|
fts3ExprLHits(pExpr, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** fts3ExprIterate() callback used to collect the "global" matchinfo stats
|
** fts3ExprIterate() callback used to collect the "global" matchinfo stats
|
||||||
** for a single query.
|
** for a single query.
|
||||||
@ -810,51 +969,6 @@ static int fts3ExprLocalHitsCb(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** fts3ExprIterate() callback used to gather information for the matchinfo
|
|
||||||
** directive 'y'.
|
|
||||||
*/
|
|
||||||
static int fts3ExprLHitsCb(
|
|
||||||
Fts3Expr *pExpr, /* Phrase expression node */
|
|
||||||
int iPhrase, /* Phrase number */
|
|
||||||
void *pCtx /* Pointer to MatchInfo structure */
|
|
||||||
){
|
|
||||||
MatchInfo *p = (MatchInfo *)pCtx;
|
|
||||||
Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
|
|
||||||
int rc = SQLITE_OK;
|
|
||||||
int iStart = iPhrase * p->nCol;
|
|
||||||
Fts3Expr *pEof; /* Ancestor node already at EOF */
|
|
||||||
|
|
||||||
/* This must be a phrase */
|
|
||||||
assert( pExpr->pPhrase );
|
|
||||||
|
|
||||||
/* Initialize all output integers to zero. */
|
|
||||||
memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
|
|
||||||
|
|
||||||
/* Check if this or any parent node is at EOF. If so, then all output
|
|
||||||
** values are zero. */
|
|
||||||
for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
|
|
||||||
|
|
||||||
if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
|
|
||||||
Fts3Phrase *pPhrase = pExpr->pPhrase;
|
|
||||||
char *pIter = pPhrase->doclist.pList;
|
|
||||||
int iCol = 0;
|
|
||||||
|
|
||||||
while( 1 ){
|
|
||||||
int nHit = fts3ColumnlistCount(&pIter);
|
|
||||||
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
|
|
||||||
p->aMatchinfo[iStart + iCol] = (u32)nHit;
|
|
||||||
}
|
|
||||||
assert( *pIter==0x00 || *pIter==0x01 );
|
|
||||||
if( *pIter!=0x01 ) break;
|
|
||||||
pIter++;
|
|
||||||
pIter += fts3GetVarint32(pIter, &iCol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fts3MatchinfoCheck(
|
static int fts3MatchinfoCheck(
|
||||||
Fts3Table *pTab,
|
Fts3Table *pTab,
|
||||||
char cArg,
|
char cArg,
|
||||||
@ -868,6 +982,7 @@ static int fts3MatchinfoCheck(
|
|||||||
|| (cArg==FTS3_MATCHINFO_LCS)
|
|| (cArg==FTS3_MATCHINFO_LCS)
|
||||||
|| (cArg==FTS3_MATCHINFO_HITS)
|
|| (cArg==FTS3_MATCHINFO_HITS)
|
||||||
|| (cArg==FTS3_MATCHINFO_LHITS)
|
|| (cArg==FTS3_MATCHINFO_LHITS)
|
||||||
|
|| (cArg==FTS3_MATCHINFO_LHITS_BM)
|
||||||
){
|
){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@ -895,6 +1010,10 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
|||||||
nVal = pInfo->nCol * pInfo->nPhrase;
|
nVal = pInfo->nCol * pInfo->nPhrase;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FTS3_MATCHINFO_LHITS_BM:
|
||||||
|
nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert( cArg==FTS3_MATCHINFO_HITS );
|
assert( cArg==FTS3_MATCHINFO_HITS );
|
||||||
nVal = pInfo->nCol * pInfo->nPhrase * 3;
|
nVal = pInfo->nCol * pInfo->nPhrase * 3;
|
||||||
@ -1089,7 +1208,7 @@ static int fts3MatchinfoValues(
|
|||||||
sqlite3_stmt *pSelect = 0;
|
sqlite3_stmt *pSelect = 0;
|
||||||
|
|
||||||
for(i=0; rc==SQLITE_OK && zArg[i]; i++){
|
for(i=0; rc==SQLITE_OK && zArg[i]; i++){
|
||||||
|
pInfo->flag = zArg[i];
|
||||||
switch( zArg[i] ){
|
switch( zArg[i] ){
|
||||||
case FTS3_MATCHINFO_NPHRASE:
|
case FTS3_MATCHINFO_NPHRASE:
|
||||||
if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
|
if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
|
||||||
@ -1149,9 +1268,13 @@ static int fts3MatchinfoValues(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTS3_MATCHINFO_LHITS:
|
case FTS3_MATCHINFO_LHITS_BM:
|
||||||
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
|
case FTS3_MATCHINFO_LHITS: {
|
||||||
|
int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
|
||||||
|
memset(pInfo->aMatchinfo, 0, nZero);
|
||||||
|
fts3ExprLHitGather(pCsr->pExpr, pInfo);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
Fts3Expr *pExpr;
|
Fts3Expr *pExpr;
|
||||||
@ -1184,7 +1307,8 @@ static int fts3MatchinfoValues(
|
|||||||
** Populate pCsr->aMatchinfo[] with data for the current row. The
|
** Populate pCsr->aMatchinfo[] with data for the current row. The
|
||||||
** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
|
** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
|
||||||
*/
|
*/
|
||||||
static int fts3GetMatchinfo(
|
static void fts3GetMatchinfo(
|
||||||
|
sqlite3_context *pCtx, /* Return results here */
|
||||||
Fts3Cursor *pCsr, /* FTS3 Cursor object */
|
Fts3Cursor *pCsr, /* FTS3 Cursor object */
|
||||||
const char *zArg /* Second argument to matchinfo() function */
|
const char *zArg /* Second argument to matchinfo() function */
|
||||||
){
|
){
|
||||||
@ -1193,6 +1317,9 @@ static int fts3GetMatchinfo(
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int bGlobal = 0; /* Collect 'global' stats as well as local */
|
int bGlobal = 0; /* Collect 'global' stats as well as local */
|
||||||
|
|
||||||
|
u32 *aOut = 0;
|
||||||
|
void (*xDestroyOut)(void*) = 0;
|
||||||
|
|
||||||
memset(&sInfo, 0, sizeof(MatchInfo));
|
memset(&sInfo, 0, sizeof(MatchInfo));
|
||||||
sInfo.pCursor = pCsr;
|
sInfo.pCursor = pCsr;
|
||||||
sInfo.nCol = pTab->nColumn;
|
sInfo.nCol = pTab->nColumn;
|
||||||
@ -1200,21 +1327,18 @@ static int fts3GetMatchinfo(
|
|||||||
/* If there is cached matchinfo() data, but the format string for the
|
/* If there is cached matchinfo() data, but the format string for the
|
||||||
** cache does not match the format string for this request, discard
|
** cache does not match the format string for this request, discard
|
||||||
** the cached data. */
|
** the cached data. */
|
||||||
if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){
|
if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){
|
||||||
assert( pCsr->aMatchinfo );
|
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||||
sqlite3_free(pCsr->aMatchinfo);
|
pCsr->pMIBuffer = 0;
|
||||||
pCsr->zMatchinfo = 0;
|
|
||||||
pCsr->aMatchinfo = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
|
/* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the
|
||||||
** matchinfo function has been called for this query. In this case
|
** matchinfo function has been called for this query. In this case
|
||||||
** allocate the array used to accumulate the matchinfo data and
|
** allocate the array used to accumulate the matchinfo data and
|
||||||
** initialize those elements that are constant for every row.
|
** initialize those elements that are constant for every row.
|
||||||
*/
|
*/
|
||||||
if( pCsr->aMatchinfo==0 ){
|
if( pCsr->pMIBuffer==0 ){
|
||||||
int nMatchinfo = 0; /* Number of u32 elements in match-info */
|
int nMatchinfo = 0; /* Number of u32 elements in match-info */
|
||||||
int nArg; /* Bytes in zArg */
|
|
||||||
int i; /* Used to iterate through zArg */
|
int i; /* Used to iterate through zArg */
|
||||||
|
|
||||||
/* Determine the number of phrases in the query */
|
/* Determine the number of phrases in the query */
|
||||||
@ -1223,30 +1347,46 @@ static int fts3GetMatchinfo(
|
|||||||
|
|
||||||
/* Determine the number of integers in the buffer returned by this call. */
|
/* Determine the number of integers in the buffer returned by this call. */
|
||||||
for(i=0; zArg[i]; i++){
|
for(i=0; zArg[i]; i++){
|
||||||
|
char *zErr = 0;
|
||||||
|
if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
|
||||||
|
sqlite3_result_error(pCtx, zErr, -1);
|
||||||
|
sqlite3_free(zErr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
|
nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
|
/* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
|
||||||
nArg = (int)strlen(zArg);
|
pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg);
|
||||||
pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1);
|
if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM;
|
||||||
if( !pCsr->aMatchinfo ) return SQLITE_NOMEM;
|
|
||||||
|
|
||||||
pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo];
|
|
||||||
pCsr->nMatchinfo = nMatchinfo;
|
|
||||||
memcpy(pCsr->zMatchinfo, zArg, nArg+1);
|
|
||||||
memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo);
|
|
||||||
pCsr->isMatchinfoNeeded = 1;
|
pCsr->isMatchinfoNeeded = 1;
|
||||||
bGlobal = 1;
|
bGlobal = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sInfo.aMatchinfo = pCsr->aMatchinfo;
|
if( rc==SQLITE_OK ){
|
||||||
sInfo.nPhrase = pCsr->nPhrase;
|
xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut);
|
||||||
if( pCsr->isMatchinfoNeeded ){
|
if( xDestroyOut==0 ){
|
||||||
rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
|
rc = SQLITE_NOMEM;
|
||||||
pCsr->isMatchinfoNeeded = 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
if( rc==SQLITE_OK ){
|
||||||
|
sInfo.aMatchinfo = aOut;
|
||||||
|
sInfo.nPhrase = pCsr->nPhrase;
|
||||||
|
rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
|
||||||
|
if( bGlobal ){
|
||||||
|
fts3MIBufferSetGlobal(pCsr->pMIBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqlite3_result_error_code(pCtx, rc);
|
||||||
|
if( xDestroyOut ) xDestroyOut(aOut);
|
||||||
|
}else{
|
||||||
|
int n = pCsr->pMIBuffer->nElem * sizeof(u32);
|
||||||
|
sqlite3_result_blob(pCtx, aOut, n, xDestroyOut);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1452,7 +1592,7 @@ void sqlite3Fts3Offsets(
|
|||||||
*/
|
*/
|
||||||
sCtx.iCol = iCol;
|
sCtx.iCol = iCol;
|
||||||
sCtx.iTerm = 0;
|
sCtx.iTerm = 0;
|
||||||
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
|
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
|
||||||
|
|
||||||
/* Retreive the text stored in column iCol. If an SQL NULL is stored
|
/* Retreive the text stored in column iCol. If an SQL NULL is stored
|
||||||
** in column iCol, jump immediately to the next iteration of the loop.
|
** in column iCol, jump immediately to the next iteration of the loop.
|
||||||
@ -1544,19 +1684,9 @@ void sqlite3Fts3Matchinfo(
|
|||||||
const char *zArg /* Second arg to matchinfo() function */
|
const char *zArg /* Second arg to matchinfo() function */
|
||||||
){
|
){
|
||||||
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
|
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
|
||||||
int rc;
|
|
||||||
int i;
|
|
||||||
const char *zFormat;
|
const char *zFormat;
|
||||||
|
|
||||||
if( zArg ){
|
if( zArg ){
|
||||||
for(i=0; zArg[i]; i++){
|
|
||||||
char *zErr = 0;
|
|
||||||
if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
|
|
||||||
sqlite3_result_error(pContext, zErr, -1);
|
|
||||||
sqlite3_free(zErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zFormat = zArg;
|
zFormat = zArg;
|
||||||
}else{
|
}else{
|
||||||
zFormat = FTS3_MATCHINFO_DEFAULT;
|
zFormat = FTS3_MATCHINFO_DEFAULT;
|
||||||
@ -1565,17 +1695,10 @@ void sqlite3Fts3Matchinfo(
|
|||||||
if( !pCsr->pExpr ){
|
if( !pCsr->pExpr ){
|
||||||
sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
|
sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve matchinfo() data. */
|
|
||||||
rc = fts3GetMatchinfo(pCsr, zFormat);
|
|
||||||
sqlite3Fts3SegmentsClose(pTab);
|
|
||||||
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
sqlite3_result_error_code(pContext, rc);
|
|
||||||
}else{
|
}else{
|
||||||
int n = pCsr->nMatchinfo * sizeof(u32);
|
/* Retrieve matchinfo() data. */
|
||||||
sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
|
fts3GetMatchinfo(pContext, pCsr, zFormat);
|
||||||
|
sqlite3Fts3SegmentsClose(pTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,6 @@ do_catchsql_test rtree9-4.3 {
|
|||||||
#
|
#
|
||||||
register_circle_geom db
|
register_circle_geom db
|
||||||
|
|
||||||
breakpoint
|
|
||||||
do_execsql_test rtree9-5.1 {
|
do_execsql_test rtree9-5.1 {
|
||||||
CREATE VIRTUAL TABLE rt2 USING rtree(id, xmin, xmax, ymin, ymax);
|
CREATE VIRTUAL TABLE rt2 USING rtree(id, xmin, xmax, ymin, ymax);
|
||||||
|
|
||||||
|
27
main.mk
27
main.mk
@ -399,6 +399,14 @@ EXTHDR += \
|
|||||||
EXTHDR += \
|
EXTHDR += \
|
||||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||||
|
|
||||||
|
# executables needed for testing
|
||||||
|
#
|
||||||
|
TESTPROGS = \
|
||||||
|
testfixture$(EXE) \
|
||||||
|
sqlite3$(EXE) \
|
||||||
|
sqlite3_analyzer$(EXE) \
|
||||||
|
sqldiff$(EXE)
|
||||||
|
|
||||||
# This is the default Makefile target. The objects listed here
|
# This is the default Makefile target. The objects listed here
|
||||||
# are what get build when you type just "make" with no arguments.
|
# are what get build when you type just "make" with no arguments.
|
||||||
#
|
#
|
||||||
@ -649,13 +657,13 @@ fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
|||||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
||||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||||
|
|
||||||
fulltest: testfixture$(EXE) sqlite3$(EXE) fuzztest
|
fulltest: $(TESTPROGS) fuzztest
|
||||||
./testfixture$(EXE) $(TOP)/test/all.test
|
./testfixture$(EXE) $(TOP)/test/all.test
|
||||||
|
|
||||||
soaktest: testfixture$(EXE) sqlite3$(EXE) fuzzoomtest
|
soaktest: $(TESTPROGS) fuzzoomtest
|
||||||
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
|
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
|
||||||
|
|
||||||
fulltestonly: testfixture$(EXE) sqlite3$(EXE) fuzztest
|
fulltestonly: $(TESTPROGS) fuzztest
|
||||||
./testfixture$(EXE) $(TOP)/test/full.test
|
./testfixture$(EXE) $(TOP)/test/full.test
|
||||||
|
|
||||||
queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
||||||
@ -667,16 +675,23 @@ fuzztest: fuzzershell$(EXE)
|
|||||||
fuzzoomtest: fuzzershell$(EXE)
|
fuzzoomtest: fuzzershell$(EXE)
|
||||||
./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||||
|
|
||||||
test: testfixture$(EXE) sqlite3$(EXE) fuzztest
|
test: $(TESTPROGS) fuzztest
|
||||||
./testfixture$(EXE) $(TOP)/test/veryquick.test
|
./testfixture$(EXE) $(TOP)/test/veryquick.test
|
||||||
|
|
||||||
# Run a test using valgrind. This can take a really long time
|
# Run a test using valgrind. This can take a really long time
|
||||||
# because valgrind is so much slower than a native machine.
|
# because valgrind is so much slower than a native machine.
|
||||||
#
|
#
|
||||||
valgrindtest: testfixture$(EXE) sqlite3$(EXE) fuzzershell$(EXE)
|
valgrindtest: $(TESTPROGS) fuzzershell$(EXE)
|
||||||
valgrind -v ./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt
|
valgrind -v ./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt
|
||||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind
|
OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind
|
||||||
|
|
||||||
|
# A very fast test that checks basic sanity. The name comes from
|
||||||
|
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||||
|
# comes out."
|
||||||
|
#
|
||||||
|
smoketest: $(TESTPROGS) fuzzershell$(EXE)
|
||||||
|
./testfixture$(EXE) $(TOP)/test/main.test
|
||||||
|
|
||||||
# The next two rules are used to support the "threadtest" target. Building
|
# 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
|
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||||
# target is invoked by the releasetest.tcl script.
|
# target is invoked by the releasetest.tcl script.
|
||||||
@ -788,3 +803,5 @@ clean:
|
|||||||
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
|
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
|
||||||
rm -f sqlite-*-output.vsix
|
rm -f sqlite-*-output.vsix
|
||||||
rm -f mptester mptester.exe
|
rm -f mptester mptester.exe
|
||||||
|
rm -f fuzzershell fuzzershell.exe
|
||||||
|
rm -f sqldiff sqldiff.exe
|
||||||
|
82
manifest
82
manifest
@ -1,19 +1,19 @@
|
|||||||
C Merge\sin\sthe\s3.8.10\srelease\schanges.
|
C Merge\sin\sthe\sIS-operator\senhancements\sand\sother\srecent\schanges\sfrom\strunk.
|
||||||
D 2015-05-07T12:29:54.271
|
D 2015-05-14T15:17:20.176
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 114f5809eeff63855cfda99551addf1e00ef7730
|
F Makefile.in 73b64617bc169971c12be153e3ad9ef76e662fe4
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
F Makefile.msc 6b0b04b6037ef272e8c1f2a24ccc0f99663dde14
|
F Makefile.msc 35200c2f470516f178392b0135375f656fdeac02
|
||||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||||
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
|
F VERSION 8af05c43e00f7de32be74ff9984d792c96cdb0de
|
||||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||||
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
||||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||||
F autoconf/Makefile.am 4012e106208c7b86ba54d06e9ed400b59a4dee6b
|
F autoconf/Makefile.am 27de1af382c82e81f1fe36a7f38528fba004eb1a
|
||||||
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
|
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
|
||||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||||
F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x
|
F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x
|
||||||
@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
|||||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||||
F configure 2ea5f5b58dd106da449ab598ab6e515339d7fa2a x
|
F configure dae9f0ec4df32a9e300befbcdbc4ff8874731357 x
|
||||||
F configure.ac 0b775d383c536bbaafc1e46dd3cbb81a7ea11aeb
|
F configure.ac 0b775d383c536bbaafc1e46dd3cbb81a7ea11aeb
|
||||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||||
@ -78,16 +78,16 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
|||||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||||
F ext/fts3/fts3.c 2fb98467f4b670c8934cdd97d1ba3ffa7382764c
|
F ext/fts3/fts3.c 341e9d9a3c7615bac8e815a8937d576265b22f78
|
||||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||||
F ext/fts3/fts3Int.h 59ecaa2d7af0da44c70b6aeaebdcfc070d14abab
|
F ext/fts3/fts3Int.h 142837a7544dff49121b67091a71c4f7a4546b0f
|
||||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||||
F ext/fts3/fts3_expr.c 71c063da9c2a4167fb54aec089dd5ef33a58c9cb
|
F ext/fts3/fts3_expr.c 71c063da9c2a4167fb54aec089dd5ef33a58c9cb
|
||||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||||
F ext/fts3/fts3_snippet.c 40a96ba78e90aba7d7d6d014a18049bb218060fd
|
F ext/fts3/fts3_snippet.c b7aaa8698096b26e1c6eb563e317409323398142
|
||||||
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
|
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
|
||||||
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
||||||
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
|
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
|
||||||
@ -134,7 +134,7 @@ F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e
|
|||||||
F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196
|
F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196
|
||||||
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
|
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
|
||||||
F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
|
F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
|
||||||
F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
|
F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea
|
||||||
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
||||||
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
||||||
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
||||||
@ -170,7 +170,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
|||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||||
F main.mk d8b3e198082720785408b7d99c2f45f749d1da7b
|
F main.mk a76e778116586db55895d3cc9796bde70bd9db08
|
||||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||||
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
||||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||||
@ -197,9 +197,9 @@ F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
|||||||
F src/build.c 61b47073f79f31e80a05db9ce13c5ca81bf8f74e
|
F src/build.c 61b47073f79f31e80a05db9ce13c5ca81bf8f74e
|
||||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||||
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
|
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||||
F src/dbstat.c 1eacd310212b5ae59b7be645a06de8f8bbe0b5d6
|
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
||||||
F src/delete.c 5075d88557eb4e2a7fdb2b61a96142830d8589b8
|
F src/delete.c 5075d88557eb4e2a7fdb2b61a96142830d8589b8
|
||||||
F src/expr.c 3fb2ab3ab69d15b4b75ae53fceb4e317f64cb306
|
F src/expr.c 3fb2ab3ab69d15b4b75ae53fceb4e317f64cb306
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
@ -214,8 +214,8 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
|||||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||||
F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
|
F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
|
||||||
F src/main.c 6b9b7976bd63b04b795f0eff6e07dcb019f56e97
|
F src/main.c 3fd7ec2399ce67b7dda1b155925d95b8afe2b9ea
|
||||||
F src/malloc.c 6a370b83d54e4bbf6f94021221c2a311cff26a18
|
F src/malloc.c 5bc15d525811d387b37c29f2e368143460e41e96
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||||
@ -234,7 +234,7 @@ F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
|||||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||||
F src/os_unix.c 23eb5f56fac54d8fe0cb204291f3b3b2d94f23fc
|
F src/os_unix.c 23eb5f56fac54d8fe0cb204291f3b3b2d94f23fc
|
||||||
F src/os_win.c 2da99cf07da7db6bcb1974013abfd89ec74749b3
|
F src/os_win.c 97f7828a9554d753665b6fcf7540e31c2b3d6a6e
|
||||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||||
F src/pager.c 97110085b1321298412f1e5c37bddb95b36d9208
|
F src/pager.c 97110085b1321298412f1e5c37bddb95b36d9208
|
||||||
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
||||||
@ -250,16 +250,16 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
|||||||
F src/resolve.c 99eabf7eff0bfa65b75939b46caa82e2b2133f28
|
F src/resolve.c 99eabf7eff0bfa65b75939b46caa82e2b2133f28
|
||||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||||
F src/select.c 1b0bfc7d59e48c26b895a6b719157111a617d9e3
|
F src/select.c 1b0bfc7d59e48c26b895a6b719157111a617d9e3
|
||||||
F src/shell.c a781037a81ac801495e06855605b444a8c5bd19b
|
F src/shell.c f26cca96f7dadab5efb5e655edf548f4b91695c5
|
||||||
F src/sqlite.h.in 679a3abfef9c13a989728fd27f308a3e3f00e232
|
F src/sqlite.h.in 0d711b199290c187b6013bc6b519ddc8ec36d4d8
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||||
F src/sqliteInt.h 15960c3f5f682abb9ac1664c6bd9146d18d3f21d
|
F src/sqliteInt.h 5f7643182e9da425d16a9ea4ad2264adf77c2c4e
|
||||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||||
F src/tclsqlite.c d6952e9d739357ffe9bbfbda3832f6315f6271a2
|
F src/tclsqlite.c 3e98ca80d7c0b66c2e89721ee263d1f396fad816
|
||||||
F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
|
F src/test1.c a8e09b811f70184ce65012f27f30cfee7e54f268
|
||||||
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
|
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
|
||||||
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
|
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
|
||||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||||
@ -325,8 +325,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
|||||||
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
|
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||||
F src/where.c 85fff9c40569ccb79c3177419b339e7d7df566cb
|
F src/where.c 08fadd0d211699348349be5449f3a1e391adf20e
|
||||||
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
|
F src/whereInt.h a6f5a762bc1b4b1c76e1cea79976b437ac35a435
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
||||||
@ -352,6 +352,7 @@ F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
|||||||
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
|
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
|
||||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||||
F test/analyzeF.test 7ccd7a04f7d3061bde1a8a4dacc4792edccf6bf2
|
F test/analyzeF.test 7ccd7a04f7d3061bde1a8a4dacc4792edccf6bf2
|
||||||
|
F test/analyzer1.test e3bccac3be49382050464952998a631bf51e3ce1
|
||||||
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
||||||
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||||
@ -611,11 +612,11 @@ F test/fts3fault2.test f953bb3cf903988172270a9a0aafd5a890b0f98f
|
|||||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||||
F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499
|
F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499
|
||||||
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
||||||
F test/fts3matchinfo.test 3e5f5ac2e0a8ba42eafd4c685f803ca48b4c3a83
|
F test/fts3matchinfo.test 07009313ad6c082f94d8c9c3228eb8940c93ac71
|
||||||
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
|
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
|
||||||
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
|
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
|
||||||
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
|
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
|
||||||
F test/fts3query.test c838b18f2b859e15fd31c64be3d79ef1556803ca
|
F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170
|
||||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||||
F test/fts3snippet.test 63dbd687d5bf5191f1b8e6a0977aa9c1e28a7004
|
F test/fts3snippet.test 63dbd687d5bf5191f1b8e6a0977aa9c1e28a7004
|
||||||
@ -709,7 +710,7 @@ F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
|||||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
||||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||||
F test/jrnlmode.test 6014ba5c11d66ff8bc7d87a7a2abc5c54be73b2e
|
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||||
@ -920,8 +921,9 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
|||||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||||
F test/speedtest1.c 2b416dca3a155fcaa849540b2e7fc1df12896c23
|
F test/speedtest1.c 2b416dca3a155fcaa849540b2e7fc1df12896c23
|
||||||
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
|
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
|
||||||
|
F test/sqldiff1.test e5ecfe95b3a2ff6380f0db6ea8bec246b675e122
|
||||||
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
|
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
|
||||||
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
|
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
|
||||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||||
@ -1099,7 +1101,7 @@ F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
|||||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||||
F test/transitive1.test 03f532954f46cdf5608f7766bff0b0c52bf2a7cd
|
F test/transitive1.test 875a9f0097a15b30a62431d183f989364d5accac
|
||||||
F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03
|
F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03
|
||||||
F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6
|
F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6
|
||||||
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||||
@ -1137,12 +1139,12 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
|||||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||||
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
|
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
|
||||||
F test/vtab1.test d1e5ec7a818f1d3f0402382b6a1d0c06071b770f
|
F test/vtab1.test dbe0e9e121102d0ba365f20d126a72676aa2343f
|
||||||
F test/vtab2.test 3644649aa8d1daac57fd541f6a5f914cac59203e
|
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
|
||||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||||
F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391
|
F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391
|
||||||
F test/vtab6.test 5f5380c425e52993560ab4763db4f826d2ba7b09
|
F test/vtab6.test d2986cf418dc51e7fb81d12366bea2caa8b812df
|
||||||
F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
|
F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
|
||||||
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
|
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
|
||||||
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
|
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
|
||||||
@ -1182,10 +1184,10 @@ F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
|
|||||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
||||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
||||||
F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b
|
F test/where.test 1ff3d9f8da0a6c0dc5ccfd38d9225b2cdb5b6afb
|
||||||
F test/where2.test 23fdb5d8e756554aad4ca7ae03de9dd8367a2c6e
|
F test/where2.test 23fdb5d8e756554aad4ca7ae03de9dd8367a2c6e
|
||||||
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
|
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
|
||||||
F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
|
F test/where4.test a4603fa0d018bd4b9430dac840c9c522af421dd5
|
||||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||||
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
|
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
|
||||||
@ -1194,7 +1196,7 @@ F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
|
|||||||
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
|
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
|
||||||
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
|
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
|
||||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||||
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
|
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
|
||||||
F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b
|
F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b
|
||||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||||
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
||||||
@ -1257,14 +1259,14 @@ F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
|
|||||||
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
|
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
|
||||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||||
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
|
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
|
||||||
F tool/spaceanal.tcl d5a09620c66a6c144576cb9d2bdfa9a6fbe362a5
|
F tool/spaceanal.tcl 713c587a057334de42c41ad9566f10e255d3ad27
|
||||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||||
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||||
F tool/sqldiff.c 10e3c01111f97b99627adf0954cf5ffbfba0723c
|
F tool/sqldiff.c 0748c0daed08f31e5a8eab6de98ca57500e61ecf
|
||||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||||
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
|
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
|
||||||
@ -1275,7 +1277,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P de7083cfe2bb00b689bec6bcc75e994f564ceda6 cf975957b9ae671f34bb65f049acf351e650d437
|
P 0404ef885e47f0df1daa04feb28452beb4d32a35 3428043cd00294457548bb07ada2ad526b6532d6
|
||||||
R 2f55d0a58047aedd7e79d4671acd0f99
|
R 25710cfb819c9f25a12055b84606adbc
|
||||||
U drh
|
U drh
|
||||||
Z 12d4e95f1926699d9a88cac43c727452
|
Z 9620c8120a371d7867c988796203e7a5
|
||||||
|
@ -1 +1 @@
|
|||||||
0404ef885e47f0df1daa04feb28452beb4d32a35
|
4f9229445c293b39c80b2a662901f608c85b36ef
|
@ -75,6 +75,9 @@ static const char * const azCompileOpt[] = {
|
|||||||
#if SQLITE_ENABLE_COLUMN_METADATA
|
#if SQLITE_ENABLE_COLUMN_METADATA
|
||||||
"ENABLE_COLUMN_METADATA",
|
"ENABLE_COLUMN_METADATA",
|
||||||
#endif
|
#endif
|
||||||
|
#if SQLITE_ENABLE_DBSTAT_VTAB
|
||||||
|
"ENABLE_DBSTAT_VTAB",
|
||||||
|
#endif
|
||||||
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
|
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||||
"ENABLE_EXPENSIVE_ASSERT",
|
"ENABLE_EXPENSIVE_ASSERT",
|
||||||
#endif
|
#endif
|
||||||
|
59
src/dbstat.c
59
src/dbstat.c
@ -18,9 +18,9 @@
|
|||||||
** for an example implementation.
|
** for an example implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sqliteInt.h" /* Requires access to internal data structures */
|
||||||
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
|
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
|
||||||
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
|
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||||
#include "sqliteInt.h" /* Requires access to internal data structures */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Page paths:
|
** Page paths:
|
||||||
@ -122,6 +122,7 @@ struct StatCursor {
|
|||||||
struct StatTable {
|
struct StatTable {
|
||||||
sqlite3_vtab base;
|
sqlite3_vtab base;
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
|
int iDb; /* Index of database to analyze */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef get2byte
|
#ifndef get2byte
|
||||||
@ -140,7 +141,17 @@ static int statConnect(
|
|||||||
){
|
){
|
||||||
StatTable *pTab = 0;
|
StatTable *pTab = 0;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
int iDb;
|
||||||
|
|
||||||
|
if( argc>=4 ){
|
||||||
|
iDb = sqlite3FindDbName(db, argv[3]);
|
||||||
|
if( iDb<0 ){
|
||||||
|
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
iDb = 0;
|
||||||
|
}
|
||||||
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
|
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
|
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
|
||||||
@ -151,6 +162,7 @@ static int statConnect(
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
memset(pTab, 0, sizeof(StatTable));
|
memset(pTab, 0, sizeof(StatTable));
|
||||||
pTab->db = db;
|
pTab->db = db;
|
||||||
|
pTab->iDb = iDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppVtab = (sqlite3_vtab*)pTab;
|
*ppVtab = (sqlite3_vtab*)pTab;
|
||||||
@ -205,16 +217,22 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
|||||||
if( pCsr==0 ){
|
if( pCsr==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
|
char *zSql;
|
||||||
memset(pCsr, 0, sizeof(StatCursor));
|
memset(pCsr, 0, sizeof(StatCursor));
|
||||||
pCsr->base.pVtab = pVTab;
|
pCsr->base.pVtab = pVTab;
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(pTab->db,
|
zSql = sqlite3_mprintf(
|
||||||
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
|
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
|
||||||
" UNION ALL "
|
" UNION ALL "
|
||||||
"SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
|
"SELECT name, rootpage, type"
|
||||||
" ORDER BY name", -1,
|
" FROM \"%w\".sqlite_master WHERE rootpage!=0"
|
||||||
&pCsr->pStmt, 0
|
" ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
|
||||||
);
|
if( zSql==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
|
||||||
|
sqlite3_free(zSql);
|
||||||
|
}
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3_free(pCsr);
|
sqlite3_free(pCsr);
|
||||||
pCsr = 0;
|
pCsr = 0;
|
||||||
@ -380,7 +398,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
|||||||
*/
|
*/
|
||||||
static void statSizeAndOffset(StatCursor *pCsr){
|
static void statSizeAndOffset(StatCursor *pCsr){
|
||||||
StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
|
StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
|
||||||
Btree *pBt = pTab->db->aDb[0].pBt;
|
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
|
||||||
Pager *pPager = sqlite3BtreePager(pBt);
|
Pager *pPager = sqlite3BtreePager(pBt);
|
||||||
sqlite3_file *fd;
|
sqlite3_file *fd;
|
||||||
sqlite3_int64 x[2];
|
sqlite3_int64 x[2];
|
||||||
@ -394,7 +412,7 @@ static void statSizeAndOffset(StatCursor *pCsr){
|
|||||||
*/
|
*/
|
||||||
fd = sqlite3PagerFile(pPager);
|
fd = sqlite3PagerFile(pPager);
|
||||||
x[0] = pCsr->iPageno;
|
x[0] = pCsr->iPageno;
|
||||||
if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
|
if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
|
||||||
pCsr->iOffset = x[0];
|
pCsr->iOffset = x[0];
|
||||||
pCsr->szPage = (int)x[1];
|
pCsr->szPage = (int)x[1];
|
||||||
}
|
}
|
||||||
@ -406,9 +424,10 @@ static void statSizeAndOffset(StatCursor *pCsr){
|
|||||||
static int statNext(sqlite3_vtab_cursor *pCursor){
|
static int statNext(sqlite3_vtab_cursor *pCursor){
|
||||||
int rc;
|
int rc;
|
||||||
int nPayload;
|
int nPayload;
|
||||||
|
char *z;
|
||||||
StatCursor *pCsr = (StatCursor *)pCursor;
|
StatCursor *pCsr = (StatCursor *)pCursor;
|
||||||
StatTable *pTab = (StatTable *)pCursor->pVtab;
|
StatTable *pTab = (StatTable *)pCursor->pVtab;
|
||||||
Btree *pBt = pTab->db->aDb[0].pBt;
|
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
|
||||||
Pager *pPager = sqlite3BtreePager(pBt);
|
Pager *pPager = sqlite3BtreePager(pBt);
|
||||||
|
|
||||||
sqlite3_free(pCsr->zPath);
|
sqlite3_free(pCsr->zPath);
|
||||||
@ -428,8 +447,9 @@ statNextRestart:
|
|||||||
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
|
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
|
||||||
pCsr->aPage[0].iPgno = iRoot;
|
pCsr->aPage[0].iPgno = iRoot;
|
||||||
pCsr->aPage[0].iCell = 0;
|
pCsr->aPage[0].iCell = 0;
|
||||||
pCsr->aPage[0].zPath = sqlite3_mprintf("/");
|
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
|
||||||
pCsr->iPage = 0;
|
pCsr->iPage = 0;
|
||||||
|
if( z==0 ) rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
pCsr->isEof = 1;
|
pCsr->isEof = 1;
|
||||||
return sqlite3_reset(pCsr->pStmt);
|
return sqlite3_reset(pCsr->pStmt);
|
||||||
@ -452,7 +472,7 @@ statNextRestart:
|
|||||||
pCsr->zPagetype = "overflow";
|
pCsr->zPagetype = "overflow";
|
||||||
pCsr->nCell = 0;
|
pCsr->nCell = 0;
|
||||||
pCsr->nMxPayload = 0;
|
pCsr->nMxPayload = 0;
|
||||||
pCsr->zPath = sqlite3_mprintf(
|
pCsr->zPath = z = sqlite3_mprintf(
|
||||||
"%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
|
"%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
|
||||||
);
|
);
|
||||||
if( pCell->iOvfl<pCell->nOvfl-1 ){
|
if( pCell->iOvfl<pCell->nOvfl-1 ){
|
||||||
@ -464,7 +484,7 @@ statNextRestart:
|
|||||||
}
|
}
|
||||||
pCell->iOvfl++;
|
pCell->iOvfl++;
|
||||||
statSizeAndOffset(pCsr);
|
statSizeAndOffset(pCsr);
|
||||||
return SQLITE_OK;
|
return z==0 ? SQLITE_NOMEM : SQLITE_OK;
|
||||||
}
|
}
|
||||||
if( p->iRightChildPg ) break;
|
if( p->iRightChildPg ) break;
|
||||||
p->iCell++;
|
p->iCell++;
|
||||||
@ -486,8 +506,9 @@ statNextRestart:
|
|||||||
}
|
}
|
||||||
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
|
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
|
||||||
p[1].iCell = 0;
|
p[1].iCell = 0;
|
||||||
p[1].zPath = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
|
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
|
||||||
p->iCell++;
|
p->iCell++;
|
||||||
|
if( z==0 ) rc = SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -520,7 +541,8 @@ statNextRestart:
|
|||||||
pCsr->nCell = p->nCell;
|
pCsr->nCell = p->nCell;
|
||||||
pCsr->nUnused = p->nUnused;
|
pCsr->nUnused = p->nUnused;
|
||||||
pCsr->nMxPayload = p->nMxPayload;
|
pCsr->nMxPayload = p->nMxPayload;
|
||||||
pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
|
pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
|
||||||
|
if( z==0 ) rc = SQLITE_NOMEM;
|
||||||
nPayload = 0;
|
nPayload = 0;
|
||||||
for(i=0; i<p->nCell; i++){
|
for(i=0; i<p->nCell; i++){
|
||||||
nPayload += p->aCell[i].nLocal;
|
nPayload += p->aCell[i].nLocal;
|
||||||
@ -556,7 +578,7 @@ static int statColumn(
|
|||||||
StatCursor *pCsr = (StatCursor *)pCursor;
|
StatCursor *pCsr = (StatCursor *)pCursor;
|
||||||
switch( i ){
|
switch( i ){
|
||||||
case 0: /* name */
|
case 0: /* name */
|
||||||
sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_STATIC);
|
sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
|
||||||
break;
|
break;
|
||||||
case 1: /* path */
|
case 1: /* path */
|
||||||
sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
|
sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
|
||||||
@ -582,7 +604,8 @@ static int statColumn(
|
|||||||
case 8: /* pgoffset */
|
case 8: /* pgoffset */
|
||||||
sqlite3_result_int64(ctx, pCsr->iOffset);
|
sqlite3_result_int64(ctx, pCsr->iOffset);
|
||||||
break;
|
break;
|
||||||
case 9: /* pgsize */
|
default: /* pgsize */
|
||||||
|
assert( i==9 );
|
||||||
sqlite3_result_int(ctx, pCsr->szPage);
|
sqlite3_result_int(ctx, pCsr->szPage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -598,7 +621,7 @@ static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
|
|||||||
/*
|
/*
|
||||||
** Invoke this routine to register the "dbstat" virtual table module
|
** Invoke this routine to register the "dbstat" virtual table module
|
||||||
*/
|
*/
|
||||||
int sqlite3_dbstat_register(sqlite3 *db){
|
int sqlite3DbstatRegister(sqlite3 *db){
|
||||||
static sqlite3_module dbstat_module = {
|
static sqlite3_module dbstat_module = {
|
||||||
0, /* iVersion */
|
0, /* iVersion */
|
||||||
statConnect, /* xCreate */
|
statConnect, /* xCreate */
|
||||||
@ -623,4 +646,6 @@ int sqlite3_dbstat_register(sqlite3 *db){
|
|||||||
};
|
};
|
||||||
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
|
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
|
||||||
}
|
}
|
||||||
|
#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
|
||||||
|
int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
|
||||||
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
|
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
|
||||||
|
@ -2899,8 +2899,7 @@ static int openDatabase(
|
|||||||
|
|
||||||
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
|
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
|
||||||
if( !db->mallocFailed && rc==SQLITE_OK){
|
if( !db->mallocFailed && rc==SQLITE_OK){
|
||||||
int sqlite3_dbstat_register(sqlite3*);
|
rc = sqlite3DbstatRegister(db);
|
||||||
rc = sqlite3_dbstat_register(db);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
14
src/malloc.c
14
src/malloc.c
@ -226,10 +226,8 @@ void sqlite3MallocEnd(void){
|
|||||||
** Return the amount of memory currently checked out.
|
** Return the amount of memory currently checked out.
|
||||||
*/
|
*/
|
||||||
sqlite3_int64 sqlite3_memory_used(void){
|
sqlite3_int64 sqlite3_memory_used(void){
|
||||||
int n, mx;
|
sqlite3_int64 res, mx;
|
||||||
sqlite3_int64 res;
|
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
|
||||||
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
|
|
||||||
res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,11 +237,9 @@ sqlite3_int64 sqlite3_memory_used(void){
|
|||||||
** or since the most recent reset.
|
** or since the most recent reset.
|
||||||
*/
|
*/
|
||||||
sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
|
sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
|
||||||
int n, mx;
|
sqlite3_int64 res, mx;
|
||||||
sqlite3_int64 res;
|
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
|
||||||
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
|
return mx;
|
||||||
res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5411,14 +5411,14 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
|||||||
UUID id;
|
UUID id;
|
||||||
memset(&id, 0, sizeof(UUID));
|
memset(&id, 0, sizeof(UUID));
|
||||||
osUuidCreate(&id);
|
osUuidCreate(&id);
|
||||||
memcpy(zBuf, &id, sizeof(UUID));
|
memcpy(&zBuf[n], &id, sizeof(UUID));
|
||||||
n += sizeof(UUID);
|
n += sizeof(UUID);
|
||||||
}
|
}
|
||||||
if( sizeof(UUID)<=nBuf-n ){
|
if( sizeof(UUID)<=nBuf-n ){
|
||||||
UUID id;
|
UUID id;
|
||||||
memset(&id, 0, sizeof(UUID));
|
memset(&id, 0, sizeof(UUID));
|
||||||
osUuidCreateSequential(&id);
|
osUuidCreateSequential(&id);
|
||||||
memcpy(zBuf, &id, sizeof(UUID));
|
memcpy(&zBuf[n], &id, sizeof(UUID));
|
||||||
n += sizeof(UUID);
|
n += sizeof(UUID);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3347,7 +3347,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
goto meta_command_exit;
|
goto meta_command_exit;
|
||||||
}
|
}
|
||||||
if( nArg==3 ){
|
if( nArg==3 ){
|
||||||
sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
|
sqlite3_limit(p->db, aLimit[iLimit].limitCode,
|
||||||
|
(int)integerValue(azArg[2]));
|
||||||
}
|
}
|
||||||
printf("%20s %d\n", aLimit[iLimit].zLimitName,
|
printf("%20s %d\n", aLimit[iLimit].zLimitName,
|
||||||
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
|
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
|
||||||
|
@ -3893,8 +3893,6 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
|||||||
** KEYWORDS: {column access functions}
|
** KEYWORDS: {column access functions}
|
||||||
** METHOD: sqlite3_stmt
|
** METHOD: sqlite3_stmt
|
||||||
**
|
**
|
||||||
** These routines form the "result set" interface.
|
|
||||||
**
|
|
||||||
** ^These routines return information about a single column of the current
|
** ^These routines return information about a single column of the current
|
||||||
** result row of a query. ^In every case the first argument is a pointer
|
** result row of a query. ^In every case the first argument is a pointer
|
||||||
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
|
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
|
||||||
@ -3954,13 +3952,14 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
|||||||
** even empty strings, are always zero-terminated. ^The return
|
** even empty strings, are always zero-terminated. ^The return
|
||||||
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
|
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
|
||||||
**
|
**
|
||||||
** ^The object returned by [sqlite3_column_value()] is an
|
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
|
||||||
** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
|
** [unprotected sqlite3_value] object. In a multithreaded environment,
|
||||||
** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
|
** an unprotected sqlite3_value object may only be used safely with
|
||||||
|
** [sqlite3_bind_value()] and [sqlite3_result_value()].
|
||||||
** If the [unprotected sqlite3_value] object returned by
|
** If the [unprotected sqlite3_value] object returned by
|
||||||
** [sqlite3_column_value()] is used in any other way, including calls
|
** [sqlite3_column_value()] is used in any other way, including calls
|
||||||
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
|
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
|
||||||
** or [sqlite3_value_bytes()], then the behavior is undefined.
|
** or [sqlite3_value_bytes()], the behavior is not threadsafe.
|
||||||
**
|
**
|
||||||
** These routines attempt to convert the value where appropriate. ^For
|
** These routines attempt to convert the value where appropriate. ^For
|
||||||
** example, if the internal representation is FLOAT and a text result
|
** example, if the internal representation is FLOAT and a text result
|
||||||
@ -3991,12 +3990,6 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
|||||||
** </table>
|
** </table>
|
||||||
** </blockquote>)^
|
** </blockquote>)^
|
||||||
**
|
**
|
||||||
** The table above makes reference to standard C library functions atoi()
|
|
||||||
** and atof(). SQLite does not really use these functions. It has its
|
|
||||||
** own equivalent internal routines. The atoi() and atof() names are
|
|
||||||
** used in the table for brevity and because they are familiar to most
|
|
||||||
** C programmers.
|
|
||||||
**
|
|
||||||
** Note that when type conversions occur, pointers returned by prior
|
** Note that when type conversions occur, pointers returned by prior
|
||||||
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
|
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
|
||||||
** sqlite3_column_text16() may be invalidated.
|
** sqlite3_column_text16() may be invalidated.
|
||||||
@ -4021,7 +4014,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
|||||||
** of conversion are done in place when it is possible, but sometimes they
|
** of conversion are done in place when it is possible, but sometimes they
|
||||||
** are not possible and in those cases prior pointers are invalidated.
|
** are not possible and in those cases prior pointers are invalidated.
|
||||||
**
|
**
|
||||||
** The safest and easiest to remember policy is to invoke these routines
|
** The safest policy is to invoke these routines
|
||||||
** in one of the following ways:
|
** in one of the following ways:
|
||||||
**
|
**
|
||||||
** <ul>
|
** <ul>
|
||||||
@ -4041,7 +4034,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
|||||||
** ^The pointers returned are valid until a type conversion occurs as
|
** ^The pointers returned are valid until a type conversion occurs as
|
||||||
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
|
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
|
||||||
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
|
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
|
||||||
** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
|
** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
|
||||||
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
|
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
|
||||||
** [sqlite3_free()].
|
** [sqlite3_free()].
|
||||||
**
|
**
|
||||||
|
@ -3879,4 +3879,8 @@ int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
|
|||||||
int sqlite3ThreadJoin(SQLiteThread*, void**);
|
int sqlite3ThreadJoin(SQLiteThread*, void**);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
|
||||||
|
int sqlite3DbstatRegister(sqlite3*);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _SQLITEINT_H_ */
|
#endif /* _SQLITEINT_H_ */
|
||||||
|
@ -3852,43 +3852,6 @@ static int db_last_stmt_ptr(
|
|||||||
}
|
}
|
||||||
#endif /* SQLITE_TEST */
|
#endif /* SQLITE_TEST */
|
||||||
|
|
||||||
#if defined(SQLITE_TEST) || defined(SQLITE_ENABLE_DBSTAT_VTAB)
|
|
||||||
/*
|
|
||||||
** tclcmd: register_dbstat_vtab DB
|
|
||||||
**
|
|
||||||
** Cause the dbstat virtual table to be available on the connection DB
|
|
||||||
*/
|
|
||||||
static int sqlite3RegisterDbstatCmd(
|
|
||||||
void *clientData,
|
|
||||||
Tcl_Interp *interp,
|
|
||||||
int objc,
|
|
||||||
Tcl_Obj *CONST objv[]
|
|
||||||
){
|
|
||||||
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
|
||||||
Tcl_AppendResult(interp, "dbstat not available because of "
|
|
||||||
"SQLITE_OMIT_VIRTUALTABLE", (void*)0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
#else
|
|
||||||
struct SqliteDb { sqlite3 *db; };
|
|
||||||
char *zDb;
|
|
||||||
Tcl_CmdInfo cmdInfo;
|
|
||||||
|
|
||||||
if( objc!=2 ){
|
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
zDb = Tcl_GetString(objv[1]);
|
|
||||||
if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
|
|
||||||
int sqlite3_dbstat_register(sqlite3*);
|
|
||||||
sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
|
|
||||||
sqlite3_dbstat_register(db);
|
|
||||||
}
|
|
||||||
return TCL_OK;
|
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
|
||||||
}
|
|
||||||
#endif /* defined(SQLITE_TEST) || defined(SQLITE_ENABLE_DBSTAT_VTAB) */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Configure the interpreter passed as the first argument to have access
|
** Configure the interpreter passed as the first argument to have access
|
||||||
** to the commands and linked variables that make up:
|
** to the commands and linked variables that make up:
|
||||||
@ -3907,16 +3870,6 @@ static void init_all(Tcl_Interp *interp){
|
|||||||
Md5_Init(interp);
|
Md5_Init(interp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Install the [register_dbstat_vtab] command to access the implementation
|
|
||||||
** of virtual table dbstat (source file test_stat.c). This command is
|
|
||||||
** required for testfixture and sqlite3_analyzer, but not by the production
|
|
||||||
** Tcl extension. */
|
|
||||||
#if defined(SQLITE_TEST) || defined(SQLITE_ENABLE_DBSTAT_VTAB)
|
|
||||||
Tcl_CreateObjCommand(
|
|
||||||
interp, "register_dbstat_vtab", sqlite3RegisterDbstatCmd, 0, 0
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
{
|
{
|
||||||
extern int Sqliteconfig_Init(Tcl_Interp*);
|
extern int Sqliteconfig_Init(Tcl_Interp*);
|
||||||
|
36
src/test1.c
36
src/test1.c
@ -6680,7 +6680,40 @@ static int test_bad_behavior(
|
|||||||
}
|
}
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** tclcmd: register_dbstat_vtab DB
|
||||||
|
**
|
||||||
|
** Cause the dbstat virtual table to be available on the connection DB
|
||||||
|
*/
|
||||||
|
static int test_register_dbstat_vtab(
|
||||||
|
void *clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
Tcl_AppendResult(interp, "dbstat not available because of "
|
||||||
|
"SQLITE_OMIT_VIRTUALTABLE", (void*)0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
#else
|
||||||
|
struct SqliteDb { sqlite3 *db; };
|
||||||
|
char *zDb;
|
||||||
|
Tcl_CmdInfo cmdInfo;
|
||||||
|
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
zDb = Tcl_GetString(objv[1]);
|
||||||
|
if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
|
||||||
|
sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
|
||||||
|
sqlite3DbstatRegister(db);
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Register commands with the TCL interpreter.
|
** Register commands with the TCL interpreter.
|
||||||
@ -6752,6 +6785,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
void *clientData;
|
void *clientData;
|
||||||
} aObjCmd[] = {
|
} aObjCmd[] = {
|
||||||
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
|
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
|
||||||
|
{ "register_dbstat_vtab", test_register_dbstat_vtab },
|
||||||
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
|
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
|
||||||
{ "sqlite3_bind_int", test_bind_int, 0 },
|
{ "sqlite3_bind_int", test_bind_int, 0 },
|
||||||
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },
|
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },
|
||||||
|
75
src/where.c
75
src/where.c
@ -363,7 +363,7 @@ static int allowedOp(int op){
|
|||||||
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
|
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
|
||||||
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
|
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
|
||||||
assert( TK_GE==TK_EQ+4 );
|
assert( TK_GE==TK_EQ+4 );
|
||||||
return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
|
return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -416,6 +416,8 @@ static u16 operatorMask(int op){
|
|||||||
c = WO_IN;
|
c = WO_IN;
|
||||||
}else if( op==TK_ISNULL ){
|
}else if( op==TK_ISNULL ){
|
||||||
c = WO_ISNULL;
|
c = WO_ISNULL;
|
||||||
|
}else if( op==TK_IS ){
|
||||||
|
c = WO_IS;
|
||||||
}else{
|
}else{
|
||||||
assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
|
assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
|
||||||
c = (u16)(WO_EQ<<(op-TK_EQ));
|
c = (u16)(WO_EQ<<(op-TK_EQ));
|
||||||
@ -427,6 +429,7 @@ static u16 operatorMask(int op){
|
|||||||
assert( op!=TK_LE || c==WO_LE );
|
assert( op!=TK_LE || c==WO_LE );
|
||||||
assert( op!=TK_GT || c==WO_GT );
|
assert( op!=TK_GT || c==WO_GT );
|
||||||
assert( op!=TK_GE || c==WO_GE );
|
assert( op!=TK_GE || c==WO_GE );
|
||||||
|
assert( op!=TK_IS || c==WO_IS );
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,11 +490,12 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( (pTerm->eOperator & WO_EQ)!=0
|
if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
|
||||||
&& (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
|
&& (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
|
||||||
&& pX->iTable==pScan->aEquiv[0]
|
&& pX->iTable==pScan->aEquiv[0]
|
||||||
&& pX->iColumn==pScan->aEquiv[1]
|
&& pX->iColumn==pScan->aEquiv[1]
|
||||||
){
|
){
|
||||||
|
testcase( pTerm->eOperator & WO_IS );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pScan->k = k+1;
|
pScan->k = k+1;
|
||||||
@ -593,9 +597,11 @@ static WhereTerm *findTerm(
|
|||||||
WhereScan scan;
|
WhereScan scan;
|
||||||
|
|
||||||
p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
|
p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
|
||||||
|
op &= WO_EQ|WO_IS;
|
||||||
while( p ){
|
while( p ){
|
||||||
if( (p->prereqRight & notReady)==0 ){
|
if( (p->prereqRight & notReady)==0 ){
|
||||||
if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){
|
if( p->prereqRight==0 && (p->eOperator&op)!=0 ){
|
||||||
|
testcase( p->eOperator & WO_IS );
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
if( pResult==0 ) pResult = p;
|
if( pResult==0 ) pResult = p;
|
||||||
@ -1254,6 +1260,7 @@ static void exprAnalyze(
|
|||||||
pTerm->u.leftColumn = pLeft->iColumn;
|
pTerm->u.leftColumn = pLeft->iColumn;
|
||||||
pTerm->eOperator = operatorMask(op) & opMask;
|
pTerm->eOperator = operatorMask(op) & opMask;
|
||||||
}
|
}
|
||||||
|
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
|
||||||
if( pRight && pRight->op==TK_COLUMN ){
|
if( pRight && pRight->op==TK_COLUMN ){
|
||||||
WhereTerm *pNew;
|
WhereTerm *pNew;
|
||||||
Expr *pDup;
|
Expr *pDup;
|
||||||
@ -1271,13 +1278,14 @@ static void exprAnalyze(
|
|||||||
markTermAsChild(pWC, idxNew, idxTerm);
|
markTermAsChild(pWC, idxNew, idxTerm);
|
||||||
pTerm = &pWC->a[idxTerm];
|
pTerm = &pWC->a[idxTerm];
|
||||||
pTerm->wtFlags |= TERM_COPIED;
|
pTerm->wtFlags |= TERM_COPIED;
|
||||||
if( pExpr->op==TK_EQ
|
if( (op==TK_EQ || op==TK_IS)
|
||||||
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
||||||
&& OptimizationEnabled(db, SQLITE_Transitive)
|
&& OptimizationEnabled(db, SQLITE_Transitive)
|
||||||
){
|
){
|
||||||
pTerm->eOperator |= WO_EQUIV;
|
pTerm->eOperator |= WO_EQUIV;
|
||||||
eExtraOp = WO_EQUIV;
|
eExtraOp = WO_EQUIV;
|
||||||
}
|
}
|
||||||
|
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
|
||||||
}else{
|
}else{
|
||||||
pDup = pExpr;
|
pDup = pExpr;
|
||||||
pNew = pTerm;
|
pNew = pTerm;
|
||||||
@ -1468,10 +1476,7 @@ static void exprAnalyze(
|
|||||||
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
|
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
|
||||||
** virtual term of that form.
|
** virtual term of that form.
|
||||||
**
|
**
|
||||||
** Note that the virtual term must be tagged with TERM_VNULL. This
|
** Note that the virtual term must be tagged with TERM_VNULL.
|
||||||
** TERM_VNULL tag will suppress the not-null check at the beginning
|
|
||||||
** of the loop. Without the TERM_VNULL flag, the not-null check at
|
|
||||||
** the start of the loop will prevent any results from being returned.
|
|
||||||
*/
|
*/
|
||||||
if( pExpr->op==TK_NOTNULL
|
if( pExpr->op==TK_NOTNULL
|
||||||
&& pExpr->pLeft->op==TK_COLUMN
|
&& pExpr->pLeft->op==TK_COLUMN
|
||||||
@ -1675,11 +1680,12 @@ static int termCanDriveIndex(
|
|||||||
){
|
){
|
||||||
char aff;
|
char aff;
|
||||||
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
|
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
|
||||||
if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
|
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
|
||||||
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
|
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
|
||||||
if( pTerm->u.leftColumn<0 ) return 0;
|
if( pTerm->u.leftColumn<0 ) return 0;
|
||||||
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
|
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
|
||||||
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
|
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
|
||||||
|
testcase( pTerm->pExpr->op==TK_IS );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1896,8 +1902,9 @@ static sqlite3_index_info *allocateIndexInfo(
|
|||||||
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
||||||
testcase( pTerm->eOperator & WO_IN );
|
testcase( pTerm->eOperator & WO_IN );
|
||||||
testcase( pTerm->eOperator & WO_ISNULL );
|
testcase( pTerm->eOperator & WO_ISNULL );
|
||||||
|
testcase( pTerm->eOperator & WO_IS );
|
||||||
testcase( pTerm->eOperator & WO_ALL );
|
testcase( pTerm->eOperator & WO_ALL );
|
||||||
if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
|
if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
|
||||||
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
||||||
nTerm++;
|
nTerm++;
|
||||||
}
|
}
|
||||||
@ -1948,9 +1955,10 @@ static sqlite3_index_info *allocateIndexInfo(
|
|||||||
if( pTerm->leftCursor != pSrc->iCursor ) continue;
|
if( pTerm->leftCursor != pSrc->iCursor ) continue;
|
||||||
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
||||||
testcase( pTerm->eOperator & WO_IN );
|
testcase( pTerm->eOperator & WO_IN );
|
||||||
|
testcase( pTerm->eOperator & WO_IS );
|
||||||
testcase( pTerm->eOperator & WO_ISNULL );
|
testcase( pTerm->eOperator & WO_ISNULL );
|
||||||
testcase( pTerm->eOperator & WO_ALL );
|
testcase( pTerm->eOperator & WO_ALL );
|
||||||
if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
|
if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
|
||||||
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
||||||
pIdxCons[j].iColumn = pTerm->u.leftColumn;
|
pIdxCons[j].iColumn = pTerm->u.leftColumn;
|
||||||
pIdxCons[j].iTermOffset = i;
|
pIdxCons[j].iTermOffset = i;
|
||||||
@ -2792,7 +2800,7 @@ static int codeEqualityTerm(
|
|||||||
int iReg; /* Register holding results */
|
int iReg; /* Register holding results */
|
||||||
|
|
||||||
assert( iTarget>0 );
|
assert( iTarget>0 );
|
||||||
if( pX->op==TK_EQ ){
|
if( pX->op==TK_EQ || pX->op==TK_IS ){
|
||||||
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
|
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
|
||||||
}else if( pX->op==TK_ISNULL ){
|
}else if( pX->op==TK_ISNULL ){
|
||||||
iReg = iTarget;
|
iReg = iTarget;
|
||||||
@ -2977,7 +2985,7 @@ static int codeAllEqualityTerms(
|
|||||||
testcase( pTerm->eOperator & WO_IN );
|
testcase( pTerm->eOperator & WO_IN );
|
||||||
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
|
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
|
||||||
Expr *pRight = pTerm->pExpr->pRight;
|
Expr *pRight = pTerm->pExpr->pRight;
|
||||||
if( sqlite3ExprCanBeNull(pRight) ){
|
if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
@ -4099,16 +4107,19 @@ static Bitmask codeOneLoopStart(
|
|||||||
Expr *pE, *pEAlt;
|
Expr *pE, *pEAlt;
|
||||||
WhereTerm *pAlt;
|
WhereTerm *pAlt;
|
||||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
|
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
|
||||||
|
if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
|
||||||
if( pTerm->leftCursor!=iCur ) continue;
|
if( pTerm->leftCursor!=iCur ) continue;
|
||||||
if( pLevel->iLeftJoin ) continue;
|
if( pLevel->iLeftJoin ) continue;
|
||||||
pE = pTerm->pExpr;
|
pE = pTerm->pExpr;
|
||||||
assert( !ExprHasProperty(pE, EP_FromJoin) );
|
assert( !ExprHasProperty(pE, EP_FromJoin) );
|
||||||
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
|
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
|
||||||
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
|
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
|
||||||
|
WO_EQ|WO_IN|WO_IS, 0);
|
||||||
if( pAlt==0 ) continue;
|
if( pAlt==0 ) continue;
|
||||||
if( pAlt->wtFlags & (TERM_CODED) ) continue;
|
if( pAlt->wtFlags & (TERM_CODED) ) continue;
|
||||||
testcase( pAlt->eOperator & WO_EQ );
|
testcase( pAlt->eOperator & WO_EQ );
|
||||||
|
testcase( pAlt->eOperator & WO_IS );
|
||||||
testcase( pAlt->eOperator & WO_IN );
|
testcase( pAlt->eOperator & WO_IN );
|
||||||
VdbeModuleComment((v, "begin transitive constraint"));
|
VdbeModuleComment((v, "begin transitive constraint"));
|
||||||
pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
|
pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
|
||||||
@ -4158,9 +4169,10 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){
|
|||||||
if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
|
if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
|
||||||
if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
|
if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
|
||||||
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
|
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
|
||||||
sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
|
sqlite3DebugPrintf(
|
||||||
iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
|
"TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n",
|
||||||
pTerm->eOperator);
|
iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
|
||||||
|
pTerm->eOperator, pTerm->wtFlags);
|
||||||
sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
|
sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4650,8 +4662,9 @@ static void whereLoopOutputAdjust(
|
|||||||
/* In the absence of explicit truth probabilities, use heuristics to
|
/* In the absence of explicit truth probabilities, use heuristics to
|
||||||
** guess a reasonable truth probability. */
|
** guess a reasonable truth probability. */
|
||||||
pLoop->nOut--;
|
pLoop->nOut--;
|
||||||
if( pTerm->eOperator&WO_EQ ){
|
if( pTerm->eOperator&(WO_EQ|WO_IS) ){
|
||||||
Expr *pRight = pTerm->pExpr->pRight;
|
Expr *pRight = pTerm->pExpr->pRight;
|
||||||
|
testcase( pTerm->pExpr->op==TK_IS );
|
||||||
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
|
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
|
||||||
k = 10;
|
k = 10;
|
||||||
}else{
|
}else{
|
||||||
@ -4719,10 +4732,10 @@ static int whereLoopAddBtreeIndex(
|
|||||||
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
|
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
|
||||||
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
|
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
|
||||||
opMask = WO_LT|WO_LE;
|
opMask = WO_LT|WO_LE;
|
||||||
}else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
|
}else if( /*pProbe->tnum<=0 ||*/ (pSrc->jointype & JT_LEFT)!=0 ){
|
||||||
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
|
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
|
||||||
}else{
|
}else{
|
||||||
opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
|
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
|
||||||
}
|
}
|
||||||
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
|
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
|
||||||
|
|
||||||
@ -4785,7 +4798,7 @@ static int whereLoopAddBtreeIndex(
|
|||||||
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
|
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
|
||||||
** changes "x IN (?)" into "x=?". */
|
** changes "x IN (?)" into "x=?". */
|
||||||
|
|
||||||
}else if( eOp & (WO_EQ) ){
|
}else if( eOp & (WO_EQ|WO_IS) ){
|
||||||
pNew->wsFlags |= WHERE_COLUMN_EQ;
|
pNew->wsFlags |= WHERE_COLUMN_EQ;
|
||||||
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
|
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
|
||||||
if( iCol>=0 && pProbe->uniqNotNull==0 ){
|
if( iCol>=0 && pProbe->uniqNotNull==0 ){
|
||||||
@ -4835,7 +4848,7 @@ static int whereLoopAddBtreeIndex(
|
|||||||
whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
|
whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
|
||||||
}else{
|
}else{
|
||||||
int nEq = ++pNew->u.btree.nEq;
|
int nEq = ++pNew->u.btree.nEq;
|
||||||
assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) );
|
assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
|
||||||
|
|
||||||
assert( pNew->nOut==saved_nOut );
|
assert( pNew->nOut==saved_nOut );
|
||||||
if( pTerm->truthProb<=0 && iCol>=0 ){
|
if( pTerm->truthProb<=0 && iCol>=0 ){
|
||||||
@ -4852,8 +4865,9 @@ static int whereLoopAddBtreeIndex(
|
|||||||
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
|
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
|
||||||
){
|
){
|
||||||
Expr *pExpr = pTerm->pExpr;
|
Expr *pExpr = pTerm->pExpr;
|
||||||
if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
|
if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
|
||||||
testcase( eOp & WO_EQ );
|
testcase( eOp & WO_EQ );
|
||||||
|
testcase( eOp & WO_IS );
|
||||||
testcase( eOp & WO_ISNULL );
|
testcase( eOp & WO_ISNULL );
|
||||||
rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
|
rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
|
||||||
}else{
|
}else{
|
||||||
@ -5690,9 +5704,9 @@ static i8 wherePathSatisfiesOrderBy(
|
|||||||
if( pOBExpr->op!=TK_COLUMN ) continue;
|
if( pOBExpr->op!=TK_COLUMN ) continue;
|
||||||
if( pOBExpr->iTable!=iCur ) continue;
|
if( pOBExpr->iTable!=iCur ) continue;
|
||||||
pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
|
pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
|
||||||
~ready, WO_EQ|WO_ISNULL, 0);
|
~ready, WO_EQ|WO_ISNULL|WO_IS, 0);
|
||||||
if( pTerm==0 ) continue;
|
if( pTerm==0 ) continue;
|
||||||
if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
|
if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
|
||||||
const char *z1, *z2;
|
const char *z1, *z2;
|
||||||
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
|
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
|
||||||
if( !pColl ) pColl = db->pDfltColl;
|
if( !pColl ) pColl = db->pDfltColl;
|
||||||
@ -5701,6 +5715,7 @@ static i8 wherePathSatisfiesOrderBy(
|
|||||||
if( !pColl ) pColl = db->pDfltColl;
|
if( !pColl ) pColl = db->pDfltColl;
|
||||||
z2 = pColl->zName;
|
z2 = pColl->zName;
|
||||||
if( sqlite3StrICmp(z1, z2)!=0 ) continue;
|
if( sqlite3StrICmp(z1, z2)!=0 ) continue;
|
||||||
|
testcase( pTerm->pExpr->op==TK_IS );
|
||||||
}
|
}
|
||||||
obSat |= MASKBIT(i);
|
obSat |= MASKBIT(i);
|
||||||
}
|
}
|
||||||
@ -5731,7 +5746,7 @@ static i8 wherePathSatisfiesOrderBy(
|
|||||||
/* Skip over == and IS NULL terms */
|
/* Skip over == and IS NULL terms */
|
||||||
if( j<pLoop->u.btree.nEq
|
if( j<pLoop->u.btree.nEq
|
||||||
&& pLoop->nSkip==0
|
&& pLoop->nSkip==0
|
||||||
&& ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
|
&& ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL|WO_IS))!=0
|
||||||
){
|
){
|
||||||
if( i & WO_ISNULL ){
|
if( i & WO_ISNULL ){
|
||||||
testcase( isOrderDistinct );
|
testcase( isOrderDistinct );
|
||||||
@ -6304,8 +6319,9 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
|
|||||||
pLoop = pBuilder->pNew;
|
pLoop = pBuilder->pNew;
|
||||||
pLoop->wsFlags = 0;
|
pLoop->wsFlags = 0;
|
||||||
pLoop->nSkip = 0;
|
pLoop->nSkip = 0;
|
||||||
pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
|
pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0);
|
||||||
if( pTerm ){
|
if( pTerm ){
|
||||||
|
testcase( pTerm->eOperator & WO_IS );
|
||||||
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
|
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
|
||||||
pLoop->aLTerm[0] = pTerm;
|
pLoop->aLTerm[0] = pTerm;
|
||||||
pLoop->nLTerm = 1;
|
pLoop->nLTerm = 1;
|
||||||
@ -6320,8 +6336,9 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
|
|||||||
|| pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
|
|| pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
|
||||||
) continue;
|
) continue;
|
||||||
for(j=0; j<pIdx->nKeyCol; j++){
|
for(j=0; j<pIdx->nKeyCol; j++){
|
||||||
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
|
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ|WO_IS, pIdx);
|
||||||
if( pTerm==0 ) break;
|
if( pTerm==0 ) break;
|
||||||
|
testcase( pTerm->eOperator & WO_IS );
|
||||||
pLoop->aLTerm[j] = pTerm;
|
pLoop->aLTerm[j] = pTerm;
|
||||||
}
|
}
|
||||||
if( j!=pIdx->nKeyCol ) continue;
|
if( j!=pIdx->nKeyCol ) continue;
|
||||||
|
@ -280,6 +280,7 @@ struct WhereTerm {
|
|||||||
#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
|
#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
|
||||||
#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
|
#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
|
||||||
#define TERM_LIKE 0x400 /* The original LIKE operator */
|
#define TERM_LIKE 0x400 /* The original LIKE operator */
|
||||||
|
#define TERM_IS 0x800 /* Term.pExpr is an IS operator */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An instance of the WhereScan object is used as an iterator for locating
|
** An instance of the WhereScan object is used as an iterator for locating
|
||||||
@ -428,21 +429,22 @@ struct WhereInfo {
|
|||||||
** OR-ed combination of these values can be used when searching for
|
** OR-ed combination of these values can be used when searching for
|
||||||
** particular WhereTerms within a WhereClause.
|
** particular WhereTerms within a WhereClause.
|
||||||
*/
|
*/
|
||||||
#define WO_IN 0x001
|
#define WO_IN 0x0001
|
||||||
#define WO_EQ 0x002
|
#define WO_EQ 0x0002
|
||||||
#define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
|
#define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
|
||||||
#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
|
#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
|
||||||
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
|
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
|
||||||
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
|
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
|
||||||
#define WO_MATCH 0x040
|
#define WO_MATCH 0x0040
|
||||||
#define WO_ISNULL 0x080
|
#define WO_IS 0x0080
|
||||||
#define WO_OR 0x100 /* Two or more OR-connected terms */
|
#define WO_ISNULL 0x0100
|
||||||
#define WO_AND 0x200 /* Two or more AND-connected terms */
|
#define WO_OR 0x0200 /* Two or more OR-connected terms */
|
||||||
#define WO_EQUIV 0x400 /* Of the form A==B, both columns */
|
#define WO_AND 0x0400 /* Two or more AND-connected terms */
|
||||||
#define WO_NOOP 0x800 /* This term does not restrict search space */
|
#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
|
||||||
|
#define WO_NOOP 0x1000 /* This term does not restrict search space */
|
||||||
|
|
||||||
#define WO_ALL 0xfff /* Mask of all possible WO_* values */
|
#define WO_ALL 0x1fff /* Mask of all possible WO_* values */
|
||||||
#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
|
#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** These are definitions of bits in the WhereLoop.wsFlags field.
|
** These are definitions of bits in the WhereLoop.wsFlags field.
|
||||||
|
47
test/analyzer1.test
Normal file
47
test/analyzer1.test
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# 2015-05-11
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# Quick tests for the sqlite3_analyzer tool
|
||||||
|
#
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
ifcapable !vtab {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$tcl_platform(platform)=="windows"} {
|
||||||
|
set PROG "sqlite3_analyzer.exe"
|
||||||
|
} else {
|
||||||
|
set PROG "./sqlite3_analyzer"
|
||||||
|
}
|
||||||
|
db close
|
||||||
|
forcedelete test.db test.db-journal test.db-wal
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_test analyzer1-1.0 {
|
||||||
|
db eval {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t2(a INT PRIMARY KEY, b) WITHOUT ROWID;
|
||||||
|
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<250)
|
||||||
|
INSERT INTO t1(a,b) SELECT x, randomblob(200) FROM c;
|
||||||
|
INSERT INTO t2(a,b) SELECT a, b FROM t1;
|
||||||
|
}
|
||||||
|
set line "exec $PROG test.db"
|
||||||
|
unset -nocomplain ::MSG
|
||||||
|
catch {eval $line} ::MSG
|
||||||
|
} {0}
|
||||||
|
do_test analyzer1-1.1 {
|
||||||
|
regexp {^/\*\* Disk-Space Utilization.*COMMIT;\W*$} $::MSG
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
finish_test
|
@ -507,10 +507,49 @@ foreach {tn expr res} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} {
|
} {
|
||||||
do_execsql_test 11.1.$tn {
|
do_execsql_test 11.1.$tn.1 {
|
||||||
SELECT rowid, mit(matchinfo(tt, 'y')) FROM tt WHERE tt MATCH $expr
|
SELECT rowid, mit(matchinfo(tt, 'y')) FROM tt WHERE tt MATCH $expr
|
||||||
} $res
|
} $res
|
||||||
|
|
||||||
|
set r2 [list]
|
||||||
|
foreach {rowid L} $res {
|
||||||
|
lappend r2 $rowid
|
||||||
|
set M [list]
|
||||||
|
foreach {a b} $L {
|
||||||
|
lappend M [expr ($a ? 1 : 0) + ($b ? 2 : 0)]
|
||||||
|
}
|
||||||
|
lappend r2 $M
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 11.1.$tn.2 {
|
||||||
|
SELECT rowid, mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH $expr
|
||||||
|
} $r2
|
||||||
|
breakpoint
|
||||||
|
|
||||||
|
do_execsql_test 11.1.$tn.2 {
|
||||||
|
SELECT rowid, mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH $expr
|
||||||
|
} $r2
|
||||||
}
|
}
|
||||||
set sqlite_fts3_enable_parentheses 0
|
set sqlite_fts3_enable_parentheses 0
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Test the 'b' matchinfo flag
|
||||||
|
#
|
||||||
|
set sqlite_fts3_enable_parentheses 1
|
||||||
|
reset_db
|
||||||
|
db func mit mit
|
||||||
|
|
||||||
|
do_test 12.0 {
|
||||||
|
set cols [list]
|
||||||
|
for {set i 0} {$i < 50} {incr i} { lappend cols "c$i" }
|
||||||
|
execsql "CREATE VIRTUAL TABLE tt USING fts3([join $cols ,])"
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_execsql_test 12.1 {
|
||||||
|
INSERT INTO tt (rowid, c4, c45) VALUES(1, 'abc', 'abc');
|
||||||
|
SELECT mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH 'abc';
|
||||||
|
} [list [list [expr 1<<4] [expr 1<<(45-32)]]]
|
||||||
|
|
||||||
|
set sqlite_fts3_enable_parentheses 0
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
@ -173,8 +173,8 @@ do_select_tests 5.4 -errorformat {
|
|||||||
4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'" optimize
|
4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'" optimize
|
||||||
}
|
}
|
||||||
do_catchsql_test 5.5.1 {
|
do_catchsql_test 5.5.1 {
|
||||||
SELECT matchinfo(t2, 'abc') FROM t2 WHERE t2 MATCH 'history'
|
SELECT matchinfo(t2, 'abcd') FROM t2 WHERE t2 MATCH 'history'
|
||||||
} {1 {unrecognized matchinfo request: b}}
|
} {1 {unrecognized matchinfo request: d}}
|
||||||
|
|
||||||
do_execsql_test 5.5 { DROP TABLE t2 }
|
do_execsql_test 5.5 { DROP TABLE t2 }
|
||||||
|
|
||||||
|
@ -559,7 +559,6 @@ do_execsql_test jrnlmode-8.30 { PRAGMA journal_mode=DELETE } {delete}
|
|||||||
do_test jrnlmode-9.1 {
|
do_test jrnlmode-9.1 {
|
||||||
forcedelete test2.db
|
forcedelete test2.db
|
||||||
sqlite3 db2 test2.db
|
sqlite3 db2 test2.db
|
||||||
breakpoint
|
|
||||||
db2 eval {CREATE TEMP TABLE t(l); PRAGMA journal_mode=off;}
|
db2 eval {CREATE TEMP TABLE t(l); PRAGMA journal_mode=off;}
|
||||||
db2 close
|
db2 close
|
||||||
} {}
|
} {}
|
||||||
|
60
test/sqldiff1.test
Normal file
60
test/sqldiff1.test
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# 2015-05-11
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# Quick tests for the sqldiff tool
|
||||||
|
#
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
if {$tcl_platform(platform)=="windows"} {
|
||||||
|
set PROG "sqldiff.exe"
|
||||||
|
} else {
|
||||||
|
set PROG "./sqldiff"
|
||||||
|
}
|
||||||
|
db close
|
||||||
|
forcedelete test.db test2.db
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_test sqldiff-1.0 {
|
||||||
|
db eval {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t2(a INT PRIMARY KEY, b) WITHOUT ROWID;
|
||||||
|
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||||
|
INSERT INTO t1(a,b) SELECT x, printf('abc-%d-xyz',x) FROM c;
|
||||||
|
INSERT INTO t2(a,b) SELECT a, b FROM t1;
|
||||||
|
}
|
||||||
|
db backup test2.db
|
||||||
|
db eval {
|
||||||
|
ATTACH 'test2.db' AS x2;
|
||||||
|
DELETE FROM x2.t1 WHERE a=49;
|
||||||
|
DELETE FROM x2.t2 WHERE a=48;
|
||||||
|
INSERT INTO x2.t1(a,b) VALUES(1234,'hello');
|
||||||
|
INSERT INTO x2.t2(a,b) VALUES(50.5,'xyzzy');
|
||||||
|
CREATE TABLE x2.t3(a,b,c);
|
||||||
|
INSERT INTO x2.t3 VALUES(111,222,333);
|
||||||
|
CREATE TABLE main.t4(x,y,z);
|
||||||
|
INSERT INTO t4 SELECT * FROM t3;
|
||||||
|
}
|
||||||
|
set line "exec $PROG test.db test2.db"
|
||||||
|
unset -nocomplain ::MSG
|
||||||
|
catch {eval $line} ::MSG
|
||||||
|
} {0}
|
||||||
|
do_test sqldiff-1.1 {
|
||||||
|
set ::MSG
|
||||||
|
} {DELETE FROM t1 WHERE a=49;
|
||||||
|
INSERT INTO t1(a,b) VALUES(1234,'hello');
|
||||||
|
DELETE FROM t2 WHERE a=48;
|
||||||
|
INSERT INTO t2(a,b) VALUES(50.5,'xyzzy');
|
||||||
|
CREATE TABLE t3(a,b,c);
|
||||||
|
INSERT INTO t3(rowid,a,b,c) VALUES(1,111,222,333);
|
||||||
|
DROP TABLE t4;}
|
||||||
|
|
||||||
|
finish_test
|
@ -166,8 +166,10 @@ sqlite3 db test.db
|
|||||||
register_dbstat_vtab db
|
register_dbstat_vtab db
|
||||||
do_execsql_test stat-5.1 {
|
do_execsql_test stat-5.1 {
|
||||||
PRAGMA auto_vacuum = OFF;
|
PRAGMA auto_vacuum = OFF;
|
||||||
CREATE VIRTUAL TABLE temp.stat USING dbstat;
|
CREATE TABLE tx(y);
|
||||||
CREATE TABLE t1(x);
|
ATTACH ':memory:' AS aux1;
|
||||||
|
CREATE VIRTUAL TABLE temp.stat USING dbstat(aux1);
|
||||||
|
CREATE TABLE aux1.t1(x);
|
||||||
INSERT INTO t1 VALUES(zeroblob(1513));
|
INSERT INTO t1 VALUES(zeroblob(1513));
|
||||||
INSERT INTO t1 VALUES(zeroblob(1514));
|
INSERT INTO t1 VALUES(zeroblob(1514));
|
||||||
SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
|
SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
|
||||||
@ -178,4 +180,8 @@ do_execsql_test stat-5.1 {
|
|||||||
t1 /001+000000 4 overflow 0 1020 0 0 \
|
t1 /001+000000 4 overflow 0 1020 0 0 \
|
||||||
]
|
]
|
||||||
|
|
||||||
|
do_catchsql_test stat-6.1 {
|
||||||
|
CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx);
|
||||||
|
} {1 {no such database: mainx}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -66,6 +66,12 @@ do_execsql_test transitive1-301 {
|
|||||||
WHERE w=y AND y IS NOT NULL
|
WHERE w=y AND y IS NOT NULL
|
||||||
ORDER BY w;
|
ORDER BY w;
|
||||||
} {1 2 1 3 3 4 3 6 5 6 5 7}
|
} {1 2 1 3 3 4 3 6 5 6 5 7}
|
||||||
|
do_execsql_test transitive1-302 {
|
||||||
|
SELECT *
|
||||||
|
FROM t301 CROSS JOIN t302
|
||||||
|
WHERE w IS y AND y IS NOT NULL
|
||||||
|
ORDER BY w;
|
||||||
|
} {1 2 1 3 3 4 3 6 5 6 5 7}
|
||||||
do_execsql_test transitive1-310 {
|
do_execsql_test transitive1-310 {
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM t301 CROSS JOIN t302 ON w=y
|
FROM t301 CROSS JOIN t302 ON w=y
|
||||||
@ -103,7 +109,7 @@ do_execsql_test transitive1-332 {
|
|||||||
} {3 4 3 6 1 2 1 3}
|
} {3 4 3 6 1 2 1 3}
|
||||||
|
|
||||||
# Ticket [c620261b5b5dc] circa 2013-10-28.
|
# Ticket [c620261b5b5dc] circa 2013-10-28.
|
||||||
# Make sureconstraints are not used with LEFT JOINs.
|
# Make sure constraints are not used with LEFT JOINs.
|
||||||
#
|
#
|
||||||
# The next case is from the ticket report. It outputs no rows in 3.8.1
|
# The next case is from the ticket report. It outputs no rows in 3.8.1
|
||||||
# prior to the bug-fix.
|
# prior to the bug-fix.
|
||||||
@ -116,6 +122,16 @@ do_execsql_test transitive1-400 {
|
|||||||
INSERT INTO t403 VALUES(1);
|
INSERT INTO t403 VALUES(1);
|
||||||
SELECT '1-row' FROM t401 LEFT JOIN t402 ON b=a JOIN t403 ON c=a;
|
SELECT '1-row' FROM t401 LEFT JOIN t402 ON b=a JOIN t403 ON c=a;
|
||||||
} {1-row}
|
} {1-row}
|
||||||
|
do_execsql_test transitive1-401 {
|
||||||
|
SELECT '1-row' FROM t401 LEFT JOIN t402 ON b IS a JOIN t403 ON c=a;
|
||||||
|
} {1-row}
|
||||||
|
do_execsql_test transitive1-402 {
|
||||||
|
SELECT '1-row' FROM t401 LEFT JOIN t402 ON b=a JOIN t403 ON c IS a;
|
||||||
|
} {1-row}
|
||||||
|
do_execsql_test transitive1-403 {
|
||||||
|
SELECT '1-row' FROM t401 LEFT JOIN t402 ON b IS a JOIN t403 ON c IS a;
|
||||||
|
} {1-row}
|
||||||
|
|
||||||
|
|
||||||
# The following is a script distilled from the XBMC project where the
|
# The following is a script distilled from the XBMC project where the
|
||||||
# bug was originally encountered. The correct answer is a single row
|
# bug was originally encountered. The correct answer is a single row
|
||||||
|
@ -1085,11 +1085,22 @@ do_test vtab1.13-3 {
|
|||||||
SELECT * FROM echo_c WHERE b IS NULL
|
SELECT * FROM echo_c WHERE b IS NULL
|
||||||
}
|
}
|
||||||
} {15 {} 16}
|
} {15 {} 16}
|
||||||
do_test vtab1.13-3 {
|
do_test vtab1.13-4 {
|
||||||
|
unset -nocomplain null
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM echo_c WHERE b IS $null
|
||||||
|
}
|
||||||
|
} {15 {} 16}
|
||||||
|
do_test vtab1.13-5 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT * FROM echo_c WHERE b IS NULL AND a = 15;
|
SELECT * FROM echo_c WHERE b IS NULL AND a = 15;
|
||||||
}
|
}
|
||||||
} {15 {} 16}
|
} {15 {} 16}
|
||||||
|
do_test vtab1.13-6 {
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM echo_c WHERE NULL IS b AND a IS 15;
|
||||||
|
}
|
||||||
|
} {15 {} 16}
|
||||||
|
|
||||||
|
|
||||||
do_test vtab1-14.001 {
|
do_test vtab1-14.001 {
|
||||||
|
@ -104,6 +104,14 @@ do_test vtab2-3.2 {
|
|||||||
WHERE a.rowid=1
|
WHERE a.rowid=1
|
||||||
}
|
}
|
||||||
} {main schema 0 database {} 0 {} 0 {} {} {} {} {} {} {} {} {}}
|
} {main schema 0 database {} 0 {} 0 {} {} {} {} {} {} {} {} {}}
|
||||||
|
do_test vtab2-3.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT *, b.rowid
|
||||||
|
FROM schema a LEFT JOIN schema b ON a.dflt_value IS b.dflt_value
|
||||||
|
AND a.dflt_value IS NOT NULL
|
||||||
|
WHERE a.rowid=1
|
||||||
|
}
|
||||||
|
} {main schema 0 database {} 0 {} 0 {} {} {} {} {} {} {} {} {}}
|
||||||
|
|
||||||
do_test vtab2-4.1 {
|
do_test vtab2-4.1 {
|
||||||
execsql {
|
execsql {
|
||||||
@ -153,4 +161,3 @@ ifcapable fts3 {
|
|||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
@ -233,6 +233,11 @@ do_test vtab6-2.4 {
|
|||||||
SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d
|
SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d
|
||||||
}
|
}
|
||||||
} {1 2 3 {} {} {} 2 3 4 {} {} {} 3 4 5 1 2 3}
|
} {1 2 3 {} {} {} 2 3 4 {} {} {} 3 4 5 1 2 3}
|
||||||
|
do_test vtab6-2.4.1 {
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON t1.a IS t2.d
|
||||||
|
}
|
||||||
|
} {1 2 3 {} {} {} 2 3 4 {} {} {} 3 4 5 1 2 3}
|
||||||
do_test vtab6-2.5 {
|
do_test vtab6-2.5 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d WHERE t1.a>1
|
SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d WHERE t1.a>1
|
||||||
|
@ -65,9 +65,15 @@ proc count sql {
|
|||||||
do_test where-1.1.1 {
|
do_test where-1.1.1 {
|
||||||
count {SELECT x, y, w FROM t1 WHERE w=10}
|
count {SELECT x, y, w FROM t1 WHERE w=10}
|
||||||
} {3 121 10 3}
|
} {3 121 10 3}
|
||||||
|
do_test where-1.1.1b {
|
||||||
|
count {SELECT x, y, w FROM t1 WHERE w IS 10}
|
||||||
|
} {3 121 10 3}
|
||||||
do_eqp_test where-1.1.2 {
|
do_eqp_test where-1.1.2 {
|
||||||
SELECT x, y, w FROM t1 WHERE w=10
|
SELECT x, y, w FROM t1 WHERE w=10
|
||||||
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
|
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
|
||||||
|
do_eqp_test where-1.1.2b {
|
||||||
|
SELECT x, y, w FROM t1 WHERE w IS 10
|
||||||
|
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
|
||||||
do_test where-1.1.3 {
|
do_test where-1.1.3 {
|
||||||
db status step
|
db status step
|
||||||
} {0}
|
} {0}
|
||||||
@ -101,12 +107,21 @@ do_test where-1.3.1 {
|
|||||||
do_test where-1.3.2 {
|
do_test where-1.3.2 {
|
||||||
count {SELECT x, y, w AS abc FROM t1 WHERE 11=abc}
|
count {SELECT x, y, w AS abc FROM t1 WHERE 11=abc}
|
||||||
} {3 144 11 3}
|
} {3 144 11 3}
|
||||||
|
do_test where-1.3.3 {
|
||||||
|
count {SELECT x, y, w AS abc FROM t1 WHERE 11 IS abc}
|
||||||
|
} {3 144 11 3}
|
||||||
do_test where-1.4.1 {
|
do_test where-1.4.1 {
|
||||||
count {SELECT w, x, y FROM t1 WHERE 11=w AND x>2}
|
count {SELECT w, x, y FROM t1 WHERE 11=w AND x>2}
|
||||||
} {11 3 144 3}
|
} {11 3 144 3}
|
||||||
|
do_test where-1.4.1b {
|
||||||
|
count {SELECT w, x, y FROM t1 WHERE 11 IS w AND x>2}
|
||||||
|
} {11 3 144 3}
|
||||||
do_eqp_test where-1.4.2 {
|
do_eqp_test where-1.4.2 {
|
||||||
SELECT w, x, y FROM t1 WHERE 11=w AND x>2
|
SELECT w, x, y FROM t1 WHERE 11=w AND x>2
|
||||||
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
|
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
|
||||||
|
do_eqp_test where-1.4.2b {
|
||||||
|
SELECT w, x, y FROM t1 WHERE 11 IS w AND x>2
|
||||||
|
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
|
||||||
do_test where-1.4.3 {
|
do_test where-1.4.3 {
|
||||||
count {SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2}
|
count {SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2}
|
||||||
} {11 3 144 3}
|
} {11 3 144 3}
|
||||||
@ -143,6 +158,9 @@ do_test where-1.10 {
|
|||||||
do_test where-1.11 {
|
do_test where-1.11 {
|
||||||
count {SELECT x, y FROM t1 WHERE x=3 AND y=100 AND w<10}
|
count {SELECT x, y FROM t1 WHERE x=3 AND y=100 AND w<10}
|
||||||
} {3 100 3}
|
} {3 100 3}
|
||||||
|
do_test where-1.11b {
|
||||||
|
count {SELECT x, y FROM t1 WHERE x IS 3 AND y IS 100 AND w<10}
|
||||||
|
} {3 100 3}
|
||||||
|
|
||||||
# New for SQLite version 2.1: Verify that that inequality constraints
|
# New for SQLite version 2.1: Verify that that inequality constraints
|
||||||
# are used correctly.
|
# are used correctly.
|
||||||
@ -150,12 +168,18 @@ do_test where-1.11 {
|
|||||||
do_test where-1.12 {
|
do_test where-1.12 {
|
||||||
count {SELECT w FROM t1 WHERE x=3 AND y<100}
|
count {SELECT w FROM t1 WHERE x=3 AND y<100}
|
||||||
} {8 3}
|
} {8 3}
|
||||||
|
do_test where-1.12b {
|
||||||
|
count {SELECT w FROM t1 WHERE x IS 3 AND y<100}
|
||||||
|
} {8 3}
|
||||||
do_test where-1.13 {
|
do_test where-1.13 {
|
||||||
count {SELECT w FROM t1 WHERE x=3 AND 100>y}
|
count {SELECT w FROM t1 WHERE x=3 AND 100>y}
|
||||||
} {8 3}
|
} {8 3}
|
||||||
do_test where-1.14 {
|
do_test where-1.14 {
|
||||||
count {SELECT w FROM t1 WHERE 3=x AND y<100}
|
count {SELECT w FROM t1 WHERE 3=x AND y<100}
|
||||||
} {8 3}
|
} {8 3}
|
||||||
|
do_test where-1.14b {
|
||||||
|
count {SELECT w FROM t1 WHERE 3 IS x AND y<100}
|
||||||
|
} {8 3}
|
||||||
do_test where-1.15 {
|
do_test where-1.15 {
|
||||||
count {SELECT w FROM t1 WHERE 3=x AND 100>y}
|
count {SELECT w FROM t1 WHERE 3=x AND 100>y}
|
||||||
} {8 3}
|
} {8 3}
|
||||||
@ -168,6 +192,9 @@ do_test where-1.17 {
|
|||||||
do_test where-1.18 {
|
do_test where-1.18 {
|
||||||
count {SELECT w FROM t1 WHERE x=3 AND y>225}
|
count {SELECT w FROM t1 WHERE x=3 AND y>225}
|
||||||
} {15 3}
|
} {15 3}
|
||||||
|
do_test where-1.18b {
|
||||||
|
count {SELECT w FROM t1 WHERE x IS 3 AND y>225}
|
||||||
|
} {15 3}
|
||||||
do_test where-1.19 {
|
do_test where-1.19 {
|
||||||
count {SELECT w FROM t1 WHERE x=3 AND 225<y}
|
count {SELECT w FROM t1 WHERE x=3 AND 225<y}
|
||||||
} {15 3}
|
} {15 3}
|
||||||
@ -180,6 +207,9 @@ do_test where-1.21 {
|
|||||||
do_test where-1.22 {
|
do_test where-1.22 {
|
||||||
count {SELECT w FROM t1 WHERE x=3 AND y>121 AND y<196}
|
count {SELECT w FROM t1 WHERE x=3 AND y>121 AND y<196}
|
||||||
} {11 12 5}
|
} {11 12 5}
|
||||||
|
do_test where-1.22b {
|
||||||
|
count {SELECT w FROM t1 WHERE x IS 3 AND y>121 AND y<196}
|
||||||
|
} {11 12 5}
|
||||||
do_test where-1.23 {
|
do_test where-1.23 {
|
||||||
count {SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<=196}
|
count {SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<=196}
|
||||||
} {10 11 12 13 9}
|
} {10 11 12 13 9}
|
||||||
|
@ -57,6 +57,10 @@ proc count sql {
|
|||||||
do_test where4-1.1 {
|
do_test where4-1.1 {
|
||||||
count {SELECT rowid FROM t1 WHERE w IS NULL}
|
count {SELECT rowid FROM t1 WHERE w IS NULL}
|
||||||
} {7 2}
|
} {7 2}
|
||||||
|
do_test where4-1.1b {
|
||||||
|
unset -nocomplain null
|
||||||
|
count {SELECT rowid FROM t1 WHERE w IS $null}
|
||||||
|
} {7 2}
|
||||||
do_test where4-1.2 {
|
do_test where4-1.2 {
|
||||||
count {SELECT rowid FROM t1 WHERE +w IS NULL}
|
count {SELECT rowid FROM t1 WHERE +w IS NULL}
|
||||||
} {7 6}
|
} {7 6}
|
||||||
@ -143,6 +147,17 @@ do_test where4-3.2 {
|
|||||||
SELECT * FROM t2 LEFT JOIN t3 ON a=x WHERE y IS NULL;
|
SELECT * FROM t2 LEFT JOIN t3 ON a=x WHERE y IS NULL;
|
||||||
}
|
}
|
||||||
} {2 2 {} 3 {} {}}
|
} {2 2 {} 3 {} {}}
|
||||||
|
do_test where4-3.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM t2 LEFT JOIN t3 ON a=x WHERE NULL is y;
|
||||||
|
}
|
||||||
|
} {2 2 {} 3 {} {}}
|
||||||
|
do_test where4-3.4 {
|
||||||
|
unset -nocomplain null
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM t2 LEFT JOIN t3 ON a=x WHERE y IS $null;
|
||||||
|
}
|
||||||
|
} {2 2 {} 3 {} {}}
|
||||||
|
|
||||||
# Ticket #2189. Probably the same bug as #2177.
|
# Ticket #2189. Probably the same bug as #2177.
|
||||||
#
|
#
|
||||||
|
@ -59,6 +59,7 @@ foreach {tn sql res} {
|
|||||||
12 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i<NULL" {}
|
12 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i<NULL" {}
|
||||||
13 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i>=NULL" {}
|
13 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i>=NULL" {}
|
||||||
14 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<4.5" {3 4}
|
14 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<4.5" {3 4}
|
||||||
|
15 "SELECT i FROM t1 WHERE rowid IS '12'" {12}
|
||||||
} {
|
} {
|
||||||
do_execsql_test 1.$tn.1 $sql $res
|
do_execsql_test 1.$tn.1 $sql $res
|
||||||
do_execsql_test 1.$tn.2 "$sql ORDER BY i ASC" [lsort -integer -inc $res]
|
do_execsql_test 1.$tn.2 "$sql ORDER BY i ASC" [lsort -integer -inc $res]
|
||||||
|
@ -88,7 +88,6 @@ if {[catch {sqlite3 db $file_to_analyze -uri 1} msg]} {
|
|||||||
puts stderr "error trying to open $file_to_analyze: $msg"
|
puts stderr "error trying to open $file_to_analyze: $msg"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
register_dbstat_vtab db
|
|
||||||
|
|
||||||
db eval {SELECT count(*) FROM sqlite_master}
|
db eval {SELECT count(*) FROM sqlite_master}
|
||||||
set pageSize [expr {wide([db one {PRAGMA page_size}])}]
|
set pageSize [expr {wide([db one {PRAGMA page_size}])}]
|
||||||
|
@ -1139,6 +1139,7 @@ int main(int argc, char **argv){
|
|||||||
char **azExt = 0;
|
char **azExt = 0;
|
||||||
|
|
||||||
g.zArgv0 = argv[0];
|
g.zArgv0 = argv[0];
|
||||||
|
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
|
||||||
for(i=1; i<argc; i++){
|
for(i=1; i<argc; i++){
|
||||||
const char *z = argv[i];
|
const char *z = argv[i];
|
||||||
if( z[0]=='-' ){
|
if( z[0]=='-' ){
|
||||||
@ -1158,12 +1159,14 @@ int main(int argc, char **argv){
|
|||||||
showHelp();
|
showHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}else
|
}else
|
||||||
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
if( strcmp(z,"lib")==0 || strcmp(z,"L")==0 ){
|
if( strcmp(z,"lib")==0 || strcmp(z,"L")==0 ){
|
||||||
if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
|
if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
|
||||||
azExt = realloc(azExt, sizeof(azExt[0])*(nExt+1));
|
azExt = realloc(azExt, sizeof(azExt[0])*(nExt+1));
|
||||||
if( azExt==0 ) cmdlineError("out of memory");
|
if( azExt==0 ) cmdlineError("out of memory");
|
||||||
azExt[nExt++] = argv[++i];
|
azExt[nExt++] = argv[++i];
|
||||||
}else
|
}else
|
||||||
|
#endif
|
||||||
if( strcmp(z,"primarykey")==0 ){
|
if( strcmp(z,"primarykey")==0 ){
|
||||||
g.bSchemaPK = 1;
|
g.bSchemaPK = 1;
|
||||||
}else
|
}else
|
||||||
@ -1199,6 +1202,7 @@ int main(int argc, char **argv){
|
|||||||
if( rc || zErrMsg ){
|
if( rc || zErrMsg ){
|
||||||
cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
|
cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
|
||||||
}
|
}
|
||||||
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
sqlite3_enable_load_extension(g.db, 1);
|
sqlite3_enable_load_extension(g.db, 1);
|
||||||
for(i=0; i<nExt; i++){
|
for(i=0; i<nExt; i++){
|
||||||
rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
|
rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
|
||||||
@ -1206,6 +1210,7 @@ int main(int argc, char **argv){
|
|||||||
cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
|
cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
free(azExt);
|
free(azExt);
|
||||||
zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
|
zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
|
||||||
rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
|
rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
|
||||||
|
Reference in New Issue
Block a user