Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 536a409396 | |||
| c941a4b3b6 | |||
| cbb3f33c56 | |||
| b492e23b42 | |||
| fd34d6d379 | |||
| 8d8738eae0 | |||
| 13cc90cfa2 | |||
| 2a45cb5c0e | |||
| 690429a08f | |||
| e006a86643 | |||
| 077f06edfa | |||
| 36f65bafe5 | |||
| d4ef026ebb | |||
| 2da47d3869 | |||
| e6d4173b78 | |||
| ad0961b31b | |||
| db222adfd3 | |||
| a712b4bb97 | |||
| 4bf66fd6f3 | |||
| 883ad04985 | |||
| 96c707a3c2 | |||
| 983b5ee73d | |||
| a0efb1ae11 | |||
| 6728cd9180 | |||
| 9fab5ed01f | |||
| 2c5e9b5672 | |||
| 2308ed3854 | |||
| 885a5b030e | |||
| 63f845734e | |||
| 17645f5eec | |||
| 0e86a1ac08 | |||
| 31e7147dfa | |||
| d10d18da5f | |||
| 0e55db1cd8 | |||
| f7502f005e | |||
| fe0e84c948 | |||
| 4bb8cb0927 | |||
| 8fb15e3b20 | |||
| 1dae26bdab | |||
| 67e65e55ab | |||
| c228be5b1f | |||
| 1ffede8c86 | |||
| 0699f29a14 | |||
| fdc2e6d344 | |||
| 976b003344 | |||
| 6267920b09 |
+3
-1
@@ -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
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
@@ -1 +1 @@
|
||||
3a6e2afe408d2b0c8166d00def2048568169d87a
|
||||
b1a9e2916f5b4adef91c34563f71b98e79a10c12
|
||||
+1
-1
@@ -191,7 +191,7 @@ static void attachFunc(
|
||||
case SQLITE_NULL:
|
||||
/* No key specified. Use the key from the main database */
|
||||
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
|
||||
if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
|
||||
if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
|
||||
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -247,7 +247,7 @@ static int backupOnePage(
|
||||
** guaranteed that the shared-mutex is held by this thread, handle
|
||||
** p->pSrc may not actually be the owner. */
|
||||
int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
|
||||
int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
|
||||
int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
|
||||
#endif
|
||||
int rc = SQLITE_OK;
|
||||
i64 iOff;
|
||||
|
||||
+22
-7
@@ -175,6 +175,12 @@ static int hasSharedCacheTableLock(
|
||||
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
|
||||
Index *pIdx = (Index *)sqliteHashData(p);
|
||||
if( pIdx->tnum==(int)iRoot ){
|
||||
if( iTab ){
|
||||
/* Two or more indexes share the same root page. There must
|
||||
** be imposter tables. So just return true. The assert is not
|
||||
** useful in that case. */
|
||||
return 1;
|
||||
}
|
||||
iTab = pIdx->pTable->tnum;
|
||||
}
|
||||
}
|
||||
@@ -2399,6 +2405,9 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
|
||||
BtShared *pBt = p->pBt;
|
||||
assert( nReserve>=-1 && nReserve<=255 );
|
||||
sqlite3BtreeEnter(p);
|
||||
#if SQLITE_HAS_CODEC
|
||||
if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
|
||||
#endif
|
||||
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
|
||||
sqlite3BtreeLeave(p);
|
||||
return SQLITE_READONLY;
|
||||
@@ -2428,7 +2437,6 @@ int sqlite3BtreeGetPageSize(Btree *p){
|
||||
return p->pBt->pageSize;
|
||||
}
|
||||
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
|
||||
/*
|
||||
** This function is similar to sqlite3BtreeGetReserve(), except that it
|
||||
** may only be called if it is guaranteed that the b-tree mutex is already
|
||||
@@ -2441,25 +2449,33 @@ int sqlite3BtreeGetPageSize(Btree *p){
|
||||
** database handle that owns *p, causing undefined behavior.
|
||||
*/
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p){
|
||||
int n;
|
||||
assert( sqlite3_mutex_held(p->pBt->mutex) );
|
||||
return p->pBt->pageSize - p->pBt->usableSize;
|
||||
n = p->pBt->pageSize - p->pBt->usableSize;
|
||||
return n;
|
||||
}
|
||||
#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
|
||||
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
|
||||
/*
|
||||
** Return the number of bytes of space at the end of every page that
|
||||
** are intentually left unused. This is the "reserved" space that is
|
||||
** sometimes used by extensions.
|
||||
**
|
||||
** If SQLITE_HAS_MUTEX is defined then the number returned is the
|
||||
** greater of the current reserved space and the maximum requested
|
||||
** reserve space.
|
||||
*/
|
||||
int sqlite3BtreeGetReserve(Btree *p){
|
||||
int sqlite3BtreeGetOptimalReserve(Btree *p){
|
||||
int n;
|
||||
sqlite3BtreeEnter(p);
|
||||
n = p->pBt->pageSize - p->pBt->usableSize;
|
||||
n = sqlite3BtreeGetReserveNoMutex(p);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
|
||||
#endif
|
||||
sqlite3BtreeLeave(p);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Set the maximum page count for a database if mxPage is positive.
|
||||
** No changes are made if mxPage is 0 or negative.
|
||||
@@ -2490,7 +2506,6 @@ int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
|
||||
sqlite3BtreeLeave(p);
|
||||
return b;
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
|
||||
|
||||
/*
|
||||
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
|
||||
|
||||
+1
-3
@@ -73,10 +73,8 @@ int sqlite3BtreeGetPageSize(Btree*);
|
||||
int sqlite3BtreeMaxPageCount(Btree*,int);
|
||||
u32 sqlite3BtreeLastPage(Btree*);
|
||||
int sqlite3BtreeSecureDelete(Btree*,int);
|
||||
int sqlite3BtreeGetReserve(Btree*);
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
|
||||
int sqlite3BtreeGetOptimalReserve(Btree*);
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
||||
#endif
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
int sqlite3BtreeBeginTrans(Btree*,int);
|
||||
|
||||
@@ -418,6 +418,9 @@ struct BtShared {
|
||||
#endif
|
||||
u8 inTransaction; /* Transaction state */
|
||||
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
u8 optimalReserve; /* Desired amount of reserved space per page */
|
||||
#endif
|
||||
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
|
||||
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
|
||||
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
||||
|
||||
+7
-8
@@ -308,10 +308,6 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
Table *p = 0;
|
||||
int i;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return 0;
|
||||
#endif
|
||||
|
||||
/* All mutexes are required for schema access. Make sure we hold them. */
|
||||
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
@@ -1731,11 +1727,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
assert( pPk!=0 );
|
||||
nPk = pPk->nKeyCol;
|
||||
|
||||
/* Make sure every column of the PRIMARY KEY is NOT NULL */
|
||||
for(i=0; i<nPk; i++){
|
||||
pTab->aCol[pPk->aiColumn[i]].notNull = 1;
|
||||
/* Make sure every column of the PRIMARY KEY is NOT NULL. (Except,
|
||||
** do not enforce this for imposter tables.) */
|
||||
if( !db->init.imposterTable ){
|
||||
for(i=0; i<nPk; i++){
|
||||
pTab->aCol[pPk->aiColumn[i]].notNull = 1;
|
||||
}
|
||||
pPk->uniqNotNull = 1;
|
||||
}
|
||||
pPk->uniqNotNull = 1;
|
||||
|
||||
/* The root page of the PRIMARY KEY is the table root page */
|
||||
pPk->tnum = pTab->tnum;
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ Expr *sqlite3LimitWhere(
|
||||
|
||||
pInClause->x.pSelect = pSelect;
|
||||
pInClause->flags |= EP_xIsSelect;
|
||||
sqlite3ExprSetHeight(pParse, pInClause);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pInClause);
|
||||
return pInClause;
|
||||
|
||||
/* something went wrong. clean up anything allocated. */
|
||||
|
||||
+56
-10
@@ -146,10 +146,25 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
break;
|
||||
}
|
||||
if( p->flags & EP_Collate ){
|
||||
if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
|
||||
if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
|
||||
p = p->pLeft;
|
||||
}else{
|
||||
p = p->pRight;
|
||||
Expr *pNext = p->pRight;
|
||||
/* The Expr.x union is never used at the same time as Expr.pRight */
|
||||
assert( p->x.pList==0 || p->pRight==0 );
|
||||
/* p->flags holds EP_Collate and p->pLeft->flags does not. And
|
||||
** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
|
||||
** least one EP_Collate. Thus the following two ALWAYS. */
|
||||
if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
|
||||
int i;
|
||||
for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
|
||||
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
|
||||
pNext = p->x.pList->a[i].pExpr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
p = pNext;
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
@@ -355,6 +370,9 @@ static void heightOfSelect(Select *p, int *pnHeight){
|
||||
** Expr.pSelect member has a height of 1. Any other expression
|
||||
** has a height equal to the maximum height of any other
|
||||
** referenced Expr plus one.
|
||||
**
|
||||
** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
|
||||
** if appropriate.
|
||||
*/
|
||||
static void exprSetHeight(Expr *p){
|
||||
int nHeight = 0;
|
||||
@@ -362,8 +380,9 @@ static void exprSetHeight(Expr *p){
|
||||
heightOfExpr(p->pRight, &nHeight);
|
||||
if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
heightOfSelect(p->x.pSelect, &nHeight);
|
||||
}else{
|
||||
}else if( p->x.pList ){
|
||||
heightOfExprList(p->x.pList, &nHeight);
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
p->nHeight = nHeight + 1;
|
||||
}
|
||||
@@ -372,8 +391,11 @@ static void exprSetHeight(Expr *p){
|
||||
** Set the Expr.nHeight variable using the exprSetHeight() function. If
|
||||
** the height is greater than the maximum allowed expression depth,
|
||||
** leave an error in pParse.
|
||||
**
|
||||
** Also propagate all EP_Propagate flags from the Expr.x.pList into
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
exprSetHeight(p);
|
||||
sqlite3ExprCheckHeight(pParse, p->nHeight);
|
||||
}
|
||||
@@ -387,8 +409,17 @@ int sqlite3SelectExprHeight(Select *p){
|
||||
heightOfSelect(p, &nHeight);
|
||||
return nHeight;
|
||||
}
|
||||
#else
|
||||
#define exprSetHeight(y)
|
||||
#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */
|
||||
/*
|
||||
** Propagate all EP_Propagate flags from the Expr.x.pList into
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
}
|
||||
#define exprSetHeight(y)
|
||||
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
||||
|
||||
/*
|
||||
@@ -490,11 +521,11 @@ void sqlite3ExprAttachSubtrees(
|
||||
}else{
|
||||
if( pRight ){
|
||||
pRoot->pRight = pRight;
|
||||
pRoot->flags |= EP_Collate & pRight->flags;
|
||||
pRoot->flags |= EP_Propagate & pRight->flags;
|
||||
}
|
||||
if( pLeft ){
|
||||
pRoot->pLeft = pLeft;
|
||||
pRoot->flags |= EP_Collate & pLeft->flags;
|
||||
pRoot->flags |= EP_Propagate & pLeft->flags;
|
||||
}
|
||||
exprSetHeight(pRoot);
|
||||
}
|
||||
@@ -594,7 +625,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
||||
}
|
||||
pNew->x.pList = pList;
|
||||
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
|
||||
sqlite3ExprSetHeight(pParse, pNew);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pNew);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
@@ -1209,6 +1240,21 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the bitwise-OR of all Expr.flags fields in the given
|
||||
** ExprList.
|
||||
*/
|
||||
u32 sqlite3ExprListFlags(const ExprList *pList){
|
||||
int i;
|
||||
u32 m = 0;
|
||||
if( pList ){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
m |= pList->a[i].pExpr->flags;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
** These routines are Walker callbacks used to check expressions to
|
||||
** see if they are "constant" for some definition of constant. The
|
||||
@@ -1249,7 +1295,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
** and either pWalker->eCode==4 or 5 or the function has the
|
||||
** SQLITE_FUNC_CONST flag. */
|
||||
case TK_FUNCTION:
|
||||
if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){
|
||||
if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
|
||||
return WRC_Continue;
|
||||
}else{
|
||||
pWalker->eCode = 0;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -120,8 +120,12 @@ static sqlite3_mutex *debugMutexAlloc(int id){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assert( id-2 >= 0 );
|
||||
assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( id-2<0 || id-2>=ArraySize(aStatic) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
pNew = &aStatic[id-2];
|
||||
pNew->id = id;
|
||||
break;
|
||||
@@ -136,8 +140,13 @@ static sqlite3_mutex *debugMutexAlloc(int id){
|
||||
static void debugMutexFree(sqlite3_mutex *pX){
|
||||
sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
|
||||
assert( p->cnt==0 );
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
sqlite3_free(p);
|
||||
if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+18
-13
@@ -40,8 +40,10 @@
|
||||
*/
|
||||
struct sqlite3_mutex {
|
||||
pthread_mutex_t mutex; /* Mutex controlling the lock */
|
||||
#if SQLITE_MUTEX_NREF
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
int id; /* Mutex type */
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
volatile int nRef; /* Number of entrances */
|
||||
volatile pthread_t owner; /* Thread that is within this mutex */
|
||||
int trace; /* True to trace changes */
|
||||
@@ -157,9 +159,6 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&p->mutex, &recursiveAttr);
|
||||
pthread_mutexattr_destroy(&recursiveAttr);
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -167,9 +166,6 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
case SQLITE_MUTEX_FAST: {
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
pthread_mutex_init(&p->mutex, 0);
|
||||
}
|
||||
break;
|
||||
@@ -182,12 +178,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
}
|
||||
#endif
|
||||
p = &staticMutexes[iType-2];
|
||||
#if SQLITE_MUTEX_NREF
|
||||
p->id = iType;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
if( p ) p->id = iType;
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -199,9 +195,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
*/
|
||||
static void pthreadMutexFree(sqlite3_mutex *p){
|
||||
assert( p->nRef==0 );
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
pthread_mutex_destroy(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE )
|
||||
#endif
|
||||
{
|
||||
pthread_mutex_destroy(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
else{
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+9
-10
@@ -194,8 +194,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
case SQLITE_MUTEX_RECURSIVE: {
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
|
||||
p->trace = 1;
|
||||
#endif
|
||||
@@ -215,12 +215,9 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
assert( iType-2 >= 0 );
|
||||
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
|
||||
assert( winMutex_isInit==1 );
|
||||
p = &winMutex_staticMutexes[iType-2];
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
|
||||
p->trace = 1;
|
||||
#endif
|
||||
@@ -239,13 +236,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
*/
|
||||
static void winMutexFree(sqlite3_mutex *p){
|
||||
assert( p );
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( p->nRef==0 && p->owner==0 );
|
||||
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( winMutex_isInit==1 );
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+89
-78
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,459 @@
|
||||
/* DO NOT EDIT!
|
||||
** This file is automatically generated by the script at
|
||||
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
||||
** that script and rerun it.
|
||||
*/
|
||||
#define PragTyp_HEADER_VALUE 0
|
||||
#define PragTyp_AUTO_VACUUM 1
|
||||
#define PragTyp_FLAG 2
|
||||
#define PragTyp_BUSY_TIMEOUT 3
|
||||
#define PragTyp_CACHE_SIZE 4
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 5
|
||||
#define PragTyp_COLLATION_LIST 6
|
||||
#define PragTyp_COMPILE_OPTIONS 7
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 8
|
||||
#define PragTyp_DATABASE_LIST 9
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 10
|
||||
#define PragTyp_ENCODING 11
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 12
|
||||
#define PragTyp_FOREIGN_KEY_LIST 13
|
||||
#define PragTyp_INCREMENTAL_VACUUM 14
|
||||
#define PragTyp_INDEX_INFO 15
|
||||
#define PragTyp_INDEX_LIST 16
|
||||
#define PragTyp_INTEGRITY_CHECK 17
|
||||
#define PragTyp_JOURNAL_MODE 18
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 19
|
||||
#define PragTyp_LOCK_PROXY_FILE 20
|
||||
#define PragTyp_LOCKING_MODE 21
|
||||
#define PragTyp_PAGE_COUNT 22
|
||||
#define PragTyp_MMAP_SIZE 23
|
||||
#define PragTyp_PAGE_SIZE 24
|
||||
#define PragTyp_SECURE_DELETE 25
|
||||
#define PragTyp_SHRINK_MEMORY 26
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 27
|
||||
#define PragTyp_STATS 28
|
||||
#define PragTyp_SYNCHRONOUS 29
|
||||
#define PragTyp_TABLE_INFO 30
|
||||
#define PragTyp_TEMP_STORE 31
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 32
|
||||
#define PragTyp_THREADS 33
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 34
|
||||
#define PragTyp_WAL_CHECKPOINT 35
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 36
|
||||
#define PragTyp_HEXKEY 37
|
||||
#define PragTyp_KEY 38
|
||||
#define PragTyp_REKEY 39
|
||||
#define PragTyp_LOCK_STATUS 40
|
||||
#define PragTyp_PARSER_TRACE 41
|
||||
#define PragFlag_NeedSchema 0x01
|
||||
#define PragFlag_ReadOnly 0x02
|
||||
static const struct sPragmaNames {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
|
||||
u32 iArg; /* Extra argument */
|
||||
} aPragmaNames[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
{ /* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_APPLICATION_ID },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
||||
{ /* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
#endif
|
||||
#endif
|
||||
{ /* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CacheSpill },
|
||||
#endif
|
||||
{ /* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
{ /* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
|
||||
{ /* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "data_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_DATA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{ /* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_UTF16)
|
||||
{ /* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{ /* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_FREE_PAGE_COUNT },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{ /* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
{ /* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 1 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ /* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
{ /* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{ /* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_SCHEMA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
#endif
|
||||
{ /* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_USER_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{ /* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{ /* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{ /* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{ /* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
{ /* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 59 on by default, 72 total. */
|
||||
+1
-1
@@ -995,7 +995,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zBuf==0 || zFormat==0 ) {
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
if( zBuf && n>0 ) zBuf[0] = 0;
|
||||
if( zBuf ) zBuf[0] = 0;
|
||||
return zBuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
+24
-17
@@ -247,9 +247,10 @@ static int lookupName(
|
||||
testcase( pNC->ncFlags & NC_PartIdx );
|
||||
testcase( pNC->ncFlags & NC_IsCheck );
|
||||
if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
|
||||
/* Silently ignore database qualifiers inside CHECK constraints and partial
|
||||
** indices. Do not raise errors because that might break legacy and
|
||||
** because it does not hurt anything to just ignore the database name. */
|
||||
/* Silently ignore database qualifiers inside CHECK constraints and
|
||||
** partial indices. Do not raise errors because that might break
|
||||
** legacy and because it does not hurt anything to just ignore the
|
||||
** database name. */
|
||||
zDb = 0;
|
||||
}else{
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -320,7 +321,8 @@ static int lookupName(
|
||||
if( pMatch ){
|
||||
pExpr->iTable = pMatch->iCursor;
|
||||
pExpr->pTab = pMatch->pTab;
|
||||
assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
|
||||
/* RIGHT JOIN not (yet) supported */
|
||||
assert( (pMatch->jointype & JT_RIGHT)==0 );
|
||||
if( (pMatch->jointype & JT_LEFT)!=0 ){
|
||||
ExprSetProperty(pExpr, EP_CanBeNull);
|
||||
}
|
||||
@@ -641,7 +643,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
break;
|
||||
}
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
|
||||
&& !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
|
||||
/* A lone identifier is the name of a column.
|
||||
*/
|
||||
@@ -706,19 +709,20 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
if( n==2 ){
|
||||
pExpr->iTable = exprProbability(pList->a[1].pExpr);
|
||||
if( pExpr->iTable<0 ){
|
||||
sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
pNC->nErr++;
|
||||
}
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
|
||||
** likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
|
||||
** likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
|
||||
** likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
|
||||
** likelihood(X,0.9375). */
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
|
||||
** equivalent to likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
|
||||
** short-hand for likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
|
||||
** for likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
|
||||
** to likelihood(X,0.9375). */
|
||||
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
|
||||
pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
|
||||
}
|
||||
@@ -735,7 +739,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Prune;
|
||||
}
|
||||
#endif
|
||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
|
||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
|
||||
ExprSetProperty(pExpr,EP_ConstFunc);
|
||||
}
|
||||
}
|
||||
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
|
||||
@@ -1046,7 +1052,8 @@ int sqlite3ResolveOrderGroupBy(
|
||||
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
|
||||
return 1;
|
||||
}
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
|
||||
zType,0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
+24
-5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -5915,7 +5915,7 @@ static int test_test_control(
|
||||
} aVerb[] = {
|
||||
{ "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
|
||||
{ "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
|
||||
{ "SQLITE_TESTCTRL_INITMODE", SQLITE_TESTCTRL_INITMODE },
|
||||
{ "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER },
|
||||
};
|
||||
int iVerb;
|
||||
int iFlag;
|
||||
@@ -5957,18 +5957,19 @@ static int test_test_control(
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_TESTCTRL_INITMODE: {
|
||||
int fBusy, iDb, newTnum;
|
||||
case SQLITE_TESTCTRL_IMPOSTER: {
|
||||
int onOff, tnum;
|
||||
const char *zDbName;
|
||||
sqlite3 *db;
|
||||
if( objc!=6 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "DB fBusy iDb newTnum");
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &fBusy) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &iDb) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[5], &newTnum) ) return TCL_ERROR;
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_INITMODE, db, fBusy, iDb, newTnum);
|
||||
zDbName = Tcl_GetString(objv[3]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR;
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "tcl.h"
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <assert.h>
|
||||
|
||||
/* These functions are implemented in main.c. */
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@
|
||||
|
||||
#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library.
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <tcl.h>
|
||||
|
||||
/* Solely for the UNUSED_PARAMETER() macro. */
|
||||
|
||||
+9
-2
@@ -301,8 +301,11 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
|
||||
if( p->nCell ){
|
||||
int i; /* Used to iterate through cells */
|
||||
int nUsable = szPage - sqlite3BtreeGetReserve(pBt);
|
||||
int nUsable; /* Usable bytes per page */
|
||||
|
||||
sqlite3BtreeEnter(pBt);
|
||||
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
|
||||
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
|
||||
|
||||
@@ -425,7 +428,11 @@ statNextRestart:
|
||||
while( p->iCell<p->nCell ){
|
||||
StatCell *pCell = &p->aCell[p->iCell];
|
||||
if( pCell->iOvfl<pCell->nOvfl ){
|
||||
int nUsable = sqlite3BtreeGetPageSize(pBt)-sqlite3BtreeGetReserve(pBt);
|
||||
int nUsable;
|
||||
sqlite3BtreeEnter(pBt);
|
||||
nUsable = sqlite3BtreeGetPageSize(pBt) -
|
||||
sqlite3BtreeGetReserveNoMutex(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
|
||||
pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
|
||||
pCsr->zPagetype = "overflow";
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
** sqlite3demo_superunlock()
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <string.h> /* memset(), strlen() */
|
||||
#include <assert.h> /* assert() */
|
||||
|
||||
|
||||
+1
-4
@@ -390,10 +390,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
int mxSqlLen; /* Max length of an SQL string */
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zSql==0 || pzErrMsg==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( zSql!=0 );
|
||||
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
** cause problems for the call to BtreeSetPageSize() below. */
|
||||
sqlite3BtreeCommit(pTemp);
|
||||
|
||||
nRes = sqlite3BtreeGetReserve(pMain);
|
||||
nRes = sqlite3BtreeGetOptimalReserve(pMain);
|
||||
|
||||
/* A VACUUM cannot change the pagesize of an encrypted database. */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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) ){
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
# This file implements tests for SQLite library.
|
||||
#
|
||||
# The focus of this file is adding extra entries in the symbol table
|
||||
# using sqlite3_test_control(SQLITE_TESTCTRL_INITMODE) and verifying that
|
||||
# using sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER) and verifying that
|
||||
# SQLite handles those as expected.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix initmode
|
||||
set testprefix imposter
|
||||
|
||||
# Create a bunch of data to sort against
|
||||
#
|
||||
do_test initmode-1.0 {
|
||||
do_test imposter-1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d NOT NULL);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
@@ -31,15 +31,21 @@ do_test initmode-1.0 {
|
||||
INSERT INTO t1(a,b,c,d) SELECT i,1000+i,2000+i,3000+i FROM c;
|
||||
}
|
||||
set t1_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1'}]
|
||||
set t1a_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1a'}]
|
||||
set t1b_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1b'}]
|
||||
set t1c_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1c'}]
|
||||
|
||||
# Create a shadow table that uses the same b-tree as t1 but which does
|
||||
# Create an imposter table that uses the same b-tree as t1 but which does
|
||||
# not have the indexes
|
||||
#
|
||||
sqlite3_test_control SQLITE_TESTCTRL_INITMODE db 1 0 $t1_root
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $t1_root
|
||||
db eval {CREATE TABLE xt1(a,b,c,d)}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_INITMODE db 0 0 0
|
||||
|
||||
# And create an imposter table for the t1c index.
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $t1c_root
|
||||
db eval {CREATE TABLE xt1c(c,rowid,PRIMARY KEY(c,rowid))WITHOUT ROWID;}
|
||||
|
||||
# Go out of imposter mode for now.
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
|
||||
|
||||
# Create triggers to record changes to xt1.
|
||||
#
|
||||
@@ -64,10 +70,10 @@ do_test initmode-1.0 {
|
||||
# column corresponds to t1.rowid and t1.a, but the xt1.a column is always
|
||||
# NULL
|
||||
#
|
||||
do_execsql_test initmode-1.1 {
|
||||
do_execsql_test imposter-1.1 {
|
||||
SELECT rowid FROM xt1 WHERE a IS NOT NULL;
|
||||
} {}
|
||||
do_execsql_test initmode-1.2 {
|
||||
do_execsql_test imposter-1.2 {
|
||||
SELECT a,b,c,d FROM t1 EXCEPT SELECT rowid,b,c,d FROM xt1;
|
||||
SELECT rowid,b,c,d FROM xt1 EXCEPT SELECT a,b,c,d FROM t1;
|
||||
} {}
|
||||
@@ -78,7 +84,7 @@ do_execsql_test initmode-1.2 {
|
||||
# the NOT NULL constraint on t1.d, resulting in a logically inconsistent
|
||||
# database.
|
||||
#
|
||||
do_execsql_test initmode-1.3 {
|
||||
do_execsql_test imposter-1.3 {
|
||||
DELETE FROM xt1 WHERE rowid=5;
|
||||
INSERT INTO xt1(rowid,a,b,c,d) VALUES(99,'hello',1099,2022,NULL);
|
||||
SELECT * FROM chnglog ORDER BY rowid;
|
||||
@@ -87,14 +93,49 @@ do_execsql_test initmode-1.3 {
|
||||
{INSERT t1: rowid=99, a='hello', b=1099, c=2022, d=NULL} \
|
||||
]
|
||||
|
||||
do_execsql_test initmode-1.4a {
|
||||
do_execsql_test imposter-1.4a {
|
||||
PRAGMA integrity_check;
|
||||
} {/NULL value in t1.d/}
|
||||
do_execsql_test initmode-1.4b {
|
||||
do_execsql_test imposter-1.4b {
|
||||
PRAGMA integrity_check;
|
||||
} {/row # missing from index t1b/}
|
||||
do_execsql_test initmode-1.4c {
|
||||
do_execsql_test imposter-1.4c {
|
||||
PRAGMA integrity_check;
|
||||
} {/row # missing from index t1c/}
|
||||
|
||||
# Cleanup the corruption.
|
||||
# Then demonstrate that the xt1c imposter table can insert non-unique
|
||||
# and NULL values into the UNIQUE index.
|
||||
#
|
||||
do_execsql_test imposter-2.0 {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
|
||||
INSERT INTO t1(a,b,c,d) SELECT i,i,i,i FROM c;
|
||||
UPDATE xt1c SET c=NULL WHERE rowid=5;
|
||||
PRAGMA integrity_check;
|
||||
} {/row # missing from index t1c/}
|
||||
|
||||
do_execsql_test imposter-2.1 {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
|
||||
INSERT INTO t1(a,b,c,d) SELECT i,i,i,i FROM c;
|
||||
UPDATE xt1c SET c=99 WHERE rowid IN (5,7,9);
|
||||
SELECT c FROM t1 ORDER BY c;
|
||||
} {1 2 3 4 6 8 10 99 99 99}
|
||||
do_execsql_test imposter-2.2 {
|
||||
UPDATE xt1 SET c=99 WHERE rowid IN (5,7,9);
|
||||
PRAGMA integrity_check;
|
||||
} {/non-unique entry in index t1c/}
|
||||
|
||||
# Erase the imposter tables
|
||||
#
|
||||
do_test imposter-3.1 {
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 1
|
||||
db eval {
|
||||
DELETE FROM t1 WHERE rowid IN (5,7,9);
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -324,12 +324,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
|
||||
|
||||
@@ -188,8 +188,10 @@ ifcapable wal {
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA incremental_vacuum(1);
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
} {wal}
|
||||
do_test 4.2.1 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
file size test.db-wal
|
||||
} [expr {32+2*(512+24)}]
|
||||
|
||||
|
||||
@@ -267,5 +267,64 @@ do_execsql_test index6-6.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# Test case for ticket [2326c258d02ead33d69faa63de8f4686b9b1b9d9] on
|
||||
# 2015-02-24. Any use of a partial index qualifying constraint inside
|
||||
# the ON clause of a LEFT JOIN was causing incorrect results for all
|
||||
# versions of SQLite 3.8.0 through 3.8.8.
|
||||
#
|
||||
do_execsql_test index6-7.0 {
|
||||
CREATE TABLE t7a(x);
|
||||
CREATE TABLE t7b(y);
|
||||
INSERT INTO t7a(x) VALUES(1);
|
||||
CREATE INDEX t7ax ON t7a(x) WHERE x=99;
|
||||
PRAGMA automatic_index=OFF;
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {}}
|
||||
do_execsql_test index6-7.1 {
|
||||
INSERT INTO t7b(y) VALUES(2);
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {}
|
||||
do_execsql_test index6-7.2 {
|
||||
INSERT INTO t7a(x) VALUES(99);
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {} 99 2}
|
||||
do_execsql_test index6-7.3 {
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {99 2}
|
||||
do_execsql_test index6-7.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {/USING COVERING INDEX t7ax/}
|
||||
|
||||
|
||||
do_execsql_test index6-8.0 {
|
||||
CREATE TABLE t8a(a,b);
|
||||
CREATE TABLE t8b(x,y);
|
||||
CREATE INDEX i8c ON t8b(y) WHERE x = 'value';
|
||||
|
||||
INSERT INTO t8a VALUES(1, 'one');
|
||||
INSERT INTO t8a VALUES(2, 'two');
|
||||
INSERT INTO t8a VALUES(3, 'three');
|
||||
|
||||
INSERT INTO t8b VALUES('value', 1);
|
||||
INSERT INTO t8b VALUES('dummy', 2);
|
||||
INSERT INTO t8b VALUES('value', 3);
|
||||
INSERT INTO t8b VALUES('dummy', 4);
|
||||
} {}
|
||||
|
||||
do_eqp_test index6-8.1 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t8a}
|
||||
0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)}
|
||||
}
|
||||
|
||||
do_execsql_test index6-8.2 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
1 one value 1
|
||||
2 two {} {}
|
||||
3 three value 3
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+47
-11
@@ -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;
|
||||
|
||||
@@ -557,5 +557,61 @@ do_catchsql_test 10.8 {
|
||||
)
|
||||
} $err
|
||||
|
||||
# 2015-02-09 Ticket [2f7170d73bf9abf80339187aa3677dce3dbcd5ca]
|
||||
# "misuse of aggregate" error if aggregate column from FROM
|
||||
# subquery is used in correlated subquery
|
||||
#
|
||||
do_execsql_test 11.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(w INT, x INT);
|
||||
INSERT INTO t1(w,x)
|
||||
VALUES(1,10),(2,20),(3,30),
|
||||
(2,21),(3,31),
|
||||
(3,32);
|
||||
CREATE INDEX t1wx ON t1(w,x);
|
||||
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(w INT, y VARCHAR(8));
|
||||
INSERT INTO t2(w,y) VALUES(1,'one'),(2,'two'),(3,'three'),(4,'four');
|
||||
CREATE INDEX t2wy ON t2(w,y);
|
||||
|
||||
SELECT cnt, xyz, (SELECT y FROM t2 WHERE w=cnt), '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 one | 2 2 two | 3 3 three |}
|
||||
do_execsql_test 11.2 {
|
||||
SELECT cnt, xyz, lower((SELECT y FROM t2 WHERE w=cnt)), '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 one | 2 2 two | 3 3 three |}
|
||||
do_execsql_test 11.3 {
|
||||
SELECT cnt, xyz, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
WHERE (SELECT y FROM t2 WHERE w=cnt)!='two'
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 | 3 3 |}
|
||||
do_execsql_test 11.4 {
|
||||
SELECT cnt, xyz, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY lower((SELECT y FROM t2 WHERE w=cnt));
|
||||
} {1 1 | 3 3 | 2 2 |}
|
||||
do_execsql_test 11.5 {
|
||||
SELECT cnt, xyz,
|
||||
CASE WHEN (SELECT y FROM t2 WHERE w=cnt)=='two'
|
||||
THEN 'aaa' ELSE 'bbb'
|
||||
END, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY +cnt;
|
||||
} {1 1 bbb | 2 2 aaa | 3 3 bbb |}
|
||||
|
||||
do_execsql_test 11.100 {
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(y, z);
|
||||
SELECT ( SELECT y FROM t2 WHERE z = cnt )
|
||||
FROM ( SELECT count(*) AS cnt FROM t1 );
|
||||
} {{}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+8
-5
@@ -406,19 +406,22 @@ do_test shell1-3.11.3 {
|
||||
catchcmd "test.db" ".import FOO BAR BAD"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
|
||||
# .indices ?TABLE? Show names of all indices
|
||||
# If TABLE specified, only show indices for tables
|
||||
# .indexes ?TABLE? Show names of all indexes
|
||||
# If TABLE specified, only show indexes for tables
|
||||
# matching LIKE pattern TABLE.
|
||||
do_test shell1-3.12.1 {
|
||||
catchcmd "test.db" ".indices"
|
||||
catchcmd "test.db" ".indexes"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.2 {
|
||||
catchcmd "test.db" ".indexes FOO"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.2-legacy {
|
||||
catchcmd "test.db" ".indices FOO"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".indices FOO BAD"
|
||||
} {1 {Usage: .indices ?LIKE-PATTERN?}}
|
||||
catchcmd "test.db" ".indexes FOO BAD"
|
||||
} {1 {Usage: .indexes ?LIKE-PATTERN?}}
|
||||
|
||||
# .mode MODE ?TABLE? Set output mode where MODE is one of:
|
||||
# ascii Columns/rows delimited by 0x1F and 0x1E
|
||||
|
||||
@@ -405,4 +405,34 @@ SELECT * FROM t5;
|
||||
set x
|
||||
} "0 \{\"test 1\"\x1F,test 2<EOL>\x1Etest 3\x1Ftest 4<EOL>\x1E\}"
|
||||
|
||||
do_test shell5-4.1 {
|
||||
forcedelete shell5.csv
|
||||
set fd [open shell5.csv w]
|
||||
puts $fd "1,2,3"
|
||||
puts $fd "4,5"
|
||||
puts $fd "6,7,8"
|
||||
close $fd
|
||||
catchcmd test.db [string trim {
|
||||
.mode csv
|
||||
CREATE TABLE t6(a, b, c);
|
||||
.import shell5.csv t6
|
||||
}]
|
||||
db eval { SELECT * FROM t6 ORDER BY a }
|
||||
} {1 2 3 4 5 {} 6 7 8}
|
||||
|
||||
do_test shell5-4.2 {
|
||||
forcedelete shell5.csv
|
||||
set fd [open shell5.csv w]
|
||||
puts $fd "1,2,3"
|
||||
puts $fd "4,5"
|
||||
puts $fd "6,7,8,9"
|
||||
close $fd
|
||||
catchcmd test.db [string trim {
|
||||
.mode csv
|
||||
CREATE TABLE t7(a, b, c);
|
||||
.import shell5.csv t7
|
||||
}]
|
||||
db eval { SELECT * FROM t7 ORDER BY a }
|
||||
} {1 2 3 4 5 {} 6 7 8}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ static const char zHelp[] =
|
||||
" --explain Like --sqlonly but with added EXPLAIN keywords\n"
|
||||
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
|
||||
" --incrvacuum Enable incremenatal vacuum mode\n"
|
||||
" --journalmode M Set the journal_mode to MODE\n"
|
||||
" --journal M Set the journal_mode to M\n"
|
||||
" --key KEY Set the encryption key to KEY\n"
|
||||
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
|
||||
" --nosync Set PRAGMA synchronous=OFF\n"
|
||||
|
||||
@@ -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
@@ -4,10 +4,10 @@
|
||||
#
|
||||
# To add new pragmas, first add the name and other relevant attributes
|
||||
# of the pragma to the "pragma_def" object below. Then run this script
|
||||
# to generate the C-code for the lookup table and copy/paste the output
|
||||
# of this script into the appropriate spot in the pragma.c source file.
|
||||
# to generate the ../src/pragma.h header file that contains macros and
|
||||
# the lookup table needed for pragma name lookup in the pragma.c module.
|
||||
# Then add the extra "case PragTyp_XXXXX:" and subsequent code for the
|
||||
# new pragma.
|
||||
# new pragma in ../src/pragma.c.
|
||||
#
|
||||
|
||||
set pragma_def {
|
||||
@@ -205,6 +205,14 @@ set pragma_def {
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_info
|
||||
TYPE: INDEX_INFO
|
||||
ARG: 0
|
||||
FLAG: NeedSchema
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_xinfo
|
||||
TYPE: INDEX_INFO
|
||||
ARG: 1
|
||||
FLAG: NeedSchema
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
@@ -308,7 +316,20 @@ set pragma_def {
|
||||
|
||||
NAME: threads
|
||||
}
|
||||
fconfigure stdout -translation lf
|
||||
|
||||
# Open the output file
|
||||
#
|
||||
set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
|
||||
puts "Overwriting $destfile with new pragma table..."
|
||||
set fd [open $destfile wb]
|
||||
puts $fd {/* DO NOT EDIT!
|
||||
** This file is automatically generated by the script at
|
||||
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
||||
** that script and rerun it.
|
||||
*/}
|
||||
|
||||
# Parse the PRAGMA table above.
|
||||
#
|
||||
set name {}
|
||||
set type {}
|
||||
set if {}
|
||||
@@ -362,7 +383,7 @@ foreach name $allnames {
|
||||
set if [lindex $allbyname($name) 2]
|
||||
if {[regexp SQLITE_DEBUG $if] || [regexp SQLITE_HAS_CODEC $if]} continue
|
||||
set seentype($type) 1
|
||||
puts [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
incr pnum
|
||||
}
|
||||
foreach name $allnames {
|
||||
@@ -371,14 +392,14 @@ foreach name $allnames {
|
||||
set if [lindex $allbyname($name) 2]
|
||||
if {[regexp SQLITE_DEBUG $if]} continue
|
||||
set seentype($type) 1
|
||||
puts [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
incr pnum
|
||||
}
|
||||
foreach name $allnames {
|
||||
set type [lindex $allbyname($name) 0]
|
||||
if {[info exists seentype($type)]} continue
|
||||
set seentype($type) 1
|
||||
puts [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
|
||||
incr pnum
|
||||
}
|
||||
|
||||
@@ -386,18 +407,18 @@ foreach name $allnames {
|
||||
#
|
||||
set fv 1
|
||||
foreach f [lsort [array names allflags]] {
|
||||
puts [format {#define PragFlag_%-20s 0x%02x} $f $fv]
|
||||
puts $fd [format {#define PragFlag_%-20s 0x%02x} $f $fv]
|
||||
set fv [expr {$fv*2}]
|
||||
}
|
||||
|
||||
# Generate the lookup table
|
||||
#
|
||||
puts "static const struct sPragmaNames \173"
|
||||
puts " const char *const zName; /* Name of pragma */"
|
||||
puts " u8 ePragTyp; /* PragTyp_XXX value */"
|
||||
puts " u8 mPragFlag; /* Zero or more PragFlag_XXX values */"
|
||||
puts " u32 iArg; /* Extra argument */"
|
||||
puts "\175 aPragmaNames\[\] = \173"
|
||||
puts $fd "static const struct sPragmaNames \173"
|
||||
puts $fd " const char *const zName; /* Name of pragma */"
|
||||
puts $fd " u8 ePragTyp; /* PragTyp_XXX value */"
|
||||
puts $fd " u8 mPragFlag; /* Zero or more PragFlag_XXX values */"
|
||||
puts $fd " u32 iArg; /* Extra argument */"
|
||||
puts $fd "\175 aPragmaNames\[\] = \173"
|
||||
|
||||
set current_if {}
|
||||
set spacer [format { %26s } {}]
|
||||
@@ -406,13 +427,13 @@ foreach name $allnames {
|
||||
if {$if!=$current_if} {
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
puts "#endif"
|
||||
puts $fd "#endif"
|
||||
}
|
||||
}
|
||||
set current_if $if
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
puts "#if $this_if"
|
||||
puts $fd "#if $this_if"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,17 +443,17 @@ foreach name $allnames {
|
||||
} else {
|
||||
set flagx PragFlag_[join $flag {|PragFlag_}]
|
||||
}
|
||||
puts " \173 /* zName: */ \"$name\","
|
||||
puts " /* ePragTyp: */ PragTyp_$type,"
|
||||
puts " /* ePragFlag: */ $flagx,"
|
||||
puts " /* iArg: */ $arg \175,"
|
||||
puts $fd " \173 /* zName: */ \"$name\","
|
||||
puts $fd " /* ePragTyp: */ PragTyp_$type,"
|
||||
puts $fd " /* ePragFlag: */ $flagx,"
|
||||
puts $fd " /* iArg: */ $arg \175,"
|
||||
}
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
puts "#endif"
|
||||
puts $fd "#endif"
|
||||
}
|
||||
}
|
||||
puts "\175;"
|
||||
puts $fd "\175;"
|
||||
|
||||
# count the number of pragmas, for information purposes
|
||||
#
|
||||
@@ -444,4 +465,4 @@ foreach name $allnames {
|
||||
if {[regexp {^defined} $if] || [regexp {[^!]defined} $if]} continue
|
||||
incr dfltcnt
|
||||
}
|
||||
puts "/* Number of pragmas: $dfltcnt on by default, $allcnt total. */"
|
||||
puts $fd "/* Number of pragmas: $dfltcnt on by default, $allcnt total. */"
|
||||
|
||||
@@ -110,6 +110,7 @@ foreach hdr {
|
||||
pager.h
|
||||
parse.h
|
||||
pcache.h
|
||||
pragma.h
|
||||
rtree.h
|
||||
sqlite3ext.h
|
||||
sqlite3.h
|
||||
|
||||
+27
-8
@@ -4,6 +4,24 @@
|
||||
#
|
||||
|
||||
if {[catch {
|
||||
|
||||
# Argument $tname is the name of a table within the database opened by
|
||||
# database handle [db]. Return true if it is a WITHOUT ROWID table, or
|
||||
# false otherwise.
|
||||
#
|
||||
proc is_without_rowid {tname} {
|
||||
set t [string map {' ''} $tname]
|
||||
db eval "PRAGMA index_list = '$t'" o {
|
||||
if {$o(origin) == "pk"} {
|
||||
set n $o(name)
|
||||
if {0==[db one { SELECT count(*) FROM sqlite_master WHERE name=$n }]} {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get the name of the database to analyze
|
||||
#
|
||||
proc usage {} {
|
||||
@@ -167,20 +185,21 @@ set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 }
|
||||
foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
|
||||
|
||||
set is_index [expr {$name!=$tblname}]
|
||||
set idx_btree [expr {$is_index || [is_without_rowid $name]}]
|
||||
db eval {
|
||||
SELECT
|
||||
sum(ncell) AS nentry,
|
||||
sum(isleaf(pagetype, $is_index) * ncell) AS leaf_entries,
|
||||
sum(isleaf(pagetype, $idx_btree) * ncell) AS leaf_entries,
|
||||
sum(payload) AS payload,
|
||||
sum(isoverflow(pagetype, $is_index) * payload) AS ovfl_payload,
|
||||
sum(isoverflow(pagetype, $idx_btree) * payload) AS ovfl_payload,
|
||||
sum(path LIKE '%+000000') AS ovfl_cnt,
|
||||
max(mx_payload) AS mx_payload,
|
||||
sum(isinternal(pagetype, $is_index)) AS int_pages,
|
||||
sum(isleaf(pagetype, $is_index)) AS leaf_pages,
|
||||
sum(isoverflow(pagetype, $is_index)) AS ovfl_pages,
|
||||
sum(isinternal(pagetype, $is_index) * unused) AS int_unused,
|
||||
sum(isleaf(pagetype, $is_index) * unused) AS leaf_unused,
|
||||
sum(isoverflow(pagetype, $is_index) * unused) AS ovfl_unused,
|
||||
sum(isinternal(pagetype, $idx_btree)) AS int_pages,
|
||||
sum(isleaf(pagetype, $idx_btree)) AS leaf_pages,
|
||||
sum(isoverflow(pagetype, $idx_btree)) AS ovfl_pages,
|
||||
sum(isinternal(pagetype, $idx_btree) * unused) AS int_unused,
|
||||
sum(isleaf(pagetype, $idx_btree) * unused) AS leaf_unused,
|
||||
sum(isoverflow(pagetype, $idx_btree) * unused) AS ovfl_unused,
|
||||
sum(pgsize) AS compressed_size
|
||||
FROM temp.dbstat WHERE name = $name
|
||||
} break
|
||||
|
||||
Reference in New Issue
Block a user