mirror of https://github.com/sqlite/sqlite
Where possible, avoid freeing buffers allocated for vdbe memory cells in case they can be reused. (CVS 4783)
FossilOrigin-Name: 990237e27e417aff3dbf05784b716c21f3761a3a
This commit is contained in:
parent
0f35a6b529
commit
a7a8e14bf2
58
manifest
58
manifest
|
@ -1,5 +1,5 @@
|
||||||
C When\smaterializing\sa\sview\sfor\san\sUPDATE\sor\sDELETE\smake\suse\sof\sthe\sWHERE\nclause\sto\slimit\sthe\snumber\sof\srows\smaterialized.\s\sTicket\s#2938.\s(CVS\s4782)
|
C Where\spossible,\savoid\sfreeing\sbuffers\sallocated\sfor\svdbe\smemory\scells\sin\scase\sthey\scan\sbe\sreused.\s(CVS\s4783)
|
||||||
D 2008-02-12T16:52:14
|
D 2008-02-13T18:25:27
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in bc2b5df3e3d0d4b801b824b7ef6dec43812b049b
|
F Makefile.in bc2b5df3e3d0d4b801b824b7ef6dec43812b049b
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
|
@ -80,7 +80,7 @@ F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
||||||
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
||||||
F src/alter.c b494a50f239a760565ce6220ee316e96956ec054
|
F src/alter.c b494a50f239a760565ce6220ee316e96956ec054
|
||||||
F src/analyze.c a78ac494668581fe7f54ee63700815bb0ea34261
|
F src/analyze.c a78ac494668581fe7f54ee63700815bb0ea34261
|
||||||
F src/attach.c 90665c7ef5145e066570f66d7f0f15cdd0a4d14b
|
F src/attach.c e13d62597e8725075b27186817f7e745122af24e
|
||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
|
F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
|
||||||
F src/btree.c 29ea577155f39be65bdec1c7782301ff2ee9eb3f
|
F src/btree.c 29ea577155f39be65bdec1c7782301ff2ee9eb3f
|
||||||
|
@ -97,24 +97,24 @@ F src/fault.c 049b88b8ba0a1db3240aeaf9695cd08b9a3ba9e1
|
||||||
F src/func.c 8e3d0c59961dc403716767308ee764504179054b
|
F src/func.c 8e3d0c59961dc403716767308ee764504179054b
|
||||||
F src/hash.c 2dc6afe7478a0b739499af360c8863c900ea11a8
|
F src/hash.c 2dc6afe7478a0b739499af360c8863c900ea11a8
|
||||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||||
F src/insert.c d422fda2d1f02219871cb7e3e4b49c680632450e
|
F src/insert.c b313f5ecadf82dda15b1aa6780b0310eceb9e776
|
||||||
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
||||||
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
F src/legacy.c cb1939fdeb91ea88fb44fbd2768a10e14bc44650
|
||||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||||
F src/loadext.c d17a0f760d6866aacf5262f97d8efaaad379cdd7
|
F src/loadext.c d17a0f760d6866aacf5262f97d8efaaad379cdd7
|
||||||
F src/main.c b4014b71979a58d6aa79549fdf87175ab7bdf1cc
|
F src/main.c b4014b71979a58d6aa79549fdf87175ab7bdf1cc
|
||||||
F src/malloc.c 60e392a4c12c839517f9b0db7b995f825444fb35
|
F src/malloc.c 60e392a4c12c839517f9b0db7b995f825444fb35
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/mem1.c 6d1a11864963d249c67e72ad5f6533b040333880
|
F src/mem1.c b15e107d51bdd4bcf410c18798ee48bee4768d4e
|
||||||
F src/mem2.c 607af52ad7593f34934e7e4fa53a364556853d30
|
F src/mem2.c ed0cb11ae43a3cc92bfb07172c2801956e94eaba
|
||||||
F src/mem3.c 9d80034bb004c1bddc28d6befe1ddb044d18deab
|
F src/mem3.c cf1bf5b2f9d4d76e465c84c0607f6882d3b1b522
|
||||||
F src/mem4.c 36ecd536a8b7acfe4cbf011353dae6ea68121e40
|
F src/mem4.c 36ecd536a8b7acfe4cbf011353dae6ea68121e40
|
||||||
F src/mutex.c 3259f62c2429967aee6dc112117a6d2f499ef061
|
F src/mutex.c 3259f62c2429967aee6dc112117a6d2f499ef061
|
||||||
F src/mutex.h 079fa6fe9da18ceb89e79012c010594c6672addb
|
F src/mutex.h 079fa6fe9da18ceb89e79012c010594c6672addb
|
||||||
F src/mutex_os2.c 19ab15764736f13b94b4f70e53f77547cbddd47a
|
F src/mutex_os2.c 19ab15764736f13b94b4f70e53f77547cbddd47a
|
||||||
F src/mutex_unix.c a6e111947a3cdaa2cda394ed060d7f496fcb4af8
|
F src/mutex_unix.c a6e111947a3cdaa2cda394ed060d7f496fcb4af8
|
||||||
F src/mutex_w32.c 6e197765f283815496193e78e9548b5d0e53b68e
|
F src/mutex_w32.c 6e197765f283815496193e78e9548b5d0e53b68e
|
||||||
F src/os.c 50c0c1706c35f872db312815aaecc4b5ebcd6a4c
|
F src/os.c 2f2753b8d33f79d169c43d6bb0b25b3c58fd33de
|
||||||
F src/os.h d04706d54a072c7a30ab9e346ad916ef28c842d5
|
F src/os.h d04706d54a072c7a30ab9e346ad916ef28c842d5
|
||||||
F src/os_common.h 98862f120ca6bf7a48ce8b16f158b77d00bc9d2f
|
F src/os_common.h 98862f120ca6bf7a48ce8b16f158b77d00bc9d2f
|
||||||
F src/os_os2.c bf1cd3d4f42c1b1ab059c12732cd9f7be4e718a6
|
F src/os_os2.c bf1cd3d4f42c1b1ab059c12732cd9f7be4e718a6
|
||||||
|
@ -128,27 +128,27 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 2ed81808091ce42ceb1cf209e4ce87922a0065c8
|
F src/pager.c 2ed81808091ce42ceb1cf209e4ce87922a0065c8
|
||||||
F src/pager.h 8174615ffd14ccc2cad2b081b919a398fa95e3f9
|
F src/pager.h 8174615ffd14ccc2cad2b081b919a398fa95e3f9
|
||||||
F src/parse.y 00f2698c8ae84f315be5e3f10b63c94f531fdd6d
|
F src/parse.y 00f2698c8ae84f315be5e3f10b63c94f531fdd6d
|
||||||
F src/pragma.c 2bb8d6882b9a330e041acd05fb6aff5a01bf0a08
|
F src/pragma.c e3f39f8576234887ecd0c1de43dc51af5855930c
|
||||||
F src/prepare.c 1b0601ca3f97a9d253cc08697484e3045a1678e9
|
F src/prepare.c 1b0601ca3f97a9d253cc08697484e3045a1678e9
|
||||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||||
F src/random.c 02ef38b469237482f1ea14a78b2087cfbaec48bd
|
F src/random.c 02ef38b469237482f1ea14a78b2087cfbaec48bd
|
||||||
F src/select.c 394aa3542e8df599dcca77b0e75f7875760a13ad
|
F src/select.c 1d780691071af7d58b83a6b38517c2687dd83c5b
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c ca06cb687c40a8bff6307b5fad41a0e86a0f8558
|
F src/shell.c ca06cb687c40a8bff6307b5fad41a0e86a0f8558
|
||||||
F src/sqlite.h.in 690736613958e0f462e08ae2a9136fa335214edc
|
F src/sqlite.h.in 690736613958e0f462e08ae2a9136fa335214edc
|
||||||
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
||||||
F src/sqliteInt.h e4ca11fff0cdac38551b75a2a278edb8ad9e1f00
|
F src/sqliteInt.h 822045362bdddd303a0b17aa09679ba735ffbaa1
|
||||||
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
||||||
F src/table.c 46ccf9b7892a86f57420ae7bac69ecd5e72d26b5
|
F src/table.c 46ccf9b7892a86f57420ae7bac69ecd5e72d26b5
|
||||||
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
F src/tclsqlite.c 0d4483e37c6a1e87f80565e50d977df6dd2bf732
|
||||||
F src/test1.c 5363a117741f26e84b85e30757f0f4414331c46f
|
F src/test1.c 28b135491b436b1df6390a8b53834da2f94efca4
|
||||||
F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
|
F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
|
||||||
F src/test3.c 4557ee13c6e5921eb28979ff77cdbd913bfde6be
|
F src/test3.c 4557ee13c6e5921eb28979ff77cdbd913bfde6be
|
||||||
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
||||||
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
||||||
F src/test6.c f8b34a6ff04937092327798ddf0ab46863535bc5
|
F src/test6.c f8b34a6ff04937092327798ddf0ab46863535bc5
|
||||||
F src/test7.c acec2256c7c2d279db5a8b5fa1a2a68fcc942c67
|
F src/test7.c acec2256c7c2d279db5a8b5fa1a2a68fcc942c67
|
||||||
F src/test8.c cab3f576353dfef4877c7cc3b0d0e48acc65c37c
|
F src/test8.c 25e127f0e21f59da24fa33cdbc645851cfb933f1
|
||||||
F src/test9.c 4615ef08750245a2d96aaa7cbe2fb4aff2b57acc
|
F src/test9.c 4615ef08750245a2d96aaa7cbe2fb4aff2b57acc
|
||||||
F src/test_async.c 5f21392d66869a4c87dc9153e40d0dc0e085261f
|
F src/test_async.c 5f21392d66869a4c87dc9153e40d0dc0e085261f
|
||||||
F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436
|
F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436
|
||||||
|
@ -157,7 +157,7 @@ F src/test_config.c e7db7a46833d0df98ae6c9a11f70dada1bcca249
|
||||||
F src/test_devsym.c fd8884c2269fb7e0db2c52d21ec59d31a33790ba
|
F src/test_devsym.c fd8884c2269fb7e0db2c52d21ec59d31a33790ba
|
||||||
F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
|
F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
|
||||||
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
||||||
F src/test_malloc.c 0bc9d27c09efe0be63d0de5fb6e38a4253cd5551
|
F src/test_malloc.c f57e6327a9c32dc71fb2c15941f64d4e91461d3b
|
||||||
F src/test_md5.c c107c96637123239c3518b5fbe97a79130f4d32e
|
F src/test_md5.c c107c96637123239c3518b5fbe97a79130f4d32e
|
||||||
F src/test_onefile.c 54282b6796d55d7acc489be83b89b8715e7d3756
|
F src/test_onefile.c 54282b6796d55d7acc489be83b89b8715e7d3756
|
||||||
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
||||||
|
@ -167,17 +167,17 @@ F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
||||||
F src/tokenize.c c4b79fd48ddb709b2b8522b7d93a5a3d98168ca4
|
F src/tokenize.c c4b79fd48ddb709b2b8522b7d93a5a3d98168ca4
|
||||||
F src/trigger.c 9bd3b6fa0beff4a02d262c96466f752ec15a7fc3
|
F src/trigger.c 9bd3b6fa0beff4a02d262c96466f752ec15a7fc3
|
||||||
F src/update.c 9b3be169cd2a0b065717164aa0f90aa48f34aed1
|
F src/update.c 9b3be169cd2a0b065717164aa0f90aa48f34aed1
|
||||||
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
F src/utf.c 32b00d6e19010025e58f2ecb2f921d5e126771b4
|
||||||
F src/util.c c56e41ed4769c1f2b8af9ffde4757a7b4fb08ed1
|
F src/util.c c56e41ed4769c1f2b8af9ffde4757a7b4fb08ed1
|
||||||
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
|
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
|
||||||
F src/vdbe.c 1049375248b494e626598abffeeb31052c660c78
|
F src/vdbe.c a172f5134d19ae910134e28987bf7906523c9b6f
|
||||||
F src/vdbe.h 58a7d931ffb704e034b2a725981cfa5bd406fad9
|
F src/vdbe.h 58a7d931ffb704e034b2a725981cfa5bd406fad9
|
||||||
F src/vdbeInt.h 969d360acc85f7b2069a8169b4f8a3e1fbaccd44
|
F src/vdbeInt.h 76c81d057a39813de0fda3cad1498655d53ec69d
|
||||||
F src/vdbeapi.c 61b37dbe11baa221baea7f93c01780705d2419ed
|
F src/vdbeapi.c cf9fc963efae3cdf5de08e2a9718b487059c7fc5
|
||||||
F src/vdbeaux.c 771b9ffd7b42cbb4bd029d7a9414a7cb03f924a7
|
F src/vdbeaux.c 36d4db24659146606a1c755650f2a70cf88eec25
|
||||||
F src/vdbeblob.c 63c750acc7b5012479f508c0e9627372a82cb65d
|
F src/vdbeblob.c 63c750acc7b5012479f508c0e9627372a82cb65d
|
||||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||||
F src/vdbemem.c cee169fb5542cccfd1e8d832ae4538cb69b8917a
|
F src/vdbemem.c e060d04bc6f8cf32c638fddada266b01cad8ee9a
|
||||||
F src/vtab.c dc8947c9c79780b19ee6d6bae4ea624a2a303353
|
F src/vtab.c dc8947c9c79780b19ee6d6bae4ea624a2a303353
|
||||||
F src/where.c 7ff0ca021cc77086e367ed3b6308fbc6bc9e1a31
|
F src/where.c 7ff0ca021cc77086e367ed3b6308fbc6bc9e1a31
|
||||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||||
|
@ -378,7 +378,7 @@ F test/malloc8.test addc27d907fec1af429551b95c72caa47fce2974
|
||||||
F test/malloc9.test 95d7069ad4fa262bf33bc4c5ca0a46f2bb2391cb
|
F test/malloc9.test 95d7069ad4fa262bf33bc4c5ca0a46f2bb2391cb
|
||||||
F test/mallocA.test 5ee8d42ff90e5b1aeee6fb645e73ffcb35bffd21
|
F test/mallocA.test 5ee8d42ff90e5b1aeee6fb645e73ffcb35bffd21
|
||||||
F test/mallocAll.test 2a2222a5e447be6c6579055a9a26e507e4586f4e
|
F test/mallocAll.test 2a2222a5e447be6c6579055a9a26e507e4586f4e
|
||||||
F test/mallocB.test 82ecf4d3fa6c389cabc747daa2deddfe94af2a74
|
F test/mallocB.test d4a91e7d9cc916d009e0fec08537b3be299ee514
|
||||||
F test/mallocC.test 9daac0aa8e5b0afa7b0a3fb0cd792f02fe0cc838
|
F test/mallocC.test 9daac0aa8e5b0afa7b0a3fb0cd792f02fe0cc838
|
||||||
F test/mallocD.test 24c1d07a00e605831d0d627b036bd690b2952416
|
F test/mallocD.test 24c1d07a00e605831d0d627b036bd690b2952416
|
||||||
F test/mallocE.test e15333c394d7c330c8372a7cdf7b0f7c16573082
|
F test/mallocE.test e15333c394d7c330c8372a7cdf7b0f7c16573082
|
||||||
|
@ -412,7 +412,7 @@ F test/pragma.test d9f3d80583b80708aa270e8c5038dee949190d78
|
||||||
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
||||||
F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d
|
F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d
|
||||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
|
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
|
||||||
F test/ptrchng.test 38ae1806833d72d9a81a6121322e274f24937e18
|
F test/ptrchng.test 1f7bb92398163f1c18d69727c3ab31d90e94b458
|
||||||
F test/quick.test 771a6b3a88fdd0e7e813ce013ceda29037bc9462
|
F test/quick.test 771a6b3a88fdd0e7e813ce013ceda29037bc9462
|
||||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||||
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
|
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
|
||||||
|
@ -453,7 +453,7 @@ F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455
|
||||||
F test/tableapi.test 4546eb710d979db023bfcc16b0c108b1557fcb43
|
F test/tableapi.test 4546eb710d979db023bfcc16b0c108b1557fcb43
|
||||||
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
||||||
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
||||||
F test/tester.tcl bfad4d2acf0659c6afbf48a98556b0433d2906dc
|
F test/tester.tcl 70ed4c0dda3e2277bac9e0bf38e60df9dc360d08
|
||||||
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
||||||
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
||||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||||
|
@ -617,7 +617,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P 607247c27b80520b8c25c489757288b8ea186f9e
|
P 5ab71c3a79cac04cb2c576f83a62218d05571006
|
||||||
R 6e7459c99c887be282a1c6ce2d461da7
|
R c1dd02f73a73bb7e12988703f2d12663
|
||||||
U drh
|
U danielk1977
|
||||||
Z 584629669827c756e74626290b2a5564
|
Z 2dff5d02e45b3ba8d57e28cad43b1b4e
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
5ab71c3a79cac04cb2c576f83a62218d05571006
|
990237e27e417aff3dbf05784b716c21f3761a3a
|
|
@ -11,7 +11,7 @@
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||||
**
|
**
|
||||||
** $Id: attach.c,v 1.71 2008/02/06 14:11:35 drh Exp $
|
** $Id: attach.c,v 1.72 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
@ -328,14 +328,14 @@ static void codeAttach(
|
||||||
}
|
}
|
||||||
|
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
regArgs = sqlite3GetTempRange(pParse, 3);
|
regArgs = sqlite3GetTempRange(pParse, 4);
|
||||||
sqlite3ExprCode(pParse, pFilename, regArgs);
|
sqlite3ExprCode(pParse, pFilename, regArgs);
|
||||||
sqlite3ExprCode(pParse, pDbname, regArgs+1);
|
sqlite3ExprCode(pParse, pDbname, regArgs+1);
|
||||||
sqlite3ExprCode(pParse, pKey, regArgs+2);
|
sqlite3ExprCode(pParse, pKey, regArgs+2);
|
||||||
|
|
||||||
assert( v || db->mallocFailed );
|
assert( v || db->mallocFailed );
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-nFunc, regArgs);
|
sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-nFunc, regArgs+3);
|
||||||
sqlite3VdbeChangeP5(v, nFunc);
|
sqlite3VdbeChangeP5(v, nFunc);
|
||||||
pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
|
pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
|
||||||
sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
|
sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.228 2008/01/25 15:04:50 drh Exp $
|
** $Id: insert.c,v 1.229 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
@ -218,14 +218,15 @@ static void autoIncEnd(
|
||||||
Vdbe *v = pParse->pVdbe;
|
Vdbe *v = pParse->pVdbe;
|
||||||
Db *pDb = &pParse->db->aDb[iDb];
|
Db *pDb = &pParse->db->aDb[iDb];
|
||||||
int j1;
|
int j1;
|
||||||
|
int iRec = ++pParse->nMem; /* Memory cell used for record */
|
||||||
|
|
||||||
assert( v );
|
assert( v );
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
|
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
|
||||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, memId+1);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, memId+1);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, memId-1);
|
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
|
||||||
sqlite3VdbeAddOp3(v, OP_Insert, iCur, memId-1, memId+1);
|
sqlite3VdbeAddOp3(v, OP_Insert, iCur, iRec, memId+1);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
|
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
|
||||||
sqlite3VdbeAddOp1(v, OP_Close, iCur);
|
sqlite3VdbeAddOp1(v, OP_Close, iCur);
|
||||||
}
|
}
|
||||||
|
|
10
src/legacy.c
10
src/legacy.c
|
@ -14,7 +14,7 @@
|
||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: legacy.c,v 1.22 2007/08/29 12:31:26 danielk1977 Exp $
|
** $Id: legacy.c,v 1.23 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
@ -82,6 +82,10 @@ int sqlite3_exec(
|
||||||
if( 0==nCallback ){
|
if( 0==nCallback ){
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
|
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
|
||||||
|
if( !azCols[i] ){
|
||||||
|
db->mallocFailed = 1;
|
||||||
|
goto exec_out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nCallback++;
|
nCallback++;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +93,10 @@ int sqlite3_exec(
|
||||||
azVals = &azCols[nCol];
|
azVals = &azCols[nCol];
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
azVals[i] = (char *)sqlite3_column_text(pStmt, i);
|
azVals[i] = (char *)sqlite3_column_text(pStmt, i);
|
||||||
|
if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
|
||||||
|
db->mallocFailed = 1;
|
||||||
|
goto exec_out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( xCallback(pArg, nCol, azVals, azCols) ){
|
if( xCallback(pArg, nCol, azVals, azCols) ){
|
||||||
|
|
12
src/mem1.c
12
src/mem1.c
|
@ -12,7 +12,7 @@
|
||||||
** This file contains the C functions that implement a memory
|
** This file contains the C functions that implement a memory
|
||||||
** allocation subsystem for use by SQLite.
|
** allocation subsystem for use by SQLite.
|
||||||
**
|
**
|
||||||
** $Id: mem1.c,v 1.14 2007/11/29 18:36:49 drh Exp $
|
** $Id: mem1.c,v 1.15 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -189,6 +189,16 @@ void sqlite3_free(void *pPrior){
|
||||||
sqlite3_mutex_leave(mem.mutex);
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the number of bytes allocated at p.
|
||||||
|
*/
|
||||||
|
int sqlite3MallocSize(void *p){
|
||||||
|
sqlite3_int64 *pInt;
|
||||||
|
if( !p ) return 0;
|
||||||
|
pInt = p;
|
||||||
|
return pInt[-1];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Change the size of an existing memory allocation
|
** Change the size of an existing memory allocation
|
||||||
*/
|
*/
|
||||||
|
|
26
src/mem2.c
26
src/mem2.c
|
@ -12,7 +12,7 @@
|
||||||
** This file contains the C functions that implement a memory
|
** This file contains the C functions that implement a memory
|
||||||
** allocation subsystem for use by SQLite.
|
** allocation subsystem for use by SQLite.
|
||||||
**
|
**
|
||||||
** $Id: mem2.c,v 1.19 2008/01/22 21:30:53 drh Exp $
|
** $Id: mem2.c,v 1.20 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -243,6 +243,18 @@ static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the number of bytes currently allocated at address p.
|
||||||
|
*/
|
||||||
|
int sqlite3MallocSize(void *p){
|
||||||
|
struct MemBlockHdr *pHdr;
|
||||||
|
if( !p ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pHdr = sqlite3MemsysGetHeader(p);
|
||||||
|
return pHdr->iSize;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allocate nByte bytes of memory.
|
** Allocate nByte bytes of memory.
|
||||||
*/
|
*/
|
||||||
|
@ -452,5 +464,17 @@ void sqlite3_memdebug_dump(const char *zFilename){
|
||||||
fclose(out);
|
fclose(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the number of times sqlite3_malloc() has been called.
|
||||||
|
*/
|
||||||
|
int sqlite3_memdebug_malloc_count(){
|
||||||
|
int i;
|
||||||
|
int nTotal = 0;
|
||||||
|
for(i=0; i<NCSIZE; i++){
|
||||||
|
nTotal += mem.sizeCnt[i];
|
||||||
|
}
|
||||||
|
return nTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */
|
#endif /* SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
** This version of the memory allocation subsystem is used if
|
** This version of the memory allocation subsystem is used if
|
||||||
** and only if SQLITE_MEMORY_SIZE is defined.
|
** and only if SQLITE_MEMORY_SIZE is defined.
|
||||||
**
|
**
|
||||||
** $Id: mem3.c,v 1.8 2007/12/29 13:18:22 drh Exp $
|
** $Id: mem3.c,v 1.9 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -291,7 +291,7 @@ static void memsys3OutOfMemory(int nByte){
|
||||||
** size returned omits the 8-byte header overhead. This only
|
** size returned omits the 8-byte header overhead. This only
|
||||||
** works for chunks that are currently checked out.
|
** works for chunks that are currently checked out.
|
||||||
*/
|
*/
|
||||||
static int memsys3Size(void *p){
|
int sqlite3MallocSize(void *p){
|
||||||
Mem3Block *pBlock = (Mem3Block*)p;
|
Mem3Block *pBlock = (Mem3Block*)p;
|
||||||
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
|
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
|
||||||
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
|
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
|
||||||
|
@ -556,7 +556,7 @@ void *sqlite3_realloc(void *pPrior, int nBytes){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert( mem.mutex!=0 );
|
assert( mem.mutex!=0 );
|
||||||
nOld = memsys3Size(pPrior);
|
nOld = sqlite3MallocSize(pPrior);
|
||||||
if( nBytes<=nOld && nBytes>=nOld-128 ){
|
if( nBytes<=nOld && nBytes>=nOld-128 ){
|
||||||
return pPrior;
|
return pPrior;
|
||||||
}
|
}
|
||||||
|
|
2
src/os.c
2
src/os.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
** 2005 November 29
|
** 2005 November 29
|
||||||
**
|
**
|
||||||
** The author disclaims copyright to this source code. In place of
|
** The author disclaims copyright to this source code. In place of
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.169 2008/01/22 01:48:09 drh Exp $
|
** $Id: pragma.c,v 1.170 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -894,8 +894,8 @@ void sqlite3Pragma(
|
||||||
if( cnt==0 ) continue;
|
if( cnt==0 ) continue;
|
||||||
|
|
||||||
/* Make sure sufficient number of registers have been allocated */
|
/* Make sure sufficient number of registers have been allocated */
|
||||||
if( pParse->nMem < cnt+3 ){
|
if( pParse->nMem < cnt+4 ){
|
||||||
pParse->nMem = cnt+3;
|
pParse->nMem = cnt+4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the b-tree integrity checks */
|
/* Do the b-tree integrity checks */
|
||||||
|
@ -905,7 +905,8 @@ void sqlite3Pragma(
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
||||||
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
||||||
P4_DYNAMIC);
|
P4_DYNAMIC);
|
||||||
sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 2);
|
sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
|
||||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.412 2008/02/06 23:52:37 drh Exp $
|
** $Id: select.c,v 1.413 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
@ -810,8 +810,8 @@ static void generateSortTail(
|
||||||
int j1;
|
int j1;
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regRow);
|
j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regRow);
|
||||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRow, &p->affinity, 1);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRow);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.660 2008/02/12 16:52:14 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.661 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
|
@ -1683,6 +1683,7 @@ char *sqlite3DbStrDup(sqlite3*,const char*);
|
||||||
char *sqlite3DbStrNDup(sqlite3*,const char*, int);
|
char *sqlite3DbStrNDup(sqlite3*,const char*, int);
|
||||||
void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
|
void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
|
||||||
void *sqlite3DbRealloc(sqlite3 *, void *, int);
|
void *sqlite3DbRealloc(sqlite3 *, void *, int);
|
||||||
|
int sqlite3MallocSize(void *);
|
||||||
|
|
||||||
char *sqlite3MPrintf(sqlite3*,const char*, ...);
|
char *sqlite3MPrintf(sqlite3*,const char*, ...);
|
||||||
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
** A TCL Interface to SQLite. Append this file to sqlite3.c and
|
** A TCL Interface to SQLite. Append this file to sqlite3.c and
|
||||||
** compile the whole thing to build a TCL-enabled version of SQLite.
|
** compile the whole thing to build a TCL-enabled version of SQLite.
|
||||||
**
|
**
|
||||||
** $Id: tclsqlite.c,v 1.207 2007/11/14 06:48:48 danielk1977 Exp $
|
** $Id: tclsqlite.c,v 1.208 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -1702,7 +1702,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||||
switch( sqlite3_column_type(pStmt, i) ){
|
switch( sqlite3_column_type(pStmt, i) ){
|
||||||
case SQLITE_BLOB: {
|
case SQLITE_BLOB: {
|
||||||
int bytes = sqlite3_column_bytes(pStmt, i);
|
int bytes = sqlite3_column_bytes(pStmt, i);
|
||||||
pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);
|
char *zBlob = sqlite3_column_blob(pStmt, i);
|
||||||
|
if( !zBlob ) bytes = 0;
|
||||||
|
pVal = Tcl_NewByteArrayObj(zBlob, bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLITE_INTEGER: {
|
case SQLITE_INTEGER: {
|
||||||
|
|
14
src/test1.c
14
src/test1.c
|
@ -13,7 +13,7 @@
|
||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.287 2008/01/23 14:51:50 drh Exp $
|
** $Id: test1.c,v 1.288 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
|
@ -954,16 +954,17 @@ static int test_create_function(
|
||||||
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
|
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
|
||||||
** because it is not tested anywhere else. */
|
** because it is not tested anywhere else. */
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
void *zUtf16;
|
||||||
sqlite3_value *pVal;
|
sqlite3_value *pVal;
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
pVal = sqlite3ValueNew(db);
|
pVal = sqlite3ValueNew(db);
|
||||||
sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
|
||||||
|
zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3_create_function16(db,
|
rc = sqlite3_create_function16(db, zUtf16,
|
||||||
sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
|
||||||
1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
|
|
||||||
}
|
}
|
||||||
sqlite3ValueFree(pVal);
|
sqlite3ValueFree(pVal);
|
||||||
sqlite3_mutex_leave(db->mutex);
|
sqlite3_mutex_leave(db->mutex);
|
||||||
|
@ -2152,6 +2153,7 @@ static int test_collate(
|
||||||
rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
|
rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
|
||||||
(void *)SQLITE_UTF8, val?test_collate_func:0);
|
(void *)SQLITE_UTF8, val?test_collate_func:0);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
void *zUtf16;
|
||||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
|
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
|
||||||
rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
|
rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
|
||||||
(void *)SQLITE_UTF16LE, val?test_collate_func:0);
|
(void *)SQLITE_UTF16LE, val?test_collate_func:0);
|
||||||
|
@ -2165,11 +2167,11 @@ static int test_collate(
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
pVal = sqlite3ValueNew(db);
|
pVal = sqlite3ValueNew(db);
|
||||||
sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
|
||||||
|
zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3_create_collation16(db,
|
rc = sqlite3_create_collation16(db, zUtf16, SQLITE_UTF16BE,
|
||||||
sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE,
|
|
||||||
(void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
(void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
||||||
}
|
}
|
||||||
sqlite3ValueFree(pVal);
|
sqlite3ValueFree(pVal);
|
||||||
|
|
21
src/test8.c
21
src/test8.c
|
@ -13,7 +13,7 @@
|
||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test8.c,v 1.59 2008/01/22 21:30:53 drh Exp $
|
** $Id: test8.c,v 1.60 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
|
@ -160,7 +160,12 @@ static int getColumnNames(
|
||||||
*/
|
*/
|
||||||
nBytes = sizeof(char *) * nCol;
|
nBytes = sizeof(char *) * nCol;
|
||||||
for(ii=0; ii<nCol; ii++){
|
for(ii=0; ii<nCol; ii++){
|
||||||
nBytes += (strlen(sqlite3_column_name(pStmt, ii)) + 1);
|
const char *zName = sqlite3_column_name(pStmt, ii);
|
||||||
|
if( !zName ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
nBytes += strlen(zName)+1;
|
||||||
}
|
}
|
||||||
aCol = (char **)sqlite3MallocZero(nBytes);
|
aCol = (char **)sqlite3MallocZero(nBytes);
|
||||||
if( !aCol ){
|
if( !aCol ){
|
||||||
|
@ -952,11 +957,15 @@ int echoUpdate(
|
||||||
if( bindArgOne ){
|
if( bindArgOne ){
|
||||||
sqlite3_bind_value(pStmt, 1, apData[1]);
|
sqlite3_bind_value(pStmt, 1, apData[1]);
|
||||||
}
|
}
|
||||||
for(i=2; i<nData; i++){
|
for(i=2; i<nData && rc==SQLITE_OK; i++){
|
||||||
if( apData[i] ) sqlite3_bind_value(pStmt, i, apData[i]);
|
if( apData[i] ) rc = sqlite3_bind_value(pStmt, i, apData[i]);
|
||||||
|
}
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
sqlite3_step(pStmt);
|
||||||
|
rc = sqlite3_finalize(pStmt);
|
||||||
|
}else{
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
}
|
}
|
||||||
sqlite3_step(pStmt);
|
|
||||||
rc = sqlite3_finalize(pStmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pRowid && rc==SQLITE_OK ){
|
if( pRowid && rc==SQLITE_OK ){
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
** This file contains code used to implement test interfaces to the
|
** This file contains code used to implement test interfaces to the
|
||||||
** memory allocation subsystem.
|
** memory allocation subsystem.
|
||||||
**
|
**
|
||||||
** $Id: test_malloc.c,v 1.11 2008/01/31 14:43:24 drh Exp $
|
** $Id: test_malloc.c,v 1.12 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
|
@ -343,6 +343,32 @@ static int test_memdebug_dump(
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Usage: sqlite3_memdebug_malloc_count
|
||||||
|
**
|
||||||
|
** Return the total number of times malloc() has been called.
|
||||||
|
*/
|
||||||
|
static int test_memdebug_malloc_count(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
int nMalloc = -1;
|
||||||
|
if( objc!=1 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
#if defined(SQLITE_MEMDEBUG)
|
||||||
|
{
|
||||||
|
extern int sqlite3_memdebug_malloc_count();
|
||||||
|
nMalloc = sqlite3_memdebug_malloc_count();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Tcl_SetObjResult(interp, Tcl_NewIntObj(nMalloc));
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS?
|
** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS?
|
||||||
|
@ -504,6 +530,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
|
||||||
{ "sqlite3_memdebug_fail", test_memdebug_fail },
|
{ "sqlite3_memdebug_fail", test_memdebug_fail },
|
||||||
{ "sqlite3_memdebug_pending", test_memdebug_pending },
|
{ "sqlite3_memdebug_pending", test_memdebug_pending },
|
||||||
{ "sqlite3_memdebug_settitle", test_memdebug_settitle },
|
{ "sqlite3_memdebug_settitle", test_memdebug_settitle },
|
||||||
|
{ "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count },
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||||
|
|
54
src/utf.c
54
src/utf.c
|
@ -12,7 +12,7 @@
|
||||||
** This file contains routines used to translate between UTF-8,
|
** This file contains routines used to translate between UTF-8,
|
||||||
** UTF-16, UTF-16BE, and UTF-16LE.
|
** UTF-16, UTF-16BE, and UTF-16LE.
|
||||||
**
|
**
|
||||||
** $Id: utf.c,v 1.59 2007/10/03 08:46:45 danielk1977 Exp $
|
** $Id: utf.c,v 1.60 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** Notes on UTF-8:
|
** Notes on UTF-8:
|
||||||
**
|
**
|
||||||
|
@ -188,7 +188,6 @@ int sqlite3Utf8Read(
|
||||||
** encoding, or if *pMem does not contain a string value.
|
** encoding, or if *pMem does not contain a string value.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
||||||
unsigned char zShort[NBFS]; /* Temporary short output buffer */
|
|
||||||
int len; /* Maximum length of output string in bytes */
|
int len; /* Maximum length of output string in bytes */
|
||||||
unsigned char *zOut; /* Output buffer */
|
unsigned char *zOut; /* Output buffer */
|
||||||
unsigned char *zIn; /* Input iterator */
|
unsigned char *zIn; /* Input iterator */
|
||||||
|
@ -254,19 +253,14 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
||||||
/* Set zIn to point at the start of the input buffer and zTerm to point 1
|
/* Set zIn to point at the start of the input buffer and zTerm to point 1
|
||||||
** byte past the end.
|
** byte past the end.
|
||||||
**
|
**
|
||||||
** Variable zOut is set to point at the output buffer. This may be space
|
** Variable zOut is set to point at the output buffer, space obtained
|
||||||
** obtained from sqlite3_malloc(), or Mem.zShort, if it large enough and
|
** from sqlite3_malloc().
|
||||||
** not in use, or the zShort array on the stack (see above).
|
|
||||||
*/
|
*/
|
||||||
zIn = (u8*)pMem->z;
|
zIn = (u8*)pMem->z;
|
||||||
zTerm = &zIn[pMem->n];
|
zTerm = &zIn[pMem->n];
|
||||||
if( len>NBFS ){
|
zOut = sqlite3DbMallocRaw(pMem->db, len);
|
||||||
zOut = sqlite3DbMallocRaw(pMem->db, len);
|
if( !zOut ){
|
||||||
if( !zOut ){
|
return SQLITE_NOMEM;
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
zOut = zShort;
|
|
||||||
}
|
}
|
||||||
z = zOut;
|
z = zOut;
|
||||||
|
|
||||||
|
@ -308,15 +302,9 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
||||||
assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
|
assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
|
||||||
|
|
||||||
sqlite3VdbeMemRelease(pMem);
|
sqlite3VdbeMemRelease(pMem);
|
||||||
pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
|
pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
|
||||||
pMem->enc = desiredEnc;
|
pMem->enc = desiredEnc;
|
||||||
if( zOut==zShort ){
|
pMem->flags |= (MEM_Term|MEM_Dyn);
|
||||||
memcpy(pMem->zShort, zOut, len);
|
|
||||||
zOut = (u8*)pMem->zShort;
|
|
||||||
pMem->flags |= (MEM_Term|MEM_Short);
|
|
||||||
}else{
|
|
||||||
pMem->flags |= (MEM_Term|MEM_Dyn);
|
|
||||||
}
|
|
||||||
pMem->z = (char*)zOut;
|
pMem->z = (char*)zOut;
|
||||||
|
|
||||||
translate_out:
|
translate_out:
|
||||||
|
@ -355,24 +343,14 @@ int sqlite3VdbeMemHandleBom(Mem *pMem){
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bom ){
|
if( bom ){
|
||||||
/* This function is called as soon as a string is stored in a Mem*,
|
rc = sqlite3VdbeMemMakeWriteable(pMem);
|
||||||
** from within sqlite3VdbeMemSetStr(). At that point it is not possible
|
if( rc==SQLITE_OK ){
|
||||||
** for the string to be stored in Mem.zShort, or for it to be stored
|
pMem->n -= 2;
|
||||||
** in dynamic memory with no destructor.
|
memmove(pMem->z, &pMem->z[2], pMem->n);
|
||||||
*/
|
pMem->z[pMem->n] = '\0';
|
||||||
assert( !(pMem->flags&MEM_Short) );
|
pMem->z[pMem->n+1] = '\0';
|
||||||
assert( !(pMem->flags&MEM_Dyn) || pMem->xDel );
|
pMem->flags |= MEM_Term;
|
||||||
if( pMem->flags & MEM_Dyn ){
|
pMem->enc = bom;
|
||||||
void (*xDel)(void*) = pMem->xDel;
|
|
||||||
char *z = pMem->z;
|
|
||||||
pMem->z = 0;
|
|
||||||
pMem->xDel = 0;
|
|
||||||
rc = sqlite3VdbeMemSetStr(pMem, &z[2], pMem->n-2, bom,
|
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
xDel(z);
|
|
||||||
}else{
|
|
||||||
rc = sqlite3VdbeMemSetStr(pMem, &pMem->z[2], pMem->n-2, bom,
|
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
|
227
src/vdbe.c
227
src/vdbe.c
|
@ -43,7 +43,7 @@
|
||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.708 2008/02/06 14:11:35 drh Exp $
|
** $Id: vdbe.c,v 1.709 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -236,9 +236,8 @@ static void applyNumericAffinity(Mem *pRec){
|
||||||
i64 value;
|
i64 value;
|
||||||
sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
|
sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
|
||||||
if( !realnum && sqlite3Atoi64(pRec->z, &value) ){
|
if( !realnum && sqlite3Atoi64(pRec->z, &value) ){
|
||||||
sqlite3VdbeMemRelease(pRec);
|
|
||||||
pRec->u.i = value;
|
pRec->u.i = value;
|
||||||
pRec->flags = MEM_Int;
|
MemSetTypeFlag(pRec, MEM_Int);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeMemRealify(pRec);
|
sqlite3VdbeMemRealify(pRec);
|
||||||
}
|
}
|
||||||
|
@ -1000,14 +999,19 @@ case OP_ResultRow: {
|
||||||
** Add the text in register P1 onto the end of the text in
|
** Add the text in register P1 onto the end of the text in
|
||||||
** register P2 and store the result in register P3.
|
** register P2 and store the result in register P3.
|
||||||
** If either the P1 or P2 text are NULL then store NULL in P3.
|
** If either the P1 or P2 text are NULL then store NULL in P3.
|
||||||
|
**
|
||||||
|
** P3 = P2 || P1
|
||||||
|
**
|
||||||
|
** It is illegal for P1 and P3 to be the same register. Sometimes,
|
||||||
|
** if P3 is the same register as P2, the implementation is able
|
||||||
|
** to avoid a memcpy().
|
||||||
*/
|
*/
|
||||||
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
|
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
|
||||||
char *zNew;
|
|
||||||
i64 nByte;
|
i64 nByte;
|
||||||
|
|
||||||
|
assert( pIn1!=pOut );
|
||||||
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
|
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
|
||||||
Release(pOut);
|
sqlite3VdbeMemSetNull(pOut);
|
||||||
pOut->flags = MEM_Null;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ExpandBlob(pIn1);
|
ExpandBlob(pIn1);
|
||||||
|
@ -1018,20 +1022,19 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
|
||||||
if( nByte>SQLITE_MAX_LENGTH ){
|
if( nByte>SQLITE_MAX_LENGTH ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
zNew = sqlite3DbMallocRaw(db, nByte+2);
|
MemSetTypeFlag(pOut, MEM_Str);
|
||||||
if( zNew==0 ){
|
if( sqlite3VdbeMemGrow(pOut, nByte+2, pOut==pIn2) ){
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
}
|
}
|
||||||
memcpy(zNew, pIn2->z, pIn2->n);
|
if( pOut!=pIn2 ){
|
||||||
memcpy(&zNew[pIn2->n], pIn1->z, pIn1->n);
|
memcpy(pOut->z, pIn2->z, pIn2->n);
|
||||||
zNew[nByte] = 0;
|
}
|
||||||
zNew[nByte+1] = 0;
|
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
|
||||||
Release(pOut);
|
pOut->z[nByte] = 0;
|
||||||
|
pOut->z[nByte+1] = 0;
|
||||||
|
pOut->flags |= MEM_Term;
|
||||||
pOut->n = nByte;
|
pOut->n = nByte;
|
||||||
pOut->flags = MEM_Str|MEM_Dyn|MEM_Term;
|
|
||||||
pOut->xDel = 0;
|
|
||||||
pOut->enc = encoding;
|
pOut->enc = encoding;
|
||||||
pOut->z = zNew;
|
|
||||||
UPDATE_MAX_BLOBSIZE(pOut);
|
UPDATE_MAX_BLOBSIZE(pOut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1105,9 +1108,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Release(pOut);
|
|
||||||
pOut->u.i = b;
|
pOut->u.i = b;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
}else{
|
}else{
|
||||||
double a, b;
|
double a, b;
|
||||||
a = sqlite3VdbeRealValue(pIn1);
|
a = sqlite3VdbeRealValue(pIn1);
|
||||||
|
@ -1133,9 +1135,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
||||||
if( sqlite3_isnan(b) ){
|
if( sqlite3_isnan(b) ){
|
||||||
goto arithmetic_result_is_null;
|
goto arithmetic_result_is_null;
|
||||||
}
|
}
|
||||||
Release(pOut);
|
|
||||||
pOut->r = b;
|
pOut->r = b;
|
||||||
pOut->flags = MEM_Real;
|
MemSetTypeFlag(pOut, MEM_Real);
|
||||||
if( (flags & MEM_Real)==0 ){
|
if( (flags & MEM_Real)==0 ){
|
||||||
sqlite3VdbeIntegerAffinity(pOut);
|
sqlite3VdbeIntegerAffinity(pOut);
|
||||||
}
|
}
|
||||||
|
@ -1168,6 +1169,7 @@ case OP_CollSeq: {
|
||||||
** Invoke a user function (P4 is a pointer to a Function structure that
|
** Invoke a user function (P4 is a pointer to a Function structure that
|
||||||
** defines the function) with P5 arguments taken from register P2 and
|
** defines the function) with P5 arguments taken from register P2 and
|
||||||
** successors. The result of the function is stored in register P3.
|
** successors. The result of the function is stored in register P3.
|
||||||
|
** Register P3 must not be one of the function inputs.
|
||||||
**
|
**
|
||||||
** P1 is a 32-bit bitmask indicating whether or not each argument to the
|
** P1 is a 32-bit bitmask indicating whether or not each argument to the
|
||||||
** function was determined to be constant at compile time. If the first
|
** function was determined to be constant at compile time. If the first
|
||||||
|
@ -1189,6 +1191,7 @@ case OP_Function: {
|
||||||
assert( apVal || n==0 );
|
assert( apVal || n==0 );
|
||||||
|
|
||||||
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) );
|
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) );
|
||||||
|
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
|
||||||
pArg = &p->aMem[pOp->p2];
|
pArg = &p->aMem[pOp->p2];
|
||||||
for(i=0; i<n; i++, pArg++){
|
for(i=0; i<n; i++, pArg++){
|
||||||
apVal[i] = pArg;
|
apVal[i] = pArg;
|
||||||
|
@ -1205,10 +1208,18 @@ case OP_Function: {
|
||||||
ctx.pFunc = ctx.pVdbeFunc->pFunc;
|
ctx.pFunc = ctx.pVdbeFunc->pFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
||||||
|
pOut = &p->aMem[pOp->p3];
|
||||||
ctx.s.flags = MEM_Null;
|
ctx.s.flags = MEM_Null;
|
||||||
ctx.s.z = 0;
|
ctx.s.db = 0;
|
||||||
ctx.s.xDel = 0;
|
|
||||||
ctx.s.db = db;
|
/* The output cell may already have a buffer allocated. Move
|
||||||
|
** the pointer to ctx.s so in case the user-function can use
|
||||||
|
** the already allocated buffer instead of allocating a new one.
|
||||||
|
*/
|
||||||
|
sqlite3VdbeMemMove(&ctx.s, pOut);
|
||||||
|
MemSetTypeFlag(&ctx.s, MEM_Null);
|
||||||
|
|
||||||
ctx.isError = 0;
|
ctx.isError = 0;
|
||||||
if( ctx.pFunc->needCollSeq ){
|
if( ctx.pFunc->needCollSeq ){
|
||||||
assert( pOp>p->aOp );
|
assert( pOp>p->aOp );
|
||||||
|
@ -1250,8 +1261,6 @@ case OP_Function: {
|
||||||
|
|
||||||
/* Copy the result of the function into register P3 */
|
/* Copy the result of the function into register P3 */
|
||||||
sqlite3VdbeChangeEncoding(&ctx.s, encoding);
|
sqlite3VdbeChangeEncoding(&ctx.s, encoding);
|
||||||
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
|
||||||
pOut = &p->aMem[pOp->p3];
|
|
||||||
sqlite3VdbeMemMove(pOut, &ctx.s);
|
sqlite3VdbeMemMove(pOut, &ctx.s);
|
||||||
if( sqlite3VdbeMemTooBig(pOut) ){
|
if( sqlite3VdbeMemTooBig(pOut) ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
|
@ -1306,9 +1315,8 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
|
||||||
default: assert( pOp->opcode==OP_ShiftRight );
|
default: assert( pOp->opcode==OP_ShiftRight );
|
||||||
a >>= b; break;
|
a >>= b; break;
|
||||||
}
|
}
|
||||||
Release(pOut);
|
|
||||||
pOut->u.i = a;
|
pOut->u.i = a;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1350,9 +1358,8 @@ case OP_ForceInt: { /* jump, in1 */
|
||||||
if( pIn1->r>(double)v ) v++;
|
if( pIn1->r>(double)v ) v++;
|
||||||
if( pOp->p3 && pIn1->r==(double)v ) v++;
|
if( pOp->p3 && pIn1->r==(double)v ) v++;
|
||||||
}
|
}
|
||||||
Release(pIn1);
|
|
||||||
pIn1->u.i = v;
|
pIn1->u.i = v;
|
||||||
pIn1->flags = MEM_Int;
|
MemSetTypeFlag(pIn1, MEM_Int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,8 +1380,7 @@ case OP_MustBeInt: { /* jump, in1 */
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Release(pIn1);
|
MemSetTypeFlag(pIn1, MEM_Int);
|
||||||
pIn1->flags = MEM_Int;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1411,7 +1417,7 @@ case OP_ToText: { /* same as TK_TO_TEXT, in1 */
|
||||||
pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
|
pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
|
||||||
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
|
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
|
||||||
rc = ExpandBlob(pIn1);
|
rc = ExpandBlob(pIn1);
|
||||||
assert( pIn1->flags & MEM_Str );
|
assert( pIn1->flags & MEM_Str || db->mallocFailed );
|
||||||
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
|
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
|
||||||
UPDATE_MAX_BLOBSIZE(pIn1);
|
UPDATE_MAX_BLOBSIZE(pIn1);
|
||||||
break;
|
break;
|
||||||
|
@ -1430,10 +1436,9 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
|
||||||
if( pIn1->flags & MEM_Null ) break;
|
if( pIn1->flags & MEM_Null ) break;
|
||||||
if( (pIn1->flags & MEM_Blob)==0 ){
|
if( (pIn1->flags & MEM_Blob)==0 ){
|
||||||
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
|
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
|
||||||
assert( pIn1->flags & MEM_Str );
|
assert( pIn1->flags & MEM_Str || db->mallocFailed );
|
||||||
pIn1->flags |= MEM_Blob;
|
|
||||||
}
|
}
|
||||||
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Str);
|
MemSetTypeFlag(pIn1, MEM_Blob);
|
||||||
UPDATE_MAX_BLOBSIZE(pIn1);
|
UPDATE_MAX_BLOBSIZE(pIn1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1591,8 +1596,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||||
*/
|
*/
|
||||||
if( pOp->p5 & SQLITE_STOREP2 ){
|
if( pOp->p5 & SQLITE_STOREP2 ){
|
||||||
pOut = &p->aMem[pOp->p2];
|
pOut = &p->aMem[pOp->p2];
|
||||||
Release(pOut);
|
MemSetTypeFlag(pOut, MEM_Null);
|
||||||
pOut->flags = MEM_Null;
|
|
||||||
REGISTER_TRACE(pOp->p2, pOut);
|
REGISTER_TRACE(pOp->p2, pOut);
|
||||||
}else if( pOp->p5 & SQLITE_JUMPIFNULL ){
|
}else if( pOp->p5 & SQLITE_JUMPIFNULL ){
|
||||||
pc = pOp->p2-1;
|
pc = pOp->p2-1;
|
||||||
|
@ -1622,8 +1626,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||||
|
|
||||||
if( pOp->p5 & SQLITE_STOREP2 ){
|
if( pOp->p5 & SQLITE_STOREP2 ){
|
||||||
pOut = &p->aMem[pOp->p2];
|
pOut = &p->aMem[pOp->p2];
|
||||||
Release(pOut);
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->flags = MEM_Int;
|
|
||||||
pOut->u.i = res;
|
pOut->u.i = res;
|
||||||
REGISTER_TRACE(pOp->p2, pOut);
|
REGISTER_TRACE(pOp->p2, pOut);
|
||||||
}else if( res ){
|
}else if( res ){
|
||||||
|
@ -1671,12 +1674,11 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||||
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
|
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
|
||||||
v1 = or_logic[v1*3+v2];
|
v1 = or_logic[v1*3+v2];
|
||||||
}
|
}
|
||||||
Release(pOut);
|
|
||||||
if( v1==2 ){
|
if( v1==2 ){
|
||||||
pOut->flags = MEM_Null;
|
MemSetTypeFlag(pOut, MEM_Null);
|
||||||
}else{
|
}else{
|
||||||
pOut->u.i = v1;
|
pOut->u.i = v1;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1691,7 +1693,7 @@ case OP_Not: { /* same as TK_NOT, in1 */
|
||||||
if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
||||||
sqlite3VdbeMemIntegerify(pIn1);
|
sqlite3VdbeMemIntegerify(pIn1);
|
||||||
pIn1->u.i = !pIn1->u.i;
|
pIn1->u.i = !pIn1->u.i;
|
||||||
assert( pIn1->flags==MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1705,7 +1707,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1 */
|
||||||
if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
||||||
sqlite3VdbeMemIntegerify(pIn1);
|
sqlite3VdbeMemIntegerify(pIn1);
|
||||||
pIn1->u.i = ~pIn1->u.i;
|
pIn1->u.i = ~pIn1->u.i;
|
||||||
assert( pIn1->flags==MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1823,10 +1825,11 @@ case OP_Column: {
|
||||||
Mem sMem; /* For storing the record being decoded */
|
Mem sMem; /* For storing the record being decoded */
|
||||||
|
|
||||||
sMem.flags = 0;
|
sMem.flags = 0;
|
||||||
|
sMem.db = 0;
|
||||||
assert( p1<p->nCursor );
|
assert( p1<p->nCursor );
|
||||||
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
||||||
pDest = &p->aMem[pOp->p3];
|
pDest = &p->aMem[pOp->p3];
|
||||||
sqlite3VdbeMemSetNull(pDest);
|
MemSetTypeFlag(pDest, MEM_Null);
|
||||||
|
|
||||||
/* This block sets the variable payloadSize to be the total number of
|
/* This block sets the variable payloadSize to be the total number of
|
||||||
** bytes in the record.
|
** bytes in the record.
|
||||||
|
@ -1877,7 +1880,7 @@ case OP_Column: {
|
||||||
|
|
||||||
/* If payloadSize is 0, then just store a NULL */
|
/* If payloadSize is 0, then just store a NULL */
|
||||||
if( payloadSize==0 ){
|
if( payloadSize==0 ){
|
||||||
assert( pDest->flags==MEM_Null );
|
assert( pDest->flags&MEM_Null );
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
if( payloadSize>SQLITE_MAX_LENGTH ){
|
if( payloadSize>SQLITE_MAX_LENGTH ){
|
||||||
|
@ -1943,6 +1946,8 @@ case OP_Column: {
|
||||||
** acquire the complete header text.
|
** acquire the complete header text.
|
||||||
*/
|
*/
|
||||||
if( !zRec && avail<offset ){
|
if( !zRec && avail<offset ){
|
||||||
|
sMem.flags = 0;
|
||||||
|
sMem.db = 0;
|
||||||
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
|
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
|
@ -1994,22 +1999,30 @@ case OP_Column: {
|
||||||
if( aOffset[p2] ){
|
if( aOffset[p2] ){
|
||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
if( zRec ){
|
if( zRec ){
|
||||||
zData = &zRec[aOffset[p2]];
|
if( pDest->flags&MEM_Dyn ){
|
||||||
|
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem);
|
||||||
|
sMem.db = db;
|
||||||
|
sqlite3VdbeMemCopy(pDest, &sMem);
|
||||||
|
assert( !(sMem.flags&MEM_Dyn) );
|
||||||
|
}else{
|
||||||
|
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
len = sqlite3VdbeSerialTypeLen(aType[p2]);
|
len = sqlite3VdbeSerialTypeLen(aType[p2]);
|
||||||
|
sqlite3VdbeMemMove(&sMem, pDest);
|
||||||
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
|
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
zData = sMem.z;
|
zData = sMem.z;
|
||||||
|
sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest);
|
||||||
}
|
}
|
||||||
sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest);
|
|
||||||
pDest->enc = encoding;
|
pDest->enc = encoding;
|
||||||
}else{
|
}else{
|
||||||
if( pOp->p4type==P4_MEM ){
|
if( pOp->p4type==P4_MEM ){
|
||||||
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
|
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
|
||||||
}else{
|
}else{
|
||||||
assert( pDest->flags==MEM_Null );
|
assert( pDest->flags&MEM_Null );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2019,16 +2032,14 @@ case OP_Column: {
|
||||||
** This prevents a memory copy.
|
** This prevents a memory copy.
|
||||||
*/
|
*/
|
||||||
if( (sMem.flags & MEM_Dyn)!=0 ){
|
if( (sMem.flags & MEM_Dyn)!=0 ){
|
||||||
assert( pDest->flags & MEM_Ephem );
|
assert( !sMem.xDel );
|
||||||
assert( pDest->flags & (MEM_Str|MEM_Blob) );
|
assert( !(pDest->flags & MEM_Dyn) );
|
||||||
assert( pDest->z==sMem.z );
|
assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
|
||||||
assert( sMem.flags & MEM_Term );
|
pDest->flags &= ~(MEM_Ephem|MEM_Static);
|
||||||
pDest->flags &= ~MEM_Ephem;
|
|
||||||
pDest->flags |= MEM_Dyn|MEM_Term;
|
pDest->flags |= MEM_Dyn|MEM_Term;
|
||||||
|
pDest->z = sMem.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pDest->z might be pointing to sMem.zShort[]. Fix that so that we
|
|
||||||
** can abandon sMem */
|
|
||||||
rc = sqlite3VdbeMemMakeWriteable(pDest);
|
rc = sqlite3VdbeMemMakeWriteable(pDest);
|
||||||
|
|
||||||
op_column_out:
|
op_column_out:
|
||||||
|
@ -2086,7 +2097,6 @@ case OP_MakeRecord: {
|
||||||
char *zAffinity; /* The affinity string for the record */
|
char *zAffinity; /* The affinity string for the record */
|
||||||
int file_format; /* File format to use for encoding */
|
int file_format; /* File format to use for encoding */
|
||||||
int i; /* Space used in zNewRecord[] */
|
int i; /* Space used in zNewRecord[] */
|
||||||
char zTemp[NBFS]; /* Space to hold small records */
|
|
||||||
|
|
||||||
nField = pOp->p1;
|
nField = pOp->p1;
|
||||||
zAffinity = pOp->p4.z;
|
zAffinity = pOp->p4.z;
|
||||||
|
@ -2130,15 +2140,17 @@ case OP_MakeRecord: {
|
||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate space for the new record. */
|
/* Make sure the output register has a buffer large enough to store
|
||||||
if( nByte>sizeof(zTemp) ){
|
** the new record. The output register (pOp->p3) is not allowed to
|
||||||
zNewRecord = sqlite3DbMallocRaw(db, nByte);
|
** be one of the input registers (because the following call to
|
||||||
if( !zNewRecord ){
|
** sqlite3VdbeMemGrow() could clobber the value before it is used).
|
||||||
goto no_mem;
|
*/
|
||||||
}
|
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
|
||||||
}else{
|
pOut = &p->aMem[pOp->p3];
|
||||||
zNewRecord = (u8*)zTemp;
|
if( sqlite3VdbeMemGrow(pOut, nByte, 0) ){
|
||||||
|
goto no_mem;
|
||||||
}
|
}
|
||||||
|
zNewRecord = (u8 *)pOut->z;
|
||||||
|
|
||||||
/* Write the record */
|
/* Write the record */
|
||||||
i = sqlite3PutVarint(zNewRecord, nHdr);
|
i = sqlite3PutVarint(zNewRecord, nHdr);
|
||||||
|
@ -2152,20 +2164,9 @@ case OP_MakeRecord: {
|
||||||
assert( i==nByte );
|
assert( i==nByte );
|
||||||
|
|
||||||
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
||||||
pOut = &p->aMem[pOp->p3];
|
|
||||||
Release(pOut);
|
|
||||||
pOut->n = nByte;
|
pOut->n = nByte;
|
||||||
if( nByte<=sizeof(zTemp) ){
|
pOut->flags = MEM_Blob | MEM_Dyn;
|
||||||
assert( zNewRecord==(unsigned char *)zTemp );
|
pOut->xDel = 0;
|
||||||
pOut->z = pOut->zShort;
|
|
||||||
memcpy(pOut->zShort, zTemp, nByte);
|
|
||||||
pOut->flags = MEM_Blob | MEM_Short;
|
|
||||||
}else{
|
|
||||||
assert( zNewRecord!=(unsigned char *)zTemp );
|
|
||||||
pOut->z = (char*)zNewRecord;
|
|
||||||
pOut->flags = MEM_Blob | MEM_Dyn;
|
|
||||||
pOut->xDel = 0;
|
|
||||||
}
|
|
||||||
if( nZero ){
|
if( nZero ){
|
||||||
pOut->u.i = nZero;
|
pOut->u.i = nZero;
|
||||||
pOut->flags |= MEM_Zero;
|
pOut->flags |= MEM_Zero;
|
||||||
|
@ -2343,7 +2344,7 @@ case OP_ReadCookie: { /* out2-prerelease */
|
||||||
*/
|
*/
|
||||||
rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta);
|
rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta);
|
||||||
pOut->u.i = iMeta;
|
pOut->u.i = iMeta;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2896,7 +2897,6 @@ case OP_IsUnique: { /* jump, in3 */
|
||||||
pK = &p->aMem[pOp->p4.i];
|
pK = &p->aMem[pOp->p4.i];
|
||||||
sqlite3VdbeMemIntegerify(pIn3);
|
sqlite3VdbeMemIntegerify(pIn3);
|
||||||
R = pIn3->u.i;
|
R = pIn3->u.i;
|
||||||
assert( (pIn3->flags & MEM_Dyn)==0 );
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pCx = p->apCsr[i];
|
pCx = p->apCsr[i];
|
||||||
assert( pCx!=0 );
|
assert( pCx!=0 );
|
||||||
|
@ -2960,7 +2960,7 @@ case OP_IsUnique: { /* jump, in3 */
|
||||||
** a UNIQUE constraint.)
|
** a UNIQUE constraint.)
|
||||||
*/
|
*/
|
||||||
pIn3->u.i = v;
|
pIn3->u.i = v;
|
||||||
assert( pIn3->flags==MEM_Int );
|
assert( pIn3->flags&MEM_Int );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3021,7 +3021,7 @@ case OP_Sequence: { /* out2-prerelease */
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
assert( p->apCsr[i]!=0 );
|
assert( p->apCsr[i]!=0 );
|
||||||
pOut->u.i = p->apCsr[i]->seqCount++;
|
pOut->u.i = p->apCsr[i]->seqCount++;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3174,7 +3174,7 @@ case OP_NewRowid: { /* out2-prerelease */
|
||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
}
|
}
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->u.i = v;
|
pOut->u.i = v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3368,13 +3368,15 @@ case OP_ResetCount: {
|
||||||
** If the P1 cursor must be pointing to a valid row (not a NULL row)
|
** If the P1 cursor must be pointing to a valid row (not a NULL row)
|
||||||
** of a real table, not a pseudo-table.
|
** of a real table, not a pseudo-table.
|
||||||
*/
|
*/
|
||||||
case OP_RowKey: /* out2-prerelease */
|
case OP_RowKey:
|
||||||
case OP_RowData: { /* out2-prerelease */
|
case OP_RowData: {
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
u32 n;
|
u32 n;
|
||||||
|
|
||||||
|
pOut = &p->aMem[pOp->p2];
|
||||||
|
|
||||||
/* Note that RowKey and RowData are really exactly the same instruction */
|
/* Note that RowKey and RowData are really exactly the same instruction */
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
@ -3401,17 +3403,11 @@ case OP_RowData: { /* out2-prerelease */
|
||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pOut->n = n;
|
if( sqlite3VdbeMemGrow(pOut, n, 0) ){
|
||||||
if( n<=NBFS ){
|
goto no_mem;
|
||||||
pOut->flags = MEM_Blob | MEM_Short;
|
|
||||||
pOut->z = pOut->zShort;
|
|
||||||
}else{
|
|
||||||
char *z = sqlite3_malloc( n );
|
|
||||||
if( z==0 ) goto no_mem;
|
|
||||||
pOut->flags = MEM_Blob | MEM_Dyn;
|
|
||||||
pOut->xDel = 0;
|
|
||||||
pOut->z = z;
|
|
||||||
}
|
}
|
||||||
|
pOut->n = n;
|
||||||
|
MemSetTypeFlag(pOut, MEM_Blob);
|
||||||
if( pC->isIndex ){
|
if( pC->isIndex ){
|
||||||
rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
|
rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
|
||||||
}else{
|
}else{
|
||||||
|
@ -3450,7 +3446,7 @@ case OP_Rowid: { /* out2-prerelease */
|
||||||
v = keyToInt(v);
|
v = keyToInt(v);
|
||||||
}
|
}
|
||||||
pOut->u.i = v;
|
pOut->u.i = v;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3642,8 +3638,9 @@ case OP_IdxInsert: { /* in2 */
|
||||||
|
|
||||||
/* Opcode: IdxDelete P1 P2 * * *
|
/* Opcode: IdxDelete P1 P2 * * *
|
||||||
**
|
**
|
||||||
** The content of register P2 is an index key built using the either the
|
** The content of register P2 is an index key built using the
|
||||||
** MakeIdxRec opcode. Removes that entry from the index.
|
** MakeIdxRec opcode. This opcode removes that entry from the
|
||||||
|
** index opened by cursor P1.
|
||||||
*/
|
*/
|
||||||
case OP_IdxDelete: { /* in2 */
|
case OP_IdxDelete: { /* in2 */
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
|
@ -3689,7 +3686,7 @@ case OP_IdxRowid: { /* out2-prerelease */
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}
|
}
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->u.i = rowid;
|
pOut->u.i = rowid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3801,7 +3798,7 @@ case OP_Destroy: { /* out2-prerelease */
|
||||||
assert( iCnt==1 );
|
assert( iCnt==1 );
|
||||||
assert( (p->btreeMask & (1<<iDb))!=0 );
|
assert( (p->btreeMask & (1<<iDb))!=0 );
|
||||||
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
|
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->u.i = iMoved;
|
pOut->u.i = iMoved;
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( rc==SQLITE_OK && iMoved!=0 ){
|
if( rc==SQLITE_OK && iMoved!=0 ){
|
||||||
|
@ -3870,7 +3867,7 @@ case OP_CreateTable: { /* out2-prerelease */
|
||||||
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
|
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pOut->u.i = pgno;
|
pOut->u.i = pgno;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4023,12 +4020,8 @@ case OP_IntegrityCk: {
|
||||||
if( nErr==0 ){
|
if( nErr==0 ){
|
||||||
assert( z==0 );
|
assert( z==0 );
|
||||||
}else{
|
}else{
|
||||||
pIn1->z = z;
|
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
|
||||||
pIn1->n = strlen(z);
|
|
||||||
pIn1->flags = MEM_Str | MEM_Dyn | MEM_Term;
|
|
||||||
pIn1->xDel = 0;
|
|
||||||
}
|
}
|
||||||
pIn1->enc = SQLITE_UTF8;
|
|
||||||
UPDATE_MAX_BLOBSIZE(pIn1);
|
UPDATE_MAX_BLOBSIZE(pIn1);
|
||||||
sqlite3VdbeChangeEncoding(pIn1, encoding);
|
sqlite3VdbeChangeEncoding(pIn1, encoding);
|
||||||
sqlite3_free(aRoot);
|
sqlite3_free(aRoot);
|
||||||
|
@ -4058,8 +4051,7 @@ case OP_FifoRead: { /* jump */
|
||||||
CHECK_FOR_INTERRUPT;
|
CHECK_FOR_INTERRUPT;
|
||||||
assert( pOp->p1>0 && pOp->p1<=p->nMem );
|
assert( pOp->p1>0 && pOp->p1<=p->nMem );
|
||||||
pOut = &p->aMem[pOp->p1];
|
pOut = &p->aMem[pOp->p1];
|
||||||
Release(pOut);
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->flags = MEM_Int;
|
|
||||||
if( sqlite3VdbeFifoPop(&p->sFifo, &pOut->u.i)==SQLITE_DONE ){
|
if( sqlite3VdbeFifoPop(&p->sFifo, &pOut->u.i)==SQLITE_DONE ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
|
@ -4137,7 +4129,7 @@ case OP_MemMax: { /* in1, in2 */
|
||||||
** not contain an integer. An assertion fault will result if you try.
|
** not contain an integer. An assertion fault will result if you try.
|
||||||
*/
|
*/
|
||||||
case OP_IfPos: { /* jump, in1 */
|
case OP_IfPos: { /* jump, in1 */
|
||||||
assert( pIn1->flags==MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
if( pIn1->u.i>0 ){
|
if( pIn1->u.i>0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
|
@ -4152,7 +4144,7 @@ case OP_IfPos: { /* jump, in1 */
|
||||||
** not contain an integer. An assertion fault will result if you try.
|
** not contain an integer. An assertion fault will result if you try.
|
||||||
*/
|
*/
|
||||||
case OP_IfNeg: { /* jump, in1 */
|
case OP_IfNeg: { /* jump, in1 */
|
||||||
assert( pIn1->flags==MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
if( pIn1->u.i<0 ){
|
if( pIn1->u.i<0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
|
@ -4167,7 +4159,7 @@ case OP_IfNeg: { /* jump, in1 */
|
||||||
** not contain an integer. An assertion fault will result if you try.
|
** not contain an integer. An assertion fault will result if you try.
|
||||||
*/
|
*/
|
||||||
case OP_IfZero: { /* jump, in1 */
|
case OP_IfZero: { /* jump, in1 */
|
||||||
assert( pIn1->flags==MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
if( pIn1->u.i==0 ){
|
if( pIn1->u.i==0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
|
@ -4502,7 +4494,7 @@ case OP_VRowid: { /* out2-prerelease */
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||||
rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
|
rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||||
pOut->flags = MEM_Int;
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->u.i = iRow;
|
pOut->u.i = iRow;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4531,8 +4523,15 @@ case OP_VColumn: {
|
||||||
pModule = pCur->pVtabCursor->pVtab->pModule;
|
pModule = pCur->pVtabCursor->pVtab->pModule;
|
||||||
assert( pModule->xColumn );
|
assert( pModule->xColumn );
|
||||||
memset(&sContext, 0, sizeof(sContext));
|
memset(&sContext, 0, sizeof(sContext));
|
||||||
sContext.s.flags = MEM_Null;
|
|
||||||
sContext.s.db = db;
|
/* The output cell may already have a buffer allocated. Move
|
||||||
|
** the current contents to sContext.s so in case the user-function
|
||||||
|
** can use the already allocated buffer instead of allocating a
|
||||||
|
** new one.
|
||||||
|
*/
|
||||||
|
sqlite3VdbeMemMove(&sContext.s, pDest);
|
||||||
|
MemSetTypeFlag(&sContext.s, MEM_Null);
|
||||||
|
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||||
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
||||||
|
|
||||||
|
|
|
@ -94,13 +94,6 @@ struct Cursor {
|
||||||
};
|
};
|
||||||
typedef struct Cursor Cursor;
|
typedef struct Cursor Cursor;
|
||||||
|
|
||||||
/*
|
|
||||||
** Number of bytes of string storage space available to each stack
|
|
||||||
** layer without having to malloc. NBFS is short for Number of Bytes
|
|
||||||
** For Strings.
|
|
||||||
*/
|
|
||||||
#define NBFS 32
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** A value for Cursor.cacheValid that means the cache is always invalid.
|
** A value for Cursor.cacheValid that means the cache is always invalid.
|
||||||
*/
|
*/
|
||||||
|
@ -130,7 +123,6 @@ struct Mem {
|
||||||
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
|
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
|
||||||
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
||||||
void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
|
void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
|
||||||
char zShort[NBFS]; /* Space for short strings */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* One or more of the following flags are set to indicate the validOK
|
/* One or more of the following flags are set to indicate the validOK
|
||||||
|
@ -154,6 +146,9 @@ struct Mem {
|
||||||
#define MEM_Real 0x0008 /* Value is a real number */
|
#define MEM_Real 0x0008 /* Value is a real number */
|
||||||
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
||||||
|
|
||||||
|
#define MemSetTypeFlag(p, f) \
|
||||||
|
((p)->flags = ((p)->flags&~(MEM_Int|MEM_Real|MEM_Null|MEM_Blob|MEM_Str))|f)
|
||||||
|
|
||||||
/* Whenever Mem contains a valid string or blob representation, one of
|
/* Whenever Mem contains a valid string or blob representation, one of
|
||||||
** the following flags must be set to determine the memory management
|
** the following flags must be set to determine the memory management
|
||||||
** policy for Mem.z. The MEM_Term flag tells us whether or not the
|
** policy for Mem.z. The MEM_Term flag tells us whether or not the
|
||||||
|
@ -163,7 +158,6 @@ struct Mem {
|
||||||
#define MEM_Dyn 0x0040 /* Need to call sqliteFree() on Mem.z */
|
#define MEM_Dyn 0x0040 /* Need to call sqliteFree() on Mem.z */
|
||||||
#define MEM_Static 0x0080 /* Mem.z points to a static string */
|
#define MEM_Static 0x0080 /* Mem.z points to a static string */
|
||||||
#define MEM_Ephem 0x0100 /* Mem.z points to an ephemeral string */
|
#define MEM_Ephem 0x0100 /* Mem.z points to an ephemeral string */
|
||||||
#define MEM_Short 0x0200 /* Mem.z points to Mem.zShort */
|
|
||||||
#define MEM_Agg 0x0400 /* Mem.z points to an agg function context */
|
#define MEM_Agg 0x0400 /* Mem.z points to an agg function context */
|
||||||
#define MEM_Zero 0x0800 /* Mem.i contains count of 0s appended to blob */
|
#define MEM_Zero 0x0800 /* Mem.i contains count of 0s appended to blob */
|
||||||
|
|
||||||
|
@ -398,6 +392,7 @@ void sqlite3VdbeMemRelease(Mem *p);
|
||||||
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
|
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
|
||||||
const char *sqlite3OpcodeName(int);
|
const char *sqlite3OpcodeName(int);
|
||||||
int sqlite3VdbeOpcodeHasProperty(int, int);
|
int sqlite3VdbeOpcodeHasProperty(int, int);
|
||||||
|
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void sqlite3VdbeMemSanity(Mem*);
|
void sqlite3VdbeMemSanity(Mem*);
|
||||||
|
|
|
@ -944,6 +944,7 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
|
rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
|
||||||
}
|
}
|
||||||
|
rc = sqlite3ApiExit(p->db, rc);
|
||||||
sqlite3_mutex_leave(p->db->mutex);
|
sqlite3_mutex_leave(p->db->mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -735,11 +735,15 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||||
** Release an array of N Mem elements
|
** Release an array of N Mem elements
|
||||||
*/
|
*/
|
||||||
static void releaseMemArray(Mem *p, int N){
|
static void releaseMemArray(Mem *p, int N){
|
||||||
if( p ){
|
if( p && N ){
|
||||||
|
sqlite3 *db = p->db;
|
||||||
|
int malloc_failed = db->mallocFailed;
|
||||||
while( N-->0 ){
|
while( N-->0 ){
|
||||||
assert( N<2 || p[0].db==p[1].db );
|
assert( N<2 || p[0].db==p[1].db );
|
||||||
sqlite3VdbeMemSetNull(p++);
|
sqlite3VdbeMemRelease(p);
|
||||||
|
p++->flags = MEM_Null;
|
||||||
}
|
}
|
||||||
|
db->mallocFailed = malloc_failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,6 +790,7 @@ int sqlite3VdbeList(
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);
|
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);
|
||||||
}else{
|
}else{
|
||||||
|
char *z;
|
||||||
Op *pOp = &p->aOp[i];
|
Op *pOp = &p->aOp[i];
|
||||||
if( p->explain==1 ){
|
if( p->explain==1 ){
|
||||||
pMem->flags = MEM_Int;
|
pMem->flags = MEM_Int;
|
||||||
|
@ -819,18 +824,29 @@ int sqlite3VdbeList(
|
||||||
pMem++;
|
pMem++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P4 */
|
if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
|
||||||
pMem->z = displayP4(pOp, pMem->zShort, sizeof(pMem->zShort));
|
p->db->mallocFailed = 1;
|
||||||
assert( pMem->z!=0 );
|
return SQLITE_NOMEM;
|
||||||
pMem->n = strlen(pMem->z);
|
}
|
||||||
|
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
|
||||||
|
z = displayP4(pOp, pMem->z, 32);
|
||||||
|
if( z!=pMem->z ){
|
||||||
|
sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
|
||||||
|
}else{
|
||||||
|
assert( pMem->z!=0 );
|
||||||
|
pMem->n = strlen(pMem->z);
|
||||||
|
pMem->enc = SQLITE_UTF8;
|
||||||
|
}
|
||||||
pMem->type = SQLITE_TEXT;
|
pMem->type = SQLITE_TEXT;
|
||||||
pMem->enc = SQLITE_UTF8;
|
|
||||||
pMem++;
|
pMem++;
|
||||||
|
|
||||||
if( p->explain==1 ){
|
if( p->explain==1 ){
|
||||||
pMem->flags = MEM_Str|MEM_Term|MEM_Short;
|
if( sqlite3VdbeMemGrow(pMem, 32, 0) ){
|
||||||
pMem->n = sprintf(pMem->zShort, "%.2x", pOp->p5); /* P5 */
|
p->db->mallocFailed = 1;
|
||||||
pMem->z = pMem->zShort;
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
|
||||||
|
pMem->n = sprintf(pMem->z, "%.2x", pOp->p5); /* P5 */
|
||||||
pMem->type = SQLITE_TEXT;
|
pMem->type = SQLITE_TEXT;
|
||||||
pMem->enc = SQLITE_UTF8;
|
pMem->enc = SQLITE_UTF8;
|
||||||
pMem++;
|
pMem++;
|
||||||
|
@ -1058,6 +1074,9 @@ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){
|
||||||
static void Cleanup(Vdbe *p){
|
static void Cleanup(Vdbe *p){
|
||||||
int i;
|
int i;
|
||||||
closeAllCursorsExceptActiveVtabs(p);
|
closeAllCursorsExceptActiveVtabs(p);
|
||||||
|
for(i=1; i<=p->nMem; i++){
|
||||||
|
MemSetTypeFlag(&p->aMem[i], MEM_Null);
|
||||||
|
}
|
||||||
releaseMemArray(&p->aMem[1], p->nMem);
|
releaseMemArray(&p->aMem[1], p->nMem);
|
||||||
sqlite3VdbeFifoClear(&p->sFifo);
|
sqlite3VdbeFifoClear(&p->sFifo);
|
||||||
if( p->contextStack ){
|
if( p->contextStack ){
|
||||||
|
@ -2133,8 +2152,10 @@ int sqlite3VdbeRecordCompare(
|
||||||
Mem mem2;
|
Mem mem2;
|
||||||
mem1.enc = pKeyInfo->enc;
|
mem1.enc = pKeyInfo->enc;
|
||||||
mem1.db = pKeyInfo->db;
|
mem1.db = pKeyInfo->db;
|
||||||
|
mem1.flags = 0;
|
||||||
mem2.enc = pKeyInfo->enc;
|
mem2.enc = pKeyInfo->enc;
|
||||||
mem2.db = pKeyInfo->db;
|
mem2.db = pKeyInfo->db;
|
||||||
|
mem2.flags = 0;
|
||||||
|
|
||||||
idx1 = GetVarint(aKey1, szHdr1);
|
idx1 = GetVarint(aKey1, szHdr1);
|
||||||
d1 = szHdr1;
|
d1 = szHdr1;
|
||||||
|
@ -2159,8 +2180,8 @@ int sqlite3VdbeRecordCompare(
|
||||||
/* Do the comparison
|
/* Do the comparison
|
||||||
*/
|
*/
|
||||||
rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
|
rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
|
||||||
if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
|
if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
|
||||||
if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
|
if( mem2.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
|
||||||
if( rc!=0 ){
|
if( rc!=0 ){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2222,6 +2243,8 @@ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
|
||||||
if( nCellKey<=0 ){
|
if( nCellKey<=0 ){
|
||||||
return SQLITE_CORRUPT_BKPT;
|
return SQLITE_CORRUPT_BKPT;
|
||||||
}
|
}
|
||||||
|
m.flags = 0;
|
||||||
|
m.db = 0;
|
||||||
rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -2261,6 +2284,8 @@ int sqlite3VdbeIdxKeyCompare(
|
||||||
*res = 0;
|
*res = 0;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
m.db = 0;
|
||||||
|
m.flags = 0;
|
||||||
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
|
|
395
src/vdbemem.c
395
src/vdbemem.c
|
@ -59,33 +59,83 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Make sure pMem->z points to a writable allocation of at least
|
||||||
|
** n bytes.
|
||||||
|
**
|
||||||
|
** If the memory cell currently contains string or blob data
|
||||||
|
** and the third argument passed to this function is true, the
|
||||||
|
** current content of the cell is preserved. Otherwise, it may
|
||||||
|
** be discarded.
|
||||||
|
**
|
||||||
|
** This function sets the MEM_Dyn flag and clears any xDel callback.
|
||||||
|
** It also clears MEM_Ephem and MEM_Static. If the preserve flag is
|
||||||
|
** not set, Mem.n is zeroed.
|
||||||
|
*/
|
||||||
|
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
|
||||||
|
int f = pMem->flags;
|
||||||
|
|
||||||
|
assert( (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==0
|
||||||
|
|| (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Dyn
|
||||||
|
|| (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Ephem
|
||||||
|
|| (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Static
|
||||||
|
);
|
||||||
|
|
||||||
|
if( ((f&MEM_Dyn)==0 || pMem->xDel || sqlite3MallocSize(pMem->z)<n) ){
|
||||||
|
|
||||||
|
/* Allocate the new buffer. The minimum allocation size is 32 bytes. */
|
||||||
|
char *z = 0;
|
||||||
|
if( n>0 ){
|
||||||
|
if( preserve && (f&MEM_Dyn) && !pMem->xDel ){
|
||||||
|
z = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
|
||||||
|
pMem->z = 0;
|
||||||
|
preserve = 0;
|
||||||
|
}else{
|
||||||
|
z = sqlite3DbMallocRaw(pMem->db, (n>32?n:32));
|
||||||
|
}
|
||||||
|
if( !z ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the value is currently a string or blob and the preserve flag
|
||||||
|
** is true, copy the content to the new buffer.
|
||||||
|
*/
|
||||||
|
if( pMem->flags&(MEM_Blob|MEM_Str) && preserve ){
|
||||||
|
int nCopy = (pMem->n>n?n:pMem->n);
|
||||||
|
memcpy(z, pMem->z, nCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the old buffer. */
|
||||||
|
sqlite3VdbeMemRelease(pMem);
|
||||||
|
|
||||||
|
pMem->z = z;
|
||||||
|
pMem->flags |= MEM_Dyn;
|
||||||
|
pMem->flags &= ~(MEM_Ephem|MEM_Static);
|
||||||
|
pMem->xDel = 0;
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Make the given Mem object MEM_Dyn.
|
** Make the given Mem object MEM_Dyn.
|
||||||
**
|
**
|
||||||
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
|
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemDynamicify(Mem *pMem){
|
int sqlite3VdbeMemDynamicify(Mem *pMem){
|
||||||
int n;
|
int f;
|
||||||
u8 *z;
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
expandBlob(pMem);
|
expandBlob(pMem);
|
||||||
if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
|
f = pMem->flags;
|
||||||
return SQLITE_OK;
|
if( (f&(MEM_Str|MEM_Blob)) && ((f&MEM_Dyn)==0 || pMem->xDel) ){
|
||||||
|
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
pMem->z[pMem->n] = 0;
|
||||||
|
pMem->z[pMem->n+1] = 0;
|
||||||
|
pMem->flags |= MEM_Term;
|
||||||
}
|
}
|
||||||
assert( (pMem->flags & MEM_Dyn)==0 );
|
|
||||||
n = pMem->n;
|
|
||||||
assert( pMem->flags & (MEM_Str|MEM_Blob) );
|
|
||||||
z = sqlite3DbMallocRaw(pMem->db, n+2 );
|
|
||||||
if( z==0 ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
pMem->flags |= MEM_Dyn|MEM_Term;
|
|
||||||
pMem->xDel = 0;
|
|
||||||
memcpy(z, pMem->z, n );
|
|
||||||
z[n] = 0;
|
|
||||||
z[n+1] = 0;
|
|
||||||
pMem->z = (char*)z;
|
|
||||||
pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,24 +146,22 @@ int sqlite3VdbeMemDynamicify(Mem *pMem){
|
||||||
#ifndef SQLITE_OMIT_INCRBLOB
|
#ifndef SQLITE_OMIT_INCRBLOB
|
||||||
int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
||||||
if( pMem->flags & MEM_Zero ){
|
if( pMem->flags & MEM_Zero ){
|
||||||
char *pNew;
|
|
||||||
int nByte;
|
int nByte;
|
||||||
assert( (pMem->flags & MEM_Blob)!=0 );
|
assert( pMem->flags&MEM_Blob );
|
||||||
nByte = pMem->n + pMem->u.i;
|
|
||||||
if( nByte<=0 ) nByte = 1;
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
pNew = sqlite3DbMallocRaw(pMem->db, nByte);
|
|
||||||
if( pNew==0 ){
|
/* Set nByte to the number of bytes required to store the expanded blob. */
|
||||||
|
nByte = pMem->n + pMem->u.i;
|
||||||
|
if( nByte<=0 ){
|
||||||
|
nByte = 1;
|
||||||
|
}
|
||||||
|
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
memcpy(pNew, pMem->z, pMem->n);
|
|
||||||
memset(&pNew[pMem->n], 0, pMem->u.i);
|
memset(&pMem->z[pMem->n], 0, pMem->u.i);
|
||||||
sqlite3VdbeMemRelease(pMem);
|
|
||||||
pMem->z = pNew;
|
|
||||||
pMem->n += pMem->u.i;
|
pMem->n += pMem->u.i;
|
||||||
pMem->u.i = 0;
|
pMem->flags &= ~(MEM_Zero|MEM_Term);
|
||||||
pMem->flags &= ~(MEM_Zero|MEM_Static|MEM_Ephem|MEM_Short|MEM_Term);
|
|
||||||
pMem->flags |= MEM_Dyn;
|
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
@ -127,33 +175,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
||||||
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
|
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||||
int n;
|
return sqlite3VdbeMemDynamicify(pMem);
|
||||||
u8 *z;
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
|
||||||
expandBlob(pMem);
|
|
||||||
if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
assert( (pMem->flags & MEM_Dyn)==0 );
|
|
||||||
assert( pMem->flags & (MEM_Str|MEM_Blob) );
|
|
||||||
if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
|
|
||||||
z = (u8*)pMem->zShort;
|
|
||||||
pMem->flags |= MEM_Short|MEM_Term;
|
|
||||||
}else{
|
|
||||||
z = sqlite3DbMallocRaw(pMem->db, n+2 );
|
|
||||||
if( z==0 ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
pMem->flags |= MEM_Dyn|MEM_Term;
|
|
||||||
pMem->xDel = 0;
|
|
||||||
}
|
|
||||||
memcpy(z, pMem->z, n );
|
|
||||||
z[n] = 0;
|
|
||||||
z[n+1] = 0;
|
|
||||||
pMem->z = (char*)z;
|
|
||||||
pMem->flags &= ~(MEM_Ephem|MEM_Static);
|
|
||||||
assert(0==(1&(int)pMem->z));
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -164,27 +186,12 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
|
||||||
if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
|
if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
|
||||||
return SQLITE_OK; /* Nothing to do */
|
return SQLITE_OK; /* Nothing to do */
|
||||||
}
|
}
|
||||||
if( pMem->flags & (MEM_Static|MEM_Ephem) ){
|
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
|
||||||
return sqlite3VdbeMemMakeWriteable(pMem);
|
return SQLITE_NOMEM;
|
||||||
}else{
|
|
||||||
char *z;
|
|
||||||
sqlite3VdbeMemExpandBlob(pMem);
|
|
||||||
z = sqlite3DbMallocRaw(pMem->db, pMem->n+2);
|
|
||||||
if( !z ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
memcpy(z, pMem->z, pMem->n);
|
|
||||||
z[pMem->n] = 0;
|
|
||||||
z[pMem->n+1] = 0;
|
|
||||||
if( pMem->xDel ){
|
|
||||||
pMem->xDel(pMem->z);
|
|
||||||
}else{
|
|
||||||
sqlite3_free(pMem->z);
|
|
||||||
}
|
|
||||||
pMem->xDel = 0;
|
|
||||||
pMem->z = z;
|
|
||||||
pMem->flags |= MEM_Term;
|
|
||||||
}
|
}
|
||||||
|
pMem->z[pMem->n] = 0;
|
||||||
|
pMem->z[pMem->n+1] = 0;
|
||||||
|
pMem->flags |= MEM_Term;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,29 +211,32 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
|
||||||
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
|
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int fg = pMem->flags;
|
int fg = pMem->flags;
|
||||||
char *z = pMem->zShort;
|
const int nByte = 32;
|
||||||
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
assert( !(fg&MEM_Zero) );
|
assert( !(fg&MEM_Zero) );
|
||||||
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
||||||
assert( fg&(MEM_Int|MEM_Real) );
|
assert( fg&(MEM_Int|MEM_Real) );
|
||||||
|
|
||||||
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
|
if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8
|
||||||
** string representation of the value. Then, if the required encoding
|
** string representation of the value. Then, if the required encoding
|
||||||
** is UTF-16le or UTF-16be do a translation.
|
** is UTF-16le or UTF-16be do a translation.
|
||||||
**
|
**
|
||||||
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
|
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
|
||||||
*/
|
*/
|
||||||
if( fg & MEM_Int ){
|
if( fg & MEM_Int ){
|
||||||
sqlite3_snprintf(NBFS, z, "%lld", pMem->u.i);
|
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
|
||||||
}else{
|
}else{
|
||||||
assert( fg & MEM_Real );
|
assert( fg & MEM_Real );
|
||||||
sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
|
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
|
||||||
}
|
}
|
||||||
pMem->n = strlen(z);
|
pMem->n = strlen(pMem->z);
|
||||||
pMem->z = z;
|
|
||||||
pMem->enc = SQLITE_UTF8;
|
pMem->enc = SQLITE_UTF8;
|
||||||
pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
|
pMem->flags |= MEM_Str|MEM_Term;
|
||||||
sqlite3VdbeChangeEncoding(pMem, enc);
|
sqlite3VdbeChangeEncoding(pMem, enc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -246,19 +256,15 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
|
||||||
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
|
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
ctx.s.flags = MEM_Null;
|
ctx.s.flags = MEM_Null;
|
||||||
ctx.s.z = pMem->zShort;
|
|
||||||
ctx.s.db = pMem->db;
|
ctx.s.db = pMem->db;
|
||||||
ctx.pMem = pMem;
|
ctx.pMem = pMem;
|
||||||
ctx.pFunc = pFunc;
|
ctx.pFunc = pFunc;
|
||||||
ctx.isError = 0;
|
ctx.isError = 0;
|
||||||
pFunc->xFinalize(&ctx);
|
pFunc->xFinalize(&ctx);
|
||||||
if( pMem->z && pMem->z!=pMem->zShort ){
|
if( pMem->z ){
|
||||||
sqlite3_free( pMem->z );
|
sqlite3_free( pMem->z );
|
||||||
}
|
}
|
||||||
*pMem = ctx.s;
|
*pMem = ctx.s;
|
||||||
if( pMem->flags & MEM_Short ){
|
|
||||||
pMem->z = pMem->zShort;
|
|
||||||
}
|
|
||||||
rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
|
rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -394,14 +400,17 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setTypeFlag(Mem *pMem, int f){
|
||||||
|
MemSetTypeFlag(pMem, f);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Convert pMem to type integer. Invalidate any prior representations.
|
** Convert pMem to type integer. Invalidate any prior representations.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemIntegerify(Mem *pMem){
|
int sqlite3VdbeMemIntegerify(Mem *pMem){
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
pMem->u.i = sqlite3VdbeIntValue(pMem);
|
pMem->u.i = sqlite3VdbeIntValue(pMem);
|
||||||
sqlite3VdbeMemRelease(pMem);
|
setTypeFlag(pMem, MEM_Int);
|
||||||
pMem->flags = MEM_Int;
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,8 +421,7 @@ int sqlite3VdbeMemIntegerify(Mem *pMem){
|
||||||
int sqlite3VdbeMemRealify(Mem *pMem){
|
int sqlite3VdbeMemRealify(Mem *pMem){
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
pMem->r = sqlite3VdbeRealValue(pMem);
|
pMem->r = sqlite3VdbeRealValue(pMem);
|
||||||
sqlite3VdbeMemRelease(pMem);
|
setTypeFlag(pMem, MEM_Real);
|
||||||
pMem->flags = MEM_Real;
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,8 +442,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
|
||||||
sqlite3VdbeMemIntegerify(pMem);
|
sqlite3VdbeMemIntegerify(pMem);
|
||||||
}else{
|
}else{
|
||||||
pMem->r = r1;
|
pMem->r = r1;
|
||||||
pMem->flags = MEM_Real;
|
setTypeFlag(pMem, MEM_Real);
|
||||||
sqlite3VdbeMemRelease(pMem);
|
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
@ -444,10 +451,8 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
|
||||||
** Delete any previous value and set the value stored in *pMem to NULL.
|
** Delete any previous value and set the value stored in *pMem to NULL.
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeMemSetNull(Mem *pMem){
|
void sqlite3VdbeMemSetNull(Mem *pMem){
|
||||||
sqlite3VdbeMemRelease(pMem);
|
setTypeFlag(pMem, MEM_Null);
|
||||||
pMem->flags = MEM_Null;
|
|
||||||
pMem->type = SQLITE_NULL;
|
pMem->type = SQLITE_NULL;
|
||||||
pMem->n = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -456,12 +461,12 @@ void sqlite3VdbeMemSetNull(Mem *pMem){
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
|
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
|
||||||
sqlite3VdbeMemRelease(pMem);
|
sqlite3VdbeMemRelease(pMem);
|
||||||
pMem->flags = MEM_Blob|MEM_Zero|MEM_Short;
|
setTypeFlag(pMem, MEM_Blob);
|
||||||
|
pMem->flags = MEM_Blob|MEM_Zero;
|
||||||
pMem->type = SQLITE_BLOB;
|
pMem->type = SQLITE_BLOB;
|
||||||
pMem->n = 0;
|
pMem->n = 0;
|
||||||
if( n<0 ) n = 0;
|
if( n<0 ) n = 0;
|
||||||
pMem->u.i = n;
|
pMem->u.i = n;
|
||||||
pMem->z = pMem->zShort;
|
|
||||||
pMem->enc = SQLITE_UTF8;
|
pMem->enc = SQLITE_UTF8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,10 +519,10 @@ int sqlite3VdbeMemTooBig(Mem *p){
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
||||||
sqlite3VdbeMemRelease(pTo);
|
sqlite3VdbeMemRelease(pTo);
|
||||||
memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
|
memcpy(pTo, pFrom, sizeof(*pFrom));
|
||||||
pTo->xDel = 0;
|
pTo->xDel = 0;
|
||||||
if( pTo->flags & (MEM_Str|MEM_Blob) ){
|
if( pTo->flags&MEM_Dyn ){
|
||||||
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem);
|
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
|
||||||
assert( srcType==MEM_Ephem || srcType==MEM_Static );
|
assert( srcType==MEM_Ephem || srcType==MEM_Static );
|
||||||
pTo->flags |= srcType;
|
pTo->flags |= srcType;
|
||||||
}
|
}
|
||||||
|
@ -528,12 +533,46 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
||||||
** freed before the copy is made.
|
** freed before the copy is made.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
||||||
int rc;
|
int rc = SQLITE_OK;
|
||||||
sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
|
char *zBuf = 0;
|
||||||
if( pTo->flags & MEM_Ephem ){
|
|
||||||
rc = sqlite3VdbeMemMakeWriteable(pTo);
|
/* If cell pTo currently has a reusable buffer, save a pointer to it
|
||||||
|
** in local variable zBuf. This function attempts to avoid freeing
|
||||||
|
** this buffer.
|
||||||
|
*/
|
||||||
|
if( pTo->xDel ){
|
||||||
|
sqlite3VdbeMemRelease(pTo);
|
||||||
|
}else if( pTo->flags&MEM_Dyn ){
|
||||||
|
zBuf = pTo->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the contents of *pFrom to *pTo */
|
||||||
|
memcpy(pTo, pFrom, sizeof(*pFrom));
|
||||||
|
|
||||||
|
if( pTo->flags&(MEM_Str|MEM_Blob) && pTo->flags&MEM_Static ){
|
||||||
|
/* pFrom contained a pointer to a static string. In this case,
|
||||||
|
** free any dynamically allocated buffer associated with pTo.
|
||||||
|
*/
|
||||||
|
sqlite3_free(zBuf);
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_OK;
|
char *zData = pTo->z;
|
||||||
|
|
||||||
|
pTo->z = zBuf;
|
||||||
|
pTo->flags &= ~(MEM_Static|MEM_Ephem);
|
||||||
|
pTo->flags |= MEM_Dyn;
|
||||||
|
pTo->xDel = 0;
|
||||||
|
|
||||||
|
if( pTo->flags&(MEM_Str|MEM_Blob) ){
|
||||||
|
if( sqlite3VdbeMemGrow(pTo, pTo->n+2, 0) ){
|
||||||
|
pTo->n = 0;
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
memcpy(pTo->z, zData, pTo->n);
|
||||||
|
pTo->z[pTo->n] = '\0';
|
||||||
|
pTo->z[pTo->n+1] = '\0';
|
||||||
|
pTo->flags |= MEM_Term;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -552,15 +591,18 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
|
||||||
sqlite3VdbeMemRelease(pTo);
|
sqlite3VdbeMemRelease(pTo);
|
||||||
}
|
}
|
||||||
memcpy(pTo, pFrom, sizeof(Mem));
|
memcpy(pTo, pFrom, sizeof(Mem));
|
||||||
if( pFrom->flags & MEM_Short ){
|
|
||||||
pTo->z = pTo->zShort;
|
|
||||||
}
|
|
||||||
pFrom->flags = MEM_Null;
|
pFrom->flags = MEM_Null;
|
||||||
pFrom->xDel = 0;
|
pFrom->xDel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Change the value of a Mem to be a string or a BLOB.
|
** Change the value of a Mem to be a string or a BLOB.
|
||||||
|
**
|
||||||
|
** The memory management strategy depends on the value of the xDel
|
||||||
|
** parameter. If the value passed is SQLITE_TRANSIENT, then the
|
||||||
|
** string is copied into a (possibly existing) buffer managed by the
|
||||||
|
** Mem structure. Otherwise, any existing buffer is freed and the
|
||||||
|
** pointer copied.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemSetStr(
|
int sqlite3VdbeMemSetStr(
|
||||||
Mem *pMem, /* Memory cell to set to string value */
|
Mem *pMem, /* Memory cell to set to string value */
|
||||||
|
@ -569,59 +611,56 @@ int sqlite3VdbeMemSetStr(
|
||||||
u8 enc, /* Encoding of z. 0 for BLOBs */
|
u8 enc, /* Encoding of z. 0 for BLOBs */
|
||||||
void (*xDel)(void*) /* Destructor function */
|
void (*xDel)(void*) /* Destructor function */
|
||||||
){
|
){
|
||||||
|
int nByte = n; /* New value for pMem->n */
|
||||||
|
int flags = 0; /* New value for pMem->flags */
|
||||||
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
sqlite3VdbeMemRelease(pMem);
|
|
||||||
|
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
|
||||||
if( !z ){
|
if( !z ){
|
||||||
pMem->flags = MEM_Null;
|
sqlite3VdbeMemSetNull(pMem);
|
||||||
pMem->type = SQLITE_NULL;
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
pMem->z = (char *)z;
|
|
||||||
if( xDel==SQLITE_STATIC ){
|
flags = (enc==0?MEM_Blob:MEM_Str);
|
||||||
pMem->flags = MEM_Static;
|
if( nByte<0 ){
|
||||||
}else if( xDel==SQLITE_TRANSIENT ){
|
assert( enc!=0 );
|
||||||
pMem->flags = MEM_Ephem;
|
nByte = ((enc==SQLITE_UTF8)?strlen(z):sqlite3Utf16ByteLen(z, -1));
|
||||||
}else{
|
flags |= MEM_Term;
|
||||||
pMem->flags = MEM_Dyn;
|
|
||||||
pMem->xDel = xDel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pMem->enc = enc;
|
/* The following block sets the new values of Mem.z and Mem.xDel. It
|
||||||
pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT;
|
** also sets a flag in local variable "flags" to indicate the memory
|
||||||
pMem->n = n;
|
** management (one of MEM_Dyn or MEM_Static).
|
||||||
|
*/
|
||||||
|
if( xDel==SQLITE_TRANSIENT ){
|
||||||
|
int nAlloc = nByte;
|
||||||
|
if( flags&MEM_Term ){
|
||||||
|
nAlloc += (enc==SQLITE_UTF8?1:2);
|
||||||
|
}
|
||||||
|
if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
memcpy(pMem->z, z, nAlloc);
|
||||||
|
flags |= MEM_Dyn;
|
||||||
|
}else{
|
||||||
|
sqlite3VdbeMemRelease(pMem);
|
||||||
|
pMem->z = (char *)z;
|
||||||
|
pMem->xDel = xDel;
|
||||||
|
flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
|
||||||
|
}
|
||||||
|
|
||||||
assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE
|
pMem->n = nByte;
|
||||||
|| enc==SQLITE_UTF16BE );
|
pMem->flags = flags;
|
||||||
switch( enc ){
|
pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
|
||||||
case 0:
|
pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
|
||||||
pMem->flags |= MEM_Blob;
|
|
||||||
pMem->enc = SQLITE_UTF8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SQLITE_UTF8:
|
|
||||||
pMem->flags |= MEM_Str;
|
|
||||||
if( n<0 ){
|
|
||||||
pMem->n = strlen(z);
|
|
||||||
pMem->flags |= MEM_Term;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
case SQLITE_UTF16LE:
|
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
|
||||||
case SQLITE_UTF16BE:
|
return SQLITE_NOMEM;
|
||||||
pMem->flags |= MEM_Str;
|
|
||||||
if( pMem->n<0 ){
|
|
||||||
pMem->n = sqlite3Utf16ByteLen(pMem->z,-1);
|
|
||||||
pMem->flags |= MEM_Term;
|
|
||||||
}
|
|
||||||
if( sqlite3VdbeMemHandleBom(pMem) ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_OMIT_UTF16 */
|
|
||||||
}
|
|
||||||
if( pMem->flags&MEM_Ephem ){
|
|
||||||
return sqlite3VdbeMemMakeWriteable(pMem);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,6 +808,7 @@ int sqlite3VdbeMemFromBtree(
|
||||||
char *zData; /* Data from the btree layer */
|
char *zData; /* Data from the btree layer */
|
||||||
int available = 0; /* Number of bytes available on the local btree page */
|
int available = 0; /* Number of bytes available on the local btree page */
|
||||||
sqlite3 *db; /* Database connection */
|
sqlite3 *db; /* Database connection */
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
db = sqlite3BtreeCursorDb(pCur);
|
db = sqlite3BtreeCursorDb(pCur);
|
||||||
assert( sqlite3_mutex_held(db->mutex) );
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
|
@ -779,49 +819,28 @@ int sqlite3VdbeMemFromBtree(
|
||||||
}
|
}
|
||||||
assert( zData!=0 );
|
assert( zData!=0 );
|
||||||
|
|
||||||
pMem->db = db;
|
if( offset+amt<=available && ((pMem->flags&MEM_Dyn)==0 || pMem->xDel) ){
|
||||||
pMem->n = amt;
|
sqlite3VdbeMemRelease(pMem);
|
||||||
if( offset+amt<=available ){
|
|
||||||
pMem->z = &zData[offset];
|
pMem->z = &zData[offset];
|
||||||
pMem->flags = MEM_Blob|MEM_Ephem;
|
pMem->flags = MEM_Blob|MEM_Ephem;
|
||||||
}else{
|
}else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
|
||||||
int rc;
|
pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
|
||||||
if( amt>NBFS-2 ){
|
|
||||||
zData = (char *)sqlite3DbMallocRaw(db, amt+2);
|
|
||||||
if( !zData ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
|
|
||||||
pMem->xDel = 0;
|
|
||||||
}else{
|
|
||||||
zData = &(pMem->zShort[0]);
|
|
||||||
pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
|
|
||||||
}
|
|
||||||
pMem->z = zData;
|
|
||||||
pMem->enc = 0;
|
pMem->enc = 0;
|
||||||
pMem->type = SQLITE_BLOB;
|
pMem->type = SQLITE_BLOB;
|
||||||
|
|
||||||
if( key ){
|
if( key ){
|
||||||
rc = sqlite3BtreeKey(pCur, offset, amt, zData);
|
rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3BtreeData(pCur, offset, amt, zData);
|
rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
|
||||||
}
|
}
|
||||||
zData[amt] = 0;
|
pMem->z[amt] = 0;
|
||||||
zData[amt+1] = 0;
|
pMem->z[amt+1] = 0;
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
if( amt>NBFS-2 ){
|
sqlite3VdbeMemRelease(pMem);
|
||||||
assert( zData!=pMem->zShort );
|
|
||||||
assert( pMem->flags & MEM_Dyn );
|
|
||||||
sqlite3_free(zData);
|
|
||||||
} else {
|
|
||||||
assert( zData==pMem->zShort );
|
|
||||||
assert( pMem->flags & MEM_Short );
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pMem->n = amt;
|
||||||
|
|
||||||
return SQLITE_OK;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1019,7 +1038,7 @@ void sqlite3ValueSetStr(
|
||||||
*/
|
*/
|
||||||
void sqlite3ValueFree(sqlite3_value *v){
|
void sqlite3ValueFree(sqlite3_value *v){
|
||||||
if( !v ) return;
|
if( !v ) return;
|
||||||
sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3VdbeMemRelease((Mem *)v);
|
||||||
sqlite3_free(v);
|
sqlite3_free(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# that they have little in common.
|
# that they have little in common.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# $Id: mallocB.test,v 1.7 2008/01/17 20:26:47 drh Exp $
|
# $Id: mallocB.test,v 1.8 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
@ -31,7 +31,7 @@ source $testdir/malloc_common.tcl
|
||||||
do_malloc_test mallocB-1 -sqlbody {SELECT - 456}
|
do_malloc_test mallocB-1 -sqlbody {SELECT - 456}
|
||||||
do_malloc_test mallocB-2 -sqlbody {SELECT - 456.1}
|
do_malloc_test mallocB-2 -sqlbody {SELECT - 456.1}
|
||||||
do_malloc_test mallocB-3 -sqlbody {SELECT random()}
|
do_malloc_test mallocB-3 -sqlbody {SELECT random()}
|
||||||
do_malloc_test mallocB-4 -sqlbody {SELECT zeroblob(1000)}
|
do_malloc_test mallocB-4 -sqlbody {SELECT length(zeroblob(1000))}
|
||||||
ifcapable subquery {
|
ifcapable subquery {
|
||||||
do_malloc_test mallocB-5 -sqlbody {SELECT * FROM (SELECT 1) GROUP BY 1;}
|
do_malloc_test mallocB-5 -sqlbody {SELECT * FROM (SELECT 1) GROUP BY 1;}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
# sqlite3_value_bytes()
|
# sqlite3_value_bytes()
|
||||||
# sqlite3_value_bytes16()
|
# sqlite3_value_bytes16()
|
||||||
#
|
#
|
||||||
# $Id: ptrchng.test,v 1.2 2007/09/12 17:01:45 danielk1977 Exp $
|
# $Id: ptrchng.test,v 1.3 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
@ -52,6 +52,8 @@ do_test ptrchng-1.1 {
|
||||||
# For the short entries that fit in the Mem.zBuf[], the pointer should
|
# For the short entries that fit in the Mem.zBuf[], the pointer should
|
||||||
# never change regardless of what type conversions occur.
|
# never change regardless of what type conversions occur.
|
||||||
#
|
#
|
||||||
|
# UPDATE: No longer true, as Mem.zBuf[] has been removed.
|
||||||
|
#
|
||||||
do_test ptrchng-2.1 {
|
do_test ptrchng-2.1 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text', 'noop', 'blob') FROM t1 WHERE x=1
|
SELECT pointer_change(y, 'text', 'noop', 'blob') FROM t1 WHERE x=1
|
||||||
|
@ -61,18 +63,18 @@ do_test ptrchng-2.2 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=1
|
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=1
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
ifcapable utf16 {
|
ifcapable utf16 {
|
||||||
do_test ptrchng-2.3 {
|
do_test ptrchng-2.3 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=1
|
SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=1
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
do_test ptrchng-2.4 {
|
do_test ptrchng-2.4 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=1
|
SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=1
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
do_test ptrchng-2.5 {
|
do_test ptrchng-2.5 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=1
|
SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=1
|
||||||
|
@ -82,7 +84,7 @@ ifcapable utf16 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=1
|
SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=1
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
}
|
}
|
||||||
do_test ptrchng-2.11 {
|
do_test ptrchng-2.11 {
|
||||||
execsql {
|
execsql {
|
||||||
|
@ -93,18 +95,18 @@ do_test ptrchng-2.12 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=3
|
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=3
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
ifcapable utf16 {
|
ifcapable utf16 {
|
||||||
do_test ptrchng-2.13 {
|
do_test ptrchng-2.13 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=3
|
SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=3
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
do_test ptrchng-2.14 {
|
do_test ptrchng-2.14 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=3
|
SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=3
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
do_test ptrchng-2.15 {
|
do_test ptrchng-2.15 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=3
|
SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=3
|
||||||
|
@ -115,7 +117,7 @@ btree_breakpoint
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=3
|
SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=3
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
}
|
}
|
||||||
|
|
||||||
# For the long entries that do not fit in the Mem.zBuf[], the pointer
|
# For the long entries that do not fit in the Mem.zBuf[], the pointer
|
||||||
|
@ -130,7 +132,7 @@ do_test ptrchng-3.2 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=2
|
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=2
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
ifcapable utf16 {
|
ifcapable utf16 {
|
||||||
do_test ptrchng-3.3 {
|
do_test ptrchng-3.3 {
|
||||||
execsql {
|
execsql {
|
||||||
|
@ -162,7 +164,7 @@ do_test ptrchng-3.12 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=4
|
SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=4
|
||||||
}
|
}
|
||||||
} {0}
|
} {1}
|
||||||
ifcapable utf16 {
|
ifcapable utf16 {
|
||||||
do_test ptrchng-3.13 {
|
do_test ptrchng-3.13 {
|
||||||
execsql {
|
execsql {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# This file implements some common TCL routines used for regression
|
# This file implements some common TCL routines used for regression
|
||||||
# testing the SQLite library
|
# testing the SQLite library
|
||||||
#
|
#
|
||||||
# $Id: tester.tcl,v 1.103 2008/02/08 18:25:30 danielk1977 Exp $
|
# $Id: tester.tcl,v 1.104 2008/02/13 18:25:27 danielk1977 Exp $
|
||||||
|
|
||||||
|
|
||||||
set tcl_precision 15
|
set tcl_precision 15
|
||||||
|
@ -227,6 +227,9 @@ proc finalize_testing {} {
|
||||||
}
|
}
|
||||||
puts "Maximum memory usage: [sqlite3_memory_highwater 1] bytes"
|
puts "Maximum memory usage: [sqlite3_memory_highwater 1] bytes"
|
||||||
puts "Current memory usage: [sqlite3_memory_highwater] bytes"
|
puts "Current memory usage: [sqlite3_memory_highwater] bytes"
|
||||||
|
if {[info commands sqlite3_memdebug_malloc_count] ne ""} {
|
||||||
|
puts "Number of malloc() : [sqlite3_memdebug_malloc_count] calls"
|
||||||
|
}
|
||||||
foreach f [glob -nocomplain test.db-*-journal] {
|
foreach f [glob -nocomplain test.db-*-journal] {
|
||||||
file delete -force $f
|
file delete -force $f
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue