Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96f4ad20fd | |||
| 81367381a9 | |||
| a9e03b1b82 | |||
| cdcc11d7d4 | |||
| 18bf807689 | |||
| cc285c5ab0 | |||
| 94929646f1 | |||
| 9b5d76bf57 | |||
| 8031462939 | |||
| a40da62dd4 | |||
| 74f4d3e5df | |||
| 52fc05ba1c | |||
| b0230249f5 | |||
| 560b7c72be | |||
| ab87a5e5b8 | |||
| b7c60ba668 | |||
| 16897072b5 | |||
| a9c18a9067 | |||
| 8f1a7ed33f | |||
| f07cf6e2a5 | |||
| 8dd7a6a925 | |||
| 0266c05fcb | |||
| 7be0fd9c58 | |||
| 5e7028c210 | |||
| 2af878ec5e | |||
| 682a6ef6bd | |||
| 0b7ff5c11b | |||
| 33e1327a22 | |||
| 39f2d0963e | |||
| e89b291828 | |||
| 91eb93c797 | |||
| 4a4b138965 | |||
| 3ba689d8ba | |||
| 8cd5b2546f | |||
| 8e8e7ef363 | |||
| 534f4dfa3c | |||
| 51a74d4cbd | |||
| e0e8429543 | |||
| 9d356fbe6e | |||
| 22ec13466c | |||
| 38e40ee2e5 | |||
| 531b55ead0 | |||
| 05f6c67cc1 | |||
| c941a4b3b6 | |||
| cbb3f33c56 | |||
| b492e23b42 | |||
| fd34d6d379 | |||
| 8d8738eae0 | |||
| 13cc90cfa2 | |||
| 2a45cb5c0e | |||
| 690429a08f | |||
| e006a86643 | |||
| 077f06edfa | |||
| 36f65bafe5 | |||
| d4ef026ebb | |||
| 2da47d3869 | |||
| e6d4173b78 | |||
| ad0961b31b | |||
| db222adfd3 | |||
| a712b4bb97 | |||
| 4bf66fd6f3 | |||
| 883ad04985 | |||
| 96c707a3c2 | |||
| 983b5ee73d | |||
| a0efb1ae11 | |||
| 6728cd9180 | |||
| 9fab5ed01f | |||
| 2c5e9b5672 | |||
| 2308ed3854 | |||
| 885a5b030e | |||
| 63f845734e | |||
| 17645f5eec | |||
| 0e86a1ac08 | |||
| 31e7147dfa | |||
| d10d18da5f | |||
| 0e55db1cd8 | |||
| f7502f005e | |||
| fe0e84c948 | |||
| 4bb8cb0927 | |||
| 8fb15e3b20 | |||
| 1dae26bdab | |||
| 67e65e55ab | |||
| c228be5b1f | |||
| 1ffede8c86 | |||
| 0699f29a14 | |||
| fdc2e6d344 | |||
| 976b003344 | |||
| 6267920b09 |
+17
-5
@@ -255,6 +255,7 @@ SRC = \
|
||||
$(TOP)/src/pcache.h \
|
||||
$(TOP)/src/pcache1.c \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/pragma.h \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
$(TOP)/src/random.c \
|
||||
@@ -286,6 +287,7 @@ SRC = \
|
||||
$(TOP)/src/vdbetrace.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/wal.c \
|
||||
$(TOP)/src/wal.h \
|
||||
$(TOP)/src/walker.c \
|
||||
@@ -474,12 +476,14 @@ HDR = \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/pcache.h \
|
||||
parse.h \
|
||||
$(TOP)/src/pragma.h \
|
||||
sqlite3.h \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/sqliteLimit.h \
|
||||
$(TOP)/src/vdbe.h \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/whereInt.h \
|
||||
config.h
|
||||
|
||||
@@ -536,11 +540,19 @@ mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
|
||||
MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
|
||||
mptest: mptester$(EXE)
|
||||
rm -f mptest1.db
|
||||
./mptester$(EXE) mptest1.db $(TOP)/mptest/crash01.test
|
||||
rm -f mptest2.db
|
||||
./mptester$(EXE) mptest2.db $(TOP)/mptest/multiwrite01.test
|
||||
rm -f mptest.db
|
||||
$(MPTEST1) --journalmode DELETE
|
||||
$(MPTEST2) --journalmode WAL
|
||||
$(MPTEST1) --journalmode WAL
|
||||
$(MPTEST2) --journalmode PERSIST
|
||||
$(MPTEST1) --journalmode PERSIST
|
||||
$(MPTEST2) --journalmode TRUNCATE
|
||||
$(MPTEST1) --journalmode TRUNCATE
|
||||
$(MPTEST2) --journalmode DELETE
|
||||
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
@@ -995,7 +1007,7 @@ LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h
|
||||
wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.c
|
||||
$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.c $(TLIBS)
|
||||
|
||||
speedtest1$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo
|
||||
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS)
|
||||
|
||||
# This target will fail if the SQLite amalgamation contains any exported
|
||||
|
||||
+48
-38
@@ -714,7 +714,7 @@ LIBRESOBJS =
|
||||
|
||||
# All of the source code files.
|
||||
#
|
||||
SRC = \
|
||||
SRC1 = \
|
||||
$(TOP)\src\alter.c \
|
||||
$(TOP)\src\analyze.c \
|
||||
$(TOP)\src\attach.c \
|
||||
@@ -764,7 +764,8 @@ SRC = \
|
||||
$(TOP)\src\os_setup.h \
|
||||
$(TOP)\src\os_unix.c \
|
||||
$(TOP)\src\os_win.c \
|
||||
$(TOP)\src\os_win.h \
|
||||
$(TOP)\src\os_win.h
|
||||
SRC2 = \
|
||||
$(TOP)\src\pager.c \
|
||||
$(TOP)\src\pager.h \
|
||||
$(TOP)\src\parse.y \
|
||||
@@ -772,6 +773,7 @@ SRC = \
|
||||
$(TOP)\src\pcache.h \
|
||||
$(TOP)\src\pcache1.c \
|
||||
$(TOP)\src\pragma.c \
|
||||
$(TOP)\src\pragma.h \
|
||||
$(TOP)\src\prepare.c \
|
||||
$(TOP)\src\printf.c \
|
||||
$(TOP)\src\random.c \
|
||||
@@ -803,6 +805,7 @@ SRC = \
|
||||
$(TOP)\src\vdbetrace.c \
|
||||
$(TOP)\src\vdbeInt.h \
|
||||
$(TOP)\src\vtab.c \
|
||||
$(TOP)\src\vxworks.h \
|
||||
$(TOP)\src\wal.c \
|
||||
$(TOP)\src\wal.h \
|
||||
$(TOP)\src\walker.c \
|
||||
@@ -811,15 +814,14 @@ SRC = \
|
||||
|
||||
# Source code for extensions
|
||||
#
|
||||
SRC = $(SRC) \
|
||||
SRC3 = \
|
||||
$(TOP)\ext\fts1\fts1.c \
|
||||
$(TOP)\ext\fts1\fts1.h \
|
||||
$(TOP)\ext\fts1\fts1_hash.c \
|
||||
$(TOP)\ext\fts1\fts1_hash.h \
|
||||
$(TOP)\ext\fts1\fts1_porter.c \
|
||||
$(TOP)\ext\fts1\fts1_tokenizer.h \
|
||||
$(TOP)\ext\fts1\fts1_tokenizer1.c
|
||||
SRC = $(SRC) \
|
||||
$(TOP)\ext\fts1\fts1_tokenizer1.c \
|
||||
$(TOP)\ext\fts2\fts2.c \
|
||||
$(TOP)\ext\fts2\fts2.h \
|
||||
$(TOP)\ext\fts2\fts2_hash.c \
|
||||
@@ -829,7 +831,7 @@ SRC = $(SRC) \
|
||||
$(TOP)\ext\fts2\fts2_tokenizer.h \
|
||||
$(TOP)\ext\fts2\fts2_tokenizer.c \
|
||||
$(TOP)\ext\fts2\fts2_tokenizer1.c
|
||||
SRC = $(SRC) \
|
||||
SRC4 = \
|
||||
$(TOP)\ext\fts3\fts3.c \
|
||||
$(TOP)\ext\fts3\fts3.h \
|
||||
$(TOP)\ext\fts3\fts3Int.h \
|
||||
@@ -846,18 +848,16 @@ SRC = $(SRC) \
|
||||
$(TOP)\ext\fts3\fts3_tokenize_vtab.c \
|
||||
$(TOP)\ext\fts3\fts3_unicode.c \
|
||||
$(TOP)\ext\fts3\fts3_unicode2.c \
|
||||
$(TOP)\ext\fts3\fts3_write.c
|
||||
SRC = $(SRC) \
|
||||
$(TOP)\ext\fts3\fts3_write.c \
|
||||
$(TOP)\ext\icu\sqliteicu.h \
|
||||
$(TOP)\ext\icu\icu.c
|
||||
SRC = $(SRC) \
|
||||
$(TOP)\ext\icu\icu.c \
|
||||
$(TOP)\ext\rtree\rtree.h \
|
||||
$(TOP)\ext\rtree\rtree.c
|
||||
|
||||
|
||||
# Generated source code files
|
||||
#
|
||||
SRC = $(SRC) \
|
||||
SRC5 = \
|
||||
keywordhash.h \
|
||||
opcodes.c \
|
||||
opcodes.h \
|
||||
@@ -865,6 +865,10 @@ SRC = $(SRC) \
|
||||
parse.h \
|
||||
sqlite3.h
|
||||
|
||||
# All source code files.
|
||||
#
|
||||
SRC = $(SRC1) $(SRC2) $(SRC3) $(SRC4) $(SRC5)
|
||||
|
||||
# Source code to the test files.
|
||||
#
|
||||
TESTSRC = \
|
||||
@@ -994,12 +998,14 @@ HDR = \
|
||||
$(TOP)\src\pager.h \
|
||||
$(TOP)\src\pcache.h \
|
||||
parse.h \
|
||||
$(TOP)\src\pragma.h \
|
||||
sqlite3.h \
|
||||
$(TOP)\src\sqlite3ext.h \
|
||||
$(TOP)\src\sqliteInt.h \
|
||||
$(TOP)\src\sqliteLimit.h \
|
||||
$(TOP)\src\vdbe.h \
|
||||
$(TOP)\src\vdbeInt.h \
|
||||
$(TOP)\src\vxworks.h \
|
||||
$(TOP)\src\whereInt.h
|
||||
|
||||
# Header files used by extensions
|
||||
@@ -1052,7 +1058,11 @@ mptester.exe: $(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
|
||||
.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl
|
||||
-rmdir /S/Q tsrc
|
||||
-mkdir tsrc
|
||||
for %i in ($(SRC)) do copy /Y %i tsrc
|
||||
for %i in ($(SRC1)) do copy /Y %i tsrc
|
||||
for %i in ($(SRC2)) do copy /Y %i tsrc
|
||||
for %i in ($(SRC3)) do copy /Y %i tsrc
|
||||
for %i in ($(SRC4)) do copy /Y %i tsrc
|
||||
for %i in ($(SRC5)) do copy /Y %i tsrc
|
||||
del /Q tsrc\sqlite.h.in tsrc\parse.y
|
||||
$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
|
||||
move vdbe.new tsrc\vdbe.c
|
||||
@@ -1528,32 +1538,32 @@ speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C)
|
||||
$(TOP)\test\speedtest1.c $(SQLITE3C)
|
||||
|
||||
clean:
|
||||
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
|
||||
del /Q *.cod *.da *.bb *.bbg gmon.out
|
||||
del /Q sqlite3.h opcodes.c opcodes.h
|
||||
del /Q lemon.* lempar.c parse.*
|
||||
del /Q mkkeywordhash.* keywordhash.h
|
||||
del /Q notasharedlib.*
|
||||
-rmdir /Q/S .deps
|
||||
-rmdir /Q/S .libs
|
||||
-rmdir /Q/S quota2a
|
||||
-rmdir /Q/S quota2b
|
||||
-rmdir /Q/S quota2c
|
||||
-rmdir /Q/S tsrc
|
||||
del /Q .target_source
|
||||
del /Q tclsqlite3.exe tclsqlite3.exp
|
||||
del /Q testloadext.dll testloadext.exp
|
||||
del /Q testfixture.exe testfixture.exp test.db
|
||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe
|
||||
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe
|
||||
del /Q wordcount.exe
|
||||
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
|
||||
del /Q sqlite3.c sqlite3-*.c
|
||||
del /Q sqlite3rc.h
|
||||
del /Q shell.c sqlite3ext.h
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
|
||||
del /Q sqlite-*-output.vsix
|
||||
del /Q mptester.exe
|
||||
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib 2>NUL
|
||||
del /Q *.cod *.da *.bb *.bbg gmon.out 2>NUL
|
||||
del /Q sqlite3.h opcodes.c opcodes.h 2>NUL
|
||||
del /Q lemon.* lempar.c parse.* 2>NUL
|
||||
del /Q mkkeywordhash.* keywordhash.h 2>NUL
|
||||
del /Q notasharedlib.* 2>NUL
|
||||
-rmdir /Q/S .deps 2>NUL
|
||||
-rmdir /Q/S .libs 2>NUL
|
||||
-rmdir /Q/S quota2a 2>NUL
|
||||
-rmdir /Q/S quota2b 2>NUL
|
||||
-rmdir /Q/S quota2c 2>NUL
|
||||
-rmdir /Q/S tsrc 2>NUL
|
||||
del /Q .target_source 2>NUL
|
||||
del /Q tclsqlite3.exe tclsqlite3.exp 2>NUL
|
||||
del /Q testloadext.dll testloadext.exp 2>NUL
|
||||
del /Q testfixture.exe testfixture.exp test.db 2>NUL
|
||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL
|
||||
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
|
||||
del /Q wordcount.exe 2>NUL
|
||||
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def 2>NUL
|
||||
del /Q sqlite3.c sqlite3-*.c 2>NUL
|
||||
del /Q sqlite3rc.h 2>NUL
|
||||
del /Q shell.c sqlite3ext.h 2>NUL
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c 2>NUL
|
||||
del /Q sqlite-*-output.vsix 2>NUL
|
||||
del /Q mptester.exe 2>NUL
|
||||
|
||||
# Dynamic link library section.
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.8.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.9.
|
||||
#
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.8.8'
|
||||
PACKAGE_STRING='sqlite 3.8.8'
|
||||
PACKAGE_VERSION='3.8.9'
|
||||
PACKAGE_STRING='sqlite 3.8.9'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@@ -1480,7 +1480,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.8.8 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.8.9 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1545,7 +1545,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.8:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.9:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1659,7 +1659,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.8.8
|
||||
sqlite configure 3.8.9
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
@@ -1673,7 +1673,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.8.8, which was
|
||||
It was created by sqlite $as_me 3.8.9, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -13951,7 +13951,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.8.8, which was
|
||||
This file was extended by sqlite $as_me 3.8.9, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -14004,7 +14004,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.8.8
|
||||
sqlite config.status 3.8.9
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
||||
@@ -1253,7 +1253,7 @@ void sqlite3Fts3Snippet(
|
||||
*/
|
||||
for(iRead=0; iRead<pTab->nColumn; iRead++){
|
||||
SnippetFragment sF = {0, 0, 0, 0};
|
||||
int iS;
|
||||
int iS = 0;
|
||||
if( iCol>=0 && iRead!=iCol ) continue;
|
||||
|
||||
/* Find the best snippet of nFToken tokens in column iRead. */
|
||||
|
||||
+9
-2
@@ -38,6 +38,7 @@ static void compressFunc(
|
||||
unsigned int nIn;
|
||||
unsigned long int nOut;
|
||||
unsigned char x[8];
|
||||
int rc;
|
||||
int i, j;
|
||||
|
||||
pIn = sqlite3_value_blob(argv[0]);
|
||||
@@ -50,8 +51,12 @@ static void compressFunc(
|
||||
for(i=0; i<4 && x[i]==0; i++){}
|
||||
for(j=0; i<=4; i++, j++) pOut[j] = x[i];
|
||||
pOut[j-1] |= 0x80;
|
||||
compress(&pOut[j], &nOut, pIn, nIn);
|
||||
sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
|
||||
rc = compress(&pOut[j], &nOut, pIn, nIn);
|
||||
if( rc==Z_OK ){
|
||||
sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pOut);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -82,6 +87,8 @@ static void uncompressFunc(
|
||||
rc = uncompress(pOut, &nOut, &pIn[i], nIn-i);
|
||||
if( rc==Z_OK ){
|
||||
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ SRC = \
|
||||
$(TOP)/src/pcache.h \
|
||||
$(TOP)/src/pcache1.c \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/pragma.h \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
$(TOP)/src/random.c \
|
||||
@@ -164,6 +165,7 @@ SRC = \
|
||||
$(TOP)/src/vdbetrace.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/wal.c \
|
||||
$(TOP)/src/wal.h \
|
||||
$(TOP)/src/walker.c \
|
||||
@@ -356,12 +358,14 @@ HDR = \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/pcache.h \
|
||||
parse.h \
|
||||
$(TOP)/src/pragma.h \
|
||||
sqlite3.h \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/sqliteLimit.h \
|
||||
$(TOP)/src/vdbe.h \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/whereInt.h
|
||||
|
||||
# Header files used by extensions
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C Add\sa\sfew\ssimple\stest\scases\sfor\sSQLITE_TESTCTRL_INITMODE\s-\scases\swhich\nalso\stest\sPRAGMA\sintegrity_check.
|
||||
D 2015-01-30T15:40:15.485
|
||||
C Always\sdisallow\sfunctions\sas\sthe\sDEFAULT\sof\sa\scolumn.\s\sAdd\sassert()s\sand
|
||||
D 2015-03-12T21:02:36.947
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5407a688f4d77a05c18a8142be8ae5a2829dd610
|
||||
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 2b1cb8881bdefcb0a8ed41c34c81cfa630374222
|
||||
F Makefile.msc 529e61cd9d29a3934758b4b3a0bb649b6c653481
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||
F VERSION d846487aff892625eb8e75960234e7285f0462fe
|
||||
F VERSION 319eb1ced4b4d17a67730f2b7b85f15c1346cb60
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure b2882796ddebd33ac4e9d4ccf5c5ca11888fc30e x
|
||||
F configure 613b220c2f2c7adcd50eb5ee4144ab581a150b47 x
|
||||
F configure.ac 6a8d145aea6d81f0b90013340780e43ed74fd5f4
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
@@ -87,7 +87,7 @@ F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c f16ef6425f92339a8fecc87d9aaf2b12355c78e4
|
||||
F ext/fts3/fts3_snippet.c 52c2dcf410b1f9af5a44d81a2cf8c68ed1cb5283
|
||||
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
|
||||
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
||||
F ext/fts3/fts3_tokenize_vtab.c becc661223db7898b213f9e8a23d75bac02408c9
|
||||
@@ -108,7 +108,7 @@ F ext/icu/icu.c d415ccf984defeb9df2c0e1afcfaa2f6dc05eacb
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/misc/amatch.c 27b9b601fb1453084e18a3432ea0240d7af8decb
|
||||
F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
|
||||
F ext/misc/compress.c 76e45655f4046e756064ab10c62e18f2eb846b9f
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c e3e18f47252c151b5553d7e806f38e757d37c4cc
|
||||
@@ -152,41 +152,41 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk e392561ffe17fc4dad945eef852400d5bf2911a0
|
||||
F main.mk 04c49c495795b18a7b70053eef285be1e4d43fa4
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test cce8e306d8596d5a2e497e27112dae1f6e5e3538
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
|
||||
F mptest/mptest.c 24c5f72415df2eab7088ef8c9f99f163aed590c8
|
||||
F mptest/multiwrite01.test 499ad0310da8dff8e8f98d2e272fc2a8aa741b2e
|
||||
F mptest/mptest.c 0c0c82c1d9aea0b1a60ef9456a04c35ab1106622
|
||||
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
||||
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb
|
||||
F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81
|
||||
F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d
|
||||
F src/attach.c 7f6b3fafa2290b407e4a94dcf1afda7ec0fe394b
|
||||
F src/attach.c 880f9b8641a829c563e52dd13c452ce457ae4dd8
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
|
||||
F src/btree.c 4c098bb6e8678e4596983862abf78f7a0fcb807e
|
||||
F src/btree.h 94277c1d30c0b75705974bcc8b0c05e79c03d474
|
||||
F src/btreeInt.h a3d0ae1d511365e1a2b76ad10960dbe55c286f34
|
||||
F src/build.c f5cfd7b32216f695b995bbc7c1a395f6d451d11f
|
||||
F src/btree.c a31ac00e30fb7bb49e90e48ce29ef8a61591be96
|
||||
F src/btree.h 9cbbb92aab22ef8b50493c40aa3f8de87c43a2fb
|
||||
F src/btreeInt.h 2bfefc01875d8da066504c233ec259fcb3b2ef72
|
||||
F src/build.c ba45ebd02904e84d98839a6ea74c3eb948596587
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c 198a0066ba60ab06fc00fba1998d870a4d575463
|
||||
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
|
||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||
F src/delete.c bd1a91ddd247ce13004075251e0b7fe2bf9925ef
|
||||
F src/expr.c abe930897ccafae3819fd2855cbc1b00c262fd12
|
||||
F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
|
||||
F src/expr.c 3ef111b88ae2941b84b6b6ea4be8d501ba1af0cb
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12
|
||||
F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430
|
||||
F src/global.c 12561d70a1b25f67b21154622bb1723426724f75
|
||||
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
|
||||
F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
@@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660
|
||||
F src/main.c b0a41ca397083b137b98e6abb829c21611665d07
|
||||
F src/main.c fa997fa27d95febc16d57095299384b667a7f762
|
||||
F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||
@@ -206,40 +206,41 @@ F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
||||
F src/msvc.h e78002098966e39b2fd9915bd70b7bc3ec8398b7
|
||||
F src/mutex.c 19bf9acba69ca2f367c3761080f8a9f0cf4670a8
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex_noop.c f3f09fd7a2eb4287cfc799753ffc30380e7b71a1
|
||||
F src/mutex_unix.c 551e2f25f0fa0ee8fd7a43f50fc3d8be00e95dde
|
||||
F src/mutex_w32.c df48fe07562a45c5c927c45b8d5873a27f98bbb0
|
||||
F src/mutex_noop.c 529bab0743c3321c940f32c3464de494fd38cfa9
|
||||
F src/mutex_unix.c 5cf676464bd19e0a866297515d146e8bf1669dfb
|
||||
F src/mutex_w32.c 61660ada28d8308ad190f444c2170c4f2a590c2f
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c aefeaf915aaef9f81aa2645e0d5d06fa1bd83beb
|
||||
F src/os_unix.c 49d06acee4053920e4a6429844f440b5f975cea4
|
||||
F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
|
||||
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
||||
F src/parse.y c5d0d964f9ac023e8154cad512e54b0b6058e086
|
||||
F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb
|
||||
F src/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8
|
||||
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
|
||||
F src/pragma.c ba149bbbc90783f84815636c509ced8eac11bbcf
|
||||
F src/pragma.c ac4f3f856b4234e85f55b0f069698a4766011100
|
||||
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
|
||||
F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
|
||||
F src/printf.c 05edc41450d0eb2c05ef7db113bf32742ae65325
|
||||
F src/printf.c 8da9a2687a396daa19860f4dc90975d319304744
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
|
||||
F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 1f2087523007c42900ffcbdeaef06a23ad9329fc
|
||||
F src/shell.c ed7cf7c29fb1a23d47179affc89cb447868fc976
|
||||
F src/sqlite.h.in 6910064681444efb5c467472499b56bb6bcee0f4
|
||||
F src/select.c 94e016b6733b1d39a2f4c8d431155b4c2897d907
|
||||
F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92
|
||||
F src/sqlite.h.in 356e69db9500b3fd11705c21ca247e19b95884a3
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h eaf210295b551d4e40e622aec1b2261c0b28f844
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
|
||||
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
|
||||
F src/tclsqlite.c b8014393a96a9781bb635c8b1f52fc9b77a2bfcf
|
||||
F src/test1.c 5dcdade99e77b7b9f7760106c80a83cf50f10e1e
|
||||
F src/tclsqlite.c b290774586f022e16e04ba8ed2f0b8edd86b5b77
|
||||
F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
|
||||
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
|
||||
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
@@ -250,11 +251,11 @@ F src/test8.c 610e3d523018ca63b08081795e76794a2121ec38
|
||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
||||
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
|
||||
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
|
||||
F src/test_blob.c 1f2e3e25255b731c4fcf15ee7990d06347cb6c09
|
||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||
F src/test_config.c e7b2e1634324d746aa5e1c7e0929470e8be27953
|
||||
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
|
||||
F src/test_config.c c2d3ff6c129d50183900c7eff14158ff7e9b3f03
|
||||
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
|
||||
F src/test_func.c 14e543ae4d905ee31dc322b2f8d31bfac1769d45
|
||||
@@ -265,7 +266,7 @@ F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
||||
F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa
|
||||
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
|
||||
F src/test_malloc.c b9495384e74923aefde8311de974bf9b0f5ba570
|
||||
F src/test_multiplex.c 72c0ad1e97af3d6d19975bbd81813072b40c7290
|
||||
F src/test_multiplex.c 61edf02530f7511a0529352cd8139ead3af4c401
|
||||
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
|
||||
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
|
||||
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
|
||||
@@ -273,12 +274,12 @@ F src/test_osinst.c 3d0340bc31a9f3d8a3547e0272373e80f78dde25
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d
|
||||
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
|
||||
F src/test_rtree.c fdd8d29ca5165c7857987a2ba263fac5c69e231f
|
||||
F src/test_rtree.c bfe6f4386517f70054311109f3528adffec34485
|
||||
F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c b690c12933f50ff46491e0d56a251f84ae16e914
|
||||
F src/test_stat.c 9898687a6c2beca733b0dd6fe19163d987826d31
|
||||
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
|
||||
F src/test_stat.c ffc8177f6e69de32a8a89fa6bca73facb6c5face
|
||||
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
||||
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
||||
@@ -286,27 +287,28 @@ F src/test_vfs.c 5a14c63da9579ba148138c1fb233100f2eb58ebb
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c e00458c9938072b0ea711c850b8dcf4ddcb5fe18
|
||||
F src/tokenize.c 05e52378c46efbc1fd63cbbbf7f3c555f840f4bf
|
||||
F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f
|
||||
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
|
||||
F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c
|
||||
F src/vdbe.c ddfc977981cd6324668aa6b114045eb1c677421a
|
||||
F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec
|
||||
F src/vdbe.c 94cbc2115075b1a562a2a702c29ba48e74f85d34
|
||||
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
|
||||
F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
|
||||
F src/vdbeapi.c 4bc511a46b9839392ae0e90844a71dc96d9dbd71
|
||||
F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a
|
||||
F src/vdbeapi.c 1295402cabda4473ddee24955c8f7039514497e4
|
||||
F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5
|
||||
F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
|
||||
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
|
||||
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
|
||||
F src/vdbemem.c d52fa9f3bcf75d27d7b7846d81ee7898829c763d
|
||||
F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9
|
||||
F src/wal.c 85353539f2d9d0c91ebd057c32525b1e1aa3335e
|
||||
F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c d46de821bc604a4fd36fa3928c086950e91aafb1
|
||||
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
|
||||
F src/where.c eb141b075776e9864d38f279333e2472a8653202
|
||||
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
||||
@@ -319,7 +321,7 @@ F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
|
||||
F test/analyze3.test bf41f0f680dd1e0d44eed5e769531e93a5320275
|
||||
F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
||||
@@ -331,6 +333,7 @@ F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d
|
||||
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
|
||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||
F test/analyzeF.test 299a47183c648d8ad92671f313def8fd7cb09875
|
||||
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
||||
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
@@ -346,10 +349,10 @@ F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360
|
||||
F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
|
||||
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
|
||||
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
|
||||
F test/autoindex1.test 7008c9f604141fdabe31b7bb95b5ff31b518251f
|
||||
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
@@ -385,7 +388,7 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test f0718f4f90d0efdc980119bfbdf1d7f1541ee5ef
|
||||
F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2
|
||||
F test/capi3d.test a82b6321c50a1cfc848e386fa2c851893606f68c
|
||||
@@ -402,7 +405,7 @@ F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177
|
||||
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
|
||||
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
|
||||
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
|
||||
F test/collate8.test df26649cfcbddf109c04122b340301616d3a88f6
|
||||
F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334
|
||||
F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
|
||||
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
||||
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||
@@ -469,7 +472,7 @@ F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
|
||||
F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad
|
||||
F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707
|
||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test 7b2fa9cd1456f83474d6c5d27db3abaeb8be2023
|
||||
F test/e_insert.test 0e63edc037afe738bb81a626a676811ed7862c90
|
||||
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
|
||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||
F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
|
||||
@@ -478,7 +481,7 @@ F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||
F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52
|
||||
F test/e_uri.test 5ae33760fb2039c61aa2d90886f1664664173585
|
||||
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
|
||||
F test/e_wal.test 0967f0b8f1dfda871dc7b9b5574198f1f4f7d69a
|
||||
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||
F test/e_walauto.test ca70cf75c07a6cb1874ced101dd426da76625649
|
||||
F test/e_walckpt.test 65e29b6631e51f210f83e4ff11571e647ba93608
|
||||
F test/e_walhook.test da3ea8b3483d1af72190337bda50155a91a4b664
|
||||
@@ -502,7 +505,7 @@ F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
|
||||
F test/fkey2.test 1db212cda86b0d3ce72714001f7b6381c321341c
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 488601fbda8350619b3029487e56830447056fd2
|
||||
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
|
||||
F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48
|
||||
F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
|
||||
F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0
|
||||
@@ -630,19 +633,20 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
F test/hexlit.test f9ecde8145bfc2341573473256c74ae37a200497
|
||||
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
|
||||
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
F test/in5.test 1de657472fa9ac2924be25c2c959ac5ca1aae554
|
||||
F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328
|
||||
F test/incrblob2.test bf4d549aa4a466d7fbe3e3a3693d3861263d5600
|
||||
F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab
|
||||
F test/incrblob_err.test af1f12ba60d220c9752073ff2bda2ad59e88960d
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b
|
||||
F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac
|
||||
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test 4d990005a67a36984e4f1a5f1bdccea8d08da4ee
|
||||
@@ -650,12 +654,11 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test 55a90cff99834305e8141df7afaef39674b57062
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
|
||||
F test/index6.test fb370966ac3cd0989053dd5385757b5c3e24ab6a
|
||||
F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b
|
||||
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
|
||||
F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
|
||||
F test/index7.test 3d54dce09344c4530ea39a458aa304da044c887a
|
||||
F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/initmode.test 38bbaefeb47e034a162856e664a0da3b95e6999b
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
@@ -687,12 +690,13 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991
|
||||
F test/like.test 4f2a71d36a536233727f71995fef900756705e56
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/limit.test 3d7df19c35ac672a11f7de406cd3205d592babbb
|
||||
F test/like3.test 7b0525a39e4f25c4fd113de7e2e28eb712dcdedf
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
|
||||
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
|
||||
F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
|
||||
F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5
|
||||
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
||||
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
|
||||
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
|
||||
@@ -706,7 +710,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test 96939d2d1a6f39667bbebe5bc27c6525f2ab614e
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
|
||||
F test/malloc5.test 79182b8bffd6d62f77b1a5a8ba8e6bf0e5053b8e
|
||||
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
|
||||
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
|
||||
@@ -751,7 +755,7 @@ F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
|
||||
F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
F test/multiplex4.test d3e8a5a522c51cbf3ed1c5b0bd496be02c29d7b1
|
||||
F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
|
||||
F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
|
||||
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
||||
F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a
|
||||
@@ -786,8 +790,8 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1
|
||||
F test/pragma.test aa16dedfe01c02c8895169012f7dfde9c163f0d5
|
||||
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
|
||||
F test/pragma.test ad99d05e411c7687302124be56f3b362204be041
|
||||
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
|
||||
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a
|
||||
@@ -801,7 +805,7 @@ F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
|
||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
|
||||
F test/rdonly.test dd30a4858d8e0fbad2304c2bd74a33d4df36412a
|
||||
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl 13f401c10dd4fe1a2fb811ae6ed27fd7d1300d3c
|
||||
@@ -831,9 +835,9 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||
F test/select4.test 8c5a60d439e2df824aed56223566877a883c5c84
|
||||
F test/select4.test e20e8ce47b558de80616102ef273704cf0d48a3b
|
||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2
|
||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
|
||||
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
|
||||
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
|
||||
@@ -857,14 +861,14 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test cdeb849acc2c37aada70d084564b0cc0a2c7df08
|
||||
F test/shell1.test ca88b14a8fc8b1f3543a24e519d019585ac9c903
|
||||
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
|
||||
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
|
||||
F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
|
||||
F test/shell5.test 81aba4793fa7441b1300daae1aec4f7e4b5741c1
|
||||
F test/shell5.test c04e9f9f948305706b88377c464c7f08ce7479f9
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||
F test/shrink.test 06deac10d591186017466ce67d10645150bfdeec
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test 2ddfe5d168462170c4487f534e2a99fb006b2076
|
||||
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
@@ -872,11 +876,11 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
|
||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
||||
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
|
||||
F test/sort.test 3f492e5b7be1d3f756728d2ff6edf4f6091e84cb
|
||||
F test/sort2.test 37afbc03f5559f2eb0f18940b55d38dfbb5172ac
|
||||
F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2
|
||||
F test/sort4.test d5e8903194ae551551349ce25dc8d0b40ca2b9c3
|
||||
F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c
|
||||
F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f
|
||||
F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66
|
||||
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
|
||||
@@ -887,9 +891,9 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c e4e2aa37ff66bad9f414a50a8cb9edfaac65c9e5
|
||||
F test/speedtest1.c 2b416dca3a155fcaa849540b2e7fc1df12896c23
|
||||
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
|
||||
F test/sqllimits1.test 9014524e7ab16e2a4976b13397db4c29cc29c6d9
|
||||
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
|
||||
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9
|
||||
@@ -1127,7 +1131,7 @@ F test/wal.test 885f32b2b390b30b4aa3dbb0e568f8f78d40f5cc
|
||||
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
|
||||
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 11b8658dd4d5448f4604124bebd9b68be5bc3e66
|
||||
F test/wal5.test 88b5d9a6a3d1532497ee9f4296f010d66f07e33c
|
||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
@@ -1156,7 +1160,7 @@ F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
|
||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
|
||||
F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1
|
||||
F test/where8.test 2eafe74e01cc10355985874e1ff868ac03dbae5e
|
||||
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
|
||||
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
|
||||
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
|
||||
@@ -1202,10 +1206,10 @@ F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
|
||||
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl 07a5124cf2dbafa1b375eefcf8ac4227028b0f8b
|
||||
F tool/mkpragmatab.tcl 94f196c9961e0ca3513e29f57125a3197808be2d
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 9ef48e1748dce7b844f67e2450ff9dfeb0fb4ab5
|
||||
F tool/mksqlite3c.tcl cfde806851c413db7689b9cb74a4eeb92539c601
|
||||
F tool/mksqlite3c.tcl 95ab31eda659e7ffb091e04bd83178f260d8edfd
|
||||
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105
|
||||
@@ -1221,7 +1225,7 @@ F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
|
||||
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
|
||||
F tool/spaceanal.tcl 8e50b217c56a6a086a1b47eac9d09c5cd65b996f
|
||||
F tool/spaceanal.tcl d5a09620c66a6c144576cb9d2bdfa9a6fbe362a5
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
@@ -1238,7 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 5940af8e7872209ce41feb958643b23f7e55d258
|
||||
R 47cbd38aaccdc229ecba207f260cbca2
|
||||
P 93f42586cc9db63c5a4599ce06630e60204a5bc9
|
||||
R b3d39823270cf35170812e8663c1c07d
|
||||
U drh
|
||||
Z f10513d756c3deb9c12d56e187b46090
|
||||
Z b97bd037eac2f46713c8bf83215d5d81
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
3a6e2afe408d2b0c8166d00def2048568169d87a
|
||||
a991bb1a9eb54bdbd45bd623e8b304bdfeb481a3
|
||||
@@ -32,6 +32,7 @@
|
||||
--end
|
||||
--wait 1
|
||||
--task 2
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t2 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
@@ -46,6 +47,7 @@
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 3
|
||||
DROP TABLE IF EXISTS t3;
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t3 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
@@ -60,6 +62,7 @@
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 4
|
||||
DROP TABLE IF EXISTS t4;
|
||||
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t4 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
@@ -74,6 +77,7 @@
|
||||
--match 29 28 27 26 25
|
||||
--end
|
||||
--task 5
|
||||
DROP TABLE IF EXISTS t5;
|
||||
CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t5 SELECT a, b FROM t1;
|
||||
UPDATE t1 SET b='x'||a||'y';
|
||||
|
||||
+17
-4
@@ -1262,6 +1262,9 @@ int main(int argc, char **argv){
|
||||
int taskId;
|
||||
const char *zTrace;
|
||||
const char *zCOption;
|
||||
const char *zJMode;
|
||||
const char *zNRep;
|
||||
int nRep = 1, iRep;
|
||||
|
||||
g.argv0 = argv[0];
|
||||
g.iTrace = 1;
|
||||
@@ -1277,6 +1280,10 @@ int main(int argc, char **argv){
|
||||
}
|
||||
n = argc-2;
|
||||
sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID());
|
||||
zJMode = findOption(argv+2, &n, "journalmode", 1);
|
||||
zNRep = findOption(argv+2, &n, "repeat", 1);
|
||||
if( zNRep ) nRep = atoi(zNRep);
|
||||
if( nRep<1 ) nRep = 1;
|
||||
g.zVfs = findOption(argv+2, &n, "vfs", 1);
|
||||
zClient = findOption(argv+2, &n, "client", 1);
|
||||
g.zErrLog = findOption(argv+2, &n, "errlog", 1);
|
||||
@@ -1348,7 +1355,11 @@ int main(int argc, char **argv){
|
||||
fatalError("missing script filename");
|
||||
}
|
||||
if( n>1 ) unrecognizedArguments(argv[0], n, argv+2);
|
||||
if( zJMode ) runSql("PRAGMA journal_mode=%Q;", zJMode);
|
||||
runSql(
|
||||
"DROP TABLE IF EXISTS task;\n"
|
||||
"DROP TABLE IF EXISTS counters;\n"
|
||||
"DROP TABLE IF EXISTS client;\n"
|
||||
"CREATE TABLE task(\n"
|
||||
" id INTEGER PRIMARY KEY,\n"
|
||||
" name TEXT,\n"
|
||||
@@ -1364,10 +1375,12 @@ int main(int argc, char **argv){
|
||||
"CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n"
|
||||
);
|
||||
zScript = readFile(argv[2]);
|
||||
if( g.iTrace ) logMessage("begin script [%s]\n", argv[2]);
|
||||
runScript(0, 0, zScript, argv[2]);
|
||||
for(iRep=1; iRep<=nRep; iRep++){
|
||||
if( g.iTrace ) logMessage("begin script [%s] cycle %d\n", argv[2], iRep);
|
||||
runScript(0, 0, zScript, argv[2]);
|
||||
if( g.iTrace ) logMessage("end script [%s] cycle %d\n", argv[2], iRep);
|
||||
}
|
||||
sqlite3_free(zScript);
|
||||
if( g.iTrace ) logMessage("end script [%s]\n", argv[2]);
|
||||
waitForClient(0, 2000, "during shutdown...\n");
|
||||
trySql("UPDATE client SET wantHalt=1");
|
||||
sqlite3_sleep(10);
|
||||
@@ -1391,7 +1404,7 @@ int main(int argc, char **argv){
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
sqlite3_close(g.db);
|
||||
sqlite3_close(g.db);
|
||||
maybeClose(g.pLog);
|
||||
maybeClose(g.pErrLog);
|
||||
if( iClient==0 ){
|
||||
|
||||
@@ -361,6 +361,8 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 5
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -371,6 +373,8 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 3
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -381,6 +385,8 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 2
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -391,6 +397,8 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--task 4
|
||||
SELECT t1.a FROM t1, t2
|
||||
@@ -401,5 +409,7 @@ PRAGMA integrity_check(10);
|
||||
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
|
||||
ORDER BY t3.a LIMIT 7
|
||||
--match 45 46 47 48 49 50 51
|
||||
PRAGMA integrity_check;
|
||||
--match ok
|
||||
--end
|
||||
--wait all
|
||||
|
||||
+4
-1
@@ -690,7 +690,10 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
*/
|
||||
if( pDflt ){
|
||||
sqlite3_value *pVal = 0;
|
||||
if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
|
||||
int rc;
|
||||
rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal);
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
|
||||
if( rc!=SQLITE_OK ){
|
||||
db->mallocFailed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ static void attachFunc(
|
||||
case SQLITE_NULL:
|
||||
/* No key specified. Use the key from the main database */
|
||||
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
|
||||
if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
|
||||
if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
|
||||
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -247,7 +247,7 @@ static int backupOnePage(
|
||||
** guaranteed that the shared-mutex is held by this thread, handle
|
||||
** p->pSrc may not actually be the owner. */
|
||||
int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
|
||||
int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
|
||||
int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
|
||||
#endif
|
||||
int rc = SQLITE_OK;
|
||||
i64 iOff;
|
||||
|
||||
+22
-7
@@ -175,6 +175,12 @@ static int hasSharedCacheTableLock(
|
||||
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
|
||||
Index *pIdx = (Index *)sqliteHashData(p);
|
||||
if( pIdx->tnum==(int)iRoot ){
|
||||
if( iTab ){
|
||||
/* Two or more indexes share the same root page. There must
|
||||
** be imposter tables. So just return true. The assert is not
|
||||
** useful in that case. */
|
||||
return 1;
|
||||
}
|
||||
iTab = pIdx->pTable->tnum;
|
||||
}
|
||||
}
|
||||
@@ -2399,6 +2405,9 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
|
||||
BtShared *pBt = p->pBt;
|
||||
assert( nReserve>=-1 && nReserve<=255 );
|
||||
sqlite3BtreeEnter(p);
|
||||
#if SQLITE_HAS_CODEC
|
||||
if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
|
||||
#endif
|
||||
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
|
||||
sqlite3BtreeLeave(p);
|
||||
return SQLITE_READONLY;
|
||||
@@ -2428,7 +2437,6 @@ int sqlite3BtreeGetPageSize(Btree *p){
|
||||
return p->pBt->pageSize;
|
||||
}
|
||||
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
|
||||
/*
|
||||
** This function is similar to sqlite3BtreeGetReserve(), except that it
|
||||
** may only be called if it is guaranteed that the b-tree mutex is already
|
||||
@@ -2441,25 +2449,33 @@ int sqlite3BtreeGetPageSize(Btree *p){
|
||||
** database handle that owns *p, causing undefined behavior.
|
||||
*/
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p){
|
||||
int n;
|
||||
assert( sqlite3_mutex_held(p->pBt->mutex) );
|
||||
return p->pBt->pageSize - p->pBt->usableSize;
|
||||
n = p->pBt->pageSize - p->pBt->usableSize;
|
||||
return n;
|
||||
}
|
||||
#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
|
||||
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
|
||||
/*
|
||||
** Return the number of bytes of space at the end of every page that
|
||||
** are intentually left unused. This is the "reserved" space that is
|
||||
** sometimes used by extensions.
|
||||
**
|
||||
** If SQLITE_HAS_MUTEX is defined then the number returned is the
|
||||
** greater of the current reserved space and the maximum requested
|
||||
** reserve space.
|
||||
*/
|
||||
int sqlite3BtreeGetReserve(Btree *p){
|
||||
int sqlite3BtreeGetOptimalReserve(Btree *p){
|
||||
int n;
|
||||
sqlite3BtreeEnter(p);
|
||||
n = p->pBt->pageSize - p->pBt->usableSize;
|
||||
n = sqlite3BtreeGetReserveNoMutex(p);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
|
||||
#endif
|
||||
sqlite3BtreeLeave(p);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Set the maximum page count for a database if mxPage is positive.
|
||||
** No changes are made if mxPage is 0 or negative.
|
||||
@@ -2490,7 +2506,6 @@ int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
|
||||
sqlite3BtreeLeave(p);
|
||||
return b;
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
|
||||
|
||||
/*
|
||||
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
|
||||
|
||||
+1
-3
@@ -73,10 +73,8 @@ int sqlite3BtreeGetPageSize(Btree*);
|
||||
int sqlite3BtreeMaxPageCount(Btree*,int);
|
||||
u32 sqlite3BtreeLastPage(Btree*);
|
||||
int sqlite3BtreeSecureDelete(Btree*,int);
|
||||
int sqlite3BtreeGetReserve(Btree*);
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
|
||||
int sqlite3BtreeGetOptimalReserve(Btree*);
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
||||
#endif
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
int sqlite3BtreeBeginTrans(Btree*,int);
|
||||
|
||||
@@ -418,6 +418,9 @@ struct BtShared {
|
||||
#endif
|
||||
u8 inTransaction; /* Transaction state */
|
||||
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
u8 optimalReserve; /* Desired amount of reserved space per page */
|
||||
#endif
|
||||
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
|
||||
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
|
||||
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
||||
|
||||
+7
-8
@@ -308,10 +308,6 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
Table *p = 0;
|
||||
int i;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return 0;
|
||||
#endif
|
||||
|
||||
/* All mutexes are required for schema access. Make sure we hold them. */
|
||||
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
@@ -1731,11 +1727,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
assert( pPk!=0 );
|
||||
nPk = pPk->nKeyCol;
|
||||
|
||||
/* Make sure every column of the PRIMARY KEY is NOT NULL */
|
||||
for(i=0; i<nPk; i++){
|
||||
pTab->aCol[pPk->aiColumn[i]].notNull = 1;
|
||||
/* Make sure every column of the PRIMARY KEY is NOT NULL. (Except,
|
||||
** do not enforce this for imposter tables.) */
|
||||
if( !db->init.imposterTable ){
|
||||
for(i=0; i<nPk; i++){
|
||||
pTab->aCol[pPk->aiColumn[i]].notNull = 1;
|
||||
}
|
||||
pPk->uniqNotNull = 1;
|
||||
}
|
||||
pPk->uniqNotNull = 1;
|
||||
|
||||
/* The root page of the PRIMARY KEY is the table root page */
|
||||
pPk->tnum = pTab->tnum;
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ Expr *sqlite3LimitWhere(
|
||||
|
||||
pInClause->x.pSelect = pSelect;
|
||||
pInClause->flags |= EP_xIsSelect;
|
||||
sqlite3ExprSetHeight(pParse, pInClause);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pInClause);
|
||||
return pInClause;
|
||||
|
||||
/* something went wrong. clean up anything allocated. */
|
||||
|
||||
+56
-10
@@ -146,10 +146,25 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
break;
|
||||
}
|
||||
if( p->flags & EP_Collate ){
|
||||
if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
|
||||
if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
|
||||
p = p->pLeft;
|
||||
}else{
|
||||
p = p->pRight;
|
||||
Expr *pNext = p->pRight;
|
||||
/* The Expr.x union is never used at the same time as Expr.pRight */
|
||||
assert( p->x.pList==0 || p->pRight==0 );
|
||||
/* p->flags holds EP_Collate and p->pLeft->flags does not. And
|
||||
** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
|
||||
** least one EP_Collate. Thus the following two ALWAYS. */
|
||||
if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
|
||||
int i;
|
||||
for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
|
||||
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
|
||||
pNext = p->x.pList->a[i].pExpr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
p = pNext;
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
@@ -355,6 +370,9 @@ static void heightOfSelect(Select *p, int *pnHeight){
|
||||
** Expr.pSelect member has a height of 1. Any other expression
|
||||
** has a height equal to the maximum height of any other
|
||||
** referenced Expr plus one.
|
||||
**
|
||||
** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
|
||||
** if appropriate.
|
||||
*/
|
||||
static void exprSetHeight(Expr *p){
|
||||
int nHeight = 0;
|
||||
@@ -362,8 +380,9 @@ static void exprSetHeight(Expr *p){
|
||||
heightOfExpr(p->pRight, &nHeight);
|
||||
if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
heightOfSelect(p->x.pSelect, &nHeight);
|
||||
}else{
|
||||
}else if( p->x.pList ){
|
||||
heightOfExprList(p->x.pList, &nHeight);
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
p->nHeight = nHeight + 1;
|
||||
}
|
||||
@@ -372,8 +391,11 @@ static void exprSetHeight(Expr *p){
|
||||
** Set the Expr.nHeight variable using the exprSetHeight() function. If
|
||||
** the height is greater than the maximum allowed expression depth,
|
||||
** leave an error in pParse.
|
||||
**
|
||||
** Also propagate all EP_Propagate flags from the Expr.x.pList into
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
exprSetHeight(p);
|
||||
sqlite3ExprCheckHeight(pParse, p->nHeight);
|
||||
}
|
||||
@@ -387,8 +409,17 @@ int sqlite3SelectExprHeight(Select *p){
|
||||
heightOfSelect(p, &nHeight);
|
||||
return nHeight;
|
||||
}
|
||||
#else
|
||||
#define exprSetHeight(y)
|
||||
#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */
|
||||
/*
|
||||
** Propagate all EP_Propagate flags from the Expr.x.pList into
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
}
|
||||
#define exprSetHeight(y)
|
||||
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
||||
|
||||
/*
|
||||
@@ -490,11 +521,11 @@ void sqlite3ExprAttachSubtrees(
|
||||
}else{
|
||||
if( pRight ){
|
||||
pRoot->pRight = pRight;
|
||||
pRoot->flags |= EP_Collate & pRight->flags;
|
||||
pRoot->flags |= EP_Propagate & pRight->flags;
|
||||
}
|
||||
if( pLeft ){
|
||||
pRoot->pLeft = pLeft;
|
||||
pRoot->flags |= EP_Collate & pLeft->flags;
|
||||
pRoot->flags |= EP_Propagate & pLeft->flags;
|
||||
}
|
||||
exprSetHeight(pRoot);
|
||||
}
|
||||
@@ -594,7 +625,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
||||
}
|
||||
pNew->x.pList = pList;
|
||||
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
|
||||
sqlite3ExprSetHeight(pParse, pNew);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pNew);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
@@ -1209,6 +1240,21 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the bitwise-OR of all Expr.flags fields in the given
|
||||
** ExprList.
|
||||
*/
|
||||
u32 sqlite3ExprListFlags(const ExprList *pList){
|
||||
int i;
|
||||
u32 m = 0;
|
||||
if( pList ){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
m |= pList->a[i].pExpr->flags;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
** These routines are Walker callbacks used to check expressions to
|
||||
** see if they are "constant" for some definition of constant. The
|
||||
@@ -1249,7 +1295,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
** and either pWalker->eCode==4 or 5 or the function has the
|
||||
** SQLITE_FUNC_CONST flag. */
|
||||
case TK_FUNCTION:
|
||||
if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){
|
||||
if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
|
||||
return WRC_Continue;
|
||||
}else{
|
||||
pWalker->eCode = 0;
|
||||
|
||||
+16
-1
@@ -22,7 +22,9 @@
|
||||
** Return the collating function associated with a function.
|
||||
*/
|
||||
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
|
||||
VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
|
||||
VdbeOp *pOp;
|
||||
assert( context->pVdbe!=0 );
|
||||
pOp = &context->pVdbe->aOp[context->iOp-1];
|
||||
assert( pOp->opcode==OP_CollSeq );
|
||||
assert( pOp->p4type==P4_COLLSEQ );
|
||||
return pOp->p4.pColl;
|
||||
@@ -291,6 +293,14 @@ static void substrFunc(
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef SQLITE_SUBSTR_COMPATIBILITY
|
||||
/* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
|
||||
** as substr(X,1,N) - it returns the first N characters of X. This
|
||||
** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
|
||||
** from 2009-02-02 for compatibility of applications that exploited the
|
||||
** old buggy behavior. */
|
||||
if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
|
||||
#endif
|
||||
if( argc==3 ){
|
||||
p2 = sqlite3_value_int(argv[2]);
|
||||
if( p2<0 ){
|
||||
@@ -1642,6 +1652,11 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
||||
** then set aWc[0] through aWc[2] to the wildcard characters and
|
||||
** return TRUE. If the function is not a LIKE-style function then
|
||||
** return FALSE.
|
||||
**
|
||||
** *pIsNocase is set to true if uppercase and lowercase are equivalent for
|
||||
** the function (default for LIKE). If the function makes the distinction
|
||||
** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
|
||||
** false.
|
||||
*/
|
||||
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||
FuncDef *pDef;
|
||||
|
||||
+5
-5
@@ -46,16 +46,16 @@ const unsigned char sqlite3UpperToLower[] = {
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
|
||||
96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
|
||||
112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
|
||||
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
|
||||
192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
|
||||
208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
|
||||
224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
|
||||
239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
|
||||
224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+67
-22
@@ -340,26 +340,28 @@ int sqlite3_config(int op, ...){
|
||||
*/
|
||||
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */
|
||||
case SQLITE_CONFIG_SINGLETHREAD: {
|
||||
/* Disable all mutexing */
|
||||
sqlite3GlobalConfig.bCoreMutex = 0;
|
||||
sqlite3GlobalConfig.bFullMutex = 0;
|
||||
/* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to
|
||||
** Single-thread. */
|
||||
sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */
|
||||
sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
|
||||
case SQLITE_CONFIG_MULTITHREAD: {
|
||||
/* Disable mutexing of database connections */
|
||||
/* Enable mutexing of core data structures */
|
||||
sqlite3GlobalConfig.bCoreMutex = 1;
|
||||
sqlite3GlobalConfig.bFullMutex = 0;
|
||||
/* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to
|
||||
** Multi-thread. */
|
||||
sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
|
||||
sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
|
||||
case SQLITE_CONFIG_SERIALIZED: {
|
||||
/* Enable all mutexing */
|
||||
sqlite3GlobalConfig.bCoreMutex = 1;
|
||||
sqlite3GlobalConfig.bFullMutex = 1;
|
||||
/* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to
|
||||
** Serialized. */
|
||||
sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
|
||||
sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -471,7 +473,8 @@ int sqlite3_config(int op, ...){
|
||||
case SQLITE_CONFIG_HEAP: {
|
||||
/* EVIDENCE-OF: R-19854-42126 There are three arguments to
|
||||
** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the
|
||||
** number of bytes in the memory buffer, and the minimum allocation size. */
|
||||
** number of bytes in the memory buffer, and the minimum allocation size.
|
||||
*/
|
||||
sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
|
||||
sqlite3GlobalConfig.nHeap = va_arg(ap, int);
|
||||
sqlite3GlobalConfig.mnReq = va_arg(ap, int);
|
||||
@@ -576,7 +579,9 @@ int sqlite3_config(int op, ...){
|
||||
** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
|
||||
** compile-time option.
|
||||
*/
|
||||
if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ) mxMmap = SQLITE_MAX_MMAP_SIZE;
|
||||
if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){
|
||||
mxMmap = SQLITE_MAX_MMAP_SIZE;
|
||||
}
|
||||
if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
|
||||
if( szMmap>mxMmap) szMmap = mxMmap;
|
||||
sqlite3GlobalConfig.mxMmap = mxMmap;
|
||||
@@ -1414,7 +1419,7 @@ int sqlite3_busy_handler(
|
||||
void *pArg
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE;
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->busyHandler.xFunc = xBusy;
|
||||
@@ -1966,6 +1971,7 @@ int sqlite3_wal_checkpoint_v2(
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
|
||||
}else{
|
||||
db->busyHandler.nBusy = 0;
|
||||
rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
|
||||
sqlite3Error(db, rc);
|
||||
}
|
||||
@@ -2419,7 +2425,19 @@ int sqlite3ParseUri(
|
||||
if( !zFile ) return SQLITE_NOMEM;
|
||||
|
||||
iIn = 5;
|
||||
#ifndef SQLITE_ALLOW_URI_AUTHORITY
|
||||
#ifdef SQLITE_ALLOW_URI_AUTHORITY
|
||||
if( strncmp(zUri+5, "///", 3)==0 ){
|
||||
iIn = 7;
|
||||
/* The following condition causes URIs with five leading / characters
|
||||
** like file://///host/path to be converted into UNCs like //host/path.
|
||||
** The correct URI for that UNC has only two or four leading / characters
|
||||
** file://host/path or file:////host/path. But 5 leading slashes is a
|
||||
** common error, we are told, so we handle it as a special case. */
|
||||
if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; }
|
||||
}else if( strncmp(zUri+5, "//localhost/", 12)==0 ){
|
||||
iIn = 16;
|
||||
}
|
||||
#else
|
||||
/* Discard the scheme and authority segments of the URI. */
|
||||
if( zUri[5]=='/' && zUri[6]=='/' ){
|
||||
iIn = 7;
|
||||
@@ -2706,6 +2724,9 @@ static int openDatabase(
|
||||
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
|
||||
| SQLITE_AutoIndex
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||
| SQLITE_CkptFullFSync
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_FILE_FORMAT<4
|
||||
| SQLITE_LegacyFileFmt
|
||||
#endif
|
||||
@@ -2859,7 +2880,8 @@ static int openDatabase(
|
||||
opendb_out:
|
||||
sqlite3_free(zOpen);
|
||||
if( db ){
|
||||
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
|
||||
assert( db->mutex!=0 || isThreadsafe==0
|
||||
|| sqlite3GlobalConfig.bFullMutex==0 );
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
}
|
||||
rc = sqlite3_errcode(db);
|
||||
@@ -3141,13 +3163,19 @@ int sqlite3_table_column_metadata(
|
||||
Table *pTab = 0;
|
||||
Column *pCol = 0;
|
||||
int iCol = 0;
|
||||
|
||||
char const *zDataType = 0;
|
||||
char const *zCollSeq = 0;
|
||||
int notnull = 0;
|
||||
int primarykey = 0;
|
||||
int autoinc = 0;
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Ensure the database schema has been loaded */
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3BtreeEnterAll(db);
|
||||
@@ -3294,7 +3322,7 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3598,15 +3626,32 @@ int sqlite3_test_control(int op, ...){
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_INITMODE, db, busy, iDb, newTnum);
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum);
|
||||
**
|
||||
** Set the db->init.busy, db->init.iDb, and db->init.tnum fields.
|
||||
** This test control is used to create imposter tables. "db" is a pointer
|
||||
** to the database connection. dbName is the database name (ex: "main" or
|
||||
** "temp") which will receive the imposter. "onOff" turns imposter mode on
|
||||
** or off. "tnum" is the root page of the b-tree to which the imposter
|
||||
** table should connect.
|
||||
**
|
||||
** Enable imposter mode only when the schema has already been parsed. Then
|
||||
** run a single CREATE TABLE statement to construct the imposter table in
|
||||
** the parsed schema. Then turn imposter mode back off again.
|
||||
**
|
||||
** If onOff==0 and tnum>0 then reset the schema for all databases, causing
|
||||
** the schema to be reparsed the next time it is needed. This has the
|
||||
** effect of erasing all imposter tables.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_INITMODE: {
|
||||
case SQLITE_TESTCTRL_IMPOSTER: {
|
||||
sqlite3 *db = va_arg(ap, sqlite3*);
|
||||
db->init.busy = va_arg(ap,int);
|
||||
db->init.iDb = va_arg(ap,int);
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
|
||||
db->init.busy = db->init.imposterTable = va_arg(ap,int);
|
||||
db->init.newTnum = va_arg(ap,int);
|
||||
if( db->init.busy==0 && db->init.newTnum>0 ){
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-4
@@ -120,8 +120,12 @@ static sqlite3_mutex *debugMutexAlloc(int id){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assert( id-2 >= 0 );
|
||||
assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( id-2<0 || id-2>=ArraySize(aStatic) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
pNew = &aStatic[id-2];
|
||||
pNew->id = id;
|
||||
break;
|
||||
@@ -136,8 +140,13 @@ static sqlite3_mutex *debugMutexAlloc(int id){
|
||||
static void debugMutexFree(sqlite3_mutex *pX){
|
||||
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
|
||||
assert( p->cnt==0 );
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
sqlite3_free(p);
|
||||
if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+18
-13
@@ -40,8 +40,10 @@
|
||||
*/
|
||||
struct sqlite3_mutex {
|
||||
pthread_mutex_t mutex; /* Mutex controlling the lock */
|
||||
#if SQLITE_MUTEX_NREF
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
int id; /* Mutex type */
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
volatile int nRef; /* Number of entrances */
|
||||
volatile pthread_t owner; /* Thread that is within this mutex */
|
||||
int trace; /* True to trace changes */
|
||||
@@ -157,9 +159,6 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&p->mutex, &recursiveAttr);
|
||||
pthread_mutexattr_destroy(&recursiveAttr);
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -167,9 +166,6 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
case SQLITE_MUTEX_FAST: {
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
pthread_mutex_init(&p->mutex, 0);
|
||||
}
|
||||
break;
|
||||
@@ -182,12 +178,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
}
|
||||
#endif
|
||||
p = &staticMutexes[iType-2];
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
if( p ) p->id = iType;
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -199,9 +195,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
*/
|
||||
static void pthreadMutexFree(sqlite3_mutex *p){
|
||||
assert( p->nRef==0 );
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
pthread_mutex_destroy(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE )
|
||||
#endif
|
||||
{
|
||||
pthread_mutex_destroy(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
else{
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+9
-10
@@ -194,8 +194,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
case SQLITE_MUTEX_RECURSIVE: {
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
|
||||
p->trace = 1;
|
||||
#endif
|
||||
@@ -215,12 +215,9 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
assert( iType-2 >= 0 );
|
||||
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
|
||||
assert( winMutex_isInit==1 );
|
||||
p = &winMutex_staticMutexes[iType-2];
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
|
||||
p->trace = 1;
|
||||
#endif
|
||||
@@ -239,13 +236,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
*/
|
||||
static void winMutexFree(sqlite3_mutex *p){
|
||||
assert( p );
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( p->nRef==0 && p->owner==0 );
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( winMutex_isInit==1 );
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+155
-148
@@ -71,18 +71,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Define the OS_VXWORKS pre-processor macro to 1 if building on
|
||||
** vxworks, or 0 otherwise.
|
||||
*/
|
||||
#ifndef OS_VXWORKS
|
||||
# if defined(__RTP__) || defined(_WRS_KERNEL)
|
||||
# define OS_VXWORKS 1
|
||||
# else
|
||||
# define OS_VXWORKS 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** standard include files.
|
||||
*/
|
||||
@@ -97,18 +85,19 @@
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
# include <sys/ioctl.h>
|
||||
# if OS_VXWORKS
|
||||
# include <semaphore.h>
|
||||
# include <limits.h>
|
||||
# else
|
||||
# include <sys/file.h>
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# include <sys/file.h>
|
||||
# include <sys/param.h>
|
||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||
|
||||
#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
||||
#if OS_VXWORKS
|
||||
# include <sys/ioctl.h>
|
||||
# include <semaphore.h>
|
||||
# include <limits.h>
|
||||
#endif /* OS_VXWORKS */
|
||||
|
||||
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
|
||||
# include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
@@ -149,6 +138,10 @@
|
||||
*/
|
||||
#define MAX_PATHNAME 512
|
||||
|
||||
/* Always cast the getpid() return type for compatibility with
|
||||
** kernel modules in VxWorks. */
|
||||
#define osGetpid(X) (pid_t)getpid()
|
||||
|
||||
/*
|
||||
** Only set the lastErrno if the error code is a real error and not
|
||||
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
|
||||
@@ -237,7 +230,7 @@ struct unixFile {
|
||||
** method was called. If xOpen() is called from a different process id,
|
||||
** indicating that a fork() has occurred, the PRNG will be reset.
|
||||
*/
|
||||
static int randomnessPid = 0;
|
||||
static pid_t randomnessPid = 0;
|
||||
|
||||
/*
|
||||
** Allowed values for the unixFile.ctrlFlags bitmask:
|
||||
@@ -254,7 +247,7 @@ static int randomnessPid = 0;
|
||||
#define UNIXFILE_DELETE 0x20 /* Delete on close */
|
||||
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
|
||||
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
|
||||
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
|
||||
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */
|
||||
|
||||
/*
|
||||
** Include code that is common to all os_*.c files
|
||||
@@ -385,7 +378,7 @@ static struct unix_syscall {
|
||||
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
||||
#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
|
||||
|
||||
#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
||||
#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ "pread", (sqlite3_syscall_ptr)pread, 0 },
|
||||
#else
|
||||
{ "pread", (sqlite3_syscall_ptr)0, 0 },
|
||||
@@ -402,7 +395,7 @@ static struct unix_syscall {
|
||||
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
||||
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
|
||||
|
||||
#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
||||
#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ "pwrite", (sqlite3_syscall_ptr)pwrite, 0 },
|
||||
#else
|
||||
{ "pwrite", (sqlite3_syscall_ptr)0, 0 },
|
||||
@@ -717,9 +710,9 @@ static int lockTrace(int fd, int op, struct flock *p){
|
||||
/*
|
||||
** Retry ftruncate() calls that fail due to EINTR
|
||||
**
|
||||
** All calls to ftruncate() within this file should be made through this wrapper.
|
||||
** On the Android platform, bypassing the logic below could lead to a corrupt
|
||||
** database.
|
||||
** All calls to ftruncate() within this file should be made through
|
||||
** this wrapper. On the Android platform, bypassing the logic below
|
||||
** could lead to a corrupt database.
|
||||
*/
|
||||
static int robust_ftruncate(int h, sqlite3_int64 sz){
|
||||
int rc;
|
||||
@@ -1178,6 +1171,14 @@ static void robust_close(unixFile *pFile, int h, int lineno){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the pFile->lastErrno. Do this in a subroutine as that provides
|
||||
** a convenient place to set a breakpoint.
|
||||
*/
|
||||
static void storeLastErrno(unixFile *pFile, int error){
|
||||
pFile->lastErrno = error;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
|
||||
*/
|
||||
@@ -1251,7 +1252,7 @@ static int findInodeInfo(
|
||||
fd = pFile->h;
|
||||
rc = osFstat(fd, &statbuf);
|
||||
if( rc!=0 ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
#ifdef EOVERFLOW
|
||||
if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
|
||||
#endif
|
||||
@@ -1272,12 +1273,12 @@ static int findInodeInfo(
|
||||
if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
|
||||
do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
|
||||
if( rc!=1 ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
rc = osFstat(fd, &statbuf);
|
||||
if( rc!=0 ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
}
|
||||
@@ -1400,7 +1401,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
lock.l_type = F_WRLCK;
|
||||
if( osFcntl(pFile->h, F_GETLK, &lock) ){
|
||||
rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
} else if( lock.l_type!=F_UNLCK ){
|
||||
reserved = 1;
|
||||
}
|
||||
@@ -1533,7 +1534,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
assert( pFile );
|
||||
OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
|
||||
azFileLock(eFileLock), azFileLock(pFile->eFileLock),
|
||||
azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
|
||||
azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared,
|
||||
osGetpid()));
|
||||
|
||||
/* If there is already a lock of this type or more restrictive on the
|
||||
** unixFile, do nothing. Don't use the end_lock: exit path, as
|
||||
@@ -1600,7 +1602,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
tErrno = errno;
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||
if( rc!=SQLITE_BUSY ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
goto end_lock;
|
||||
}
|
||||
@@ -1635,7 +1637,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
|
||||
if( rc ){
|
||||
if( rc!=SQLITE_BUSY ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
goto end_lock;
|
||||
}else{
|
||||
@@ -1668,7 +1670,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
tErrno = errno;
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||
if( rc!=SQLITE_BUSY ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1741,7 +1743,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
assert( pFile );
|
||||
OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
|
||||
pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
|
||||
getpid()));
|
||||
osGetpid()));
|
||||
|
||||
assert( eFileLock<=SHARED_LOCK );
|
||||
if( pFile->eFileLock<=eFileLock ){
|
||||
@@ -1775,7 +1777,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
** 4: [RRRR.]
|
||||
*/
|
||||
if( eFileLock==SHARED_LOCK ){
|
||||
|
||||
#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
|
||||
(void)handleNFSUnlock;
|
||||
assert( handleNFSUnlock==0 );
|
||||
@@ -1793,7 +1794,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
tErrno = errno;
|
||||
rc = SQLITE_IOERR_UNLOCK;
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
goto end_unlock;
|
||||
}
|
||||
@@ -1805,7 +1806,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
tErrno = errno;
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
goto end_unlock;
|
||||
}
|
||||
@@ -1817,7 +1818,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
tErrno = errno;
|
||||
rc = SQLITE_IOERR_UNLOCK;
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
goto end_unlock;
|
||||
}
|
||||
@@ -1836,7 +1837,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
** SQLITE_BUSY would confuse the upper layer (in practice it causes
|
||||
** an assert to fail). */
|
||||
rc = SQLITE_IOERR_RDLOCK;
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
goto end_unlock;
|
||||
}
|
||||
}
|
||||
@@ -1849,7 +1850,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
pInode->eFileLock = SHARED_LOCK;
|
||||
}else{
|
||||
rc = SQLITE_IOERR_UNLOCK;
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
goto end_unlock;
|
||||
}
|
||||
}
|
||||
@@ -1867,7 +1868,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
pInode->eFileLock = NO_LOCK;
|
||||
}else{
|
||||
rc = SQLITE_IOERR_UNLOCK;
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
pInode->eFileLock = NO_LOCK;
|
||||
pFile->eFileLock = NO_LOCK;
|
||||
}
|
||||
@@ -2142,7 +2143,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
|
||||
} else {
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
@@ -2169,7 +2170,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
||||
|
||||
assert( pFile );
|
||||
OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
|
||||
pFile->eFileLock, getpid()));
|
||||
pFile->eFileLock, osGetpid()));
|
||||
assert( eFileLock<=SHARED_LOCK );
|
||||
|
||||
/* no-op if possible */
|
||||
@@ -2196,7 +2197,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
||||
rc = SQLITE_IOERR_UNLOCK;
|
||||
}
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -2232,10 +2233,9 @@ static int dotlockClose(sqlite3_file *id) {
|
||||
** still works when you do this, but concurrency is reduced since
|
||||
** only a single process can be reading the database at a time.
|
||||
**
|
||||
** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
|
||||
** compiling for VXWORKS.
|
||||
** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off
|
||||
*/
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
|
||||
/*
|
||||
** Retry flock() calls that fail with EINTR
|
||||
@@ -2283,7 +2283,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
/* unlock failed with an error */
|
||||
lrc = SQLITE_IOERR_UNLOCK;
|
||||
if( IS_LOCK_ERROR(lrc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
rc = lrc;
|
||||
}
|
||||
}
|
||||
@@ -2293,7 +2293,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
/* someone else might have it reserved */
|
||||
lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||
if( IS_LOCK_ERROR(lrc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
rc = lrc;
|
||||
}
|
||||
}
|
||||
@@ -2359,7 +2359,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
|
||||
/* didn't get, must be busy */
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
} else {
|
||||
/* got it, set the type and return ok */
|
||||
@@ -2388,7 +2388,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
|
||||
|
||||
assert( pFile );
|
||||
OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
|
||||
pFile->eFileLock, getpid()));
|
||||
pFile->eFileLock, osGetpid()));
|
||||
assert( eFileLock<=SHARED_LOCK );
|
||||
|
||||
/* no-op if possible */
|
||||
@@ -2449,7 +2449,7 @@ static int flockClose(sqlite3_file *id) {
|
||||
** to a non-zero value otherwise *pResOut is set to zero. The return value
|
||||
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
|
||||
*/
|
||||
static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||
static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||
int rc = SQLITE_OK;
|
||||
int reserved = 0;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
@@ -2471,7 +2471,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||
int tErrno = errno;
|
||||
if( EAGAIN != tErrno ){
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
} else {
|
||||
/* someone else has the lock when we are in NO_LOCK */
|
||||
reserved = (pFile->eFileLock < SHARED_LOCK);
|
||||
@@ -2516,7 +2516,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||
** This routine will only increase a lock. Use the sqlite3OsUnlock()
|
||||
** routine to lower a locking level.
|
||||
*/
|
||||
static int semLock(sqlite3_file *id, int eFileLock) {
|
||||
static int semXLock(sqlite3_file *id, int eFileLock) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
sem_t *pSem = pFile->pInode->pSem;
|
||||
int rc = SQLITE_OK;
|
||||
@@ -2549,14 +2549,14 @@ static int semLock(sqlite3_file *id, int eFileLock) {
|
||||
** If the locking level of the file descriptor is already at or below
|
||||
** the requested locking level, this routine is a no-op.
|
||||
*/
|
||||
static int semUnlock(sqlite3_file *id, int eFileLock) {
|
||||
static int semXUnlock(sqlite3_file *id, int eFileLock) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
sem_t *pSem = pFile->pInode->pSem;
|
||||
|
||||
assert( pFile );
|
||||
assert( pSem );
|
||||
OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
|
||||
pFile->eFileLock, getpid()));
|
||||
pFile->eFileLock, osGetpid()));
|
||||
assert( eFileLock<=SHARED_LOCK );
|
||||
|
||||
/* no-op if possible */
|
||||
@@ -2575,7 +2575,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
|
||||
int rc, tErrno = errno;
|
||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -2586,10 +2586,10 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
static int semClose(sqlite3_file *id) {
|
||||
static int semXClose(sqlite3_file *id) {
|
||||
if( id ){
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
semUnlock(id, NO_LOCK);
|
||||
semXUnlock(id, NO_LOCK);
|
||||
assert( pFile );
|
||||
unixEnterMutex();
|
||||
releaseInodeInfo(pFile);
|
||||
@@ -2677,7 +2677,7 @@ static int afpSetLock(
|
||||
setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
|
||||
#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
|
||||
if( IS_LOCK_ERROR(rc) ){
|
||||
pFile->lastErrno = tErrno;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
}
|
||||
return rc;
|
||||
} else {
|
||||
@@ -2770,7 +2770,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
|
||||
assert( pFile );
|
||||
OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
|
||||
azFileLock(eFileLock), azFileLock(pFile->eFileLock),
|
||||
azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
|
||||
azFileLock(pInode->eFileLock), pInode->nShared , osGetpid()));
|
||||
|
||||
/* If there is already a lock of this type or more restrictive on the
|
||||
** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
|
||||
@@ -2860,7 +2860,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
|
||||
lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
|
||||
|
||||
if( IS_LOCK_ERROR(lrc1) ) {
|
||||
pFile->lastErrno = lrc1Errno;
|
||||
storeLastErrno(pFile, lrc1Errno);
|
||||
rc = lrc1;
|
||||
goto afp_end_lock;
|
||||
} else if( IS_LOCK_ERROR(lrc2) ){
|
||||
@@ -2956,7 +2956,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
|
||||
assert( pFile );
|
||||
OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock,
|
||||
pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
|
||||
getpid()));
|
||||
osGetpid()));
|
||||
|
||||
assert( eFileLock<=SHARED_LOCK );
|
||||
if( pFile->eFileLock<=eFileLock ){
|
||||
@@ -3147,9 +3147,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
||||
SimulateIOError( newOffset-- );
|
||||
if( newOffset!=offset ){
|
||||
if( newOffset == -1 ){
|
||||
((unixFile*)id)->lastErrno = errno;
|
||||
storeLastErrno((unixFile*)id, errno);
|
||||
}else{
|
||||
((unixFile*)id)->lastErrno = 0;
|
||||
storeLastErrno((unixFile*)id, 0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -3159,7 +3159,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
||||
if( got<0 ){
|
||||
if( errno==EINTR ){ got = 1; continue; }
|
||||
prior = 0;
|
||||
((unixFile*)id)->lastErrno = errno;
|
||||
storeLastErrno((unixFile*)id, errno);
|
||||
break;
|
||||
}else if( got>0 ){
|
||||
cnt -= got;
|
||||
@@ -3224,7 +3224,7 @@ static int unixRead(
|
||||
/* lastErrno set by seekAndRead */
|
||||
return SQLITE_IOERR_READ;
|
||||
}else{
|
||||
pFile->lastErrno = 0; /* not a system error */
|
||||
storeLastErrno(pFile, 0); /* not a system error */
|
||||
/* Unread parts of the buffer must be zero-filled */
|
||||
memset(&((char*)pBuf)[got], 0, amt-got);
|
||||
return SQLITE_IOERR_SHORT_READ;
|
||||
@@ -3253,9 +3253,9 @@ static int seekAndWriteFd(
|
||||
TIMER_START;
|
||||
|
||||
#if defined(USE_PREAD)
|
||||
do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
|
||||
do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
|
||||
#elif defined(USE_PREAD64)
|
||||
do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
|
||||
do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
|
||||
#else
|
||||
do{
|
||||
i64 iSeek = lseek(fd, iOff, SEEK_SET);
|
||||
@@ -3365,7 +3365,7 @@ static int unixWrite(
|
||||
/* lastErrno set by seekAndWrite */
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}else{
|
||||
pFile->lastErrno = 0; /* not a system error */
|
||||
storeLastErrno(pFile, 0); /* not a system error */
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
}
|
||||
@@ -3574,7 +3574,7 @@ static int unixSync(sqlite3_file *id, int flags){
|
||||
rc = full_fsync(pFile->h, isFullsync, isDataOnly);
|
||||
SimulateIOError( rc=1 );
|
||||
if( rc ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
|
||||
}
|
||||
|
||||
@@ -3618,7 +3618,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||
|
||||
rc = robust_ftruncate(pFile->h, nByte);
|
||||
if( rc ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
||||
}else{
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -3658,7 +3658,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
|
||||
rc = osFstat(((unixFile*)id)->h, &buf);
|
||||
SimulateIOError( rc=1 );
|
||||
if( rc!=0 ){
|
||||
((unixFile*)id)->lastErrno = errno;
|
||||
storeLastErrno((unixFile*)id, errno);
|
||||
return SQLITE_IOERR_FSTAT;
|
||||
}
|
||||
*pSize = buf.st_size;
|
||||
@@ -3694,7 +3694,9 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
||||
i64 nSize; /* Required file size */
|
||||
struct stat buf; /* Used to hold return values of fstat() */
|
||||
|
||||
if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
|
||||
if( osFstat(pFile->h, &buf) ){
|
||||
return SQLITE_IOERR_FSTAT;
|
||||
}
|
||||
|
||||
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
|
||||
if( nSize>(i64)buf.st_size ){
|
||||
@@ -3741,7 +3743,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
||||
int rc;
|
||||
if( pFile->szChunk<=0 ){
|
||||
if( robust_ftruncate(pFile->h, nByte) ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
||||
}
|
||||
}
|
||||
@@ -3783,7 +3785,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
*(int*)pArg = pFile->eFileLock;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_LAST_ERRNO: {
|
||||
case SQLITE_FCNTL_LAST_ERRNO: {
|
||||
*(int*)pArg = pFile->lastErrno;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -3852,8 +3854,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
#endif
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
||||
case SQLITE_SET_LOCKPROXYFILE:
|
||||
case SQLITE_GET_LOCKPROXYFILE: {
|
||||
case SQLITE_FCNTL_SET_LOCKPROXYFILE:
|
||||
case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
|
||||
return proxyFileControl(id,op,pArg);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
|
||||
@@ -3993,7 +3995,9 @@ static int unixDeviceCharacteristics(sqlite3_file *id){
|
||||
** Instead, it should be called via macro osGetpagesize().
|
||||
*/
|
||||
static int unixGetpagesize(void){
|
||||
#if defined(_BSD_SOURCE)
|
||||
#if OS_VXWORKS
|
||||
return 1024;
|
||||
#elif defined(_BSD_SOURCE)
|
||||
return getpagesize();
|
||||
#else
|
||||
return (int)sysconf(_SC_PAGESIZE);
|
||||
@@ -4258,6 +4262,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
pShmNode = pInode->pShmNode;
|
||||
if( pShmNode==0 ){
|
||||
struct stat sStat; /* fstat() info for database file */
|
||||
#ifndef SQLITE_SHM_DIRECTORY
|
||||
const char *zBasePath = pDbFd->zPath;
|
||||
#endif
|
||||
|
||||
/* Call fstat() to figure out the permissions on the database file. If
|
||||
** a new *-shm file is created, an attempt will be made to create it
|
||||
@@ -4271,7 +4278,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
#ifdef SQLITE_SHM_DIRECTORY
|
||||
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
|
||||
#else
|
||||
nShmFilename = 6 + (int)strlen(pDbFd->zPath);
|
||||
nShmFilename = 6 + (int)strlen(zBasePath);
|
||||
#endif
|
||||
pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
|
||||
if( pShmNode==0 ){
|
||||
@@ -4285,7 +4292,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
|
||||
(u32)sStat.st_ino, (u32)sStat.st_dev);
|
||||
#else
|
||||
sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
|
||||
sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
|
||||
sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
|
||||
#endif
|
||||
pShmNode->h = -1;
|
||||
@@ -4619,7 +4626,7 @@ static int unixShmLock(
|
||||
}
|
||||
sqlite3_mutex_leave(pShmNode->mutex);
|
||||
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
|
||||
p->id, getpid(), p->sharedMask, p->exclMask));
|
||||
p->id, osGetpid(), p->sharedMask, p->exclMask));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -4678,7 +4685,9 @@ static int unixShmUnmap(
|
||||
assert( pShmNode->nRef>0 );
|
||||
pShmNode->nRef--;
|
||||
if( pShmNode->nRef==0 ){
|
||||
if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
|
||||
if( deleteFlag && pShmNode->h>=0 ){
|
||||
osUnlink(pShmNode->zFilename);
|
||||
}
|
||||
unixShmPurge(pDbFd);
|
||||
}
|
||||
unixLeaveMutex();
|
||||
@@ -4955,7 +4964,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
|
||||
** * An I/O method finder function called FINDER that returns a pointer
|
||||
** to the METHOD object in the previous bullet.
|
||||
*/
|
||||
#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
|
||||
#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \
|
||||
static const sqlite3_io_methods METHOD = { \
|
||||
VERSION, /* iVersion */ \
|
||||
CLOSE, /* xClose */ \
|
||||
@@ -5020,7 +5029,7 @@ IOMETHODS(
|
||||
0 /* xShmMap method */
|
||||
)
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
IOMETHODS(
|
||||
flockIoFinder, /* Finder function name */
|
||||
flockIoMethods, /* sqlite3_io_methods object name */
|
||||
@@ -5038,10 +5047,10 @@ IOMETHODS(
|
||||
semIoFinder, /* Finder function name */
|
||||
semIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
semClose, /* xClose method */
|
||||
semLock, /* xLock method */
|
||||
semUnlock, /* xUnlock method */
|
||||
semCheckReservedLock, /* xCheckReservedLock method */
|
||||
semXClose, /* xClose method */
|
||||
semXLock, /* xLock method */
|
||||
semXUnlock, /* xUnlock method */
|
||||
semXCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* xShmMap method */
|
||||
)
|
||||
#endif
|
||||
@@ -5165,15 +5174,13 @@ static const sqlite3_io_methods
|
||||
|
||||
#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
|
||||
|
||||
#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
|
||||
/*
|
||||
** This "finder" function attempts to determine the best locking strategy
|
||||
** for the database file "filePath". It then returns the sqlite3_io_methods
|
||||
** object that implements that strategy.
|
||||
**
|
||||
** This is for VXWorks only.
|
||||
#if OS_VXWORKS
|
||||
/*
|
||||
** This "finder" function for VxWorks checks to see if posix advisory
|
||||
** locking works. If it does, then that is what is used. If it does not
|
||||
** work, then fallback to named semaphore locking.
|
||||
*/
|
||||
static const sqlite3_io_methods *autolockIoFinderImpl(
|
||||
static const sqlite3_io_methods *vxworksIoFinderImpl(
|
||||
const char *filePath, /* name of the database file */
|
||||
unixFile *pNew /* the open file object */
|
||||
){
|
||||
@@ -5199,9 +5206,9 @@ static const sqlite3_io_methods *autolockIoFinderImpl(
|
||||
}
|
||||
}
|
||||
static const sqlite3_io_methods
|
||||
*(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
|
||||
*(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl;
|
||||
|
||||
#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
|
||||
#endif /* OS_VXWORKS */
|
||||
|
||||
/*
|
||||
** An abstract type for a pointer to an IO method finder function:
|
||||
@@ -5383,7 +5390,7 @@ static int fillInUnixFile(
|
||||
}
|
||||
#endif
|
||||
|
||||
pNew->lastErrno = 0;
|
||||
storeLastErrno(pNew, 0);
|
||||
#if OS_VXWORKS
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( h>=0 ) robust_close(pNew, h, __LINE__);
|
||||
@@ -5714,8 +5721,8 @@ static int unixOpen(
|
||||
** the same instant might all reset the PRNG. But multiple resets
|
||||
** are harmless.
|
||||
*/
|
||||
if( randomnessPid!=getpid() ){
|
||||
randomnessPid = getpid();
|
||||
if( randomnessPid!=osGetpid() ){
|
||||
randomnessPid = osGetpid();
|
||||
sqlite3_randomness(0,0);
|
||||
}
|
||||
|
||||
@@ -5831,13 +5838,16 @@ static int unixOpen(
|
||||
|
||||
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
|
||||
if( fstatfs(fd, &fsInfo) == -1 ){
|
||||
((unixFile*)pFile)->lastErrno = errno;
|
||||
storeLastErrno(p, errno);
|
||||
robust_close(p, fd, __LINE__);
|
||||
return SQLITE_IOERR_ACCESS;
|
||||
}
|
||||
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
|
||||
((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
|
||||
}
|
||||
if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
|
||||
((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set up appropriate ctrlFlags */
|
||||
@@ -5860,19 +5870,6 @@ static int unixOpen(
|
||||
if( envforce!=NULL ){
|
||||
useProxy = atoi(envforce)>0;
|
||||
}else{
|
||||
if( statfs(zPath, &fsInfo) == -1 ){
|
||||
/* In theory, the close(fd) call is sub-optimal. If the file opened
|
||||
** with fd is a database file, and there are other connections open
|
||||
** on that file that are currently holding advisory locks on it,
|
||||
** then the call to close() will cancel those locks. In practice,
|
||||
** we're assuming that statfs() doesn't fail very often. At least
|
||||
** not while other file descriptors opened by the same process on
|
||||
** the same file are working. */
|
||||
p->lastErrno = errno;
|
||||
robust_close(p, fd, __LINE__);
|
||||
rc = SQLITE_IOERR_ACCESS;
|
||||
goto open_finished;
|
||||
}
|
||||
useProxy = !(fsInfo.f_flags&MNT_LOCAL);
|
||||
}
|
||||
if( useProxy ){
|
||||
@@ -6116,7 +6113,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
|
||||
** tests repeatable.
|
||||
*/
|
||||
memset(zBuf, 0, nBuf);
|
||||
randomnessPid = getpid();
|
||||
randomnessPid = osGetpid();
|
||||
#if !defined(SQLITE_TEST)
|
||||
{
|
||||
int fd, got;
|
||||
@@ -6298,9 +6295,10 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
|
||||
**
|
||||
** C APIs
|
||||
**
|
||||
** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
|
||||
** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE,
|
||||
** <proxy_path> | ":auto:");
|
||||
** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
|
||||
** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE,
|
||||
** &<proxy_path>);
|
||||
**
|
||||
**
|
||||
** SQL pragmas
|
||||
@@ -6393,7 +6391,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
|
||||
** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
|
||||
** force proxy locking to be used for every database file opened, and 0
|
||||
** will force automatic proxy locking to be disabled for all database
|
||||
** files (explicitly calling the SQLITE_SET_LOCKPROXYFILE pragma or
|
||||
** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or
|
||||
** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
|
||||
*/
|
||||
|
||||
@@ -6414,6 +6412,7 @@ struct proxyLockingContext {
|
||||
char *lockProxyPath; /* Name of the proxy lock file */
|
||||
char *dbPath; /* Name of the open file */
|
||||
int conchHeld; /* 1 if the conch is held, -1 if lockless */
|
||||
int nFails; /* Number of conch taking failures */
|
||||
void *oldLockingContext; /* Original lockingcontext to restore on close */
|
||||
sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */
|
||||
};
|
||||
@@ -6435,7 +6434,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
|
||||
{
|
||||
if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
|
||||
OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n",
|
||||
lPath, errno, getpid()));
|
||||
lPath, errno, osGetpid()));
|
||||
return SQLITE_IOERR_LOCK;
|
||||
}
|
||||
len = strlcat(lPath, "sqliteplocks", maxLen);
|
||||
@@ -6457,7 +6456,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
|
||||
}
|
||||
lPath[i+len]='\0';
|
||||
strlcat(lPath, ":auto:", maxLen);
|
||||
OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid()));
|
||||
OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid()));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -6484,7 +6483,7 @@ static int proxyCreateLockPath(const char *lockPath){
|
||||
if( err!=EEXIST ) {
|
||||
OSTRACE(("CREATELOCKPATH FAILED creating %s, "
|
||||
"'%s' proxy lock path=%s pid=%d\n",
|
||||
buf, strerror(err), lockPath, getpid()));
|
||||
buf, strerror(err), lockPath, osGetpid()));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -6493,7 +6492,7 @@ static int proxyCreateLockPath(const char *lockPath){
|
||||
}
|
||||
buf[i] = lockPath[i];
|
||||
}
|
||||
OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid()));
|
||||
OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, osGetpid()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6602,10 +6601,10 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
||||
static int proxyGetHostID(unsigned char *pHostID, int *pError){
|
||||
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
|
||||
memset(pHostID, 0, PROXY_HOSTIDLEN);
|
||||
#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
|
||||
&& __MAC_OS_X_VERSION_MIN_REQUIRED<1050
|
||||
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
|
||||
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
|
||||
{
|
||||
static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
||||
struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
||||
if( gethostuuid(pHostID, &timeout) ){
|
||||
int err = errno;
|
||||
if( pError ){
|
||||
@@ -6720,7 +6719,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
||||
*/
|
||||
struct stat buf;
|
||||
if( osFstat(conchFile->h, &buf) ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return SQLITE_IOERR_LOCK;
|
||||
}
|
||||
|
||||
@@ -6740,7 +6739,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
||||
char tBuf[PROXY_MAXCONCHLEN];
|
||||
int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
|
||||
if( len<0 ){
|
||||
pFile->lastErrno = errno;
|
||||
storeLastErrno(pFile, errno);
|
||||
return SQLITE_IOERR_LOCK;
|
||||
}
|
||||
if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
|
||||
@@ -6760,7 +6759,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
||||
if( 0==proxyBreakConchLock(pFile, myHostID) ){
|
||||
rc = SQLITE_OK;
|
||||
if( lockType==EXCLUSIVE_LOCK ){
|
||||
rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
|
||||
rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
|
||||
}
|
||||
if( !rc ){
|
||||
rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
|
||||
@@ -6798,11 +6797,12 @@ static int proxyTakeConch(unixFile *pFile){
|
||||
int forceNewLockPath = 0;
|
||||
|
||||
OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h,
|
||||
(pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
|
||||
(pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
|
||||
osGetpid()));
|
||||
|
||||
rc = proxyGetHostID(myHostID, &pError);
|
||||
if( (rc&0xff)==SQLITE_IOERR ){
|
||||
pFile->lastErrno = pError;
|
||||
storeLastErrno(pFile, pError);
|
||||
goto end_takeconch;
|
||||
}
|
||||
rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
|
||||
@@ -6813,7 +6813,7 @@ static int proxyTakeConch(unixFile *pFile){
|
||||
readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
|
||||
if( readLen<0 ){
|
||||
/* I/O error: lastErrno set by seekAndRead */
|
||||
pFile->lastErrno = conchFile->lastErrno;
|
||||
storeLastErrno(pFile, conchFile->lastErrno);
|
||||
rc = SQLITE_IOERR_READ;
|
||||
goto end_takeconch;
|
||||
}else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) ||
|
||||
@@ -6886,7 +6886,7 @@ static int proxyTakeConch(unixFile *pFile){
|
||||
rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
|
||||
}
|
||||
}else{
|
||||
rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
|
||||
rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
char writeBuffer[PROXY_MAXCONCHLEN];
|
||||
@@ -6895,7 +6895,8 @@ static int proxyTakeConch(unixFile *pFile){
|
||||
writeBuffer[0] = (char)PROXY_CONCHVERSION;
|
||||
memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
|
||||
if( pCtx->lockProxyPath!=NULL ){
|
||||
strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
|
||||
strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath,
|
||||
MAXPATHLEN);
|
||||
}else{
|
||||
strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
|
||||
}
|
||||
@@ -7007,7 +7008,7 @@ static int proxyReleaseConch(unixFile *pFile){
|
||||
conchFile = pCtx->conchFile;
|
||||
OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h,
|
||||
(pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
|
||||
getpid()));
|
||||
osGetpid()));
|
||||
if( pCtx->conchHeld>0 ){
|
||||
rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
|
||||
}
|
||||
@@ -7107,7 +7108,8 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
|
||||
/* afp style keeps a reference to the db path in the filePath field
|
||||
** of the struct */
|
||||
assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
|
||||
strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN);
|
||||
strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath,
|
||||
MAXPATHLEN);
|
||||
} else
|
||||
#endif
|
||||
if( pFile->pMethod == &dotlockIoMethods ){
|
||||
@@ -7148,7 +7150,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
||||
}
|
||||
|
||||
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
|
||||
(lockPath ? lockPath : ":auto:"), getpid()));
|
||||
(lockPath ? lockPath : ":auto:"), osGetpid()));
|
||||
|
||||
pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
||||
if( pCtx==0 ){
|
||||
@@ -7220,7 +7222,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
||||
*/
|
||||
static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
switch( op ){
|
||||
case SQLITE_GET_LOCKPROXYFILE: {
|
||||
case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
if( pFile->pMethod == &proxyIoMethods ){
|
||||
proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
|
||||
@@ -7235,13 +7237,16 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_SET_LOCKPROXYFILE: {
|
||||
case SQLITE_FCNTL_SET_LOCKPROXYFILE: {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
int rc = SQLITE_OK;
|
||||
int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
|
||||
if( pArg==NULL || (const char *)pArg==0 ){
|
||||
if( isProxyStyle ){
|
||||
/* turn off proxy locking - not supported */
|
||||
/* turn off proxy locking - not supported. If support is added for
|
||||
** switching proxy locking mode off then it will need to fail if
|
||||
** the journal mode is WAL mode.
|
||||
*/
|
||||
rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
|
||||
}else{
|
||||
/* turn off proxy locking - already off - NOOP */
|
||||
@@ -7486,8 +7491,10 @@ int sqlite3_os_init(void){
|
||||
** array cannot be const.
|
||||
*/
|
||||
static sqlite3_vfs aVfs[] = {
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
||||
UNIXVFS("unix", autolockIoFinder ),
|
||||
#elif OS_VXWORKS
|
||||
UNIXVFS("unix", vxworksIoFinder ),
|
||||
#else
|
||||
UNIXVFS("unix", posixIoFinder ),
|
||||
#endif
|
||||
@@ -7497,11 +7504,11 @@ int sqlite3_os_init(void){
|
||||
#if OS_VXWORKS
|
||||
UNIXVFS("unix-namedsem", semIoFinder ),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
|
||||
UNIXVFS("unix-posix", posixIoFinder ),
|
||||
#if !OS_VXWORKS
|
||||
UNIXVFS("unix-flock", flockIoFinder ),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
UNIXVFS("unix-flock", flockIoFinder ),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
||||
UNIXVFS("unix-afp", afpIoFinder ),
|
||||
|
||||
+10
-10
@@ -1078,7 +1078,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pList = Y;
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
}
|
||||
@@ -1091,8 +1091,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = X;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
}
|
||||
@@ -1103,8 +1103,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = Y;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
@@ -1117,8 +1117,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SrcListDelete(pParse->db, pSrc);
|
||||
}
|
||||
@@ -1130,8 +1130,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
|
||||
if( p ){
|
||||
p->x.pSelect = Y;
|
||||
ExprSetProperty(p, EP_xIsSelect);
|
||||
sqlite3ExprSetHeight(pParse, p);
|
||||
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, p);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
@@ -1145,7 +1145,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
sqlite3ExprDelete(pParse->db, Z);
|
||||
|
||||
+9
-1
@@ -114,12 +114,20 @@ static void pcacheUnpin(PgHdr *p){
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute the number of pages of cache requested.
|
||||
** Compute the number of pages of cache requested. p->szCache is the
|
||||
** cache size requested by the "PRAGMA cache_size" statement.
|
||||
**
|
||||
**
|
||||
*/
|
||||
static int numberOfCachePages(PCache *p){
|
||||
if( p->szCache>=0 ){
|
||||
/* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
|
||||
** suggested cache size is set to N. */
|
||||
return p->szCache;
|
||||
}else{
|
||||
/* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
|
||||
** the number of cache pages is adjusted to use approximately abs(N*1024)
|
||||
** bytes of memory. */
|
||||
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
|
||||
}
|
||||
}
|
||||
|
||||
+72
-479
@@ -22,464 +22,13 @@
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
** The next block of code, including the PragTyp_XXXX macro definitions and
|
||||
** the aPragmaName[] object is composed of generated code. DO NOT EDIT.
|
||||
**
|
||||
** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun
|
||||
** that script. Then copy/paste the output in place of the following:
|
||||
*/
|
||||
#define PragTyp_HEADER_VALUE 0
|
||||
#define PragTyp_AUTO_VACUUM 1
|
||||
#define PragTyp_FLAG 2
|
||||
#define PragTyp_BUSY_TIMEOUT 3
|
||||
#define PragTyp_CACHE_SIZE 4
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 5
|
||||
#define PragTyp_COLLATION_LIST 6
|
||||
#define PragTyp_COMPILE_OPTIONS 7
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 8
|
||||
#define PragTyp_DATABASE_LIST 9
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 10
|
||||
#define PragTyp_ENCODING 11
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 12
|
||||
#define PragTyp_FOREIGN_KEY_LIST 13
|
||||
#define PragTyp_INCREMENTAL_VACUUM 14
|
||||
#define PragTyp_INDEX_INFO 15
|
||||
#define PragTyp_INDEX_LIST 16
|
||||
#define PragTyp_INTEGRITY_CHECK 17
|
||||
#define PragTyp_JOURNAL_MODE 18
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 19
|
||||
#define PragTyp_LOCK_PROXY_FILE 20
|
||||
#define PragTyp_LOCKING_MODE 21
|
||||
#define PragTyp_PAGE_COUNT 22
|
||||
#define PragTyp_MMAP_SIZE 23
|
||||
#define PragTyp_PAGE_SIZE 24
|
||||
#define PragTyp_SECURE_DELETE 25
|
||||
#define PragTyp_SHRINK_MEMORY 26
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 27
|
||||
#define PragTyp_STATS 28
|
||||
#define PragTyp_SYNCHRONOUS 29
|
||||
#define PragTyp_TABLE_INFO 30
|
||||
#define PragTyp_TEMP_STORE 31
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 32
|
||||
#define PragTyp_THREADS 33
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 34
|
||||
#define PragTyp_WAL_CHECKPOINT 35
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 36
|
||||
#define PragTyp_HEXKEY 37
|
||||
#define PragTyp_KEY 38
|
||||
#define PragTyp_REKEY 39
|
||||
#define PragTyp_LOCK_STATUS 40
|
||||
#define PragTyp_PARSER_TRACE 41
|
||||
#define PragFlag_NeedSchema 0x01
|
||||
#define PragFlag_ReadOnly 0x02
|
||||
static const struct sPragmaNames {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
|
||||
u32 iArg; /* Extra argument */
|
||||
} aPragmaNames[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
{ /* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_APPLICATION_ID },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
||||
{ /* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
#endif
|
||||
#endif
|
||||
{ /* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CacheSpill },
|
||||
#endif
|
||||
{ /* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
{ /* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
|
||||
{ /* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "data_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_DATA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{ /* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_UTF16)
|
||||
{ /* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{ /* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_FREE_PAGE_COUNT },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{ /* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
{ /* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ /* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
{ /* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{ /* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_SCHEMA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
#endif
|
||||
{ /* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_USER_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{ /* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{ /* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{ /* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{ /* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
{ /* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 58 on by default, 71 total. */
|
||||
/* End of the automatically generated pragma table.
|
||||
***************************************************************************/
|
||||
** The "pragma.h" include file is an automatically generated file that
|
||||
** that includes the PragType_XXXX macro definitions and the aPragmaName[]
|
||||
** object. This ensures that the aPragmaName[] table is arranged in
|
||||
** lexicographical order to facility a binary search of the pragma name.
|
||||
** Do not edit pragma.h directly. Edit and rerun the script in at
|
||||
** ../tool/mkpragmatab.tcl. */
|
||||
#include "pragma.h"
|
||||
|
||||
/*
|
||||
** Interpret the given string as a safety level. Return 0 for OFF,
|
||||
@@ -732,6 +281,7 @@ void sqlite3Pragma(
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
Db *pDb; /* The specific database being pragmaed */
|
||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
|
||||
const struct sPragmaNames *pPragma;
|
||||
|
||||
if( v==0 ) return;
|
||||
sqlite3VdbeRunOnlyOnce(v);
|
||||
@@ -767,6 +317,17 @@ void sqlite3Pragma(
|
||||
/* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
|
||||
** connection. If it returns SQLITE_OK, then assume that the VFS
|
||||
** handled the pragma and generate a no-op prepared statement.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed,
|
||||
** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file
|
||||
** object corresponding to the database file to which the pragma
|
||||
** statement refers.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
|
||||
** file control is an array of pointers to strings (char**) in which the
|
||||
** second element of the array is the name of the pragma and the third
|
||||
** element is the argument to the pragma or NULL if the pragma has no
|
||||
** argument.
|
||||
*/
|
||||
aFcntl[0] = 0;
|
||||
aFcntl[1] = zLeft;
|
||||
@@ -809,14 +370,15 @@ void sqlite3Pragma(
|
||||
}
|
||||
}
|
||||
if( lwr>upr ) goto pragma_out;
|
||||
pPragma = &aPragmaNames[mid];
|
||||
|
||||
/* Make sure the database schema is loaded if the pragma requires that */
|
||||
if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){
|
||||
if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
}
|
||||
|
||||
/* Jump to the appropriate pragma handler */
|
||||
switch( aPragmaNames[mid].ePragTyp ){
|
||||
switch( pPragma->ePragTyp ){
|
||||
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
/*
|
||||
@@ -1395,10 +957,9 @@ void sqlite3Pragma(
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
case PragTyp_FLAG: {
|
||||
if( zRight==0 ){
|
||||
returnSingleInt(pParse, aPragmaNames[mid].zName,
|
||||
(db->flags & aPragmaNames[mid].iArg)!=0 );
|
||||
returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
|
||||
}else{
|
||||
int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */
|
||||
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
|
||||
if( db->autoCommit==0 ){
|
||||
/* Foreign key support may not be enabled or disabled while not
|
||||
** in auto-commit mode. */
|
||||
@@ -1527,20 +1088,42 @@ void sqlite3Pragma(
|
||||
pIdx = sqlite3FindIndex(db, zRight, zDb);
|
||||
if( pIdx ){
|
||||
int i;
|
||||
int mx;
|
||||
if( pPragma->iArg ){
|
||||
/* PRAGMA index_xinfo (newer version with more rows and columns) */
|
||||
mx = pIdx->nColumn;
|
||||
pParse->nMem = 6;
|
||||
}else{
|
||||
/* PRAGMA index_info (legacy version) */
|
||||
mx = pIdx->nKeyCol;
|
||||
pParse->nMem = 3;
|
||||
}
|
||||
pTab = pIdx->pTable;
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
pParse->nMem = 3;
|
||||
sqlite3VdbeSetNumCols(v, pParse->nMem);
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
for(i=0; i<pIdx->nKeyCol; i++){
|
||||
if( pPragma->iArg ){
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
|
||||
}
|
||||
for(i=0; i<mx; i++){
|
||||
i16 cnum = pIdx->aiColumn[i];
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
|
||||
assert( pTab->nCol>cnum );
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
if( cnum<0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
|
||||
}else{
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
|
||||
}
|
||||
if( pPragma->iArg ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1553,17 +1136,22 @@ void sqlite3Pragma(
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
pParse->nMem = 3;
|
||||
sqlite3VdbeSetNumCols(v, 5);
|
||||
pParse->nMem = 5;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
|
||||
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
|
||||
const char *azOrigin[] = { "c", "u", "pk" };
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2133,9 +1721,9 @@ void sqlite3Pragma(
|
||||
** applications for any purpose.
|
||||
*/
|
||||
case PragTyp_HEADER_VALUE: {
|
||||
int iCookie = aPragmaNames[mid].iArg; /* Which cookie to read or write */
|
||||
int iCookie = pPragma->iArg; /* Which cookie to read or write */
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
if( zRight && (aPragmaNames[mid].mPragFlag & PragFlag_ReadOnly)==0 ){
|
||||
if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
|
||||
/* Write the specified cookie value */
|
||||
static const VdbeOpList setCookie[] = {
|
||||
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
||||
@@ -2237,8 +1825,9 @@ void sqlite3Pragma(
|
||||
/*
|
||||
** PRAGMA shrink_memory
|
||||
**
|
||||
** This pragma attempts to free as much memory as possible from the
|
||||
** current database connection.
|
||||
** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database
|
||||
** connection on which it is invoked to free up as much memory as it
|
||||
** can, by calling sqlite3_db_release_memory().
|
||||
*/
|
||||
case PragTyp_SHRINK_MEMORY: {
|
||||
sqlite3_db_release_memory(db);
|
||||
@@ -2255,7 +1844,7 @@ void sqlite3Pragma(
|
||||
** disables the timeout.
|
||||
*/
|
||||
/*case PragTyp_BUSY_TIMEOUT*/ default: {
|
||||
assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT );
|
||||
assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
|
||||
if( zRight ){
|
||||
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
|
||||
}
|
||||
@@ -2267,8 +1856,12 @@ void sqlite3Pragma(
|
||||
** PRAGMA soft_heap_limit
|
||||
** PRAGMA soft_heap_limit = N
|
||||
**
|
||||
** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted,
|
||||
** use -1.
|
||||
** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the
|
||||
** sqlite3_soft_heap_limit64() interface with the argument N, if N is
|
||||
** specified and is a non-negative integer.
|
||||
** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always
|
||||
** returns the same integer that would be returned by the
|
||||
** sqlite3_soft_heap_limit64(-1) C-language function.
|
||||
*/
|
||||
case PragTyp_SOFT_HEAP_LIMIT: {
|
||||
sqlite3_int64 N;
|
||||
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
/* DO NOT EDIT!
|
||||
** This file is automatically generated by the script at
|
||||
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
||||
** that script and rerun it.
|
||||
*/
|
||||
#define PragTyp_HEADER_VALUE 0
|
||||
#define PragTyp_AUTO_VACUUM 1
|
||||
#define PragTyp_FLAG 2
|
||||
#define PragTyp_BUSY_TIMEOUT 3
|
||||
#define PragTyp_CACHE_SIZE 4
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 5
|
||||
#define PragTyp_COLLATION_LIST 6
|
||||
#define PragTyp_COMPILE_OPTIONS 7
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 8
|
||||
#define PragTyp_DATABASE_LIST 9
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 10
|
||||
#define PragTyp_ENCODING 11
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 12
|
||||
#define PragTyp_FOREIGN_KEY_LIST 13
|
||||
#define PragTyp_INCREMENTAL_VACUUM 14
|
||||
#define PragTyp_INDEX_INFO 15
|
||||
#define PragTyp_INDEX_LIST 16
|
||||
#define PragTyp_INTEGRITY_CHECK 17
|
||||
#define PragTyp_JOURNAL_MODE 18
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 19
|
||||
#define PragTyp_LOCK_PROXY_FILE 20
|
||||
#define PragTyp_LOCKING_MODE 21
|
||||
#define PragTyp_PAGE_COUNT 22
|
||||
#define PragTyp_MMAP_SIZE 23
|
||||
#define PragTyp_PAGE_SIZE 24
|
||||
#define PragTyp_SECURE_DELETE 25
|
||||
#define PragTyp_SHRINK_MEMORY 26
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 27
|
||||
#define PragTyp_STATS 28
|
||||
#define PragTyp_SYNCHRONOUS 29
|
||||
#define PragTyp_TABLE_INFO 30
|
||||
#define PragTyp_TEMP_STORE 31
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 32
|
||||
#define PragTyp_THREADS 33
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 34
|
||||
#define PragTyp_WAL_CHECKPOINT 35
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 36
|
||||
#define PragTyp_HEXKEY 37
|
||||
#define PragTyp_KEY 38
|
||||
#define PragTyp_REKEY 39
|
||||
#define PragTyp_LOCK_STATUS 40
|
||||
#define PragTyp_PARSER_TRACE 41
|
||||
#define PragFlag_NeedSchema 0x01
|
||||
#define PragFlag_ReadOnly 0x02
|
||||
static const struct sPragmaNames {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
|
||||
u32 iArg; /* Extra argument */
|
||||
} aPragmaNames[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
{ /* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_APPLICATION_ID },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
||||
{ /* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
#endif
|
||||
#endif
|
||||
{ /* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CacheSpill },
|
||||
#endif
|
||||
{ /* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
{ /* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
|
||||
{ /* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "data_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_DATA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{ /* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_UTF16)
|
||||
{ /* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{ /* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_FREE_PAGE_COUNT },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{ /* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
{ /* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 1 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ /* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
{ /* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{ /* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_SCHEMA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
#endif
|
||||
{ /* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_USER_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{ /* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{ /* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{ /* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{ /* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
{ /* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 59 on by default, 72 total. */
|
||||
+1
-1
@@ -995,7 +995,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zBuf==0 || zFormat==0 ) {
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
if( zBuf && n>0 ) zBuf[0] = 0;
|
||||
if( zBuf ) zBuf[0] = 0;
|
||||
return zBuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
+24
-17
@@ -247,9 +247,10 @@ static int lookupName(
|
||||
testcase( pNC->ncFlags & NC_PartIdx );
|
||||
testcase( pNC->ncFlags & NC_IsCheck );
|
||||
if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
|
||||
/* Silently ignore database qualifiers inside CHECK constraints and partial
|
||||
** indices. Do not raise errors because that might break legacy and
|
||||
** because it does not hurt anything to just ignore the database name. */
|
||||
/* Silently ignore database qualifiers inside CHECK constraints and
|
||||
** partial indices. Do not raise errors because that might break
|
||||
** legacy and because it does not hurt anything to just ignore the
|
||||
** database name. */
|
||||
zDb = 0;
|
||||
}else{
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -320,7 +321,8 @@ static int lookupName(
|
||||
if( pMatch ){
|
||||
pExpr->iTable = pMatch->iCursor;
|
||||
pExpr->pTab = pMatch->pTab;
|
||||
assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
|
||||
/* RIGHT JOIN not (yet) supported */
|
||||
assert( (pMatch->jointype & JT_RIGHT)==0 );
|
||||
if( (pMatch->jointype & JT_LEFT)!=0 ){
|
||||
ExprSetProperty(pExpr, EP_CanBeNull);
|
||||
}
|
||||
@@ -641,7 +643,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
break;
|
||||
}
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
|
||||
&& !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
|
||||
/* A lone identifier is the name of a column.
|
||||
*/
|
||||
@@ -706,19 +709,20 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
if( n==2 ){
|
||||
pExpr->iTable = exprProbability(pList->a[1].pExpr);
|
||||
if( pExpr->iTable<0 ){
|
||||
sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
pNC->nErr++;
|
||||
}
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
|
||||
** likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
|
||||
** likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
|
||||
** likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
|
||||
** likelihood(X,0.9375). */
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
|
||||
** equivalent to likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
|
||||
** short-hand for likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
|
||||
** for likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
|
||||
** to likelihood(X,0.9375). */
|
||||
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
|
||||
pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
|
||||
}
|
||||
@@ -735,7 +739,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Prune;
|
||||
}
|
||||
#endif
|
||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
|
||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
|
||||
ExprSetProperty(pExpr,EP_ConstFunc);
|
||||
}
|
||||
}
|
||||
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
|
||||
@@ -1046,7 +1052,8 @@ int sqlite3ResolveOrderGroupBy(
|
||||
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
|
||||
return 1;
|
||||
}
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
|
||||
zType,0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
+32
-16
@@ -563,20 +563,17 @@ static void pushOntoSorter(
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
|
||||
if( pSelect->iLimit ){
|
||||
int addr1, addr2;
|
||||
int addr;
|
||||
int iLimit;
|
||||
if( pSelect->iOffset ){
|
||||
iLimit = pSelect->iOffset+1;
|
||||
}else{
|
||||
iLimit = pSelect->iLimit;
|
||||
}
|
||||
addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
|
||||
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
|
||||
sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
|
||||
sqlite3VdbeJumpHere(v, addr2);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,7 +970,7 @@ static void selectInnerLoop(
|
||||
** the output for us.
|
||||
*/
|
||||
if( pSort==0 && p->iLimit ){
|
||||
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1826,7 +1823,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
||||
sqlite3ExprCode(pParse, p->pLimit, iLimit);
|
||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
|
||||
VdbeComment((v, "LIMIT counter"));
|
||||
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
|
||||
}
|
||||
if( p->pOffset ){
|
||||
p->iOffset = iOffset = ++pParse->nMem;
|
||||
@@ -2045,7 +2042,7 @@ static void generateWithRecursiveQuery(
|
||||
selectInnerLoop(pParse, p, p->pEList, iCurrent,
|
||||
0, 0, pDest, addrCont, addrBreak);
|
||||
if( regLimit ){
|
||||
sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, addrCont);
|
||||
@@ -2270,7 +2267,7 @@ static int multiSelect(
|
||||
p->iLimit = pPrior->iLimit;
|
||||
p->iOffset = pPrior->iOffset;
|
||||
if( p->iLimit ){
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
|
||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||
}
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
@@ -2671,7 +2668,7 @@ static int generateOutputSubroutine(
|
||||
/* Jump to the end of the loop if the LIMIT is reached.
|
||||
*/
|
||||
if( p->iLimit ){
|
||||
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
|
||||
}
|
||||
|
||||
/* Generate the subroutine return
|
||||
@@ -3194,7 +3191,10 @@ static void substSelect(
|
||||
**
|
||||
** (1) The subquery and the outer query do not both use aggregates.
|
||||
**
|
||||
** (2) The subquery is not an aggregate or the outer query is not a join.
|
||||
** (2) The subquery is not an aggregate or (2a) the outer query is not a join
|
||||
** and (2b) the outer query does not use subqueries other than the one
|
||||
** FROM-clause subquery that is a candidate for flattening. (2b is
|
||||
** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
|
||||
**
|
||||
** (3) The subquery is not the right operand of a left outer join
|
||||
** (Originally ticket #306. Strengthened by ticket #3300)
|
||||
@@ -3331,8 +3331,17 @@ static int flattenSubquery(
|
||||
iParent = pSubitem->iCursor;
|
||||
pSub = pSubitem->pSelect;
|
||||
assert( pSub!=0 );
|
||||
if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
|
||||
if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
|
||||
if( subqueryIsAgg ){
|
||||
if( isAgg ) return 0; /* Restriction (1) */
|
||||
if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
|
||||
if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
|
||||
|| (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
|
||||
|| (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
|
||||
){
|
||||
return 0; /* Restriction (2b) */
|
||||
}
|
||||
}
|
||||
|
||||
pSubSrc = pSub->pSrc;
|
||||
assert( pSubSrc );
|
||||
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
|
||||
@@ -4752,6 +4761,13 @@ int sqlite3Select(
|
||||
}
|
||||
isAgg = (p->selFlags & SF_Aggregate)!=0;
|
||||
assert( pEList!=0 );
|
||||
#if SELECTTRACE_ENABLED
|
||||
if( sqlite3SelectTrace & 0x100 ){
|
||||
SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Begin generating code.
|
||||
*/
|
||||
@@ -5497,9 +5513,9 @@ select_end:
|
||||
void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
int n = 0;
|
||||
pView = sqlite3TreeViewPush(pView, moreToFollow);
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s",
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
|
||||
);
|
||||
if( p->pSrc && p->pSrc->nSrc ) n++;
|
||||
if( p->pWhere ) n++;
|
||||
|
||||
+205
-45
@@ -24,6 +24,13 @@
|
||||
#include "msvc.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** No support for loadable extensions in VxWorks.
|
||||
*/
|
||||
#if defined(_WRS_KERNEL) && !SQLITE_OMIT_LOAD_EXTENSION
|
||||
# define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Enable large-file support for fopen() and friends on unix.
|
||||
*/
|
||||
@@ -59,18 +66,38 @@
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_EDITLINE
|
||||
# undef HAVE_READLINE
|
||||
# define HAVE_READLINE 1
|
||||
# include <editline/readline.h>
|
||||
#endif
|
||||
#if !HAVE_READLINE
|
||||
# define add_history(X)
|
||||
# define read_history(X)
|
||||
# define write_history(X)
|
||||
# define stifle_history(X)
|
||||
|
||||
#if HAVE_EDITLINE || HAVE_READLINE
|
||||
|
||||
# define shell_add_history(X) add_history(X)
|
||||
# define shell_read_history(X) read_history(X)
|
||||
# define shell_write_history(X) write_history(X)
|
||||
# define shell_stifle_history(X) stifle_history(X)
|
||||
# define shell_readline(X) readline(X)
|
||||
|
||||
#elif HAVE_LINENOISE
|
||||
|
||||
# include "linenoise.h"
|
||||
# define shell_add_history(X) linenoiseHistoryAdd(X)
|
||||
# define shell_read_history(X) linenoiseHistoryLoad(X)
|
||||
# define shell_write_history(X) linenoiseHistorySave(X)
|
||||
# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
|
||||
# define shell_readline(X) linenoise(X)
|
||||
|
||||
#else
|
||||
|
||||
# define shell_read_history(X)
|
||||
# define shell_write_history(X)
|
||||
# define shell_stifle_history(X)
|
||||
|
||||
# define SHELL_USE_LOCAL_GETLINE 1
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
@@ -87,10 +114,15 @@
|
||||
*/
|
||||
extern int isatty(int);
|
||||
|
||||
/* popen and pclose are not C89 functions and so are sometimes omitted from
|
||||
** the <stdio.h> header */
|
||||
extern FILE *popen(const char*,const char*);
|
||||
extern int pclose(FILE*);
|
||||
#if !defined(__RTP__) && !defined(_WRS_KERNEL)
|
||||
/* popen and pclose are not C89 functions and so are sometimes omitted from
|
||||
** the <stdio.h> header */
|
||||
extern FILE *popen(const char*,const char*);
|
||||
extern int pclose(FILE*);
|
||||
#else
|
||||
# define SQLITE_OMIT_POPEN 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
@@ -145,11 +177,19 @@ static sqlite3_int64 timeOfDay(void){
|
||||
return t;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
|
||||
&& !defined(__minux)
|
||||
#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
/* VxWorks does not support getrusage() as far as we can determine */
|
||||
#if defined(_WRS_KERNEL) || defined(__RTP__)
|
||||
struct rusage {
|
||||
struct timeval ru_utime; /* user CPU time used */
|
||||
struct timeval ru_stime; /* system CPU time used */
|
||||
};
|
||||
#define getrusage(A,B) memset(B,0,sizeof(*B))
|
||||
#endif
|
||||
|
||||
/* Saved resource information for the beginning of an operation */
|
||||
static struct rusage sBegin; /* CPU time at start */
|
||||
static sqlite3_int64 iBegin; /* Wall-clock time at start */
|
||||
@@ -175,8 +215,8 @@ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
|
||||
*/
|
||||
static void endTimer(void){
|
||||
if( enableTimer ){
|
||||
struct rusage sEnd;
|
||||
sqlite3_int64 iEnd = timeOfDay();
|
||||
struct rusage sEnd;
|
||||
getrusage(RUSAGE_SELF, &sEnd);
|
||||
printf("Run Time: real %.3f user %f sys %f\n",
|
||||
(iEnd - iBegin)*0.001,
|
||||
@@ -451,14 +491,14 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
|
||||
zResult = local_getline(zPrior, in);
|
||||
}else{
|
||||
zPrompt = isContinuation ? continuePrompt : mainPrompt;
|
||||
#if HAVE_READLINE
|
||||
free(zPrior);
|
||||
zResult = readline(zPrompt);
|
||||
if( zResult && *zResult ) add_history(zResult);
|
||||
#else
|
||||
#if SHELL_USE_LOCAL_GETLINE
|
||||
printf("%s", zPrompt);
|
||||
fflush(stdout);
|
||||
zResult = local_getline(zPrior, stdin);
|
||||
#else
|
||||
free(zPrior);
|
||||
zResult = shell_readline(zPrompt);
|
||||
if( zResult && *zResult ) shell_add_history(zResult);
|
||||
#endif
|
||||
}
|
||||
return zResult;
|
||||
@@ -1733,6 +1773,7 @@ static char zHelp[] =
|
||||
".bail on|off Stop after hitting an error. Default OFF\n"
|
||||
".clone NEWDB Clone data into NEWDB from the existing database\n"
|
||||
".databases List names and files of attached databases\n"
|
||||
".dbinfo ?DB? Show status information about the database\n"
|
||||
".dump ?TABLE? ... Dump the database in an SQL text format\n"
|
||||
" If TABLE specified, only dump tables matching\n"
|
||||
" LIKE pattern TABLE.\n"
|
||||
@@ -1745,8 +1786,8 @@ static char zHelp[] =
|
||||
".headers on|off Turn display of headers on or off\n"
|
||||
".help Show this message\n"
|
||||
".import FILE TABLE Import data from FILE into TABLE\n"
|
||||
".indices ?TABLE? Show names of all indices\n"
|
||||
" If TABLE specified, only show indices for tables\n"
|
||||
".indexes ?TABLE? Show names of all indexes\n"
|
||||
" If TABLE specified, only show indexes for tables\n"
|
||||
" matching LIKE pattern TABLE.\n"
|
||||
#ifdef SQLITE_ENABLE_IOTRACE
|
||||
".iotrace FILE Enable I/O diagnostic logging to FILE\n"
|
||||
@@ -2418,7 +2459,9 @@ static void tryToClone(ShellState *p, const char *zNewDb){
|
||||
*/
|
||||
static void output_reset(ShellState *p){
|
||||
if( p->outfile[0]=='|' ){
|
||||
#ifndef SQLITE_OMIT_POPEN
|
||||
pclose(p->out);
|
||||
#endif
|
||||
}else{
|
||||
output_file_close(p->out);
|
||||
}
|
||||
@@ -2426,6 +2469,115 @@ static void output_reset(ShellState *p){
|
||||
p->out = stdout;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run an SQL command and return the single integer result.
|
||||
*/
|
||||
static int db_int(ShellState *p, const char *zSql){
|
||||
sqlite3_stmt *pStmt;
|
||||
int res = 0;
|
||||
sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
res = sqlite3_column_int(pStmt,0);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert a 2-byte or 4-byte big-endian integer into a native integer
|
||||
*/
|
||||
unsigned int get2byteInt(unsigned char *a){
|
||||
return (a[0]<<8) + a[1];
|
||||
}
|
||||
unsigned int get4byteInt(unsigned char *a){
|
||||
return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the ".info" command.
|
||||
**
|
||||
** Return 1 on error, 2 to exit, and 0 otherwise.
|
||||
*/
|
||||
static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
|
||||
static const struct { const char *zName; int ofst; } aField[] = {
|
||||
{ "file change counter:", 24 },
|
||||
{ "database page count:", 28 },
|
||||
{ "freelist page count:", 36 },
|
||||
{ "schema cookie:", 40 },
|
||||
{ "schema format:", 44 },
|
||||
{ "default cache size:", 48 },
|
||||
{ "autovacuum top root:", 52 },
|
||||
{ "incremental vacuum:", 64 },
|
||||
{ "text encoding:", 56 },
|
||||
{ "user version:", 60 },
|
||||
{ "application id:", 68 },
|
||||
{ "software version:", 96 },
|
||||
};
|
||||
static const struct { const char *zName; const char *zSql; } aQuery[] = {
|
||||
{ "number of tables:",
|
||||
"SELECT count(*) FROM %s WHERE type='table'" },
|
||||
{ "number of indexes:",
|
||||
"SELECT count(*) FROM %s WHERE type='index'" },
|
||||
{ "number of triggers:",
|
||||
"SELECT count(*) FROM %s WHERE type='trigger'" },
|
||||
{ "number of views:",
|
||||
"SELECT count(*) FROM %s WHERE type='view'" },
|
||||
{ "schema size:",
|
||||
"SELECT total(length(sql)) FROM %s" },
|
||||
};
|
||||
sqlite3_file *pFile;
|
||||
int i;
|
||||
char *zSchemaTab;
|
||||
char *zDb = nArg>=2 ? azArg[1] : "main";
|
||||
unsigned char aHdr[100];
|
||||
open_db(p, 0);
|
||||
if( p->db==0 ) return 1;
|
||||
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
|
||||
if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
|
||||
return 1;
|
||||
}
|
||||
i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
|
||||
if( i!=SQLITE_OK ){
|
||||
fprintf(stderr, "unable to read database header\n");
|
||||
return 1;
|
||||
}
|
||||
i = get2byteInt(aHdr+16);
|
||||
if( i==1 ) i = 65536;
|
||||
fprintf(p->out, "%-20s %d\n", "database page size:", i);
|
||||
fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
|
||||
fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
|
||||
fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
|
||||
for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
|
||||
int ofst = aField[i].ofst;
|
||||
unsigned int val = get4byteInt(aHdr + ofst);
|
||||
fprintf(p->out, "%-20s %u", aField[i].zName, val);
|
||||
switch( ofst ){
|
||||
case 56: {
|
||||
if( val==1 ) fprintf(p->out, " (utf8)");
|
||||
if( val==2 ) fprintf(p->out, " (utf16le)");
|
||||
if( val==3 ) fprintf(p->out, " (utf16be)");
|
||||
}
|
||||
}
|
||||
fprintf(p->out, "\n");
|
||||
}
|
||||
if( zDb==0 ){
|
||||
zSchemaTab = sqlite3_mprintf("main.sqlite_master");
|
||||
}else if( strcmp(zDb,"temp")==0 ){
|
||||
zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
|
||||
}else{
|
||||
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
|
||||
}
|
||||
for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
|
||||
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
|
||||
int val = db_int(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
|
||||
}
|
||||
sqlite3_free(zSchemaTab);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If an input line begins with "." then invoke this routine to
|
||||
** process that line.
|
||||
@@ -2568,6 +2720,10 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
|
||||
rc = shell_dbinfo_command(p, nArg, azArg);
|
||||
}else
|
||||
|
||||
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
|
||||
open_db(p, 0);
|
||||
/* When playing back a "dump", the content might appear in an order
|
||||
@@ -2798,9 +2954,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sCtx.zFile = zFile;
|
||||
sCtx.nLine = 1;
|
||||
if( sCtx.zFile[0]=='|' ){
|
||||
#ifdef SQLITE_OMIT_POPEN
|
||||
fprintf(stderr, "Error: pipes are not supporte in this OS\n");
|
||||
return 1;
|
||||
#else
|
||||
sCtx.in = popen(sCtx.zFile+1, "r");
|
||||
sCtx.zFile = "<pipe>";
|
||||
xCloser = pclose;
|
||||
#endif
|
||||
}else{
|
||||
sCtx.in = fopen(sCtx.zFile, "rb");
|
||||
xCloser = fclose;
|
||||
@@ -2907,7 +3068,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
|
||||
"filling the rest with NULL\n",
|
||||
sCtx.zFile, startLine, nCol, i+1);
|
||||
i++;
|
||||
i += 2;
|
||||
while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
|
||||
}
|
||||
}
|
||||
@@ -2936,7 +3097,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
}else
|
||||
|
||||
if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
|
||||
if( c=='i' && (strncmp(azArg[0], "indices", n)==0
|
||||
|| strncmp(azArg[0], "indexes", n)==0) ){
|
||||
ShellState data;
|
||||
char *zErrMsg = 0;
|
||||
open_db(p, 0);
|
||||
@@ -2966,7 +3128,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
);
|
||||
zShellStatic = 0;
|
||||
}else{
|
||||
fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
|
||||
fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
@@ -3122,6 +3284,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
output_reset(p);
|
||||
if( zFile[0]=='|' ){
|
||||
#ifdef SQLITE_OMIT_POPEN
|
||||
fprintf(stderr,"Error: pipes are not supported in this OS\n");
|
||||
rc = 1;
|
||||
p->out = stdout;
|
||||
#else
|
||||
p->out = popen(zFile + 1, "w");
|
||||
if( p->out==0 ){
|
||||
fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
|
||||
@@ -3130,6 +3297,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else{
|
||||
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
p->out = output_file_open(zFile);
|
||||
if( p->out==0 ){
|
||||
@@ -3536,7 +3704,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
|
||||
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER },
|
||||
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
|
||||
{ "initmode", SQLITE_TESTCTRL_INITMODE },
|
||||
{ "imposter", SQLITE_TESTCTRL_IMPOSTER },
|
||||
};
|
||||
int testctrl = -1;
|
||||
int rc = 0;
|
||||
@@ -3629,14 +3797,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SQLITE_TESTCTRL_INITMODE:
|
||||
case SQLITE_TESTCTRL_IMPOSTER:
|
||||
if( nArg==5 ){
|
||||
rc = sqlite3_test_control(testctrl, p->db,
|
||||
integerValue(azArg[2]),
|
||||
azArg[2],
|
||||
integerValue(azArg[3]),
|
||||
integerValue(azArg[4]));
|
||||
}else{
|
||||
fprintf(stderr,"Usage: .testctrl initmode fBusy iDb newTnum\n");
|
||||
fprintf(stderr,"Usage: .testctrl initmode dbName onoff tnum\n");
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
@@ -4054,7 +4222,7 @@ static char *find_home_dir(void){
|
||||
**
|
||||
** Returns the number of errors.
|
||||
*/
|
||||
static int process_sqliterc(
|
||||
static void process_sqliterc(
|
||||
ShellState *p, /* Configuration data */
|
||||
const char *sqliterc_override /* Name of config file. NULL to use default */
|
||||
){
|
||||
@@ -4062,15 +4230,13 @@ static int process_sqliterc(
|
||||
const char *sqliterc = sqliterc_override;
|
||||
char *zBuf = 0;
|
||||
FILE *in = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (sqliterc == NULL) {
|
||||
home_dir = find_home_dir();
|
||||
if( home_dir==0 ){
|
||||
#if !defined(__RTP__) && !defined(_WRS_KERNEL)
|
||||
fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
|
||||
#endif
|
||||
return 1;
|
||||
fprintf(stderr, "-- warning: cannot find home directory;"
|
||||
" cannot read ~/.sqliterc\n");
|
||||
return;
|
||||
}
|
||||
sqlite3_initialize();
|
||||
zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
|
||||
@@ -4081,11 +4247,10 @@ static int process_sqliterc(
|
||||
if( stdin_is_interactive ){
|
||||
fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
|
||||
}
|
||||
rc = process_input(p,in);
|
||||
process_input(p,in);
|
||||
fclose(in);
|
||||
}
|
||||
sqlite3_free(zBuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4361,10 +4526,7 @@ int main(int argc, char **argv){
|
||||
** is given on the command line, look for a file named ~/.sqliterc and
|
||||
** try to process it.
|
||||
*/
|
||||
rc = process_sqliterc(&data,zInitFile);
|
||||
if( rc>0 ){
|
||||
return rc;
|
||||
}
|
||||
process_sqliterc(&data,zInitFile);
|
||||
|
||||
/* Make a second pass through the command-line argument and set
|
||||
** options. This second pass is delayed until after the initialization
|
||||
@@ -4521,13 +4683,11 @@ int main(int argc, char **argv){
|
||||
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
|
||||
}
|
||||
}
|
||||
#if HAVE_READLINE
|
||||
if( zHistory ) read_history(zHistory);
|
||||
#endif
|
||||
if( zHistory ) shell_read_history(zHistory);
|
||||
rc = process_input(&data, 0);
|
||||
if( zHistory ){
|
||||
stifle_history(100);
|
||||
write_history(zHistory);
|
||||
shell_stifle_history(100);
|
||||
shell_write_history(zHistory);
|
||||
free(zHistory);
|
||||
}
|
||||
}else{
|
||||
|
||||
+56
-34
@@ -751,14 +751,16 @@ struct sqlite3_io_methods {
|
||||
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
|
||||
** interface.
|
||||
**
|
||||
** <ul>
|
||||
** <li>[[SQLITE_FCNTL_LOCKSTATE]]
|
||||
** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This
|
||||
** opcode causes the xFileControl method to write the current state of
|
||||
** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
|
||||
** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
|
||||
** into an integer that the pArg argument points to. This capability
|
||||
** is used during testing and only needs to be supported when SQLITE_TEST
|
||||
** is defined.
|
||||
** <ul>
|
||||
** is used during testing and is only available when the SQLITE_TEST
|
||||
** compile-time option is used.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_SIZE_HINT]]
|
||||
** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
|
||||
** layer a hint of how large the database file will grow to be during the
|
||||
@@ -883,7 +885,9 @@ struct sqlite3_io_methods {
|
||||
** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA]
|
||||
** file control returns [SQLITE_OK], then the parser assumes that the
|
||||
** VFS has handled the PRAGMA itself and the parser generates a no-op
|
||||
** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns
|
||||
** prepared statement if result string is NULL, or that returns a copy
|
||||
** of the result string if the string is non-NULL.
|
||||
** ^If the [SQLITE_FCNTL_PRAGMA] file control returns
|
||||
** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
|
||||
** that the VFS encountered an error while handling the [PRAGMA] and the
|
||||
** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA]
|
||||
@@ -944,9 +948,9 @@ struct sqlite3_io_methods {
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
#define SQLITE_GET_LOCKPROXYFILE 2
|
||||
#define SQLITE_SET_LOCKPROXYFILE 3
|
||||
#define SQLITE_LAST_ERRNO 4
|
||||
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
|
||||
#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
|
||||
#define SQLITE_FCNTL_LAST_ERRNO 4
|
||||
#define SQLITE_FCNTL_SIZE_HINT 5
|
||||
#define SQLITE_FCNTL_CHUNK_SIZE 6
|
||||
#define SQLITE_FCNTL_FILE_POINTER 7
|
||||
@@ -966,6 +970,12 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
|
||||
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
|
||||
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
|
||||
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle
|
||||
**
|
||||
@@ -1736,7 +1746,6 @@ struct sqlite3_mem_methods {
|
||||
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
|
||||
** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
|
||||
** that specifies the maximum size of the created heap.
|
||||
** </dl>
|
||||
**
|
||||
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
|
||||
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
|
||||
@@ -2226,6 +2235,10 @@ void sqlite3_free_table(char **result);
|
||||
**
|
||||
** These routines are work-alikes of the "printf()" family of functions
|
||||
** from the standard C library.
|
||||
** These routines understand most of the common K&R formatting options,
|
||||
** plus some additional non-standard formats, detailed below.
|
||||
** Note that some of the more obscure formatting options from recent
|
||||
** C-library standards are omitted from this implementation.
|
||||
**
|
||||
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
|
||||
** results into memory obtained from [sqlite3_malloc()].
|
||||
@@ -2258,7 +2271,7 @@ void sqlite3_free_table(char **result);
|
||||
** These routines all implement some additional formatting
|
||||
** options that are useful for constructing SQL statements.
|
||||
** All of the usual printf() formatting options apply. In addition, there
|
||||
** is are "%q", "%Q", and "%z" options.
|
||||
** is are "%q", "%Q", "%w" and "%z" options.
|
||||
**
|
||||
** ^(The %q option works like %s in that it substitutes a nul-terminated
|
||||
** string from the argument list. But %q also doubles every '\'' character.
|
||||
@@ -2311,6 +2324,12 @@ void sqlite3_free_table(char **result);
|
||||
** The code above will render a correct SQL statement in the zSQL
|
||||
** variable even if the zText variable is a NULL pointer.
|
||||
**
|
||||
** ^(The "%w" formatting option is like "%q" except that it expects to
|
||||
** be contained within double-quotes instead of single quotes, and it
|
||||
** escapes the double-quote character instead of the single-quote
|
||||
** character.)^ The "%w" formatting option is intended for safely inserting
|
||||
** table and column names into a constructed SQL statement.
|
||||
**
|
||||
** ^(The "%z" formatting option works like "%s" but with the
|
||||
** addition that after the string has been read and copied into
|
||||
** the result, [sqlite3_free()] is called on the input string.)^
|
||||
@@ -3166,16 +3185,14 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
|
||||
** use UTF-16.
|
||||
**
|
||||
** ^If the nByte argument is less than zero, then zSql is read up to the
|
||||
** first zero terminator. ^If nByte is non-negative, then it is the maximum
|
||||
** number of bytes read from zSql. ^When nByte is non-negative, the
|
||||
** zSql string ends at either the first '\000' or '\u0000' character or
|
||||
** the nByte-th byte, whichever comes first. If the caller knows
|
||||
** that the supplied string is nul-terminated, then there is a small
|
||||
** performance advantage to be gained by passing an nByte parameter that
|
||||
** is equal to the number of bytes in the input string <i>including</i>
|
||||
** the nul-terminator bytes as this saves SQLite from having to
|
||||
** make a copy of the input string.
|
||||
** ^If the nByte argument is negative, then zSql is read up to the
|
||||
** first zero terminator. ^If nByte is positive, then it is the
|
||||
** number of bytes read from zSql. ^If nByte is zero, then no prepared
|
||||
** statement is generated.
|
||||
** If the caller knows that the supplied string is nul-terminated, then
|
||||
** there is a small performance advantage to passing an nByte parameter that
|
||||
** is the number of bytes in the input string <i>including</i>
|
||||
** the nul-terminator.
|
||||
**
|
||||
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
|
||||
** past the end of the first SQL statement in zSql. These routines only
|
||||
@@ -4204,8 +4221,8 @@ int sqlite3_create_function_v2(
|
||||
** These functions are [deprecated]. In order to maintain
|
||||
** backwards compatibility with older code, these functions continue
|
||||
** to be supported. However, new applications should avoid
|
||||
** the use of these functions. To help encourage people to avoid
|
||||
** using these functions, we are not going to tell you what they do.
|
||||
** the use of these functions. To encourage programmers to avoid
|
||||
** these functions, we will not explain what they do.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
|
||||
@@ -5061,6 +5078,11 @@ void *sqlite3_update_hook(
|
||||
** future releases of SQLite. Applications that care about shared
|
||||
** cache setting should set it explicitly.
|
||||
**
|
||||
** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
|
||||
** and will always return SQLITE_MISUSE. On those systems,
|
||||
** shared cache mode should be enabled per-database connection via
|
||||
** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
|
||||
**
|
||||
** This interface is threadsafe on processors where writing a
|
||||
** 32-bit integer is atomic.
|
||||
**
|
||||
@@ -6260,7 +6282,7 @@ int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_BYTEORDER 22
|
||||
#define SQLITE_TESTCTRL_ISINIT 23
|
||||
#define SQLITE_TESTCTRL_SORTER_MMAP 24
|
||||
#define SQLITE_TESTCTRL_INITMODE 25
|
||||
#define SQLITE_TESTCTRL_IMPOSTER 25
|
||||
#define SQLITE_TESTCTRL_LAST 25
|
||||
|
||||
/*
|
||||
@@ -6962,20 +6984,20 @@ typedef struct sqlite3_backup sqlite3_backup;
|
||||
** is not a permanent error and does not affect the return value of
|
||||
** sqlite3_backup_finish().
|
||||
**
|
||||
** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
|
||||
** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
|
||||
** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
|
||||
**
|
||||
** ^Each call to sqlite3_backup_step() sets two values inside
|
||||
** the [sqlite3_backup] object: the number of pages still to be backed
|
||||
** up and the total number of pages in the source database file.
|
||||
** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
|
||||
** retrieve these two values, respectively.
|
||||
**
|
||||
** ^The values returned by these functions are only updated by
|
||||
** sqlite3_backup_step(). ^If the source database is modified during a backup
|
||||
** operation, then the values are not updated to account for any extra
|
||||
** pages that need to be updated or the size of the source database file
|
||||
** changing.
|
||||
** ^The sqlite3_backup_remaining() routine returns the number of pages still
|
||||
** to be backed up at the conclusion of the most recent sqlite3_backup_step().
|
||||
** ^The sqlite3_backup_pagecount() routine returns the total number of pages
|
||||
** in the source database at the conclusion of the most recent
|
||||
** sqlite3_backup_step().
|
||||
** ^(The values returned by these functions are only updated by
|
||||
** sqlite3_backup_step(). If the source database is modified in a way that
|
||||
** changes the size of the source database or the number of pages remaining,
|
||||
** those changes are not reflected in the output of sqlite3_backup_pagecount()
|
||||
** and sqlite3_backup_remaining() until after the next
|
||||
** sqlite3_backup_step().)^
|
||||
**
|
||||
** <b>Concurrent Usage of Database Handles</b>
|
||||
**
|
||||
|
||||
+16
-4
@@ -23,6 +23,11 @@
|
||||
*/
|
||||
#include "msvc.h"
|
||||
|
||||
/*
|
||||
** Special setup for VxWorks
|
||||
*/
|
||||
#include "vxworks.h"
|
||||
|
||||
/*
|
||||
** These #defines should enable >2GB file support on POSIX if the
|
||||
** underlying operating system supports it. If the OS lacks
|
||||
@@ -1087,6 +1092,7 @@ struct sqlite3 {
|
||||
u8 iDb; /* Which db file is being initialized */
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
|
||||
u8 imposterTable; /* Building an imposter table */
|
||||
} init;
|
||||
int nVdbeActive; /* Number of VDBEs currently running */
|
||||
int nVdbeRead; /* Number of active VDBEs that read or write */
|
||||
@@ -2043,8 +2049,14 @@ struct Expr {
|
||||
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_Constant 0x080000 /* Node is a constant */
|
||||
#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
|
||||
|
||||
/*
|
||||
** Combinations of two or more EP_* flags
|
||||
*/
|
||||
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
|
||||
|
||||
/*
|
||||
** These macros can be used to test, set, or clear bits in the
|
||||
@@ -2243,7 +2255,7 @@ struct SrcList {
|
||||
#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
|
||||
#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
|
||||
#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
|
||||
/* 0x0080 // not currently used */
|
||||
#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */
|
||||
#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
|
||||
#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
|
||||
#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
|
||||
@@ -3152,6 +3164,7 @@ ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
||||
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
||||
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
|
||||
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
u32 sqlite3ExprListFlags(const ExprList*);
|
||||
int sqlite3Init(sqlite3*, char**);
|
||||
int sqlite3InitCallback(void*, int, char**, char**);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
||||
@@ -3735,12 +3748,11 @@ void sqlite3MemJournalOpen(sqlite3_file *);
|
||||
int sqlite3MemJournalSize(void);
|
||||
int sqlite3IsMemJournal(sqlite3_file *);
|
||||
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
|
||||
int sqlite3SelectExprHeight(Select *);
|
||||
int sqlite3ExprCheckHeight(Parse*, int);
|
||||
#else
|
||||
#define sqlite3ExprSetHeight(x,y)
|
||||
#define sqlite3SelectExprHeight(x) 0
|
||||
#define sqlite3ExprCheckHeight(x,y)
|
||||
#endif
|
||||
|
||||
+7
-5
@@ -98,15 +98,17 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The maximum number of in-memory pages to use for the main database
|
||||
** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
|
||||
** The suggested maximum number of in-memory pages to use for
|
||||
** the main database table and for temporary tables.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
|
||||
** is 2000 pages.
|
||||
** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
|
||||
** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_CACHE_SIZE
|
||||
# define SQLITE_DEFAULT_CACHE_SIZE 2000
|
||||
#endif
|
||||
#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
|
||||
# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The default number of frames to accumulate in the log file before
|
||||
|
||||
+1
-1
@@ -3429,7 +3429,7 @@ static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
|
||||
for(i=j=0; i<16; i+=2){
|
||||
x = digest[i]*256 + digest[i+1];
|
||||
if( i>0 ) zDigest[j++] = '-';
|
||||
sqlite3_snprintf(16-j, &zDigest[j], "%05u", x);
|
||||
sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
|
||||
j += 5;
|
||||
}
|
||||
zDigest[j] = 0;
|
||||
|
||||
+9
-8
@@ -5915,7 +5915,7 @@ static int test_test_control(
|
||||
} aVerb[] = {
|
||||
{ "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
|
||||
{ "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
|
||||
{ "SQLITE_TESTCTRL_INITMODE", SQLITE_TESTCTRL_INITMODE },
|
||||
{ "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER },
|
||||
};
|
||||
int iVerb;
|
||||
int iFlag;
|
||||
@@ -5957,18 +5957,19 @@ static int test_test_control(
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_TESTCTRL_INITMODE: {
|
||||
int fBusy, iDb, newTnum;
|
||||
case SQLITE_TESTCTRL_IMPOSTER: {
|
||||
int onOff, tnum;
|
||||
const char *zDbName;
|
||||
sqlite3 *db;
|
||||
if( objc!=6 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "DB fBusy iDb newTnum");
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &fBusy) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &iDb) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[5], &newTnum) ) return TCL_ERROR;
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_INITMODE, db, fBusy, iDb, newTnum);
|
||||
zDbName = Tcl_GetString(objv[3]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR;
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "tcl.h"
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <assert.h>
|
||||
|
||||
/* These functions are implemented in main.c. */
|
||||
|
||||
@@ -650,7 +650,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
LINKVAR( MAX_PAGE_COUNT );
|
||||
LINKVAR( MAX_LIKE_PATTERN_LENGTH );
|
||||
LINKVAR( MAX_TRIGGER_DEPTH );
|
||||
LINKVAR( DEFAULT_TEMP_CACHE_SIZE );
|
||||
LINKVAR( DEFAULT_CACHE_SIZE );
|
||||
LINKVAR( DEFAULT_PAGE_SIZE );
|
||||
LINKVAR( DEFAULT_FILE_FORMAT );
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@
|
||||
|
||||
#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -1004,6 +1004,13 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|
||||
break;
|
||||
case SQLITE_FCNTL_PRAGMA: {
|
||||
char **aFcntl = (char**)pArg;
|
||||
/*
|
||||
** EVIDENCE-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
|
||||
** file control is an array of pointers to strings (char**) in which the
|
||||
** second element of the array is the name of the pragma and the third
|
||||
** element is the argument to the pragma or NULL if the pragma has no
|
||||
** argument.
|
||||
*/
|
||||
if( aFcntl[1] && sqlite3_stricmp(aFcntl[1],"multiplex_truncate")==0 ){
|
||||
if( aFcntl[2] && aFcntl[2][0] ){
|
||||
if( sqlite3_stricmp(aFcntl[2], "on")==0
|
||||
@@ -1015,6 +1022,12 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|
||||
pGroup->bTruncate = 0;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-27806-26076 The handler for an SQLITE_FCNTL_PRAGMA
|
||||
** file control can optionally make the first element of the char**
|
||||
** argument point to a string obtained from sqlite3_mprintf() or the
|
||||
** equivalent and that string will become the result of the pragma
|
||||
** or the error message if the pragma fails.
|
||||
*/
|
||||
aFcntl[0] = sqlite3_mprintf(pGroup->bTruncate ? "on" : "off");
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library.
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <tcl.h>
|
||||
|
||||
/* Solely for the UNUSED_PARAMETER() macro. */
|
||||
|
||||
+9
-2
@@ -301,8 +301,11 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
|
||||
if( p->nCell ){
|
||||
int i; /* Used to iterate through cells */
|
||||
int nUsable = szPage - sqlite3BtreeGetReserve(pBt);
|
||||
int nUsable; /* Usable bytes per page */
|
||||
|
||||
sqlite3BtreeEnter(pBt);
|
||||
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
|
||||
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
|
||||
|
||||
@@ -425,7 +428,11 @@ statNextRestart:
|
||||
while( p->iCell<p->nCell ){
|
||||
StatCell *pCell = &p->aCell[p->iCell];
|
||||
if( pCell->iOvfl<pCell->nOvfl ){
|
||||
int nUsable = sqlite3BtreeGetPageSize(pBt)-sqlite3BtreeGetReserve(pBt);
|
||||
int nUsable;
|
||||
sqlite3BtreeEnter(pBt);
|
||||
nUsable = sqlite3BtreeGetPageSize(pBt) -
|
||||
sqlite3BtreeGetReserveNoMutex(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
|
||||
pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
|
||||
pCsr->zPagetype = "overflow";
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
** sqlite3demo_superunlock()
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <string.h> /* memset(), strlen() */
|
||||
#include <assert.h> /* assert() */
|
||||
|
||||
|
||||
+1
-4
@@ -390,10 +390,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
int mxSqlLen; /* Max length of an SQL string */
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zSql==0 || pzErrMsg==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( zSql!=0 );
|
||||
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
** cause problems for the call to BtreeSetPageSize() below. */
|
||||
sqlite3BtreeCommit(pTemp);
|
||||
|
||||
nRes = sqlite3BtreeGetReserve(pMain);
|
||||
nRes = sqlite3BtreeGetOptimalReserve(pMain);
|
||||
|
||||
/* A VACUUM cannot change the pagesize of an encrypted database. */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
|
||||
+67
-12
@@ -1015,7 +1015,7 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
|
||||
** Synopsis: r[P2]='P4'
|
||||
**
|
||||
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
|
||||
** into a String before it is executed for the first time. During
|
||||
** into a String opcode before it is executed for the first time. During
|
||||
** this transformation, the length of string P4 is computed and stored
|
||||
** as the P1 parameter.
|
||||
*/
|
||||
@@ -1047,10 +1047,15 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
|
||||
/* Fall through to the next case, OP_String */
|
||||
}
|
||||
|
||||
/* Opcode: String P1 P2 * P4 *
|
||||
/* Opcode: String P1 P2 P3 P4 P5
|
||||
** Synopsis: r[P2]='P4' (len=P1)
|
||||
**
|
||||
** The string value P4 of length P1 (bytes) is stored in register P2.
|
||||
**
|
||||
** If P5!=0 and the content of register P3 is greater than zero, then
|
||||
** the datatype of the register P2 is converted to BLOB. The content is
|
||||
** the same sequence of bytes, it is merely interpreted as a BLOB instead
|
||||
** of a string, as if it had been CAST.
|
||||
*/
|
||||
case OP_String: { /* out2-prerelease */
|
||||
assert( pOp->p4.z!=0 );
|
||||
@@ -1059,6 +1064,13 @@ case OP_String: { /* out2-prerelease */
|
||||
pOut->n = pOp->p1;
|
||||
pOut->enc = encoding;
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
if( pOp->p5 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=(p->nMem-p->nCursor) );
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
assert( pIn3->flags & MEM_Int );
|
||||
if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3050,7 +3062,12 @@ case OP_Transaction: {
|
||||
p->nStmtDefImmCons = db->nDeferredImmCons;
|
||||
}
|
||||
|
||||
/* Gather the schema version number for checking */
|
||||
/* Gather the schema version number for checking:
|
||||
** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
|
||||
** each time a query is executed to ensure that the internal cache of the
|
||||
** schema used when compiling the SQL query matches the schema of the
|
||||
** database against which the compiled query is actually executed.
|
||||
*/
|
||||
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
|
||||
iGen = db->aDb[pOp->p1].pSchema->iGeneration;
|
||||
}else{
|
||||
@@ -5568,10 +5585,12 @@ case OP_MemMax: { /* in2 */
|
||||
/* Opcode: IfPos P1 P2 * * *
|
||||
** Synopsis: if r[P1]>0 goto P2
|
||||
**
|
||||
** If the value of register P1 is 1 or greater, jump to P2.
|
||||
** Register P1 must contain an integer.
|
||||
** If the value of register P1 is 1 or greater, jump to P2 and
|
||||
** add the literal value P3 to register P1.
|
||||
**
|
||||
** It is illegal to use this instruction on a register that does
|
||||
** not contain an integer. An assertion fault will result if you try.
|
||||
** If the initial value of register P1 is less than 1, then the
|
||||
** value is unchanged and control passes through to the next instruction.
|
||||
*/
|
||||
case OP_IfPos: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
@@ -5600,16 +5619,34 @@ case OP_IfNeg: { /* jump, in1 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IfZero P1 P2 P3 * *
|
||||
** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2
|
||||
/* Opcode: IfNotZero P1 P2 P3 * *
|
||||
** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2
|
||||
**
|
||||
** The register P1 must contain an integer. Add literal P3 to the
|
||||
** value in register P1. If the result is exactly 0, jump to P2.
|
||||
** Register P1 must contain an integer. If the content of register P1 is
|
||||
** initially nonzero, then add P3 to P1 and jump to P2. If register P1 is
|
||||
** initially zero, leave it unchanged and fall through.
|
||||
*/
|
||||
case OP_IfZero: { /* jump, in1 */
|
||||
case OP_IfNotZero: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
pIn1->u.i += pOp->p3;
|
||||
VdbeBranchTaken(pIn1->u.i<0, 2);
|
||||
if( pIn1->u.i ){
|
||||
pIn1->u.i += pOp->p3;
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: DecrJumpZero P1 P2 * * *
|
||||
** Synopsis: if (--r[P1])==0 goto P2
|
||||
**
|
||||
** Register P1 must hold an integer. Decrement the value in register P1
|
||||
** then jump to P2 if the new value is exactly zero.
|
||||
*/
|
||||
case OP_DecrJumpZero: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
pIn1->u.i--;
|
||||
VdbeBranchTaken(pIn1->u.i==0, 2);
|
||||
if( pIn1->u.i==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
@@ -5617,6 +5654,24 @@ case OP_IfZero: { /* jump, in1 */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Opcode: JumpZeroIncr P1 P2 * * *
|
||||
** Synopsis: if (r[P1]++)==0 ) goto P2
|
||||
**
|
||||
** The register P1 must contain an integer. If register P1 is initially
|
||||
** zero, then jump to P2. Increment register P1 regardless of whether or
|
||||
** not the jump is taken.
|
||||
*/
|
||||
case OP_JumpZeroIncr: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
VdbeBranchTaken(pIn1->u.i==0, 2);
|
||||
if( (pIn1->u.i++)==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: AggStep * P2 P3 P4 P5
|
||||
** Synopsis: accum=r[P3] step(r[P2@P5])
|
||||
**
|
||||
|
||||
@@ -344,6 +344,9 @@ struct Vdbe {
|
||||
u32 cacheCtr; /* VdbeCursor row cache generation counter */
|
||||
int pc; /* The program counter */
|
||||
int rc; /* Value to return */
|
||||
#ifdef SQLITE_DEBUG
|
||||
int rcApp; /* errcode set by sqlite3_result_error_code() */
|
||||
#endif
|
||||
u16 nResColumn; /* Number of columns in one row of the result set */
|
||||
u8 errorAction; /* Recovery action to do in case of an error */
|
||||
u8 minWriteFileFormat; /* Minimum file format for writable database files */
|
||||
|
||||
+39
-8
@@ -170,6 +170,10 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){
|
||||
return sqlite3ValueText(pVal, SQLITE_UTF16LE);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
|
||||
** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
|
||||
** point number string BLOB NULL
|
||||
*/
|
||||
int sqlite3_value_type(sqlite3_value* pVal){
|
||||
static const u8 aType[] = {
|
||||
SQLITE_BLOB, /* 0x00 */
|
||||
@@ -365,6 +369,9 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
|
||||
void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
|
||||
pCtx->isError = errCode;
|
||||
pCtx->fErrorOrAux = 1;
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
|
||||
#endif
|
||||
if( pCtx->pOut->flags & MEM_Null ){
|
||||
sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
@@ -445,7 +452,7 @@ static int sqlite3Step(Vdbe *p){
|
||||
** or SQLITE_BUSY error.
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_AUTORESET
|
||||
if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
|
||||
if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
|
||||
sqlite3_reset((sqlite3_stmt*)p);
|
||||
}else{
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
@@ -491,6 +498,9 @@ static int sqlite3Step(Vdbe *p){
|
||||
if( p->bIsReader ) db->nVdbeRead++;
|
||||
p->pc = 0;
|
||||
}
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->rcApp = SQLITE_OK;
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
if( p->explain ){
|
||||
rc = sqlite3VdbeList(p);
|
||||
@@ -535,7 +545,7 @@ end_of_step:
|
||||
assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
|
||||
|| rc==SQLITE_BUSY || rc==SQLITE_MISUSE
|
||||
);
|
||||
assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
|
||||
assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
|
||||
if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
|
||||
/* If this statement was prepared using sqlite3_prepare_v2(), and an
|
||||
** error has occurred, then return the error code in p->rc to the
|
||||
@@ -623,16 +633,27 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current time for a statement
|
||||
** Return the current time for a statement. If the current time
|
||||
** is requested more than once within the same run of a single prepared
|
||||
** statement, the exact same time is returned for each invocation regardless
|
||||
** of the amount of time that elapses between invocations. In other words,
|
||||
** the time returned is always the time of the first call.
|
||||
*/
|
||||
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
|
||||
Vdbe *v = p->pVdbe;
|
||||
int rc;
|
||||
if( v->iCurrentTime==0 ){
|
||||
rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime);
|
||||
if( rc ) v->iCurrentTime = 0;
|
||||
sqlite3_int64 iTime = 0;
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
sqlite3_int64 *piTime = &iTime;
|
||||
assert( p->pVdbe!=0 );
|
||||
#else
|
||||
sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
|
||||
if( *piTime==0 )
|
||||
#endif
|
||||
{
|
||||
rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime);
|
||||
if( rc ) *piTime = 0;
|
||||
}
|
||||
return v->iCurrentTime;
|
||||
return *piTime;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -702,6 +723,11 @@ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
|
||||
AuxData *pAuxData;
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
#if SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
if( pCtx->pVdbe==0 ) return 0;
|
||||
#else
|
||||
assert( pCtx->pVdbe!=0 );
|
||||
#endif
|
||||
for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
|
||||
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
|
||||
}
|
||||
@@ -725,6 +751,11 @@ void sqlite3_set_auxdata(
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
if( iArg<0 ) goto failed;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
if( pVdbe==0 ) goto failed;
|
||||
#else
|
||||
assert( pVdbe!=0 );
|
||||
#endif
|
||||
|
||||
for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
|
||||
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
|
||||
|
||||
+8
-3
@@ -154,12 +154,17 @@ int sqlite3_blob_open(
|
||||
Incrblob *pBlob = 0;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || ppBlob==0 || zTable==0 ){
|
||||
if( ppBlob==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
*ppBlob = 0;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || zTable==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
flags = !!flags; /* flags = (flags ? 1 : 0); */
|
||||
*ppBlob = 0;
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
|
||||
@@ -373,7 +378,7 @@ static int blobReadWrite(
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
v = (Vdbe*)p->pStmt;
|
||||
|
||||
if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
|
||||
if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
|
||||
/* Request is out of range. Return a transient error. */
|
||||
rc = SQLITE_ERROR;
|
||||
}else if( v==0 ){
|
||||
|
||||
+116
-1
@@ -1090,7 +1090,7 @@ struct ValueNewStat4Ctx {
|
||||
** Otherwise, if the second argument is non-zero, then this function is
|
||||
** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
|
||||
** already been allocated, allocate the UnpackedRecord structure that
|
||||
** that function will return to its caller here. Then return a pointer
|
||||
** that function will return to its caller here. Then return a pointer to
|
||||
** an sqlite3_value within the UnpackedRecord.a[] array.
|
||||
*/
|
||||
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
||||
@@ -1134,6 +1134,111 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
||||
return sqlite3ValueNew(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** The expression object indicated by the second argument is guaranteed
|
||||
** to be a scalar SQL function. If
|
||||
**
|
||||
** * all function arguments are SQL literals,
|
||||
** * the SQLITE_FUNC_CONSTANT function flag is set, and
|
||||
** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
|
||||
**
|
||||
** then this routine attempts to invoke the SQL function. Assuming no
|
||||
** error occurs, output parameter (*ppVal) is set to point to a value
|
||||
** object containing the result before returning SQLITE_OK.
|
||||
**
|
||||
** Affinity aff is applied to the result of the function before returning.
|
||||
** If the result is a text value, the sqlite3_value object uses encoding
|
||||
** enc.
|
||||
**
|
||||
** If the conditions above are not met, this function returns SQLITE_OK
|
||||
** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
|
||||
** NULL and an SQLite error code returned.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
static int valueFromFunction(
|
||||
sqlite3 *db, /* The database connection */
|
||||
Expr *p, /* The expression to evaluate */
|
||||
u8 enc, /* Encoding to use */
|
||||
u8 aff, /* Affinity to use */
|
||||
sqlite3_value **ppVal, /* Write the new value here */
|
||||
struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
|
||||
){
|
||||
sqlite3_context ctx; /* Context object for function invocation */
|
||||
sqlite3_value **apVal = 0; /* Function arguments */
|
||||
int nVal = 0; /* Size of apVal[] array */
|
||||
FuncDef *pFunc = 0; /* Function definition */
|
||||
sqlite3_value *pVal = 0; /* New value */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int nName; /* Size of function name in bytes */
|
||||
ExprList *pList = 0; /* Function arguments */
|
||||
int i; /* Iterator variable */
|
||||
|
||||
assert( pCtx!=0 );
|
||||
assert( (p->flags & EP_TokenOnly)==0 );
|
||||
pList = p->x.pList;
|
||||
if( pList ) nVal = pList->nExpr;
|
||||
nName = sqlite3Strlen30(p->u.zToken);
|
||||
pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
|
||||
assert( pFunc );
|
||||
if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0
|
||||
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
|
||||
){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
if( pList ){
|
||||
apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
|
||||
if( apVal==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto value_from_function_out;
|
||||
}
|
||||
for(i=0; i<nVal; i++){
|
||||
rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
|
||||
if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
|
||||
}
|
||||
}
|
||||
|
||||
pVal = valueNew(db, pCtx);
|
||||
if( pVal==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto value_from_function_out;
|
||||
}
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.pOut = pVal;
|
||||
ctx.pFunc = pFunc;
|
||||
pFunc->xFunc(&ctx, nVal, apVal);
|
||||
if( ctx.isError ){
|
||||
rc = ctx.isError;
|
||||
sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
|
||||
pCtx->pParse->rc = rc;
|
||||
}else{
|
||||
sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
|
||||
assert( rc==SQLITE_OK );
|
||||
rc = sqlite3VdbeChangeEncoding(pVal, enc);
|
||||
if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
|
||||
rc = SQLITE_TOOBIG;
|
||||
}
|
||||
}
|
||||
|
||||
value_from_function_out:
|
||||
if( rc!=SQLITE_OK ){
|
||||
pVal = 0;
|
||||
}
|
||||
if( apVal ){
|
||||
for(i=0; i<nVal; i++){
|
||||
sqlite3ValueFree(apVal[i]);
|
||||
}
|
||||
sqlite3DbFree(db, apVal);
|
||||
}
|
||||
|
||||
*ppVal = pVal;
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
|
||||
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
|
||||
|
||||
/*
|
||||
** Extract a value from the supplied expression in the manner described
|
||||
** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
|
||||
@@ -1166,6 +1271,12 @@ static int valueFromExpr(
|
||||
while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
|
||||
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
|
||||
|
||||
/* Compressed expressions only appear when parsing the DEFAULT clause
|
||||
** on a table column definition, and hence only when pCtx==0. This
|
||||
** check ensures that an EP_TokenOnly expression is never passed down
|
||||
** into valueFromFunction(). */
|
||||
assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
|
||||
|
||||
if( op==TK_CAST ){
|
||||
u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
|
||||
rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
|
||||
@@ -1242,6 +1353,10 @@ static int valueFromExpr(
|
||||
}
|
||||
#endif
|
||||
|
||||
else if( op==TK_FUNCTION && pCtx!=0 ){
|
||||
rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
|
||||
}
|
||||
|
||||
*ppVal = pVal;
|
||||
return rc;
|
||||
|
||||
|
||||
+3
-1
@@ -710,7 +710,9 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
char *zErr = 0;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
** 2015-03-02
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This file contains code that is specific to Wind River's VxWorks
|
||||
*/
|
||||
#if defined(__RTP__) || defined(_WRS_KERNEL)
|
||||
/* This is VxWorks. Set up things specially for that OS
|
||||
*/
|
||||
#include <vxWorks.h>
|
||||
#include <pthread.h> /* amalgamator: dontcache */
|
||||
#define OS_VXWORKS 1
|
||||
#define SQLITE_OS_OTHER 0
|
||||
#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1
|
||||
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||
#define SQLITE_ENABLE_LOCKING_STYLE 0
|
||||
#define HAVE_UTIME 1
|
||||
#else
|
||||
/* This is not VxWorks. */
|
||||
#define OS_VXWORKS 0
|
||||
#endif /* defined(_WRS_KERNEL) */
|
||||
@@ -1694,7 +1694,7 @@ static int walCheckpoint(
|
||||
int sync_flags, /* Flags for OsSync() (or 0) */
|
||||
u8 *zBuf /* Temporary buffer to use */
|
||||
){
|
||||
int rc; /* Return code */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int szPage; /* Database page-size */
|
||||
WalIterator *pIter = 0; /* Wal iterator context */
|
||||
u32 iDbpage = 0; /* Next database page to write */
|
||||
@@ -1708,104 +1708,107 @@ static int walCheckpoint(
|
||||
testcase( szPage<=32768 );
|
||||
testcase( szPage>=65536 );
|
||||
pInfo = walCkptInfo(pWal);
|
||||
if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
|
||||
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
|
||||
|
||||
/* Allocate the iterator */
|
||||
rc = walIteratorInit(pWal, &pIter);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
|
||||
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
||||
** safe to write into the database. Frames beyond mxSafeFrame might
|
||||
** overwrite database pages that are in use by active readers and thus
|
||||
** cannot be backfilled from the WAL.
|
||||
*/
|
||||
mxSafeFrame = pWal->hdr.mxFrame;
|
||||
mxPage = pWal->hdr.nPage;
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
u32 y = pInfo->aReadMark[i];
|
||||
if( mxSafeFrame>y ){
|
||||
assert( y<=pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
}else if( rc==SQLITE_BUSY ){
|
||||
mxSafeFrame = y;
|
||||
xBusy = 0;
|
||||
}else{
|
||||
goto walcheckpoint_out;
|
||||
}
|
||||
/* Allocate the iterator */
|
||||
rc = walIteratorInit(pWal, &pIter);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
if( pInfo->nBackfill<mxSafeFrame
|
||||
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
|
||||
){
|
||||
i64 nSize; /* Current size of database file */
|
||||
u32 nBackfill = pInfo->nBackfill;
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
|
||||
/* Sync the WAL to disk */
|
||||
if( sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
|
||||
/* If the database may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
||||
** safe to write into the database. Frames beyond mxSafeFrame might
|
||||
** overwrite database pages that are in use by active readers and thus
|
||||
** cannot be backfilled from the WAL.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nReq = ((i64)mxPage * szPage);
|
||||
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
|
||||
if( rc==SQLITE_OK && nSize<nReq ){
|
||||
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Iterate through the contents of the WAL, copying data to the db file. */
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
|
||||
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
|
||||
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
iOffset = (iDbpage-1)*(i64)szPage;
|
||||
testcase( IS_BIG_INT(iOffset) );
|
||||
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
|
||||
/* If work was actually accomplished... */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
|
||||
i64 szDb = pWal->hdr.nPage*(i64)szPage;
|
||||
testcase( IS_BIG_INT(szDb) );
|
||||
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
|
||||
if( rc==SQLITE_OK && sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
|
||||
mxSafeFrame = pWal->hdr.mxFrame;
|
||||
mxPage = pWal->hdr.nPage;
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
u32 y = pInfo->aReadMark[i];
|
||||
if( mxSafeFrame>y ){
|
||||
assert( y<=pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
}else if( rc==SQLITE_BUSY ){
|
||||
mxSafeFrame = y;
|
||||
xBusy = 0;
|
||||
}else{
|
||||
goto walcheckpoint_out;
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->nBackfill = mxSafeFrame;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the reader lock held while backfilling */
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
||||
}
|
||||
if( pInfo->nBackfill<mxSafeFrame
|
||||
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
|
||||
){
|
||||
i64 nSize; /* Current size of database file */
|
||||
u32 nBackfill = pInfo->nBackfill;
|
||||
|
||||
if( rc==SQLITE_BUSY ){
|
||||
/* Reset the return code so as not to report a checkpoint failure
|
||||
** just because there are active readers. */
|
||||
rc = SQLITE_OK;
|
||||
/* Sync the WAL to disk */
|
||||
if( sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
|
||||
/* If the database may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nReq = ((i64)mxPage * szPage);
|
||||
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
|
||||
if( rc==SQLITE_OK && nSize<nReq ){
|
||||
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Iterate through the contents of the WAL, copying data to the db file */
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
|
||||
continue;
|
||||
}
|
||||
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
|
||||
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
iOffset = (iDbpage-1)*(i64)szPage;
|
||||
testcase( IS_BIG_INT(iOffset) );
|
||||
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
|
||||
/* If work was actually accomplished... */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
|
||||
i64 szDb = pWal->hdr.nPage*(i64)szPage;
|
||||
testcase( IS_BIG_INT(szDb) );
|
||||
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
|
||||
if( rc==SQLITE_OK && sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->nBackfill = mxSafeFrame;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the reader lock held while backfilling */
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_BUSY ){
|
||||
/* Reset the return code so as not to report a checkpoint failure
|
||||
** just because there are active readers. */
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
|
||||
@@ -1820,7 +1823,7 @@ static int walCheckpoint(
|
||||
}else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
|
||||
u32 salt1;
|
||||
sqlite3_randomness(4, &salt1);
|
||||
assert( mxSafeFrame==pWal->hdr.mxFrame );
|
||||
assert( pInfo->nBackfill==pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
|
||||
|
||||
+156
-22
@@ -202,7 +202,7 @@ static void whereClauseClear(WhereClause *pWC){
|
||||
** calling this routine. Such pointers may be reinitialized by referencing
|
||||
** the pWC->a[] array.
|
||||
*/
|
||||
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
|
||||
static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
|
||||
WhereTerm *pTerm;
|
||||
int idx;
|
||||
testcase( wtFlags & TERM_VIRTUAL );
|
||||
@@ -627,7 +627,11 @@ static void exprAnalyzeAll(
|
||||
** so and false if not.
|
||||
**
|
||||
** In order for the operator to be optimizible, the RHS must be a string
|
||||
** literal that does not begin with a wildcard.
|
||||
** literal that does not begin with a wildcard. The LHS must be a column
|
||||
** that may only be NULL, a string, or a BLOB, never a number. (This means
|
||||
** that virtual tables cannot participate in the LIKE optimization.) If the
|
||||
** collating sequence for the column on the LHS must be appropriate for
|
||||
** the operator.
|
||||
*/
|
||||
static int isLikeOrGlob(
|
||||
Parse *pParse, /* Parsing and code generating context */
|
||||
@@ -656,7 +660,7 @@ static int isLikeOrGlob(
|
||||
pLeft = pList->a[1].pExpr;
|
||||
if( pLeft->op!=TK_COLUMN
|
||||
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|
||||
|| IsVirtual(pLeft->pTab)
|
||||
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
|
||||
){
|
||||
/* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
|
||||
** be the name of an indexed column with TEXT affinity. */
|
||||
@@ -1105,7 +1109,7 @@ static void exprAnalyze(
|
||||
Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */
|
||||
Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */
|
||||
int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */
|
||||
int noCase = 0; /* LIKE/GLOB distinguishes case */
|
||||
int noCase = 0; /* uppercase equivalent to lowercase */
|
||||
int op; /* Top-level operator. pExpr->op */
|
||||
Parse *pParse = pWInfo->pParse; /* Parsing context */
|
||||
sqlite3 *db = pParse->db; /* Database connection */
|
||||
@@ -1243,12 +1247,15 @@ static void exprAnalyze(
|
||||
/* Add constraints to reduce the search space on a LIKE or GLOB
|
||||
** operator.
|
||||
**
|
||||
** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
|
||||
** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints
|
||||
**
|
||||
** x>='abc' AND x<'abd' AND x LIKE 'abc%'
|
||||
** x>='ABC' AND x<'abd' AND x LIKE 'aBc%'
|
||||
**
|
||||
** The last character of the prefix "abc" is incremented to form the
|
||||
** termination condition "abd".
|
||||
** termination condition "abd". If case is not significant (the default
|
||||
** for LIKE) then the lower-bound is made all uppercase and the upper-
|
||||
** bound is made all lowercase so that the bounds also work when comparing
|
||||
** BLOBs.
|
||||
*/
|
||||
if( pWC->op==TK_AND
|
||||
&& isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
|
||||
@@ -1260,9 +1267,25 @@ static void exprAnalyze(
|
||||
int idxNew1;
|
||||
int idxNew2;
|
||||
Token sCollSeqName; /* Name of collating sequence */
|
||||
const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
|
||||
|
||||
pLeft = pExpr->x.pList->a[1].pExpr;
|
||||
pStr2 = sqlite3ExprDup(db, pStr1, 0);
|
||||
|
||||
/* Convert the lower bound to upper-case and the upper bound to
|
||||
** lower-case (upper-case is less than lower-case in ASCII) so that
|
||||
** the range constraints also work for BLOBs
|
||||
*/
|
||||
if( noCase && !pParse->db->mallocFailed ){
|
||||
int i;
|
||||
char c;
|
||||
pTerm->wtFlags |= TERM_LIKE;
|
||||
for(i=0; (c = pStr1->u.zToken[i])!=0; i++){
|
||||
pStr1->u.zToken[i] = sqlite3Toupper(c);
|
||||
pStr2->u.zToken[i] = sqlite3Tolower(c);
|
||||
}
|
||||
}
|
||||
|
||||
if( !db->mallocFailed ){
|
||||
u8 c, *pC; /* Last character before the first wildcard */
|
||||
pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
|
||||
@@ -1282,11 +1305,11 @@ static void exprAnalyze(
|
||||
sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
|
||||
sCollSeqName.n = 6;
|
||||
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
|
||||
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
|
||||
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
|
||||
sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
|
||||
pStr1, 0);
|
||||
transferJoinMarkings(pNewExpr1, pExpr);
|
||||
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
|
||||
testcase( idxNew1==0 );
|
||||
exprAnalyze(pSrc, pWC, idxNew1);
|
||||
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
|
||||
@@ -1294,7 +1317,7 @@ static void exprAnalyze(
|
||||
sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
|
||||
pStr2, 0);
|
||||
transferJoinMarkings(pNewExpr2, pExpr);
|
||||
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
|
||||
testcase( idxNew2==0 );
|
||||
exprAnalyze(pSrc, pWC, idxNew2);
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
@@ -1612,11 +1635,16 @@ static void constructAutomaticIndex(
|
||||
pLoop = pLevel->pWLoop;
|
||||
idxCols = 0;
|
||||
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */
|
||||
|| pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */
|
||||
|| pLoop->prereq!=0 ); /* table of a LEFT JOIN */
|
||||
if( pLoop->prereq==0
|
||||
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){
|
||||
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
|
||||
pPartial = sqlite3ExprAnd(pParse->db, pPartial,
|
||||
sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
|
||||
sqlite3ExprDup(pParse->db, pExpr, 0));
|
||||
}
|
||||
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
|
||||
int iCol = pTerm->u.leftColumn;
|
||||
@@ -2464,20 +2492,43 @@ static int whereInScanEst(
|
||||
** but joins might run a little slower. The trick is to disable as much
|
||||
** as we can without disabling too much. If we disabled in (1), we'd get
|
||||
** the wrong answer. See ticket #813.
|
||||
**
|
||||
** If all the children of a term are disabled, then that term is also
|
||||
** automatically disabled. In this way, terms get disabled if derived
|
||||
** virtual terms are tested first. For example:
|
||||
**
|
||||
** x GLOB 'abc*' AND x>='abc' AND x<'acd'
|
||||
** \___________/ \______/ \_____/
|
||||
** parent child1 child2
|
||||
**
|
||||
** Only the parent term was in the original WHERE clause. The child1
|
||||
** and child2 terms were added by the LIKE optimization. If both of
|
||||
** the virtual child terms are valid, then testing of the parent can be
|
||||
** skipped.
|
||||
**
|
||||
** Usually the parent term is marked as TERM_CODED. But if the parent
|
||||
** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
|
||||
** The TERM_LIKECOND marking indicates that the term should be coded inside
|
||||
** a conditional such that is only evaluated on the second pass of a
|
||||
** LIKE-optimization loop, when scanning BLOBs instead of strings.
|
||||
*/
|
||||
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
|
||||
if( pTerm
|
||||
int nLoop = 0;
|
||||
while( pTerm
|
||||
&& (pTerm->wtFlags & TERM_CODED)==0
|
||||
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
|
||||
&& (pLevel->notReady & pTerm->prereqAll)==0
|
||||
){
|
||||
pTerm->wtFlags |= TERM_CODED;
|
||||
if( pTerm->iParent>=0 ){
|
||||
WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
|
||||
if( (--pOther->nChild)==0 ){
|
||||
disableTerm(pLevel, pOther);
|
||||
}
|
||||
if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
|
||||
pTerm->wtFlags |= TERM_LIKECOND;
|
||||
}else{
|
||||
pTerm->wtFlags |= TERM_CODED;
|
||||
}
|
||||
if( pTerm->iParent<0 ) break;
|
||||
pTerm = &pTerm->pWC->a[pTerm->iParent];
|
||||
pTerm->nChild--;
|
||||
if( pTerm->nChild!=0 ) break;
|
||||
nLoop++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2961,7 +3012,34 @@ static void addScanStatus(
|
||||
# define addScanStatus(a, b, c, d) ((void)d)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** If the most recently coded instruction is a constant range contraint
|
||||
** that originated from the LIKE optimization, then change the P3 to be
|
||||
** pLoop->iLikeRepCntr and set P5.
|
||||
**
|
||||
** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
|
||||
** expression: "x>='ABC' AND x<'abd'". But this requires that the range
|
||||
** scan loop run twice, once for strings and a second time for BLOBs.
|
||||
** The OP_String opcodes on the second pass convert the upper and lower
|
||||
** bound string contants to blobs. This routine makes the necessary changes
|
||||
** to the OP_String opcodes for that to happen.
|
||||
*/
|
||||
static void whereLikeOptimizationStringFixup(
|
||||
Vdbe *v, /* prepared statement under construction */
|
||||
WhereLevel *pLevel, /* The loop that contains the LIKE operator */
|
||||
WhereTerm *pTerm /* The upper or lower bound just coded */
|
||||
){
|
||||
if( pTerm->wtFlags & TERM_LIKEOPT ){
|
||||
VdbeOp *pOp;
|
||||
assert( pLevel->iLikeRepCntr>0 );
|
||||
pOp = sqlite3VdbeGetOp(v, -1);
|
||||
assert( pOp!=0 );
|
||||
assert( pOp->opcode==OP_String8
|
||||
|| pTerm->pWC->pWInfo->pParse->db->mallocFailed );
|
||||
pOp->p3 = pLevel->iLikeRepCntr;
|
||||
pOp->p5 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code for the start of the iLevel-th loop in the WHERE clause
|
||||
@@ -3291,10 +3369,25 @@ static Bitmask codeOneLoopStart(
|
||||
if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
|
||||
pRangeStart = pLoop->aLTerm[j++];
|
||||
nExtraReg = 1;
|
||||
/* Like optimization range constraints always occur in pairs */
|
||||
assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 ||
|
||||
(pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
|
||||
}
|
||||
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
|
||||
pRangeEnd = pLoop->aLTerm[j++];
|
||||
nExtraReg = 1;
|
||||
if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
|
||||
assert( pRangeStart!=0 ); /* LIKE opt constraints */
|
||||
assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */
|
||||
pLevel->iLikeRepCntr = ++pParse->nMem;
|
||||
testcase( bRev );
|
||||
testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer,
|
||||
bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC),
|
||||
pLevel->iLikeRepCntr);
|
||||
VdbeComment((v, "LIKE loop counter"));
|
||||
pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
|
||||
}
|
||||
if( pRangeStart==0
|
||||
&& (j = pIdx->aiColumn[nEq])>=0
|
||||
&& pIdx->pTable->aCol[j].notNull==0
|
||||
@@ -3337,6 +3430,7 @@ static Bitmask codeOneLoopStart(
|
||||
if( pRangeStart ){
|
||||
Expr *pRight = pRangeStart->pExpr->pRight;
|
||||
sqlite3ExprCode(pParse, pRight, regBase+nEq);
|
||||
whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
|
||||
if( (pRangeStart->wtFlags & TERM_VNULL)==0
|
||||
&& sqlite3ExprCanBeNull(pRight)
|
||||
){
|
||||
@@ -3382,6 +3476,7 @@ static Bitmask codeOneLoopStart(
|
||||
Expr *pRight = pRangeEnd->pExpr->pRight;
|
||||
sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
|
||||
sqlite3ExprCode(pParse, pRight, regBase+nEq);
|
||||
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
|
||||
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
|
||||
&& sqlite3ExprCanBeNull(pRight)
|
||||
){
|
||||
@@ -3609,7 +3704,8 @@ static Bitmask codeOneLoopStart(
|
||||
*/
|
||||
wctrlFlags = WHERE_OMIT_OPEN_CLOSE
|
||||
| WHERE_FORCE_TABLE
|
||||
| WHERE_ONETABLE_ONLY;
|
||||
| WHERE_ONETABLE_ONLY
|
||||
| WHERE_NO_AUTOINDEX;
|
||||
for(ii=0; ii<pOrWc->nTerm; ii++){
|
||||
WhereTerm *pOrTerm = &pOrWc->a[ii];
|
||||
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
|
||||
@@ -3771,6 +3867,7 @@ static Bitmask codeOneLoopStart(
|
||||
*/
|
||||
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
|
||||
Expr *pE;
|
||||
int skipLikeAddr = 0;
|
||||
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||
testcase( pTerm->wtFlags & TERM_CODED );
|
||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
@@ -3785,7 +3882,13 @@ static Bitmask codeOneLoopStart(
|
||||
if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
|
||||
continue;
|
||||
}
|
||||
if( pTerm->wtFlags & TERM_LIKECOND ){
|
||||
assert( pLevel->iLikeRepCntr>0 );
|
||||
skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
|
||||
if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
|
||||
pTerm->wtFlags |= TERM_CODED;
|
||||
}
|
||||
|
||||
@@ -4450,6 +4553,10 @@ static int whereLoopAddBtreeIndex(
|
||||
}
|
||||
if( pTerm->prereqRight & pNew->maskSelf ) continue;
|
||||
|
||||
/* Do not allow the upper bound of a LIKE optimization range constraint
|
||||
** to mix with a lower range bound from some other source */
|
||||
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
|
||||
|
||||
pNew->wsFlags = saved_wsFlags;
|
||||
pNew->u.btree.nEq = saved_nEq;
|
||||
pNew->nLTerm = saved_nLTerm;
|
||||
@@ -4493,6 +4600,17 @@ static int whereLoopAddBtreeIndex(
|
||||
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
|
||||
pBtm = pTerm;
|
||||
pTop = 0;
|
||||
if( pTerm->wtFlags & TERM_LIKEOPT ){
|
||||
/* Range contraints that come from the LIKE optimization are
|
||||
** always used in pairs. */
|
||||
pTop = &pTerm[1];
|
||||
assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
|
||||
assert( pTop->wtFlags & TERM_LIKEOPT );
|
||||
assert( pTop->eOperator==WO_LT );
|
||||
if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
|
||||
pNew->aLTerm[pNew->nLTerm++] = pTop;
|
||||
pNew->wsFlags |= WHERE_TOP_LIMIT;
|
||||
}
|
||||
}else{
|
||||
assert( eOp & (WO_LT|WO_LE) );
|
||||
testcase( eOp & WO_LT );
|
||||
@@ -4694,7 +4812,12 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
int i;
|
||||
WhereTerm *pTerm;
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
|
||||
&& (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -4798,6 +4921,7 @@ static int whereLoopAddBtree(
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
/* Automatic indexes */
|
||||
if( !pBuilder->pOrSet
|
||||
&& (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
|
||||
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
|
||||
&& pSrc->pIndex==0
|
||||
&& !pSrc->viaCoroutine
|
||||
@@ -6583,6 +6707,16 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
|
||||
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
|
||||
}
|
||||
if( pLevel->addrLikeRep ){
|
||||
int op;
|
||||
if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
|
||||
op = OP_DecrJumpZero;
|
||||
}else{
|
||||
op = OP_JumpZeroIncr;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
if( pLevel->iLeftJoin ){
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
|
||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||
|
||||
+6
-1
@@ -69,6 +69,8 @@ struct WhereLevel {
|
||||
int addrCont; /* Jump here to continue with the next loop cycle */
|
||||
int addrFirst; /* First instruction of interior of the loop */
|
||||
int addrBody; /* Beginning of the body of this loop */
|
||||
int iLikeRepCntr; /* LIKE range processing counter register */
|
||||
int addrLikeRep; /* LIKE range processing address */
|
||||
u8 iFrom; /* Which entry in the FROM clause */
|
||||
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
|
||||
int p1, p2; /* Operands of the opcode used to ends the loop */
|
||||
@@ -253,7 +255,7 @@ struct WhereTerm {
|
||||
} u;
|
||||
LogEst truthProb; /* Probability of truth for this expression */
|
||||
u16 eOperator; /* A WO_xx value describing <op> */
|
||||
u8 wtFlags; /* TERM_xxx bit flags. See below */
|
||||
u16 wtFlags; /* TERM_xxx bit flags. See below */
|
||||
u8 nChild; /* Number of children that must disable us */
|
||||
WhereClause *pWC; /* The clause this term is part of */
|
||||
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
|
||||
@@ -275,6 +277,9 @@ struct WhereTerm {
|
||||
#else
|
||||
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
|
||||
#endif
|
||||
#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
|
||||
#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
|
||||
#define TERM_LIKE 0x400 /* The original LIKE operator */
|
||||
|
||||
/*
|
||||
** An instance of the WhereScan object is used as an iterator for locating
|
||||
|
||||
+12
-12
@@ -281,35 +281,35 @@ do_eqp_test analyze3-2.3 {
|
||||
|
||||
do_test analyze3-2.4 {
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
|
||||
} {101 0 100}
|
||||
} {102 0 100}
|
||||
do_test analyze3-2.5 {
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
|
||||
} {999 999 100}
|
||||
|
||||
do_test analyze3-2.4 {
|
||||
do_test analyze3-2.6 {
|
||||
set like "a%"
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
|
||||
} {101 0 100}
|
||||
do_test analyze3-2.5 {
|
||||
} {102 0 100}
|
||||
do_test analyze3-2.7 {
|
||||
set like "%a"
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
|
||||
} {999 999 100}
|
||||
do_test analyze3-2.6 {
|
||||
do_test analyze3-2.8 {
|
||||
set like "a"
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
|
||||
} {101 0 0}
|
||||
do_test analyze3-2.7 {
|
||||
} {102 0 0}
|
||||
do_test analyze3-2.9 {
|
||||
set like "ab"
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
|
||||
} {11 0 0}
|
||||
do_test analyze3-2.8 {
|
||||
} {12 0 0}
|
||||
do_test analyze3-2.10 {
|
||||
set like "abc"
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
|
||||
} {2 0 1}
|
||||
do_test analyze3-2.9 {
|
||||
} {3 0 1}
|
||||
do_test analyze3-2.11 {
|
||||
set like "a_c"
|
||||
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
|
||||
} {101 0 10}
|
||||
} {102 0 10}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# 2015-03-12
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# Test that deterministic scalar functions passed constant arguments
|
||||
# are used with stat4 data.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix analyzeF
|
||||
|
||||
ifcapable {!stat4} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc isqrt {i} { expr { int(sqrt($i)) } }
|
||||
db func isqrt isqrt
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x INTEGER, y INTEGER);
|
||||
WITH data(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM data
|
||||
)
|
||||
INSERT INTO t1 SELECT isqrt(i), isqrt(i) FROM data LIMIT 400;
|
||||
CREATE INDEX t1x ON t1(x);
|
||||
CREATE INDEX t1y ON t1(y);
|
||||
ANALYZE;
|
||||
}
|
||||
|
||||
proc str {a} { return $a }
|
||||
db func str str
|
||||
|
||||
# Note: tests 7 to 12 might be unstable - as they assume SQLite will
|
||||
# prefer the expression to the right of the AND clause. Which of
|
||||
# course could change.
|
||||
#
|
||||
# Note 2: tests 9 and 10 depend on the tcl interface creating functions
|
||||
# without the SQLITE_DETERMINISTIC flag set.
|
||||
#
|
||||
foreach {tn where idx} {
|
||||
1 "x = 4 AND y = 19" {t1x (x=?)}
|
||||
2 "x = 19 AND y = 4" {t1y (y=?)}
|
||||
3 "x = '4' AND y = '19'" {t1x (x=?)}
|
||||
4 "x = '19' AND y = '4'" {t1y (y=?)}
|
||||
5 "x = substr('5195', 2, 2) AND y = substr('145', 2, 1)" {t1y (y=?)}
|
||||
6 "x = substr('145', 2, 1) AND y = substr('5195', 2, 2)" {t1x (x=?)}
|
||||
|
||||
7 "x = substr('5195', 2, 2+0) AND y = substr('145', 2, 1+0)" {t1y (y=?)}
|
||||
8 "x = substr('145', 2, 1+0) AND y = substr('5195', 2, 2+0)" {t1y (y=?)}
|
||||
|
||||
9 "x = str('19') AND y = str('4')" {t1y (y=?)}
|
||||
10 "x = str('4') AND y = str('19')" {t1y (y=?)}
|
||||
|
||||
11 "x = nullif('19', 0) AND y = nullif('4', 0)" {t1y (y=?)}
|
||||
12 "x = nullif('4', 0) AND y = nullif('19', 0)" {t1y (y=?)}
|
||||
} {
|
||||
set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
|
||||
do_eqp_test 1.$tn "SELECT * FROM t1 WHERE $where" $res
|
||||
}
|
||||
|
||||
do_catchsql_test 2.1 {
|
||||
SELECT * FROM t1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3)
|
||||
} {1 {no such function: func}}
|
||||
do_catchsql_test 2.2 {
|
||||
UPDATE t1 SET y=y+1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3)
|
||||
} {1 {no such function: func}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing automatic index creation logic.
|
||||
#
|
||||
# EVIDENCE-OF: R-34271-33106 PRAGMA automatic_index; PRAGMA
|
||||
# automatic_index = boolean; Query, set, or clear the automatic indexing
|
||||
# capability.
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
@@ -49,4 +49,35 @@ do_execsql_test autoindex4-2.0 {
|
||||
ORDER BY rowid;
|
||||
} {1 123 654 | 0 555 444 | 4 234 987 |}
|
||||
|
||||
# Ticket [2326c258d02ead33d]
|
||||
# Two joins, one with and the other without an ORDER BY clause.
|
||||
# The one without ORDER BY correctly returns two rows of result.
|
||||
# The one with ORDER BY returns no rows.
|
||||
#
|
||||
do_execsql_test autoindex4-3.0 {
|
||||
CREATE TABLE A(Name text);
|
||||
CREATE TABLE Items(ItemName text , Name text);
|
||||
INSERT INTO Items VALUES('Item1','Parent');
|
||||
INSERT INTO Items VALUES('Item2','Parent');
|
||||
CREATE TABLE B(Name text);
|
||||
|
||||
SELECT Items.ItemName
|
||||
FROM Items
|
||||
LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy')
|
||||
LEFT JOIN B ON (B.Name = Items.ItemName)
|
||||
WHERE Items.Name = 'Parent'
|
||||
ORDER BY Items.ItemName;
|
||||
} {Item1 Item2}
|
||||
do_execsql_test autoindex4-3.1 {
|
||||
CREATE INDEX Items_x1 ON Items(ItemName,Name) WHERE ItemName = 'dummy';
|
||||
|
||||
SELECT Items.ItemName
|
||||
FROM Items
|
||||
LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy')
|
||||
LEFT JOIN B ON (B.Name = Items.ItemName)
|
||||
WHERE Items.Name = 'Parent'
|
||||
ORDER BY Items.ItemName;
|
||||
} {Item1 Item2}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+13
-1
@@ -452,9 +452,21 @@ proc check_data {STMT test types ints doubles strings} {
|
||||
# types
|
||||
do_test $test.1 {
|
||||
set types [list]
|
||||
foreach i $idxlist {lappend types [sqlite3_column_type $STMT $i]}
|
||||
foreach i $idxlist {
|
||||
set x [sqlite3_column_type $STMT $i]
|
||||
# EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
|
||||
# fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
|
||||
# point number string BLOB NULL
|
||||
if {[lsearch {INTEGER FLOAT TEXT BLOB NULL} $x]<0} {
|
||||
set types ERROR
|
||||
break
|
||||
} else {
|
||||
lappend types $x
|
||||
}
|
||||
}
|
||||
set types
|
||||
} $types
|
||||
|
||||
|
||||
# Integers
|
||||
do_test $test.2 {
|
||||
|
||||
+33
-1
@@ -13,7 +13,9 @@
|
||||
# focus of this script is making sure collations pass through the
|
||||
# unary + operator.
|
||||
#
|
||||
# $Id: collate8.test,v 1.2 2008/08/25 12:14:09 drh Exp $
|
||||
# 2015-02-09: Added tests to make sure COLLATE passes through function
|
||||
# calls. Ticket [ca0d20b6cdddec5e81b8d66f89c46a5583b5f6f6].
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -122,4 +124,34 @@ do_test collate8-2.8 {
|
||||
}
|
||||
} {abc}
|
||||
|
||||
# Make sure the COLLATE operator perculates up through function calls
|
||||
# and other Expr structures that use the Expr.x.pList field.
|
||||
#
|
||||
do_execsql_test collate8-3.1 {
|
||||
SELECT 'abc'==('ABC'||'') COLLATE nocase;
|
||||
SELECT 'abc'==('ABC'||'' COLLATE nocase);
|
||||
SELECT 'abc'==('ABC'||('' COLLATE nocase));
|
||||
SELECT 'abc'==('ABC'||upper('' COLLATE nocase));
|
||||
} {1 1 1 1}
|
||||
do_execsql_test collate8-3.2 {
|
||||
SELECT 'abc'==('ABC'||max('' COLLATE nocase,'' COLLATE binary));
|
||||
} {1}
|
||||
|
||||
# The COLLATE binary is on the left and so takes precedence
|
||||
do_execsql_test collate8-3.3 {
|
||||
SELECT 'abc'==('ABC'||max('' COLLATE binary,'' COLLATE nocase));
|
||||
} {0}
|
||||
|
||||
do_execsql_test collate8-3.4 {
|
||||
SELECT 'abc'==('ABC'||CASE WHEN 1-1=2 THEN '' COLLATE nocase
|
||||
ELSE '' COLLATE binary END);
|
||||
SELECT 'abc'==('ABC'||CASE WHEN 1+1=2 THEN '' COLLATE nocase
|
||||
ELSE '' COLLATE binary END);
|
||||
} {1 1}
|
||||
do_execsql_test collate8-3.5 {
|
||||
SELECT 'abc'==('ABC'||CASE WHEN 1=2 THEN '' COLLATE binary
|
||||
ELSE '' COLLATE nocase END);
|
||||
} {0}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-3
@@ -348,9 +348,9 @@ do_insert_tests e_insert-3.2 {
|
||||
6.2 "SELECT * FROM a1" {{} {} {} {}}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-46928-50290 The optional conflict-clause allows the
|
||||
# specification of an alternative constraint conflict resolution
|
||||
# algorithm to use during this one INSERT command.
|
||||
# EVIDENCE-OF: R-03235-45250 The "REPLACE" and "INSERT OR action" forms
|
||||
# specify an alternative constraint conflict resolution algorithm to use
|
||||
# during this one INSERT command.
|
||||
#
|
||||
# EVIDENCE-OF: R-23110-47146 the parser allows the use of the single
|
||||
# keyword REPLACE as an alias for "INSERT OR REPLACE".
|
||||
|
||||
+5
-4
@@ -200,10 +200,11 @@ do_test 3.4.2 {
|
||||
db close
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-22428-28959 To prevent older versions of SQLite from
|
||||
# trying to recover a WAL-mode database (and making matters worse) the
|
||||
# database file format version numbers (bytes 18 and 19 in the database
|
||||
# header) are increased from 1 to 2 in WAL mode.
|
||||
# EVIDENCE-OF: R-45540-25505 To prevent older versions of SQLite (prior
|
||||
# to version 3.7.0, 2010-07-22) from trying to recover a WAL-mode
|
||||
# database (and making matters worse) the database file format version
|
||||
# numbers (bytes 18 and 19 in the database header) are increased from 1
|
||||
# to 2 in WAL mode.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 4.1.1 { CREATE TABLE t1(x, y) }
|
||||
|
||||
+27
-2
@@ -12,8 +12,13 @@
|
||||
#
|
||||
# This file tests the PRAGMA foreign_key_check command.
|
||||
#
|
||||
# EVIDENCE-OF: R-05426-18119 PRAGMA foreign_key_check; PRAGMA
|
||||
# foreign_key_check(table-name);
|
||||
# EVIDENCE-OF: R-01427-50262 PRAGMA database.foreign_key_check; PRAGMA
|
||||
# database.foreign_key_check(table-name);
|
||||
#
|
||||
# EVIDENCE-OF: R-23918-17301 The foreign_key_check pragma checks the
|
||||
# database, or the table called "table-name", for foreign key
|
||||
# constraints that are violated and returns one row of output for each
|
||||
# violation.
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -74,6 +79,16 @@ do_test fkey5-1.2 {
|
||||
PRAGMA foreign_key_check;
|
||||
}
|
||||
} {c1 87 p1 0 c1 90 p1 0}
|
||||
do_test fkey5-1.2b {
|
||||
db eval {
|
||||
PRAGMA main.foreign_key_check;
|
||||
}
|
||||
} {c1 87 p1 0 c1 90 p1 0}
|
||||
do_test fkey5-1.2c {
|
||||
db eval {
|
||||
PRAGMA temp.foreign_key_check;
|
||||
}
|
||||
} {}
|
||||
do_test fkey5-1.3 {
|
||||
db eval {
|
||||
PRAGMA foreign_key_check(c1);
|
||||
@@ -84,6 +99,16 @@ do_test fkey5-1.4 {
|
||||
PRAGMA foreign_key_check(c2);
|
||||
}
|
||||
} {}
|
||||
do_test fkey5-1.5 {
|
||||
db eval {
|
||||
PRAGMA main.foreign_key_check(c2);
|
||||
}
|
||||
} {}
|
||||
do_test fkey5-1.6 {
|
||||
catchsql {
|
||||
PRAGMA temp.foreign_key_check(c2);
|
||||
}
|
||||
} {1 {no such table: temp.c2}}
|
||||
|
||||
# EVIDENCE-OF: R-45728-08709 There are four columns in each result row.
|
||||
#
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
# This file implements tests for SQLite library.
|
||||
#
|
||||
# The focus of this file is adding extra entries in the symbol table
|
||||
# using sqlite3_test_control(SQLITE_TESTCTRL_INITMODE) and verifying that
|
||||
# using sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER) and verifying that
|
||||
# SQLite handles those as expected.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix initmode
|
||||
set testprefix imposter
|
||||
|
||||
# Create a bunch of data to sort against
|
||||
#
|
||||
do_test initmode-1.0 {
|
||||
do_test imposter-1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d NOT NULL);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
@@ -31,15 +31,21 @@ do_test initmode-1.0 {
|
||||
INSERT INTO t1(a,b,c,d) SELECT i,1000+i,2000+i,3000+i FROM c;
|
||||
}
|
||||
set t1_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1'}]
|
||||
set t1a_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1a'}]
|
||||
set t1b_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1b'}]
|
||||
set t1c_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1c'}]
|
||||
|
||||
# Create a shadow table that uses the same b-tree as t1 but which does
|
||||
# Create an imposter table that uses the same b-tree as t1 but which does
|
||||
# not have the indexes
|
||||
#
|
||||
sqlite3_test_control SQLITE_TESTCTRL_INITMODE db 1 0 $t1_root
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $t1_root
|
||||
db eval {CREATE TABLE xt1(a,b,c,d)}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_INITMODE db 0 0 0
|
||||
|
||||
# And create an imposter table for the t1c index.
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $t1c_root
|
||||
db eval {CREATE TABLE xt1c(c,rowid,PRIMARY KEY(c,rowid))WITHOUT ROWID;}
|
||||
|
||||
# Go out of imposter mode for now.
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
|
||||
|
||||
# Create triggers to record changes to xt1.
|
||||
#
|
||||
@@ -64,10 +70,10 @@ do_test initmode-1.0 {
|
||||
# column corresponds to t1.rowid and t1.a, but the xt1.a column is always
|
||||
# NULL
|
||||
#
|
||||
do_execsql_test initmode-1.1 {
|
||||
do_execsql_test imposter-1.1 {
|
||||
SELECT rowid FROM xt1 WHERE a IS NOT NULL;
|
||||
} {}
|
||||
do_execsql_test initmode-1.2 {
|
||||
do_execsql_test imposter-1.2 {
|
||||
SELECT a,b,c,d FROM t1 EXCEPT SELECT rowid,b,c,d FROM xt1;
|
||||
SELECT rowid,b,c,d FROM xt1 EXCEPT SELECT a,b,c,d FROM t1;
|
||||
} {}
|
||||
@@ -78,7 +84,7 @@ do_execsql_test initmode-1.2 {
|
||||
# the NOT NULL constraint on t1.d, resulting in a logically inconsistent
|
||||
# database.
|
||||
#
|
||||
do_execsql_test initmode-1.3 {
|
||||
do_execsql_test imposter-1.3 {
|
||||
DELETE FROM xt1 WHERE rowid=5;
|
||||
INSERT INTO xt1(rowid,a,b,c,d) VALUES(99,'hello',1099,2022,NULL);
|
||||
SELECT * FROM chnglog ORDER BY rowid;
|
||||
@@ -87,14 +93,49 @@ do_execsql_test initmode-1.3 {
|
||||
{INSERT t1: rowid=99, a='hello', b=1099, c=2022, d=NULL} \
|
||||
]
|
||||
|
||||
do_execsql_test initmode-1.4a {
|
||||
do_execsql_test imposter-1.4a {
|
||||
PRAGMA integrity_check;
|
||||
} {/NULL value in t1.d/}
|
||||
do_execsql_test initmode-1.4b {
|
||||
do_execsql_test imposter-1.4b {
|
||||
PRAGMA integrity_check;
|
||||
} {/row # missing from index t1b/}
|
||||
do_execsql_test initmode-1.4c {
|
||||
do_execsql_test imposter-1.4c {
|
||||
PRAGMA integrity_check;
|
||||
} {/row # missing from index t1c/}
|
||||
|
||||
# Cleanup the corruption.
|
||||
# Then demonstrate that the xt1c imposter table can insert non-unique
|
||||
# and NULL values into the UNIQUE index.
|
||||
#
|
||||
do_execsql_test imposter-2.0 {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
|
||||
INSERT INTO t1(a,b,c,d) SELECT i,i,i,i FROM c;
|
||||
UPDATE xt1c SET c=NULL WHERE rowid=5;
|
||||
PRAGMA integrity_check;
|
||||
} {/row # missing from index t1c/}
|
||||
|
||||
do_execsql_test imposter-2.1 {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
|
||||
INSERT INTO t1(a,b,c,d) SELECT i,i,i,i FROM c;
|
||||
UPDATE xt1c SET c=99 WHERE rowid IN (5,7,9);
|
||||
SELECT c FROM t1 ORDER BY c;
|
||||
} {1 2 3 4 6 8 10 99 99 99}
|
||||
do_execsql_test imposter-2.2 {
|
||||
UPDATE xt1 SET c=99 WHERE rowid IN (5,7,9);
|
||||
PRAGMA integrity_check;
|
||||
} {/non-unique entry in index t1c/}
|
||||
|
||||
# Erase the imposter tables
|
||||
#
|
||||
do_test imposter-3.1 {
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 1
|
||||
db eval {
|
||||
DELETE FROM t1 WHERE rowid IN (5,7,9);
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -324,12 +324,44 @@ do_test incrblob2-6.2 {
|
||||
sqlite3_blob_read $rdHandle 0 2
|
||||
} {AB}
|
||||
|
||||
if {$::tcl_platform(pointerSize)>=8} {
|
||||
do_test incrblob2-6.2b {
|
||||
set rc [catch {
|
||||
# Prior to 2015-02-07, the following caused a segfault due to
|
||||
# integer overflow.
|
||||
sqlite3_blob_read $rdHandle 2147483647 2147483647
|
||||
} errmsg]
|
||||
lappend rc $errmsg
|
||||
} {1 SQLITE_ERROR}
|
||||
}
|
||||
do_test incrblob2-6.2c {
|
||||
set rc [catch {
|
||||
# Prior to 2015-02-07, the following caused a segfault due to
|
||||
# integer overflow.
|
||||
sqlite3_blob_read $rdHandle 2147483647 100
|
||||
} errmsg]
|
||||
lappend rc $errmsg
|
||||
} {1 SQLITE_ERROR}
|
||||
|
||||
do_test incrblob2-6.3 {
|
||||
set wrHandle [db incrblob t1 data 1]
|
||||
sqlite3_blob_write $wrHandle 0 ZZZZZZZZZZ
|
||||
sqlite3_blob_read $rdHandle 2 4
|
||||
} {ZZZZ}
|
||||
|
||||
do_test incrblob2-6.3b {
|
||||
set rc [catch {
|
||||
# Prior to 2015-02-07, the following caused a segfault due to
|
||||
# integer overflow.
|
||||
sqlite3_blob_write $wrHandle 2147483647 YYYYYYYYYYYYYYYYYY
|
||||
} errmsg]
|
||||
lappend rc $errmsg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_test incrblob2-6.3c {
|
||||
sqlite3_blob_read $rdHandle 2 4
|
||||
} {ZZZZ}
|
||||
|
||||
|
||||
do_test incrblob2-6.4 {
|
||||
close $wrHandle
|
||||
close $rdHandle
|
||||
|
||||
@@ -188,8 +188,10 @@ ifcapable wal {
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA incremental_vacuum(1);
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
} {wal}
|
||||
do_test 4.2.1 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
file size test.db-wal
|
||||
} [expr {32+2*(512+24)}]
|
||||
|
||||
|
||||
@@ -267,5 +267,64 @@ do_execsql_test index6-6.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# Test case for ticket [2326c258d02ead33d69faa63de8f4686b9b1b9d9] on
|
||||
# 2015-02-24. Any use of a partial index qualifying constraint inside
|
||||
# the ON clause of a LEFT JOIN was causing incorrect results for all
|
||||
# versions of SQLite 3.8.0 through 3.8.8.
|
||||
#
|
||||
do_execsql_test index6-7.0 {
|
||||
CREATE TABLE t7a(x);
|
||||
CREATE TABLE t7b(y);
|
||||
INSERT INTO t7a(x) VALUES(1);
|
||||
CREATE INDEX t7ax ON t7a(x) WHERE x=99;
|
||||
PRAGMA automatic_index=OFF;
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {}}
|
||||
do_execsql_test index6-7.1 {
|
||||
INSERT INTO t7b(y) VALUES(2);
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {}
|
||||
do_execsql_test index6-7.2 {
|
||||
INSERT INTO t7a(x) VALUES(99);
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {} 99 2}
|
||||
do_execsql_test index6-7.3 {
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {99 2}
|
||||
do_execsql_test index6-7.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {/USING COVERING INDEX t7ax/}
|
||||
|
||||
|
||||
do_execsql_test index6-8.0 {
|
||||
CREATE TABLE t8a(a,b);
|
||||
CREATE TABLE t8b(x,y);
|
||||
CREATE INDEX i8c ON t8b(y) WHERE x = 'value';
|
||||
|
||||
INSERT INTO t8a VALUES(1, 'one');
|
||||
INSERT INTO t8a VALUES(2, 'two');
|
||||
INSERT INTO t8a VALUES(3, 'three');
|
||||
|
||||
INSERT INTO t8b VALUES('value', 1);
|
||||
INSERT INTO t8b VALUES('dummy', 2);
|
||||
INSERT INTO t8b VALUES('value', 3);
|
||||
INSERT INTO t8b VALUES('dummy', 4);
|
||||
} {}
|
||||
|
||||
do_eqp_test index6-8.1 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t8a}
|
||||
0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)}
|
||||
}
|
||||
|
||||
do_execsql_test index6-8.2 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
1 one value 1
|
||||
2 two {} {}
|
||||
3 three value 3
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -21,6 +21,31 @@ ifcapable !vtab {
|
||||
return
|
||||
}
|
||||
|
||||
# Capture the output of a pragma in a TEMP table.
|
||||
#
|
||||
proc capture_pragma {db tabname sql} {
|
||||
$db eval "DROP TABLE IF EXISTS temp.$tabname"
|
||||
set once 1
|
||||
$db eval $sql x {
|
||||
if {$once} {
|
||||
set once 0
|
||||
set ins "INSERT INTO $tabname VALUES"
|
||||
set crtab "CREATE TEMP TABLE $tabname "
|
||||
set sep "("
|
||||
foreach col $x(*) {
|
||||
append ins ${sep}\$x($col)
|
||||
append crtab ${sep}\"$col\"
|
||||
set sep ,
|
||||
}
|
||||
append ins )
|
||||
append crtab )
|
||||
$db eval $crtab
|
||||
}
|
||||
$db eval $ins
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
load_static_extension db wholenumber;
|
||||
do_test index7-1.1 {
|
||||
# Able to parse and manage partial indices
|
||||
@@ -37,6 +62,15 @@ do_test index7-1.1 {
|
||||
}
|
||||
} {14 20 ok}
|
||||
|
||||
# (The "partial" column of the PRAGMA index_list output is...)
|
||||
# EVIDENCE-OF: R-34457-09668 "1" if the index is a partial index and "0"
|
||||
# if not.
|
||||
#
|
||||
do_test index7-1.1a {
|
||||
capture_pragma db out {PRAGMA index_list(t1)}
|
||||
db eval {SELECT "name", "partial", '|' FROM out ORDER BY "name"}
|
||||
} {sqlite_autoindex_t1_1 0 | t1a 1 | t1b 1 |}
|
||||
|
||||
# Make sure the count(*) optimization works correctly with
|
||||
# partial indices. Ticket [a5c8ed66cae16243be6] 2013-10-03.
|
||||
#
|
||||
|
||||
+46
-3
@@ -1,4 +1,4 @@
|
||||
# 2008 October 4
|
||||
# 2008-10-04
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
@@ -9,7 +9,6 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: indexedby.test,v 1.5 2009/03/22 20:36:19 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -58,20 +57,45 @@ do_execsql_test indexedby-1.4 {
|
||||
# attached to a table in the FROM clause, but not to a sub-select or
|
||||
# SQL view. Also test that specifying an index that does not exist or
|
||||
# is attached to a different table is detected as an error.
|
||||
#
|
||||
# EVIDENCE-OF: R-63761-48810 -- syntax diagram qualified-table-name
|
||||
#
|
||||
# EVIDENCE-OF: R-58230-57098 The "INDEXED BY index-name" phrase
|
||||
# specifies that the named index must be used in order to look up values
|
||||
# on the preceding table.
|
||||
#
|
||||
do_test indexedby-2.1 {
|
||||
execsql { SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'}
|
||||
} {}
|
||||
do_test indexedby-2.1b {
|
||||
execsql { SELECT * FROM main.t1 NOT INDEXED WHERE a = 'one' AND b = 'two'}
|
||||
} {}
|
||||
do_test indexedby-2.2 {
|
||||
execsql { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'}
|
||||
} {}
|
||||
do_test indexedby-2.2b {
|
||||
execsql { SELECT * FROM main.t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'}
|
||||
} {}
|
||||
do_test indexedby-2.3 {
|
||||
execsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'}
|
||||
} {}
|
||||
|
||||
# EVIDENCE-OF: R-44699-55558 The INDEXED BY clause does not give the
|
||||
# optimizer hints about which index to use; it gives the optimizer a
|
||||
# requirement of which index to use.
|
||||
# EVIDENCE-OF: R-15800-25719 If index-name does not exist or cannot be
|
||||
# used for the query, then the preparation of the SQL statement fails.
|
||||
#
|
||||
do_test indexedby-2.4 {
|
||||
catchsql { SELECT * FROM t1 INDEXED BY i3 WHERE a = 'one' AND b = 'two'}
|
||||
} {1 {no such index: i3}}
|
||||
|
||||
# EVIDENCE-OF: R-62112-42456 If the query optimizer is unable to use the
|
||||
# index specified by the INDEX BY clause, then the query will fail with
|
||||
# an error.
|
||||
do_test indexedby-2.4.1 {
|
||||
catchsql { SELECT b FROM t1 INDEXED BY i1 WHERE b = 'two' }
|
||||
} {1 {no query solution}}
|
||||
|
||||
do_test indexedby-2.5 {
|
||||
catchsql { SELECT * FROM t1 INDEXED BY i5 WHERE a = 'one' AND b = 'two'}
|
||||
} {1 {no such index: i5}}
|
||||
@@ -82,11 +106,26 @@ do_test indexedby-2.7 {
|
||||
catchsql { SELECT * FROM v1 INDEXED BY i1 WHERE a = 'one' }
|
||||
} {1 {no such index: i1}}
|
||||
|
||||
|
||||
# Tests for single table cases.
|
||||
#
|
||||
# EVIDENCE-OF: R-37002-28871 The "NOT INDEXED" clause specifies that no
|
||||
# index shall be used when accessing the preceding table, including
|
||||
# implied indices create by UNIQUE and PRIMARY KEY constraints. However,
|
||||
# the rowid can still be used to look up entries even when "NOT INDEXED"
|
||||
# is specified.
|
||||
#
|
||||
do_execsql_test indexedby-3.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a = 'one' AND b = 'two'
|
||||
} {/SEARCH TABLE t1 USING INDEX/}
|
||||
do_execsql_test indexedby-3.1.1 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
do_execsql_test indexedby-3.1.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE rowid=1
|
||||
} {/SEARCH TABLE t1 USING INTEGER PRIMARY KEY .rowid=/}
|
||||
|
||||
|
||||
do_execsql_test indexedby-3.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'
|
||||
@@ -184,6 +223,10 @@ do_execsql_test indexedby-6.2 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
|
||||
# EVIDENCE-OF: R-40297-14464 The INDEXED BY phrase forces the SQLite
|
||||
# query planner to use a particular named index on a DELETE, SELECT, or
|
||||
# UPDATE statement.
|
||||
#
|
||||
# Test that "INDEXED BY" can be used in a DELETE statement.
|
||||
#
|
||||
do_execsql_test indexedby-7.1 {
|
||||
|
||||
+2
-2
@@ -749,7 +749,7 @@ ifcapable like_opt&&!icu {
|
||||
count {
|
||||
SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
|
||||
}
|
||||
} {12 123 scan 3 like 0}
|
||||
} {12 123 scan 4 like 0}
|
||||
do_test like-10.6 {
|
||||
count {
|
||||
SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
|
||||
@@ -790,7 +790,7 @@ ifcapable like_opt&&!icu {
|
||||
count {
|
||||
SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
|
||||
}
|
||||
} {12 123 scan 3 like 0}
|
||||
} {12 123 scan 4 like 0}
|
||||
do_test like-10.15 {
|
||||
count {
|
||||
SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
# 2015-03-06
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the LIKE and GLOB operators and
|
||||
# in particular the optimizations that occur to help those operators
|
||||
# run faster and that those optimizations work correctly when there
|
||||
# are both strings and blobs being tested.
|
||||
#
|
||||
# Ticket 05f43be8fdda9fbd948d374319b99b054140bc36 shows that the following
|
||||
# SQL was not working correctly:
|
||||
#
|
||||
# CREATE TABLE t1(x TEXT UNIQUE COLLATE nocase);
|
||||
# INSERT INTO t1(x) VALUES(x'616263');
|
||||
# SELECT 'query-1', x FROM t1 WHERE x LIKE 'a%';
|
||||
# SELECT 'query-2', x FROM t1 WHERE +x LIKE 'a%';
|
||||
#
|
||||
# This script verifies that it works right now.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_execsql_test like3-1.1 {
|
||||
PRAGMA encoding=UTF8;
|
||||
CREATE TABLE t1(a,b TEXT COLLATE nocase);
|
||||
INSERT INTO t1(a,b)
|
||||
VALUES(1,'abc'),
|
||||
(2,'ABX'),
|
||||
(3,'BCD'),
|
||||
(4,x'616263'),
|
||||
(5,x'414258'),
|
||||
(6,x'424344');
|
||||
CREATE INDEX t1ba ON t1(b,a);
|
||||
|
||||
SELECT a, b FROM t1 WHERE b LIKE 'aB%' ORDER BY +a;
|
||||
} {1 abc 2 ABX 4 abc 5 ABX}
|
||||
do_execsql_test like3-1.2 {
|
||||
SELECT a, b FROM t1 WHERE +b LIKE 'aB%' ORDER BY +a;
|
||||
} {1 abc 2 ABX 4 abc 5 ABX}
|
||||
|
||||
do_execsql_test like3-2.0 {
|
||||
CREATE TABLE t2(a, b TEXT);
|
||||
INSERT INTO t2 SELECT a, b FROM t1;
|
||||
CREATE INDEX t2ba ON t2(b,a);
|
||||
SELECT a, b FROM t2 WHERE b GLOB 'ab*' ORDER BY +a;
|
||||
} {1 abc 4 abc}
|
||||
do_execsql_test like3-2.1 {
|
||||
SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a;
|
||||
} {1 abc 4 abc}
|
||||
do_execsql_test like3-2.2 {
|
||||
SELECT a, b FROM t2 WHERE b>=x'6162' AND b GLOB 'ab*'
|
||||
} {4 abc}
|
||||
do_execsql_test like3-2.3 {
|
||||
SELECT a, b FROM t2 WHERE +b>=x'6162' AND +b GLOB 'ab*'
|
||||
} {4 abc}
|
||||
do_execsql_test like3-2.4 {
|
||||
SELECT a, b FROM t2 WHERE b GLOB 'ab*' AND b>=x'6162'
|
||||
} {4 abc}
|
||||
do_execsql_test like3-2.5 {
|
||||
SELECT a, b FROM t2 WHERE +b GLOB 'ab*' AND +b>=x'6162'
|
||||
} {4 abc}
|
||||
|
||||
do_execsql_test like3-3.0 {
|
||||
CREATE TABLE t3(x TEXT PRIMARY KEY COLLATE nocase);
|
||||
INSERT INTO t3(x) VALUES('aaa'),('abc'),('abd'),('abe'),('acz');
|
||||
INSERT INTO t3(x) SELECT CAST(x AS blob) FROM t3;
|
||||
SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x;
|
||||
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
|
||||
do_execsql_test like3-3.1 {
|
||||
SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x DESC;
|
||||
} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
|
||||
do_execsql_test like3-3.1ck {
|
||||
SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x DESC;
|
||||
} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
|
||||
do_execsql_test like3-3.2 {
|
||||
SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x ASC;
|
||||
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
|
||||
do_execsql_test like3-3.2ck {
|
||||
SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x ASC;
|
||||
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
|
||||
|
||||
do_execsql_test like3-4.0 {
|
||||
CREATE TABLE t4(x TEXT COLLATE nocase);
|
||||
CREATE INDEX t4x ON t4(x DESC);
|
||||
INSERT INTO t4(x) SELECT x FROM t3;
|
||||
SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x;
|
||||
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
|
||||
do_execsql_test like3-4.1 {
|
||||
SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x DESC;
|
||||
} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
|
||||
do_execsql_test like3-4.1ck {
|
||||
SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x DESC;
|
||||
} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
|
||||
do_execsql_test like3-4.2 {
|
||||
SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x ASC;
|
||||
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
|
||||
do_execsql_test like3-4.2ck {
|
||||
SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x ASC;
|
||||
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -251,6 +251,12 @@ do_test limit-6.8 {
|
||||
# Make sure LIMIT works well with compound SELECT statements.
|
||||
# Ticket #393
|
||||
#
|
||||
# EVIDENCE-OF: R-13512-64012 In a compound SELECT, only the last or
|
||||
# right-most simple SELECT may contain a LIMIT clause.
|
||||
#
|
||||
# EVIDENCE-OF: R-03782-50113 In a compound SELECT, the LIMIT clause
|
||||
# applies to the entire compound, not just the final SELECT.
|
||||
#
|
||||
ifcapable compound {
|
||||
do_test limit-7.1.1 {
|
||||
catchsql {
|
||||
|
||||
@@ -241,6 +241,9 @@ execsql {ROLLBACK}
|
||||
|
||||
# Test the built-in busy timeout handler
|
||||
#
|
||||
# EVIDENCE-OF: R-23579-05241 PRAGMA busy_timeout; PRAGMA busy_timeout =
|
||||
# milliseconds; Query or change the setting of the busy timeout.
|
||||
#
|
||||
do_test lock-2.8 {
|
||||
db2 timeout 400
|
||||
execsql BEGIN
|
||||
|
||||
+23
-6
@@ -71,6 +71,23 @@ do_test malloc5-1.3 {
|
||||
expr $::pgalloc > 0
|
||||
} {1}
|
||||
|
||||
# The sizes of memory allocations from system malloc() might vary,
|
||||
# depending on the memory allocator algorithms used. The following
|
||||
# routine is designed to support answers that fall within a range
|
||||
# of values while also supplying easy-to-understand "expected" values
|
||||
# when errors occur.
|
||||
#
|
||||
proc value_in_range {target x args} {
|
||||
set v [lindex $args 0]
|
||||
if {$v!=""} {
|
||||
if {$v<$target*$x} {return $v}
|
||||
if {$v>$target/$x} {return $v}
|
||||
}
|
||||
return "number between [expr {int($target*$x)}] and [expr {int($target/$x)}]"
|
||||
}
|
||||
set mrange 0.98 ;# plus or minus 2%
|
||||
|
||||
|
||||
do_test malloc5-1.4 {
|
||||
# Commit the transaction and open a new one. Read 1 page into the cache.
|
||||
# Because the page is not dirty, it is eligible for collection even
|
||||
@@ -81,16 +98,16 @@ do_test malloc5-1.4 {
|
||||
BEGIN;
|
||||
SELECT * FROM abc;
|
||||
}
|
||||
sqlite3_release_memory
|
||||
} $::pgalloc
|
||||
value_in_range $::pgalloc $::mrange [sqlite3_release_memory]
|
||||
} [value_in_range $::pgalloc $::mrange]
|
||||
|
||||
do_test malloc5-1.5 {
|
||||
# Conclude the transaction opened in the previous [do_test] block. This
|
||||
# causes another page (page 1) to become eligible for recycling.
|
||||
#
|
||||
execsql { COMMIT }
|
||||
sqlite3_release_memory
|
||||
} $::pgalloc
|
||||
value_in_range $::pgalloc $::mrange [sqlite3_release_memory]
|
||||
} [value_in_range $::pgalloc $::mrange]
|
||||
|
||||
do_test malloc5-1.6 {
|
||||
# Manipulate the cache so that it contains two unused pages. One requires
|
||||
@@ -101,8 +118,8 @@ do_test malloc5-1.6 {
|
||||
SELECT * FROM abc;
|
||||
CREATE TABLE def(d, e, f);
|
||||
}
|
||||
sqlite3_release_memory 500
|
||||
} $::pgalloc
|
||||
value_in_range $::pgalloc $::mrange [sqlite3_release_memory 500]
|
||||
} [value_in_range $::pgalloc $::mrange]
|
||||
|
||||
do_test malloc5-1.7 {
|
||||
# Database should not be locked this time.
|
||||
|
||||
@@ -59,6 +59,14 @@ do_test multiplex4-1.1 {
|
||||
multiplex_file_list mx4test
|
||||
} {mx4test.db}
|
||||
|
||||
# NB: The PRAGMA multiplex_truncate command is implemented using the
|
||||
# SQLITE_FCNTL_PRAGMA file-control...
|
||||
#
|
||||
# EVIDENCE-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, an
|
||||
# SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file
|
||||
# object corresponding to the database file to which the pragma
|
||||
# statement refers.
|
||||
#
|
||||
do_test multiplex4-1.2 {
|
||||
db eval {PRAGMA multiplex_truncate}
|
||||
} {on}
|
||||
@@ -84,6 +92,16 @@ do_test multiplex4-1.9 {
|
||||
db eval {PRAGMA multiplex_truncate=0}
|
||||
} {off}
|
||||
|
||||
# EVIDENCE-OF: R-26188-08449 If the SQLITE_FCNTL_PRAGMA file control
|
||||
# returns SQLITE_OK, then the parser assumes that the VFS has handled
|
||||
# the PRAGMA itself and the parser generates a no-op prepared statement
|
||||
# if result string is NULL, or that returns a copy of the result string
|
||||
# if the string is non-NULL.
|
||||
#
|
||||
do_test multiplex4-1.9-explain {
|
||||
db eval {EXPLAIN PRAGMA multiplex_truncate=0;}
|
||||
} {/String8 \d \d \d off/}
|
||||
|
||||
do_test multiplex4-1.10 {
|
||||
db eval {
|
||||
INSERT INTO t1(x) VALUES(randomblob(250000));
|
||||
|
||||
+158
-17
@@ -51,6 +51,30 @@ ifcapable !pragma {
|
||||
return
|
||||
}
|
||||
|
||||
# Capture the output of a pragma in a TEMP table.
|
||||
#
|
||||
proc capture_pragma {db tabname sql} {
|
||||
$db eval "DROP TABLE IF EXISTS temp.$tabname"
|
||||
set once 1
|
||||
$db eval $sql x {
|
||||
if {$once} {
|
||||
set once 0
|
||||
set ins "INSERT INTO $tabname VALUES"
|
||||
set crtab "CREATE TEMP TABLE $tabname "
|
||||
set sep "("
|
||||
foreach col $x(*) {
|
||||
append ins ${sep}\$x($col)
|
||||
append crtab ${sep}\"$col\"
|
||||
set sep ,
|
||||
}
|
||||
append ins )
|
||||
append crtab )
|
||||
$db eval $crtab
|
||||
}
|
||||
$db eval $ins
|
||||
}
|
||||
}
|
||||
|
||||
# Delete the preexisting database to avoid the special setup
|
||||
# that the "all.test" script does.
|
||||
#
|
||||
@@ -59,7 +83,11 @@ delete_file test.db test.db-journal
|
||||
delete_file test3.db test3.db-journal
|
||||
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-24197-42751 PRAGMA database.cache_size; PRAGMA
|
||||
# database.cache_size = pages; PRAGMA database.cache_size = -kibibytes;
|
||||
# Query or change the suggested maximum number of database disk pages
|
||||
# that SQLite will hold in memory at once per open database file.
|
||||
#
|
||||
ifcapable pager_pragmas {
|
||||
set DFLT_CACHE_SZ [db one {PRAGMA default_cache_size}]
|
||||
set TEMP_CACHE_SZ [db one {PRAGMA temp.default_cache_size}]
|
||||
@@ -71,6 +99,8 @@ do_test pragma-1.1 {
|
||||
}
|
||||
} [list $DFLT_CACHE_SZ $DFLT_CACHE_SZ 2]
|
||||
do_test pragma-1.2 {
|
||||
# EVIDENCE-OF: R-42059-47211 If the argument N is positive then the
|
||||
# suggested cache size is set to N.
|
||||
execsql {
|
||||
PRAGMA synchronous=OFF;
|
||||
PRAGMA cache_size=1234;
|
||||
@@ -620,9 +650,10 @@ ifcapable {foreignkey} {
|
||||
}
|
||||
} {}
|
||||
do_test pragma-6.4 {
|
||||
execsql {
|
||||
capture_pragma db out {
|
||||
pragma index_list(t3);
|
||||
}
|
||||
db eval {SELECT seq, "name", "unique" FROM out ORDER BY seq}
|
||||
} {0 sqlite_autoindex_t3_1 1}
|
||||
}
|
||||
ifcapable {!foreignkey} {
|
||||
@@ -631,9 +662,43 @@ ifcapable {!foreignkey} {
|
||||
do_test pragma-6.5.1 {
|
||||
execsql {
|
||||
CREATE INDEX t3i1 ON t3(a,b);
|
||||
}
|
||||
capture_pragma db out {
|
||||
pragma index_info(t3i1);
|
||||
}
|
||||
db eval {SELECT seqno, cid, name FROM out ORDER BY seqno}
|
||||
} {0 0 a 1 1 b}
|
||||
|
||||
# EVIDENCE-OF: R-23114-21695 The auxiliary index-columns are not shown
|
||||
# by the index_info pragma, but they are listed by the index_xinfo
|
||||
# pragma.
|
||||
#
|
||||
do_test pragma-6.5.1b {
|
||||
capture_pragma db out {PRAGMA index_xinfo(t3i1)}
|
||||
db eval {SELECT seqno, cid, name FROM out ORDER BY seqno}
|
||||
} {0 0 a 1 1 b 2 -1 {}}
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-62725-03366 PRAGMA database.index_info(index-name);
|
||||
# This pragma returns one row for each key column in the named index.
|
||||
#
|
||||
# (The first column of output from PRAGMA index_info is...)
|
||||
# EVIDENCE-OF: R-34186-52914 The rank of the column within the index. (0
|
||||
# means left-most.)
|
||||
#
|
||||
# (The second column of output from PRAGMA index_info is...)
|
||||
# EVIDENCE-OF: R-65019-08383 The rank of the column within the table
|
||||
# being indexed.
|
||||
#
|
||||
# (The third column of output from PRAGMA index_info is...)
|
||||
# EVIDENCE-OF: R-09773-34266 The name of the column being indexed.
|
||||
#
|
||||
do_execsql_test pragma-6.5.1c {
|
||||
CREATE INDEX t3i2 ON t3(b,a);
|
||||
PRAGMA index_info='t3i2';
|
||||
DROP INDEX t3i2;
|
||||
} {0 1 b 1 0 a}
|
||||
|
||||
do_test pragma-6.5.2 {
|
||||
execsql {
|
||||
pragma index_info(t3i1_bogus);
|
||||
@@ -676,8 +741,10 @@ do_test pragma-6.7 {
|
||||
four REAL DEFAULT X'abcdef',
|
||||
five DEFAULT CURRENT_TIME
|
||||
);
|
||||
PRAGMA table_info(test_table);
|
||||
}
|
||||
capture_pragma db out {PRAGMA table_info(test_table)}
|
||||
db eval {SELECT cid, "name", type, "notnull", dflt_value, pk FROM out
|
||||
ORDER BY cid}
|
||||
} [concat \
|
||||
{0 one INT 1 -1 0} \
|
||||
{1 two text 0 {} 0} \
|
||||
@@ -689,14 +756,16 @@ do_test pragma-6.7 {
|
||||
# Miscellaneous tests
|
||||
#
|
||||
ifcapable schema_pragmas {
|
||||
# EVIDENCE-OF: R-63500-32024 PRAGMA database.index_list(table-name);
|
||||
# This pragma returns one row for each index associated with the given
|
||||
# table.
|
||||
do_test pragma-7.1.1 {
|
||||
# Make sure a pragma knows to read the schema if it needs to
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
pragma index_list(t3);
|
||||
}
|
||||
} {0 t3i1 0 1 sqlite_autoindex_t3_1 1}
|
||||
capture_pragma db out "PRAGMA index_list(t3)"
|
||||
db eval {SELECT name, "origin" FROM out ORDER BY name DESC}
|
||||
} {t3i1 c sqlite_autoindex_t3_1 u}
|
||||
do_test pragma-7.1.2 {
|
||||
execsql {
|
||||
pragma index_list(t3_bogus);
|
||||
@@ -1281,18 +1350,23 @@ ifcapable pager_pragmas {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-13905-26312 PRAGMA database.page_count; Return the
|
||||
# total number of pages in the database file.
|
||||
#
|
||||
do_test pragma-14.1 {
|
||||
execsql { pragma auto_vacuum = 0 }
|
||||
execsql { pragma page_count }
|
||||
} {0}
|
||||
execsql { pragma page_count; pragma main.page_count }
|
||||
} {0 0}
|
||||
|
||||
do_test pragma-14.2 {
|
||||
execsql {
|
||||
CREATE TABLE abc(a, b, c);
|
||||
PRAGMA page_count;
|
||||
PRAGMA main.page_count;
|
||||
PRAGMA temp.page_count;
|
||||
}
|
||||
} {2}
|
||||
} {2 2 0}
|
||||
do_test pragma-14.2uc {
|
||||
execsql {pragma PAGE_COUNT}
|
||||
} {2}
|
||||
@@ -1701,23 +1775,90 @@ do_test 23.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);
|
||||
CREATE INDEX i1 ON t1(b,c);
|
||||
CREATE INDEX i2 ON t1(c,d);
|
||||
CREATE INDEX i2x ON t1(d COLLATE nocase, c DESC);
|
||||
CREATE TABLE t2(x INTEGER REFERENCES t1);
|
||||
}
|
||||
db2 eval {SELECT name FROM sqlite_master}
|
||||
} {t1 i1 i2 t2}
|
||||
do_test 23.2 {
|
||||
} {t1 i1 i2 i2x t2}
|
||||
do_test 23.2a {
|
||||
db eval {
|
||||
DROP INDEX i2;
|
||||
CREATE INDEX i2 ON t1(c,d,b);
|
||||
}
|
||||
db2 eval {PRAGMA index_info(i2)}
|
||||
} {0 2 c 1 3 d 2 1 b}
|
||||
capture_pragma db2 out {PRAGMA index_info(i2)}
|
||||
db2 eval {SELECT cid, name, '|' FROM out ORDER BY seqno}
|
||||
} {2 c | 3 d | 1 b |}
|
||||
|
||||
# EVIDENCE-OF: R-44874-46325 PRAGMA database.index_xinfo(index-name);
|
||||
# This pragma returns information about every column in an index.
|
||||
#
|
||||
# EVIDENCE-OF: R-45970-35618 Unlike this index_info pragma, this pragma
|
||||
# returns information about every column in the index, not just the key
|
||||
# columns.
|
||||
#
|
||||
do_test 23.2b {
|
||||
capture_pragma db2 out {PRAGMA index_xinfo(i2)}
|
||||
db2 eval {SELECT cid, name, "desc", coll, "key", '|' FROM out ORDER BY seqno}
|
||||
} {2 c 0 BINARY 1 | 3 d 0 BINARY 1 | 1 b 0 BINARY 1 | -1 {} 0 BINARY 0 |}
|
||||
|
||||
# (The first column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-00197-14279 The rank of the column within the index. (0
|
||||
# means left-most. Key columns come before auxiliary columns.)
|
||||
#
|
||||
# (The second column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-40889-06838 The rank of the column within the table
|
||||
# being indexed, or -1 if the index-column is the rowid of the table
|
||||
# being indexed.
|
||||
#
|
||||
# (The third column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-22751-28901 The name of the column being indexed, or
|
||||
# NULL if the index-column is the rowid of the table being indexed.
|
||||
#
|
||||
# (The fourth column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-11847-09179 1 if the index-column is sorted in reverse
|
||||
# (DESC) order by the index and 0 otherwise.
|
||||
#
|
||||
# (The fifth column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-15313-19540 The name for the collating sequence used to
|
||||
# compare values in the index-column.
|
||||
#
|
||||
# (The sixth column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-14310-64553 1 if the index-column is a key column and 0
|
||||
# if the index-column is an auxiliary column.
|
||||
#
|
||||
do_test 23.2c {
|
||||
db2 eval {PRAGMA index_xinfo(i2)}
|
||||
} {0 2 c 0 BINARY 1 1 3 d 0 BINARY 1 2 1 b 0 BINARY 1 3 -1 {} 0 BINARY 0}
|
||||
do_test 23.2d {
|
||||
db2 eval {PRAGMA index_xinfo(i2x)}
|
||||
} {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0}
|
||||
|
||||
# EVIDENCE-OF: R-63500-32024 PRAGMA database.index_list(table-name);
|
||||
# This pragma returns one row for each index associated with the given
|
||||
# table.
|
||||
#
|
||||
# (The first column of output from PRAGMA index_list is...)
|
||||
# EVIDENCE-OF: R-02753-24748 A sequence number assigned to each index
|
||||
# for internal tracking purposes.
|
||||
#
|
||||
# (The second column of output from PRAGMA index_list is...)
|
||||
# EVIDENCE-OF: R-35496-03635 The name of the index.
|
||||
#
|
||||
# (The third column of output from PRAGMA index_list is...)
|
||||
# EVIDENCE-OF: R-57301-64506 "1" if the index is UNIQUE and "0" if not.
|
||||
#
|
||||
# (The fourth column of output from PRAGMA index_list is...)
|
||||
# EVIDENCE-OF: R-36609-39554 "c" if the index was created by a CREATE
|
||||
# INDEX statement, "u" if the index was created by a UNIQUE constraint,
|
||||
# or "pk" if the index was created by a PRIMARY KEY constraint.
|
||||
#
|
||||
do_test 23.3 {
|
||||
db eval {
|
||||
CREATE INDEX i3 ON t1(d,b,c);
|
||||
}
|
||||
db2 eval {PRAGMA index_list(t1)}
|
||||
} {0 i3 0 1 i2 0 2 i1 0}
|
||||
capture_pragma db2 out {PRAGMA index_list(t1)}
|
||||
db2 eval {SELECT seq, name, "unique", origin, '|' FROM out ORDER BY seq}
|
||||
} {0 i3 0 c | 1 i2 0 c | 2 i2x 0 c | 3 i1 0 c |}
|
||||
do_test 23.4 {
|
||||
db eval {
|
||||
ALTER TABLE t1 ADD COLUMN e;
|
||||
|
||||
@@ -39,6 +39,10 @@ delete_file test3.db test3.db-journal
|
||||
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
|
||||
db eval {PRAGMA auto_vacuum=0}
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-17887-14874 PRAGMA database.freelist_count; Return the
|
||||
# number of unused pages in the database file.
|
||||
#
|
||||
do_test pragma2-1.1 {
|
||||
execsql {
|
||||
PRAGMA freelist_count;
|
||||
|
||||
@@ -32,6 +32,11 @@ do_test rdonly-1.1 {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1}
|
||||
|
||||
# EVIDENCE-OF: R-29639-16887 The sqlite3_db_readonly(D,N) interface
|
||||
# returns 1 if the database N of connection D is read-only, 0 if it is
|
||||
# read/write, or -1 if N is not the name of a database on connection D.
|
||||
#
|
||||
do_test rdonly-1.1.1 {
|
||||
sqlite3_db_readonly db main
|
||||
} {0}
|
||||
|
||||
@@ -105,6 +105,10 @@ ifcapable subquery {
|
||||
}
|
||||
} {0 1 2 2 3 3 3 3}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-02644-22131 In a compound SELECT statement, only the
|
||||
# last or right-most simple SELECT may have an ORDER BY clause.
|
||||
#
|
||||
do_test select4-1.3 {
|
||||
set v [catch {execsql {
|
||||
SELECT DISTINCT log FROM t1 ORDER BY log
|
||||
|
||||
@@ -557,5 +557,61 @@ do_catchsql_test 10.8 {
|
||||
)
|
||||
} $err
|
||||
|
||||
# 2015-02-09 Ticket [2f7170d73bf9abf80339187aa3677dce3dbcd5ca]
|
||||
# "misuse of aggregate" error if aggregate column from FROM
|
||||
# subquery is used in correlated subquery
|
||||
#
|
||||
do_execsql_test 11.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(w INT, x INT);
|
||||
INSERT INTO t1(w,x)
|
||||
VALUES(1,10),(2,20),(3,30),
|
||||
(2,21),(3,31),
|
||||
(3,32);
|
||||
CREATE INDEX t1wx ON t1(w,x);
|
||||
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(w INT, y VARCHAR(8));
|
||||
INSERT INTO t2(w,y) VALUES(1,'one'),(2,'two'),(3,'three'),(4,'four');
|
||||
CREATE INDEX t2wy ON t2(w,y);
|
||||
|
||||
SELECT cnt, xyz, (SELECT y FROM t2 WHERE w=cnt), '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 one | 2 2 two | 3 3 three |}
|
||||
do_execsql_test 11.2 {
|
||||
SELECT cnt, xyz, lower((SELECT y FROM t2 WHERE w=cnt)), '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 one | 2 2 two | 3 3 three |}
|
||||
do_execsql_test 11.3 {
|
||||
SELECT cnt, xyz, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
WHERE (SELECT y FROM t2 WHERE w=cnt)!='two'
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 | 3 3 |}
|
||||
do_execsql_test 11.4 {
|
||||
SELECT cnt, xyz, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY lower((SELECT y FROM t2 WHERE w=cnt));
|
||||
} {1 1 | 3 3 | 2 2 |}
|
||||
do_execsql_test 11.5 {
|
||||
SELECT cnt, xyz,
|
||||
CASE WHEN (SELECT y FROM t2 WHERE w=cnt)=='two'
|
||||
THEN 'aaa' ELSE 'bbb'
|
||||
END, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY +cnt;
|
||||
} {1 1 bbb | 2 2 aaa | 3 3 bbb |}
|
||||
|
||||
do_execsql_test 11.100 {
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(y, z);
|
||||
SELECT ( SELECT y FROM t2 WHERE z = cnt )
|
||||
FROM ( SELECT count(*) AS cnt FROM t1 );
|
||||
} {{}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+8
-5
@@ -406,19 +406,22 @@ do_test shell1-3.11.3 {
|
||||
catchcmd "test.db" ".import FOO BAR BAD"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
|
||||
# .indices ?TABLE? Show names of all indices
|
||||
# If TABLE specified, only show indices for tables
|
||||
# .indexes ?TABLE? Show names of all indexes
|
||||
# If TABLE specified, only show indexes for tables
|
||||
# matching LIKE pattern TABLE.
|
||||
do_test shell1-3.12.1 {
|
||||
catchcmd "test.db" ".indices"
|
||||
catchcmd "test.db" ".indexes"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.2 {
|
||||
catchcmd "test.db" ".indexes FOO"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.2-legacy {
|
||||
catchcmd "test.db" ".indices FOO"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".indices FOO BAD"
|
||||
} {1 {Usage: .indices ?LIKE-PATTERN?}}
|
||||
catchcmd "test.db" ".indexes FOO BAD"
|
||||
} {1 {Usage: .indexes ?LIKE-PATTERN?}}
|
||||
|
||||
# .mode MODE ?TABLE? Set output mode where MODE is one of:
|
||||
# ascii Columns/rows delimited by 0x1F and 0x1E
|
||||
|
||||
@@ -405,4 +405,34 @@ SELECT * FROM t5;
|
||||
set x
|
||||
} "0 \{\"test 1\"\x1F,test 2<EOL>\x1Etest 3\x1Ftest 4<EOL>\x1E\}"
|
||||
|
||||
do_test shell5-4.1 {
|
||||
forcedelete shell5.csv
|
||||
set fd [open shell5.csv w]
|
||||
puts $fd "1,2,3"
|
||||
puts $fd "4,5"
|
||||
puts $fd "6,7,8"
|
||||
close $fd
|
||||
catchcmd test.db [string trim {
|
||||
.mode csv
|
||||
CREATE TABLE t6(a, b, c);
|
||||
.import shell5.csv t6
|
||||
}]
|
||||
db eval { SELECT * FROM t6 ORDER BY a }
|
||||
} {1 2 3 4 5 {} 6 7 8}
|
||||
|
||||
do_test shell5-4.2 {
|
||||
forcedelete shell5.csv
|
||||
set fd [open shell5.csv w]
|
||||
puts $fd "1,2,3"
|
||||
puts $fd "4,5"
|
||||
puts $fd "6,7,8,9"
|
||||
close $fd
|
||||
catchcmd test.db [string trim {
|
||||
.mode csv
|
||||
CREATE TABLE t7(a, b, c);
|
||||
.import shell5.csv t7
|
||||
}]
|
||||
db eval { SELECT * FROM t7 ORDER BY a }
|
||||
} {1 2 3 4 5 {} 6 7 8}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -24,6 +24,9 @@ do_test shrink-1.1 {
|
||||
INSERT INTO t1 VALUES(randomblob(1000000),1);
|
||||
}
|
||||
set ::baseline sqlite3_memory_used
|
||||
# EVIDENCE-OF: R-58814-63508 The sqlite3_db_release_memory(D) interface
|
||||
# attempts to free as much heap memory as possible from database
|
||||
# connection D.
|
||||
sqlite3_db_release_memory db
|
||||
expr {$::baseline > [sqlite3_memory_used]+500000}
|
||||
} {1}
|
||||
|
||||
@@ -24,6 +24,14 @@ ifcapable !integrityck {
|
||||
return
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-26343-45930 This pragma invokes the
|
||||
# sqlite3_soft_heap_limit64() interface with the argument N, if N is
|
||||
# specified and is a non-negative integer.
|
||||
#
|
||||
# EVIDENCE-OF: R-64451-07163 The soft_heap_limit pragma always returns
|
||||
# the same integer that would be returned by the
|
||||
# sqlite3_soft_heap_limit64(-1) C-language function.
|
||||
#
|
||||
do_test softheap1-1.0 {
|
||||
execsql {PRAGMA soft_heap_limit}
|
||||
} [sqlite3_soft_heap_limit -1]
|
||||
|
||||
+14
-1
@@ -25,7 +25,20 @@ sqlite3 db test.db
|
||||
|
||||
|
||||
# Configure the sorter to use 3 background threads.
|
||||
db eval {PRAGMA threads=3}
|
||||
#
|
||||
# EVIDENCE-OF: R-19249-32353 SQLITE_LIMIT_WORKER_THREADS The maximum
|
||||
# number of auxiliary worker threads that a single prepared statement
|
||||
# may start.
|
||||
#
|
||||
do_test sort4-init001 {
|
||||
db eval {PRAGMA threads=5}
|
||||
sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS -1
|
||||
} {5}
|
||||
do_test sort4-init002 {
|
||||
sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS 3
|
||||
db eval {PRAGMA threads}
|
||||
} {3}
|
||||
|
||||
|
||||
# Minimum number of seconds to run for. If the value is 0, each test
|
||||
# is run exactly once. Otherwise, tests are repeated until the timeout
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ static const char zHelp[] =
|
||||
" --explain Like --sqlonly but with added EXPLAIN keywords\n"
|
||||
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
|
||||
" --incrvacuum Enable incremenatal vacuum mode\n"
|
||||
" --journalmode M Set the journal_mode to MODE\n"
|
||||
" --journal M Set the journal_mode to M\n"
|
||||
" --key KEY Set the encryption key to KEY\n"
|
||||
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
|
||||
" --nosync Set PRAGMA synchronous=OFF\n"
|
||||
|
||||
@@ -250,6 +250,9 @@ do_test sqllimits1-4.10.1 {
|
||||
# Test cases sqllimits1-5.* test that the SQLITE_MAX_LENGTH limit
|
||||
# is enforced.
|
||||
#
|
||||
# EVIDENCE-OF: R-61987-00541 SQLITE_LIMIT_LENGTH The maximum size of any
|
||||
# string or BLOB or table row, in bytes.
|
||||
#
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set LARGESIZE 99999
|
||||
@@ -406,6 +409,9 @@ unset strvalue
|
||||
# Test cases sqllimits1-6.* test that the SQLITE_MAX_SQL_LENGTH limit
|
||||
# is enforced.
|
||||
#
|
||||
# EVIDENCE-OF: R-09808-17554 SQLITE_LIMIT_SQL_LENGTH The maximum length
|
||||
# of an SQL statement, in bytes.
|
||||
#
|
||||
do_test sqllimits1-6.1 {
|
||||
sqlite3_limit db SQLITE_LIMIT_SQL_LENGTH 50000
|
||||
set sql "SELECT 1 WHERE 1==1"
|
||||
@@ -567,6 +573,11 @@ do_test sqllimits1-7.7.4 {
|
||||
#--------------------------------------------------------------------
|
||||
# Test cases sqllimits1-8.* test the SQLITE_MAX_COLUMN limit.
|
||||
#
|
||||
# EVIDENCE-OF: R-43996-29471 SQLITE_LIMIT_COLUMN The maximum number of
|
||||
# columns in a table definition or in the result set of a SELECT or the
|
||||
# maximum number of columns in an index or in an ORDER BY or GROUP BY
|
||||
# clause.
|
||||
#
|
||||
set SQLITE_LIMIT_COLUMN 200
|
||||
sqlite3_limit db SQLITE_LIMIT_COLUMN $SQLITE_LIMIT_COLUMN
|
||||
do_test sqllimits1-8.1 {
|
||||
@@ -670,6 +681,9 @@ do_test sqllimits1-8.11 {
|
||||
# limit is enforced. The limit refers to the number of terms in
|
||||
# the expression.
|
||||
#
|
||||
# EVIDENCE-OF: R-12723-08526 SQLITE_LIMIT_EXPR_DEPTH The maximum depth
|
||||
# of the parse tree on any expression.
|
||||
#
|
||||
if {$SQLITE_MAX_EXPR_DEPTH==0} {
|
||||
puts -nonewline stderr "WARNING: Compile with -DSQLITE_MAX_EXPR_DEPTH to run "
|
||||
puts stderr "tests sqllimits1-9.X"
|
||||
@@ -729,6 +743,9 @@ if 0 {
|
||||
# Test the SQLITE_LIMIT_FUNCTION_ARG limit works. Test case names
|
||||
# match the pattern "sqllimits1-11.*".
|
||||
#
|
||||
# EVIDENCE-OF: R-59001-45278 SQLITE_LIMIT_FUNCTION_ARG The maximum
|
||||
# number of arguments on a function.
|
||||
#
|
||||
for {set max 5} {$max<=$SQLITE_MAX_FUNCTION_ARG} {incr max} {
|
||||
do_test sqllimits1-11.$max.1 {
|
||||
set vals [list]
|
||||
@@ -762,6 +779,9 @@ for {set max 5} {$max<=$SQLITE_MAX_FUNCTION_ARG} {incr max} {
|
||||
#--------------------------------------------------------------------
|
||||
# Test cases sqllimits1-12.*: Test the SQLITE_MAX_ATTACHED limit.
|
||||
#
|
||||
# EVIDENCE-OF: R-41778-26203 SQLITE_LIMIT_ATTACHED The maximum number of
|
||||
# attached databases.
|
||||
#
|
||||
ifcapable attach {
|
||||
do_test sqllimits1-12.1 {
|
||||
set max $::SQLITE_MAX_ATTACHED
|
||||
@@ -785,6 +805,9 @@ ifcapable attach {
|
||||
# Test cases sqllimits1-13.*: Check that the SQLITE_MAX_VARIABLE_NUMBER
|
||||
# limit works.
|
||||
#
|
||||
# EVIDENCE-OF: R-42363-29104 SQLITE_LIMIT_VARIABLE_NUMBER The maximum
|
||||
# index number of any parameter in an SQL statement.
|
||||
#
|
||||
do_test sqllimits1-13.1 {
|
||||
set max $::SQLITE_MAX_VARIABLE_NUMBER
|
||||
catchsql "SELECT ?[expr {$max+1}] FROM t1"
|
||||
@@ -806,6 +829,9 @@ do_test sqllimits1-13.2 {
|
||||
# implementation by overriding the like() scalar function bypasses
|
||||
# this limitation.
|
||||
#
|
||||
# EVIDENCE-OF: R-12940-37052 SQLITE_LIMIT_LIKE_PATTERN_LENGTH The
|
||||
# maximum length of the pattern argument to the LIKE or GLOB operators.
|
||||
#
|
||||
# These tests check that the limit is not incorrectly applied to
|
||||
# the left-hand-side of the LIKE operator (the string being tested
|
||||
# against the pattern).
|
||||
|
||||
@@ -390,6 +390,87 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
} [wal_file_size 2 1024]
|
||||
|
||||
}
|
||||
|
||||
# Test that FULL, RESTART and TRUNCATE callbacks block on other clients
|
||||
# and truncate the wal file as required even if the entire wal file has
|
||||
# already been checkpointed when they are invoked.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
|
||||
code1 $do_wal_checkpoint
|
||||
code2 $do_wal_checkpoint
|
||||
code3 $do_wal_checkpoint
|
||||
|
||||
do_test 5.$tn.1 {
|
||||
sql1 {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA auto_vacuum = 0;
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA synchronous = normal;
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE INDEX i1 ON t1(x, y);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
}
|
||||
file size test.db-wal
|
||||
} [wal_file_size 10 1024]
|
||||
|
||||
do_test 5.$tn.2 {
|
||||
sql2 { BEGIN; SELECT * FROM t1 }
|
||||
} {1 2 3 4 5 6}
|
||||
|
||||
do_test 5.$tn.3 { do_wal_checkpoint db -mode passive } {0 10 10}
|
||||
|
||||
do_test 5.$tn.4 {
|
||||
sql3 { BEGIN; INSERT INTO t1 VALUES(7, 8); }
|
||||
} {}
|
||||
|
||||
do_test 5.$tn.5 { do_wal_checkpoint db -mode passive } {0 10 10}
|
||||
do_test 5.$tn.6 { do_wal_checkpoint db -mode full } {1 10 10}
|
||||
|
||||
do_test 5.$tn.7 { sql3 { ROLLBACK } } {}
|
||||
|
||||
do_test 5.$tn.8 { do_wal_checkpoint db -mode full } {0 10 10}
|
||||
do_test 5.$tn.9 { do_wal_checkpoint db -mode truncate } {1 10 10}
|
||||
|
||||
do_test 5.$tn.10 {
|
||||
file size test.db-wal
|
||||
} [wal_file_size 10 1024]
|
||||
|
||||
proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 }
|
||||
db busy xBusyHandler
|
||||
|
||||
do_test 5.$tn.11 { do_wal_checkpoint db -mode truncate } {0 0 0}
|
||||
do_test 5.$tn.12 { file size test.db-wal } 0
|
||||
|
||||
do_test 5.$tn.13 {
|
||||
sql1 {
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
do_test 5.$tn.14 {
|
||||
sql2 { BEGIN; SELECT * FROM t1 }
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
proc xBusyHandler {n} { return 1 }
|
||||
do_test 5.$tn.15 { do_wal_checkpoint db -mode truncate } {1 4 4}
|
||||
do_test 5.$tn.16 { file size test.db-wal } [wal_file_size 4 1024]
|
||||
|
||||
do_test 5.$tn.17 { do_wal_checkpoint db -mode restart } {1 4 4}
|
||||
|
||||
proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 }
|
||||
db busy xBusyHandler
|
||||
do_test 5.$tn.18 { do_wal_checkpoint db -mode restart } {0 4 4}
|
||||
do_test 5.$tn.19 { file size test.db-wal } [wal_file_size 4 1024]
|
||||
|
||||
do_test 5.$tn.20 { do_wal_checkpoint db -mode truncate } {0 0 0}
|
||||
do_test 5.$tn.21 { file size test.db-wal } 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -66,11 +66,11 @@ do_test where8-1.3 {
|
||||
|
||||
do_test where8-1.4 {
|
||||
execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' }
|
||||
} {IX X III II 0 0 9}
|
||||
} {IX X III II 0 0 10}
|
||||
|
||||
do_test where8-1.5 {
|
||||
execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' }
|
||||
} {IX X V IV 0 0 9}
|
||||
} {IX X V IV 0 0 10}
|
||||
|
||||
do_test where8-1.6 {
|
||||
execsql_status { SELECT c FROM t1 WHERE a = 1 OR b = 'three' ORDER BY rowid }
|
||||
|
||||
+44
-23
@@ -4,10 +4,10 @@
|
||||
#
|
||||
# To add new pragmas, first add the name and other relevant attributes
|
||||
# of the pragma to the "pragma_def" object below. Then run this script
|
||||
# to generate the C-code for the lookup table and copy/paste the output
|
||||
# of this script into the appropriate spot in the pragma.c source file.
|
||||
# to generate the ../src/pragma.h header file that contains macros and
|
||||
# the lookup table needed for pragma name lookup in the pragma.c module.
|
||||
# Then add the extra "case PragTyp_XXXXX:" and subsequent code for the
|
||||
# new pragma.
|
||||
# new pragma in ../src/pragma.c.
|
||||
#
|
||||
|
||||
set pragma_def {
|
||||
@@ -205,6 +205,14 @@ set pragma_def {
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_info
|
||||
TYPE: INDEX_INFO
|
||||
ARG: 0
|
||||
FLAG: NeedSchema
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_xinfo
|
||||
TYPE: INDEX_INFO
|
||||
ARG: 1
|
||||
FLAG: NeedSchema
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
@@ -308,7 +316,20 @@ set pragma_def {
|
||||
|
||||
NAME: threads
|
||||
}
|
||||
fconfigure stdout -translation lf
|
||||
|
||||
# Open the output file
|
||||
#
|
||||
set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
|
||||
puts "Overwriting $destfile with new pragma table..."
|
||||
set fd [open $destfile wb]
|
||||
puts $fd {/* DO NOT EDIT!
|
||||
** This file is automatically generated by the script at
|
||||
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
||||
** that script and rerun it.
|
||||
*/}
|
||||
|
||||
# Parse the PRAGMA table above.
|
||||
#
|
||||
set name {}
|
||||
set type {}
|
||||
set if {}
|
||||
@@ -362,7 +383,7 @@ foreach name $allnames {
|
||||
set if [lindex $allbyname($name) 2]
|
||||
if {[regexp SQLITE_DEBUG $if] || [regexp SQLITE_HAS_CODEC $if]} continue
|
||||
set seentype($type) 1
|
||||
puts [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
incr pnum
|
||||
}
|
||||
foreach name $allnames {
|
||||
@@ -371,14 +392,14 @@ foreach name $allnames {
|
||||
set if [lindex $allbyname($name) 2]
|
||||
if {[regexp SQLITE_DEBUG $if]} continue
|
||||
set seentype($type) 1
|
||||
puts [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
incr pnum
|
||||
}
|
||||
foreach name $allnames {
|
||||
set type [lindex $allbyname($name) 0]
|
||||
if {[info exists seentype($type)]} continue
|
||||
set seentype($type) 1
|
||||
puts [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
incr pnum
|
||||
}
|
||||
|
||||
@@ -386,18 +407,18 @@ foreach name $allnames {
|
||||
#
|
||||
set fv 1
|
||||
foreach f [lsort [array names allflags]] {
|
||||
puts [format {#define PragFlag_%-20s 0x%02x} $f $fv]
|
||||
puts $fd [format {#define PragFlag_%-20s 0x%02x} $f $fv]
|
||||
set fv [expr {$fv*2}]
|
||||
}
|
||||
|
||||
# Generate the lookup table
|
||||
#
|
||||
puts "static const struct sPragmaNames \173"
|
||||
puts " const char *const zName; /* Name of pragma */"
|
||||
puts " u8 ePragTyp; /* PragTyp_XXX value */"
|
||||
puts " u8 mPragFlag; /* Zero or more PragFlag_XXX values */"
|
||||
puts " u32 iArg; /* Extra argument */"
|
||||
puts "\175 aPragmaNames\[\] = \173"
|
||||
puts $fd "static const struct sPragmaNames \173"
|
||||
puts $fd " const char *const zName; /* Name of pragma */"
|
||||
puts $fd " u8 ePragTyp; /* PragTyp_XXX value */"
|
||||
puts $fd " u8 mPragFlag; /* Zero or more PragFlag_XXX values */"
|
||||
puts $fd " u32 iArg; /* Extra argument */"
|
||||
puts $fd "\175 aPragmaNames\[\] = \173"
|
||||
|
||||
set current_if {}
|
||||
set spacer [format { %26s } {}]
|
||||
@@ -406,13 +427,13 @@ foreach name $allnames {
|
||||
if {$if!=$current_if} {
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
puts "#endif"
|
||||
puts $fd "#endif"
|
||||
}
|
||||
}
|
||||
set current_if $if
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
puts "#if $this_if"
|
||||
puts $fd "#if $this_if"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,17 +443,17 @@ foreach name $allnames {
|
||||
} else {
|
||||
set flagx PragFlag_[join $flag {|PragFlag_}]
|
||||
}
|
||||
puts " \173 /* zName: */ \"$name\","
|
||||
puts " /* ePragTyp: */ PragTyp_$type,"
|
||||
puts " /* ePragFlag: */ $flagx,"
|
||||
puts " /* iArg: */ $arg \175,"
|
||||
puts $fd " \173 /* zName: */ \"$name\","
|
||||
puts $fd " /* ePragTyp: */ PragTyp_$type,"
|
||||
puts $fd " /* ePragFlag: */ $flagx,"
|
||||
puts $fd " /* iArg: */ $arg \175,"
|
||||
}
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
puts "#endif"
|
||||
puts $fd "#endif"
|
||||
}
|
||||
}
|
||||
puts "\175;"
|
||||
puts $fd "\175;"
|
||||
|
||||
# count the number of pragmas, for information purposes
|
||||
#
|
||||
@@ -444,4 +465,4 @@ foreach name $allnames {
|
||||
if {[regexp {^defined} $if] || [regexp {[^!]defined} $if]} continue
|
||||
incr dfltcnt
|
||||
}
|
||||
puts "/* Number of pragmas: $dfltcnt on by default, $allcnt total. */"
|
||||
puts $fd "/* Number of pragmas: $dfltcnt on by default, $allcnt total. */"
|
||||
|
||||
@@ -110,6 +110,7 @@ foreach hdr {
|
||||
pager.h
|
||||
parse.h
|
||||
pcache.h
|
||||
pragma.h
|
||||
rtree.h
|
||||
sqlite3ext.h
|
||||
sqlite3.h
|
||||
@@ -118,6 +119,7 @@ foreach hdr {
|
||||
sqliteLimit.h
|
||||
vdbe.h
|
||||
vdbeInt.h
|
||||
vxworks.h
|
||||
wal.h
|
||||
whereInt.h
|
||||
} {
|
||||
|
||||
+27
-8
@@ -4,6 +4,24 @@
|
||||
#
|
||||
|
||||
if {[catch {
|
||||
|
||||
# Argument $tname is the name of a table within the database opened by
|
||||
# database handle [db]. Return true if it is a WITHOUT ROWID table, or
|
||||
# false otherwise.
|
||||
#
|
||||
proc is_without_rowid {tname} {
|
||||
set t [string map {' ''} $tname]
|
||||
db eval "PRAGMA index_list = '$t'" o {
|
||||
if {$o(origin) == "pk"} {
|
||||
set n $o(name)
|
||||
if {0==[db one { SELECT count(*) FROM sqlite_master WHERE name=$n }]} {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get the name of the database to analyze
|
||||
#
|
||||
proc usage {} {
|
||||
@@ -167,20 +185,21 @@ set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 }
|
||||
foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
|
||||
|
||||
set is_index [expr {$name!=$tblname}]
|
||||
set idx_btree [expr {$is_index || [is_without_rowid $name]}]
|
||||
db eval {
|
||||
SELECT
|
||||
sum(ncell) AS nentry,
|
||||
sum(isleaf(pagetype, $is_index) * ncell) AS leaf_entries,
|
||||
sum(isleaf(pagetype, $idx_btree) * ncell) AS leaf_entries,
|
||||
sum(payload) AS payload,
|
||||
sum(isoverflow(pagetype, $is_index) * payload) AS ovfl_payload,
|
||||
sum(isoverflow(pagetype, $idx_btree) * payload) AS ovfl_payload,
|
||||
sum(path LIKE '%+000000') AS ovfl_cnt,
|
||||
max(mx_payload) AS mx_payload,
|
||||
sum(isinternal(pagetype, $is_index)) AS int_pages,
|
||||
sum(isleaf(pagetype, $is_index)) AS leaf_pages,
|
||||
sum(isoverflow(pagetype, $is_index)) AS ovfl_pages,
|
||||
sum(isinternal(pagetype, $is_index) * unused) AS int_unused,
|
||||
sum(isleaf(pagetype, $is_index) * unused) AS leaf_unused,
|
||||
sum(isoverflow(pagetype, $is_index) * unused) AS ovfl_unused,
|
||||
sum(isinternal(pagetype, $idx_btree)) AS int_pages,
|
||||
sum(isleaf(pagetype, $idx_btree)) AS leaf_pages,
|
||||
sum(isoverflow(pagetype, $idx_btree)) AS ovfl_pages,
|
||||
sum(isinternal(pagetype, $idx_btree) * unused) AS int_unused,
|
||||
sum(isleaf(pagetype, $idx_btree) * unused) AS leaf_unused,
|
||||
sum(isoverflow(pagetype, $idx_btree) * unused) AS ovfl_unused,
|
||||
sum(pgsize) AS compressed_size
|
||||
FROM temp.dbstat WHERE name = $name
|
||||
} break
|
||||
|
||||
Reference in New Issue
Block a user