Merge the latest trunk changes, especially the ORDER BY optimizer enhancements
but also other fixes, onto the sessions branch. FossilOrigin-Name: f1fbb8c5bfa84e84e0b8e2872d83b06a0c0d5acc
This commit is contained in:
commit
d1102b1ec7
46
Makefile.msc
46
Makefile.msc
@ -30,6 +30,10 @@ XCOMPILE = 0
|
||||
#
|
||||
USE_NATIVE_LIBPATHS = 0
|
||||
|
||||
# Set this 0 to skip the compiling and embedding of version resources.
|
||||
#
|
||||
USE_RC = 1
|
||||
|
||||
# Set this non-0 to compile binaries suitable for the WinRT environment.
|
||||
# This setting does not apply to any binaries that require Tcl to operate
|
||||
# properly (i.e. the text fixture, etc).
|
||||
@ -168,8 +172,8 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
|
||||
!IF $(FOR_WINRT)!=0
|
||||
TCC = $(TCC) -DSQLITE_OS_WINRT=1
|
||||
RCC = $(RCC) -DSQLITE_OS_WINRT=1
|
||||
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
|
||||
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
|
||||
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||
!ENDIF
|
||||
|
||||
# Also, we need to dynamically link to the correct MSVC runtime
|
||||
@ -180,14 +184,18 @@ RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
|
||||
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
|
||||
!IF $(DEBUG)>0
|
||||
TCC = $(TCC) -MDd
|
||||
BCC = $(BCC) -MDd
|
||||
!ELSE
|
||||
TCC = $(TCC) -MD
|
||||
BCC = $(BCC) -MD
|
||||
!ENDIF
|
||||
!ELSE
|
||||
!IF $(DEBUG)>0
|
||||
TCC = $(TCC) -MTd
|
||||
BCC = $(BCC) -MTd
|
||||
!ELSE
|
||||
TCC = $(TCC) -MT
|
||||
BCC = $(BCC) -MT
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@ -474,6 +482,14 @@ LIBOBJ = $(LIBOBJS0)
|
||||
LIBOBJ = $(LIBOBJS1)
|
||||
!ENDIF
|
||||
|
||||
# Determine if embedded resource compilation and usage are enabled.
|
||||
#
|
||||
!IF $(USE_RC)!=0
|
||||
LIBRESOBJS = sqlite3res.lo
|
||||
!ELSE
|
||||
LIBRESOBJS =
|
||||
!ENDIF
|
||||
|
||||
# All of the source code files.
|
||||
#
|
||||
SRC = \
|
||||
@ -782,10 +798,10 @@ libsqlite3.lib: $(LIBOBJ)
|
||||
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
|
||||
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
|
||||
|
||||
sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3res.lo sqlite3.h
|
||||
sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
|
||||
$(LTLINK) $(READLINE_FLAGS) \
|
||||
$(TOP)\src\shell.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib sqlite3res.lo $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
@ -835,14 +851,16 @@ opcodes.lo: opcodes.c
|
||||
|
||||
# Rule to build the Win32 resources object file.
|
||||
#
|
||||
sqlite3res.lo: $(TOP)\src\sqlite3.rc $(HDR)
|
||||
!IF $(USE_RC)!=0
|
||||
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
|
||||
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||
echo #define SQLITE_RESOURCE_VERSION %%V \
|
||||
| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
|
||||
)
|
||||
echo #endif >> sqlite3rc.h
|
||||
$(LTRCOMPILE) -fo sqlite3res.lo $(TOP)\src\sqlite3.rc
|
||||
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
|
||||
!ENDIF
|
||||
|
||||
# Rules to build individual *.lo files from files in the src directory.
|
||||
#
|
||||
@ -1059,8 +1077,8 @@ tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR)
|
||||
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
|
||||
$(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
||||
|
||||
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib sqlite3res.lo
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo sqlite3res.lo $(LTLIBS) $(TLIBS)
|
||||
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib $(LIBRESOBJS)
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
# Rules to build opcodes.c and opcodes.h
|
||||
#
|
||||
@ -1173,11 +1191,11 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
|
||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
|
||||
!ENDIF
|
||||
|
||||
testfixture.exe: $(TESTFIXTURE_SRC) sqlite3res.lo $(HDR)
|
||||
testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
|
||||
-DBUILD_sqlite -I$(TCLINCDIR) \
|
||||
$(TESTFIXTURE_SRC) \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS)
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
fulltest: testfixture.exe sqlite3.exe
|
||||
.\testfixture.exe $(TOP)\test\all.test
|
||||
@ -1198,9 +1216,9 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TO
|
||||
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
|
||||
echo ; return zMainloop; } >> $@
|
||||
|
||||
sqlite3_analyzer.exe: sqlite3_analyzer.c sqlite3res.lo
|
||||
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||
$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS)
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
clean:
|
||||
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
|
||||
@ -1233,5 +1251,5 @@ sqlite3.def: libsqlite3.lib
|
||||
| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
|
||||
| sort >> sqlite3.def
|
||||
|
||||
sqlite3.dll: $(LIBOBJ) sqlite3res.lo sqlite3.def
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) sqlite3res.lo $(LTLIBS) $(TLIBS)
|
||||
sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
@ -2660,7 +2660,7 @@ static int newRowid(Rtree *pRtree, i64 *piRowid){
|
||||
*/
|
||||
static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
|
||||
int rc; /* Return code */
|
||||
RtreeNode *pLeaf; /* Leaf node containing record iDelete */
|
||||
RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */
|
||||
int iCell; /* Index of iDelete cell in pLeaf */
|
||||
RtreeNode *pRoot; /* Root node of rtree structure */
|
||||
|
||||
@ -2863,7 +2863,7 @@ static int rtreeUpdate(
|
||||
*/
|
||||
if( rc==SQLITE_OK && nData>1 ){
|
||||
/* Insert the new record into the r-tree */
|
||||
RtreeNode *pLeaf;
|
||||
RtreeNode *pLeaf = 0;
|
||||
|
||||
/* Figure out the rowid of the new row. */
|
||||
if( bHaveRowid==0 ){
|
||||
|
86
manifest
86
manifest
@ -1,9 +1,9 @@
|
||||
C Merge\sthe\slatest\strunk\schanges\s(especially\s"PRAGMA\sbusy_timeout"\sand\sthe\nORDER\sBY\squery\splanner\soptimizations)\sinto\sthe\ssessions\sbranch.
|
||||
D 2012-09-28T13:05:48.372
|
||||
C Merge\sthe\slatest\strunk\schanges,\sespecially\sthe\sORDER\sBY\soptimizer\senhancements\nbut\salso\sother\sfixes,\sonto\sthe\ssessions\sbranch.
|
||||
D 2012-10-09T14:58:15.175
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 321efe6f572a1d4f8e27794c4575dd9b51d3e731
|
||||
F Makefile.msc a26021086defb54e6cb61439a90be5960b713017
|
||||
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d
|
||||
@ -83,7 +83,7 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
|
||||
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c d17aecb7a92762efa7b1f5d5fd7c88fd77d70827
|
||||
F ext/rtree/rtree.c 47064ee2995a396bfb626337d2b43f12cc0af687
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@ -126,23 +126,23 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||
F src/alter.c 0c1716aa8d248bd6bc750e23be4c68ad05f8668c
|
||||
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
|
||||
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
|
||||
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143
|
||||
F src/attach.c 34c15ecd686e58f08e5bb1389e28a0b65c2c83db
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 5b31b24d6814b11de763debf342c8cd0a15a4910
|
||||
F src/backup.c afc067b9a9050ff48b9d46285c53d096c556a73d
|
||||
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 9cf6de113d23d47967df24b8d8ce6501c879d7e6
|
||||
F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2
|
||||
F src/btree.c 14de53ebb334633ee632ab3c5b9262cfe7cbe455
|
||||
F src/btree.h 078f76b28c338ab6eb6dd7324d63ee54463aeb6c
|
||||
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
|
||||
F src/build.c c4555e16f8ccdadb2616014c617ed8166c5a93f7
|
||||
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
|
||||
F src/build.c b21c130017820dfe8721e380325e128fd0c6e019
|
||||
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c c856ca31177a5cc1612b47ca0c628cd227aa072e
|
||||
F src/expr.c 4de967b85f577ba00a7cdcb53d22070def6198db
|
||||
F src/delete.c e44a1b66cd3dc1e9e2c74147ee4991214e6e6978
|
||||
F src/expr.c 57fb8e7a05d4147e40b9f4c439e37ed2abab9332
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af
|
||||
F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898
|
||||
@ -150,12 +150,12 @@ F src/global.c fb44b11e02e06c995e6ed6642509edd23599d584
|
||||
F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
|
||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 08ec5cec28c692fc27a23659875cc167f5c6ece7
|
||||
F src/insert.c 6273647b67e27e3f81b7d1fd144307ea726841d0
|
||||
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
||||
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
|
||||
F src/main.c febaf66b42c36433b170e4704fef5b8b073a6d61
|
||||
F src/main.c 5cee8048dde78b2b47f5c2090cbb31b10d190673
|
||||
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
|
||||
@ -172,31 +172,31 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
|
||||
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9
|
||||
F src/os_win.c 90c7a1fe2698867555ba4266f5bd436c85d0d1dc
|
||||
F src/pager.c 9c59818c480261c1c5a4772532e0df92a27745a1
|
||||
F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5
|
||||
F src/os_unix.c a5a45a2857c43b37bac145b521064a85a544cd7a
|
||||
F src/os_win.c 28bd027791252a4012dffd4d64355a1eb84d761c
|
||||
F src/pager.c a7ad8c38809edf0be545e8f52da5bcbb88885b38
|
||||
F src/pager.h bdbc379557eb2e233dfec10986b3086877e72db7
|
||||
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
|
||||
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
|
||||
F src/pragma.c 7f5a0fa6dead752d9af3a1e1d16bace81d22ef95
|
||||
F src/pragma.c 4f31fe4ae4b885a8be8b1db9d94f9f5b6c8b5624
|
||||
F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
|
||||
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32
|
||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||
F src/select.c 75c5e37cc882c468383c9d9e07496b9a16cfae3e
|
||||
F src/select.c 2a82736faeca1fe93315eda20c691d68ec13bb6c
|
||||
F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7
|
||||
F src/sqlite.h.in 2f2822ac789d820e05afb19831e62fd83e69c60b
|
||||
F src/sqlite.h.in d460ae07ecdd1c820272d9c217547c7b572cb4b7
|
||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||
F src/sqliteInt.h 34844b666512c2c5656c5d470f165ed1db0fcd48
|
||||
F src/sqliteInt.h fec16c0932b30aedf5d3b577aaf5f881589c8dd0
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c 79ac64bdd8555b8967032e1e69051d88366f9b77
|
||||
F src/test1.c 0354b555639c92d2a63c0ad4e74ed152ba47e604
|
||||
F src/tclsqlite.c 289be7b639406314813219ee7bc043d21f36ab12
|
||||
F src/test1.c 936afc02766403e5debca49a1817a780e116df7e
|
||||
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
|
||||
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
|
||||
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
|
||||
@ -216,7 +216,7 @@ F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
|
||||
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
|
||||
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
||||
F src/test_intarray.c 07ddcebe4097d400ffca362770f1d883c112387a
|
||||
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
|
||||
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
@ -227,7 +227,7 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
|
||||
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
|
||||
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 8ab295092c70903ca6f3209fa4c75f5cb6c1bf8e
|
||||
F src/test_quota.c e5fdb7d28e5afae1b619922804e544db0041ec81
|
||||
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
|
||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||
@ -252,16 +252,16 @@ F src/vdbe.c e8e2e34c23a474c38f494d572a0d8accaabd0b4a
|
||||
F src/vdbe.h 87b8ff40de3f55dbcdc33029416862f517c37a2f
|
||||
F src/vdbeInt.h 39acf85fa83f98e27e728722a0f53daf7d174b61
|
||||
F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647
|
||||
F src/vdbeaux.c 857c8372d3b06d66e37428712265f9033932f3ec
|
||||
F src/vdbeaux.c 1005a2ea2cbbe5d2841367eebae67ce848a6247a
|
||||
F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381
|
||||
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
|
||||
F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b
|
||||
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
|
||||
F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9
|
||||
F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d
|
||||
F src/vtab.c 9c64ae18af78c740610df841c6f49fc2d240a279
|
||||
F src/wal.c e1fe8f92a0ea0fef8faa87ec43a127a478589d22
|
||||
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
|
||||
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
|
||||
F src/where.c d836df3a2096c41c39e48ab5636f09f94ba02676
|
||||
F src/where.c 410017c604713ab6c010a9e3731a7688a0c7a059
|
||||
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
|
||||
@ -307,8 +307,8 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
|
||||
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
|
||||
F test/bigfile.test 8f88b5ef065e31c615c49d725ede94155fbe9609
|
||||
F test/bigfile2.test 8a3c242c3c3481e7cde5a6ef2a66fdc367a095f7
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 7c79f1ef0c6c2c2bc1e7bd895596fab32bfb4796
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
|
||||
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
|
||||
@ -524,7 +524,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
|
||||
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzer1.test 69cf1036b92fd3b8e1fd65bef4d7ee3f085c28fb
|
||||
F test/fuzzer1.test a2e93bb1e19513dd6bf9c63d3d7c4673c983ca19
|
||||
F test/fuzzerfault.test ff2282c81797b6a355f0748d8b54c7287c5d2b25
|
||||
F test/hook.test 94b927b15883f5c1477ab09eecd16275addb08f4
|
||||
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
|
||||
@ -646,7 +646,8 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
|
||||
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/orderby1.test 31c9865626046666e81cd22ecf8e1c24a4ea41b6
|
||||
F test/orderby1.test ef4f7c40df81b9a4303a718433d34052f07db47d
|
||||
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
|
||||
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
|
||||
F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
|
||||
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
|
||||
@ -714,6 +715,7 @@ F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
|
||||
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
|
||||
F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
|
||||
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
|
||||
F test/shared9.test 614a3ca431adc73c857632deb4eff75bcaee40ec
|
||||
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
|
||||
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
|
||||
F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53
|
||||
@ -749,7 +751,7 @@ F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a
|
||||
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
|
||||
F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tclsqlite.test 02b2c268d38203987dd1839598ac524f7612ec3c
|
||||
F test/tclsqlite.test a7308276aad2e6c0bfb5b0414424dd0d9cc0cad7
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
|
||||
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
|
||||
@ -896,7 +898,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
|
||||
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
|
||||
F test/trigger1.test de42feb7cd442787d38185ae74f5a1d7afa400cb
|
||||
F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931
|
||||
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
|
||||
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
|
||||
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
||||
@ -968,7 +970,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
|
||||
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
|
||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
||||
F test/where.test a6bfb5a29286811d798d326a8f1153a58c0fb2bd
|
||||
F test/where.test 41b65069a227a61238c1387b050f029480ca5677
|
||||
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
|
||||
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
|
||||
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
|
||||
@ -986,7 +988,7 @@ F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
||||
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
|
||||
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
||||
F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c
|
||||
F tool/build-all-msvc.bat 1a18aa39983ae7354d834bc55a850a54fc007576 x
|
||||
F tool/build-all-msvc.bat cd505f24717ca4ecd94c651f763d7bb4e7fe68af x
|
||||
F tool/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381
|
||||
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
|
||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||
@ -1030,7 +1032,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
|
||||
P fae9eb197fcef726fd2c7c701afe6805fc008cf9 1e874629d7cf568368b912b295bd3001147d0b52
|
||||
R 3dd4bfa3bb20bc9f3b355292d5659141
|
||||
P 6ca8eae1f89d19ee23cbc3a869d85b57d29b4a7d a02599ad85d02470c9effa51c02dbda7796bfa16
|
||||
R 05272e22ec105aad09507c576198ab3e
|
||||
U drh
|
||||
Z d6a15b3f33482cbc762a2fcdf6bf0623
|
||||
Z 8b270f262a5da1e0ba6e8c7b897dd596
|
||||
|
@ -1 +1 @@
|
||||
6ca8eae1f89d19ee23cbc3a869d85b57d29b4a7d
|
||||
f1fbb8c5bfa84e84e0b8e2872d83b06a0c0d5acc
|
@ -414,7 +414,7 @@ void sqlite3AlterRenameTable(
|
||||
assert( pSrc->nSrc==1 );
|
||||
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
|
||||
|
||||
pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
|
||||
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
|
||||
if( !pTab ) goto exit_rename_table;
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
|
||||
zDb = db->aDb[iDb].zName;
|
||||
@ -757,7 +757,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
|
||||
assert( pParse->pNewTable==0 );
|
||||
assert( sqlite3BtreeHoldsAllMutexes(db) );
|
||||
if( db->mallocFailed ) goto exit_begin_add_column;
|
||||
pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
|
||||
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
|
||||
if( !pTab ) goto exit_begin_add_column;
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
@ -434,6 +434,7 @@ int sqlite3FixInit(
|
||||
assert( db->nDb>iDb );
|
||||
pFix->pParse = pParse;
|
||||
pFix->zDb = db->aDb[iDb].zName;
|
||||
pFix->pSchema = db->aDb[iDb].pSchema;
|
||||
pFix->zType = zType;
|
||||
pFix->pName = pName;
|
||||
return 1;
|
||||
@ -464,14 +465,15 @@ int sqlite3FixSrcList(
|
||||
if( NEVER(pList==0) ) return 0;
|
||||
zDb = pFix->zDb;
|
||||
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
|
||||
if( pItem->zDatabase==0 ){
|
||||
pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
|
||||
}else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
|
||||
if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
|
||||
sqlite3ErrorMsg(pFix->pParse,
|
||||
"%s %T cannot reference objects in database %s",
|
||||
pFix->zType, pFix->pName, pItem->zDatabase);
|
||||
return 1;
|
||||
}
|
||||
sqlite3_free(pItem->zDatabase);
|
||||
pItem->zDatabase = 0;
|
||||
pItem->pSchema = pFix->pSchema;
|
||||
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
|
||||
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
|
||||
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
|
||||
|
@ -219,13 +219,16 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
|
||||
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
|
||||
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
|
||||
/* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
|
||||
** 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);
|
||||
#endif
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
i64 iOff;
|
||||
|
||||
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
|
||||
assert( p->bDestLocked );
|
||||
assert( !isFatalError(p->rc) );
|
||||
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
|
||||
|
26
src/btree.c
26
src/btree.c
@ -2200,6 +2200,24 @@ 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
|
||||
** held.
|
||||
**
|
||||
** This is useful in one special case in the backup API code where it is
|
||||
** known that the shared b-tree mutex is held, but the mutex on the
|
||||
** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
|
||||
** were to be called, it might collide with some other operation on the
|
||||
** database handle that owns *p, causing undefined behaviour.
|
||||
*/
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p){
|
||||
assert( sqlite3_mutex_held(p->pBt->mutex) );
|
||||
return p->pBt->pageSize - p->pBt->usableSize;
|
||||
}
|
||||
#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
|
||||
@ -5256,7 +5274,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
|
||||
return SQLITE_OK; /* No overflow pages. Return without doing anything */
|
||||
}
|
||||
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
|
||||
return SQLITE_CORRUPT; /* Cell extends past end of page */
|
||||
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
|
||||
}
|
||||
ovflPgno = get4byte(&pCell[info.iOverflow]);
|
||||
assert( pBt->usableSize > 4 );
|
||||
@ -5922,6 +5940,9 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
|
||||
** If aOvflSpace is set to a null pointer, this function returns
|
||||
** SQLITE_NOMEM.
|
||||
*/
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||
#pragma optimize("", off)
|
||||
#endif
|
||||
static int balance_nonroot(
|
||||
MemPage *pParent, /* Parent page of siblings being balanced */
|
||||
int iParentIdx, /* Index of "the page" in pParent */
|
||||
@ -6552,6 +6573,9 @@ balance_cleanup:
|
||||
|
||||
return rc;
|
||||
}
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -71,6 +71,9 @@ int sqlite3BtreeMaxPageCount(Btree*,int);
|
||||
u32 sqlite3BtreeLastPage(Btree*);
|
||||
int sqlite3BtreeSecureDelete(Btree*,int);
|
||||
int sqlite3BtreeGetReserve(Btree*);
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
||||
#endif
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
int sqlite3BtreeBeginTrans(Btree*,int);
|
||||
|
39
src/build.c
39
src/build.c
@ -319,6 +319,31 @@ Table *sqlite3LocateTable(
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Locate the table identified by *p.
|
||||
**
|
||||
** This is a wrapper around sqlite3LocateTable(). The difference between
|
||||
** sqlite3LocateTable() and this function is that this function restricts
|
||||
** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
|
||||
** non-NULL if it is part of a view or trigger program definition. See
|
||||
** sqlite3FixSrcList() for details.
|
||||
*/
|
||||
Table *sqlite3LocateTableItem(
|
||||
Parse *pParse,
|
||||
int isView,
|
||||
struct SrcList_item *p
|
||||
){
|
||||
const char *zDb;
|
||||
assert( p->pSchema==0 || p->zDatabase==0 );
|
||||
if( p->pSchema ){
|
||||
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
|
||||
zDb = pParse->db->aDb[iDb].zName;
|
||||
}else{
|
||||
zDb = p->zDatabase;
|
||||
}
|
||||
return sqlite3LocateTable(pParse, isView, p->zName, zDb);
|
||||
}
|
||||
|
||||
/*
|
||||
** Locate the in-memory structure that describes
|
||||
** a particular index given the name of that index
|
||||
@ -1295,10 +1320,7 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
|
||||
|
||||
pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
|
||||
if( !initbusy && (!pColl || !pColl->xCmp) ){
|
||||
pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
|
||||
if( !pColl ){
|
||||
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
|
||||
}
|
||||
pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
|
||||
}
|
||||
|
||||
return pColl;
|
||||
@ -2114,8 +2136,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
assert( pParse->nErr==0 );
|
||||
assert( pName->nSrc==1 );
|
||||
if( noErr ) db->suppressErr++;
|
||||
pTab = sqlite3LocateTable(pParse, isView,
|
||||
pName->a[0].zName, pName->a[0].zDatabase);
|
||||
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
|
||||
if( noErr ) db->suppressErr--;
|
||||
|
||||
if( pTab==0 ){
|
||||
@ -2555,9 +2576,9 @@ Index *sqlite3CreateIndex(
|
||||
** sqlite3FixSrcList can never fail. */
|
||||
assert(0);
|
||||
}
|
||||
pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
|
||||
pTblName->a[0].zDatabase);
|
||||
if( !pTab || db->mallocFailed ) goto exit_create_index;
|
||||
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
|
||||
assert( db->mallocFailed==0 || pTab==0 );
|
||||
if( pTab==0 ) goto exit_create_index;
|
||||
assert( db->aDb[iDb].pSchema==pTab->pSchema );
|
||||
}else{
|
||||
assert( pName==0 );
|
||||
|
@ -75,17 +75,18 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
|
||||
**
|
||||
** The return value is either the collation sequence to be used in database
|
||||
** db for collation type name zName, length nName, or NULL, if no collation
|
||||
** sequence can be found.
|
||||
** sequence can be found. If no collation is found, leave an error message.
|
||||
**
|
||||
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
|
||||
*/
|
||||
CollSeq *sqlite3GetCollSeq(
|
||||
sqlite3* db, /* The database connection */
|
||||
Parse *pParse, /* Parsing context */
|
||||
u8 enc, /* The desired encoding for the collating sequence */
|
||||
CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
|
||||
const char *zName /* Collating sequence name */
|
||||
){
|
||||
CollSeq *p;
|
||||
sqlite3 *db = pParse->db;
|
||||
|
||||
p = pColl;
|
||||
if( !p ){
|
||||
@ -102,6 +103,9 @@ CollSeq *sqlite3GetCollSeq(
|
||||
p = 0;
|
||||
}
|
||||
assert( !p || p->xCmp );
|
||||
if( p==0 ){
|
||||
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -120,10 +124,8 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
|
||||
if( pColl ){
|
||||
const char *zName = pColl->zName;
|
||||
sqlite3 *db = pParse->db;
|
||||
CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
|
||||
CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
|
||||
if( !p ){
|
||||
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
|
||||
pParse->nErr++;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
assert( p==pColl );
|
||||
|
@ -32,7 +32,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
|
||||
struct SrcList_item *pItem = pSrc->a;
|
||||
Table *pTab;
|
||||
assert( pItem && pSrc->nSrc==1 );
|
||||
pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
|
||||
pTab = sqlite3LocateTableItem(pParse, 0, pItem);
|
||||
sqlite3DeleteTable(pParse->db, pItem->pTab);
|
||||
pItem->pTab = pTab;
|
||||
if( pTab ){
|
||||
|
@ -930,6 +930,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
|
||||
struct SrcList_item *pNewItem = &pNew->a[i];
|
||||
struct SrcList_item *pOldItem = &p->a[i];
|
||||
Table *pTab;
|
||||
pNewItem->pSchema = pOldItem->pSchema;
|
||||
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
|
||||
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
|
||||
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
|
||||
|
29
src/insert.c
29
src/insert.c
@ -1274,20 +1274,25 @@ void sqlite3GenerateConstraintChecks(
|
||||
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
|
||||
for(i=0; i<pCheck->nExpr; i++){
|
||||
int allOk = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
|
||||
if( onError==OE_Ignore ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
}else{
|
||||
char *zConsName = pCheck->a[i].zName;
|
||||
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
|
||||
if( zConsName ){
|
||||
zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
|
||||
Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
|
||||
if( !db->mallocFailed ){
|
||||
assert( pDup!=0 );
|
||||
sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
|
||||
if( onError==OE_Ignore ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
}else{
|
||||
zConsName = 0;
|
||||
char *zConsName = pCheck->a[i].zName;
|
||||
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
|
||||
if( zConsName ){
|
||||
zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
|
||||
}else{
|
||||
zConsName = 0;
|
||||
}
|
||||
sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
|
||||
}
|
||||
sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
|
||||
sqlite3VdbeResolveLabel(v, allOk);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, allOk);
|
||||
sqlite3ExprDelete(db, pDup);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_CHECK) */
|
||||
@ -1753,7 +1758,7 @@ static int xferOptimization(
|
||||
** we have to check the semantics.
|
||||
*/
|
||||
pItem = pSelect->pSrc->a;
|
||||
pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
|
||||
pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
|
||||
if( pSrc==0 ){
|
||||
return 0; /* FROM clause does not contain a real table */
|
||||
}
|
||||
|
@ -3040,7 +3040,7 @@ int sqlite3_test_control(int op, ...){
|
||||
*/
|
||||
case SQLITE_TESTCTRL_OPTIMIZATIONS: {
|
||||
sqlite3 *db = va_arg(ap, sqlite3*);
|
||||
db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
|
||||
db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3010,6 +3010,8 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
||||
i64 newOffset;
|
||||
#endif
|
||||
TIMER_START;
|
||||
assert( cnt==(cnt&0x1ffff) );
|
||||
cnt &= 0x1ffff;
|
||||
do{
|
||||
#if defined(USE_PREAD)
|
||||
got = osPread(id->h, pBuf, cnt, offset);
|
||||
@ -3099,6 +3101,8 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
|
||||
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
|
||||
i64 newOffset;
|
||||
#endif
|
||||
assert( cnt==(cnt&0x1ffff) );
|
||||
cnt &= 0x1ffff;
|
||||
TIMER_START;
|
||||
#if defined(USE_PREAD)
|
||||
do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
|
||||
|
74
src/os_win.c
74
src/os_win.c
@ -33,6 +33,57 @@
|
||||
with SQLITE_OMIT_WAL."
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
|
||||
** based on the sub-platform)?
|
||||
*/
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
|
||||
# define SQLITE_WIN32_HAS_ANSI
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
|
||||
** based on the sub-platform)?
|
||||
*/
|
||||
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
|
||||
# define SQLITE_WIN32_HAS_WIDE
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Do we need to manually define the Win32 file mapping APIs for use with WAL
|
||||
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
|
||||
** are not present in the header file)?
|
||||
*/
|
||||
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
|
||||
/*
|
||||
** Two of the file mapping APIs are different under WinRT. Figure out which
|
||||
** set we need.
|
||||
*/
|
||||
#if SQLITE_OS_WINRT
|
||||
WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
|
||||
LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
|
||||
|
||||
WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
|
||||
#else
|
||||
#if defined(SQLITE_WIN32_HAS_ANSI)
|
||||
WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
|
||||
DWORD, DWORD, DWORD, LPCSTR);
|
||||
#endif /* defined(SQLITE_WIN32_HAS_ANSI) */
|
||||
|
||||
#if defined(SQLITE_WIN32_HAS_WIDE)
|
||||
WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
|
||||
DWORD, DWORD, DWORD, LPCWSTR);
|
||||
#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
|
||||
|
||||
WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||
#endif /* SQLITE_OS_WINRT */
|
||||
|
||||
/*
|
||||
** This file mapping API is common to both Win32 and WinRT.
|
||||
*/
|
||||
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
|
||||
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
|
||||
|
||||
/*
|
||||
** Macro to find the minimum of two numeric values.
|
||||
*/
|
||||
@ -238,14 +289,6 @@ int sqlite3_os_type = 0;
|
||||
static int sqlite3_os_type = 0;
|
||||
#endif
|
||||
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
|
||||
# define SQLITE_WIN32_HAS_ANSI
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
|
||||
# define SQLITE_WIN32_HAS_WIDE
|
||||
#endif
|
||||
|
||||
#ifndef SYSCALL
|
||||
# define SYSCALL sqlite3_syscall_ptr
|
||||
#endif
|
||||
@ -402,7 +445,11 @@ static struct win_syscall {
|
||||
#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
|
||||
DWORD,va_list*))aSyscall[15].pCurrent)
|
||||
|
||||
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
{ "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
|
||||
#else
|
||||
{ "FreeLibrary", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
|
||||
|
||||
@ -483,6 +530,7 @@ static struct win_syscall {
|
||||
|
||||
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
|
||||
|
||||
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#if SQLITE_OS_WINCE
|
||||
/* The GetProcAddressA() routine is only available on Windows CE. */
|
||||
{ "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
|
||||
@ -491,6 +539,9 @@ static struct win_syscall {
|
||||
** an ANSI string regardless of the _UNICODE setting */
|
||||
{ "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
|
||||
#endif
|
||||
#else
|
||||
{ "GetProcAddressA", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
|
||||
LPCSTR))aSyscall[27].pCurrent)
|
||||
@ -594,7 +645,7 @@ static struct win_syscall {
|
||||
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
|
||||
LPCVOID))aSyscall[41].pCurrent)
|
||||
|
||||
#if defined(SQLITE_WIN32_HAS_ANSI)
|
||||
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
|
||||
#else
|
||||
{ "LoadLibraryA", (SYSCALL)0, 0 },
|
||||
@ -602,7 +653,8 @@ static struct win_syscall {
|
||||
|
||||
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
|
||||
|
||||
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
|
||||
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
|
||||
!defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
{ "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
|
||||
#else
|
||||
{ "LoadLibraryW", (SYSCALL)0, 0 },
|
||||
@ -791,7 +843,7 @@ static struct win_syscall {
|
||||
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
|
||||
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
|
||||
|
||||
#if SQLITE_OS_WINRT
|
||||
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
|
||||
#else
|
||||
{ "LoadPackagedLibrary", (SYSCALL)0, 0 },
|
||||
|
33
src/pager.c
33
src/pager.c
@ -2509,6 +2509,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a sanitized version of the sector-size of OS file pFile. The
|
||||
** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
|
||||
*/
|
||||
int sqlite3SectorSize(sqlite3_file *pFile){
|
||||
int iRet = sqlite3OsSectorSize(pFile);
|
||||
if( iRet<32 ){
|
||||
iRet = 512;
|
||||
}else if( iRet>MAX_SECTOR_SIZE ){
|
||||
assert( MAX_SECTOR_SIZE>=512 );
|
||||
iRet = MAX_SECTOR_SIZE;
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the value of the Pager.sectorSize variable for the given
|
||||
** pager based on the value returned by the xSectorSize method
|
||||
@ -2544,14 +2559,7 @@ static void setSectorSize(Pager *pPager){
|
||||
** call will segfault. */
|
||||
pPager->sectorSize = 512;
|
||||
}else{
|
||||
pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
|
||||
if( pPager->sectorSize<32 ){
|
||||
pPager->sectorSize = 512;
|
||||
}
|
||||
if( pPager->sectorSize>MAX_SECTOR_SIZE ){
|
||||
assert( MAX_SECTOR_SIZE>=512 );
|
||||
pPager->sectorSize = MAX_SECTOR_SIZE;
|
||||
}
|
||||
pPager->sectorSize = sqlite3SectorSize(pPager->fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3468,9 +3476,16 @@ void sqlite3PagerSetBusyhandler(
|
||||
Pager *pPager, /* Pager object */
|
||||
int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
|
||||
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
|
||||
){
|
||||
){
|
||||
pPager->xBusyHandler = xBusyHandler;
|
||||
pPager->pBusyHandlerArg = pBusyHandlerArg;
|
||||
|
||||
if( isOpen(pPager->fd) ){
|
||||
void **ap = (void **)&pPager->xBusyHandler;
|
||||
assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
|
||||
assert( ap[1]==pBusyHandlerArg );
|
||||
sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -160,6 +160,7 @@ void *sqlite3PagerTempSpace(Pager*);
|
||||
int sqlite3PagerIsMemdb(Pager*);
|
||||
void sqlite3PagerCacheStat(Pager *, int, int, int *);
|
||||
void sqlite3PagerClearCache(Pager *);
|
||||
int sqlite3SectorSize(sqlite3_file *);
|
||||
|
||||
/* Functions used to truncate the database file. */
|
||||
void sqlite3PagerTruncateImage(Pager*,Pgno);
|
||||
|
@ -357,6 +357,7 @@ void sqlite3Pragma(
|
||||
aFcntl[1] = zLeft;
|
||||
aFcntl[2] = zRight;
|
||||
aFcntl[3] = 0;
|
||||
db->busyHandler.nBusy = 0;
|
||||
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( aFcntl[0] ){
|
||||
|
@ -3332,8 +3332,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
}else{
|
||||
/* An ordinary table or view name in the FROM clause */
|
||||
assert( pFrom->pTab==0 );
|
||||
pFrom->pTab = pTab =
|
||||
sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
|
||||
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
|
||||
if( pTab==0 ) return WRC_Abort;
|
||||
pTab->nRef++;
|
||||
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
|
||||
|
@ -852,6 +852,17 @@ struct sqlite3_io_methods {
|
||||
** file control occurs at the beginning of pragma statement analysis and so
|
||||
** it is able to override built-in [PRAGMA] statements.
|
||||
** </ul>
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
|
||||
** ^This file-control may be invoked by SQLite on the database file handle
|
||||
** shortly after it is opened in order to provide a custom VFS with access
|
||||
** to the connections busy-handler callback. The argument is of type (void **)
|
||||
** - an array of two (void *) values. The first (void *) actually points
|
||||
** to a function of type (int (*)(void *)). In order to invoke the connections
|
||||
** busy-handler, this function should be invoked with the second (void *) in
|
||||
** the array as the only argument. If it returns non-zero, then the operation
|
||||
** should be retried. If it returns zero, the custom VFS should abandon the
|
||||
** current operation.
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
#define SQLITE_GET_LOCKPROXYFILE 2
|
||||
@ -867,6 +878,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_VFSNAME 12
|
||||
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
|
||||
#define SQLITE_FCNTL_PRAGMA 14
|
||||
#define SQLITE_FCNTL_BUSYHANDLER 15
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle
|
||||
|
@ -1877,6 +1877,7 @@ struct SrcList {
|
||||
i16 nSrc; /* Number of tables or subqueries in the FROM clause */
|
||||
i16 nAlloc; /* Number of entries allocated in a[] below */
|
||||
struct SrcList_item {
|
||||
Schema *pSchema; /* Schema to which this item is fixed */
|
||||
char *zDatabase; /* Name of database holding this table */
|
||||
char *zName; /* Name of the table */
|
||||
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
|
||||
@ -2449,6 +2450,7 @@ struct TriggerStep {
|
||||
typedef struct DbFixer DbFixer;
|
||||
struct DbFixer {
|
||||
Parse *pParse; /* The parsing context. Error messages written here */
|
||||
Schema *pSchema; /* Fix items to this schema */
|
||||
const char *zDb; /* Make sure all objects are contained in this database */
|
||||
const char *zType; /* Type of the container - used for error messages */
|
||||
const Token *pName; /* Name of the container - used for error messages */
|
||||
@ -2859,6 +2861,7 @@ void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
|
||||
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
|
||||
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
|
||||
Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
|
||||
Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
|
||||
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
|
||||
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
|
||||
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
|
||||
@ -3089,7 +3092,7 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
|
||||
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
|
||||
void sqlite3AlterFinishAddColumn(Parse *, Token *);
|
||||
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
|
||||
CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
|
||||
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
|
||||
char sqlite3AffinityType(const char*);
|
||||
void sqlite3Analyze(Parse*, Token*, Token*);
|
||||
int sqlite3InvokeBusyHandler(BusyHandler*);
|
||||
|
@ -53,15 +53,8 @@
|
||||
#define NUM_PREPARED_STMTS 10
|
||||
#define MAX_PREPARED_STMTS 100
|
||||
|
||||
/*
|
||||
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
|
||||
** have to do a translation when going between the two. Set the
|
||||
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
|
||||
** this translation.
|
||||
*/
|
||||
#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
|
||||
# define UTF_TRANSLATION_NEEDED 1
|
||||
#endif
|
||||
/* Forward declaration */
|
||||
typedef struct SqliteDb SqliteDb;
|
||||
|
||||
/*
|
||||
** New SQL functions can be created as TCL scripts. Each such function
|
||||
@ -71,6 +64,7 @@ typedef struct SqlFunc SqlFunc;
|
||||
struct SqlFunc {
|
||||
Tcl_Interp *interp; /* The TCL interpret to execute the function */
|
||||
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
|
||||
SqliteDb *pDb; /* Database connection that owns this function */
|
||||
int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
|
||||
char *zName; /* Name of this function */
|
||||
SqlFunc *pNext; /* Next function on the list of them all */
|
||||
@ -113,7 +107,6 @@ typedef struct IncrblobChannel IncrblobChannel;
|
||||
** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
|
||||
** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
|
||||
*/
|
||||
typedef struct SqliteDb SqliteDb;
|
||||
struct SqliteDb {
|
||||
sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
|
||||
Tcl_Interp *interp; /* The interpreter used for this database */
|
||||
@ -432,6 +425,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
|
||||
}
|
||||
}
|
||||
pNew->interp = pDb->interp;
|
||||
pNew->pDb = pDb;
|
||||
pNew->pScript = 0;
|
||||
pNew->pNext = pDb->pFunc;
|
||||
pDb->pFunc = pNew;
|
||||
@ -479,6 +473,7 @@ static void DbDeleteCmd(void *db){
|
||||
while( pDb->pFunc ){
|
||||
SqlFunc *pFunc = pDb->pFunc;
|
||||
pDb->pFunc = pFunc->pNext;
|
||||
assert( pFunc->pDb==pDb );
|
||||
Tcl_DecrRefCount(pFunc->pScript);
|
||||
Tcl_Free((char*)pFunc);
|
||||
}
|
||||
@ -838,7 +833,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
|
||||
break;
|
||||
}
|
||||
case SQLITE_NULL: {
|
||||
pVal = Tcl_NewStringObj("", 0);
|
||||
pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -977,26 +972,6 @@ static int auth_callback(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
|
||||
/*
|
||||
** zText is a pointer to text obtained via an sqlite3_result_text()
|
||||
** or similar interface. This routine returns a Tcl string object,
|
||||
** reference count set to 0, containing the text. If a translation
|
||||
** between iso8859 and UTF-8 is required, it is preformed.
|
||||
*/
|
||||
static Tcl_Obj *dbTextToObj(char const *zText){
|
||||
Tcl_Obj *pVal;
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DString dCol;
|
||||
Tcl_DStringInit(&dCol);
|
||||
Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
|
||||
pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
|
||||
Tcl_DStringFree(&dCol);
|
||||
#else
|
||||
pVal = Tcl_NewStringObj(zText, -1);
|
||||
#endif
|
||||
return pVal;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine reads a line of text from FILE in, stores
|
||||
** the text in memory obtained from malloc() and returns a pointer
|
||||
@ -1184,13 +1159,13 @@ static int dbPrepareAndBind(
|
||||
int nByte;
|
||||
|
||||
if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
|
||||
Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( pStmt==0 ){
|
||||
if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
|
||||
/* A compile-time error in the statement. */
|
||||
Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
/* The statement was a no-op. Continue to the next statement
|
||||
@ -1409,7 +1384,7 @@ static void dbEvalRowInfo(
|
||||
if( nCol>0 && (papColName || p->pArray) ){
|
||||
apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
|
||||
for(i=0; i<nCol; i++){
|
||||
apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
|
||||
apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
|
||||
Tcl_IncrRefCount(apColName[i]);
|
||||
}
|
||||
p->apColName = apColName;
|
||||
@ -1496,7 +1471,8 @@ static int dbEvalStep(DbEvalContext *p){
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
|
||||
Tcl_SetObjResult(pDb->interp,
|
||||
Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
dbReleaseStmt(pDb, pPreStmt, 0);
|
||||
@ -1553,11 +1529,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
|
||||
return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
|
||||
}
|
||||
case SQLITE_NULL: {
|
||||
return dbTextToObj(p->pDb->zNull);
|
||||
return Tcl_NewStringObj(p->pDb->zNull, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
|
||||
return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2452,7 +2428,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
const char *zDb = "main";
|
||||
const char *zTable;
|
||||
const char *zColumn;
|
||||
sqlite_int64 iRow;
|
||||
Tcl_WideInt iRow;
|
||||
|
||||
/* Check for the -readonly option */
|
||||
if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
|
||||
@ -2518,7 +2494,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
pDb->zNull = 0;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3067,7 +3067,7 @@ static int test_bind_int64(
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int idx;
|
||||
i64 value;
|
||||
Tcl_WideInt value;
|
||||
int rc;
|
||||
|
||||
if( objc!=4 ){
|
||||
@ -4703,7 +4703,7 @@ static int test_soft_heap_limit(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_int64 amt;
|
||||
sqlite3_int64 N = -1;
|
||||
Tcl_WideInt N = -1;
|
||||
if( objc!=1 && objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?N?");
|
||||
return TCL_ERROR;
|
||||
@ -5096,7 +5096,7 @@ static int file_control_sizehint_test(
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_int64 nSize; /* Hinted size */
|
||||
Tcl_WideInt nSize; /* Hinted size */
|
||||
char *zDb; /* Db name ("main", "temp" etc.) */
|
||||
sqlite3 *db; /* Database handle */
|
||||
int rc; /* file_control() return code */
|
||||
|
@ -346,8 +346,9 @@ static int test_intarray_bind(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for(i=0; i<n; i++){
|
||||
a[i] = 0;
|
||||
Tcl_GetWideIntFromObj(0, objv[i+2], &a[i]);
|
||||
Tcl_WideInt x = 0;
|
||||
Tcl_GetWideIntFromObj(0, objv[i+2], &x);
|
||||
a[i] = x;
|
||||
}
|
||||
rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);
|
||||
if( rc!=SQLITE_OK ){
|
||||
|
@ -1073,7 +1073,7 @@ size_t sqlite3_quota_fwrite(
|
||||
/* If the write was incomplete, adjust the file size and group size
|
||||
** downward */
|
||||
if( rc<nmemb && pFile ){
|
||||
size_t nWritten = rc>=0 ? rc : 0;
|
||||
size_t nWritten = rc;
|
||||
sqlite3_int64 iNewEnd = iOfst + size*nWritten;
|
||||
if( iNewEnd<iEnd ) iNewEnd = iEnd;
|
||||
quotaEnter();
|
||||
@ -1354,8 +1354,10 @@ static void tclQuotaCallback(
|
||||
rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
|
||||
|
||||
if( rc==TCL_OK ){
|
||||
Tcl_WideInt x;
|
||||
Tcl_Obj *pLimit = Tcl_ObjGetVar2(p->interp, pVarname, 0, 0);
|
||||
rc = Tcl_GetWideIntFromObj(p->interp, pLimit, piLimit);
|
||||
rc = Tcl_GetWideIntFromObj(p->interp, pLimit, &x);
|
||||
*piLimit = x;
|
||||
Tcl_UnsetVar(p->interp, Tcl_GetString(pVarname), 0);
|
||||
}
|
||||
|
||||
@ -1437,7 +1439,7 @@ static int test_quota_set(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
const char *zPattern; /* File pattern to configure */
|
||||
sqlite3_int64 iLimit; /* Initial quota in bytes */
|
||||
Tcl_WideInt iLimit; /* Initial quota in bytes */
|
||||
Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */
|
||||
int rc; /* Value returned by quota_set() */
|
||||
TclQuotaCallback *p; /* Callback object */
|
||||
@ -1613,7 +1615,6 @@ static int test_quota_fread(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
got = sqlite3_quota_fread(zBuf, sz, nElem, p);
|
||||
if( got<0 ) got = 0;
|
||||
zBuf[got*sz] = 0;
|
||||
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
|
||||
sqlite3_free(zBuf);
|
||||
|
@ -1771,7 +1771,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
if( sqlite3BtreeIsInTrans(pBt) ){
|
||||
needXcommit = 1;
|
||||
if( i!=1 ) nTrans++;
|
||||
sqlite3BtreeEnter(pBt);
|
||||
rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
|
||||
sqlite3BtreeLeave(pBt);
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
|
10
src/vtab.c
10
src/vtab.c
@ -264,7 +264,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){
|
||||
if( p->azModuleArg ){
|
||||
int i;
|
||||
for(i=0; i<p->nModuleArg; i++){
|
||||
sqlite3DbFree(db, p->azModuleArg[i]);
|
||||
if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
|
||||
}
|
||||
sqlite3DbFree(db, p->azModuleArg);
|
||||
}
|
||||
@ -324,7 +324,7 @@ void sqlite3VtabBeginParse(
|
||||
pTable->tabFlags |= TF_Virtual;
|
||||
pTable->nModuleArg = 0;
|
||||
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
|
||||
addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
|
||||
addModuleArgument(db, pTable, 0);
|
||||
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
|
||||
pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
|
||||
|
||||
@ -481,6 +481,7 @@ static int vtabCallConstructor(
|
||||
int nArg = pTab->nModuleArg;
|
||||
char *zErr = 0;
|
||||
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
|
||||
int iDb;
|
||||
|
||||
if( !zModuleName ){
|
||||
return SQLITE_NOMEM;
|
||||
@ -494,6 +495,10 @@ static int vtabCallConstructor(
|
||||
pVTable->db = db;
|
||||
pVTable->pMod = pMod;
|
||||
|
||||
assert( pTab->azModuleArg[1]==0 );
|
||||
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||
pTab->azModuleArg[1] = db->aDb[iDb].zName;
|
||||
|
||||
/* Invoke the virtual table constructor */
|
||||
assert( &db->pVtabCtx );
|
||||
assert( xConstruct );
|
||||
@ -504,6 +509,7 @@ static int vtabCallConstructor(
|
||||
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
|
||||
db->pVtabCtx = pPriorCtx;
|
||||
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
|
||||
pTab->azModuleArg[1] = 0;
|
||||
|
||||
if( SQLITE_OK!=rc ){
|
||||
if( zErr==0 ){
|
||||
|
@ -2828,7 +2828,7 @@ int sqlite3WalFrames(
|
||||
*/
|
||||
if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
|
||||
if( pWal->padToSectorBoundary ){
|
||||
int sectorSize = sqlite3OsSectorSize(pWal->pWalFd);
|
||||
int sectorSize = sqlite3SectorSize(pWal->pWalFd);
|
||||
w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
|
||||
while( iOffset<w.iSyncPoint ){
|
||||
rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
|
||||
|
733
src/where.c
733
src/where.c
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@
|
||||
#
|
||||
|
||||
if {[file exists skip-big-file]} return
|
||||
if {$tcl_platform(os)=="Darwin"} return
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -14,6 +14,7 @@
|
||||
#
|
||||
|
||||
if {[file exists skip-big-file]} return
|
||||
if {$tcl_platform(os)=="Darwin"} return
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -1864,5 +1864,3 @@ do_execsql_test 10.3 {
|
||||
} {1 21 41 61 81}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ do_test 1.4c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
|
||||
}
|
||||
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
|
||||
} {~/ORDER BY/} ;# optimized out
|
||||
|
||||
|
||||
do_test 1.5a {
|
||||
@ -132,7 +132,7 @@ do_test 1.5c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
|
||||
}
|
||||
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
|
||||
} {~/ORDER BY/} ;# optimized out
|
||||
|
||||
do_test 1.6a {
|
||||
db eval {
|
||||
@ -170,14 +170,14 @@ do_test 2.0 {
|
||||
name TEXT,
|
||||
UNIQUE(aid, tn)
|
||||
);
|
||||
INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
|
||||
INSERT INTO album VALUES(1, '1-one'), (20, '2-two'), (3, '3-three');
|
||||
INSERT INTO track VALUES
|
||||
(1, 1, 'one-a'),
|
||||
(2, 2, 'two-b'),
|
||||
(3, 3, 'three-c'),
|
||||
(1, 3, 'one-c'),
|
||||
(2, 1, 'two-a'),
|
||||
(3, 1, 'three-a');
|
||||
(1, 1, 'one-a'),
|
||||
(20, 2, 'two-b'),
|
||||
(3, 3, 'three-c'),
|
||||
(1, 3, 'one-c'),
|
||||
(20, 1, 'two-a'),
|
||||
(3, 1, 'three-a');
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
@ -196,6 +196,18 @@ do_test 2.1b {
|
||||
}
|
||||
} {~/ORDER BY/} ;# ORDER BY optimized out
|
||||
|
||||
do_test 2.1c {
|
||||
db eval {
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
|
||||
}
|
||||
} {one-a one-c two-a two-b three-a three-c}
|
||||
do_test 2.1d {
|
||||
db eval {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
|
||||
}
|
||||
} {~/ORDER BY/} ;# ORDER BY optimized out
|
||||
|
||||
# The same query with ORDER BY clause optimization disabled via + operators
|
||||
# should give exactly the same answer.
|
||||
#
|
||||
@ -249,7 +261,7 @@ do_test 2.4c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
|
||||
}
|
||||
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
|
||||
} {~/ORDER BY/} ;# optimized out
|
||||
|
||||
|
||||
do_test 2.5a {
|
||||
@ -267,7 +279,7 @@ do_test 2.5c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
|
||||
}
|
||||
} {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC
|
||||
} {~/ORDER BY/} ;# optimized out
|
||||
|
||||
do_test 2.6a {
|
||||
db eval {
|
||||
@ -284,7 +296,7 @@ do_test 2.6c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
|
||||
}
|
||||
} {~/ORDER BY/} ;# ORDER BY optimized-out
|
||||
} {~/ORDER BY/} ;# ORDER BY optimized out
|
||||
|
||||
|
||||
# Generate another test dataset, but this time using mixed ASC/DESC indices.
|
||||
@ -384,7 +396,7 @@ do_test 3.4c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
|
||||
}
|
||||
} {/ORDER BY/} ;# separate sorting pass due to mismatched DESC/ASC
|
||||
} {~/ORDER BY/} ;# optimized out
|
||||
|
||||
|
||||
do_test 3.5a {
|
||||
@ -402,7 +414,7 @@ do_test 3.5c {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
|
||||
}
|
||||
} {/ORDER BY/} ;# separate sorting pass due to mismatched ASC/DESC
|
||||
} {~/ORDER BY/} ;# optimzed out
|
||||
|
||||
|
||||
do_test 3.6a {
|
||||
|
117
test/orderby2.test
Normal file
117
test/orderby2.test
Normal file
@ -0,0 +1,117 @@
|
||||
# 2012 Sept 27
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing that the optimizations that disable
|
||||
# ORDER BY clauses when the natural order of a query is correct.
|
||||
#
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix orderby2
|
||||
|
||||
# Generate test data for a join. Verify that the join gets the
|
||||
# correct answer.
|
||||
#
|
||||
do_test 1.0 {
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1,11), (2,22);
|
||||
CREATE TABLE t2(d, e, UNIQUE(d,e));
|
||||
INSERT INTO t2 VALUES(10, 'ten'), (11,'eleven'), (12,'twelve'),
|
||||
(11, 'oneteen');
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 1.1a {
|
||||
db eval {
|
||||
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY d, e;
|
||||
}
|
||||
} {eleven oneteen}
|
||||
do_test 1.1b {
|
||||
db eval {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY d, e;
|
||||
}
|
||||
} {~/ORDER BY/}
|
||||
|
||||
do_test 1.2a {
|
||||
db eval {
|
||||
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY e;
|
||||
}
|
||||
} {eleven oneteen}
|
||||
do_test 1.2b {
|
||||
db eval {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY e;
|
||||
}
|
||||
} {~/ORDER BY/}
|
||||
|
||||
do_test 1.3a {
|
||||
db eval {
|
||||
SELECT e, b FROM t1, t2 WHERE a=1 ORDER BY d, e;
|
||||
}
|
||||
} {ten 11 eleven 11 oneteen 11 twelve 11}
|
||||
do_test 1.3b {
|
||||
db eval {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT e, b FROM t1, t2 WHERE a=1 ORDER BY d, e;
|
||||
}
|
||||
} {~/ORDER BY/}
|
||||
|
||||
# The following tests derived from TH3 test module cov1/where34.test
|
||||
#
|
||||
do_test 2.0 {
|
||||
db eval {
|
||||
CREATE TABLE t31(a,b); CREATE INDEX t31ab ON t31(a,b);
|
||||
CREATE TABLE t32(c,d); CREATE INDEX t32cd ON t32(c,d);
|
||||
CREATE TABLE t33(e,f); CREATE INDEX t33ef ON t33(e,f);
|
||||
CREATE TABLE t34(g,h); CREATE INDEX t34gh ON t34(g,h);
|
||||
|
||||
INSERT INTO t31 VALUES(1,4), (2,3), (1,3);
|
||||
INSERT INTO t32 VALUES(4,5), (3,6), (3,7), (4,8);
|
||||
INSERT INTO t33 VALUES(5,9), (7,10), (6,11), (8,12), (8,13), (7,14);
|
||||
INSERT INTO t34 VALUES(11,20), (10,21), (12,22), (9,23), (13,24),
|
||||
(14,25), (12,26);
|
||||
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
|
||||
WHERE c=b AND e=d AND g=f
|
||||
ORDER BY a ASC, c ASC, e DESC, g ASC;
|
||||
}
|
||||
} {1,3,7,10 1,3,7,14 1,3,6,11 1,4,8,12 1,4,8,12 1,4,8,13 1,4,5,9 2,3,7,10 2,3,7,14 2,3,6,11}
|
||||
do_test 2.1 {
|
||||
db eval {
|
||||
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
|
||||
WHERE c=b AND e=d AND g=f
|
||||
ORDER BY +a ASC, +c ASC, +e DESC, +g ASC;
|
||||
}
|
||||
} {1,3,7,10 1,3,7,14 1,3,6,11 1,4,8,12 1,4,8,12 1,4,8,13 1,4,5,9 2,3,7,10 2,3,7,14 2,3,6,11}
|
||||
do_test 2.2 {
|
||||
db eval {
|
||||
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
|
||||
WHERE c=b AND e=d AND g=f
|
||||
ORDER BY a ASC, c ASC, e ASC, g ASC;
|
||||
}
|
||||
} {1,3,6,11 1,3,7,10 1,3,7,14 1,4,5,9 1,4,8,12 1,4,8,12 1,4,8,13 2,3,6,11 2,3,7,10 2,3,7,14}
|
||||
do_test 2.3 {
|
||||
optimization_control db cover-idx-scan off
|
||||
db cache flush
|
||||
db eval {
|
||||
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
|
||||
WHERE c=b AND e=d AND g=f
|
||||
ORDER BY a ASC, c ASC, e ASC, g ASC;
|
||||
}
|
||||
} {1,3,6,11 1,3,7,10 1,3,7,14 1,4,5,9 1,4,8,12 1,4,8,12 1,4,8,13 2,3,6,11 2,3,7,10 2,3,7,14}
|
||||
optimization_control db all on
|
||||
db cache flush
|
||||
|
||||
|
||||
|
||||
finish_test
|
207
test/shared9.test
Normal file
207
test/shared9.test
Normal file
@ -0,0 +1,207 @@
|
||||
# 2012 October 5
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# The tests in this file are intended to show if two connections attach
|
||||
# to the same shared cache using different database names, views and
|
||||
# virtual tables may still be accessed.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
set testprefix shared9
|
||||
|
||||
ifcapable !view||!trigger {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
db close
|
||||
set enable_shared_cache [sqlite3_enable_shared_cache 1]
|
||||
|
||||
sqlite3 db1 test.db
|
||||
sqlite3 db2 test.db
|
||||
forcedelete test.db2
|
||||
|
||||
do_test 1.1 {
|
||||
db1 eval {
|
||||
ATTACH 'test.db2' AS 'fred';
|
||||
CREATE TABLE fred.t1(a, b, c);
|
||||
CREATE VIEW fred.v1 AS SELECT * FROM t1;
|
||||
|
||||
CREATE TABLE fred.t2(a, b);
|
||||
CREATE TABLE fred.t3(a, b);
|
||||
CREATE TRIGGER fred.trig AFTER INSERT ON t2 BEGIN
|
||||
DELETE FROM t3;
|
||||
INSERT INTO t3 SELECT * FROM t2;
|
||||
END;
|
||||
INSERT INTO t2 VALUES(1, 2);
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {1 2}
|
||||
|
||||
do_test 1.2 { db2 eval "ATTACH 'test.db2' AS 'jones'" } {}
|
||||
do_test 1.3 { db2 eval "SELECT * FROM v1" } {}
|
||||
do_test 1.4 { db2 eval "INSERT INTO t2 VALUES(3, 4)" } {}
|
||||
|
||||
ifcapable fts3 {
|
||||
do_test 1.5 {
|
||||
db1 eval {
|
||||
CREATE VIRTUAL TABLE fred.t4 USING fts4;
|
||||
INSERT INTO t4 VALUES('hello world');
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 1.6 {
|
||||
db2 eval {
|
||||
INSERT INTO t4 VALUES('shared cache');
|
||||
SELECT * FROM t4 WHERE t4 MATCH 'hello';
|
||||
}
|
||||
} {{hello world}}
|
||||
|
||||
do_test 1.7 {
|
||||
db1 eval {
|
||||
SELECT * FROM t4 WHERE t4 MATCH 'c*';
|
||||
}
|
||||
} {{shared cache}}
|
||||
}
|
||||
|
||||
db1 close
|
||||
db2 close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests attempt to find a similar problem with collation
|
||||
# sequence names - pointers to database handle specific allocations leaking
|
||||
# into schema objects and being used after the original handle has been
|
||||
# closed.
|
||||
#
|
||||
forcedelete test.db test.db2
|
||||
sqlite3 db1 test.db
|
||||
sqlite3 db2 test.db
|
||||
foreach x {collate1 collate2 collate3} {
|
||||
proc $x {a b} { string compare $a $b }
|
||||
db1 collate $x $x
|
||||
db2 collate $x $x
|
||||
}
|
||||
do_test 2.1 {
|
||||
db1 eval {
|
||||
CREATE TABLE t1(a, b, c COLLATE collate1);
|
||||
CREATE INDEX i1 ON t1(a COLLATE collate2, c, b);
|
||||
}
|
||||
} {}
|
||||
do_test 2.2 {
|
||||
db1 close
|
||||
db2 eval "INSERT INTO t1 VALUES('abc', 'def', 'ghi')"
|
||||
} {}
|
||||
db2 close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# At one point, the following would cause a collation sequence belonging
|
||||
# to connection [db1] to be invoked by a call to [db2 eval]. Which is a
|
||||
# problem if [db1] has already been closed.
|
||||
#
|
||||
forcedelete test.db test.db2
|
||||
sqlite3 db1 test.db
|
||||
sqlite3 db2 test.db
|
||||
|
||||
proc mycollate_db1 {a b} {set ::invoked_mycollate_db1 1 ; string compare $a $b}
|
||||
proc mycollate_db2 {a b} {string compare $a $b}
|
||||
|
||||
db1 collate mycollate mycollate_db1
|
||||
db2 collate mycollate mycollate_db2
|
||||
|
||||
do_test 2.3 {
|
||||
set ::invoked_mycollate_db1 0
|
||||
db1 eval {
|
||||
CREATE TABLE t1(a COLLATE mycollate, CHECK (a IN ('one', 'two', 'three')));
|
||||
INSERT INTO t1 VALUES('one');
|
||||
}
|
||||
db1 close
|
||||
set ::invoked_mycollate_db1
|
||||
} {1}
|
||||
do_test 2.4 {
|
||||
set ::invoked_mycollate_db1 0
|
||||
db2 eval {
|
||||
INSERT INTO t1 VALUES('two');
|
||||
}
|
||||
db2 close
|
||||
set ::invoked_mycollate_db1
|
||||
} {0}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# This test verifies that a bug causing a busy-handler belonging to one
|
||||
# shared-cache connection to be executed as a result of an sqlite3_step()
|
||||
# on another has been fixed.
|
||||
#
|
||||
forcedelete test.db test.db2
|
||||
sqlite3 db1 test.db
|
||||
sqlite3 db2 test.db
|
||||
|
||||
proc busyhandler {handle args} {
|
||||
set ::busyhandler_invoked_for $handle
|
||||
return 1
|
||||
}
|
||||
db1 busy [list busyhandler db1]
|
||||
db2 busy [list busyhandler db2]
|
||||
|
||||
do_test 3.1 {
|
||||
db1 eval {
|
||||
BEGIN;
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t2 VALUES(1, 2);
|
||||
}
|
||||
# Keep this next COMMIT as a separate statement. This ensures that COMMIT
|
||||
# has already been compiled and loaded into the tcl interface statement
|
||||
# cache when it is attempted below.
|
||||
db1 eval COMMIT
|
||||
db1 eval {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 3.2 {
|
||||
set ::tf [launch_testfixture]
|
||||
testfixture $::tf {
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
}
|
||||
} {1 2}
|
||||
|
||||
do_test 3.3 {
|
||||
db2 eval { SELECT * FROM t2 }
|
||||
} {1 2}
|
||||
|
||||
do_test 3.4 {
|
||||
list [catch { db1 eval COMMIT } msg] $msg
|
||||
} {1 {database is locked}}
|
||||
|
||||
# At one point the following would fail, showing that the busy-handler
|
||||
# belonging to [db2] was invoked instead.
|
||||
do_test 3.5 {
|
||||
set ::busyhandler_invoked_for
|
||||
} {db1}
|
||||
do_test 3.6 {
|
||||
close $::tf
|
||||
db1 eval COMMIT
|
||||
} {}
|
||||
|
||||
db1 close
|
||||
db2 close
|
||||
|
||||
sqlite3_enable_shared_cache $::enable_shared_cache
|
||||
finish_test
|
||||
|
@ -319,14 +319,23 @@ do_test tcl-8.1 {
|
||||
execsql {INSERT INTO t1 VALUES(30,NULL)}
|
||||
db eval {SELECT * FROM t1 WHERE b IS NULL}
|
||||
} {30 NaN}
|
||||
proc concatFunc args {return [join $args {}]}
|
||||
do_test tcl-8.2 {
|
||||
db function concat concatFunc
|
||||
db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL}
|
||||
} {aNaNz}
|
||||
do_test tcl-8.3 {
|
||||
db nullvalue NULL
|
||||
db nullvalue
|
||||
} {NULL}
|
||||
do_test tcl-8.3 {
|
||||
do_test tcl-8.4 {
|
||||
db nullvalue {}
|
||||
db eval {SELECT * FROM t1 WHERE b IS NULL}
|
||||
} {30 {}}
|
||||
do_test tcl-8.5 {
|
||||
db function concat concatFunc
|
||||
db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL}
|
||||
} {az}
|
||||
|
||||
# Test the return type of user-defined functions
|
||||
#
|
||||
|
@ -11,20 +11,20 @@
|
||||
# with the database COMMIT/ROLLBACK logic.
|
||||
#
|
||||
# 1. CREATE and DROP TRIGGER tests
|
||||
# trig-1.1: Error if table does not exist
|
||||
# trig-1.2: Error if trigger already exists
|
||||
# trig-1.3: Created triggers are deleted if the transaction is rolled back
|
||||
# trig-1.4: DROP TRIGGER removes trigger
|
||||
# trig-1.5: Dropped triggers are restored if the transaction is rolled back
|
||||
# trig-1.6: Error if dropped trigger doesn't exist
|
||||
# trig-1.7: Dropping the table automatically drops all triggers
|
||||
# trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master
|
||||
# trig-1.9: Ensure that we cannot create a trigger on sqlite_master
|
||||
# trig-1.10:
|
||||
# trig-1.11:
|
||||
# trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
|
||||
# trig-1.13: Ensure that AFTER triggers cannot be created on views
|
||||
# trig-1.14: Ensure that BEFORE triggers cannot be created on views
|
||||
# trigger1-1.1: Error if table does not exist
|
||||
# trigger1-1.2: Error if trigger already exists
|
||||
# trigger1-1.3: Created triggers are deleted if the transaction is rolled back
|
||||
# trigger1-1.4: DROP TRIGGER removes trigger
|
||||
# trigger1-1.5: Dropped triggers are restored if the transaction is rolled back
|
||||
# trigger1-1.6: Error if dropped trigger doesn't exist
|
||||
# trigger1-1.7: Dropping the table automatically drops all triggers
|
||||
# trigger1-1.8: A trigger created on a TEMP table is not inserted into sqlite_master
|
||||
# trigger1-1.9: Ensure that we cannot create a trigger on sqlite_master
|
||||
# trigger1-1.10:
|
||||
# trigger1-1.11:
|
||||
# trigger1-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
|
||||
# trigger1-1.13: Ensure that AFTER triggers cannot be created on views
|
||||
# trigger1-1.14: Ensure that BEFORE triggers cannot be created on views
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -210,7 +210,7 @@ do_test trigger1-1.12 {
|
||||
delete from t1 WHERE a=old.a+2;
|
||||
end;
|
||||
}
|
||||
} {1 {cannot create INSTEAD OF trigger on table: main.t1}}
|
||||
} {1 {cannot create INSTEAD OF trigger on table: t1}}
|
||||
|
||||
ifcapable view {
|
||||
# Ensure that we cannot create BEFORE triggers on views
|
||||
@ -221,7 +221,7 @@ do_test trigger1-1.13 {
|
||||
delete from t1 WHERE a=old.a+2;
|
||||
end;
|
||||
}
|
||||
} {1 {cannot create BEFORE trigger on view: main.v1}}
|
||||
} {1 {cannot create BEFORE trigger on view: v1}}
|
||||
# Ensure that we cannot create AFTER triggers on views
|
||||
do_test trigger1-1.14 {
|
||||
catchsql {
|
||||
@ -231,7 +231,7 @@ do_test trigger1-1.14 {
|
||||
delete from t1 WHERE a=old.a+2;
|
||||
end;
|
||||
}
|
||||
} {1 {cannot create AFTER trigger on view: main.v1}}
|
||||
} {1 {cannot create AFTER trigger on view: v1}}
|
||||
} ;# ifcapable view
|
||||
|
||||
# Check for memory leaks in the trigger parser
|
||||
@ -265,32 +265,32 @@ ifcapable tempdb {
|
||||
END;
|
||||
}
|
||||
} {0 {}}
|
||||
do_test trigger-3.2 {
|
||||
do_test trigger1-3.2 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {1 {no such table: main.t2}}
|
||||
do_test trigger-3.3 {
|
||||
do_test trigger1-3.3 {
|
||||
db close
|
||||
set rc [catch {sqlite3 db test.db} err]
|
||||
if {$rc} {lappend rc $err}
|
||||
set rc
|
||||
} {0}
|
||||
do_test trigger-3.4 {
|
||||
do_test trigger1-3.4 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {1 {no such table: main.t2}}
|
||||
do_test trigger-3.5 {
|
||||
do_test trigger1-3.5 {
|
||||
catchsql {
|
||||
CREATE TEMP TABLE t2(x,y);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {1 {no such table: main.t2}}
|
||||
do_test trigger-3.6.1 {
|
||||
do_test trigger1-3.6.1 {
|
||||
catchsql {
|
||||
DROP TRIGGER r1;
|
||||
CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
|
||||
@ -300,7 +300,7 @@ ifcapable tempdb {
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {0 {1 2 200 100}}
|
||||
do_test trigger-3.6.2 {
|
||||
do_test trigger1-3.6.2 {
|
||||
catchsql {
|
||||
DROP TRIGGER r1;
|
||||
DELETE FROM t1;
|
||||
@ -312,7 +312,7 @@ ifcapable tempdb {
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {0 {1 2}}
|
||||
do_test trigger-3.7 {
|
||||
do_test trigger1-3.7 {
|
||||
execsql {
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2(x,y);
|
||||
@ -320,7 +320,7 @@ ifcapable tempdb {
|
||||
}
|
||||
} {}
|
||||
|
||||
# There are two versions of trigger-3.8 and trigger-3.9. One that uses
|
||||
# There are two versions of trigger1-3.8 and trigger1-3.9. One that uses
|
||||
# compound SELECT statements, and another that does not.
|
||||
ifcapable compound {
|
||||
do_test trigger1-3.8 {
|
||||
@ -446,7 +446,7 @@ do_test trigger1-6.8 {
|
||||
execsql {SELECT * FROM t2}
|
||||
} {3 4 7 8}
|
||||
|
||||
integrity_check trigger-7.1
|
||||
integrity_check trigger1-7.1
|
||||
|
||||
# Check to make sure the name of a trigger can be quoted so that keywords
|
||||
# can be used as trigger names. Ticket #468
|
||||
@ -491,7 +491,7 @@ do_test trigger1-8.6 {
|
||||
ifcapable conflict {
|
||||
# Make sure REPLACE works inside of triggers.
|
||||
#
|
||||
# There are two versions of trigger-9.1 and trigger-9.2. One that uses
|
||||
# There are two versions of trigger1-9.1 and trigger1-9.2. One that uses
|
||||
# compound SELECT statements, and another that does not.
|
||||
ifcapable compound {
|
||||
do_test trigger1-9.1 {
|
||||
@ -612,7 +612,7 @@ ifcapable tempdb&&attach {
|
||||
SELECT * FROM insert_log;
|
||||
}
|
||||
} {main 11 12 13 temp 14 15 16 aux 17 18 19}
|
||||
do_test trigger1-10.8 {
|
||||
do_test trigger1-10.9 {
|
||||
# Drop and re-create the insert_log table in a different database. Note
|
||||
# that we can change the column names because the trigger programs don't
|
||||
# use them explicitly.
|
||||
|
@ -1088,12 +1088,12 @@ do_test where-14.1 {
|
||||
cksort {
|
||||
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b
|
||||
}
|
||||
} {1/4 1/1 4/4 4/1 sort}
|
||||
} {1/4 1/1 4/4 4/1 nosort}
|
||||
do_test where-14.2 {
|
||||
cksort {
|
||||
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b DESC
|
||||
}
|
||||
} {1/1 1/4 4/1 4/4 sort}
|
||||
} {1/1 1/4 4/1 4/4 nosort}
|
||||
do_test where-14.3 {
|
||||
cksort {
|
||||
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b
|
||||
|
@ -142,7 +142,7 @@ FOR %%P IN (%PLATFORMS%) DO (
|
||||
REM be used for the name of the platform-specific binary directory via
|
||||
REM the environment variables setup earlier.
|
||||
REM
|
||||
CALL :fn_SetVariable %%P_NAME PLATFORMNAME
|
||||
CALL :fn_CopyVariable %%P_NAME PLATFORMNAME
|
||||
|
||||
REM
|
||||
REM NOTE: This is the inner loop. There should be exactly one iteration.
|
||||
@ -230,7 +230,7 @@ FOR %%P IN (%PLATFORMS%) DO (
|
||||
REM file used to setup the MSVC environment.
|
||||
REM
|
||||
IF DEFINED SET_NSDKLIBPATH (
|
||||
CALL :fn_SetVariable WindowsSdkDir NSDKLIBPATH
|
||||
CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
|
||||
CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
|
||||
)
|
||||
|
||||
@ -339,7 +339,7 @@ GOTO no_errors
|
||||
VERIFY MAYBE 2> NUL
|
||||
GOTO :EOF
|
||||
|
||||
:fn_SetVariable
|
||||
:fn_CopyVariable
|
||||
SETLOCAL
|
||||
IF NOT DEFINED %1 GOTO :EOF
|
||||
IF "%2" == "" GOTO :EOF
|
||||
|
Loading…
Reference in New Issue
Block a user