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:
drh 2012-10-09 14:58:15 +00:00
commit d1102b1ec7
41 changed files with 1105 additions and 565 deletions

View File

@ -30,6 +30,10 @@ XCOMPILE = 0
# #
USE_NATIVE_LIBPATHS = 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. # 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 # This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc). # 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 !IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1 TCC = $(TCC) -DSQLITE_OS_WINRT=1
RCC = $(RCC) -DSQLITE_OS_WINRT=1 RCC = $(RCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
!ENDIF !ENDIF
# Also, we need to dynamically link to the correct MSVC runtime # 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 $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>0 !IF $(DEBUG)>0
TCC = $(TCC) -MDd TCC = $(TCC) -MDd
BCC = $(BCC) -MDd
!ELSE !ELSE
TCC = $(TCC) -MD TCC = $(TCC) -MD
BCC = $(BCC) -MD
!ENDIF !ENDIF
!ELSE !ELSE
!IF $(DEBUG)>0 !IF $(DEBUG)>0
TCC = $(TCC) -MTd TCC = $(TCC) -MTd
BCC = $(BCC) -MTd
!ELSE !ELSE
TCC = $(TCC) -MT TCC = $(TCC) -MT
BCC = $(BCC) -MT
!ENDIF !ENDIF
!ENDIF !ENDIF
@ -474,6 +482,14 @@ LIBOBJ = $(LIBOBJS0)
LIBOBJ = $(LIBOBJS1) LIBOBJ = $(LIBOBJS1)
!ENDIF !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. # All of the source code files.
# #
SRC = \ SRC = \
@ -782,10 +798,10 @@ libsqlite3.lib: $(LIBOBJ)
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS) $(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) \ $(LTLINK) $(READLINE_FLAGS) \
$(TOP)\src\shell.c \ $(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 # This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to # 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. # 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 echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
for /F %%V in ('type "$(TOP)\VERSION"') do ( \ for /F %%V in ('type "$(TOP)\VERSION"') do ( \
echo #define SQLITE_RESOURCE_VERSION %%V \ echo #define SQLITE_RESOURCE_VERSION %%V \
| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \ | $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
) )
echo #endif >> 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. # 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) tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
$(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c $(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib sqlite3res.lo tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib $(LIBRESOBJS)
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo sqlite3res.lo $(LTLIBS) $(TLIBS) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
# Rules to build opcodes.c and opcodes.h # 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) TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
!ENDIF !ENDIF
testfixture.exe: $(TESTFIXTURE_SRC) sqlite3res.lo $(HDR) testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
-DBUILD_sqlite -I$(TCLINCDIR) \ -DBUILD_sqlite -I$(TCLINCDIR) \
$(TESTFIXTURE_SRC) \ $(TESTFIXTURE_SRC) \
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS) /link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
fulltest: testfixture.exe sqlite3.exe fulltest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test .\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 >> $@ $(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
echo ; return zMainloop; } >> $@ 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 \ $(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS) /link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
clean: clean:
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
@ -1233,5 +1251,5 @@ sqlite3.def: libsqlite3.lib
| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \ | $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
| sort >> sqlite3.def | sort >> sqlite3.def
sqlite3.dll: $(LIBOBJ) sqlite3res.lo sqlite3.def sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) sqlite3res.lo $(LTLIBS) $(TLIBS) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

View File

@ -2660,7 +2660,7 @@ static int newRowid(Rtree *pRtree, i64 *piRowid){
*/ */
static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
int rc; /* Return code */ 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 */ int iCell; /* Index of iDelete cell in pLeaf */
RtreeNode *pRoot; /* Root node of rtree structure */ RtreeNode *pRoot; /* Root node of rtree structure */
@ -2863,7 +2863,7 @@ static int rtreeUpdate(
*/ */
if( rc==SQLITE_OK && nData>1 ){ if( rc==SQLITE_OK && nData>1 ){
/* Insert the new record into the r-tree */ /* Insert the new record into the r-tree */
RtreeNode *pLeaf; RtreeNode *pLeaf = 0;
/* Figure out the rowid of the new row. */ /* Figure out the rowid of the new row. */
if( bHaveRowid==0 ){ if( bHaveRowid==0 ){

View File

@ -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. C Merge\sthe\slatest\strunk\schanges,\sespecially\sthe\sORDER\sBY\soptimizer\senhancements\nbut\salso\sother\sfixes,\sonto\sthe\ssessions\sbranch.
D 2012-09-28T13:05:48.372 D 2012-10-09T14:58:15.175
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 321efe6f572a1d4f8e27794c4575dd9b51d3e731 F Makefile.msc a26021086defb54e6cb61439a90be5960b713017
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d
@ -83,7 +83,7 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 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/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9 F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@ -126,23 +126,23 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 0c1716aa8d248bd6bc750e23be4c68ad05f8668c F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410 F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143 F src/attach.c 34c15ecd686e58f08e5bb1389e28a0b65c2c83db
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 5b31b24d6814b11de763debf342c8cd0a15a4910 F src/backup.c afc067b9a9050ff48b9d46285c53d096c556a73d
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1 F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 9cf6de113d23d47967df24b8d8ce6501c879d7e6 F src/btree.c 14de53ebb334633ee632ab3c5b9262cfe7cbe455
F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2 F src/btree.h 078f76b28c338ab6eb6dd7324d63ee54463aeb6c
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
F src/build.c c4555e16f8ccdadb2616014c617ed8166c5a93f7 F src/build.c b21c130017820dfe8721e380325e128fd0c6e019
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c c856ca31177a5cc1612b47ca0c628cd227aa072e F src/delete.c e44a1b66cd3dc1e9e2c74147ee4991214e6e6978
F src/expr.c 4de967b85f577ba00a7cdcb53d22070def6198db F src/expr.c 57fb8e7a05d4147e40b9f4c439e37ed2abab9332
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af
F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898
@ -150,12 +150,12 @@ F src/global.c fb44b11e02e06c995e6ed6642509edd23599d584
F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 08ec5cec28c692fc27a23659875cc167f5c6ece7 F src/insert.c 6273647b67e27e3f81b7d1fd144307ea726841d0
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c febaf66b42c36433b170e4704fef5b8b073a6d61 F src/main.c 5cee8048dde78b2b47f5c2090cbb31b10d190673
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@ -172,31 +172,31 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9 F src/os_unix.c a5a45a2857c43b37bac145b521064a85a544cd7a
F src/os_win.c 90c7a1fe2698867555ba4266f5bd436c85d0d1dc F src/os_win.c 28bd027791252a4012dffd4d64355a1eb84d761c
F src/pager.c 9c59818c480261c1c5a4772532e0df92a27745a1 F src/pager.c a7ad8c38809edf0be545e8f52da5bcbb88885b38
F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5 F src/pager.h bdbc379557eb2e233dfec10986b3086877e72db7
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
F src/pragma.c 7f5a0fa6dead752d9af3a1e1d16bace81d22ef95 F src/pragma.c 4f31fe4ae4b885a8be8b1db9d94f9f5b6c8b5624
F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 75c5e37cc882c468383c9d9e07496b9a16cfae3e F src/select.c 2a82736faeca1fe93315eda20c691d68ec13bb6c
F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7
F src/sqlite.h.in 2f2822ac789d820e05afb19831e62fd83e69c60b F src/sqlite.h.in d460ae07ecdd1c820272d9c217547c7b572cb4b7
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 34844b666512c2c5656c5d470f165ed1db0fcd48 F src/sqliteInt.h fec16c0932b30aedf5d3b577aaf5f881589c8dd0
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 79ac64bdd8555b8967032e1e69051d88366f9b77 F src/tclsqlite.c 289be7b639406314813219ee7bc043d21f36ab12
F src/test1.c 0354b555639c92d2a63c0ad4e74ed152ba47e604 F src/test1.c 936afc02766403e5debca49a1817a780e116df7e
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
@ -216,7 +216,7 @@ F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148 F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a 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_intarray.h 489edb9068bb926583445cb02589344961054207
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e 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_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 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_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
@ -252,16 +252,16 @@ F src/vdbe.c e8e2e34c23a474c38f494d572a0d8accaabd0b4a
F src/vdbe.h 87b8ff40de3f55dbcdc33029416862f517c37a2f F src/vdbe.h 87b8ff40de3f55dbcdc33029416862f517c37a2f
F src/vdbeInt.h 39acf85fa83f98e27e728722a0f53daf7d174b61 F src/vdbeInt.h 39acf85fa83f98e27e728722a0f53daf7d174b61
F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647 F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647
F src/vdbeaux.c 857c8372d3b06d66e37428712265f9033932f3ec F src/vdbeaux.c 1005a2ea2cbbe5d2841367eebae67ce848a6247a
F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381 F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835 F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/vtab.c 9c64ae18af78c740610df841c6f49fc2d240a279
F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.c e1fe8f92a0ea0fef8faa87ec43a127a478589d22
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c d836df3a2096c41c39e48ab5636f09f94ba02676 F src/where.c 410017c604713ab6c010a9e3731a7688a0c7a059
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
@ -307,8 +307,8 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070 F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test 8f88b5ef065e31c615c49d725ede94155fbe9609 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 8a3c242c3c3481e7cde5a6ef2a66fdc367a095f7 F test/bigfile2.test 7c79f1ef0c6c2c2bc1e7bd895596fab32bfb4796
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0 F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
@ -524,7 +524,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test 69cf1036b92fd3b8e1fd65bef4d7ee3f085c28fb F test/fuzzer1.test a2e93bb1e19513dd6bf9c63d3d7c4673c983ca19
F test/fuzzerfault.test ff2282c81797b6a355f0748d8b54c7287c5d2b25 F test/fuzzerfault.test ff2282c81797b6a355f0748d8b54c7287c5d2b25
F test/hook.test 94b927b15883f5c1477ab09eecd16275addb08f4 F test/hook.test 94b927b15883f5c1477ab09eecd16275addb08f4
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
@ -646,7 +646,8 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 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/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
@ -714,6 +715,7 @@ F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
F test/shared9.test 614a3ca431adc73c857632deb4eff75bcaee40ec
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53 F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53
@ -749,7 +751,7 @@ F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tclsqlite.test 02b2c268d38203987dd1839598ac524f7612ec3c F test/tclsqlite.test a7308276aad2e6c0bfb5b0414424dd0d9cc0cad7
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
@ -896,7 +898,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
F test/trigger1.test de42feb7cd442787d38185ae74f5a1d7afa400cb F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
@ -968,7 +970,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test a6bfb5a29286811d798d326a8f1153a58c0fb2bd F test/where.test 41b65069a227a61238c1387b050f029480ca5677
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@ -986,7 +988,7 @@ F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c 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/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
@ -1030,7 +1032,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
P fae9eb197fcef726fd2c7c701afe6805fc008cf9 1e874629d7cf568368b912b295bd3001147d0b52 P 6ca8eae1f89d19ee23cbc3a869d85b57d29b4a7d a02599ad85d02470c9effa51c02dbda7796bfa16
R 3dd4bfa3bb20bc9f3b355292d5659141 R 05272e22ec105aad09507c576198ab3e
U drh U drh
Z d6a15b3f33482cbc762a2fcdf6bf0623 Z 8b270f262a5da1e0ba6e8c7b897dd596

View File

@ -1 +1 @@
6ca8eae1f89d19ee23cbc3a869d85b57d29b4a7d f1fbb8c5bfa84e84e0b8e2872d83b06a0c0d5acc

View File

@ -414,7 +414,7 @@ void sqlite3AlterRenameTable(
assert( pSrc->nSrc==1 ); assert( pSrc->nSrc==1 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); 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; if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zName; zDb = db->aDb[iDb].zName;
@ -757,7 +757,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
assert( pParse->pNewTable==0 ); assert( pParse->pNewTable==0 );
assert( sqlite3BtreeHoldsAllMutexes(db) ); assert( sqlite3BtreeHoldsAllMutexes(db) );
if( db->mallocFailed ) goto exit_begin_add_column; 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; if( !pTab ) goto exit_begin_add_column;
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE

View File

@ -434,6 +434,7 @@ int sqlite3FixInit(
assert( db->nDb>iDb ); assert( db->nDb>iDb );
pFix->pParse = pParse; pFix->pParse = pParse;
pFix->zDb = db->aDb[iDb].zName; pFix->zDb = db->aDb[iDb].zName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType; pFix->zType = zType;
pFix->pName = pName; pFix->pName = pName;
return 1; return 1;
@ -464,14 +465,15 @@ int sqlite3FixSrcList(
if( NEVER(pList==0) ) return 0; if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb; zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->zDatabase==0 ){ if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
}else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
sqlite3ErrorMsg(pFix->pParse, sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s", "%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase); pFix->zType, pFix->pName, pItem->zDatabase);
return 1; return 1;
} }
sqlite3_free(pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;

View File

@ -219,13 +219,16 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
const int nCopy = MIN(nSrcPgsz, nDestPgsz); const int nCopy = MIN(nSrcPgsz, nDestPgsz);
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
#ifdef SQLITE_HAS_CODEC #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); int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
#endif #endif
int rc = SQLITE_OK; int rc = SQLITE_OK;
i64 iOff; i64 iOff;
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
assert( p->bDestLocked ); assert( p->bDestLocked );
assert( !isFatalError(p->rc) ); assert( !isFatalError(p->rc) );
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );

View File

@ -2200,6 +2200,24 @@ int sqlite3BtreeGetPageSize(Btree *p){
return p->pBt->pageSize; 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) #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/* /*
** Return the number of bytes of space at the end of every page that ** 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 */ return SQLITE_OK; /* No overflow pages. Return without doing anything */
} }
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ 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]); ovflPgno = get4byte(&pCell[info.iOverflow]);
assert( pBt->usableSize > 4 ); 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 ** If aOvflSpace is set to a null pointer, this function returns
** SQLITE_NOMEM. ** SQLITE_NOMEM.
*/ */
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", off)
#endif
static int balance_nonroot( static int balance_nonroot(
MemPage *pParent, /* Parent page of siblings being balanced */ MemPage *pParent, /* Parent page of siblings being balanced */
int iParentIdx, /* Index of "the page" in pParent */ int iParentIdx, /* Index of "the page" in pParent */
@ -6552,6 +6573,9 @@ balance_cleanup:
return rc; return rc;
} }
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", on)
#endif
/* /*

View File

@ -71,6 +71,9 @@ int sqlite3BtreeMaxPageCount(Btree*,int);
u32 sqlite3BtreeLastPage(Btree*); u32 sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeSecureDelete(Btree*,int); int sqlite3BtreeSecureDelete(Btree*,int);
int sqlite3BtreeGetReserve(Btree*); int sqlite3BtreeGetReserve(Btree*);
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
int sqlite3BtreeGetReserveNoMutex(Btree *p);
#endif
int sqlite3BtreeSetAutoVacuum(Btree *, int); int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *); int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int); int sqlite3BtreeBeginTrans(Btree*,int);

View File

@ -319,6 +319,31 @@ Table *sqlite3LocateTable(
return p; 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 ** Locate the in-memory structure that describes
** a particular index given the name of that index ** 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); pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){ if( !initbusy && (!pColl || !pColl->xCmp) ){
pColl = sqlite3GetCollSeq(db, enc, pColl, zName); pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
if( !pColl ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
} }
return pColl; return pColl;
@ -2114,8 +2136,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
assert( pParse->nErr==0 ); assert( pParse->nErr==0 );
assert( pName->nSrc==1 ); assert( pName->nSrc==1 );
if( noErr ) db->suppressErr++; if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTable(pParse, isView, pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
pName->a[0].zName, pName->a[0].zDatabase);
if( noErr ) db->suppressErr--; if( noErr ) db->suppressErr--;
if( pTab==0 ){ if( pTab==0 ){
@ -2555,9 +2576,9 @@ Index *sqlite3CreateIndex(
** sqlite3FixSrcList can never fail. */ ** sqlite3FixSrcList can never fail. */
assert(0); assert(0);
} }
pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
pTblName->a[0].zDatabase); assert( db->mallocFailed==0 || pTab==0 );
if( !pTab || db->mallocFailed ) goto exit_create_index; if( pTab==0 ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema ); assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{ }else{
assert( pName==0 ); assert( pName==0 );

View File

@ -75,17 +75,18 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
** **
** The return value is either the collation sequence to be used in database ** 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 ** 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() ** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/ */
CollSeq *sqlite3GetCollSeq( CollSeq *sqlite3GetCollSeq(
sqlite3* db, /* The database connection */ Parse *pParse, /* Parsing context */
u8 enc, /* The desired encoding for the collating sequence */ u8 enc, /* The desired encoding for the collating sequence */
CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
const char *zName /* Collating sequence name */ const char *zName /* Collating sequence name */
){ ){
CollSeq *p; CollSeq *p;
sqlite3 *db = pParse->db;
p = pColl; p = pColl;
if( !p ){ if( !p ){
@ -102,6 +103,9 @@ CollSeq *sqlite3GetCollSeq(
p = 0; p = 0;
} }
assert( !p || p->xCmp ); assert( !p || p->xCmp );
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
return p; return p;
} }
@ -120,10 +124,8 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){ if( pColl ){
const char *zName = pColl->zName; const char *zName = pColl->zName;
sqlite3 *db = pParse->db; sqlite3 *db = pParse->db;
CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName); CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
if( !p ){ if( !p ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
pParse->nErr++;
return SQLITE_ERROR; return SQLITE_ERROR;
} }
assert( p==pColl ); assert( p==pColl );

View File

@ -32,7 +32,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
struct SrcList_item *pItem = pSrc->a; struct SrcList_item *pItem = pSrc->a;
Table *pTab; Table *pTab;
assert( pItem && pSrc->nSrc==1 ); assert( pItem && pSrc->nSrc==1 );
pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); pTab = sqlite3LocateTableItem(pParse, 0, pItem);
sqlite3DeleteTable(pParse->db, pItem->pTab); sqlite3DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab; pItem->pTab = pTab;
if( pTab ){ if( pTab ){

View File

@ -930,6 +930,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pNewItem = &pNew->a[i];
struct SrcList_item *pOldItem = &p->a[i]; struct SrcList_item *pOldItem = &p->a[i];
Table *pTab; Table *pTab;
pNewItem->pSchema = pOldItem->pSchema;
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);

View File

@ -1274,20 +1274,25 @@ void sqlite3GenerateConstraintChecks(
onError = overrideError!=OE_Default ? overrideError : OE_Abort; onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; i<pCheck->nExpr; i++){ for(i=0; i<pCheck->nExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v); int allOk = sqlite3VdbeMakeLabel(v);
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL); Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
if( onError==OE_Ignore ){ if( !db->mallocFailed ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); assert( pDup!=0 );
}else{ sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
char *zConsName = pCheck->a[i].zName; if( onError==OE_Ignore ){
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
if( zConsName ){
zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
}else{ }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) */ #endif /* !defined(SQLITE_OMIT_CHECK) */
@ -1753,7 +1758,7 @@ static int xferOptimization(
** we have to check the semantics. ** we have to check the semantics.
*/ */
pItem = pSelect->pSrc->a; pItem = pSelect->pSrc->a;
pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
if( pSrc==0 ){ if( pSrc==0 ){
return 0; /* FROM clause does not contain a real table */ return 0; /* FROM clause does not contain a real table */
} }

View File

@ -3040,7 +3040,7 @@ int sqlite3_test_control(int op, ...){
*/ */
case SQLITE_TESTCTRL_OPTIMIZATIONS: { case SQLITE_TESTCTRL_OPTIMIZATIONS: {
sqlite3 *db = va_arg(ap, sqlite3*); sqlite3 *db = va_arg(ap, sqlite3*);
db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
break; break;
} }

View File

@ -3010,6 +3010,8 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
i64 newOffset; i64 newOffset;
#endif #endif
TIMER_START; TIMER_START;
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
do{ do{
#if defined(USE_PREAD) #if defined(USE_PREAD)
got = osPread(id->h, pBuf, cnt, offset); 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)) #if (!defined(USE_PREAD) && !defined(USE_PREAD64))
i64 newOffset; i64 newOffset;
#endif #endif
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
TIMER_START; TIMER_START;
#if defined(USE_PREAD) #if defined(USE_PREAD)
do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );

View File

@ -33,6 +33,57 @@
with SQLITE_OMIT_WAL." with SQLITE_OMIT_WAL."
#endif #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. ** Macro to find the minimum of two numeric values.
*/ */
@ -238,14 +289,6 @@ int sqlite3_os_type = 0;
static int sqlite3_os_type = 0; static int sqlite3_os_type = 0;
#endif #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 #ifndef SYSCALL
# define SYSCALL sqlite3_syscall_ptr # define SYSCALL sqlite3_syscall_ptr
#endif #endif
@ -402,7 +445,11 @@ static struct win_syscall {
#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
DWORD,va_list*))aSyscall[15].pCurrent) DWORD,va_list*))aSyscall[15].pCurrent)
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, { "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
#else
{ "FreeLibrary", (SYSCALL)0, 0 },
#endif
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) #define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
@ -483,6 +530,7 @@ static struct win_syscall {
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
#if SQLITE_OS_WINCE #if SQLITE_OS_WINCE
/* The GetProcAddressA() routine is only available on Windows CE. */ /* The GetProcAddressA() routine is only available on Windows CE. */
{ "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
@ -491,6 +539,9 @@ static struct win_syscall {
** an ANSI string regardless of the _UNICODE setting */ ** an ANSI string regardless of the _UNICODE setting */
{ "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
#endif #endif
#else
{ "GetProcAddressA", (SYSCALL)0, 0 },
#endif
#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
LPCSTR))aSyscall[27].pCurrent) LPCSTR))aSyscall[27].pCurrent)
@ -594,7 +645,7 @@ static struct win_syscall {
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[41].pCurrent) 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 }, { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
#else #else
{ "LoadLibraryA", (SYSCALL)0, 0 }, { "LoadLibraryA", (SYSCALL)0, 0 },
@ -602,7 +653,8 @@ static struct win_syscall {
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) #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 }, { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
#else #else
{ "LoadLibraryW", (SYSCALL)0, 0 }, { "LoadLibraryW", (SYSCALL)0, 0 },
@ -791,7 +843,7 @@ static struct win_syscall {
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent) LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
#else #else
{ "LoadPackagedLibrary", (SYSCALL)0, 0 }, { "LoadPackagedLibrary", (SYSCALL)0, 0 },

View File

@ -2509,6 +2509,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
return rc; 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 ** Set the value of the Pager.sectorSize variable for the given
** pager based on the value returned by the xSectorSize method ** pager based on the value returned by the xSectorSize method
@ -2544,14 +2559,7 @@ static void setSectorSize(Pager *pPager){
** call will segfault. */ ** call will segfault. */
pPager->sectorSize = 512; pPager->sectorSize = 512;
}else{ }else{
pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); pPager->sectorSize = sqlite3SectorSize(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;
}
} }
} }
@ -3468,9 +3476,16 @@ void sqlite3PagerSetBusyhandler(
Pager *pPager, /* Pager object */ Pager *pPager, /* Pager object */
int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
){ ){
pPager->xBusyHandler = xBusyHandler; pPager->xBusyHandler = xBusyHandler;
pPager->pBusyHandlerArg = pBusyHandlerArg; 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);
}
} }
/* /*

View File

@ -160,6 +160,7 @@ void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*); int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *); void sqlite3PagerCacheStat(Pager *, int, int, int *);
void sqlite3PagerClearCache(Pager *); void sqlite3PagerClearCache(Pager *);
int sqlite3SectorSize(sqlite3_file *);
/* Functions used to truncate the database file. */ /* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno); void sqlite3PagerTruncateImage(Pager*,Pgno);

View File

@ -357,6 +357,7 @@ void sqlite3Pragma(
aFcntl[1] = zLeft; aFcntl[1] = zLeft;
aFcntl[2] = zRight; aFcntl[2] = zRight;
aFcntl[3] = 0; aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
if( aFcntl[0] ){ if( aFcntl[0] ){

View File

@ -3332,8 +3332,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}else{ }else{
/* An ordinary table or view name in the FROM clause */ /* An ordinary table or view name in the FROM clause */
assert( pFrom->pTab==0 ); assert( pFrom->pTab==0 );
pFrom->pTab = pTab = pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
if( pTab==0 ) return WRC_Abort; if( pTab==0 ) return WRC_Abort;
pTab->nRef++; pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)

View File

@ -852,6 +852,17 @@ struct sqlite3_io_methods {
** file control occurs at the beginning of pragma statement analysis and so ** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements. ** it is able to override built-in [PRAGMA] statements.
** </ul> ** </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_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_GET_LOCKPROXYFILE 2
@ -867,6 +878,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_VFSNAME 12 #define SQLITE_FCNTL_VFSNAME 12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14 #define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
/* /*
** CAPI3REF: Mutex Handle ** CAPI3REF: Mutex Handle

View File

@ -1877,6 +1877,7 @@ struct SrcList {
i16 nSrc; /* Number of tables or subqueries in the FROM clause */ i16 nSrc; /* Number of tables or subqueries in the FROM clause */
i16 nAlloc; /* Number of entries allocated in a[] below */ i16 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item { struct SrcList_item {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */ char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */ char *zName; /* Name of the table */
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ 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; typedef struct DbFixer DbFixer;
struct DbFixer { struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */ 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 *zDb; /* Make sure all objects are contained in this database */
const char *zType; /* Type of the container - used for error messages */ const char *zType; /* Type of the container - used for error messages */
const Token *pName; /* Name 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); void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,int isView,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*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(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 sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*); char sqlite3AffinityType(const char*);
void sqlite3Analyze(Parse*, Token*, Token*); void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3InvokeBusyHandler(BusyHandler*);

View File

@ -53,15 +53,8 @@
#define NUM_PREPARED_STMTS 10 #define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100 #define MAX_PREPARED_STMTS 100
/* /* Forward declaration */
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we typedef struct SqliteDb SqliteDb;
** 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
/* /*
** New SQL functions can be created as TCL scripts. Each such function ** New SQL functions can be created as TCL scripts. Each such function
@ -71,6 +64,7 @@ typedef struct SqlFunc SqlFunc;
struct SqlFunc { struct SqlFunc {
Tcl_Interp *interp; /* The TCL interpret to execute the function */ Tcl_Interp *interp; /* The TCL interpret to execute the function */
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */ 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 */ int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
char *zName; /* Name of this function */ char *zName; /* Name of this function */
SqlFunc *pNext; /* Next function on the list of them all */ 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. ** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used. ** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
*/ */
typedef struct SqliteDb SqliteDb;
struct SqliteDb { struct SqliteDb {
sqlite3 *db; /* The "real" database structure. MUST BE FIRST */ sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
Tcl_Interp *interp; /* The interpreter used for this database */ 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->interp = pDb->interp;
pNew->pDb = pDb;
pNew->pScript = 0; pNew->pScript = 0;
pNew->pNext = pDb->pFunc; pNew->pNext = pDb->pFunc;
pDb->pFunc = pNew; pDb->pFunc = pNew;
@ -479,6 +473,7 @@ static void DbDeleteCmd(void *db){
while( pDb->pFunc ){ while( pDb->pFunc ){
SqlFunc *pFunc = pDb->pFunc; SqlFunc *pFunc = pDb->pFunc;
pDb->pFunc = pFunc->pNext; pDb->pFunc = pFunc->pNext;
assert( pFunc->pDb==pDb );
Tcl_DecrRefCount(pFunc->pScript); Tcl_DecrRefCount(pFunc->pScript);
Tcl_Free((char*)pFunc); Tcl_Free((char*)pFunc);
} }
@ -838,7 +833,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
break; break;
} }
case SQLITE_NULL: { case SQLITE_NULL: {
pVal = Tcl_NewStringObj("", 0); pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
break; break;
} }
default: { default: {
@ -977,26 +972,6 @@ static int auth_callback(
} }
#endif /* SQLITE_OMIT_AUTHORIZATION */ #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 ** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer ** the text in memory obtained from malloc() and returns a pointer
@ -1184,13 +1159,13 @@ static int dbPrepareAndBind(
int nByte; int nByte;
if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){ 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; return TCL_ERROR;
} }
if( pStmt==0 ){ if( pStmt==0 ){
if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
/* A compile-time error in the statement. */ /* 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; return TCL_ERROR;
}else{ }else{
/* The statement was a no-op. Continue to the next statement /* The statement was a no-op. Continue to the next statement
@ -1409,7 +1384,7 @@ static void dbEvalRowInfo(
if( nCol>0 && (papColName || p->pArray) ){ if( nCol>0 && (papColName || p->pArray) ){
apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
for(i=0; i<nCol; i++){ 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]); Tcl_IncrRefCount(apColName[i]);
} }
p->apColName = apColName; p->apColName = apColName;
@ -1496,7 +1471,8 @@ static int dbEvalStep(DbEvalContext *p){
continue; continue;
} }
#endif #endif
Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db))); Tcl_SetObjResult(pDb->interp,
Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR; return TCL_ERROR;
}else{ }else{
dbReleaseStmt(pDb, pPreStmt, 0); dbReleaseStmt(pDb, pPreStmt, 0);
@ -1553,11 +1529,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol)); return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
} }
case SQLITE_NULL: { 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 *zDb = "main";
const char *zTable; const char *zTable;
const char *zColumn; const char *zColumn;
sqlite_int64 iRow; Tcl_WideInt iRow;
/* Check for the -readonly option */ /* Check for the -readonly option */
if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ 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; pDb->zNull = 0;
} }
} }
Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull)); Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
break; break;
} }

View File

@ -3067,7 +3067,7 @@ static int test_bind_int64(
){ ){
sqlite3_stmt *pStmt; sqlite3_stmt *pStmt;
int idx; int idx;
i64 value; Tcl_WideInt value;
int rc; int rc;
if( objc!=4 ){ if( objc!=4 ){
@ -4703,7 +4703,7 @@ static int test_soft_heap_limit(
Tcl_Obj *CONST objv[] Tcl_Obj *CONST objv[]
){ ){
sqlite3_int64 amt; sqlite3_int64 amt;
sqlite3_int64 N = -1; Tcl_WideInt N = -1;
if( objc!=1 && objc!=2 ){ if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?N?"); Tcl_WrongNumArgs(interp, 1, objv, "?N?");
return TCL_ERROR; return TCL_ERROR;
@ -5096,7 +5096,7 @@ static int file_control_sizehint_test(
int objc, /* Number of arguments */ int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */ Tcl_Obj *CONST objv[] /* Command arguments */
){ ){
sqlite3_int64 nSize; /* Hinted size */ Tcl_WideInt nSize; /* Hinted size */
char *zDb; /* Db name ("main", "temp" etc.) */ char *zDb; /* Db name ("main", "temp" etc.) */
sqlite3 *db; /* Database handle */ sqlite3 *db; /* Database handle */
int rc; /* file_control() return code */ int rc; /* file_control() return code */

View File

@ -346,8 +346,9 @@ static int test_intarray_bind(
return TCL_ERROR; return TCL_ERROR;
} }
for(i=0; i<n; i++){ for(i=0; i<n; i++){
a[i] = 0; Tcl_WideInt x = 0;
Tcl_GetWideIntFromObj(0, objv[i+2], &a[i]); Tcl_GetWideIntFromObj(0, objv[i+2], &x);
a[i] = x;
} }
rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free); rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){

View File

@ -1073,7 +1073,7 @@ size_t sqlite3_quota_fwrite(
/* If the write was incomplete, adjust the file size and group size /* If the write was incomplete, adjust the file size and group size
** downward */ ** downward */
if( rc<nmemb && pFile ){ if( rc<nmemb && pFile ){
size_t nWritten = rc>=0 ? rc : 0; size_t nWritten = rc;
sqlite3_int64 iNewEnd = iOfst + size*nWritten; sqlite3_int64 iNewEnd = iOfst + size*nWritten;
if( iNewEnd<iEnd ) iNewEnd = iEnd; if( iNewEnd<iEnd ) iNewEnd = iEnd;
quotaEnter(); quotaEnter();
@ -1354,8 +1354,10 @@ static void tclQuotaCallback(
rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL); rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
if( rc==TCL_OK ){ if( rc==TCL_OK ){
Tcl_WideInt x;
Tcl_Obj *pLimit = Tcl_ObjGetVar2(p->interp, pVarname, 0, 0); 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); Tcl_UnsetVar(p->interp, Tcl_GetString(pVarname), 0);
} }
@ -1437,7 +1439,7 @@ static int test_quota_set(
Tcl_Obj *CONST objv[] Tcl_Obj *CONST objv[]
){ ){
const char *zPattern; /* File pattern to configure */ 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 */ Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */
int rc; /* Value returned by quota_set() */ int rc; /* Value returned by quota_set() */
TclQuotaCallback *p; /* Callback object */ TclQuotaCallback *p; /* Callback object */
@ -1613,7 +1615,6 @@ static int test_quota_fread(
return TCL_ERROR; return TCL_ERROR;
} }
got = sqlite3_quota_fread(zBuf, sz, nElem, p); got = sqlite3_quota_fread(zBuf, sz, nElem, p);
if( got<0 ) got = 0;
zBuf[got*sz] = 0; zBuf[got*sz] = 0;
Tcl_SetResult(interp, zBuf, TCL_VOLATILE); Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
sqlite3_free(zBuf); sqlite3_free(zBuf);

View File

@ -1771,7 +1771,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( sqlite3BtreeIsInTrans(pBt) ){ if( sqlite3BtreeIsInTrans(pBt) ){
needXcommit = 1; needXcommit = 1;
if( i!=1 ) nTrans++; if( i!=1 ) nTrans++;
sqlite3BtreeEnter(pBt);
rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt)); rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
} }
} }
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){

View File

@ -264,7 +264,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){
if( p->azModuleArg ){ if( p->azModuleArg ){
int i; int i;
for(i=0; i<p->nModuleArg; 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); sqlite3DbFree(db, p->azModuleArg);
} }
@ -324,7 +324,7 @@ void sqlite3VtabBeginParse(
pTable->tabFlags |= TF_Virtual; pTable->tabFlags |= TF_Virtual;
pTable->nModuleArg = 0; pTable->nModuleArg = 0;
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); 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)); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z); pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
@ -481,6 +481,7 @@ static int vtabCallConstructor(
int nArg = pTab->nModuleArg; int nArg = pTab->nModuleArg;
char *zErr = 0; char *zErr = 0;
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
int iDb;
if( !zModuleName ){ if( !zModuleName ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
@ -494,6 +495,10 @@ static int vtabCallConstructor(
pVTable->db = db; pVTable->db = db;
pVTable->pMod = pMod; 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 */ /* Invoke the virtual table constructor */
assert( &db->pVtabCtx ); assert( &db->pVtabCtx );
assert( xConstruct ); assert( xConstruct );
@ -504,6 +509,7 @@ static int vtabCallConstructor(
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = pPriorCtx; db->pVtabCtx = pPriorCtx;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
pTab->azModuleArg[1] = 0;
if( SQLITE_OK!=rc ){ if( SQLITE_OK!=rc ){
if( zErr==0 ){ if( zErr==0 ){

View File

@ -2828,7 +2828,7 @@ int sqlite3WalFrames(
*/ */
if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
if( pWal->padToSectorBoundary ){ if( pWal->padToSectorBoundary ){
int sectorSize = sqlite3OsSectorSize(pWal->pWalFd); int sectorSize = sqlite3SectorSize(pWal->pWalFd);
w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
while( iOffset<w.iSyncPoint ){ while( iOffset<w.iSyncPoint ){
rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset); rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
# #
if {[file exists skip-big-file]} return if {[file exists skip-big-file]} return
if {$tcl_platform(os)=="Darwin"} return
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl

View File

@ -14,6 +14,7 @@
# #
if {[file exists skip-big-file]} return if {[file exists skip-big-file]} return
if {$tcl_platform(os)=="Darwin"} return
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl

View File

@ -1864,5 +1864,3 @@ do_execsql_test 10.3 {
} {1 21 41 61 81} } {1 21 41 61 81}
finish_test finish_test

View File

@ -114,7 +114,7 @@ do_test 1.4c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn 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 { do_test 1.5a {
@ -132,7 +132,7 @@ do_test 1.5c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC 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 { do_test 1.6a {
db eval { db eval {
@ -170,14 +170,14 @@ do_test 2.0 {
name TEXT, name TEXT,
UNIQUE(aid, tn) 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 INSERT INTO track VALUES
(1, 1, 'one-a'), (1, 1, 'one-a'),
(2, 2, 'two-b'), (20, 2, 'two-b'),
(3, 3, 'three-c'), (3, 3, 'three-c'),
(1, 3, 'one-c'), (1, 3, 'one-c'),
(2, 1, 'two-a'), (20, 1, 'two-a'),
(3, 1, 'three-a'); (3, 1, 'three-a');
COMMIT; COMMIT;
} }
} {} } {}
@ -196,6 +196,18 @@ do_test 2.1b {
} }
} {~/ORDER BY/} ;# ORDER BY optimized out } {~/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 # The same query with ORDER BY clause optimization disabled via + operators
# should give exactly the same answer. # should give exactly the same answer.
# #
@ -249,7 +261,7 @@ do_test 2.4c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn 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 { do_test 2.5a {
@ -267,7 +279,7 @@ do_test 2.5c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC 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 { do_test 2.6a {
db eval { db eval {
@ -284,7 +296,7 @@ do_test 2.6c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC 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. # Generate another test dataset, but this time using mixed ASC/DESC indices.
@ -384,7 +396,7 @@ do_test 3.4c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn 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 { do_test 3.5a {
@ -402,7 +414,7 @@ do_test 3.5c {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC 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 { do_test 3.6a {

117
test/orderby2.test Normal file
View 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
View 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

View File

@ -319,14 +319,23 @@ do_test tcl-8.1 {
execsql {INSERT INTO t1 VALUES(30,NULL)} execsql {INSERT INTO t1 VALUES(30,NULL)}
db eval {SELECT * FROM t1 WHERE b IS NULL} db eval {SELECT * FROM t1 WHERE b IS NULL}
} {30 NaN} } {30 NaN}
proc concatFunc args {return [join $args {}]}
do_test tcl-8.2 { 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
db nullvalue db nullvalue
} {NULL} } {NULL}
do_test tcl-8.3 { do_test tcl-8.4 {
db nullvalue {} db nullvalue {}
db eval {SELECT * FROM t1 WHERE b IS NULL} db eval {SELECT * FROM t1 WHERE b IS NULL}
} {30 {}} } {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 # Test the return type of user-defined functions
# #

View File

@ -11,20 +11,20 @@
# with the database COMMIT/ROLLBACK logic. # with the database COMMIT/ROLLBACK logic.
# #
# 1. CREATE and DROP TRIGGER tests # 1. CREATE and DROP TRIGGER tests
# trig-1.1: Error if table does not exist # trigger1-1.1: Error if table does not exist
# trig-1.2: Error if trigger already exists # trigger1-1.2: Error if trigger already exists
# trig-1.3: Created triggers are deleted if the transaction is rolled back # trigger1-1.3: Created triggers are deleted if the transaction is rolled back
# trig-1.4: DROP TRIGGER removes trigger # trigger1-1.4: DROP TRIGGER removes trigger
# trig-1.5: Dropped triggers are restored if the transaction is rolled back # trigger1-1.5: Dropped triggers are restored if the transaction is rolled back
# trig-1.6: Error if dropped trigger doesn't exist # trigger1-1.6: Error if dropped trigger doesn't exist
# trig-1.7: Dropping the table automatically drops all triggers # trigger1-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 # trigger1-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 # trigger1-1.9: Ensure that we cannot create a trigger on sqlite_master
# trig-1.10: # trigger1-1.10:
# trig-1.11: # trigger1-1.11:
# trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables # trigger1-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
# trig-1.13: Ensure that AFTER triggers cannot be created on views # trigger1-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.14: Ensure that BEFORE triggers cannot be created on views
# #
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
@ -210,7 +210,7 @@ do_test trigger1-1.12 {
delete from t1 WHERE a=old.a+2; delete from t1 WHERE a=old.a+2;
end; end;
} }
} {1 {cannot create INSTEAD OF trigger on table: main.t1}} } {1 {cannot create INSTEAD OF trigger on table: t1}}
ifcapable view { ifcapable view {
# Ensure that we cannot create BEFORE triggers on views # 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; delete from t1 WHERE a=old.a+2;
end; 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 # Ensure that we cannot create AFTER triggers on views
do_test trigger1-1.14 { do_test trigger1-1.14 {
catchsql { catchsql {
@ -231,7 +231,7 @@ do_test trigger1-1.14 {
delete from t1 WHERE a=old.a+2; delete from t1 WHERE a=old.a+2;
end; end;
} }
} {1 {cannot create AFTER trigger on view: main.v1}} } {1 {cannot create AFTER trigger on view: v1}}
} ;# ifcapable view } ;# ifcapable view
# Check for memory leaks in the trigger parser # Check for memory leaks in the trigger parser
@ -265,32 +265,32 @@ ifcapable tempdb {
END; END;
} }
} {0 {}} } {0 {}}
do_test trigger-3.2 { do_test trigger1-3.2 {
catchsql { catchsql {
INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(1,2);
SELECT * FROM t2; SELECT * FROM t2;
} }
} {1 {no such table: main.t2}} } {1 {no such table: main.t2}}
do_test trigger-3.3 { do_test trigger1-3.3 {
db close db close
set rc [catch {sqlite3 db test.db} err] set rc [catch {sqlite3 db test.db} err]
if {$rc} {lappend rc $err} if {$rc} {lappend rc $err}
set rc set rc
} {0} } {0}
do_test trigger-3.4 { do_test trigger1-3.4 {
catchsql { catchsql {
INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(1,2);
SELECT * FROM t2; SELECT * FROM t2;
} }
} {1 {no such table: main.t2}} } {1 {no such table: main.t2}}
do_test trigger-3.5 { do_test trigger1-3.5 {
catchsql { catchsql {
CREATE TEMP TABLE t2(x,y); CREATE TEMP TABLE t2(x,y);
INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(1,2);
SELECT * FROM t2; SELECT * FROM t2;
} }
} {1 {no such table: main.t2}} } {1 {no such table: main.t2}}
do_test trigger-3.6.1 { do_test trigger1-3.6.1 {
catchsql { catchsql {
DROP TRIGGER r1; DROP TRIGGER r1;
CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
@ -300,7 +300,7 @@ ifcapable tempdb {
SELECT * FROM t2; SELECT * FROM t2;
} }
} {0 {1 2 200 100}} } {0 {1 2 200 100}}
do_test trigger-3.6.2 { do_test trigger1-3.6.2 {
catchsql { catchsql {
DROP TRIGGER r1; DROP TRIGGER r1;
DELETE FROM t1; DELETE FROM t1;
@ -312,7 +312,7 @@ ifcapable tempdb {
SELECT * FROM t2; SELECT * FROM t2;
} }
} {0 {1 2}} } {0 {1 2}}
do_test trigger-3.7 { do_test trigger1-3.7 {
execsql { execsql {
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t2(x,y); 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. # compound SELECT statements, and another that does not.
ifcapable compound { ifcapable compound {
do_test trigger1-3.8 { do_test trigger1-3.8 {
@ -446,7 +446,7 @@ do_test trigger1-6.8 {
execsql {SELECT * FROM t2} execsql {SELECT * FROM t2}
} {3 4 7 8} } {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 # Check to make sure the name of a trigger can be quoted so that keywords
# can be used as trigger names. Ticket #468 # can be used as trigger names. Ticket #468
@ -491,7 +491,7 @@ do_test trigger1-8.6 {
ifcapable conflict { ifcapable conflict {
# Make sure REPLACE works inside of triggers. # 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. # compound SELECT statements, and another that does not.
ifcapable compound { ifcapable compound {
do_test trigger1-9.1 { do_test trigger1-9.1 {
@ -612,7 +612,7 @@ ifcapable tempdb&&attach {
SELECT * FROM insert_log; SELECT * FROM insert_log;
} }
} {main 11 12 13 temp 14 15 16 aux 17 18 19} } {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 # 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 # that we can change the column names because the trigger programs don't
# use them explicitly. # use them explicitly.

View File

@ -1088,12 +1088,12 @@ do_test where-14.1 {
cksort { cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b 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 { do_test where-14.2 {
cksort { cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b DESC 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 { do_test where-14.3 {
cksort { cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b

View File

@ -142,7 +142,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM be used for the name of the platform-specific binary directory via REM be used for the name of the platform-specific binary directory via
REM the environment variables setup earlier. REM the environment variables setup earlier.
REM REM
CALL :fn_SetVariable %%P_NAME PLATFORMNAME CALL :fn_CopyVariable %%P_NAME PLATFORMNAME
REM REM
REM NOTE: This is the inner loop. There should be exactly one iteration. 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 file used to setup the MSVC environment.
REM REM
IF DEFINED SET_NSDKLIBPATH ( IF DEFINED SET_NSDKLIBPATH (
CALL :fn_SetVariable WindowsSdkDir NSDKLIBPATH CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86 CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
) )
@ -339,7 +339,7 @@ GOTO no_errors
VERIFY MAYBE 2> NUL VERIFY MAYBE 2> NUL
GOTO :EOF GOTO :EOF
:fn_SetVariable :fn_CopyVariable
SETLOCAL SETLOCAL
IF NOT DEFINED %1 GOTO :EOF IF NOT DEFINED %1 GOTO :EOF
IF "%2" == "" GOTO :EOF IF "%2" == "" GOTO :EOF