Compare commits

..

46 Commits

Author SHA1 Message Date
drh 536a409396 In the command-line shell, change the units on the ".width" separate from
bytes to characters.

FossilOrigin-Name: b1a9e2916f5b4adef91c34563f71b98e79a10c12
2015-02-26 14:27:16 +00:00
drh c941a4b3b6 Simplifications to the description of the nByte parameter to sqlite3_prepare()
and friends.

FossilOrigin-Name: 4bee8295e36fb61f903210b6d052ee9b8fb3b6d0
2015-02-26 02:33:52 +00:00
drh cbb3f33c56 Make sure the sqlite3_mutex.id field is initialized in the Win32
mutex implementation, even when SQLITE_DEBUG is turned off.

FossilOrigin-Name: 6d132e7a224ee68b5cefe9222944aac5760ffc20
2015-02-25 14:25:31 +00:00
drh b492e23b42 Add support for the linenoise command-line editing library in shell.c.
FossilOrigin-Name: 03bbb947192b0c28d960604eae12e5fc2fa6e74e
2015-02-25 13:48:10 +00:00
dan fd34d6d379 Add support for linenoise to shell.c.
FossilOrigin-Name: f7f2598c376a27a86acc21578779c03d0016cd30
2015-02-25 10:54:53 +00:00
mistachkin 8d8738eae0 When cleaning with MSVC, prevent superfluous output regarding 'missing' files and directories.
FossilOrigin-Name: 034c16bd24ddca363946a4b8751418469d890d2a
2015-02-25 01:06:08 +00:00
drh 13cc90cfa2 Remove an always-false conditional from constructAutomaticIndex(). Put an
assert() in its place to prove that the conditional is always false.

FossilOrigin-Name: 3af300bf6f5bee0b51a4c1ac1dc3879771378bff
2015-02-25 00:24:41 +00:00
dan 2a45cb5c0e Prevent partial indexes on the table on the left hand side of a LEFT JOIN from being incorrectly qualified by a constraint in the ON clause of the join. This relaxes the rule introduced by the previous commit (as the partial indexes on the table on the rhs of the LEFT JOIN may now be qualified by terms within the ON clause).
FossilOrigin-Name: 1d6fb43a576d335d2717e94d28385178c23c81a1
2015-02-24 20:10:49 +00:00
drh 690429a08f Make sure partial indexes are not qualified incorrectly by a constraint that
is inside the ON clause of a LEFT JOIN.  Fix for ticket [2326c258d02ead33].

FossilOrigin-Name: 491cfe9b3f87f5fcc579f953745012cea8d64db7
2015-02-24 20:04:59 +00:00
drh e006a86643 More test cases to help ensure that partial indexes do not get used if their
qualifing constraint is inside the ON clause of a LEFT JOIN.

FossilOrigin-Name: c6399958a17e8b7c1798a9240fb06bffc774b332
2015-02-24 18:39:00 +00:00
drh 077f06edfa This additional fix prevents a partial index from being qualified for use
if the constraint that qualifies the partial index is part of the ON clause of
a LEFT JOIN.

FossilOrigin-Name: 1a1516e4da26dcee35e6fbb6604ce252faf3d116
2015-02-24 16:48:59 +00:00
drh 36f65bafe5 Make sure partial automatic indexes are not based on terms in the ON clause
of a LEFT JOIN.  Fix for ticket [2326c258d02ead3].

FossilOrigin-Name: c0f4e308a508183b72ceda447dc3ac778cb85b9f
2015-02-24 16:05:54 +00:00
drh d4ef026ebb Update document on sqlite3_mprintf() and related functions. Discuss the
%w format and point out that obscure ANSI-C formats are not supported.
No changes to code.

FossilOrigin-Name: f8917ba4d917bc762b3b252466ab72a8a70dc0d8
2015-02-21 15:42:57 +00:00
drh 2da47d3869 Fix a compiler warning associated with USE_PREAD64.
FossilOrigin-Name: c299e55a661c04f71ab43cb8aed04f8ece6e0567
2015-02-21 00:56:05 +00:00
drh e6d4173b78 Fix over-length source code lines in os_unix.c.
FossilOrigin-Name: 7560a9fa50236ecaa0617f1ab5bb5662f4a61c72
2015-02-21 00:49:00 +00:00
drh ad0961b31b Keep track of the optimal number of reserved bytes (by looking at reserve
byte requests in calls to sqlite3BtreeSetPageSize()) and then change the
reserve byte count to the optimal when doing a VACUUM or when using the
backup API.

FossilOrigin-Name: 28c2b726285ea88b334acfd6390a057d2d244838
2015-02-21 00:19:25 +00:00
drh db222adfd3 Fix errors in the EBCDIC upper-case to lower-case translation table.
FossilOrigin-Name: 905009f6723040d4da4776b6fd07e83c628dea2b
2015-02-19 17:16:14 +00:00
drh a712b4bb97 Remove a redundant call to statfs() in the xOpen() method of the unix VFS.
Also fix an unused local variable warning.

FossilOrigin-Name: 8215727dda384351765ab1d5c53ea80775b4ec65
2015-02-19 16:12:04 +00:00
drh 4bf66fd6f3 Move the os_unix.c file closer to apple-osx.
FossilOrigin-Name: 81f242e338d6122e27aad86986bfd140012c6582
2015-02-19 02:43:02 +00:00
drh 883ad04985 First small steps toward brining trunk and apple-osx closer together.
FossilOrigin-Name: 28284ccc0d7301503f6d2d7bee9093738d52e331
2015-02-19 00:29:11 +00:00
drh 96c707a3c2 Improvements to SQLITE_ENABLE_API_ARMOR.
FossilOrigin-Name: 823ad40ccb5b51aaa0d5a48da63b465df9d0649a
2015-02-13 16:36:14 +00:00
drh 983b5ee73d Make sure the prepared statement auto-resets on extended error codes
of SQLITE_BUSY and SQLITE_LOCKED even when compiled using
SQLITE_OMIT_AUTORESET.

FossilOrigin-Name: 3c6ca414879feb1f5d31d5fd95a1737530aca624
2015-02-13 12:05:56 +00:00
mistachkin a0efb1ae11 For the shell '.import' command, make sure the last column value present is considered before NULL filling any missing ones.
FossilOrigin-Name: 9c5bcad1f7d04c16f3ec7fc483280059ae93961b
2015-02-12 22:45:25 +00:00
drh 6728cd9180 Propagate COLLATE operators upward through function calls and CASE operations.
And do not flatten an aggregate subquery into a query that uses other
subqueries.  Fixes for tickets [ca0d20b6cdddec5] and
[2f7170d73bf9], respectively.

FossilOrigin-Name: 24e78b8d65734a6a8ae21a20542cd1839e756fb1
2015-02-09 18:28:03 +00:00
dan 9fab5ed01f Fix WITHOUT ROWID table handing in sqlite3_analyzer.
FossilOrigin-Name: 937e0fe7008c0f76b6a584180df9a9457166a0b1
2015-02-09 17:46:11 +00:00
drh 2c5e9b5672 Add test cases for the query flattener fix for
ticket [2f7170d73bf9abf8].

FossilOrigin-Name: dd8f7f7511639a1baa41a6ff2e359dc6f1e66943
2015-02-09 16:34:33 +00:00
drh 2308ed3854 Propagate the COLLATE operator upward through function calls.
Initial fix for ticket [ca0d20b6cdddec5e8].

FossilOrigin-Name: c053448a55f9d030e8ffe88cf4fc14ada7f6ec19
2015-02-09 16:09:34 +00:00
drh 885a5b030e Disable the query flattener for aggregate subqueries if the parent query
uses other subqueries in its result set or WHERE clause or ORDER BY clause.
Preliminary fix for ticket [2f7170d73bf9abf8].  However it still contains
a defect similar to the COLLATE problem of [ca0d20b6cddd].

FossilOrigin-Name: 0b7d65e3fda676d193347cb782854c28a48252af
2015-02-09 15:21:36 +00:00
drh 63f845734e Rename the internal "EP_Constant" bitmask to a less misleading "EP_ConstFunc".
FossilOrigin-Name: 4ef7ceced2b0000d21f7f8014384c04a0e4661d3
2015-02-09 14:07:07 +00:00
drh 17645f5eec In selecttrace 0x100 mode, show the parse tree after name resolution instead
of before flattening, so that it is always seen even if flattening does not
occur.  Also: add the hex pointer value to the top of each SELECT tree.

FossilOrigin-Name: aa093fef2d2a7e26d987b46654963e4d7e66d444
2015-02-09 13:42:59 +00:00
drh 0e86a1ac08 In selecttrace mode 0x100, show a complete parse-tree both before and after
query flattening.  This is a change to debugging code only.

FossilOrigin-Name: b3c6b8a3c1075d2a87cef68f061d6a0098e6d8d0
2015-02-09 11:54:41 +00:00
drh 31e7147dfa Fix over-length source code lines in resolver.c. No logic changes.
FossilOrigin-Name: c12edb85076d0832e3a0abbbba4d07f3cb5d7f0e
2015-02-09 10:20:19 +00:00
drh d10d18da5f Fix potential 32-bit integer overflow problems on the offset and length
parameters to sqlite3_blob_read() and sqlite3_blob_write().  For
sqlite3_blob_open(), make sure the *ppBlob return parameter is zeroed if
the interface fails with SQLITE_MISUSE.

FossilOrigin-Name: 5df02f50f8348dfde4fc15126abc7b7ef7803e69
2015-02-07 15:16:35 +00:00
drh 0e55db1cd8 Change the name of ".info" to ".dbinfo" and add an optional second argument
which is the ATTACH-ed DB about which information is provided.  Provide
".indexes" as an alternative name to the legacy ".indices" command.

FossilOrigin-Name: 0f65a7e2e09f801b66897479d501607caeae4abf
2015-02-06 14:51:13 +00:00
drh f7502f005e Add the ".info" command to the shell.
FossilOrigin-Name: 0a3100a7f264ffce6078c35e341f2f0af6c09fbb
2015-02-06 14:19:44 +00:00
drh fe0e84c948 Add the index_xinfo pragma which gives information about the fields that
reference the table PRIMARY KEY in addition to the index key fields.
Add extra columns "desc", "coll", and "key" to the index_info and index_xinfo
pragmas.  Add the "origin" and "partial" columns to the index_list pragma.

FossilOrigin-Name: 2743846cdba572f616f56d310633703b8b50959e
2015-02-06 01:07:15 +00:00
drh 4bb8cb0927 Merge all recent trunk changes, including the movement of the pragma
table into the separate pragma.h header file.

FossilOrigin-Name: 3af19f84446ba5fc1ed754d0d73f6a6d7fb2f365
2015-02-04 23:13:48 +00:00
drh 8fb15e3b20 Fix a missing mutex in SQLITE_TESTCTRL_IMPOSTER.
FossilOrigin-Name: 71691c4be54b9ac6a35e35013f939b7d6fd4e6b8
2015-02-04 20:56:49 +00:00
drh 1dae26bdab Fix a typo in the --help output for speedtest1. Fix a dependency error
in the Makefile.in for speedtest1.

FossilOrigin-Name: f30a057aeeac2b863493b6325325b075a76b9d21
2015-02-03 19:20:03 +00:00
drh 67e65e55ab Break out the (script-generated) pragma parsing tables into a separate file,
pragma.h, to make editing easier.

FossilOrigin-Name: 32c0325bcb083fe3f0f0cfe999d00f754e15299e
2015-02-02 21:34:54 +00:00
drh c228be5b1f Add the "index_xinfo" pragma. Add new columns to the "index_info" and
"index_list" pragmas.

FossilOrigin-Name: 30f51d7b3b292191e8351223242e708bb7f3dfa6
2015-01-31 02:00:01 +00:00
drh 1ffede8c86 Change SQLITE_TESTCTRL_INITMODE to SQLITE_TESTCTRL_IMPOSTER. Revise the order
of parameters.  Give it the ability to reset the schema parse table so that
imposter tables can be erased.

FossilOrigin-Name: 42d5601739c90434e5adfda8fa99ef7b903877db
2015-01-30 20:59:27 +00:00
drh 0699f29a14 Added SQLITE_TESTCTRL_INITMODE for improved testability.
FossilOrigin-Name: 98e029134dc1300d3ecb48b41b5107ec69ba85db
2015-01-30 15:52:26 +00:00
mistachkin fdc2e6d344 Fix some duplicated test names.
FossilOrigin-Name: 1797158db2a818134c5cba1578f69ed85948b980
2015-01-29 19:27:31 +00:00
dan 976b003344 Ensure that "PRAGMA wal_checkpoint = TRUNCATE|FULL|RESTART" block on other connections and truncate the database file as required even if the entire wal file has already been checkpointed.
FossilOrigin-Name: 53429689d4fcf472edbc89cc50b5e69ba3270634
2015-01-29 19:12:12 +00:00
drh 6267920b09 Split up the SRC variable in Makefile.msc to avoid over-long cmd.exe commands when TOP is set to a long pathname.
FossilOrigin-Name: 7d70ac65c16f08832a1f0fc4dec0f62a17cbcc85
2015-01-29 18:38:05 +00:00
58 changed files with 1844 additions and 1001 deletions
+3 -1
View File
@@ -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 \
@@ -474,6 +475,7 @@ 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 \
@@ -995,7 +997,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
+46 -38
View File
@@ -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 \
@@ -811,15 +813,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 +830,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 +847,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 +864,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,6 +997,7 @@ 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 \
@@ -1052,7 +1056,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 +1536,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.
#
+2
View File
@@ -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 \
@@ -356,6 +357,7 @@ 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 \
+64 -60
View File
@@ -1,9 +1,9 @@
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 In\sthe\scommand-line\sshell,\schange\sthe\sunits\son\sthe\s".width"\sseparate\sfrom\nbytes\sto\scharacters.
D 2015-02-26T14:27:16.982
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5407a688f4d77a05c18a8142be8ae5a2829dd610
F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 2b1cb8881bdefcb0a8ed41c34c81cfa630374222
F Makefile.msc edbe2e2a9d27a4a56bd2891808a7c013bc322f6e
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
F VERSION d846487aff892625eb8e75960234e7285f0462fe
@@ -152,7 +152,7 @@ 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 0bae136db3f3ce451079ae335124b46163d37020
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -168,25 +168,25 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb
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 f7f0f44b0a2cb568a9c42b1b07e613380ee0b9c6
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 80edeba383aac89f72498b2572a115e21d0ecbbd
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 c06b1b263d52e14473ccc619422af6b64570a3b8
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/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8
F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
F src/pragma.c ba149bbbc90783f84815636c509ced8eac11bbcf
F src/pragma.c ea0be138a99784b14e87bd4522fea40e7b979e9c
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 e46cef4c224549b439384c88fc7f57ba064dad54
F src/shell.c c8a769c563b41b16196dfef675b008ba543a492f
F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h eaf210295b551d4e40e622aec1b2261c0b28f844
F src/sqliteInt.h 57a405ae6d2ed10fff52de376d18f21e04d96609
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
F src/tclsqlite.c b8014393a96a9781bb635c8b1f52fc9b77a2bfcf
F src/test1.c 5dcdade99e77b7b9f7760106c80a83cf50f10e1e
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_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c 14e543ae4d905ee31dc322b2f8d31bfac1769d45
@@ -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,26 +287,26 @@ 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/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec
F src/vdbe.c ddfc977981cd6324668aa6b114045eb1c677421a
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
F src/vdbeapi.c 4bc511a46b9839392ae0e90844a71dc96d9dbd71
F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a
F src/vdbeapi.c 3d88089b10f71750b019a806224f0277d371a072
F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5
F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
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/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c d46de821bc604a4fd36fa3928c086950e91aafb1
F src/where.c a50d5082b0fecd2bcf1725cdd012732d9d1e9d5c
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -349,7 +350,7 @@ F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
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
@@ -402,7 +403,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
@@ -630,19 +631,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 0d8821730a84f90af78a9dd547fe7a2480a06240
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 +652,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/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
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
@@ -786,7 +787,7 @@ 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/pragma.test 6cf0f0ce4618e841457aa42745afda55ddbc95fe
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@@ -833,7 +834,7 @@ F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 8c5a60d439e2df824aed56223566877a883c5c84
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,11 +858,11 @@ 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
@@ -887,7 +888,7 @@ 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/stat.test 76fd746b85459e812a0193410fb599f0531f22de
@@ -1127,7 +1128,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
@@ -1202,10 +1203,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 6b8e572a90eb4e0086e3ba90d88b76c085919863
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105
@@ -1221,7 +1222,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 +1239,10 @@ 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 4bee8295e36fb61f903210b6d052ee9b8fb3b6d0
R 143a1a32cdae3a721c8dd7822db13dda
T *branch * cli-char-width
T *sym-cli-char-width *
T -sym-trunk *
U drh
Z f10513d756c3deb9c12d56e187b46090
Z 9e05d9065c7895cfbe90dd1f0cc9db4d
+1 -1
View File
@@ -1 +1 @@
3a6e2afe408d2b0c8166d00def2048568169d87a
b1a9e2916f5b4adef91c34563f71b98e79a10c12
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+8
View File
@@ -291,6 +291,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 ){
+5 -5
View File
@@ -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
};
+35 -8
View File
@@ -1414,7 +1414,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 +1966,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);
}
@@ -2706,6 +2707,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
@@ -3141,13 +3145,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 +3304,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 +3608,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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
/*
+89 -78
View File
@@ -254,7 +254,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
@@ -717,9 +717,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 +1178,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 +1259,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 +1280,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 +1408,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;
}
@@ -1600,7 +1608,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 +1643,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 +1676,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);
}
}
}
@@ -1775,7 +1783,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 +1800,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 +1812,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 +1824,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 +1843,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 +1856,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 +1874,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 +2149,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;
@@ -2196,7 +2203,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;
}
@@ -2283,7 +2290,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 +2300,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 +2366,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 */
@@ -2471,7 +2478,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);
@@ -2575,7 +2582,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;
}
@@ -2677,7 +2684,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 {
@@ -2860,7 +2867,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) ){
@@ -3147,9 +3154,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 +3166,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 +3231,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 +3260,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 +3372,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 +3581,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 +3625,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 +3665,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 +3701,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 +3750,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 +3792,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 +3861,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__) */
@@ -4258,6 +4267,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 +4283,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 +4297,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;
@@ -4678,7 +4690,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 +4969,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 */ \
@@ -5383,7 +5397,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__);
@@ -5831,13 +5845,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 +5877,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 ){
@@ -6298,9 +6302,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 +6398,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 +6419,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 */
};
@@ -6602,10 +6608,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 +6726,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 +6746,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 +6766,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);
@@ -6802,7 +6808,7 @@ static int proxyTakeConch(unixFile *pFile){
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 +6819,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 +6892,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 +6901,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);
}
@@ -7107,7 +7114,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 ){
@@ -7220,7 +7228,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 +7243,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 */
+10 -10
View File
@@ -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);
+40 -475
View File
@@ -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);
@@ -809,14 +359,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 +946,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 +1077,30 @@ void sqlite3Pragma(
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
int i;
int mx = pPragma->iArg ? pIdx->nColumn : pIdx->nKeyCol;
pTab = pIdx->pTable;
sqlite3VdbeSetNumCols(v, 3);
pParse->nMem = 3;
sqlite3VdbeSetNumCols(v, 6);
pParse->nMem = 6;
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++){
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);
}
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, 6);
}
}
}
@@ -1553,17 +1113,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 +1698,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 */
@@ -2255,7 +1820,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));
}
+459
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+24 -5
View File
@@ -3194,7 +3194,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 +3334,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 +4764,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 +5516,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++;
+208 -45
View File
@@ -59,18 +59,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>
@@ -451,14 +471,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;
@@ -768,6 +788,48 @@ static void interrupt_handler(int NotUsed){
}
#endif
/*
** Return the length of a string in characters. Multibyte UTF8 characters
** count as a single character.
*/
static int strlenChar(const char *z){
int n = 0;
while( *z ){
if( (0xc0&*(z++))!=0x80 ) n++;
}
return n;
}
/*
** Print abs(w) characters of string "z" on FILE "out".
**
** w is in units of characters, not bytes!
**
** The output is always exactly abs(w) characters wide. If z contains
** more than abs(w) characters, it is truncated. If z contains fewer
** than abs(w) characters it is padded with spaces. Spaces are added
** on the right if w>0 (left justification) or on the left if w<0
** (right justification).
*/
static void outputFixedWidth(FILE *out, int w, const char *z){
int n = strlenChar(z);
int absw = w<0 ? -w : w;
int i;
if( n<=absw ){
if( w<0 ) for(i=absw-n; i>0; i--) putc(' ', out);
fputs(z, out);
if( w>0 ) for(i=absw-n; i>0; i--) putc(' ', out);
}else{
for(i=n=0; z[i]; i++){
if( (z[i]&0xc0)==0x80 ) continue;
if( n==absw ) break;
n++;
}
fwrite(z, 1, i, out);
}
}
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
@@ -808,22 +870,17 @@ static int shell_callback(
w = 0;
}
if( w==0 ){
w = strlen30(azCol[i] ? azCol[i] : "");
w = strlenChar(azCol[i] ? azCol[i] : "");
if( w<10 ) w = 10;
n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
if( w<n ) w = n;
}
if( i<ArraySize(p->actualWidth) ){
p->actualWidth[i] = w;
}
if( p->showHeader ){
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
i==nArg-1 ? p->rowSeparator : " ");
}else{
fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
i==nArg-1 ? p->rowSeparator : " ");
}
outputFixedWidth(p->out, w, azCol[i]);
fprintf(p->out, "%s", i==nArg-1 ? p->rowSeparator : " ");
}
}
if( p->showHeader ){
@@ -850,7 +907,7 @@ static int shell_callback(
w = 10;
}
if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
w = strlen30(azArg[i]);
w = strlenChar(azArg[i]);
}
if( i==1 && p->aiIndent && p->pStmt ){
if( p->iIndent<p->nIndent ){
@@ -858,15 +915,8 @@ static int shell_callback(
}
p->iIndent++;
}
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? p->rowSeparator : " ");
}else{
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? p->rowSeparator : " ");
}
outputFixedWidth(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
fprintf(p->out, "%s", i==nArg-1 ? p->rowSeparator : " ");
}
break;
}
@@ -1733,6 +1783,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 +1796,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"
@@ -2426,6 +2477,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 +2728,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
@@ -2907,7 +3071,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 +3100,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 +3131,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;
}
@@ -3536,7 +3701,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 +3794,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;
@@ -4521,13 +4686,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{
+34 -15
View File
@@ -944,9 +944,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 +966,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
**
@@ -2226,6 +2232,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 +2268,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 +2321,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 +3182,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
@@ -5061,6 +5075,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 +6279,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
/*
+10 -3
View File
@@ -1087,6 +1087,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 +2044,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
@@ -3152,6 +3159,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 +3743,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
+9 -8
View File
@@ -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
View File
@@ -14,7 +14,7 @@
*/
#include "tcl.h"
#include <sqlite3.h>
#include "sqlite3.h"
#include <assert.h>
/* These functions are implemented in main.c. */
+1 -1
View File
@@ -115,7 +115,7 @@
#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
#include <sqlite3.h>
#include "sqlite3.h"
#include <assert.h>
#include <string.h>
+1 -1
View File
@@ -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
View File
@@ -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";
+1 -1
View File
@@ -18,7 +18,7 @@
** sqlite3demo_superunlock()
*/
#include <sqlite3.h>
#include "sqlite3.h"
#include <string.h> /* memset(), strlen() */
#include <assert.h> /* assert() */
+1 -4
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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 */
+8 -2
View File
@@ -365,6 +365,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
pCtx->pVdbe->rcApp = errCode;
#endif
if( pCtx->pOut->flags & MEM_Null ){
sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
@@ -445,7 +448,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 +494,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 +541,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
+8 -3
View File
@@ -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 ){
+3 -1
View File
@@ -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) ){
+93 -90
View File
@@ -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 ){
+13 -3
View File
@@ -1612,11 +1612,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;
@@ -4694,7 +4699,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;
}
+31
View File
@@ -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
+33 -1
View File
@@ -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
+54 -13
View File
@@ -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
+22
View File
@@ -324,12 +324,34 @@ do_test incrblob2-6.2 {
sqlite3_blob_read $rdHandle 0 2
} {AB}
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.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
+3 -1
View File
@@ -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)}]
+59
View File
@@ -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
+47 -11
View File
@@ -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.
#
@@ -620,9 +644,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,8 +656,11 @@ 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}
do_test pragma-6.5.2 {
execsql {
@@ -676,8 +704,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} \
@@ -693,10 +723,9 @@ 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);
@@ -1705,19 +1734,26 @@ do_test 23.1 {
}
db2 eval {SELECT name FROM sqlite_master}
} {t1 i1 i2 t2}
do_test 23.2 {
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, "desc", coll, "key", '|' FROM out ORDER BY seqno}
} {2 c 0 BINARY 1 | 3 d 0 BINARY 1 | 1 b 0 BINARY 1 |}
do_test 23.2b {
breakpoint;
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 |}
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 name, "unique", origin FROM out ORDER BY seq}
} {i3 0 c i2 0 c i1 0 c}
do_test 23.4 {
db eval {
ALTER TABLE t1 ADD COLUMN e;
+56
View File
@@ -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
View File
@@ -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
+30
View File
@@ -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
+1 -1
View File
@@ -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"
+81
View File
@@ -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
}
}
+44 -23
View File
@@ -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. */"
+1
View File
@@ -110,6 +110,7 @@ foreach hdr {
pager.h
parse.h
pcache.h
pragma.h
rtree.h
sqlite3ext.h
sqlite3.h
+27 -8
View File
@@ -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