Merge updates from trunk.

FossilOrigin-Name: b8094166b3c6a8ec7913b403e08b5e6790fb03c1
This commit is contained in:
mistachkin 2016-04-11 22:24:03 +00:00
commit 9cdd401d37
27 changed files with 689 additions and 428 deletions

View File

@ -1228,7 +1228,6 @@ clean:
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f *.da *.bb *.bbg gmon.out rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc .target_source rm -rf tsrc .target_source
rm -f tclsqlite3$(TEXE) rm -f tclsqlite3$(TEXE)
rm -f testfixture$(TEXE) test.db rm -f testfixture$(TEXE) test.db

View File

@ -1882,7 +1882,7 @@ fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR) rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c
sqlite3session.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR) sqlite3session.lo: $(TOP)\ext\session\sqlite3session.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c
# FTS5 things # FTS5 things
@ -2075,9 +2075,6 @@ clean:
del /Q notasharedlib.* 2>NUL del /Q notasharedlib.* 2>NUL
-rmdir /Q/S .deps 2>NUL -rmdir /Q/S .deps 2>NUL
-rmdir /Q/S .libs 2>NUL -rmdir /Q/S .libs 2>NUL
-rmdir /Q/S quota2a 2>NUL
-rmdir /Q/S quota2b 2>NUL
-rmdir /Q/S quota2c 2>NUL
-rmdir /Q/S tsrc 2>NUL -rmdir /Q/S tsrc 2>NUL
del /Q .target_source 2>NUL del /Q .target_source 2>NUL
del /Q tclsqlite3.exe 2>NUL del /Q tclsqlite3.exe 2>NUL

View File

@ -905,7 +905,6 @@ clean:
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
rm -f $(PUBLISH) rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc target_source rm -rf tsrc target_source
rm -f testloadext.dll libtestloadext.so rm -f testloadext.dll libtestloadext.so
rm -f amalgamation-testfixture amalgamation-testfixture.exe rm -f amalgamation-testfixture amalgamation-testfixture.exe

View File

@ -1,8 +1,8 @@
C Fix\ssome\scompilation\sissues. C Merge\supdates\sfrom\strunk.
D 2016-04-11T22:10:26.085 D 2016-04-11T22:24:03.058
F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@ -300,7 +300,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 942e1fd30eb352492cf599aa7fcb5334783e4cbf F main.mk a283660f75c3c4b75d8c9d12a40fa38a066eee9d
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@ -319,21 +319,21 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
F src/btree.c 556203aab543e91f4e20cc273a507ed712c8da26 F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf
F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
F src/build.c c5cf206191880f88142352629d53fed174fc10bd F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
F src/date.c cd412cb2adb0c3a60e085107864931e508f45ad8 F src/date.c cd412cb2adb0c3a60e085107864931e508f45ad8
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
F src/delete.c eeac28b3d3d88e3541bdf93e91ea7492a7b67842 F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
F src/expr.c 289ffac5240b60fee0a824d3d5ab2d7bd2630c94 F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
F src/func.c 552d300265aed09eea21f68ac742a440550c0062 F src/func.c 552d300265aed09eea21f68ac742a440550c0062
F src/global.c 884d4c7eba9f5fc25c96a23b21520da19b7713e2 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
@ -347,7 +347,7 @@ F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memjournal.c 5253fd4335a8d9c64e5df25cb9da6329af5242c7 F src/memjournal.c 2815ef7684671d93a1ec6a31e1e63c45de4b4d31
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
@ -359,12 +359,12 @@ F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e
F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b
F src/os_win.c 1245c1c1b03f269f8beca1464df2f9a174236dab F src/os_win.c 1245c1c1b03f269f8beca1464df2f9a174236dab
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05
@ -375,12 +375,12 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 F src/select.c d9b8628acb98f1a38921888d823a6b70c7a7774b
F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5
F src/sqlite.h.in 7f437b068314f053e6417d452c59f08d05092591 F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 F src/sqliteInt.h b3744b29555b83054f315f62d61b3a6558fa9e1c
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
@ -439,13 +439,13 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a F src/util.c 187a0a2aaa3c5d2ccd2ab0143b2fd9e86d6bc816
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
F src/vdbe.c 936166d3dc5aa00364877603f545707896c1519e F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c
F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
F src/vdbeaux.c fa06ba5441714160ab5f64422660ee286968672f F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f
F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb
F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
@ -455,9 +455,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c 99cc6270fc3915201e2a90bbac3768f007a89c44 F src/where.c 24ab561466d92d313747c04edb1a36a7af8663be
F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34
F src/wherecode.c 863aedf086131743763c1960637fde904eadc442 F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340
F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@ -519,7 +519,7 @@ F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
F test/bestindex1.test d5ba89a7941a941476d8d69be39b146aaed3614c F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee
F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
@ -615,7 +615,7 @@ F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
F test/delete4.test 3ac0b8d23689ba764c2e8b78c1b56b8f1b942fa2 F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b
F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
@ -1011,7 +1011,7 @@ F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
@ -1308,7 +1308,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@ -1420,7 +1420,7 @@ F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 00990020d07d7c87b922cdbfa5373298a86bb4b3 P 016481b39f8b23b4f0f851053068d8eaee6122e1 3189a7f1851f823218d85a2455bf218d00d81543
R b5c956e1077b7c3e444e8f4ed923bce8 R 7558a8a571dae2778f18625aa658ad38
U mistachkin U mistachkin
Z 76d8e561edd13c0c75a00b4aec6f1897 Z b10810d48122d46da89a3713378b4792

View File

@ -1 +1 @@
016481b39f8b23b4f0f851053068d8eaee6122e1 b8094166b3c6a8ec7913b403e08b5e6790fb03c1

View File

@ -8140,6 +8140,28 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
pPage = pCur->apPage[iCellDepth]; pPage = pCur->apPage[iCellDepth];
pCell = findCell(pPage, iCellIdx); pCell = findCell(pPage, iCellIdx);
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* If the page containing the entry to delete is not a leaf page, move /* If the page containing the entry to delete is not a leaf page, move
** the cursor to the largest entry in the tree that is smaller than ** the cursor to the largest entry in the tree that is smaller than
** the entry being deleted. This cell will replace the cell being deleted ** the entry being deleted. This cell will replace the cell being deleted
@ -8166,28 +8188,6 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
invalidateIncrblobCursors(p, pCur->info.nKey, 0); invalidateIncrblobCursors(p, pCur->info.nKey, 0);
} }
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* Make the page containing the entry to be deleted writable. Then free any /* Make the page containing the entry to be deleted writable. Then free any
** overflow pages associated with the entry and finally remove the cell ** overflow pages associated with the entry and finally remove the cell
** itself from within the page. */ ** itself from within the page. */

View File

@ -2176,44 +2176,55 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
** statement that defines the view. ** statement that defines the view.
*/ */
assert( pTable->pSelect ); assert( pTable->pSelect );
if( pTable->pCheck ){ pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
if( pSel ){
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
db->lookaside.bDisable++; db->lookaside.bDisable++;
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
&pTable->nCol, &pTable->aCol);
db->lookaside.bDisable--;
}else{
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
if( pSel ){
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
db->lookaside.bDisable++;
#ifndef SQLITE_OMIT_AUTHORIZATION #ifndef SQLITE_OMIT_AUTHORIZATION
xAuth = db->xAuth; xAuth = db->xAuth;
db->xAuth = 0; db->xAuth = 0;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
db->xAuth = xAuth; db->xAuth = xAuth;
#else #else
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
#endif #endif
db->lookaside.bDisable--; pParse->nTab = n;
pParse->nTab = n; if( pTable->pCheck ){
if( pSelTab ){ /* CREATE VIEW name(arglist) AS ...
assert( pTable->aCol==0 ); ** The names of the columns in the table are taken from
pTable->nCol = pSelTab->nCol; ** arglist which is stored in pTable->pCheck. The pCheck field
pTable->aCol = pSelTab->aCol; ** normally holds CHECK constraints on an ordinary table, but for
pSelTab->nCol = 0; ** a VIEW it holds the list of column names.
pSelTab->aCol = 0; */
sqlite3DeleteTable(db, pSelTab); sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); &pTable->nCol, &pTable->aCol);
}else{ if( db->mallocFailed==0
pTable->nCol = 0; && pParse->nErr==0
nErr++; && pTable->nCol==pSel->pEList->nExpr
){
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
} }
sqlite3SelectDelete(db, pSel); }else if( pSelTab ){
} else { /* CREATE VIEW name AS... without an argument list. Construct
** the column names from the SELECT statement that defines the view.
*/
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
}else{
pTable->nCol = 0;
nErr++; nErr++;
} }
if( pSelTab ) sqlite3DeleteTable(db, pSelTab);
sqlite3SelectDelete(db, pSel);
db->lookaside.bDisable--;
} else {
nErr++;
} }
pTable->pSchema->schemaFlags |= DB_UnresetViews; pTable->pSchema->schemaFlags |= DB_UnresetViews;
#endif /* SQLITE_OMIT_VIEW */ #endif /* SQLITE_OMIT_VIEW */

View File

@ -143,7 +143,7 @@ Expr *sqlite3LimitWhere(
*/ */
if( pOrderBy && (pLimit == 0) ) { if( pOrderBy && (pLimit == 0) ) {
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
goto limit_where_cleanup_2; goto limit_where_cleanup;
} }
/* We only need to generate a select expression if there /* We only need to generate a select expression if there
@ -165,16 +165,16 @@ Expr *sqlite3LimitWhere(
*/ */
pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup_2; if( pSelectRowid == 0 ) goto limit_where_cleanup;
pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
if( pEList == 0 ) goto limit_where_cleanup_2; if( pEList == 0 ) goto limit_where_cleanup;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */ ** and the SELECT subtree. */
pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
if( pSelectSrc == 0 ) { if( pSelectSrc == 0 ) {
sqlite3ExprListDelete(pParse->db, pEList); sqlite3ExprListDelete(pParse->db, pEList);
goto limit_where_cleanup_2; goto limit_where_cleanup;
} }
/* generate the SELECT expression tree. */ /* generate the SELECT expression tree. */
@ -184,21 +184,11 @@ Expr *sqlite3LimitWhere(
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pWhereRowid == 0 ) goto limit_where_cleanup_1; pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0;
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); sqlite3PExprAddSelect(pParse, pInClause, pSelect);
if( pInClause == 0 ) goto limit_where_cleanup_1;
pInClause->x.pSelect = pSelect;
pInClause->flags |= EP_xIsSelect;
sqlite3ExprSetHeightAndFlags(pParse, pInClause);
return pInClause; return pInClause;
/* something went wrong. clean up anything allocated. */ limit_where_cleanup:
limit_where_cleanup_1:
sqlite3SelectDelete(pParse->db, pSelect);
return 0;
limit_where_cleanup_2:
sqlite3ExprDelete(pParse->db, pWhere); sqlite3ExprDelete(pParse->db, pWhere);
sqlite3ExprListDelete(pParse->db, pOrderBy); sqlite3ExprListDelete(pParse->db, pOrderBy);
sqlite3ExprDelete(pParse->db, pLimit); sqlite3ExprDelete(pParse->db, pLimit);

View File

@ -471,15 +471,13 @@ Expr *sqlite3ExprAlloc(
pNew->flags |= EP_IntValue; pNew->flags |= EP_IntValue;
pNew->u.iValue = iValue; pNew->u.iValue = iValue;
}else{ }else{
int c;
pNew->u.zToken = (char*)&pNew[1]; pNew->u.zToken = (char*)&pNew[1];
assert( pToken->z!=0 || pToken->n==0 ); assert( pToken->z!=0 || pToken->n==0 );
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0; pNew->u.zToken[pToken->n] = 0;
if( dequote && nExtra>=3 if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){ if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
sqlite3Dequote(pNew->u.zToken); sqlite3Dequote(pNew->u.zToken);
if( c=='"' ) pNew->flags |= EP_DblQuoted;
} }
} }
} }
@ -562,6 +560,22 @@ Expr *sqlite3PExpr(
return p; return p;
} }
/*
** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due
** do a memory allocation failure) then delete the pSelect object.
*/
void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
if( pExpr ){
pExpr->x.pSelect = pSelect;
ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, pExpr);
}else{
assert( pParse->db->mallocFailed );
sqlite3SelectDelete(pParse->db, pSelect);
}
}
/* /*
** If the expression is always either TRUE or FALSE (respectively), ** If the expression is always either TRUE or FALSE (respectively),
** then return 1. If one cannot determine the truth value of the ** then return 1. If one cannot determine the truth value of the
@ -722,8 +736,8 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
/* /*
** Recursively delete an expression tree. ** Recursively delete an expression tree.
*/ */
void sqlite3ExprDelete(sqlite3 *db, Expr *p){ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
if( p==0 ) return; assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */ /* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
if( !ExprHasProperty(p, EP_TokenOnly) ){ if( !ExprHasProperty(p, EP_TokenOnly) ){
@ -742,6 +756,9 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
sqlite3DbFree(db, p); sqlite3DbFree(db, p);
} }
} }
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
/* /*
** Return the number of bytes allocated for the expression structure ** Return the number of bytes allocated for the expression structure
@ -793,7 +810,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
assert( EXPR_FULLSIZE<=0xfff ); assert( EXPR_FULLSIZE<=0xfff );
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==(flags&EXPRDUP_REDUCE) ){ if( 0==flags ){
nSize = EXPR_FULLSIZE; nSize = EXPR_FULLSIZE;
}else{ }else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@ -855,88 +872,88 @@ static int dupedExprSize(Expr *p, int flags){
** if any. Before returning, *pzBuffer is set to the first byte past the ** if any. Before returning, *pzBuffer is set to the first byte past the
** portion of the buffer copied into by this function. ** portion of the buffer copied into by this function.
*/ */
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */ Expr *pNew; /* Value to return */
assert( flags==0 || flags==EXPRDUP_REDUCE ); u8 *zAlloc; /* Memory space from which to build Expr object */
u32 staticFlag; /* EP_Static if space not obtained from malloc */
assert( db!=0 ); assert( db!=0 );
if( p ){ assert( p );
const int isReduced = (flags&EXPRDUP_REDUCE); assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
u8 *zAlloc; assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
u32 staticFlag = 0;
assert( pzBuffer==0 || isReduced ); /* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
staticFlag = EP_Static;
}else{
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
staticFlag = 0;
}
pNew = (Expr *)zAlloc;
/* Figure out where to write the new Expr structure. */ if( pNew ){
if( pzBuffer ){ /* Set nNewSize to the size allocated for the structure pointed to
zAlloc = *pzBuffer; ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
staticFlag = EP_Static; ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
** by the copy of the p->u.zToken string (if any).
*/
const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
const int nNewSize = nStructSize & 0xfff;
int nToken;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nToken = sqlite3Strlen30(p->u.zToken) + 1;
}else{ }else{
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags)); nToken = 0;
}
if( dupFlags ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
u32 nSize = (u32)exprStructSize(p);
memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
} }
pNew = (Expr *)zAlloc;
if( pNew ){ /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
/* Set nNewSize to the size allocated for the structure pointed to pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed pNew->flags |= staticFlag;
** by the copy of the p->u.zToken string (if any).
*/ /* Copy the p->u.zToken string, if any. */
const unsigned nStructSize = dupedExprStructSize(p, flags); if( nToken ){
const int nNewSize = nStructSize & 0xfff; char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
int nToken; memcpy(zToken, p->u.zToken, nToken);
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ }
nToken = sqlite3Strlen30(p->u.zToken) + 1;
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
}else{ }else{
nToken = 0; pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
} }
if( isReduced ){ }
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize); /* Fill in pNew->pLeft and pNew->pRight. */
}else{ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
u32 nSize = (u32)exprStructSize(p); zAlloc += dupedExprNodeSize(p, dupFlags);
memcpy(zAlloc, p, nSize); if( ExprHasProperty(pNew, EP_Reduced) ){
if( nSize<EXPR_FULLSIZE ){ pNew->pLeft = p->pLeft ?
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
} pNew->pRight = p->pRight ?
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
} }
if( pzBuffer ){
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ *pzBuffer = zAlloc;
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
/* Copy the p->u.zToken string, if any. */
if( nToken ){
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
memcpy(zToken, p->u.zToken, nToken);
} }
}else{
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ if( !ExprHasProperty(p, EP_TokenOnly) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
if( ExprHasProperty(p, EP_xIsSelect) ){ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
}else{
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
}
} }
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
}
if( pzBuffer ){
*pzBuffer = zAlloc;
}
}else{
if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
} }
} }
return pNew; return pNew;
@ -988,7 +1005,7 @@ static With *withDup(sqlite3 *db, With *p){
*/ */
Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
assert( flags==0 || flags==EXPRDUP_REDUCE ); assert( flags==0 || flags==EXPRDUP_REDUCE );
return exprDup(db, p, flags, 0); return p ? exprDup(db, p, flags, 0) : 0;
} }
ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
ExprList *pNew; ExprList *pNew;
@ -1210,7 +1227,7 @@ void sqlite3ExprListSetName(
pItem = &pList->a[pList->nExpr-1]; pItem = &pList->a[pList->nExpr-1];
assert( pItem->zName==0 ); assert( pItem->zName==0 );
pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName); if( dequote ) sqlite3Dequote(pItem->zName);
} }
} }
@ -1259,10 +1276,9 @@ void sqlite3ExprListCheckLength(
/* /*
** Delete an entire expression list. ** Delete an entire expression list.
*/ */
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
int i; int i;
struct ExprList_item *pItem; struct ExprList_item *pItem;
if( pList==0 ) return;
assert( pList->a!=0 || pList->nExpr==0 ); assert( pList->a!=0 || pList->nExpr==0 );
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){ for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite3ExprDelete(db, pItem->pExpr); sqlite3ExprDelete(db, pItem->pExpr);
@ -1272,6 +1288,9 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
sqlite3DbFree(db, pList->a); sqlite3DbFree(db, pList->a);
sqlite3DbFree(db, pList); sqlite3DbFree(db, pList);
} }
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
if( pList ) exprListDeleteNN(db, pList);
}
/* /*
** Return the bitwise-OR of all Expr.flags fields in the given ** Return the bitwise-OR of all Expr.flags fields in the given
@ -2316,6 +2335,19 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
} }
} }
#if defined(SQLITE_DEBUG)
/*
** Verify the consistency of the column cache
*/
static int cacheIsValid(Parse *pParse){
int i, n;
for(i=n=0; i<SQLITE_N_COLCACHE; i++){
if( pParse->aColCache[i].iReg>0 ) n++;
}
return n==pParse->nColCache;
}
#endif
/* /*
** Clear a cache entry. ** Clear a cache entry.
*/ */
@ -2326,6 +2358,9 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){
} }
p->tempReg = 0; p->tempReg = 0;
} }
p->iReg = 0;
pParse->nColCache--;
assert( cacheIsValid(pParse) );
} }
@ -2369,6 +2404,8 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
p->iReg = iReg; p->iReg = iReg;
p->tempReg = 0; p->tempReg = 0;
p->lru = pParse->iCacheCnt++; p->lru = pParse->iCacheCnt++;
pParse->nColCache++;
assert( cacheIsValid(pParse) );
return; return;
} }
} }
@ -2390,6 +2427,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
p->iReg = iReg; p->iReg = iReg;
p->tempReg = 0; p->tempReg = 0;
p->lru = pParse->iCacheCnt++; p->lru = pParse->iCacheCnt++;
assert( cacheIsValid(pParse) );
return; return;
} }
} }
@ -2399,15 +2437,13 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
** Purge the range of registers from the column cache. ** Purge the range of registers from the column cache.
*/ */
void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
int i;
int iLast = iReg + nReg - 1;
struct yColCache *p; struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ if( iReg<=0 || pParse->nColCache==0 ) return;
int r = p->iReg; p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
if( r>=iReg && r<=iLast ){ while(1){
cacheEntryClear(pParse, p); if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
p->iReg = 0; if( p==pParse->aColCache ) break;
} p--;
} }
} }
@ -2443,7 +2479,6 @@ void sqlite3ExprCachePop(Parse *pParse){
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){ if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p); cacheEntryClear(pParse, p);
p->iReg = 0;
} }
} }
} }
@ -2578,7 +2613,6 @@ void sqlite3ExprCacheClear(Parse *pParse){
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){ if( p->iReg ){
cacheEntryClear(pParse, p); cacheEntryClear(pParse, p);
p->iReg = 0;
} }
} }
} }
@ -2620,6 +2654,7 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
} }
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
/* /*
** Convert an expression node to a TK_REGISTER ** Convert an expression node to a TK_REGISTER
*/ */

View File

@ -70,6 +70,7 @@ const unsigned char sqlite3UpperToLower[] = {
** isxdigit() 0x08 ** isxdigit() 0x08
** toupper() 0x20 ** toupper() 0x20
** SQLite identifier character 0x40 ** SQLite identifier character 0x40
** Quote character 0x80
** **
** Bit 0x20 is set if the mapped character requires translation to upper ** Bit 0x20 is set if the mapped character requires translation to upper
** case. i.e. if the character is a lower-case ASCII character. ** case. i.e. if the character is a lower-case ASCII character.
@ -95,7 +96,7 @@ const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */ 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */ 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
@ -103,8 +104,8 @@ const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */

View File

@ -94,6 +94,7 @@ static int memjrnlRead(
#endif #endif
assert( (iAmt+iOfst)<=p->endpoint.iOffset ); assert( (iAmt+iOfst)<=p->endpoint.iOffset );
assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
sqlite3_int64 iOff = 0; sqlite3_int64 iOff = 0;
for(pChunk=p->pFirst; for(pChunk=p->pFirst;
@ -104,6 +105,7 @@ static int memjrnlRead(
} }
}else{ }else{
pChunk = p->readpoint.pChunk; pChunk = p->readpoint.pChunk;
assert( pChunk!=0 );
} }
iChunkOffset = (int)(iOfst%p->nChunkSize); iChunkOffset = (int)(iOfst%p->nChunkSize);
@ -115,7 +117,7 @@ static int memjrnlRead(
nRead -= iSpace; nRead -= iSpace;
iChunkOffset = 0; iChunkOffset = 0;
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
p->readpoint.iOffset = iOfst+iAmt; p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
p->readpoint.pChunk = pChunk; p->readpoint.pChunk = pChunk;
return SQLITE_OK; return SQLITE_OK;

View File

@ -1502,7 +1502,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** lock transitions in terms of the POSIX advisory shared and exclusive ** lock transitions in terms of the POSIX advisory shared and exclusive
** lock primitives (called read-locks and write-locks below, to avoid ** lock primitives (called read-locks and write-locks below, to avoid
** confusion with SQLite lock names). The algorithms are complicated ** confusion with SQLite lock names). The algorithms are complicated
** slightly in order to be compatible with windows systems simultaneously ** slightly in order to be compatible with Windows95 systems simultaneously
** accessing the same database file, in case that is ever required. ** accessing the same database file, in case that is ever required.
** **
** Symbols defined in os.h indentify the 'pending byte' and the 'reserved ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
@ -1510,8 +1510,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** range', a range of 510 bytes at a well known offset. ** range', a range of 510 bytes at a well known offset.
** **
** To obtain a SHARED lock, a read-lock is obtained on the 'pending ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
** byte'. If this is successful, a random byte from the 'shared byte ** byte'. If this is successful, 'shared byte range' is read-locked
** range' is read-locked and the lock on the 'pending byte' released. ** and the lock on the 'pending byte' released. (Legacy note: When
** SQLite was first developed, Windows95 systems were still very common,
** and Widnows95 lacks a shared-lock capability. So on Windows95, a
** single randomly selected by from the 'shared byte range' is locked.
** Windows95 is now pretty much extinct, but this work-around for the
** lack of shared-locks on Windows95 lives on, for backwards
** compatibility.)
** **
** A process may only obtain a RESERVED lock after it has a SHARED lock. ** A process may only obtain a RESERVED lock after it has a SHARED lock.
** A RESERVED lock is implemented by grabbing a write-lock on the ** A RESERVED lock is implemented by grabbing a write-lock on the
@ -1530,11 +1536,6 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** range'. Since all other locks require a read-lock on one of the bytes ** range'. Since all other locks require a read-lock on one of the bytes
** within this range, this ensures that no other locks are held on the ** within this range, this ensures that no other locks are held on the
** database. ** database.
**
** The reason a single byte cannot be used instead of the 'shared byte
** range' is that some versions of windows do not support read-locks. By
** locking a random byte from a range, concurrent SHARED locks may exist
** even if the locking primitive used is always a write-lock.
*/ */
int rc = SQLITE_OK; int rc = SQLITE_OK;
unixFile *pFile = (unixFile*)id; unixFile *pFile = (unixFile*)id;

View File

@ -194,28 +194,6 @@ columnlist ::= columnlist COMMA columnname carglist.
columnlist ::= columnname carglist. columnlist ::= columnname carglist.
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
// An IDENTIFIER can be a generic identifier, or one of several
// keywords. Any non-standard keyword can also be an identifier.
//
%token_class id ID|INDEXED.
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
// fallback to ID if they will not parse as their original value.
// This obviates the need for the "id" nonterminal.
//
%fallback ID
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
REINDEX RENAME CTIME_KW IF
.
%wildcard ANY.
// Define operator precedence early so that this is the first occurrence // Define operator precedence early so that this is the first occurrence
// of the operator tokens in the grammer. Keeping the operators together // of the operator tokens in the grammer. Keeping the operators together
// causes them to be assigned integer values that are close together, // causes them to be assigned integer values that are close together,
@ -240,6 +218,29 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
%left COLLATE. %left COLLATE.
%right BITNOT. %right BITNOT.
// An IDENTIFIER can be a generic identifier, or one of several
// keywords. Any non-standard keyword can also be an identifier.
//
%token_class id ID|INDEXED.
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
// fallback to ID if they will not parse as their original value.
// This obviates the need for the "id" nonterminal.
//
%fallback ID
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
REINDEX RENAME CTIME_KW IF
.
%wildcard ANY.
// And "ids" is an identifer-or-string. // And "ids" is an identifer-or-string.
// //
%token_class ids ID|STRING. %token_class ids ID|STRING.
@ -871,11 +872,15 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
expr(A) ::= VARIABLE(X). { expr(A) ::= VARIABLE(X). {
Token t = X; /*A-overwrites-X*/ if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
if( t.n>=2 && t.z[0]=='#' && sqlite3Isdigit(t.z[1]) ){ spanExpr(&A, pParse, TK_VARIABLE, X);
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
}else{
/* When doing a nested parse, one can include terms in an expression /* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers ** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */ ** in the virtual machine. #N is the N-th register. */
Token t = X; /*A-overwrites-X*/
assert( t.n>=2 );
spanSet(&A, &t, &t); spanSet(&A, &t, &t);
if( pParse->nested==0 ){ if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
@ -884,9 +889,6 @@ expr(A) ::= VARIABLE(X). {
A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t); A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable); if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable);
} }
}else{
spanExpr(&A, pParse, TK_VARIABLE, t);
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
} }
} }
expr(A) ::= expr(A) COLLATE ids(C). { expr(A) ::= expr(A) COLLATE ids(C). {
@ -1122,36 +1124,19 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
expr(A) ::= LP(B) select(X) RP(E). { expr(A) ::= LP(B) select(X) RP(E). {
spanSet(&A,&B,&E); /*A-overwrites-B*/ spanSet(&A,&B,&E); /*A-overwrites-B*/
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( A.pExpr ){ sqlite3PExprAddSelect(pParse, A.pExpr, X);
A.pExpr->x.pSelect = X;
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3SelectDelete(pParse->db, X);
}
} }
expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] { expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] {
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){ sqlite3PExprAddSelect(pParse, A.pExpr, Y);
A.pExpr->x.pSelect = Y;
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3SelectDelete(pParse->db, Y);
}
exprNot(pParse, N, &A); exprNot(pParse, N, &A);
A.zEnd = &E.z[E.n]; A.zEnd = &E.z[E.n];
} }
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] { expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){ sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
exprNot(pParse, N, &A); exprNot(pParse, N, &A);
A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
} }
@ -1159,13 +1144,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
Expr *p; Expr *p;
spanSet(&A,&B,&E); /*A-overwrites-B*/ spanSet(&A,&B,&E); /*A-overwrites-B*/
p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){ sqlite3PExprAddSelect(pParse, p, Y);
p->x.pSelect = Y;
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, Y);
}
} }
%endif SQLITE_OMIT_SUBQUERY %endif SQLITE_OMIT_SUBQUERY

View File

@ -1704,7 +1704,7 @@ int sqlite3ColumnsFromExprList(
** This routine requires that all identifiers in the SELECT ** This routine requires that all identifiers in the SELECT
** statement be resolved. ** statement be resolved.
*/ */
static void selectAddColumnTypeAndCollation( void sqlite3SelectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */ Parse *pParse, /* Parsing contexts */
Table *pTab, /* Add column type information to this table */ Table *pTab, /* Add column type information to this table */
Select *pSelect /* SELECT used to determine types and collations */ Select *pSelect /* SELECT used to determine types and collations */
@ -1726,10 +1726,20 @@ static void selectAddColumnTypeAndCollation(
sNC.pSrcList = pSelect->pSrc; sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a; a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
const char *zType;
int n, m;
p = a[i].pExpr; p = a[i].pExpr;
columnType(&sNC, p, 0, 0, 0, &pCol->szEst); zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
szAll += pCol->szEst; szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p); pCol->affinity = sqlite3ExprAffinity(p);
if( zType && (m = sqlite3Strlen30(zType))>0 ){
n = sqlite3Strlen30(pCol->zName);
pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
if( pCol->zName ){
memcpy(&pCol->zName[n+1], zType, m+1);
pCol->colFlags |= COLFLAG_HASTYPE;
}
}
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB; if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
pColl = sqlite3ExprCollSeq(pParse, p); pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl && pCol->zColl==0 ){ if( pColl && pCol->zColl==0 ){
@ -1766,7 +1776,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
pTab->zName = 0; pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab, pSelect); sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1; pTab->iPKey = -1;
if( db->mallocFailed ){ if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab); sqlite3DeleteTable(db, pTab);
@ -4550,7 +4560,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Select *pSel = pFrom->pSelect; Select *pSel = pFrom->pSelect;
if( pSel ){ if( pSel ){
while( pSel->pPrior ) pSel = pSel->pPrior; while( pSel->pPrior ) pSel = pSel->pPrior;
selectAddColumnTypeAndCollation(pParse, pTab, pSel); sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
} }
} }
} }

View File

@ -8081,20 +8081,29 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
** CAPI3REF: Start a read transaction on an historical snapshot ** CAPI3REF: Start a read transaction on an historical snapshot
** EXPERIMENTAL ** EXPERIMENTAL
** **
** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the ** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
** read transaction that is currently open on schema S of ** read transaction for schema S of
** [database connection] D so that it refers to historical [snapshot] P. ** [database connection] D such that the read transaction
** refers to historical [snapshot] P, rather than the most
** recent change to the database.
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success ** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
** or an appropriate [error code] if it fails. ** or an appropriate [error code] if it fails.
** **
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be ** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
** the first operation, apart from other sqlite3_snapshot_open() calls, ** the first operation following the [BEGIN] that takes the schema S
** following the [BEGIN] that starts a new read transaction. ** out of [autocommit mode].
** ^A [snapshot] will fail to open if it has been overwritten by a ** ^In other words, schema S must not currently be in
** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
** database connection D must be out of [autocommit mode].
** ^A [snapshot] will fail to open if it has been overwritten by a
** [checkpoint]. ** [checkpoint].
** ^A [snapshot] will fail to open if the database connection D has not ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
** previously completed at least one read operation against the database ** database connection D does not know that the database file for
** file. (Hint: Run "[PRAGMA application_id]" against a newly opened ** schema S is in [WAL mode]. A database connection might not know
** that the database file is in [WAL mode] if there has been no prior
** I/O on that database connection, or if the database entered [WAL mode]
** after the most recent I/O on the database connection.)^
** (Hint: Run "[PRAGMA application_id]" against a newly opened
** database connection in order to make it ready to use snapshots.) ** database connection in order to make it ready to use snapshots.)
** **
** The [sqlite3_snapshot_open()] interface is only available when the ** The [sqlite3_snapshot_open()] interface is only available when the

View File

@ -2814,6 +2814,7 @@ struct Parse {
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */ u8 okConstFactor; /* OK to factor out constants */
u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 nColCache; /* Number of entries in aColCache[] */
int aTempReg[8]; /* Holding area for temporary registers */ int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */ int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */ int iRangeReg; /* First register in temporary register block */
@ -3301,6 +3302,7 @@ int sqlite3CantopenError(int);
# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) # define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) # define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) # define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
#else #else
# define sqlite3Toupper(x) toupper((unsigned char)(x)) # define sqlite3Toupper(x) toupper((unsigned char)(x))
# define sqlite3Isspace(x) isspace((unsigned char)(x)) # define sqlite3Isspace(x) isspace((unsigned char)(x))
@ -3309,6 +3311,7 @@ int sqlite3CantopenError(int);
# define sqlite3Isdigit(x) isdigit((unsigned char)(x)) # define sqlite3Isdigit(x) isdigit((unsigned char)(x))
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
# define sqlite3Tolower(x) tolower((unsigned char)(x)) # define sqlite3Tolower(x) tolower((unsigned char)(x))
# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
#endif #endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
int sqlite3IsIdChar(u8); int sqlite3IsIdChar(u8);
@ -3432,7 +3435,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
void sqlite3SetString(char **, sqlite3*, const char*); void sqlite3SetString(char **, sqlite3*, const char*);
void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3ErrorMsg(Parse*, const char*, ...);
int sqlite3Dequote(char*); void sqlite3Dequote(char*);
void sqlite3TokenInit(Token*,char*); void sqlite3TokenInit(Token*,char*);
int sqlite3KeywordCode(const unsigned char*, int); int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **); int sqlite3RunParser(Parse*, const char*, char **);
@ -3449,6 +3452,7 @@ Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*); Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*); void sqlite3ExprAssignVarNumber(Parse*, Expr*);
@ -3468,6 +3472,7 @@ void sqlite3CollapseDatabaseArray(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*); void sqlite3DeleteColumnNames(sqlite3*,Table*);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
Table *sqlite3ResultSetOfSelect(Parse*,Select*); Table *sqlite3ResultSetOfSelect(Parse*,Select*);
void sqlite3OpenMasterTable(Parse *, int); void sqlite3OpenMasterTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*); Index *sqlite3PrimaryKeyIndex(Table*);

View File

@ -242,18 +242,13 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
** brackets from around identifiers. For example: "[a-b-c]" becomes ** brackets from around identifiers. For example: "[a-b-c]" becomes
** "a-b-c". ** "a-b-c".
*/ */
int sqlite3Dequote(char *z){ void sqlite3Dequote(char *z){
char quote; char quote;
int i, j; int i, j;
if( z==0 ) return -1; if( z==0 ) return;
quote = z[0]; quote = z[0];
switch( quote ){ if( !sqlite3Isquote(quote) ) return;
case '\'': break; if( quote=='[' ) quote = ']';
case '"': break;
case '`': break; /* For MySQL compatibility */
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
default: return -1;
}
for(i=1, j=0;; i++){ for(i=1, j=0;; i++){
assert( z[i] ); assert( z[i] );
if( z[i]==quote ){ if( z[i]==quote ){
@ -268,7 +263,6 @@ int sqlite3Dequote(char *z){
} }
} }
z[j] = 0; z[j] = 0;
return j;
} }
/* /*
@ -1448,7 +1442,6 @@ LogEst sqlite3LogEstFromDouble(double x){
*/ */
u64 sqlite3LogEstToInt(LogEst x){ u64 sqlite3LogEstToInt(LogEst x){
u64 n; u64 n;
if( x<10 ) return 1;
n = x%10; n = x%10;
x /= 10; x /= 10;
if( n>=5 ) n -= 2; if( n>=5 ) n -= 2;

View File

@ -674,37 +674,39 @@ int sqlite3VdbeExec(
/* Sanity checking on other operands */ /* Sanity checking on other operands */
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); {
if( (pOp->opflags & OPFLG_IN1)!=0 ){ u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
assert( pOp->p1>0 ); if( (opProperty & OPFLG_IN1)!=0 ){
assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); assert( pOp->p1>0 );
assert( memIsValid(&aMem[pOp->p1]) ); assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); assert( memIsValid(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
} REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
if( (pOp->opflags & OPFLG_IN2)!=0 ){ }
assert( pOp->p2>0 ); if( (opProperty & OPFLG_IN2)!=0 ){
assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); assert( pOp->p2>0 );
assert( memIsValid(&aMem[pOp->p2]) ); assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); assert( memIsValid(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
} REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
if( (pOp->opflags & OPFLG_IN3)!=0 ){ }
assert( pOp->p3>0 ); if( (opProperty & OPFLG_IN3)!=0 ){
assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( pOp->p3>0 );
assert( memIsValid(&aMem[pOp->p3]) ); assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); assert( memIsValid(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
} REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
if( (pOp->opflags & OPFLG_OUT2)!=0 ){ }
assert( pOp->p2>0 ); if( (opProperty & OPFLG_OUT2)!=0 ){
assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); assert( pOp->p2>0 );
memAboutToChange(p, &aMem[pOp->p2]); assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
} memAboutToChange(p, &aMem[pOp->p2]);
if( (pOp->opflags & OPFLG_OUT3)!=0 ){ }
assert( pOp->p3>0 ); if( (opProperty & OPFLG_OUT3)!=0 ){
assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( pOp->p3>0 );
memAboutToChange(p, &aMem[pOp->p3]); assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
} }
#endif #endif
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@ -2755,7 +2757,9 @@ case OP_MakeRecord: {
testcase( serial_type==127 ); testcase( serial_type==127 );
testcase( serial_type==128 ); testcase( serial_type==128 );
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
}while( (--pRec)>=pData0 ); if( pRec==pData0 ) break;
pRec--;
}while(1);
/* EVIDENCE-OF: R-22564-11647 The header begins with a single varint /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
** which determines the total number of bytes in the header. The varint ** which determines the total number of bytes in the header. The varint
@ -6875,11 +6879,12 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){ if( db->flags & SQLITE_VdbeTrace ){
u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
if( rc!=0 ) printf("rc=%d\n",rc); if( rc!=0 ) printf("rc=%d\n",rc);
if( pOrigOp->opflags & (OPFLG_OUT2) ){ if( opProperty & (OPFLG_OUT2) ){
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
} }
if( pOrigOp->opflags & OPFLG_OUT3 ){ if( opProperty & OPFLG_OUT3 ){
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
} }
} }

View File

@ -41,7 +41,7 @@ typedef struct SubProgram SubProgram;
struct VdbeOp { struct VdbeOp {
u8 opcode; /* What operation to perform */ u8 opcode; /* What operation to perform */
signed char p4type; /* One of the P4_xxx constants for p4 */ signed char p4type; /* One of the P4_xxx constants for p4 */
u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */ u8 notUsed1;
u8 p5; /* Fifth parameter is an unsigned character */ u8 p5; /* Fifth parameter is an unsigned character */
int p1; /* First operand */ int p1; /* First operand */
int p2; /* Second parameter (often the jump destination) */ int p2; /* Second parameter (often the jump destination) */

View File

@ -545,73 +545,84 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** (4) Initialize the p4.xAdvance pointer on opcodes that use it. ** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
** **
** (5) Reclaim the memory allocated for storing labels. ** (5) Reclaim the memory allocated for storing labels.
**
** This routine will only function correctly if the mkopcodeh.tcl generator
** script numbers the opcodes correctly. Changes to this routine must be
** coordinated with changes to mkopcodeh.tcl.
*/ */
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs; int nMaxArgs = *pMaxFuncArgs;
Op *pOp; Op *pOp;
Parse *pParse = p->pParse; Parse *pParse = p->pParse;
int *aLabel = pParse->aLabel; int *aLabel = pParse->aLabel;
p->readOnly = 1; p->readOnly = 1;
p->bIsReader = 0; p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ pOp = &p->aOp[p->nOp-1];
u8 opcode = pOp->opcode; while(1){
/* NOTE: Be sure to update mkopcodeh.tcl when adding or removing /* Only JUMP opcodes and the short list of special opcodes in the switch
** cases from this switch! */ ** below need to be considered. The mkopcodeh.tcl generator script groups
switch( opcode ){ ** all these opcodes together near the front of the opcode list. Skip
case OP_Transaction: { ** any opcode that does not need processing by virtual of the fact that
if( pOp->p2!=0 ) p->readOnly = 0; ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
/* fall thru */ */
} if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
case OP_AutoCommit: /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
case OP_Savepoint: { ** cases from this switch! */
p->bIsReader = 1; switch( pOp->opcode ){
break; case OP_Transaction: {
} if( pOp->p2!=0 ) p->readOnly = 0;
/* fall thru */
}
case OP_AutoCommit:
case OP_Savepoint: {
p->bIsReader = 1;
break;
}
#ifndef SQLITE_OMIT_WAL #ifndef SQLITE_OMIT_WAL
case OP_Checkpoint: case OP_Checkpoint:
#endif #endif
case OP_Vacuum: case OP_Vacuum:
case OP_JournalMode: { case OP_JournalMode: {
p->readOnly = 0; p->readOnly = 0;
p->bIsReader = 1; p->bIsReader = 1;
break; break;
} }
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
case OP_VUpdate: { case OP_VUpdate: {
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
break; break;
} }
case OP_VFilter: { case OP_VFilter: {
int n; int n;
assert( p->nOp - i >= 3 ); assert( (pOp - p->aOp) >= 3 );
assert( pOp[-1].opcode==OP_Integer ); assert( pOp[-1].opcode==OP_Integer );
n = pOp[-1].p1; n = pOp[-1].p1;
if( n>nMaxArgs ) nMaxArgs = n; if( n>nMaxArgs ) nMaxArgs = n;
break; break;
} }
#endif #endif
case OP_Next: case OP_Next:
case OP_NextIfOpen: case OP_NextIfOpen:
case OP_SorterNext: { case OP_SorterNext: {
pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4.xAdvance = sqlite3BtreeNext;
pOp->p4type = P4_ADVANCE; pOp->p4type = P4_ADVANCE;
break; break;
}
case OP_Prev:
case OP_PrevIfOpen: {
pOp->p4.xAdvance = sqlite3BtreePrevious;
pOp->p4type = P4_ADVANCE;
break;
}
} }
case OP_Prev: if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
case OP_PrevIfOpen: { assert( ADDR(pOp->p2)<pParse->nLabel );
pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p2 = aLabel[ADDR(pOp->p2)];
pOp->p4type = P4_ADVANCE;
break;
} }
} }
if( pOp==p->aOp ) break;
pOp->opflags = sqlite3OpcodeProperty[opcode]; pOp--;
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( ADDR(pOp->p2)<pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
} }
sqlite3DbFree(p->db, pParse->aLabel); sqlite3DbFree(p->db, pParse->aLabel);
pParse->aLabel = 0; pParse->aLabel = 0;
@ -791,52 +802,50 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
** Delete a P4 value if necessary. ** Delete a P4 value if necessary.
*/ */
static void freeP4(sqlite3 *db, int p4type, void *p4){ static void freeP4(sqlite3 *db, int p4type, void *p4){
if( p4 ){ assert( db );
assert( db ); switch( p4type ){
switch( p4type ){ case P4_FUNCCTX: {
case P4_FUNCCTX: { freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc); /* Fall through into the next case */
/* Fall through into the next case */ }
} case P4_REAL:
case P4_REAL: case P4_INT64:
case P4_INT64: case P4_DYNAMIC:
case P4_DYNAMIC: case P4_INTARRAY: {
case P4_INTARRAY: { sqlite3DbFree(db, p4);
sqlite3DbFree(db, p4); break;
break; }
} case P4_KEYINFO: {
case P4_KEYINFO: { if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); break;
break; }
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS #ifdef SQLITE_ENABLE_CURSOR_HINTS
case P4_EXPR: { case P4_EXPR: {
sqlite3ExprDelete(db, (Expr*)p4); sqlite3ExprDelete(db, (Expr*)p4);
break; break;
} }
#endif #endif
case P4_MPRINTF: { case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4); if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break; break;
} }
case P4_FUNCDEF: { case P4_FUNCDEF: {
freeEphemeralFunction(db, (FuncDef*)p4); freeEphemeralFunction(db, (FuncDef*)p4);
break; break;
} }
case P4_MEM: { case P4_MEM: {
if( db->pnBytesFreed==0 ){ if( db->pnBytesFreed==0 ){
sqlite3ValueFree((sqlite3_value*)p4); sqlite3ValueFree((sqlite3_value*)p4);
}else{ }else{
Mem *p = (Mem*)p4; Mem *p = (Mem*)p4;
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
sqlite3DbFree(db, p); sqlite3DbFree(db, p);
}
break;
}
case P4_VTAB : {
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
break;
} }
break;
}
case P4_VTAB : {
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
break;
} }
} }
} }

View File

@ -1651,11 +1651,12 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){
*/ */
static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
WhereInfo *pWInfo = pWC->pWInfo; WhereInfo *pWInfo = pWC->pWInfo;
int nb = 1+(pWInfo->pTabList->nSrc+7)/8; int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pTab; Table *pTab = pItem->pTab;
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq); p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
sqlite3DebugPrintf(" %12s", sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName); pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){

View File

@ -941,7 +941,13 @@ Bitmask sqlite3WhereCodeOneLoopStart(
} }
} }
} }
sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); /* These registers need to be preserved in case there is an IN operator
** loop. So we could deallocate the registers here (and potentially
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
** simpler and safer to simply not reuse the registers.
**
** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
*/
sqlite3ExprCachePop(pParse); sqlite3ExprCachePop(pParse);
}else }else
#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_VIRTUALTABLE */

View File

@ -165,4 +165,111 @@ foreach {tn mode} {
} $plan($mode) } $plan($mode)
} }
# 2016-04-09.
# Demonstrate a register overwrite problem when using two virtual
# tables where the outer loop uses the IN operator.
#
set G(collist) [list PrimaryKey flagA columnA]
set G(cols) [join $G(collist) ,]
set G(nulls) "NULL"
proc vtab_command {method args} {
global G
switch -- $method {
xConnect {
return "CREATE TABLE t1($G(cols))"
}
xBestIndex {
set clist [lindex $args 0]
#puts $clist
set W [list]
set U [list]
set i 0
for {set idx 0} {$idx < [llength $clist]} {incr idx} {
array set c [lindex $clist $idx]
if {$c(op)=="eq" && $c(usable)} {
lappend W "[lindex $G(collist) $c(column)] = %$i%"
lappend U use $idx
incr i
}
}
if {$W==""} {
set sql "SELECT rowid, * FROM t1"
} else {
set sql "SELECT rowid, * FROM t1 WHERE [join $W { AND }]"
}
return [concat [list idxstr $sql] $U]
}
xFilter {
foreach {idxnum idxstr vals} $args {}
set map [list]
for {set i 0} {$i < [llength $vals]} {incr i} {
lappend map "%$i%"
set v [lindex $vals $i]
if {[string is integer $v]} {
lappend map $v
} else {
lappend map "'$v'"
}
}
set sql [string map $map $idxstr]
#puts "SQL: $sql"
return [list sql $sql]
}
}
return {}
}
db close
forcedelete test.db
sqlite3 db test.db
register_tcl_module db
do_execsql_test 3.1 "
CREATE TABLE t1($G(cols));
INSERT INTO t1 VALUES(1, 0, 'ValueA');
INSERT INTO t1 VALUES(2, 0, 'ValueA');
INSERT INTO t1 VALUES(3, 0, 'ValueB');
INSERT INTO t1 VALUES(4, 0, 'ValueB');
"
do_execsql_test 3.2 {
CREATE VIRTUAL TABLE VirtualTableA USING tcl(vtab_command);
CREATE VIRTUAL TABLE VirtualTableB USING tcl(vtab_command);
}
do_execsql_test 3.3 { SELECT primarykey FROM VirtualTableA } {1 2 3 4}
do_execsql_test 3.4 {
SELECT * FROM
VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey
WHERE a.ColumnA IN ('ValueA', 'ValueB') AND a.FlagA=0
} {
1 0 ValueA 1 0 ValueA
2 0 ValueA 2 0 ValueA
3 0 ValueB 3 0 ValueB
4 0 ValueB 4 0 ValueB
}
do_execsql_test 3.5 {
SELECT * FROM
VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey
WHERE a.FlagA=0 AND a.ColumnA IN ('ValueA', 'ValueB')
} {
1 0 ValueA 1 0 ValueA
2 0 ValueA 2 0 ValueA
3 0 ValueB 3 0 ValueB
4 0 ValueB 4 0 ValueB
}
finish_test finish_test

View File

@ -139,7 +139,26 @@ do_execsql_test 4.12 {
PRAGMA integrity_check; PRAGMA integrity_check;
} {ok} } {ok}
# 2016-04-09
# Ticket https://sqlite.org/src/info/a306e56ff68b8fa5
# Failure to completely delete when reverse_unordered_selects is
# engaged.
#
db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test 5.0 {
PRAGMA page_size=1024;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX x1 ON t1(b, c);
INSERT INTO t1(a,b,c) VALUES(1, 1, zeroblob(80));
INSERT INTO t1(a,b,c) SELECT a+1, 1, c FROM t1;
INSERT INTO t1(a,b,c) SELECT a+2, 1, c FROM t1;
INSERT INTO t1(a,b,c) SELECT a+10, 2, c FROM t1 WHERE b=1;
INSERT INTO t1(a,b,c) SELECT a+20, 3, c FROM t1 WHERE b=1;
PRAGMA reverse_unordered_selects = ON;
DELETE FROM t1 WHERE b=2;
SELECT a FROM t1 WHERE b=2;
} {}
finish_test finish_test

View File

@ -95,4 +95,38 @@ do_test savepoint7-2.2 {
list $rc $msg [db eval {SELECT * FROM t2}] list $rc $msg [db eval {SELECT * FROM t2}]
} {1 {abort due to ROLLBACK} {}} } {1 {abort due to ROLLBACK} {}}
# Ticket: https://www.sqlite.org/src/tktview/7f7f8026eda387d544b
# Segfault in the in-memory journal logic triggered by a tricky
# combination of SAVEPOINT operations.
#
unset -nocomplain i
for {set i 248} {$i<=253} {incr i} {
do_test savepoint7-3.$i {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=1024;
PRAGMA temp_store=MEMORY;
BEGIN;
CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
INSERT INTO t1(x,y) SELECT x*10, printf('%04d%.800c',x,'*') FROM c;
SAVEPOINT one;
SELECT count(*) FROM t1;
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
INSERT INTO t1(x,y) SELECT x*10+1, printf('%04d%.800c',x,'*') FROM c;
ROLLBACK TO one;
SELECT count(*) FROM t1;
SAVEPOINT twoB;
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10)
INSERT INTO t1(x,y) SELECT x*10+2, printf('%04d%.800c',x,'*') FROM c;
ROLLBACK TO twoB;
RELEASE one;
COMMIT;
}
} [list $i $i]
}
finish_test finish_test

View File

@ -92,6 +92,26 @@ do_test view-1.8 {
} }
} {2 3 5 6 8 9} } {2 3 5 6 8 9}
do_execsql_test view-1.10 {
CREATE TABLE t9(x INTEGER);
CREATE VIEW v9a AS SELECT x FROM t9;
CREATE VIEW v9b AS SELECT * FROM t9;
CREATE VIEW v9c(x) AS SELECT x FROM t9;
CREATE VIEW v9d(x) AS SELECT * FROM t9;
} {}
do_execsql_test view-1.11 {
PRAGMA table_info(v9a);
} {0 x INTEGER 0 {} 0}
do_execsql_test view-1.12 {
PRAGMA table_info(v9b);
} {0 x INTEGER 0 {} 0}
do_execsql_test view-1.13 {
PRAGMA table_info(v9c);
} {0 x INTEGER 0 {} 0}
do_execsql_test view-1.14 {
PRAGMA table_info(v9d);
} {0 x INTEGER 0 {} 0}
do_test view-2.1 { do_test view-2.1 {
execsql { execsql {
CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5 CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5

View File

@ -20,8 +20,7 @@
# during code generation, we need to generate corresponding opcodes like # during code generation, we need to generate corresponding opcodes like
# OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide, # OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
# code to translate from one to the other is avoided. This makes the # code to translate from one to the other is avoided. This makes the
# code generator run (infinitesimally) faster and more importantly it makes # code generator smaller and faster.
# the library footprint smaller.
# #
# This script also scans for lines of the form: # This script also scans for lines of the form:
# #
@ -159,7 +158,29 @@ for {set i 0} {$i<$nOp} {incr i} {
} }
} }
# Generate the numeric values for remaining opcodes # Assign the next group of values to JUMP opcodes
#
for {set i 0} {$i<$nOp} {incr i} {
set name $order($i)
if {$op($name)>=0} continue
if {!$jump($name)} continue
incr cnt
while {[info exists used($cnt)]} {incr cnt}
set op($name) $cnt
set used($cnt) 1
set def($cnt) $name
}
# Find the numeric value for the largest JUMP opcode
#
set mxJump -1
for {set i 0} {$i<$nOp} {incr i} {
set name $order($i)
if {$jump($name) && $op($name)>$mxJump} {set mxJump $op($name)}
}
# Generate the numeric values for all remaining opcodes
# #
for {set i 0} {$i<$nOp} {incr i} { for {set i 0} {$i<$nOp} {incr i} {
set name $order($i) set name $order($i)
@ -232,3 +253,11 @@ for {set i 0} {$i<=$max} {incr i} {
} }
} }
puts "\175" puts "\175"
puts ""
puts "/* The sqlite3P2Values() routine is able to run faster if it knows"
puts "** the value of the largest JUMP opcode. The smaller the maximum"
puts "** JUMP opcode the better, so the mkopcodeh.tcl script that"
puts "** generated this include file strives to group all JUMP opcodes"
puts "** together near the beginning of the list."
puts "*/"
puts "#define SQLITE_MX_JUMP_OPCODE $mxJump /* Maximum JUMP opcode */"