]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Implement the "lookaside" memory allocation cache. Use of this cache makes
authordrh <drh@noemail.net>
Mon, 28 Jul 2008 19:34:53 +0000 (19:34 +0000)
committerdrh <drh@noemail.net>
Mon, 28 Jul 2008 19:34:53 +0000 (19:34 +0000)
the speed1.test script run about 15% faster.  Added new interfaces to
control the cache. (CVS 5488)

FossilOrigin-Name: e48f9697e9fea339e150ddc32940760027dd07d9

50 files changed:
manifest
manifest.uuid
src/alter.c
src/analyze.c
src/attach.c
src/btree.c
src/build.c
src/callback.c
src/date.c
src/delete.c
src/expr.c
src/func.c
src/global.c
src/insert.c
src/legacy.c
src/loadext.c
src/main.c
src/malloc.c
src/mem6.c
src/os.c
src/parse.y
src/pragma.c
src/prepare.c
src/printf.c
src/select.c
src/sqlite.h.in
src/sqliteInt.h
src/status.c
src/test4.c
src/test5.c
src/test7.c
src/test8.c
src/test_malloc.c
src/tokenize.c
src/trigger.c
src/update.c
src/util.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c
src/vdbeblob.c
src/vdbefifo.c
src/vdbemem.c
src/vtab.c
src/where.c
test/memsubsys1.test
test/speed1.test
tool/lemon.c
tool/lempar.c

index a6d8cd3932ee0d3998f2dac00c32e4d3415ddce8..22da79fbfc82cb6ac9121d55c58f483693a4d725 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\smem6.c\sto\sMakefile.in.\sTicket\s#3253.\s(CVS\s5487)
-D 2008-07-28T05:26:33
+C Implement\sthe\s"lookaside"\smemory\sallocation\scache.\s\sUse\sof\sthis\scache\smakes\nthe\sspeed1.test\sscript\srun\sabout\s15%\sfaster.\s\sAdded\snew\sinterfaces\sto\ncontrol\sthe\scache.\s(CVS\s5488)
+D 2008-07-28T19:34:53
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in bbb62eecc851379aef5a48a1bf8787eb13e6ec06
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -90,46 +90,46 @@ F sqlite.pc.in c322c6244c6395955dca34d87955aabde7df7623
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.def a1be7b9a4b8b51ac41c6ff6e8e44a14ef66b338b
 F sqlite3.pc.in 32b8a014799c2028c8e0c9cc5659718262fc493f
-F src/alter.c 73ec449c299bccd175aede22b56400134055f9db
-F src/analyze.c 9ee63497ee720728abe630d169ab91323ac7519c
-F src/attach.c b18ba42c77f7d3941f5d23d2ca20fa1d841a4e91
+F src/alter.c 2c541aaa88d720301253f181799d4af7bb9ddf1c
+F src/analyze.c 747ce8cb6b318bb0d0576cfb5277aed98cbbeb5c
+F src/attach.c a85c14612e7e3410e0c3d2e0241832fa9688bd14
 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
 F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d
 F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53
-F src/btree.c 1318ab0eaad158aad791d73611c1c63c9b5e981f
+F src/btree.c 540186cc76840ef9c6be5ec55793de79e33cf409
 F src/btree.h 03256ed7ee42b5ecacbe887070b0f8249e7d069d
 F src/btreeInt.h 6e4cb69a9192a8d609c27034ae5f921cf0ecdde1
-F src/build.c bac7233d984be3805aaa41cf500f7ee12dc97249
-F src/callback.c aa492a0ad8c2d454edff9fb8a57fae13743cf71d
+F src/build.c 77d5518a64c0a905024bee80f6df2e794f4f5d43
+F src/callback.c c9f75a4c403f166af3761df47d78a806587d63af
 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
-F src/date.c 243677c51b740933761b63c660eb85b01bf3c74d
-F src/delete.c 4a1f98fb2ffead69c8c685dcac33253ac6f9d56d
-F src/expr.c 18d04f1c15e760d4329b5e0383a0c8a8320f0005
+F src/date.c 52a54811218a76da6235420f532ece841159a96d
+F src/delete.c 0d115c173863b3c688c3083ef7857c7f2e9f7a18
+F src/expr.c 4f5221197384d923525fdfd117298eab073e9539
 F src/fault.c 3638519d1e0b82bccfafcb9f5ff491918b28f8e1
-F src/func.c 08422a7bd06c25c5e6823d525f7c63563e3fcf61
-F src/global.c f12dc84d23f52d2ed42d1bdb5460fa3caf63e890
+F src/func.c 54efe220cc1ef3859a4b738011621b63a0d697c5
+F src/global.c b9c96ee2317a6e1391763c7db1098a6473a91863
 F src/hash.c eb64e48f3781100e5934f759fbe72a63a8fe78cb
 F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
 F src/hwtime.h 745961687a65ef8918cd551c02e5ccb4b8e772de
-F src/insert.c e8efc17d037346e4a4a6949e72aab850befe3d5d
+F src/insert.c 89cd9af52a5ea6fb7d0cfc9c3b935d6406c360c4
 F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
-F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df
-F src/loadext.c ae0eed9fa96d74172d2a90ee63b5bc36d284295c
-F src/main.c 97b638ed3bab4b804439209e4a20fc8017fb859f
-F src/malloc.c c4b525896b8c188dab98609180d13dbeeeb33a84
+F src/legacy.c 3635cc6a5889918086b3501de8287cbbecb55917
+F src/loadext.c 9ab55455f59dce0ae6388952216a1505ce7f9d13
+F src/main.c 70d285dce241ad8daa320f78b060edb73bba637e
+F src/malloc.c 2aa685ca13019d6c46d43516578596afefa59425
 F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
 F src/mem1.c 3a7fe31d8290baa3bb203af72f7dfd6323966bcd
 F src/mem2.c 87381b143530cc377592e868bd548e881c2498a3
 F src/mem3.c c73e935d0b900abc51d5fa45f880937b062f4a9f
 F src/mem4.c 6703adb1717b26d9d70a1c2586b4b7b7ffee7909
 F src/mem5.c 0b0ba1c2a02d86eb812dea6debacee841e3856f7
-F src/mem6.c d1767b3715c31b830955bda1f3f1852619dcb687
+F src/mem6.c a3932c3d2f6382f077d7c94cf6a6e15e0a8cbd07
 F src/mutex.c a485a0eac8ee2cd95f66e565b4c6696c18db968f
 F src/mutex.h e52ffa1dfc6a6077e8b1823d2c2b7dfcbcf85594
 F src/mutex_os2.c 9c5637aa4c307c552566d0f0b3bd206245b54a97
 F src/mutex_unix.c 29049a61755cccddb2ee53904e6906bb7674223c
 F src/mutex_w32.c f0d21ff1f6981e5aedc56796adf3a347423ef736
-F src/os.c 292b3b4a49fe5bf6cf2f1cf0af186ebd334e80b8
+F src/os.c 939ae7690a01d9401685ba124b4ba45fd4a7a2ad
 F src/os.h ef8abeb9afc694b82dbd169a91c9b7e26db3c892
 F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
 F src/os_os2.c da14449fc210cd313eb56cf511ae05b350e323d6
@@ -137,28 +137,28 @@ F src/os_unix.c 1df6108efdb7957a9f28b9700600e58647c9c12d
 F src/os_win.c 50ec783403b418ddc9e6e05d541c6027dfd41070
 F src/pager.c a6ecad26297469a8a3d1fd7a7c3dc2d603955044
 F src/pager.h 588c1ac195228b2da45c4e5f7ab6c2fd253d1751
-F src/parse.y d1316f1b8b251412bdf4926c4c34803977958b65
-F src/pragma.c 6fad83fbcc7ec6e76d91fe2805fe972ff3af6a0c
-F src/prepare.c c9bb0aacb7a571d049805699ed18f2bb136ea091
-F src/printf.c 2174222bc346a11b1eac2a654ccc4f635355ae7e
+F src/parse.y 5ce0b04d2d35b987ccca8b46cfc2527dd932f040
+F src/pragma.c 6e207b4f69901089758c02c02e0bf86ed12a4d8f
+F src/prepare.c d2d53aec81517f8666450aa5fd1a041a3b72320e
+F src/printf.c 2e984b2507291a7e16d89dc9bb60582904f6247d
 F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a
-F src/select.c a152b1436d7117e25ce010453c61d1002214e337
+F src/select.c ef18af5624fc3189014e6b617a36562394740f91
 F src/shell.c 4b835fe734304ac22a3385868cd3790c1e4f7aa1
-F src/sqlite.h.in 534688abf1580de0a458f017c97770a96c3827ac
+F src/sqlite.h.in c1afc4a05dde8c6b9c8ea783b0b5a624892e299b
 F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
-F src/sqliteInt.h f9036237debe48d3542595fae2a18dcb41cd71e9
+F src/sqliteInt.h a4d6bcf383b1ff207f175f7e274a83d1283c73d7
 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
-F src/status.c 0f72b854aa75bb209718e0bb37728602c7ecdee6
+F src/status.c ca61c18b6f1c632b771514e0c39a7d662c805bbf
 F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
 F src/tclsqlite.c ec46084184f033ba396a9ee7b5514b695083d0f3
 F src/test1.c 346e9262793be825ebadd9e69600d1b4682650f1
 F src/test2.c 7a634c1e044be3ea5845e65155fdd1cab13936cb
 F src/test3.c e00795839be38f0345a4845170426fb17d828bf9
-F src/test4.c ff4ecde3cafc71337b04e8cb7da5bb88e85d70e7
-F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
+F src/test4.c 41056378671e7b00e6305fa9ac6fa27e6f96f406
+F src/test5.c 847eb5cfe89c197b6b494858ccf60be981235bdf
 F src/test6.c 0a0304a69cfa4962a429d084c6d451ff9e4fb572
-F src/test7.c 19474b1802858cd2017493c907f70ac2d57ab092
-F src/test8.c cc541736127cb95fe6966120f546c051e1c8aed8
+F src/test7.c 475b1fa7e3275408b40a3cbdc9508cbdc41ffa02
+F src/test8.c ae09a70c009097561d0d21e0291d383ad059d3f8
 F src/test9.c 904ebe0ed1472d6bad17a81e2ecbfc20017dc237
 F src/test_async.c da9f58f49faccd3a26ba89f58de125862351b6e2
 F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
@@ -168,7 +168,7 @@ F src/test_devsym.c 6012cb8e3acf812513511025a4fa5d626e0ba19b
 F src/test_func.c 24a556989685495013e08f311ae31c4ef86ddb8c
 F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
 F src/test_loadext.c df8ab3a6481ddebbdf0d28ebac5d9e0790f7860f
-F src/test_malloc.c daacb05668cc10e43c71291afc23088ff372488e
+F src/test_malloc.c f760300736b923c98f5bb620a3146d31845e4acc
 F src/test_md5.c 28209a4e2068711b5443c33104fe41f21d160071
 F src/test_mutex.c d3422d9f60cc1330249d102e74b333f0d24a0cb6
 F src/test_onefile.c 243157b10275251c5dc2d6619aee2ff9ae22379c
@@ -177,22 +177,22 @@ F src/test_schema.c 4b4bf7bb329326458c491b0e6facd4c8c4c5b479
 F src/test_server.c f0a403b5f699c09bd2b1236b6f69830fd6221f6b
 F src/test_tclvar.c 73530070df8378571c8ce6bbbbb993236ae3ad0b
 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
-F src/tokenize.c 70c6b5c394761816522611e70098e8c9bd58b486
-F src/trigger.c bdb56bb9db1a7b18f8505484051221ab5123f21d
-F src/update.c 4e698fcc0c91c241a960304c4236dc3a49603155
+F src/tokenize.c bfdc945527a4645bf54c8bf34d1f18c019b37117
+F src/trigger.c b61aaf7bff8e3763b234dbf46a1a64fb88a34e64
+F src/update.c 79b77a3cc8ed5f8903a7f37055fcedd69388dcae
 F src/utf.c 8d52f620a7153d90b058502124fe51d821fcdf57
-F src/util.c 06c5476b440f141987e5d829efd25900df72f629
+F src/util.c afe659ccc05d1f8af9e8631dabfec3ee3a7144af
 F src/vacuum.c ef342828002debc97514617af3424aea8ef8522c
-F src/vdbe.c aa0922d62e58dae8440d78a81a312531655db882
+F src/vdbe.c 40b188e5bed3d942596471fb5cb526a6516ebcec
 F src/vdbe.h c46155c221418bea29ee3a749d5950fcf85a70e2
-F src/vdbeInt.h 3c12ae0982c03ddac43a2531d41e6eca9fd89eb2
-F src/vdbeapi.c 17fa6f432197d759b15d3b37a7d672a34043c078
-F src/vdbeaux.c 0d221c85240eddbce498cc0136a5edd43927d67e
-F src/vdbeblob.c a20fe9345062b1a1b4cc187dc5fad45c9414033b
-F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136
-F src/vdbemem.c 0c72b58ffd759676ce4829f42bacb83842a58c21
-F src/vtab.c e67eaa311446ba216d0ffea916586da46e4e13f5
-F src/where.c e4c40d224cc6931bece3a33b35bd6b6a8deade3f
+F src/vdbeInt.h 1672cc137eb1d693090a17ded6682927fc851ca9
+F src/vdbeapi.c 25dd01c8b12978c14ec30e9a50666b23da767b27
+F src/vdbeaux.c 706d722088350fe18bc9c41250b4f19509f00390
+F src/vdbeblob.c f93110888ddc246215e9ba1f831d3d375bfd8355
+F src/vdbefifo.c 20fda2a7c4c0bcee1b90eb7e545fefcdbf2e1de7
+F src/vdbemem.c 7ab2a77d7f07ae74d678b6754488bcd50c4ea3aa
+F src/vtab.c 691813795f1bba5df57389c1cec62f9e73eebd9d
+F src/where.c ee4878e42ac97e2b3389b44cee34b35458321488
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/all.test 89e09ed0074083ac6f208dc3243429e8f89efb69
@@ -412,7 +412,7 @@ F test/malloc_common.tcl 17d60dfefc1598d1a7fe6da6511933536caea1d7
 F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
 F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893
 F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
-F test/memsubsys1.test ac18e8a045480611a467a3dc72c2ece4f530b9e4
+F test/memsubsys1.test 567ec52e742b669fac69cec303a93aead9377ce3
 F test/memsubsys2.test c05b541f9c2a1234a9dc2ff2233b3a9544fa5139
 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
 F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
@@ -474,7 +474,7 @@ F test/sidedelete.test 736ac1da08b3b1aa62df97fef2fcdb1b660111b9
 F test/soak.test 3c317b3e55e1160731030c8e865d1858fab66fea
 F test/softheap1.test 73ebd6e020d2954d965da2072baba5922fc8fb6a
 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
-F test/speed1.test cd5d9302f18946c18570e9ce6c736a5e283c8fcf
+F test/speed1.test 7ac6aecd2ab834de2fb81058944a5092f0368f67
 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
 F test/speed1p.test 1c932ff428cd7c26f0324a6ac59b16dfb2fd8efa
 F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded
@@ -590,8 +590,8 @@ F test/where6.test 42c4373595f4409d9c6a9987b4a60000ad664faf
 F test/zeroblob.test 792124852ec61458a2eb527b5091791215e0be95
 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
-F tool/lemon.c 13e9c37ab9e0cc182cc10b93ac0e5270bbf472c8
-F tool/lempar.c 49e9b3b9b48f6b0799560ed4d090627c51513344
+F tool/lemon.c bd3f56f7e949fc016639159d77936d07a29ad418
+F tool/lempar.c 4d115ee7c0c8a749d5b22abed731abb4e6546a5f
 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
 F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf
@@ -612,7 +612,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 1ffdd46f0bf5c82c652dedf74660e913b5699b18
-R 5006c92fb864a0ff2f6bebcd27de2d76
-U danielk1977
-Z 66bcbf1b22aa20922ecfd56da69c3011
+P 51be2e4463ca32f290feb610f59553b55bc67a5c
+R 1624ec122f5ffb86a37761ed2b47d75a
+U drh
+Z 5a311db47e066a208f5f741cb81e1882
index 69390dad28950af4026c39eca9705b180708e4e3..5aad7c290a2fb547bf75085f6f9c94b9dfe34f92 100644 (file)
@@ -1 +1 @@
-51be2e4463ca32f290feb610f59553b55bc67a5c
\ No newline at end of file
+e48f9697e9fea339e150ddc32940760027dd07d9
\ No newline at end of file
index c0a81090946c7bc92261663df118b9c8b3b4a4c8..ba929beddc1df089d5e20b66f586c9f983d00733 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that used to generate VDBE code
 ** that implements the ALTER TABLE command.
 **
-** $Id: alter.c,v 1.46 2008/07/15 14:47:19 drh Exp $
+** $Id: alter.c,v 1.47 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -80,7 +80,7 @@ static void renameTableFunc(
 
     zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
        zTableName, tname.z+tname.n);
-    sqlite3_result_text(context, zRet, -1, sqlite3_free);
+    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
   }
 }
 
@@ -155,7 +155,7 @@ static void renameTriggerFunc(
     */
     zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
        zTableName, tname.z+tname.n);
-    sqlite3_result_text(context, zRet, -1, sqlite3_free);
+    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
   }
 }
 #endif   /* !SQLITE_OMIT_TRIGGER */
@@ -198,7 +198,7 @@ static char *whereTempTriggers(Parse *pParse, Table *pTab){
         }else{
           tmp = zWhere;
           zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name);
-          sqlite3_free(tmp);
+          sqlite3DbFree(db, tmp);
         }
       }
     }
@@ -409,7 +409,7 @@ void sqlite3AlterRenameTable(
             "sql = sqlite_rename_trigger(sql, %Q), "
             "tbl_name = %Q "
             "WHERE %s;", zName, zName, zWhere);
-    sqlite3_free(zWhere);
+    sqlite3DbFree(db, zWhere);
   }
 #endif
 
@@ -417,8 +417,8 @@ void sqlite3AlterRenameTable(
   reloadTableSchema(pParse, pTab, zName);
 
 exit_rename_table:
-  sqlite3SrcListDelete(pSrc);
-  sqlite3_free(zName);
+  sqlite3SrcListDelete(db, pSrc);
+  sqlite3DbFree(db, zName);
 }
 
 
@@ -518,7 +518,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
       zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
       zTab
     );
-    sqlite3_free(zCol);
+    sqlite3DbFree(db, zCol);
   }
 
   /* If the default value of the new column is NULL, then set the file
@@ -585,6 +585,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
   if( !pNew ) goto exit_begin_add_column;
   pParse->pNewTable = pNew;
   pNew->nRef = 1;
+  pNew->db = db;
   pNew->nCol = pTab->nCol;
   assert( pNew->nCol>0 );
   nAlloc = (((pNew->nCol-1)/8)*8)+8;
@@ -614,7 +615,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
   sqlite3ChangeCookie(pParse, iDb);
 
 exit_begin_add_column:
-  sqlite3SrcListDelete(pSrc);
+  sqlite3SrcListDelete(db, pSrc);
   return;
 }
 #endif  /* SQLITE_ALTER_TABLE */
index aeb9972745abfb39c3cfb1b21379dbd42a9d7d9c..2c57d7fd0b9dcf28239b8de8fa0bf98f3ea745fc 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code associated with the ANALYZE command.
 **
-** @(#) $Id: analyze.c,v 1.42 2008/03/25 09:47:35 danielk1977 Exp $
+** @(#) $Id: analyze.c,v 1.43 2008/07/28 19:34:53 drh Exp $
 */
 #ifndef SQLITE_OMIT_ANALYZE
 #include "sqliteInt.h"
@@ -316,7 +316,7 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
       z = sqlite3NameFromToken(db, pName1);
       if( z ){
         pTab = sqlite3LocateTable(pParse, 0, z, 0);
-        sqlite3_free(z);
+        sqlite3DbFree(db, z);
         if( pTab ){
           analyzeTable(pParse, pTab);
         }
@@ -330,7 +330,7 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
       z = sqlite3NameFromToken(db, pTableName);
       if( z ){
         pTab = sqlite3LocateTable(pParse, 0, z, zDb);
-        sqlite3_free(z);
+        sqlite3DbFree(db, z);
         if( pTab ){
           analyzeTable(pParse, pTab);
         }
@@ -417,7 +417,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
   (void)sqlite3SafetyOff(db);
   rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
   (void)sqlite3SafetyOn(db);
-  sqlite3_free(zSql);
+  sqlite3DbFree(db, zSql);
   return rc;
 }
 
index 3964f379e09a130a56426d24f34153a460e5a09a..b8668f52bb5a718c902a23326eaf9f2ecffec90c 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.76 2008/06/15 02:51:47 drh Exp $
+** $Id: attach.c,v 1.77 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -214,7 +214,7 @@ attach_error:
   /* Return an error if we get here */
   if( zErrDyn ){
     sqlite3_result_error(context, zErrDyn, -1);
-    sqlite3_free(zErrDyn);
+    sqlite3DbFree(db, zErrDyn);
   }else{
     zErr[sizeof(zErr)-1] = 0;
     sqlite3_result_error(context, zErr, -1);
@@ -305,7 +305,7 @@ static void codeAttach(
       goto attach_end;
     }
     rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
-    sqlite3_free(zAuthArg);
+    sqlite3DbFree(db, zAuthArg);
     if(rc!=SQLITE_OK ){
       goto attach_end;
     }
@@ -345,9 +345,9 @@ static void codeAttach(
   }
   
 attach_end:
-  sqlite3ExprDelete(pFilename);
-  sqlite3ExprDelete(pDbname);
-  sqlite3ExprDelete(pKey);
+  sqlite3ExprDelete(db, pFilename);
+  sqlite3ExprDelete(db, pDbname);
+  sqlite3ExprDelete(db, pKey);
 }
 
 /*
index a51ed1b7826eed62afa21092ace0ba166cc4bbbe..0e91a5f1fa27944dd79ea9e3b3abf41ab5408887 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.491 2008/07/19 14:25:16 danielk1977 Exp $
+** $Id: btree.c,v 1.492 2008/07/28 19:34:53 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -6814,7 +6814,7 @@ char *sqlite3BtreeIntegrityCheck(
   nRef = sqlite3PagerRefcount(pBt->pPager);
   if( lockBtreeWithRetry(p)!=SQLITE_OK ){
     sqlite3BtreeLeave(p);
-    return sqlite3StrDup("Unable to acquire a read lock on the database");
+    return sqlite3DbStrDup(0, "Unable to acquire a read lock on the database");
   }
   sCheck.pBt = pBt;
   sCheck.pPager = pBt->pPager;
index 8a1d4bb7550df306adf4cdc622a13dc15857e2b7..19f09dc8d8296ab2380f6383043c53c697d14bbb 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.490 2008/07/08 23:40:20 drh Exp $
+** $Id: build.c,v 1.491 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -239,24 +239,24 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
   va_list ap;
   char *zSql;
   char *zErrMsg = 0;
+  sqlite3 *db = pParse->db;
 # define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
   char saveBuf[SAVE_SZ];
 
   if( pParse->nErr ) return;
   assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
   va_start(ap, zFormat);
-  zSql = sqlite3VMPrintf(pParse->db, zFormat, ap);
+  zSql = sqlite3VMPrintf(db, zFormat, ap);
   va_end(ap);
   if( zSql==0 ){
-    pParse->db->mallocFailed = 1;
     return;   /* A malloc must have failed */
   }
   pParse->nested++;
   memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
   memset(&pParse->nVar, 0, SAVE_SZ);
   sqlite3RunParser(pParse, zSql, &zErrMsg);
-  sqlite3_free(zErrMsg);
-  sqlite3_free(zSql);
+  sqlite3DbFree(db, zErrMsg);
+  sqlite3DbFree(db, zSql);
   memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
   pParse->nested--;
 }
@@ -358,8 +358,9 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
 ** Reclaim the memory used by an index
 */
 static void freeIndex(Index *p){
-  sqlite3_free(p->zColAff);
-  sqlite3_free(p);
+  sqlite3 *db = p->pTable->db;
+  sqlite3DbFree(db, p->zColAff);
+  sqlite3DbFree(db, p);
 }
 
 /*
@@ -453,7 +454,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
   for(i=j=2; i<db->nDb; i++){
     struct Db *pDb = &db->aDb[i];
     if( pDb->pBt==0 ){
-      sqlite3_free(pDb->zName);
+      sqlite3DbFree(db, pDb->zName);
       pDb->zName = 0;
       continue;
     }
@@ -466,7 +467,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
   db->nDb = j;
   if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
     memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
-    sqlite3_free(db->aDb);
+    sqlite3DbFree(db, db->aDb);
     db->aDb = db->aDbStatic;
   }
 }
@@ -484,15 +485,16 @@ void sqlite3CommitInternalChanges(sqlite3 *db){
 static void sqliteResetColumnNames(Table *pTable){
   int i;
   Column *pCol;
+  sqlite3 *db = pTable->db;
   assert( pTable!=0 );
   if( (pCol = pTable->aCol)!=0 ){
     for(i=0; i<pTable->nCol; i++, pCol++){
-      sqlite3_free(pCol->zName);
-      sqlite3ExprDelete(pCol->pDflt);
-      sqlite3_free(pCol->zType);
-      sqlite3_free(pCol->zColl);
+      sqlite3DbFree(db, pCol->zName);
+      sqlite3ExprDelete(db, pCol->pDflt);
+      sqlite3DbFree(db, pCol->zType);
+      sqlite3DbFree(db, pCol->zColl);
     }
-    sqlite3_free(pTable->aCol);
+    sqlite3DbFree(db, pTable->aCol);
   }
   pTable->aCol = 0;
   pTable->nCol = 0;
@@ -511,8 +513,10 @@ static void sqliteResetColumnNames(Table *pTable){
 void sqlite3DeleteTable(Table *pTable){
   Index *pIndex, *pNext;
   FKey *pFKey, *pNextFKey;
+  sqlite3 *db;
 
   if( pTable==0 ) return;
+  db = pTable->db;
 
   /* Do not delete the table until the reference count reaches zero. */
   pTable->nRef--;
@@ -537,21 +541,21 @@ void sqlite3DeleteTable(Table *pTable){
     pNextFKey = pFKey->pNextFrom;
     assert( sqlite3HashFind(&pTable->pSchema->aFKey,
                            pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
-    sqlite3_free(pFKey);
+    sqlite3DbFree(db, pFKey);
   }
 #endif
 
   /* Delete the Table structure itself.
   */
   sqliteResetColumnNames(pTable);
-  sqlite3_free(pTable->zName);
-  sqlite3_free(pTable->zColAff);
-  sqlite3SelectDelete(pTable->pSelect);
+  sqlite3DbFree(db, pTable->zName);
+  sqlite3DbFree(db, pTable->zColAff);
+  sqlite3SelectDelete(db, pTable->pSelect);
 #ifndef SQLITE_OMIT_CHECK
-  sqlite3ExprDelete(pTable->pCheck);
+  sqlite3ExprDelete(db, pTable->pCheck);
 #endif
   sqlite3VtabClear(pTable);
-  sqlite3_free(pTable);
+  sqlite3DbFree(db, pTable);
 }
 
 /*
@@ -641,7 +645,7 @@ int sqlite3FindDb(sqlite3 *db, Token *pName){
         break;
       }
     }
-    sqlite3_free(zName);
+    sqlite3DbFree(db, zName);
   }
   return i;
 }
@@ -832,6 +836,7 @@ void sqlite3StartTable(
   pTable->iPKey = -1;
   pTable->pSchema = db->aDb[iDb].pSchema;
   pTable->nRef = 1;
+  pTable->db = db;
   if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
   pParse->pNewTable = pTable;
 
@@ -911,7 +916,7 @@ void sqlite3StartTable(
 
   /* If an error occurs, we jump here */
 begin_table_error:
-  sqlite3_free(zName);
+  sqlite3DbFree(db, zName);
   return;
 }
 
@@ -954,7 +959,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){
   for(i=0; i<p->nCol; i++){
     if( STRICMP(z, p->aCol[i].zName) ){
       sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
-      sqlite3_free(z);
+      sqlite3DbFree(db, z);
       return;
     }
   }
@@ -962,7 +967,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){
     Column *aNew;
     aNew = sqlite3DbRealloc(pParse->db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
     if( aNew==0 ){
-      sqlite3_free(z);
+      sqlite3DbFree(db, z);
       return;
     }
     p->aCol = aNew;
@@ -1069,13 +1074,15 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){
   Table *p;
   int i;
   Column *pCol;
+  sqlite3 *db;
 
   if( (p = pParse->pNewTable)==0 ) return;
   i = p->nCol-1;
   if( i<0 ) return;
   pCol = &p->aCol[i];
-  sqlite3_free(pCol->zType);
-  pCol->zType = sqlite3NameFromToken(pParse->db, pType);
+  db = pParse->db;
+  sqlite3DbFree(db, pCol->zType);
+  pCol->zType = sqlite3NameFromToken(db, pType);
   pCol->affinity = sqlite3AffinityType(pType);
 }
 
@@ -1092,6 +1099,7 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){
 void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
   Table *p;
   Column *pCol;
+  sqlite3 *db = pParse->db;
   if( (p = pParse->pNewTable)!=0 ){
     pCol = &(p->aCol[p->nCol-1]);
     if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
@@ -1099,15 +1107,14 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
           pCol->zName);
     }else{
       Expr *pCopy;
-      sqlite3 *db = pParse->db;
-      sqlite3ExprDelete(pCol->pDflt);
+      sqlite3ExprDelete(db, pCol->pDflt);
       pCol->pDflt = pCopy = sqlite3ExprDup(db, pExpr);
       if( pCopy ){
         sqlite3TokenCopy(db, &pCopy->span, &pExpr->span);
       }
     }
   }
-  sqlite3ExprDelete(pExpr);
+  sqlite3ExprDelete(db, pExpr);
 }
 
 /*
@@ -1180,7 +1187,7 @@ void sqlite3AddPrimaryKey(
   }
 
 primary_key_exit:
-  sqlite3ExprListDelete(pList);
+  sqlite3ExprListDelete(pParse->db, pList);
   return;
 }
 
@@ -1191,9 +1198,9 @@ void sqlite3AddCheckConstraint(
   Parse *pParse,    /* Parsing context */
   Expr *pCheckExpr  /* The check expression */
 ){
+  sqlite3 *db = pParse->db;
 #ifndef SQLITE_OMIT_CHECK
   Table *pTab = pParse->pNewTable;
-  sqlite3 *db = pParse->db;
   if( pTab && !IN_DECLARE_VTAB ){
     /* The CHECK expression must be duplicated so that tokens refer
     ** to malloced space and not the (ephemeral) text of the CREATE TABLE
@@ -1202,7 +1209,7 @@ void sqlite3AddCheckConstraint(
                                   sqlite3ExprDup(db, pCheckExpr));
   }
 #endif
-  sqlite3ExprDelete(pCheckExpr);
+  sqlite3ExprDelete(db, pCheckExpr);
 }
 
 /*
@@ -1213,11 +1220,12 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){
   Table *p;
   int i;
   char *zColl;              /* Dequoted name of collation sequence */
+  sqlite3 *db;
 
   if( (p = pParse->pNewTable)==0 ) return;
   i = p->nCol-1;
-
-  zColl = sqlite3NameFromToken(pParse->db, pToken);
+  db = pParse->db;
+  zColl = sqlite3NameFromToken(db, pToken);
   if( !zColl ) return;
 
   if( sqlite3LocateCollSeq(pParse, zColl, -1) ){
@@ -1235,7 +1243,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){
       }
     }
   }else{
-    sqlite3_free(zColl);
+    sqlite3DbFree(db, zColl);
   }
 }
 
@@ -1568,7 +1576,7 @@ void sqlite3EndTable(
       zStmt,
       pParse->regRowid
     );
-    sqlite3_free(zStmt);
+    sqlite3DbFree(db, zStmt);
     sqlite3ChangeCookie(pParse, iDb);
 
 #ifndef SQLITE_OMIT_AUTOINCREMENT
@@ -1658,13 +1666,13 @@ void sqlite3CreateView(
 
   if( pParse->nVar>0 ){
     sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
-    sqlite3SelectDelete(pSelect);
+    sqlite3SelectDelete(db, pSelect);
     return;
   }
   sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
   p = pParse->pNewTable;
   if( p==0 || pParse->nErr ){
-    sqlite3SelectDelete(pSelect);
+    sqlite3SelectDelete(db, pSelect);
     return;
   }
   sqlite3TwoPartName(pParse, pName1, pName2, &pName);
@@ -1672,7 +1680,7 @@ void sqlite3CreateView(
   if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
     && sqlite3FixSelect(&sFix, pSelect)
   ){
-    sqlite3SelectDelete(pSelect);
+    sqlite3SelectDelete(db, pSelect);
     return;
   }
 
@@ -1682,7 +1690,7 @@ void sqlite3CreateView(
   ** they will persist after the current sqlite3_exec() call returns.
   */
   p->pSelect = sqlite3SelectDup(db, pSelect);
-  sqlite3SelectDelete(pSelect);
+  sqlite3SelectDelete(db, pSelect);
   if( db->mallocFailed ){
     return;
   }
@@ -1789,7 +1797,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
       pTable->nCol = 0;
       nErr++;
     }
-    sqlite3SelectDelete(pSel);
+    sqlite3SelectDelete(db, pSel);
   } else {
     nErr++;
   }
@@ -2105,7 +2113,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
   sqliteViewResetAll(db, iDb);
 
 exit_drop_table:
-  sqlite3SrcListDelete(pName);
+  sqlite3SrcListDelete(db, pName);
 }
 
 /*
@@ -2140,8 +2148,10 @@ void sqlite3CreateForeignKey(
   int i;
   int nCol;
   char *z;
+  sqlite3 *db;
 
   assert( pTo!=0 );
+  db = pParse->db;
   if( p==0 || pParse->nErr || IN_DECLARE_VTAB ) goto fk_end;
   if( pFromCol==0 ){
     int iCol = p->nCol-1;
@@ -2167,7 +2177,7 @@ void sqlite3CreateForeignKey(
       nByte += strlen(pToCol->a[i].zName) + 1;
     }
   }
-  pFKey = sqlite3DbMallocZero(pParse->db, nByte );
+  pFKey = sqlite3DbMallocZero(db, nByte );
   if( pFKey==0 ){
     goto fk_end;
   }
@@ -2221,10 +2231,10 @@ void sqlite3CreateForeignKey(
   pFKey = 0;
 
 fk_end:
-  sqlite3_free(pFKey);
+  sqlite3DbFree(db, pFKey);
 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
-  sqlite3ExprListDelete(pFromCol);
-  sqlite3ExprListDelete(pToCol);
+  sqlite3ExprListDelete(db, pFromCol);
+  sqlite3ExprListDelete(db, pToCol);
 }
 
 /*
@@ -2711,7 +2721,7 @@ void sqlite3CreateIndex(
         iMem,
         zStmt
     );
-    sqlite3_free(zStmt);
+    sqlite3DbFree(db, zStmt);
 
     /* Fill the index with data and reparse the schema. Code an OP_Expire
     ** to invalidate all pre-compiled statements.
@@ -2751,9 +2761,9 @@ exit_create_index:
   if( pIndex ){
     freeIndex(pIndex);
   }
-  sqlite3ExprListDelete(pList);
-  sqlite3SrcListDelete(pTblName);
-  sqlite3_free(zName);
+  sqlite3ExprListDelete(db, pList);
+  sqlite3SrcListDelete(db, pTblName);
+  sqlite3DbFree(db, zName);
   return;
 }
 
@@ -2882,7 +2892,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
   }
 
 exit_drop_index:
-  sqlite3SrcListDelete(pName);
+  sqlite3SrcListDelete(db, pName);
 }
 
 /*
@@ -2952,7 +2962,7 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
       &i
   );
   if( i<0 ){
-    sqlite3IdListDelete(pList);
+    sqlite3IdListDelete(db, pList);
     return 0;
   }
   pList->a[i].zName = sqlite3NameFromToken(db, pToken);
@@ -2962,14 +2972,14 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
 /*
 ** Delete an IdList.
 */
-void sqlite3IdListDelete(IdList *pList){
+void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
   int i;
   if( pList==0 ) return;
   for(i=0; i<pList->nId; i++){
-    sqlite3_free(pList->a[i].zName);
+    sqlite3DbFree(db, pList->a[i].zName);
   }
-  sqlite3_free(pList->a);
-  sqlite3_free(pList);
+  sqlite3DbFree(db, pList->a);
+  sqlite3DbFree(db, pList);
 }
 
 /*
@@ -3028,7 +3038,7 @@ SrcList *sqlite3SrcListAppend(
     pNew = sqlite3DbRealloc(db, pList,
                sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
     if( pNew==0 ){
-      sqlite3SrcListDelete(pList);
+      sqlite3SrcListDelete(db, pList);
       return 0;
     }
     pList = pNew;
@@ -3072,20 +3082,20 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
 /*
 ** Delete an entire SrcList including all its substructure.
 */
-void sqlite3SrcListDelete(SrcList *pList){
+void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
   int i;
   struct SrcList_item *pItem;
   if( pList==0 ) return;
   for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
-    sqlite3_free(pItem->zDatabase);
-    sqlite3_free(pItem->zName);
-    sqlite3_free(pItem->zAlias);
+    sqlite3DbFree(db, pItem->zDatabase);
+    sqlite3DbFree(db, pItem->zName);
+    sqlite3DbFree(db, pItem->zAlias);
     sqlite3DeleteTable(pItem->pTab);
-    sqlite3SelectDelete(pItem->pSelect);
-    sqlite3ExprDelete(pItem->pOn);
-    sqlite3IdListDelete(pItem->pUsing);
+    sqlite3SelectDelete(db, pItem->pSelect);
+    sqlite3ExprDelete(db, pItem->pOn);
+    sqlite3IdListDelete(db, pItem->pUsing);
   }
-  sqlite3_free(pList);
+  sqlite3DbFree(db, pList);
 }
 
 /*
@@ -3118,9 +3128,9 @@ SrcList *sqlite3SrcListAppendFromTerm(
   sqlite3 *db = pParse->db;
   p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
   if( p==0 || p->nSrc==0 ){
-    sqlite3ExprDelete(pOn);
-    sqlite3IdListDelete(pUsing);
-    sqlite3SelectDelete(pSubquery);
+    sqlite3ExprDelete(db, pOn);
+    sqlite3IdListDelete(db, pUsing);
+    sqlite3SelectDelete(db, pSubquery);
     return p;
   }
   pItem = &p->a[p->nSrc-1];
@@ -3425,11 +3435,11 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
     if( pColl ){
       if( zColl ){
         reindexDatabases(pParse, zColl);
-        sqlite3_free(zColl);
+        sqlite3DbFree(db, zColl);
       }
       return;
     }
-    sqlite3_free(zColl);
+    sqlite3DbFree(db, zColl);
   }
   iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
   if( iDb<0 ) return;
@@ -3439,11 +3449,11 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
   pTab = sqlite3FindTable(db, z, zDb);
   if( pTab ){
     reindexTable(pParse, pTab, 0);
-    sqlite3_free(z);
+    sqlite3DbFree(db, z);
     return;
   }
   pIndex = sqlite3FindIndex(db, z, zDb);
-  sqlite3_free(z);
+  sqlite3DbFree(db, z);
   if( pIndex ){
     sqlite3BeginWriteOperation(pParse, 0, iDb);
     sqlite3RefillIndex(pParse, pIndex, -1);
@@ -3458,7 +3468,7 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
 ** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
 **
 ** If successful, a pointer to the new structure is returned. In this case
-** the caller is responsible for calling sqlite3_free() on the returned 
+** the caller is responsible for calling sqlite3DbFree(db, ) on the returned 
 ** pointer. If an error occurs (out of memory or missing collation 
 ** sequence), NULL is returned and the state of pParse updated to reflect
 ** the error.
@@ -3467,7 +3477,8 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
   int i;
   int nCol = pIdx->nColumn;
   int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
-  KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes);
+  sqlite3 *db = pParse->db;
+  KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
 
   if( pKey ){
     pKey->db = pParse->db;
@@ -3483,7 +3494,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
   }
 
   if( pParse->nErr ){
-    sqlite3_free(pKey);
+    sqlite3DbFree(db, pKey);
     pKey = 0;
   }
   return pKey;
index 09f6841d9537ff8ce77692f8b31685769b174855..a77f99410031c47598487e9b0028a35afa08ad9c 100644 (file)
@@ -13,7 +13,7 @@
 ** This file contains functions used to access the internal hash tables
 ** of user defined functions and collation sequences.
 **
-** $Id: callback.c,v 1.25 2008/07/08 14:52:10 drh Exp $
+** $Id: callback.c,v 1.26 2008/07/28 19:34:53 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -30,7 +30,7 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
     char *zExternal = sqlite3DbStrNDup(db, zName, nName);
     if( !zExternal ) return;
     db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
-    sqlite3_free(zExternal);
+    sqlite3DbFree(db, zExternal);
   }
 #ifndef SQLITE_OMIT_UTF16
   if( db->xCollNeeded16 ){
@@ -182,7 +182,7 @@ static CollSeq *findCollSeqEntry(
       assert( pDel==0 || pDel==pColl );
       if( pDel!=0 ){
         db->mallocFailed = 1;
-        sqlite3_free(pDel);
+        sqlite3DbFree(db, pDel);
         pColl = 0;
       }
     }
@@ -312,7 +312,7 @@ FuncDef *sqlite3FindFunction(
     pBest->zName[nName] = 0;
     if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
       db->mallocFailed = 1;
-      sqlite3_free(pBest);
+      sqlite3DbFree(db, pBest);
       return 0;
     }
   }
@@ -325,7 +325,7 @@ FuncDef *sqlite3FindFunction(
 
 /*
 ** Free all resources held by the schema structure. The void* argument points
-** at a Schema struct. This function does not call sqlite3_free() on the 
+** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the 
 ** pointer itself, it just cleans up subsiduary resources (i.e. the contents
 ** of the schema hash tables).
 **
@@ -343,7 +343,7 @@ void sqlite3SchemaFree(void *p){
   sqlite3HashClear(&pSchema->aFKey);
   sqlite3HashClear(&pSchema->idxHash);
   for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
-    sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
+    sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
   }
   sqlite3HashClear(&temp2);
   sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
index d9b39b8b60367f8f9988a6216264558e0f7abdaf..08ee30c38ac1e600ea70d989ce0b8882f66373b2 100644 (file)
@@ -16,7 +16,7 @@
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.86 2008/07/25 16:39:25 drh Exp $
+** $Id: date.c,v 1.87 2008/07/28 19:34:53 drh Exp $
 **
 ** SQLite processes all times and dates as Julian Day numbers.  The
 ** dates and times are stored as the number of days since noon
@@ -849,9 +849,11 @@ static void strftimeFunc(
   u64 n;
   int i, j;
   char *z;
+  sqlite3 *db;
   const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
   char zBuf[100];
   if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
+  db = sqlite3_context_db_handle(context);
   for(i=0, n=1; zFmt[i]; i++, n++){
     if( zFmt[i]=='%' ){
       switch( zFmt[i+1] ){
@@ -887,11 +889,11 @@ static void strftimeFunc(
   }
   if( n<sizeof(zBuf) ){
     z = zBuf;
-  }else if( n>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){
+  }else if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     sqlite3_result_error_toobig(context);
     return;
   }else{
-    z = sqlite3Malloc( n );
+    z = sqlite3DbMallocRaw(db, n);
     if( z==0 ){
       sqlite3_result_error_nomem(context);
       return;
@@ -956,7 +958,7 @@ static void strftimeFunc(
   }
   z[j] = 0;
   sqlite3_result_text(context, z, -1,
-                      z==zBuf ? SQLITE_TRANSIENT : sqlite3_free);
+                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
 }
 
 /*
index 654570bc53758b4258ab6a0178956b24465330f0..26824241e234c710adf821f81f18ecf5532121b7 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** in order to generate code for DELETE FROM statements.
 **
-** $Id: delete.c,v 1.170 2008/07/08 23:40:20 drh Exp $
+** $Id: delete.c,v 1.171 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -107,7 +107,7 @@ void sqlite3MaterializeView(
   }
   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
   sqlite3Select(pParse, pDup, &dest, 0, 0, 0);
-  sqlite3SelectDelete(pDup);
+  sqlite3SelectDelete(db, pDup);
 }
 #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
 
@@ -415,8 +415,8 @@ void sqlite3DeleteFrom(
 
 delete_from_cleanup:
   sqlite3AuthContextPop(&sContext);
-  sqlite3SrcListDelete(pTabList);
-  sqlite3ExprDelete(pWhere);
+  sqlite3SrcListDelete(db, pTabList);
+  sqlite3ExprDelete(db, pWhere);
   return;
 }
 
index 87be4a91574ebcb90278cfcc511969a3883f0ef1..e8d8a1e9933053bd1be30feeeaf6875352137040 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.386 2008/07/18 17:03:53 drh Exp $
+** $Id: expr.c,v 1.387 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -56,7 +56,8 @@ char sqlite3ExprAffinity(Expr *pExpr){
 Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
   char *zColl = 0;            /* Dequoted name of collation sequence */
   CollSeq *pColl;
-  zColl = sqlite3NameFromToken(pParse->db, pName);
+  sqlite3 *db = pParse->db;
+  zColl = sqlite3NameFromToken(db, pName);
   if( pExpr && zColl ){
     pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
     if( pColl ){
@@ -64,7 +65,7 @@ Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
       pExpr->flags |= EP_ExpCollate;
     }
   }
-  sqlite3_free(zColl);
+  sqlite3DbFree(db, zColl);
   return pExpr;
 }
 
@@ -367,8 +368,8 @@ Expr *sqlite3Expr(
     ** this function must always be allocated with sqlite3Expr() for this 
     ** reason. 
     */
-    sqlite3ExprDelete(pLeft);
-    sqlite3ExprDelete(pRight);
+    sqlite3ExprDelete(db, pLeft);
+    sqlite3ExprDelete(db, pRight);
     return 0;
   }
   pNew->op = op;
@@ -477,10 +478,11 @@ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
 */
 Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
   Expr *pNew;
+  sqlite3 *db = pParse->db;
   assert( pToken );
-  pNew = sqlite3DbMallocZero(pParse->db, sizeof(Expr) );
+  pNew = sqlite3DbMallocZero(db, sizeof(Expr) );
   if( pNew==0 ){
-    sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
+    sqlite3ExprListDelete(db, pList); /* Avoid leaking memory when malloc fails */
     return 0;
   }
   pNew->op = TK_FUNCTION;
@@ -578,15 +580,15 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
 /*
 ** Recursively delete an expression tree.
 */
-void sqlite3ExprDelete(Expr *p){
+void sqlite3ExprDelete(sqlite3 *db, Expr *p){
   if( p==0 ) return;
-  if( p->span.dyn ) sqlite3_free((char*)p->span.z);
-  if( p->token.dyn ) sqlite3_free((char*)p->token.z);
-  sqlite3ExprDelete(p->pLeft);
-  sqlite3ExprDelete(p->pRight);
-  sqlite3ExprListDelete(p->pList);
-  sqlite3SelectDelete(p->pSelect);
-  sqlite3_free(p);
+  if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
+  if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);
+  sqlite3ExprDelete(db, p->pLeft);
+  sqlite3ExprDelete(db, p->pRight);
+  sqlite3ExprListDelete(db, p->pList);
+  sqlite3SelectDelete(db, p->pSelect);
+  sqlite3DbFree(db, p);
 }
 
 /*
@@ -637,7 +639,7 @@ Expr *sqlite3ExprDup(sqlite3 *db, Expr *p){
   return pNew;
 }
 void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){
-  if( pTo->dyn ) sqlite3_free((char*)pTo->z);
+  if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z);
   if( pFrom->z ){
     pTo->n = pFrom->n;
     pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);
@@ -657,7 +659,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){
   pNew->nExpr = pNew->nAlloc = p->nExpr;
   pNew->a = pItem = sqlite3DbMallocRaw(db,  p->nExpr*sizeof(p->a[0]) );
   if( pItem==0 ){
-    sqlite3_free(pNew);
+    sqlite3DbFree(db, pNew);
     return 0;
   } 
   pOldItem = p->a;
@@ -728,7 +730,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
   pNew->nId = pNew->nAlloc = p->nId;
   pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
   if( pNew->a==0 ){
-    sqlite3_free(pNew);
+    sqlite3DbFree(db, pNew);
     return 0;
   }
   for(i=0; i<p->nId; i++){
@@ -814,8 +816,8 @@ ExprList *sqlite3ExprListAppend(
 
 no_mem:     
   /* Avoid leaking memory if malloc has failed. */
-  sqlite3ExprDelete(pExpr);
-  sqlite3ExprListDelete(pList);
+  sqlite3ExprDelete(db, pExpr);
+  sqlite3ExprListDelete(db, pList);
   return 0;
 }
 
@@ -839,18 +841,18 @@ void sqlite3ExprListCheckLength(
 /*
 ** Delete an entire expression list.
 */
-void sqlite3ExprListDelete(ExprList *pList){
+void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
   int i;
   struct ExprList_item *pItem;
   if( pList==0 ) return;
   assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
   assert( pList->nExpr<=pList->nAlloc );
   for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
-    sqlite3ExprDelete(pItem->pExpr);
-    sqlite3_free(pItem->zName);
+    sqlite3ExprDelete(db, pItem->pExpr);
+    sqlite3DbFree(db, pItem->zName);
   }
-  sqlite3_free(pList->a);
-  sqlite3_free(pList);
+  sqlite3DbFree(db, pList->a);
+  sqlite3DbFree(db, pList);
 }
 
 /*
@@ -1264,7 +1266,7 @@ static int lookupName(
           pOrig = pEList->a[j].pExpr;
           if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
             sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
-            sqlite3_free(zCol);
+            sqlite3DbFree(db, zCol);
             return 2;
           }
           pDup = sqlite3ExprDup(db, pOrig);
@@ -1272,10 +1274,10 @@ static int lookupName(
             pDup->pColl = pExpr->pColl;
             pDup->flags |= EP_ExpCollate;
           }
-          if( pExpr->span.dyn ) sqlite3_free((char*)pExpr->span.z);
-          if( pExpr->token.dyn ) sqlite3_free((char*)pExpr->token.z);
+          if( pExpr->span.dyn ) sqlite3DbFree(db, (char*)pExpr->span.z);
+          if( pExpr->token.dyn ) sqlite3DbFree(db, (char*)pExpr->token.z);
           memcpy(pExpr, pDup, sizeof(*pExpr));
-          sqlite3_free(pDup);
+          sqlite3DbFree(db, pDup);
           cnt = 1;
           pMatch = 0;
           assert( zTab==0 && zDb==0 );
@@ -1303,7 +1305,7 @@ static int lookupName(
   ** fields are not changed in any context.
   */
   if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
-    sqlite3_free(zCol);
+    sqlite3DbFree(db, zCol);
     return 0;
   }
 
@@ -1343,15 +1345,15 @@ static int lookupName(
 lookupname_end:
   /* Clean up and return
   */
-  sqlite3_free(zDb);
-  sqlite3_free(zTab);
-  sqlite3ExprDelete(pExpr->pLeft);
+  sqlite3DbFree(db, zDb);
+  sqlite3DbFree(db, zTab);
+  sqlite3ExprDelete(db, pExpr->pLeft);
   pExpr->pLeft = 0;
-  sqlite3ExprDelete(pExpr->pRight);
+  sqlite3ExprDelete(db, pExpr->pRight);
   pExpr->pRight = 0;
   pExpr->op = TK_COLUMN;
 lookupname_end_2:
-  sqlite3_free(zCol);
+  sqlite3DbFree(db, zCol);
   if( cnt==1 ){
     assert( pNC!=0 );
     sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
@@ -1966,7 +1968,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr, int rMayHaveNull){
         sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
         VdbeComment((v, "Init EXISTS result"));
       }
-      sqlite3ExprDelete(pSel->pLimit);
+      sqlite3ExprDelete(pParse->db, pSel->pLimit);
       pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
       if( sqlite3Select(pParse, pSel, &dest, 0, 0, 0) ){
         return;
index 47709caab7b0a0722c4a7555a5384fed0db2bf25..d4489f9d4cac0c19b2e7079d4804584d23ecf0cb 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.195 2008/07/08 22:28:49 shane Exp $
+** $Id: func.c,v 1.196 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -832,14 +832,14 @@ static void replaceFunc(
       nOut += nRep - nPattern;
       if( nOut>=db->aLimit[SQLITE_LIMIT_LENGTH] ){
         sqlite3_result_error_toobig(context);
-        sqlite3_free(zOut);
+        sqlite3DbFree(db, zOut);
         return;
       }
       zOld = zOut;
       zOut = sqlite3_realloc(zOut, (int)nOut);
       if( zOut==0 ){
         sqlite3_result_error_nomem(context);
-        sqlite3_free(zOld);
+        sqlite3DbFree(db, zOld);
         return;
       }
       memcpy(&zOut[j], zRep, nRep);
index 4211c58356de8dbf6d4959039b779cfe38860c9a..fa59d4a8486a800d848987f1c87e3e2ed360d032 100644 (file)
@@ -12,7 +12,7 @@
 **
 ** This file contains definitions of global variables and contants.
 **
-** $Id: global.c,v 1.3 2008/07/08 14:52:10 drh Exp $
+** $Id: global.c,v 1.4 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -66,4 +66,12 @@ const unsigned char sqlite3UpperToLower[] = {
 ** The following singleton contains the global configuration for
 ** the SQLite library.
 */
-struct Sqlite3Config sqlite3Config = { 1, 1, 1, 0x7ffffffe };
+struct Sqlite3Config sqlite3Config = {
+   1,                /* bMemstat */
+   1,                /* bCoreMutex */
+   1,                /* bFullMutex */
+   0x7ffffffe,       /* mxStrlen */
+   100,              /* szLookaside */
+   500,              /* nLookaside */
+   /* Other fields all default to zero */
+};
index 9dda3954f10c5e9f6c2cf46a349ec22bf43b3281..9a3d46f1b3db0535cb407f90c4a73640a736cb0e 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.247 2008/07/08 23:40:20 drh Exp $
+** $Id: insert.c,v 1.248 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -45,8 +45,9 @@ void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
     int n;
     Table *pTab = pIdx->pTable;
     sqlite3 *db = sqlite3VdbeDb(v);
-    pIdx->zColAff = (char *)sqlite3DbMallocRaw(db, pIdx->nColumn+2);
+    pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2);
     if( !pIdx->zColAff ){
+      db->mallocFailed = 1;
       return;
     }
     for(n=0; n<pIdx->nColumn; n++){
@@ -86,8 +87,9 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
     int i;
     sqlite3 *db = sqlite3VdbeDb(v);
 
-    zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1);
+    zColAff = (char *)sqlite3Malloc(pTab->nCol+1);
     if( !zColAff ){
+      db->mallocFailed = 1;
       return;
     }
 
@@ -994,11 +996,11 @@ void sqlite3Insert(
   }
 
 insert_cleanup:
-  sqlite3SrcListDelete(pTabList);
-  sqlite3ExprListDelete(pList);
-  sqlite3SelectDelete(pSelect);
-  sqlite3IdListDelete(pColumn);
-  sqlite3_free(aRegIdx);
+  sqlite3SrcListDelete(db, pTabList);
+  sqlite3ExprListDelete(db, pList);
+  sqlite3SelectDelete(db, pSelect);
+  sqlite3IdListDelete(db, pColumn);
+  sqlite3DbFree(db, aRegIdx);
 }
 
 /*
index 6d84d70391582df95d0da71a88ee7a7ec55275ce..825c57b25d27a7824ae272408d59ee8d101a4fe1 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: legacy.c,v 1.27 2008/06/15 02:51:47 drh Exp $
+** $Id: legacy.c,v 1.28 2008/07/28 19:34:53 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -122,13 +122,13 @@ int sqlite3_exec(
       }
     }
 
-    sqlite3_free(azCols);
+    sqlite3DbFree(db, azCols);
     azCols = 0;
   }
 
 exec_out:
   if( pStmt ) sqlite3_finalize(pStmt);
-  if( azCols ) sqlite3_free(azCols);
+  sqlite3DbFree(db, azCols);
 
   rc = sqlite3ApiExit(db, rc);
   if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
index b9b47b6ed30ac88b69648008e8c1130d648649a6..2d44f315be428b36e1ff84ea15560fffbc3fb662 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains code used to dynamically load extensions into
 ** the SQLite library.
 **
-** $Id: loadext.c,v 1.51 2008/07/08 14:17:35 danielk1977 Exp $
+** $Id: loadext.c,v 1.52 2008/07/28 19:34:53 drh Exp $
 */
 
 #ifndef SQLITE_CORE
@@ -326,7 +326,7 @@ static const sqlite3_api_routines sqlite3Apis = {
 **
 ** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with 
 ** error message text.  The calling function should free this memory
-** by calling sqlite3_free().
+** by calling sqlite3DbFree(db, ).
 */
 static int sqlite3LoadExtension(
   sqlite3 *db,          /* Load the extension into this database connection */
@@ -365,7 +365,7 @@ static int sqlite3LoadExtension(
       sqlite3_snprintf(sizeof(zErr)-1, zErr, 
           "unable to open shared library [%s]", zFile);
       sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
-      *pzErrMsg = sqlite3DbStrDup(db, zErr);
+      *pzErrMsg = sqlite3DbStrDup(0, zErr);
     }
     return SQLITE_ERROR;
   }
@@ -378,7 +378,7 @@ static int sqlite3LoadExtension(
       sqlite3_snprintf(sizeof(zErr)-1, zErr,
           "no entry point [%s] in shared library [%s]", zProc,zFile);
       sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
-      *pzErrMsg = sqlite3DbStrDup(db, zErr);
+      *pzErrMsg = sqlite3DbStrDup(0, zErr);
       sqlite3OsDlClose(pVfs, handle);
     }
     return SQLITE_ERROR;
@@ -400,7 +400,7 @@ static int sqlite3LoadExtension(
   if( db->nExtension>0 ){
     memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1));
   }
-  sqlite3_free(db->aExtension);
+  sqlite3DbFree(db, db->aExtension);
   db->aExtension = aHandle;
 
   db->aExtension[db->nExtension-1] = handle;
@@ -429,7 +429,7 @@ void sqlite3CloseExtensions(sqlite3 *db){
   for(i=0; i<db->nExtension; i++){
     sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
   }
-  sqlite3_free(db->aExtension);
+  sqlite3DbFree(db, db->aExtension);
 }
 
 /*
index cf558783983442ea276c34bc3ed3a1e13efc0093..92e259fc750df7d4fca0f9f691e9e6c519945188 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.482 2008/07/25 08:49:00 danielk1977 Exp $
+** $Id: main.c,v 1.483 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -275,6 +275,12 @@ int sqlite3_config(int op, ...){
     }
 #endif
 
+    case SQLITE_CONFIG_LOOKASIDE: {
+      sqlite3Config.szLookaside = va_arg(ap, int);
+      sqlite3Config.nLookaside = va_arg(ap, int);
+      break;
+    }
+
     default: {
       rc = SQLITE_ERROR;
       break;
@@ -284,6 +290,60 @@ int sqlite3_config(int op, ...){
   return rc;
 }
 
+/*
+** Set up the lookaside buffers for a database connection.
+** Return SQLITE_OK on success.  
+** If lookaside is already active, return SQLITE_BUSY.
+*/
+static int setupLookaside(sqlite3 *db, int sz, int cnt){
+  void *pStart;
+  if( db->lookaside.nOut ){
+    return SQLITE_BUSY;
+  }
+  if( sz<0 ) sz = 0;
+  if( cnt<0 ) cnt = 0;
+  sz = (sz+7)&~7;
+  sqlite3BeginBenignMalloc();
+  pStart = sqlite3Malloc( sz*cnt );
+  sqlite3EndBenignMalloc();
+  if( pStart ){
+    int i;
+    LookasideSlot *p;
+    sqlite3_free(db->lookaside.pStart);
+    db->lookaside.pFree = 0;
+    db->lookaside.pStart = pStart;
+    p = (LookasideSlot*)pStart;
+    for(i=cnt-1; i>=0; i--){
+      p->pNext = db->lookaside.pFree;
+      db->lookaside.pFree = p;
+      p = (LookasideSlot*)&((u8*)p)[sz];
+    }
+    db->lookaside.pEnd = p;
+    db->lookaside.bEnabled = 1;
+    db->lookaside.sz = sz;
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Configuration settings for an individual database connection
+*/
+int sqlite3_db_config(sqlite3 *db, int op, ...){
+  va_list ap;
+  int rc = SQLITE_OK;
+  va_start(ap, op);
+  switch( op ){
+    case SQLITE_CONFIG_LOOKASIDE: {
+      int sz = va_arg(ap, int);
+      int cnt = va_arg(ap, int);
+      rc = setupLookaside(db, sz, cnt);
+      break;
+    }
+  }
+  va_end(ap);
+  return rc;
+}
+
 /*
 ** Routine needed to support the testcase() macro.
 */
@@ -433,7 +493,7 @@ int sqlite3_close(sqlite3 *db){
     FuncDef *pFunc, *pNext;
     for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
       pNext = pFunc->pNext;
-      sqlite3_free(pFunc);
+      sqlite3DbFree(db, pFunc);
     }
   }
 
@@ -445,7 +505,7 @@ int sqlite3_close(sqlite3 *db){
         pColl[j].xDel(pColl[j].pUser);
       }
     }
-    sqlite3_free(pColl);
+    sqlite3DbFree(db, pColl);
   }
   sqlite3HashClear(&db->aCollSeq);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -454,7 +514,7 @@ int sqlite3_close(sqlite3 *db){
     if( pMod->xDestroy ){
       pMod->xDestroy(pMod->pAux);
     }
-    sqlite3_free(pMod);
+    sqlite3DbFree(db, pMod);
   }
   sqlite3HashClear(&db->aModule);
 #endif
@@ -474,10 +534,11 @@ int sqlite3_close(sqlite3 *db){
   ** the same sqliteMalloc() as the one that allocates the database 
   ** structure?
   */
-  sqlite3_free(db->aDb[1].pSchema);
+  sqlite3DbFree(db, db->aDb[1].pSchema);
   sqlite3_mutex_leave(db->mutex);
   db->magic = SQLITE_MAGIC_CLOSED;
   sqlite3_mutex_free(db->mutex);
+  sqlite3_free(db->lookaside.pStart);
   sqlite3_free(db);
   return SQLITE_OK;
 }
@@ -807,7 +868,7 @@ int sqlite3_create_function16(
   assert( !db->mallocFailed );
   zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
   rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
-  sqlite3_free(zFunc8);
+  sqlite3DbFree(db, zFunc8);
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
   return rc;
@@ -1312,6 +1373,7 @@ static int openDatabase(
   db->nDb = 2;
   db->magic = SQLITE_MAGIC_BUSY;
   db->aDb = db->aDbStatic;
+
   assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
   memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
   db->autoCommit = 1;
@@ -1453,6 +1515,9 @@ static int openDatabase(
                           SQLITE_DEFAULT_LOCKING_MODE);
 #endif
 
+  /* Enable the lookaside-malloc subsystem */
+  setupLookaside(db, sqlite3Config.szLookaside, sqlite3Config.nLookaside);
+
 opendb_out:
   if( db ){
     assert( db->mutex!=0 || isThreadsafe==0 || sqlite3Config.bFullMutex==0 );
@@ -1580,7 +1645,7 @@ int sqlite3_create_collation16(
   zName8 = sqlite3Utf16to8(db, zName, -1);
   if( zName8 ){
     rc = createCollation(db, zName8, enc, pCtx, xCompare, 0);
-    sqlite3_free(zName8);
+    sqlite3DbFree(db, zName8);
   }
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
@@ -1769,13 +1834,13 @@ error_out:
   if( pAutoinc ) *pAutoinc = autoinc;
 
   if( SQLITE_OK==rc && !pTab ){
-    sqlite3_free(zErrMsg);
+    sqlite3DbFree(db, zErrMsg);
     zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
         zColumnName);
     rc = SQLITE_ERROR;
   }
   sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
-  sqlite3_free(zErrMsg);
+  sqlite3DbFree(db, zErrMsg);
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
   return rc;
index 86ba2be96c7f565693b43db2506d7a28bda30852..f90e62753656248fd920d9caaf2db052b695fba3 100644 (file)
@@ -12,7 +12,7 @@
 **
 ** Memory allocation functions used throughout sqlite.
 **
-** $Id: malloc.c,v 1.29 2008/07/18 18:56:17 drh Exp $
+** $Id: malloc.c,v 1.30 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -453,6 +453,13 @@ void sqlite3PageFree(void *p){
   }
 }
 
+/*
+** TRUE if p is a lookaside memory allocation from db
+*/
+static int isLookaside(sqlite3 *db, void *p){
+  return db && p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
+}
+
 /*
 ** Return the size of a memory allocation previously obtained from
 ** sqlite3Malloc() or sqlite3_malloc().
@@ -460,6 +467,13 @@ void sqlite3PageFree(void *p){
 int sqlite3MallocSize(void *p){
   return sqlite3Config.m.xSize(p);
 }
+int sqlite3DbMallocSize(sqlite3 *db, void *p){
+  if( isLookaside(db, p) ){
+    return db->lookaside.sz;
+  }else{
+    return sqlite3Config.m.xSize(p);
+  }
+}
 
 /*
 ** Free memory previously obtained from sqlite3Malloc().
@@ -476,6 +490,21 @@ void sqlite3_free(void *p){
   }
 }
 
+/*
+** Free memory that might be associated with a particular database
+** connection.
+*/
+void sqlite3DbFree(sqlite3 *db, void *p){
+  if( isLookaside(db, p) ){
+    LookasideSlot *pBuf = (LookasideSlot*)p;
+    pBuf->pNext = db->lookaside.pFree;
+    db->lookaside.pFree = pBuf;
+    db->lookaside.nOut--;
+  }else{
+    sqlite3_free(p);
+  }
+}
+
 /*
 ** Change the size of an existing memory allocation
 */
@@ -558,26 +587,53 @@ void *sqlite3DbMallocZero(sqlite3 *db, int n){
 ** the mallocFailed flag in the connection pointer.
 */
 void *sqlite3DbMallocRaw(sqlite3 *db, int n){
-  void *p = 0;
-  if( !db || db->mallocFailed==0 ){
-    p = sqlite3Malloc(n);
-    if( !p && db ){
-      db->mallocFailed = 1;
+  void *p;
+  if( db ){
+    LookasideSlot *pBuf;
+    if( db->mallocFailed ){
+      return 0;
+    }
+    if( db->lookaside.bEnabled && n<=db->lookaside.sz
+         && (pBuf = db->lookaside.pFree)!=0 ){
+      db->lookaside.pFree = pBuf->pNext;
+      db->lookaside.nOut++;
+      if( db->lookaside.nOut>db->lookaside.mxOut ){
+        db->lookaside.mxOut = db->lookaside.nOut;
+      }
+      return (void*)pBuf;
     }
   }
+  p = sqlite3Malloc(n);
+  if( !p && db ){
+    db->mallocFailed = 1;
+  }
   return p;
 }
 
 /*
 ** Resize the block of memory pointed to by p to n bytes. If the
-** resize fails, set the mallocFailed flag inthe connection object.
+** resize fails, set the mallocFailed flag in the connection object.
 */
 void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
   void *pNew = 0;
   if( db->mallocFailed==0 ){
-    pNew = sqlite3_realloc(p, n);
-    if( !pNew ){
-      db->mallocFailed = 1;
+    if( p==0 ){
+      return sqlite3DbMallocRaw(db, n);
+    }
+    if( isLookaside(db, p) ){
+      if( n<=db->lookaside.sz ){
+        return p;
+      }
+      pNew = sqlite3DbMallocRaw(db, n);
+      if( pNew ){
+        memcpy(pNew, p, db->lookaside.sz);
+        sqlite3DbFree(db, p);
+      }
+    }else{
+      pNew = sqlite3_realloc(p, n);
+      if( !pNew ){
+        db->mallocFailed = 1;
+      }
     }
   }
   return pNew;
@@ -591,7 +647,7 @@ void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){
   void *pNew;
   pNew = sqlite3DbRealloc(db, p, n);
   if( !pNew ){
-    sqlite3_free(p);
+    sqlite3DbFree(db, p);
   }
   return pNew;
 }
@@ -603,37 +659,30 @@ void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){
 ** called via macros that record the current file and line number in the
 ** ThreadData structure.
 */
-char *sqlite3StrDup(const char *z){
+char *sqlite3DbStrDup(sqlite3 *db, const char *z){
   char *zNew;
-  int n;
-  if( z==0 ) return 0;
+  size_t n;
+  if( z==0 ){
+    return 0;
+  }
   n = strlen(z)+1;
-  zNew = sqlite3Malloc(n);
-  if( zNew ) memcpy(zNew, z, n);
-  return zNew;
-}
-char *sqlite3StrNDup(const char *z, int n){
-  char *zNew;
-  if( z==0 ) return 0;
-  zNew = sqlite3Malloc(n+1);
+  assert( (n&0x7fffffff)==n );
+  zNew = sqlite3DbMallocRaw(db, (int)n);
   if( zNew ){
     memcpy(zNew, z, n);
-    zNew[n] = 0;
-  }
-  return zNew;
-}
-
-char *sqlite3DbStrDup(sqlite3 *db, const char *z){
-  char *zNew = sqlite3StrDup(z);
-  if( z && !zNew ){
-    db->mallocFailed = 1;
   }
   return zNew;
 }
 char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
-  char *zNew = sqlite3StrNDup(z, n);
-  if( z && !zNew ){
-    db->mallocFailed = 1;
+  char *zNew;
+  if( z==0 ){
+    return 0;
+  }
+  assert( (n&0x7fffffff)==n );
+  zNew = sqlite3DbMallocRaw(db, n+1);
+  if( zNew ){
+    memcpy(zNew, z, n);
+    zNew[n] = 0;
   }
   return zNew;
 }
@@ -650,7 +699,7 @@ void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
   va_start(ap, zFormat);
   z = sqlite3VMPrintf(db, zFormat, ap);
   va_end(ap);
-  sqlite3_free(*pz);
+  sqlite3DbFree(db, *pz);
   *pz = z;
 }
 
index aafa568ece76ddaac97d72f0087432c09a9edcc4..95723ad39c91012bef868f41e9e9d255a6f063bd 100644 (file)
@@ -32,7 +32,7 @@
 ** fragmentation. On some systems, heap fragmentation can cause a 
 ** significant real-time slowdown.
 **
-** $Id: mem6.c,v 1.6 2008/07/25 16:07:01 danielk1977 Exp $
+** $Id: mem6.c,v 1.7 2008/07/28 19:34:53 drh Exp $
 */
 
 #ifdef SQLITE_ENABLE_MEMSYS6
@@ -418,8 +418,9 @@ static void memsys6Free(void *pPrior){
   void *p = &((u32 *)pPrior)[-2];
   iSlot = ((u32 *)p)[0];
   if( iSlot ){
+    Mem6Chunk *pChunk;
     mem6Enter();
-    Mem6Chunk *pChunk = (Mem6Chunk *)(&((u8 *)p)[-1 * iSlot]);
+    pChunk = (Mem6Chunk *)(&((u8 *)p)[-1 * iSlot]);
     chunkFree(pChunk, p);
     if( chunkIsEmpty(pChunk) ){
       freeChunk(pChunk);
index 9d066d090b802d31a33f48b94a1847568d68120d..0f141c3782086b2fe31fecf159e2338e91bd9e2a 100644 (file)
--- a/src/os.c
+++ b/src/os.c
@@ -13,7 +13,7 @@
 ** This file contains OS interface code that is common to all
 ** architectures.
 **
-** $Id: os.c,v 1.119 2008/06/26 18:16:06 drh Exp $
+** $Id: os.c,v 1.120 2008/07/28 19:34:53 drh Exp $
 */
 #define _SQLITE_OS_C_ 1
 #include "sqliteInt.h"
@@ -36,7 +36,7 @@
 **     sqlite3OsLock()
 **
 */
-#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
+#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) && 0
   #define DO_OS_MALLOC_TEST if (1) {            \
     void *pTstAlloc = sqlite3Malloc(10);       \
     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
index 7642fe93f3eb6257511e207a9ae82fdb25d61aaa..8fe3acb7579be75a8bcef6015c6e10cefceb5636 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.246 2008/07/18 17:03:53 drh Exp $
+** @(#) $Id: parse.y,v 1.247 2008/07/28 19:34:53 drh Exp $
 */
 
 // All token codes are small integers with #defines that begin with "TK_"
@@ -135,7 +135,7 @@ create_table_args ::= LP columnlist conslist_opt(X) RP(Y). {
 }
 create_table_args ::= AS select(S). {
   sqlite3EndTable(pParse,0,0,S);
-  sqlite3SelectDelete(S);
+  sqlite3SelectDelete(pParse->db, S);
 }
 columnlist ::= columnlist COMMA column.
 columnlist ::= column.
@@ -362,13 +362,13 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). {
 cmd ::= select(X).  {
   SelectDest dest = {SRT_Callback, 0, 0, 0, 0};
   sqlite3Select(pParse, X, &dest, 0, 0, 0);
-  sqlite3SelectDelete(X);
+  sqlite3SelectDelete(pParse->db, X);
 }
 
 %type select {Select*}
-%destructor select {sqlite3SelectDelete($$);}
+%destructor select {sqlite3SelectDelete(pParse->db, $$);}
 %type oneselect {Select*}
-%destructor oneselect {sqlite3SelectDelete($$);}
+%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
 
 select(A) ::= oneselect(X).                      {A = X;}
 %ifndef SQLITE_OMIT_COMPOUND_SELECT
@@ -377,7 +377,7 @@ select(A) ::= select(X) multiselect_op(Y) oneselect(Z).  {
     Z->op = Y;
     Z->pPrior = X;
   }else{
-    sqlite3SelectDelete(X);
+    sqlite3SelectDelete(pParse->db, X);
   }
   A = Z;
 }
@@ -405,9 +405,9 @@ distinct(A) ::= .           {A = 0;}
 // opcode of TK_ALL.
 //
 %type selcollist {ExprList*}
-%destructor selcollist {sqlite3ExprListDelete($$);}
+%destructor selcollist {sqlite3ExprListDelete(pParse->db, $$);}
 %type sclp {ExprList*}
-%destructor sclp {sqlite3ExprListDelete($$);}
+%destructor sclp {sqlite3ExprListDelete(pParse->db, $$);}
 sclp(A) ::= selcollist(X) COMMA.             {A = X;}
 sclp(A) ::= .                                {A = 0;}
 selcollist(A) ::= sclp(P) expr(X) as(Y).     {
@@ -434,11 +434,11 @@ as(X) ::= .            {X.n = 0;}
 
 
 %type seltablist {SrcList*}
-%destructor seltablist {sqlite3SrcListDelete($$);}
+%destructor seltablist {sqlite3SrcListDelete(pParse->db, $$);}
 %type stl_prefix {SrcList*}
-%destructor stl_prefix {sqlite3SrcListDelete($$);}
+%destructor stl_prefix {sqlite3SrcListDelete(pParse->db, $$);}
 %type from {SrcList*}
-%destructor from {sqlite3SrcListDelete($$);}
+%destructor from {sqlite3SrcListDelete(pParse->db, $$);}
 
 // A complete FROM clause.
 //
@@ -470,7 +470,7 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
   // a grouping of table and subqueries.
   //
   %type seltablist_paren {Select*}
-  %destructor seltablist_paren {sqlite3SelectDelete($$);}
+  %destructor seltablist_paren {sqlite3SelectDelete(pParse->db, $$);}
   seltablist_paren(A) ::= select(S).      {A = S;}
   seltablist_paren(A) ::= seltablist(F).  {
      sqlite3SrcListShiftJoinType(F);
@@ -483,7 +483,7 @@ dbnm(A) ::= .          {A.z=0; A.n=0;}
 dbnm(A) ::= DOT nm(X). {A = X;}
 
 %type fullname {SrcList*}
-%destructor fullname {sqlite3SrcListDelete($$);}
+%destructor fullname {sqlite3SrcListDelete(pParse->db, $$);}
 fullname(A) ::= nm(X) dbnm(Y).  {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y);}
 
 %type joinop {int}
@@ -495,22 +495,22 @@ joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
                                        { X = sqlite3JoinType(pParse,&A,&B,&C); }
 
 %type on_opt {Expr*}
-%destructor on_opt {sqlite3ExprDelete($$);}
+%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);}
 on_opt(N) ::= ON expr(E).   {N = E;}
 on_opt(N) ::= .             {N = 0;}
 
 %type using_opt {IdList*}
-%destructor using_opt {sqlite3IdListDelete($$);}
+%destructor using_opt {sqlite3IdListDelete(pParse->db, $$);}
 using_opt(U) ::= USING LP inscollist(L) RP.  {U = L;}
 using_opt(U) ::= .                        {U = 0;}
 
 
 %type orderby_opt {ExprList*}
-%destructor orderby_opt {sqlite3ExprListDelete($$);}
+%destructor orderby_opt {sqlite3ExprListDelete(pParse->db, $$);}
 %type sortlist {ExprList*}
-%destructor sortlist {sqlite3ExprListDelete($$);}
+%destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);}
 %type sortitem {Expr*}
-%destructor sortitem {sqlite3ExprDelete($$);}
+%destructor sortitem {sqlite3ExprDelete(pParse->db, $$);}
 
 orderby_opt(A) ::= .                          {A = 0;}
 orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
@@ -531,12 +531,12 @@ sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
 sortorder(A) ::= .              {A = SQLITE_SO_ASC;}
 
 %type groupby_opt {ExprList*}
-%destructor groupby_opt {sqlite3ExprListDelete($$);}
+%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
 groupby_opt(A) ::= .                      {A = 0;}
 groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}
 
 %type having_opt {Expr*}
-%destructor having_opt {sqlite3ExprDelete($$);}
+%destructor having_opt {sqlite3ExprDelete(pParse->db, $$);}
 having_opt(A) ::= .                {A = 0;}
 having_opt(A) ::= HAVING expr(X).  {A = X;}
 
@@ -550,8 +550,8 @@ having_opt(A) ::= HAVING expr(X).  {A = X;}
 // except as a transient.  So there is never anything to destroy.
 //
 //%destructor limit_opt {
-//  sqlite3ExprDelete($$.pLimit);
-//  sqlite3ExprDelete($$.pOffset);
+//  sqlite3ExprDelete(pParse->db, $$.pLimit);
+//  sqlite3ExprDelete(pParse->db, $$.pOffset);
 //}
 limit_opt(A) ::= .                     {A.pLimit = 0; A.pOffset = 0;}
 limit_opt(A) ::= LIMIT expr(X).        {A.pLimit = X; A.pOffset = 0;}
@@ -565,7 +565,7 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y).
 cmd ::= DELETE FROM fullname(X) where_opt(Y). {sqlite3DeleteFrom(pParse,X,Y);}
 
 %type where_opt {Expr*}
-%destructor where_opt {sqlite3ExprDelete($$);}
+%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
 
 where_opt(A) ::= .                    {A = 0;}
 where_opt(A) ::= WHERE expr(X).       {A = X;}
@@ -578,7 +578,7 @@ cmd ::= UPDATE orconf(R) fullname(X) SET setlist(Y) where_opt(Z).  {
 }
 
 %type setlist {ExprList*}
-%destructor setlist {sqlite3ExprListDelete($$);}
+%destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}
 
 setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y).
     {A = sqlite3ExprListAppend(pParse,Z,Y,&X);}
@@ -601,7 +601,7 @@ insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}
 
 
 %type itemlist {ExprList*}
-%destructor itemlist {sqlite3ExprListDelete($$);}
+%destructor itemlist {sqlite3ExprListDelete(pParse->db, $$);}
 
 itemlist(A) ::= itemlist(X) COMMA expr(Y).
     {A = sqlite3ExprListAppend(pParse,X,Y,0);}
@@ -609,9 +609,9 @@ itemlist(A) ::= expr(X).
     {A = sqlite3ExprListAppend(pParse,0,X,0);}
 
 %type inscollist_opt {IdList*}
-%destructor inscollist_opt {sqlite3IdListDelete($$);}
+%destructor inscollist_opt {sqlite3IdListDelete(pParse->db, $$);}
 %type inscollist {IdList*}
-%destructor inscollist {sqlite3IdListDelete($$);}
+%destructor inscollist {sqlite3IdListDelete(pParse->db, $$);}
 
 inscollist_opt(A) ::= .                       {A = 0;}
 inscollist_opt(A) ::= LP inscollist(X) RP.    {A = X;}
@@ -624,9 +624,9 @@ inscollist(A) ::= nm(Y).
 //
 
 %type expr {Expr*}
-%destructor expr {sqlite3ExprDelete($$);}
+%destructor expr {sqlite3ExprDelete(pParse->db, $$);}
 %type term {Expr*}
-%destructor term {sqlite3ExprDelete($$);}
+%destructor term {sqlite3ExprDelete(pParse->db, $$);}
 
 expr(A) ::= term(X).             {A = X;}
 expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqlite3ExprSpan(A,&B,&E); }
@@ -702,7 +702,7 @@ likeop(A) ::= NOT LIKE_KW(X). {A.eOperator = X; A.not = 1;}
 likeop(A) ::= MATCH(X).       {A.eOperator = X; A.not = 0;}
 likeop(A) ::= NOT MATCH(X).   {A.eOperator = X; A.not = 1;}
 %type escape {Expr*}
-%destructor escape {sqlite3ExprDelete($$);}
+%destructor escape {sqlite3ExprDelete(pParse->db, $$);}
 escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;}
 escape(X) ::= .               [ESCAPE] {X = 0;}
 expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E).  [LIKE_KW]  {
@@ -760,7 +760,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
   if( A ){
     A->pList = pList;
   }else{
-    sqlite3ExprListDelete(pList);
+    sqlite3ExprListDelete(pParse->db, pList);
   } 
   if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0);
   sqlite3ExprSpan(A,&W->span,&Y->span);
@@ -775,7 +775,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       A->pList = Y;
       sqlite3ExprSetHeight(pParse, A);
     }else{
-      sqlite3ExprListDelete(Y);
+      sqlite3ExprListDelete(pParse->db, Y);
     }
     if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0);
     sqlite3ExprSpan(A,&X->span,&E);
@@ -786,7 +786,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       A->pSelect = X;
       sqlite3ExprSetHeight(pParse, A);
     }else{
-      sqlite3SelectDelete(X);
+      sqlite3SelectDelete(pParse->db, X);
     }
     sqlite3ExprSpan(A,&B,&E);
   }
@@ -796,7 +796,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       A->pSelect = Y;
       sqlite3ExprSetHeight(pParse, A);
     }else{
-      sqlite3SelectDelete(Y);
+      sqlite3SelectDelete(pParse->db, Y);
     }
     if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0);
     sqlite3ExprSpan(A,&X->span,&E);
@@ -808,7 +808,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       A->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
       sqlite3ExprSetHeight(pParse, A);
     }else{
-      sqlite3SrcListDelete(pSrc);
+      sqlite3SrcListDelete(pParse->db, pSrc);
     }
     if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0);
     sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y);
@@ -820,7 +820,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       sqlite3ExprSpan(p,&B,&E);
       sqlite3ExprSetHeight(pParse, A);
     }else{
-      sqlite3SelectDelete(Y);
+      sqlite3SelectDelete(pParse->db, Y);
     }
   }
 %endif SQLITE_OMIT_SUBQUERY
@@ -832,12 +832,12 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
     A->pList = Y;
     sqlite3ExprSetHeight(pParse, A);
   }else{
-    sqlite3ExprListDelete(Y);
+    sqlite3ExprListDelete(pParse->db, Y);
   }
   sqlite3ExprSpan(A, &C, &E);
 }
 %type case_exprlist {ExprList*}
-%destructor case_exprlist {sqlite3ExprListDelete($$);}
+%destructor case_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
 case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
   A = sqlite3ExprListAppend(pParse,X, Y, 0);
   A = sqlite3ExprListAppend(pParse,A, Z, 0);
@@ -847,18 +847,18 @@ case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
   A = sqlite3ExprListAppend(pParse,A, Z, 0);
 }
 %type case_else {Expr*}
-%destructor case_else {sqlite3ExprDelete($$);}
+%destructor case_else {sqlite3ExprDelete(pParse->db, $$);}
 case_else(A) ::=  ELSE expr(X).         {A = X;}
 case_else(A) ::=  .                     {A = 0;} 
 %type case_operand {Expr*}
-%destructor case_operand {sqlite3ExprDelete($$);}
+%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);}
 case_operand(A) ::= expr(X).            {A = X;} 
 case_operand(A) ::= .                   {A = 0;} 
 
 %type exprlist {ExprList*}
-%destructor exprlist {sqlite3ExprListDelete($$);}
+%destructor exprlist {sqlite3ExprListDelete(pParse->db, $$);}
 %type nexprlist {ExprList*}
-%destructor nexprlist {sqlite3ExprListDelete($$);}
+%destructor nexprlist {sqlite3ExprListDelete(pParse->db, $$);}
 
 exprlist(A) ::= nexprlist(X).                {A = X;}
 exprlist(A) ::= .                            {A = 0;}
@@ -882,9 +882,9 @@ uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
 uniqueflag(A) ::= .        {A = OE_None;}
 
 %type idxlist {ExprList*}
-%destructor idxlist {sqlite3ExprListDelete($$);}
+%destructor idxlist {sqlite3ExprListDelete(pParse->db, $$);}
 %type idxlist_opt {ExprList*}
-%destructor idxlist_opt {sqlite3ExprListDelete($$);}
+%destructor idxlist_opt {sqlite3ExprListDelete(pParse->db, $$);}
 %type idxitem {Token}
 
 idxlist_opt(A) ::= .                         {A = 0;}
@@ -974,7 +974,7 @@ trigger_time(A) ::= INSTEAD OF.  { A = TK_INSTEAD;}
 trigger_time(A) ::= .            { A = TK_BEFORE; }
 
 %type trigger_event {struct TrigEvent}
-%destructor trigger_event {sqlite3IdListDelete($$.b);}
+%destructor trigger_event {sqlite3IdListDelete(pParse->db, $$.b);}
 trigger_event(A) ::= DELETE|INSERT(OP).       {A.a = @OP; A.b = 0;}
 trigger_event(A) ::= UPDATE(OP).              {A.a = @OP; A.b = 0;}
 trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X;}
@@ -983,12 +983,12 @@ foreach_clause ::= .
 foreach_clause ::= FOR EACH ROW.
 
 %type when_clause {Expr*}
-%destructor when_clause {sqlite3ExprDelete($$);}
+%destructor when_clause {sqlite3ExprDelete(pParse->db, $$);}
 when_clause(A) ::= .             { A = 0; }
 when_clause(A) ::= WHEN expr(X). { A = X; }
 
 %type trigger_cmd_list {TriggerStep*}
-%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);}
+%destructor trigger_cmd_list {sqlite3DeleteTriggerStep(pParse->db, $$);}
 trigger_cmd_list(A) ::= trigger_cmd_list(Y) trigger_cmd(X) SEMI. {
   if( Y ){
     Y->pLast->pNext = X;
@@ -1001,7 +1001,7 @@ trigger_cmd_list(A) ::= trigger_cmd_list(Y) trigger_cmd(X) SEMI. {
 trigger_cmd_list(A) ::= . { A = 0; }
 
 %type trigger_cmd {TriggerStep*}
-%destructor trigger_cmd {sqlite3DeleteTriggerStep($$);}
+%destructor trigger_cmd {sqlite3DeleteTriggerStep(pParse->db, $$);}
 // UPDATE 
 trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).  
                { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }
@@ -1061,7 +1061,7 @@ cmd ::= DETACH database_kw_opt expr(D). {
 }
 
 %type key_opt {Expr*}
-%destructor key_opt {sqlite3ExprDelete($$);}
+%destructor key_opt {sqlite3ExprDelete(pParse->db, $$);}
 key_opt(A) ::= .                     { A = 0; }
 key_opt(A) ::= KEY expr(X).          { A = X; }
 
index bac601c0c33e3849a481759dc87d10b57a02e228..6ffc60d58c2c472d3da9f4b43889d051021bb9d1 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.182 2008/07/08 07:35:52 danielk1977 Exp $
+** $Id: pragma.c,v 1.183 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -682,8 +682,7 @@ void sqlite3Pragma(
       }
       sqlite3_free(sqlite3_temp_directory);
       if( zRight[0] ){
-        sqlite3_temp_directory = zRight;
-        zRight = 0;
+        sqlite3_temp_directory = sqlite3DbStrDup(0, zRight);
       }else{
         sqlite3_temp_directory = 0;
       }
@@ -1323,8 +1322,8 @@ void sqlite3Pragma(
 #endif
   }
 pragma_out:
-  sqlite3_free(zLeft);
-  sqlite3_free(zRight);
+  sqlite3DbFree(db, zLeft);
+  sqlite3DbFree(db, zRight);
 }
 
 #endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */
index 6d984f1ad295cd351ca95952492fbef333982643..a8d98bddbd445909c8a6765103e2d66f05be47a7 100644 (file)
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.89 2008/07/08 19:34:07 drh Exp $
+** $Id: prepare.c,v 1.90 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -32,7 +32,7 @@ static void corruptSchema(
     sqlite3SetString(pData->pzErrMsg, pData->db,
        "malformed database schema (%s)", zObj);
     if( zExtra && zExtra[0] ){
-      *pData->pzErrMsg = sqlite3MPrintf(pData->db, "%z - %s",
+      *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s",
                                   *pData->pzErrMsg, zExtra);
     }
   }
@@ -79,11 +79,15 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
     */
     char *zErr;
     int rc;
+    u8 lookasideEnabled;
     assert( db->init.busy );
     db->init.iDb = iDb;
     db->init.newTnum = atoi(argv[1]);
+    lookasideEnabled = db->lookaside.bEnabled;
+    db->lookaside.bEnabled = 0;
     rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
     db->init.iDb = 0;
+    db->lookaside.bEnabled = lookasideEnabled;
     assert( rc!=SQLITE_OK || zErr==0 );
     if( SQLITE_OK!=rc ){
       pData->rc = rc;
@@ -92,7 +96,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
       }else if( rc!=SQLITE_INTERRUPT ){
         corruptSchema(pData, argv[0], zErr);
       }
-      sqlite3_free(zErr);
+      sqlite3DbFree(db, zErr);
       return 1;
     }
   }else if( argv[0]==0 ){
@@ -336,7 +340,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
 #endif
     if( rc==SQLITE_ABORT ) rc = initData.rc;
     (void)sqlite3SafetyOn(db);
-    sqlite3_free(zSql);
+    sqlite3DbFree(db, zSql);
 #ifndef SQLITE_OMIT_ANALYZE
     if( rc==SQLITE_OK ){
       sqlite3AnalysisLoad(db, iDb);
@@ -568,7 +572,7 @@ static int sqlite3Prepare(
     zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
     if( zSqlCopy ){
       sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
-      sqlite3_free(zSqlCopy);
+      sqlite3DbFree(db, zSqlCopy);
       sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
     }else{
       sParse.zTail = &zSql[nBytes];
@@ -632,7 +636,7 @@ static int sqlite3Prepare(
 
   if( zErrMsg ){
     sqlite3Error(db, rc, "%s", zErrMsg);
-    sqlite3_free(zErrMsg);
+    sqlite3DbFree(db, zErrMsg);
   }else{
     sqlite3Error(db, rc, 0);
   }
@@ -767,7 +771,7 @@ static int sqlite3Prepare16(
     int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8);
     *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
   }
-  sqlite3_free(zSql8); 
+  sqlite3DbFree(db, zSql8); 
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
   return rc;
index 5935f97e48c6a82fe7dc4c15ddf2d7222a8b3345..b88a7d8d0b8152b1dec5cdd23f618093f0bd3d9d 100644 (file)
@@ -5,7 +5,7 @@
 ** an historical reference.  Most of the "enhancements" have been backed
 ** out so that the functionality is now the same as standard printf().
 **
-** $Id: printf.c,v 1.92 2008/07/15 00:27:35 drh Exp $
+** $Id: printf.c,v 1.93 2008/07/28 19:34:53 drh Exp $
 **
 **************************************************************************
 **
@@ -746,7 +746,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
       }else{
         p->nAlloc = szNew;
       }
-      zNew = sqlite3Malloc( p->nAlloc );
+      zNew = sqlite3DbMallocRaw(p->db, p->nAlloc );
       if( zNew ){
         memcpy(zNew, p->zText, p->nChar);
         sqlite3StrAccumReset(p);
@@ -771,7 +771,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){
   if( p->zText ){
     p->zText[p->nChar] = 0;
     if( p->useMalloc && p->zText==p->zBase ){
-      p->zText = sqlite3Malloc( p->nChar+1 );
+      p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
       if( p->zText ){
         memcpy(p->zText, p->zBase, p->nChar+1);
       }else{
@@ -787,7 +787,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){
 */
 void sqlite3StrAccumReset(StrAccum *p){
   if( p->zText!=p->zBase ){
-    sqlite3_free(p->zText);
+    sqlite3DbFree(p->db, p->zText);
   }
   p->zText = 0;
 }
@@ -797,6 +797,7 @@ void sqlite3StrAccumReset(StrAccum *p){
 */
 void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
   p->zText = p->zBase = zBase;
+  p->db = 0;
   p->nChar = 0;
   p->nAlloc = n;
   p->mxAlloc = mx;
@@ -815,6 +816,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
   StrAccum acc;
   sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
                       db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
+  acc.db = db;
   sqlite3VXPrintf(&acc, 1, zFormat, ap);
   z = sqlite3StrAccumFinish(&acc);
   if( acc.mallocFailed && db ){
@@ -836,6 +838,24 @@ char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
   return z;
 }
 
+/*
+** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
+** the string and before returnning.  This routine is intended to be used
+** to modify an existing string.  For example:
+**
+**       x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
+**
+*/
+char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
+  va_list ap;
+  char *z;
+  va_start(ap, zFormat);
+  z = sqlite3VMPrintf(db, zFormat, ap);
+  va_end(ap);
+  sqlite3DbFree(db, zStr);
+  return z;
+}
+
 /*
 ** Print into memory obtained from sqlite3_malloc().  Omit the internal
 ** %-conversion extensions.
index 353ef06c99a74c8713313a705c0974cec07af868..56a75c97fa9ce2ed97d28bba66f75807a1557c49 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.459 2008/07/24 15:50:41 drh Exp $
+** $Id: select.c,v 1.460 2008/07/28 19:34:53 drh Exp $
 */
 #include "sqliteInt.h"
 
 ** Delete all the content of a Select structure but do not deallocate
 ** the select structure itself.
 */
-static void clearSelect(Select *p){
-  sqlite3ExprListDelete(p->pEList);
-  sqlite3SrcListDelete(p->pSrc);
-  sqlite3ExprDelete(p->pWhere);
-  sqlite3ExprListDelete(p->pGroupBy);
-  sqlite3ExprDelete(p->pHaving);
-  sqlite3ExprListDelete(p->pOrderBy);
-  sqlite3SelectDelete(p->pPrior);
-  sqlite3ExprDelete(p->pLimit);
-  sqlite3ExprDelete(p->pOffset);
+static void clearSelect(sqlite3 *db, Select *p){
+  sqlite3ExprListDelete(db, p->pEList);
+  sqlite3SrcListDelete(db, p->pSrc);
+  sqlite3ExprDelete(db, p->pWhere);
+  sqlite3ExprListDelete(db, p->pGroupBy);
+  sqlite3ExprDelete(db, p->pHaving);
+  sqlite3ExprListDelete(db, p->pOrderBy);
+  sqlite3SelectDelete(db, p->pPrior);
+  sqlite3ExprDelete(db, p->pLimit);
+  sqlite3ExprDelete(db, p->pOffset);
 }
 
 /*
@@ -88,7 +88,7 @@ Select *sqlite3SelectNew(
   pNew->addrOpenEphm[1] = -1;
   pNew->addrOpenEphm[2] = -1;
   if( pNew==&standin) {
-    clearSelect(pNew);
+    clearSelect(db, pNew);
     pNew = 0;
   }
   return pNew;
@@ -97,10 +97,10 @@ Select *sqlite3SelectNew(
 /*
 ** Delete the given Select structure and all of its substructures.
 */
-void sqlite3SelectDelete(Select *p){
+void sqlite3SelectDelete(sqlite3 *db, Select *p){
   if( p ){
-    clearSelect(p);
-    sqlite3_free(p);
+    clearSelect(db, p);
+    sqlite3DbFree(db, p);
   }
 }
 
@@ -1163,6 +1163,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
   if( pTab==0 ){
     return 0;
   }
+  pTab->db = db;
   pTab->nRef = 1;
   pTab->zName = zTabName ? sqlite3DbStrDup(db, zTabName) : 0;
   pEList = pSelect->pEList;
@@ -1196,7 +1197,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
       zName = sqlite3MPrintf(db, "%T", &p->span);
     }
     if( db->mallocFailed ){
-      sqlite3_free(zName);
+      sqlite3DbFree(db, zName);
       break;
     }
     sqlite3Dequote(zName);
@@ -1207,8 +1208,11 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
     nName = strlen(zName);
     for(j=cnt=0; j<i; j++){
       if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
+        char *zNewName;
         zName[nName] = 0;
-        zName = sqlite3MPrintf(db, "%z:%d", zName, ++cnt);
+        zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
+        sqlite3DbFree(db, zName);
+        zName = zNewName;
         j = -1;
         if( zName==0 ) break;
       }
@@ -1474,10 +1478,10 @@ static int prepSelectStmt(Parse *pParse, Select *p){
           }
           rc = 1;
         }
-        sqlite3_free(zTName);
+        sqlite3DbFree(db, zTName);
       }
     }
-    sqlite3ExprListDelete(pEList);
+    sqlite3ExprListDelete(db, pEList);
     p->pEList = pNew;
   }
 #if SQLITE_MAX_COLUMN
@@ -1538,11 +1542,11 @@ static int matchOrderByTermToExprList(
     for(i=0; i<pEList->nExpr; i++){
       char *zAs = pEList->a[i].zName;
       if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
-        sqlite3_free(zCol);
+        sqlite3DbFree(db, zCol);
         return i+1;
       }
     }
-    sqlite3_free(zCol);
+    sqlite3DbFree(db, zCol);
   }
 
   /* Resolve all names in the ORDER BY term expression
@@ -1631,7 +1635,7 @@ static int processOrderGroupBy(
     if( iCol>0 ){
       CollSeq *pColl = pE->pColl;
       int flags = pE->flags & EP_ExpCollate;
-      sqlite3ExprDelete(pE);
+      sqlite3ExprDelete(db, pE);
       pE = sqlite3ExprDup(db, pEList->a[iCol-1].pExpr);
       pOrderBy->a[i].pExpr = pE;
       if( pE && pColl && flags ){
@@ -1702,7 +1706,7 @@ static int processCompoundOrderBy(
           assert(pDup);
           iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0);
         }
-        sqlite3ExprDelete(pDup);
+        sqlite3ExprDelete(db, pDup);
         if( iCol<0 ){
           return 1;
         }
@@ -1882,6 +1886,7 @@ static int multiSelect(
   Vdbe *v;              /* Generate code to this VDBE */
   SelectDest dest;      /* Alternative data destination */
   Select *pDelete = 0;  /* Chain of simple selects to delete */
+  sqlite3 *db;          /* Database connection */
 
   /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
   ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
@@ -1890,6 +1895,7 @@ static int multiSelect(
     rc = 1;
     goto multi_select_end;
   }
+  db = pParse->db;
   pPrior = p->pPrior;
   assert( pPrior->pRightmost!=pPrior );
   assert( pPrior->pRightmost==p->pRightmost );
@@ -2026,11 +2032,11 @@ static int multiSelect(
       rc = sqlite3Select(pParse, p, &uniondest, 0, 0, 0);
       /* Query flattening in sqlite3Select() might refill p->pOrderBy.
       ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
-      sqlite3ExprListDelete(p->pOrderBy);
+      sqlite3ExprListDelete(db, p->pOrderBy);
       pDelete = p->pPrior;
       p->pPrior = pPrior;
       p->pOrderBy = 0;
-      sqlite3ExprDelete(p->pLimit);
+      sqlite3ExprDelete(db, p->pLimit);
       p->pLimit = pLimit;
       p->pOffset = pOffset;
       p->iLimit = 0;
@@ -2109,7 +2115,7 @@ static int multiSelect(
       rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0);
       pDelete = p->pPrior;
       p->pPrior = pPrior;
-      sqlite3ExprDelete(p->pLimit);
+      sqlite3ExprDelete(db, p->pLimit);
       p->pLimit = pLimit;
       p->pOffset = pOffset;
       if( rc ){
@@ -2162,20 +2168,20 @@ static int multiSelect(
 
     assert( p->pRightmost==p );
     nCol = p->pEList->nExpr;
-    pKeyInfo = sqlite3DbMallocZero(pParse->db,
+    pKeyInfo = sqlite3DbMallocZero(db,
                        sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
     if( !pKeyInfo ){
       rc = SQLITE_NOMEM;
       goto multi_select_end;
     }
 
-    pKeyInfo->enc = ENC(pParse->db);
+    pKeyInfo->enc = ENC(db);
     pKeyInfo->nField = nCol;
 
     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
       *apColl = multiSelectCollSeq(pParse, p, i);
       if( 0==*apColl ){
-        *apColl = pParse->db->pDfltColl;
+        *apColl = db->pDfltColl;
       }
     }
 
@@ -2193,13 +2199,13 @@ static int multiSelect(
         pLoop->addrOpenEphm[i] = -1;
       }
     }
-    sqlite3_free(pKeyInfo);
+    sqlite3DbFree(db, pKeyInfo);
   }
 
 multi_select_end:
   pDest->iMem = dest.iMem;
   pDest->nMem = dest.nMem;
-  sqlite3SelectDelete(pDelete);
+  sqlite3SelectDelete(db, pDelete);
   return rc;
 }
 #endif /* SQLITE_OMIT_COMPOUND_SELECT */
@@ -2622,9 +2628,9 @@ static int multiSelectOrderBy(
   }else{
     regLimitA = regLimitB = 0;
   }
-  sqlite3ExprDelete(p->pLimit);
+  sqlite3ExprDelete(db, p->pLimit);
   p->pLimit = 0;
-  sqlite3ExprDelete(p->pOffset);
+  sqlite3ExprDelete(db, p->pOffset);
   p->pOffset = 0;
 
   regAddrA = ++pParse->nMem;
@@ -2786,7 +2792,7 @@ static int multiSelectOrderBy(
   /* Reassembly the compound query so that it will be freed correctly
   ** by the calling function */
   if( p->pPrior ){
-    sqlite3SelectDelete(p->pPrior);
+    sqlite3SelectDelete(db, p->pPrior);
   }
   p->pPrior = pPrior;
 
@@ -3155,9 +3161,9 @@ static int flattenSubquery(
       nSubSrc = pSubSrc->nSrc;
       jointype = pSubitem->jointype;
       sqlite3DeleteTable(pSubitem->pTab);
-      sqlite3_free(pSubitem->zDatabase);
-      sqlite3_free(pSubitem->zName);
-      sqlite3_free(pSubitem->zAlias);
+      sqlite3DbFree(db, pSubitem->zDatabase);
+      sqlite3DbFree(db, pSubitem->zName);
+      sqlite3DbFree(db, pSubitem->zAlias);
       pSubitem->pTab = 0;
       pSubitem->zDatabase = 0;
       pSubitem->zName = 0;
@@ -3254,7 +3260,7 @@ static int flattenSubquery(
   /* Finially, delete what is left of the subquery and return
   ** success.
   */
-  sqlite3SelectDelete(pSub1);
+  sqlite3SelectDelete(db, pSub1);
 
   return 1;
 }
@@ -3525,33 +3531,6 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
   pAggInfo->directMode = 0;
 }
 
-#if 0
-/*
-** This function is used when a SELECT statement is used to create a
-** temporary table for iterating through when running an INSTEAD OF
-** UPDATE or INSTEAD OF DELETE trigger. 
-**
-** If possible, the SELECT statement is modified so that NULL values
-** are stored in the temporary table for all columns for which the 
-** corresponding bit in argument mask is not set. If mask takes the
-** special value 0xffffffff, then all columns are populated.
-*/
-void sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
-  if( p && !p->pPrior && !p->isDistinct && mask!=0xffffffff ){
-    ExprList *pEList;
-    int i;
-    sqlite3SelectResolve(pParse, p, 0);
-    pEList = p->pEList;
-    for(i=0; pEList && i<pEList->nExpr && i<32; i++){
-      if( !(mask&((u32)1<<i)) ){
-        sqlite3ExprDelete(pEList->a[i].pExpr);
-        pEList->a[i].pExpr = sqlite3Expr(pParse->db, TK_NULL, 0, 0, 0);
-      }
-    }
-  }
-}
-#endif
-
 /*
 ** Generate code for the given SELECT statement.
 **
@@ -4144,7 +4123,7 @@ int sqlite3Select(
       resetAccumulator(pParse, &sAggInfo);
       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag);
       if( pWInfo==0 ){
-        sqlite3ExprListDelete(pDel);
+        sqlite3ExprListDelete(db, pDel);
         goto select_end;
       }
       updateAccumulator(pParse, &sAggInfo);
@@ -4161,7 +4140,7 @@ int sqlite3Select(
       selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, 
                       pDest, addrEnd, addrEnd);
 
-      sqlite3ExprListDelete(pDel);
+      sqlite3ExprListDelete(db, pDel);
     }
     sqlite3VdbeResolveLabel(v, addrEnd);
     
@@ -4208,8 +4187,8 @@ select_end:
     generateColumnNames(pParse, pTabList, pEList);
   }
 
-  sqlite3_free(sAggInfo.aCol);
-  sqlite3_free(sAggInfo.aFunc);
+  sqlite3DbFree(db, sAggInfo.aCol);
+  sqlite3DbFree(db, sAggInfo.aFunc);
   return rc;
 }
 
index 10434e05bd2df3e1d02003fc423f7a3caf466936..13d6fe5bce1123f3f79d76e97d64a8f3be58566b 100644 (file)
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.381 2008/07/28 05:22:36 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.382 2008/07/28 19:34:53 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -971,6 +971,14 @@ int sqlite3_os_end(void);
 */
 int sqlite3_config(int, ...);
 
+/*
+** CAPI3REF: Configure database connections  {H10180} <S20000>
+**
+** The sqlite3_db_config() interface is used to make configuration
+** changes to a [database connection].  
+*/
+int sqlite3_db_config(sqlite3*, int, ...);
+
 /*
 ** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
 **
@@ -1146,6 +1154,14 @@ struct sqlite3_mem_methods {
 ** This option can be used to overload the default mutex allocation
 ** routines with a wrapper used to track mutex usage for performance
 ** profiling or testing, for example.</dd>
+**
+** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
+** <dd>This option takes two arguments that determine the default
+** memory allcation lookaside optimization.  The first argument is the
+** size of each lookaside buffer slot and the second is the number of
+** slots allocated to each database connection.</dd>
+**
+** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
 #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
@@ -1159,6 +1175,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
 #define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
 #define SQLITE_CONFIG_CHUNKALLOC   12  /* int threshold */
+#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
 
 
 /*
@@ -6073,6 +6090,7 @@ int sqlite3_test_control(int op, ...);
 ** removal in future releases of SQLite.
 */
 int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters {H17250} <H17200>
@@ -6136,6 +6154,18 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
 #define SQLITE_STATUS_MALLOC_SIZE          5
 #define SQLITE_STATUS_PARSER_STACK         6
 
+/*
+** CAPI3REF: Status Parameters for database connections {H17275} <H17200>
+**
+** Status verbs for [sqlite3_db_status()].
+**
+** <dl>
+** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
+** <dd>This parameter returns the number of lookaside memory slots currently
+** checked out.</dd>
+** </dl>
+*/
+#define SQLITE_DBSTATUS_LOOKASIDE_USED     0
 
 /*
 ** Undo the hack that converts floating point types to integer for
index 567239490008ebca2264e43e092d085c71965399..518fa76f6c2ed65fbbce8f6beb01239885044be9 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.746 2008/07/25 15:39:04 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.747 2008/07/28 19:34:54 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -430,6 +430,12 @@ struct BusyHandler {
 */
 #define ArraySize(X)    (sizeof(X)/sizeof(X[0]))
 
+/*
+** The following value as a destructor means to use sqlite3DbFree().
+** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT.
+*/
+#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3DbFree)
+
 /*
 ** Forward references to structures
 */
@@ -448,6 +454,8 @@ typedef struct IdList IdList;
 typedef struct Index Index;
 typedef struct KeyClass KeyClass;
 typedef struct KeyInfo KeyInfo;
+typedef struct Lookaside Lookaside;
+typedef struct LookasideSlot LookasideSlot;
 typedef struct Module Module;
 typedef struct NameContext NameContext;
 typedef struct Parse Parse;
@@ -549,6 +557,32 @@ struct Schema {
 */
 #define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1)
 
+/*
+** Lookaside malloc is a set of fixed-size buffers that can be used
+** to satisify small transient memory allocation requests for objects
+** associated with a particular database connection.  The use of
+** lookaside malloc provides a significant performance enhancement
+** (approx 10%) by avoiding numerous malloc/free requests while parsing
+** SQL statements.
+**
+** The Lookaside structure holds configuration information about the
+** lookaside malloc subsystem.  Each available memory allocation in
+** the lookaside subsystem is stored on a linked list of LookasideSlot
+** objects.
+*/
+struct Lookaside {
+  u16 sz;                 /* Size of each buffer in bytes */
+  u8 bEnabled;            /* True if use lookaside.  False to ignore it */
+  int nOut;               /* Number of buffers currently checked out */
+  int mxOut;              /* Highwater mark for nOut */
+  LookasideSlot *pFree;   /* List if available buffers */
+  void *pStart;           /* First byte of available memory space */
+  void *pEnd;             /* First byte past end of available space */
+};
+struct LookasideSlot {
+  LookasideSlot *pNext;    /* Next buffer in the list of free buffers */
+};
+
 /*
 ** Each database is an instance of the following structure.
 **
@@ -628,6 +662,7 @@ struct sqlite3 {
     int isInterrupted;          /* True if sqlite3_interrupt has been called */
     double notUsed1;            /* Spacer */
   } u1;
+  Lookaside lookaside;          /* Lookaside malloc configuration */
 #ifndef SQLITE_OMIT_AUTHORIZATION
   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
                                 /* Access authorization function */
@@ -867,6 +902,7 @@ struct CollSeq {
 ** of a SELECT statement.
 */
 struct Table {
+  sqlite3 *db;     /* Associated database connection.  Might be NULL. */
   char *zName;     /* Name of the table */
   int nCol;        /* Number of columns in this table */
   Column *aCol;    /* Information about each column */
@@ -1744,10 +1780,11 @@ struct DbFixer {
 ** do not necessarily know how big the string will be in the end.
 */
 struct StrAccum {
-  char *zBase;     /* A base allocation.  Not from malloc. */
-  char *zText;     /* The string collected so far */
-  int  nChar;      /* Length of the string so far */
-  int  nAlloc;     /* Amount of space allocated in zText */
+  sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
+  char *zBase;         /* A base allocation.  Not from malloc. */
+  char *zText;         /* The string collected so far */
+  int  nChar;          /* Length of the string so far */
+  int  nAlloc;         /* Amount of space allocated in zText */
   int  mxAlloc;        /* Maximum allowed string length */
   u8   mallocFailed;   /* Becomes true if any memory allocation fails */
   u8   useMalloc;      /* True if zText is enlargable using realloc */
@@ -1775,6 +1812,8 @@ struct Sqlite3Config {
   int bCoreMutex;                   /* True to enable core mutexing */
   int bFullMutex;                   /* True to enable full mutexing */
   int mxStrlen;                     /* Maximum string length */
+  int szLookaside;                  /* Default lookaside buffer size */
+  int nLookaside;                   /* Default lookaside buffer count */
   sqlite3_mem_methods m;            /* Low-level memory allocation interface */
   sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
   void *pHeap;                      /* Heap storage space */
@@ -1830,14 +1869,14 @@ void *sqlite3Malloc(int);
 void *sqlite3MallocZero(int);
 void *sqlite3DbMallocZero(sqlite3*, int);
 void *sqlite3DbMallocRaw(sqlite3*, int);
-char *sqlite3StrDup(const char*);
-char *sqlite3StrNDup(const char*, int);
 char *sqlite3DbStrDup(sqlite3*,const char*);
 char *sqlite3DbStrNDup(sqlite3*,const char*, int);
 void *sqlite3Realloc(void*, int);
 void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
 void *sqlite3DbRealloc(sqlite3 *, void *, int);
-int sqlite3MallocSize(void *);
+void sqlite3DbFree(sqlite3*, void*);
+int sqlite3MallocSize(void*);
+int sqlite3DbMallocSize(sqlite3*, void*);
 void *sqlite3ScratchMalloc(int);
 void sqlite3ScratchFree(void*);
 void *sqlite3PageMalloc(int);
@@ -1866,6 +1905,7 @@ int sqlite3IsNaN(double);
 void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
 char *sqlite3MPrintf(sqlite3*,const char*, ...);
 char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
+char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
   void sqlite3DebugPrintf(const char*, ...);
 #endif
@@ -1891,9 +1931,9 @@ Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
 void sqlite3ExprSpan(Expr*,Token*,Token*);
 Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
 void sqlite3ExprAssignVarNumber(Parse*, Expr*);
-void sqlite3ExprDelete(Expr*);
+void sqlite3ExprDelete(sqlite3*, Expr*);
 ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*,Token*);
-void sqlite3ExprListDelete(ExprList*);
+void sqlite3ExprListDelete(sqlite3*, ExprList*);
 int sqlite3Init(sqlite3*, char**);
 int sqlite3InitCallback(void*, int, char**, char**);
 void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -1938,15 +1978,15 @@ SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*,
                                       Select*, Expr*, IdList*);
 void sqlite3SrcListShiftJoinType(SrcList*);
 void sqlite3SrcListAssignCursors(Parse*, SrcList*);
-void sqlite3IdListDelete(IdList*);
-void sqlite3SrcListDelete(SrcList*);
+void sqlite3IdListDelete(sqlite3*, IdList*);
+void sqlite3SrcListDelete(sqlite3*, SrcList*);
 void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                         Token*, int, int);
 void sqlite3DropIndex(Parse*, SrcList*, int);
 int sqlite3Select(Parse*, Select*, SelectDest*, Select*, int, int*);
 Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                          Expr*,ExprList*,int,Expr*,Expr*);
-void sqlite3SelectDelete(Select*);
+void sqlite3SelectDelete(sqlite3*, Select*);
 Table *sqlite3SrcListLookup(Parse*, SrcList*);
 int sqlite3IsReadOnly(Parse*, Table*, int);
 void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
@@ -2035,17 +2075,17 @@ void sqlite3MaterializeView(Parse*, Select*, Expr*, int);
   int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
                            int, int, u32*, u32*);
   void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
-  void sqlite3DeleteTriggerStep(TriggerStep*);
+  void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
   TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
   TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
                                         ExprList*,Select*,int);
   TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, int);
   TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
-  void sqlite3DeleteTrigger(Trigger*);
+  void sqlite3DeleteTrigger(sqlite3*, Trigger*);
   void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
 #else
 # define sqlite3TriggersExist(A,B,C,D,E,F) 0
-# define sqlite3DeleteTrigger(A)
+# define sqlite3DeleteTrigger(A,B)
 # define sqlite3DropTriggerPtr(A,B)
 # define sqlite3UnlinkAndDeleteTrigger(A,B,C)
 # define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K) 0
index 504f44e50e6fe48579d4a590068943e56610013d..a5e45dd33aedecec46d866cc082c3eacce33426d 100644 (file)
@@ -13,7 +13,7 @@
 ** This module implements the sqlite3_status() interface and related
 ** functionality.
 **
-** $Id: status.c,v 1.4 2008/07/25 15:39:04 drh Exp $
+** $Id: status.c,v 1.5 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -83,3 +83,26 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
   }
   return SQLITE_OK;
 }
+
+/*
+** Query status information for a single database connection
+*/
+int sqlite3_db_status(
+  sqlite3 *db,          /* The database connection whose status is desired */
+  int op,               /* Status verb */
+  int *pCurrent,        /* Write current value here */
+  int *pHighwater,      /* Write high-water mark here */
+  int resetFlag         /* Reset high-water mark if true */
+){
+  switch( op ){
+    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
+      *pCurrent = db->lookaside.nOut;
+      *pHighwater = db->lookaside.mxOut;
+      if( resetFlag ){
+        db->lookaside.mxOut = db->lookaside.nOut;
+      }
+      break;
+    }
+  }
+  return SQLITE_OK;
+}
index 622ca93bf19ac32b26818814db05f6033e090b92..de5d3a2e3c4df9f5537d8a6e1d519061c2911204 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Code for testing the the SQLite library in a multithreaded environment.
 **
-** $Id: test4.c,v 1.22 2008/06/26 10:41:19 danielk1977 Exp $
+** $Id: test4.c,v 1.23 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -142,7 +142,7 @@ static int tcl_thread_create(
   }
   threadset[i].busy = 1;
   sqlite3_free(threadset[i].zFilename);
-  threadset[i].zFilename = sqlite3StrDup(argv[2]);
+  threadset[i].zFilename = sqlite3DbStrDup(0, argv[2]);
   threadset[i].opnum = 1;
   threadset[i].completed = 0;
   rc = pthread_create(&x, 0, thread_main, &threadset[i]);
@@ -476,7 +476,7 @@ static int tcl_thread_compile(
   thread_wait(&threadset[i]);
   threadset[i].xOp = do_compile;
   sqlite3_free(threadset[i].zArg);
-  threadset[i].zArg = sqlite3StrDup(argv[2]);
+  threadset[i].zArg = sqlite3DbStrDup(0, argv[2]);
   threadset[i].opnum++;
   return TCL_OK;
 }
index 58d65aa28fecc7095e93ba209bf22d96991b4a54..cbb8840a006205f002ba3b7b31ce1c8247530fe5 100644 (file)
@@ -15,7 +15,7 @@
 ** is used for testing the SQLite routines for converting between
 ** the various supported unicode encodings.
 **
-** $Id: test5.c,v 1.20 2007/08/21 19:33:57 drh Exp $
+** $Id: test5.c,v 1.21 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
@@ -154,7 +154,7 @@ static int test_translate(
   if( enc_from==SQLITE_UTF8 ){
     z = Tcl_GetString(objv[1]);
     if( objc==5 ){
-      z = sqlite3StrDup(z);
+      z = sqlite3DbStrDup(0, z);
     }
     sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
   }else{
index 04a10fa9dc5f3ded1e17d221f497fea3cde4ebb9..78754bfa7976bf64be30d8df3656a504a9d6a054 100644 (file)
@@ -12,7 +12,7 @@
 ** Code for testing the client/server version of the SQLite library.
 ** Derived from test4.c.
 **
-** $Id: test7.c,v 1.11 2008/06/26 10:41:19 danielk1977 Exp $
+** $Id: test7.c,v 1.12 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -164,7 +164,7 @@ static int tcl_client_create(
   }
   threadset[i].busy = 1;
   sqlite3_free(threadset[i].zFilename);
-  threadset[i].zFilename = sqlite3StrDup(argv[2]);
+  threadset[i].zFilename = sqlite3DbStrDup(0, argv[2]);
   threadset[i].opnum = 1;
   threadset[i].completed = 0;
   rc = pthread_create(&x, 0, client_main, &threadset[i]);
@@ -507,7 +507,7 @@ static int tcl_client_compile(
   client_wait(&threadset[i]);
   threadset[i].xOp = do_compile;
   sqlite3_free(threadset[i].zArg);
-  threadset[i].zArg = sqlite3StrDup(argv[2]);
+  threadset[i].zArg = sqlite3DbStrDup(0, argv[2]);
   threadset[i].opnum++;
   return TCL_OK;
 }
index c64e55d4651fb15c8480348a1a978c4b289c9826..effd768b8fd265e2b6f587f30de2291e9308b68f 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test8.c,v 1.68 2008/07/23 18:17:32 drh Exp $
+** $Id: test8.c,v 1.69 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -459,7 +459,7 @@ static int echoCreate(
     rc = sqlite3_exec(db, zSql, 0, 0, 0);
     sqlite3_free(zSql);
     if( rc!=SQLITE_OK ){
-      *pzErr = sqlite3StrDup(sqlite3_errmsg(db));
+      *pzErr = sqlite3DbStrDup(0, sqlite3_errmsg(db));
     }
   }
 
index 0c963ad4000665d7b01954953d40fdd7b2a8a404..d8cc15849a1a4a7320db227ce617a6846d75b40a 100644 (file)
@@ -13,7 +13,7 @@
 ** This file contains code used to implement test interfaces to the
 ** memory allocation subsystem.
 **
-** $Id: test_malloc.c,v 1.41 2008/07/25 15:39:04 drh Exp $
+** $Id: test_malloc.c,v 1.42 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -978,6 +978,56 @@ static int test_config_chunkalloc(
   return TCL_OK;
 }
 
+/*
+** Usage:    sqlite3_config_lookaside  SIZE  COUNT
+**
+*/
+static int test_config_lookaside(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  int rc;
+  int sz, cnt;
+  if( objc!=3 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT");
+    return TCL_ERROR;
+  }
+  if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
+  if( Tcl_GetIntFromObj(interp, objv[2], &cnt) ) return TCL_ERROR;
+  rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
+  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
+  return TCL_OK;
+}
+
+
+/*
+** Usage:    sqlite3_db_config_lookaside  CONNECTION  SIZE  COUNT
+**
+*/
+static int test_db_config_lookaside(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  int rc;
+  int sz, cnt;
+  sqlite3 *db;
+  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
+  if( objc!=4 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT");
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR;
+  if( Tcl_GetIntFromObj(interp, objv[3], &cnt) ) return TCL_ERROR;
+  rc = sqlite3_db_config(db, SQLITE_CONFIG_LOOKASIDE, sz, cnt);
+  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
+  return TCL_OK;
+}
+
 /*
 ** Usage:
 **
@@ -1112,6 +1162,57 @@ static int test_status(
   return TCL_OK;
 }
 
+/*
+** Usage:    sqlite3_db_status  DATABASE  OPCODE  RESETFLAG
+**
+** Return a list of three elements which are the sqlite3_db_status() return
+** code, the current value, and the high-water mark value.
+*/
+static int test_db_status(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  int rc, iValue, mxValue;
+  int i, op, resetFlag;
+  const char *zOpName;
+  sqlite3 *db;
+  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
+  static const struct {
+    const char *zName;
+    int op;
+  } aOp[] = {
+    { "SQLITE_DBSTATUS_LOOKASIDE_USED",    SQLITE_DBSTATUS_LOOKASIDE_USED   },
+  };
+  Tcl_Obj *pResult;
+  if( objc!=4 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG");
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  zOpName = Tcl_GetString(objv[2]);
+  for(i=0; i<ArraySize(aOp); i++){
+    if( strcmp(aOp[i].zName, zOpName)==0 ){
+      op = aOp[i].op;
+      break;
+    }
+  }
+  if( i>=ArraySize(aOp) ){
+    if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
+  }
+  if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
+  iValue = 0;
+  mxValue = 0;
+  rc = sqlite3_db_status(db, op, &iValue, &mxValue, resetFlag);
+  pResult = Tcl_NewObj();
+  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
+  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
+  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
+  Tcl_SetObjResult(interp, pResult);
+  return TCL_OK;
+}
+
 /*
 ** install_malloc_faultsim BOOLEAN
 */
@@ -1162,10 +1263,13 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
      { "sqlite3_config_scratch",     test_config_scratch           ,0 },
      { "sqlite3_config_pagecache",   test_config_pagecache         ,0 },
      { "sqlite3_status",             test_status                   ,0 },
+     { "sqlite3_db_status",          test_db_status                ,0 },
      { "install_malloc_faultsim",    test_install_malloc_faultsim  ,0 },
      { "sqlite3_config_heap",        test_config_heap              ,0 },
      { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
      { "sqlite3_config_chunkalloc",  test_config_chunkalloc        ,0 },
+     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
+     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
      { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
      { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 }
   };
index 70b2d3ad9fae6cf6446b283690dd28278e7c5c30..bea8d5eba4d98a8c193d250a27a59cf10fdc01fc 100644 (file)
@@ -15,7 +15,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.147 2008/07/25 15:39:04 drh Exp $
+** $Id: tokenize.c,v 1.148 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -427,7 +427,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
         break;
       }
       case TK_ILLEGAL: {
-        sqlite3_free(*pzErrMsg);
+        sqlite3DbFree(db, *pzErrMsg);
         *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
                         &pParse->sLastToken);
         nErr++;
@@ -471,7 +471,7 @@ abort_parse:
     if( *pzErrMsg==0 ){
       *pzErrMsg = pParse->zErrMsg;
     }else{
-      sqlite3_free(pParse->zErrMsg);
+      sqlite3DbFree(db, pParse->zErrMsg);
     }
     pParse->zErrMsg = 0;
     nErr++;
@@ -482,13 +482,13 @@ abort_parse:
   }
 #ifndef SQLITE_OMIT_SHARED_CACHE
   if( pParse->nested==0 ){
-    sqlite3_free(pParse->aTableLock);
+    sqlite3DbFree(db, pParse->aTableLock);
     pParse->aTableLock = 0;
     pParse->nTableLock = 0;
   }
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  sqlite3_free(pParse->apVtabLock);
+  sqlite3DbFree(db, pParse->apVtabLock);
 #endif
 
   if( !IN_DECLARE_VTAB ){
@@ -499,8 +499,8 @@ abort_parse:
     sqlite3DeleteTable(pParse->pNewTable);
   }
 
-  sqlite3DeleteTrigger(pParse->pNewTrigger);
-  sqlite3_free(pParse->apVarExpr);
+  sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+  sqlite3DbFree(db, pParse->apVarExpr);
   if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
     pParse->rc = SQLITE_ERROR;
   }
index ccee82917b95f9110ab29363279a7203a1f22ec0..760c708c616ba091d71f9f12662708f8c76e50be 100644 (file)
@@ -10,7 +10,7 @@
 *************************************************************************
 **
 **
-** $Id: trigger.c,v 1.127 2008/07/08 23:40:20 drh Exp $
+** $Id: trigger.c,v 1.128 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 
 /*
 ** Delete a linked list of TriggerStep structures.
 */
-void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
+void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
   while( pTriggerStep ){
     TriggerStep * pTmp = pTriggerStep;
     pTriggerStep = pTriggerStep->pNext;
 
-    if( pTmp->target.dyn ) sqlite3_free((char*)pTmp->target.z);
-    sqlite3ExprDelete(pTmp->pWhere);
-    sqlite3ExprListDelete(pTmp->pExprList);
-    sqlite3SelectDelete(pTmp->pSelect);
-    sqlite3IdListDelete(pTmp->pIdList);
+    if( pTmp->target.dyn ) sqlite3DbFree(db, (char*)pTmp->target.z);
+    sqlite3ExprDelete(db, pTmp->pWhere);
+    sqlite3ExprListDelete(db, pTmp->pExprList);
+    sqlite3SelectDelete(db, pTmp->pSelect);
+    sqlite3IdListDelete(db, pTmp->pIdList);
 
-    sqlite3_free(pTmp);
+    sqlite3DbFree(db, pTmp);
   }
 }
 
@@ -186,12 +186,12 @@ void sqlite3BeginTrigger(
   pParse->pNewTrigger = pTrigger;
 
 trigger_cleanup:
-  sqlite3_free(zName);
-  sqlite3SrcListDelete(pTableName);
-  sqlite3IdListDelete(pColumns);
-  sqlite3ExprDelete(pWhen);
+  sqlite3DbFree(db, zName);
+  sqlite3SrcListDelete(db, pTableName);
+  sqlite3IdListDelete(db, pColumns);
+  sqlite3ExprDelete(db, pWhen);
   if( !pParse->pNewTrigger ){
-    sqlite3DeleteTrigger(pTrigger);
+    sqlite3DeleteTrigger(db, pTrigger);
   }else{
     assert( pParse->pNewTrigger==pTrigger );
   }
@@ -241,7 +241,7 @@ void sqlite3FinishTrigger(
        "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
        db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrig->name,
        pTrig->table, z);
-    sqlite3_free(z);
+    sqlite3DbFree(db, z);
     sqlite3ChangeCookie(pParse, iDb);
     sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
         db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
@@ -268,9 +268,9 @@ void sqlite3FinishTrigger(
   }
 
 triggerfinish_cleanup:
-  sqlite3DeleteTrigger(pTrig);
+  sqlite3DeleteTrigger(db, pTrig);
   assert( !pParse->pNewTrigger );
-  sqlite3DeleteTriggerStep(pStepList);
+  sqlite3DeleteTriggerStep(db, pStepList);
 }
 
 /*
@@ -290,22 +290,22 @@ static void sqlitePersistTriggerStep(sqlite3 *db, TriggerStep *p){
   }
   if( p->pSelect ){
     Select *pNew = sqlite3SelectDup(db, p->pSelect);
-    sqlite3SelectDelete(p->pSelect);
+    sqlite3SelectDelete(db, p->pSelect);
     p->pSelect = pNew;
   }
   if( p->pWhere ){
     Expr *pNew = sqlite3ExprDup(db, p->pWhere);
-    sqlite3ExprDelete(p->pWhere);
+    sqlite3ExprDelete(db, p->pWhere);
     p->pWhere = pNew;
   }
   if( p->pExprList ){
     ExprList *pNew = sqlite3ExprListDup(db, p->pExprList);
-    sqlite3ExprListDelete(p->pExprList);
+    sqlite3ExprListDelete(db, p->pExprList);
     p->pExprList = pNew;
   }
   if( p->pIdList ){
     IdList *pNew = sqlite3IdListDup(db, p->pIdList);
-    sqlite3IdListDelete(p->pIdList);
+    sqlite3IdListDelete(db, p->pIdList);
     p->pIdList = pNew;
   }
 }
@@ -320,7 +320,7 @@ static void sqlitePersistTriggerStep(sqlite3 *db, TriggerStep *p){
 TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
   if( pTriggerStep==0 ) {
-    sqlite3SelectDelete(pSelect);
+    sqlite3SelectDelete(db, pSelect);
     return 0;
   }
 
@@ -362,9 +362,9 @@ TriggerStep *sqlite3TriggerInsertStep(
     pTriggerStep->orconf = orconf;
     sqlitePersistTriggerStep(db, pTriggerStep);
   }else{
-    sqlite3IdListDelete(pColumn);
-    sqlite3ExprListDelete(pEList);
-    sqlite3SelectDelete(pSelect);
+    sqlite3IdListDelete(db, pColumn);
+    sqlite3ExprListDelete(db, pEList);
+    sqlite3SelectDelete(db, pSelect);
   }
 
   return pTriggerStep;
@@ -384,8 +384,8 @@ TriggerStep *sqlite3TriggerUpdateStep(
 ){
   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
   if( pTriggerStep==0 ){
-     sqlite3ExprListDelete(pEList);
-     sqlite3ExprDelete(pWhere);
+     sqlite3ExprListDelete(db, pEList);
+     sqlite3ExprDelete(db, pWhere);
      return 0;
   }
 
@@ -411,7 +411,7 @@ TriggerStep *sqlite3TriggerDeleteStep(
 ){
   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
   if( pTriggerStep==0 ){
-    sqlite3ExprDelete(pWhere);
+    sqlite3ExprDelete(db, pWhere);
     return 0;
   }
 
@@ -427,15 +427,15 @@ TriggerStep *sqlite3TriggerDeleteStep(
 /* 
 ** Recursively delete a Trigger structure
 */
-void sqlite3DeleteTrigger(Trigger *pTrigger){
+void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
   if( pTrigger==0 ) return;
-  sqlite3DeleteTriggerStep(pTrigger->step_list);
-  sqlite3_free(pTrigger->name);
-  sqlite3_free(pTrigger->table);
-  sqlite3ExprDelete(pTrigger->pWhen);
-  sqlite3IdListDelete(pTrigger->pColumns);
-  if( pTrigger->nameToken.dyn ) sqlite3_free((char*)pTrigger->nameToken.z);
-  sqlite3_free(pTrigger);
+  sqlite3DeleteTriggerStep(db, pTrigger->step_list);
+  sqlite3DbFree(db, pTrigger->name);
+  sqlite3DbFree(db, pTrigger->table);
+  sqlite3ExprDelete(db, pTrigger->pWhen);
+  sqlite3IdListDelete(db, pTrigger->pColumns);
+  if( pTrigger->nameToken.dyn ) sqlite3DbFree(db, (char*)pTrigger->nameToken.z);
+  sqlite3DbFree(db, pTrigger);
 }
 
 /*
@@ -478,7 +478,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
   sqlite3DropTriggerPtr(pParse, pTrigger);
 
 drop_trigger_cleanup:
-  sqlite3SrcListDelete(pName);
+  sqlite3SrcListDelete(db, pName);
 }
 
 /*
@@ -570,7 +570,7 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
       }
       assert(cc);
     }
-    sqlite3DeleteTrigger(pTrigger);
+    sqlite3DeleteTrigger(db, pTrigger);
     db->flags |= SQLITE_InternChanges;
   }
 }
@@ -681,7 +681,7 @@ static int codeTriggerProgram(
           sqlite3SelectDestInit(&dest, SRT_Discard, 0);
           sqlite3SelectResolve(pParse, ss, 0);
           sqlite3Select(pParse, ss, &dest, 0, 0, 0);
-          sqlite3SelectDelete(ss);
+          sqlite3SelectDelete(db, ss);
         }
         break;
       }
@@ -831,11 +831,11 @@ int sqlite3CodeRowTrigger(
       whenExpr = sqlite3ExprDup(db, p->pWhen);
       if( db->mallocFailed || sqlite3ExprResolveNames(&sNC, whenExpr) ){
         pParse->trigStack = trigStackEntry.pNext;
-        sqlite3ExprDelete(whenExpr);
+        sqlite3ExprDelete(db, whenExpr);
         return 1;
       }
       sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL);
-      sqlite3ExprDelete(whenExpr);
+      sqlite3ExprDelete(db, whenExpr);
 
       codeTriggerProgram(pParse, p->step_list, orconf); 
 
index 9df83664f91732cb8b7befa947a0c1f6bfb074be..7647d4a7e2e6f275bf718cf20799460c78d71102 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.180 2008/07/09 16:51:51 drh Exp $
+** $Id: update.c,v 1.181 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -570,11 +570,11 @@ void sqlite3Update(
 
 update_cleanup:
   sqlite3AuthContextPop(&sContext);
-  sqlite3_free(aRegIdx);
-  sqlite3_free(aXRef);
-  sqlite3SrcListDelete(pTabList);
-  sqlite3ExprListDelete(pChanges);
-  sqlite3ExprDelete(pWhere);
+  sqlite3DbFree(db, aRegIdx);
+  sqlite3DbFree(db, aXRef);
+  sqlite3SrcListDelete(db, pTabList);
+  sqlite3ExprListDelete(db, pChanges);
+  sqlite3ExprDelete(db, pWhere);
   return;
 }
 
@@ -668,7 +668,7 @@ static void updateVirtualTable(
   sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
 
   /* Cleanup */
-  sqlite3SelectDelete(pSelect);  
+  sqlite3SelectDelete(db, pSelect);  
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
index 18340837badd0f789082530e3c290ec0faaa5dba..919452c5729874c91b487f4fd6bda0d14c340acf 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.240 2008/07/24 17:06:48 drh Exp $
+** $Id: util.c,v 1.241 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -98,7 +98,7 @@ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
       va_start(ap, zFormat);
       z = sqlite3VMPrintf(db, zFormat, ap);
       va_end(ap);
-      sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3_free);
+      sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
     }else{
       sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
     }
@@ -124,10 +124,11 @@ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
 */
 void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
   va_list ap;
+  sqlite3 *db = pParse->db;
   pParse->nErr++;
-  sqlite3_free(pParse->zErrMsg);
+  sqlite3DbFree(db, pParse->zErrMsg);
   va_start(ap, zFormat);
-  pParse->zErrMsg = sqlite3VMPrintf(pParse->db, zFormat, ap);
+  pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
   va_end(ap);
   if( pParse->rc==SQLITE_OK ){
     pParse->rc = SQLITE_ERROR;
@@ -138,7 +139,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
 ** Clear the error message in pParse, if any
 */
 void sqlite3ErrorClear(Parse *pParse){
-  sqlite3_free(pParse->zErrMsg);
+  sqlite3DbFree(pParse->db, pParse->zErrMsg);
   pParse->zErrMsg = 0;
   pParse->nErr = 0;
 }
index caf6d5c028a8e41ea82e54c4cf6d28e37d578e37..cab2cde5ff2f159ba86da03121b54224ab0e97cf 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.765 2008/07/26 18:47:27 danielk1977 Exp $
+** $Id: vdbe.c,v 1.766 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -895,7 +895,7 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */
     pOut->flags |= MEM_Static;
     pOut->flags &= ~MEM_Dyn;
     if( pOp->p4type==P4_DYNAMIC ){
-      sqlite3_free(pOp->p4.z);
+      sqlite3DbFree(db, pOp->p4.z);
     }
     pOp->p4type = P4_DYNAMIC;
     pOp->p4.z = pOut->z;
@@ -2605,7 +2605,7 @@ case OP_VerifyCookie: {
     iMeta = 0;
   }
   if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
-    sqlite3_free(p->zErrMsg);
+    sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
     /* If the schema-cookie from the database file matches the cookie 
     ** stored with the in-memory representation of the schema, do
@@ -3470,7 +3470,7 @@ case OP_Insert: {
   }
   if( pC->pseudoTable ){
     if( !pC->ephemPseudoTable ){
-      sqlite3_free(pC->pData);
+      sqlite3DbFree(db, pC->pData);
     }
     pC->iKey = iKey;
     pC->nData = pData->n;
@@ -4149,7 +4149,7 @@ case OP_ParseSchema: {
   assert( !db->mallocFailed );
   rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
   if( rc==SQLITE_ABORT ) rc = initData.rc;
-  sqlite3_free(zSql);
+  sqlite3DbFree(db, zSql);
   db->init.busy = 0;
   (void)sqlite3SafetyOn(db);
   if( rc==SQLITE_NOMEM ){
@@ -4241,7 +4241,7 @@ case OP_IntegrityCk: {
   
   nRoot = pOp->p2;
   assert( nRoot>0 );
-  aRoot = sqlite3Malloc( sizeof(int)*(nRoot+1) );
+  aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
   if( aRoot==0 ) goto no_mem;
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
   pnErr = &p->aMem[pOp->p3];
@@ -4265,7 +4265,7 @@ case OP_IntegrityCk: {
   }
   UPDATE_MAX_BLOBSIZE(pIn1);
   sqlite3VdbeChangeEncoding(pIn1, encoding);
-  sqlite3_free(aRoot);
+  sqlite3DbFree(db, aRoot);
   break;
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -4275,6 +4275,7 @@ case OP_IntegrityCk: {
 ** Write the integer from register P1 into the Fifo.
 */
 case OP_FifoWrite: {        /* in1 */
+  p->sFifo.db = db;
   if( sqlite3VdbeFifoPush(&p->sFifo, sqlite3VdbeIntValue(pIn1))==SQLITE_NOMEM ){
     goto no_mem;
   }
@@ -4322,7 +4323,7 @@ case OP_ContextPush: {
   pContext->lastRowid = db->lastRowid;
   pContext->nChange = p->nChange;
   pContext->sFifo = p->sFifo;
-  sqlite3VdbeFifoInit(&p->sFifo);
+  sqlite3VdbeFifoInit(&p->sFifo, db);
   break;
 }
 
@@ -4628,7 +4629,7 @@ case OP_VOpen: {
   assert(pVtab && pModule);
   if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   rc = pModule->xOpen(pVtab, &pVtabCursor);
-  sqlite3_free(p->zErrMsg);
+  sqlite3DbFree(db, p->zErrMsg);
   p->zErrMsg = pVtab->zErrMsg;
   pVtab->zErrMsg = 0;
   if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
@@ -4860,7 +4861,7 @@ case OP_VRename: {
   if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   sqlite3VtabLock(pVtab);
   rc = pVtab->pModule->xRename(pVtab, pName->z);
-  sqlite3_free(p->zErrMsg);
+  sqlite3DbFree(db, p->zErrMsg);
   p->zErrMsg = pVtab->zErrMsg;
   pVtab->zErrMsg = 0;
   sqlite3VtabUnlock(db, pVtab);
@@ -4915,7 +4916,7 @@ case OP_VUpdate: {
     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
     sqlite3VtabLock(pVtab);
     rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
-    sqlite3_free(p->zErrMsg);
+    sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = pVtab->zErrMsg;
     pVtab->zErrMsg = 0;
     sqlite3VtabUnlock(db, pVtab);
index 50c34d1b9de5eb3a4b0788535ecc2f42b8cc4034..6ce400e926ed39c7b6986ccca16b2eb1c4611977 100644 (file)
@@ -15,7 +15,7 @@
 ** 6000 lines long) it was split up into several smaller files and
 ** this header information was factored out.
 **
-** $Id: vdbeInt.h,v 1.150 2008/07/26 18:26:10 danielk1977 Exp $
+** $Id: vdbeInt.h,v 1.151 2008/07/28 19:34:54 drh Exp $
 */
 #ifndef _VDBEINT_H_
 #define _VDBEINT_H_
@@ -245,6 +245,7 @@ struct FifoPage {
 typedef struct Fifo Fifo;
 struct Fifo {
   int nEntry;         /* Total number of entries */
+  sqlite3 *db;        /* The associated database connection */
   FifoPage *pFirst;   /* First page on the list */
   FifoPage *pLast;    /* Last page on the list */
 };
@@ -434,7 +435,7 @@ int sqlite3VdbeMemTranslate(Mem*, u8);
   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
 #endif
 int sqlite3VdbeMemHandleBom(Mem *pMem);
-void sqlite3VdbeFifoInit(Fifo*);
+void sqlite3VdbeFifoInit(Fifo*, sqlite3*);
 int sqlite3VdbeFifoPush(Fifo*, i64);
 int sqlite3VdbeFifoPop(Fifo*, i64*);
 void sqlite3VdbeFifoClear(Fifo*);
index 1539c5bd7cd7e7d1200ad665d0c549380722e327..2dce1413259486fd0960467d5693676ca3645eb4 100644 (file)
@@ -13,7 +13,7 @@
 ** This file contains code use to implement APIs that are part of the
 ** VDBE.
 **
-** $Id: vdbeapi.c,v 1.135 2008/07/23 21:07:25 drh Exp $
+** $Id: vdbeapi.c,v 1.136 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
@@ -556,7 +556,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
       ** sqlite3_errmsg() and sqlite3_errcode().
       */
       const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
-      sqlite3_free(v->zErrMsg);
+      sqlite3DbFree(db, v->zErrMsg);
       if( !db->mallocFailed ){
         v->zErrMsg = sqlite3DbStrDup(db, zErr);
       } else {
index 9082757030077518a000a9f9f2d16bccc0eb6af1..9ab8ebd17297ba78074de585e4fea2b79326e996 100644 (file)
@@ -14,7 +14,7 @@
 ** to version 2.8.7, all this code was combined into the vdbe.c source file.
 ** But that file was getting too big so this subroutines were split out.
 **
-** $Id: vdbeaux.c,v 1.400 2008/07/26 18:26:10 danielk1977 Exp $
+** $Id: vdbeaux.c,v 1.401 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -302,7 +302,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
       pOp->p2 = aLabel[-1-pOp->p2];
     }
   }
-  sqlite3_free(p->aLabel);
+  sqlite3DbFree(p->db, p->aLabel);
   p->aLabel = 0;
 
   *pMaxFuncArgs = nMaxArgs;
@@ -432,16 +432,16 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){
 ** If the input FuncDef structure is ephemeral, then free it.  If
 ** the FuncDef is not ephermal, then do nothing.
 */
-static void freeEphemeralFunction(FuncDef *pDef){
+static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
   if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
-    sqlite3_free(pDef);
+    sqlite3DbFree(db, pDef);
   }
 }
 
 /*
 ** Delete a P4 value if necessary.
 */
-static void freeP4(int p4type, void *p4){
+static void freeP4(sqlite3 *db, int p4type, void *p4){
   if( p4 ){
     switch( p4type ){
       case P4_REAL:
@@ -451,18 +451,18 @@ static void freeP4(int p4type, void *p4){
       case P4_KEYINFO:
       case P4_INTARRAY:
       case P4_KEYINFO_HANDOFF: {
-        sqlite3_free(p4);
+        sqlite3DbFree(db, p4);
         break;
       }
       case P4_VDBEFUNC: {
         VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
-        freeEphemeralFunction(pVdbeFunc->pFunc);
+        freeEphemeralFunction(db, pVdbeFunc->pFunc);
         sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
-        sqlite3_free(pVdbeFunc);
+        sqlite3DbFree(db, pVdbeFunc);
         break;
       }
       case P4_FUNCDEF: {
-        freeEphemeralFunction((FuncDef*)p4);
+        freeEphemeralFunction(db, (FuncDef*)p4);
         break;
       }
       case P4_MEM: {
@@ -480,8 +480,9 @@ static void freeP4(int p4type, void *p4){
 void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
   if( p && p->aOp ){
     VdbeOp *pOp = &p->aOp[addr];
+    sqlite3 *db = p->db;
     while( N-- ){
-      freeP4(pOp->p4type, pOp->p4.p);
+      freeP4(db, pOp->p4type, pOp->p4.p);
       memset(pOp, 0, sizeof(pOp[0]));
       pOp->opcode = OP_Noop;
       pOp++;
@@ -516,11 +517,13 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
 */
 void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
   Op *pOp;
+  sqlite3 *db;
   assert( p!=0 );
+  db = p->db;
   assert( p->magic==VDBE_MAGIC_INIT );
-  if( p->aOp==0 || p->db->mallocFailed ){
+  if( p->aOp==0 || db->mallocFailed ){
     if (n != P4_KEYINFO) {
-      freeP4(n, (void*)*(char**)&zP4);
+      freeP4(db, n, (void*)*(char**)&zP4);
     }
     return;
   }
@@ -530,7 +533,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
     if( addr<0 ) return;
   }
   pOp = &p->aOp[addr];
-  freeP4(pOp->p4type, pOp->p4.p);
+  freeP4(db, pOp->p4type, pOp->p4.p);
   pOp->p4.p = 0;
   if( n==P4_INT32 ){
     /* Note: this cast is safe, because the origin data point was an int
@@ -588,7 +591,7 @@ void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
   if( p->nOp ){
     char **pz = &p->aOp[p->nOp-1].zComment;
     va_start(ap, zFormat);
-    sqlite3_free(*pz);
+    sqlite3DbFree(p->db, *pz);
     *pz = sqlite3VMPrintf(p->db, zFormat, ap);
     va_end(ap);
   }
@@ -601,7 +604,7 @@ void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
   if( p->nOp ){
     char **pz = &p->aOp[p->nOp-1].zComment;
     va_start(ap, zFormat);
-    sqlite3_free(*pz);
+    sqlite3DbFree(p->db, *pz);
     *pz = sqlite3VMPrintf(p->db, zFormat, ap);
     va_end(ap);
   }
@@ -783,7 +786,7 @@ int sqlite3VdbeReleaseBuffers(Vdbe *p){
     Mem *pMem = &p->aMem[ii];
     if( pMem->z && pMem->flags&MEM_Dyn ){
       assert( !pMem->xDel );
-      nFree += sqlite3MallocSize(pMem->z);
+      nFree += sqlite3DbMallocSize(pMem->db, pMem->z);
       sqlite3VdbeMemRelease(pMem);
     }
   }
@@ -1102,11 +1105,8 @@ void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){
   }
 #endif
   if( !pCx->ephemPseudoTable ){
-    sqlite3_free(pCx->pData);
+    sqlite3DbFree(p->db, pCx->pData);
   }
-  /* memset(pCx, 0, sizeof(Cursor)); */
-  /* sqlite3_free(pCx->aType); */
-  /* sqlite3_free(pCx); */
 }
 
 /*
@@ -1134,6 +1134,7 @@ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){
 */
 static void Cleanup(Vdbe *p, int freebuffers){
   int i;
+  sqlite3 *db = p->db;
   closeAllCursorsExceptActiveVtabs(p);
   for(i=1; i<=p->nMem; i++){
     MemSetTypeFlag(&p->aMem[i], MEM_Null);
@@ -1144,12 +1145,12 @@ static void Cleanup(Vdbe *p, int freebuffers){
     for(i=0; i<p->contextStackTop; i++){
       sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
     }
-    sqlite3_free(p->contextStack);
+    sqlite3DbFree(db, p->contextStack);
   }
   p->contextStack = 0;
   p->contextStackDepth = 0;
   p->contextStackTop = 0;
-  sqlite3_free(p->zErrMsg);
+  sqlite3DbFree(db, p->zErrMsg);
   p->zErrMsg = 0;
   p->pResultSet = 0;
 }
@@ -1163,12 +1164,13 @@ static void Cleanup(Vdbe *p, int freebuffers){
 void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
   Mem *pColName;
   int n;
+  sqlite3 *db = p->db;
 
   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1);
-  sqlite3_free(p->aColName);
+  sqlite3DbFree(db, p->aColName);
   n = nResColumn*COLNAME_N;
   p->nResColumn = nResColumn;
-  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
+  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
   if( p->aColName==0 ) return;
   while( n-- > 0 ){
     pColName->flags = MEM_Null;
@@ -1185,7 +1187,7 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
 **
 ** If N==P4_STATIC  it means that zName is a pointer to a constant static
 ** string and we can just copy the pointer. If it is P4_DYNAMIC, then 
-** the string is freed using sqlite3_free() when the vdbe is finished with
+** the string is freed using sqlite3DbFree(db, ) when the vdbe is finished with
 ** it. Otherwise, N bytes of zName are copied.
 */
 int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
@@ -1305,7 +1307,7 @@ static int vdbeCommit(sqlite3 *db){
     /* Select a master journal file name */
     do {
       u32 random;
-      sqlite3_free(zMaster);
+      sqlite3DbFree(db, zMaster);
       sqlite3_randomness(sizeof(random), &random);
       zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);
       if( !zMaster ){
@@ -1321,7 +1323,7 @@ static int vdbeCommit(sqlite3 *db){
       );
     }
     if( rc!=SQLITE_OK ){
-      sqlite3_free(zMaster);
+      sqlite3DbFree(db, zMaster);
       return rc;
     }
  
@@ -1345,7 +1347,7 @@ static int vdbeCommit(sqlite3 *db){
         if( rc!=SQLITE_OK ){
           sqlite3OsCloseFree(pMaster);
           sqlite3OsDelete(pVfs, zMaster, 0);
-          sqlite3_free(zMaster);
+          sqlite3DbFree(db, zMaster);
           return rc;
         }
       }
@@ -1360,7 +1362,7 @@ static int vdbeCommit(sqlite3 *db){
      && (rc=sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))!=SQLITE_OK) ){
       sqlite3OsCloseFree(pMaster);
       sqlite3OsDelete(pVfs, zMaster, 0);
-      sqlite3_free(zMaster);
+      sqlite3DbFree(db, zMaster);
       return rc;
     }
 
@@ -1382,7 +1384,7 @@ static int vdbeCommit(sqlite3 *db){
     }
     sqlite3OsCloseFree(pMaster);
     if( rc!=SQLITE_OK ){
-      sqlite3_free(zMaster);
+      sqlite3DbFree(db, zMaster);
       return rc;
     }
 
@@ -1391,7 +1393,7 @@ static int vdbeCommit(sqlite3 *db){
     ** transaction files are deleted.
     */
     rc = sqlite3OsDelete(pVfs, zMaster, 1);
-    sqlite3_free(zMaster);
+    sqlite3DbFree(db, zMaster);
     zMaster = 0;
     if( rc ){
       return rc;
@@ -1633,7 +1635,7 @@ int sqlite3VdbeHalt(Vdbe *p){
         rc = xFunc(pBt);
         if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
           p->rc = rc;
-          sqlite3_free(p->zErrMsg);
+          sqlite3DbFree(db, p->zErrMsg);
           p->zErrMsg = 0;
         }
       }
@@ -1713,8 +1715,9 @@ int sqlite3VdbeReset(Vdbe *p, int freebuffers){
   */
   if( p->pc>=0 ){
     if( p->zErrMsg ){
-      sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,sqlite3_free);
+      sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,SQLITE_TRANSIENT);
       db->errCode = p->rc;
+      sqlite3DbFree(db, p->zErrMsg);
       p->zErrMsg = 0;
     }else if( p->rc ){
       sqlite3Error(db, p->rc, 0);
@@ -1727,7 +1730,8 @@ int sqlite3VdbeReset(Vdbe *p, int freebuffers){
     ** called), set the database error in this case as well.
     */
     sqlite3Error(db, p->rc, 0);
-    sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free);
+    sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
+    sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = 0;
   }
 
@@ -1805,13 +1809,15 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
 */
 void sqlite3VdbeDelete(Vdbe *p){
   int i;
+  sqlite3 *db;
+
   if( p==0 ) return;
-  /* Cleanup(p, 1); */
+  db = p->db;
   if( p->pPrev ){
     p->pPrev->pNext = p->pNext;
   }else{
-    assert( p->db->pVdbe==p );
-    p->db->pVdbe = p->pNext;
+    assert( db->pVdbe==p );
+    db->pVdbe = p->pNext;
   }
   if( p->pNext ){
     p->pNext->pPrev = p->pPrev;
@@ -1819,23 +1825,23 @@ void sqlite3VdbeDelete(Vdbe *p){
   if( p->aOp ){
     Op *pOp = p->aOp;
     for(i=0; i<p->nOp; i++, pOp++){
-      freeP4(pOp->p4type, pOp->p4.p);
+      freeP4(db, pOp->p4type, pOp->p4.p);
 #ifdef SQLITE_DEBUG
-      sqlite3_free(pOp->zComment);
+      sqlite3DbFree(db, pOp->zComment);
 #endif     
     }
-    sqlite3_free(p->aOp);
+    sqlite3DbFree(db, p->aOp);
   }
   releaseMemArray(p->aVar, p->nVar, 1);
-  sqlite3_free(p->aLabel);
+  sqlite3DbFree(db, p->aLabel);
   if( p->aMem ){
-    sqlite3_free(&p->aMem[1]);
+    sqlite3DbFree(db, &p->aMem[1]);
   }
   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1);
-  sqlite3_free(p->aColName);
-  sqlite3_free(p->zSql);
+  sqlite3DbFree(db, p->aColName);
+  sqlite3DbFree(db, p->zSql);
   p->magic = VDBE_MAGIC_DEAD;
-  sqlite3_free(p);
+  sqlite3DbFree(db, p);
 }
 
 /*
@@ -2259,7 +2265,7 @@ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
       }
     }
     if( p->needFree ){
-      sqlite3_free(p);
+      sqlite3DbFree(p->pKeyInfo->db, p);
     }
   }
 }
index e2cfb503ddbb3e1ff98c3d0b952b7ff32fd759f8..746bfe4c37b8da4a5b7639e2be20e2aea0c5209e 100644 (file)
@@ -12,7 +12,7 @@
 **
 ** This file contains code used to implement incremental BLOB I/O.
 **
-** $Id: vdbeblob.c,v 1.24 2008/07/10 00:32:42 drh Exp $
+** $Id: vdbeblob.c,v 1.25 2008/07/28 19:34:54 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -117,7 +117,7 @@ int sqlite3_blob_open(
       if( sParse.zErrMsg ){
         sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
       }
-      sqlite3_free(sParse.zErrMsg);
+      sqlite3DbFree(db, sParse.zErrMsg);
       rc = SQLITE_ERROR;
       (void)sqlite3SafetyOff(db);
       sqlite3BtreeLeaveAll(db);
@@ -229,7 +229,7 @@ int sqlite3_blob_open(
     }
     pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
     if( db->mallocFailed ){
-      sqlite3_free(pBlob);
+      sqlite3DbFree(db, pBlob);
       goto blob_open_out;
     }
     pBlob->flags = flags;
@@ -268,7 +268,7 @@ int sqlite3_blob_close(sqlite3_blob *pBlob){
   int rc;
 
   rc = sqlite3_finalize(p->pStmt);
-  sqlite3_free(p);
+  sqlite3DbFree(p->db, p);
   return rc;
 }
 
index 956321c059fac0b4b2b50acc25aa63be5ce4ddb6..a5e270d8ae25b88fdfba5a7ed50dd7fc219abd45 100644 (file)
@@ -12,7 +12,7 @@
 ** This file implements a FIFO queue of rowids used for processing
 ** UPDATE and DELETE statements.
 **
-** $Id: vdbefifo.c,v 1.7 2008/06/15 02:51:48 drh Exp $
+** $Id: vdbefifo.c,v 1.8 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
 ** Allocate a new FifoPage and return a pointer to it.  Return NULL if
 ** we run out of memory.  Leave space on the page for nEntry entries.
 */
-static FifoPage *allocateFifoPage(int nEntry){
+static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
   FifoPage *pPage;
   if( nEntry>FIFOSIZE_MAX ){
     nEntry = FIFOSIZE_MAX;
   }
-  pPage = sqlite3Malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
+  pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
   if( pPage ){
     pPage->nSlot = nEntry;
     pPage->iWrite = 0;
@@ -51,8 +51,9 @@ static FifoPage *allocateFifoPage(int nEntry){
 /*
 ** Initialize a Fifo structure.
 */
-void sqlite3VdbeFifoInit(Fifo *pFifo){
+void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
   memset(pFifo, 0, sizeof(*pFifo));
+  pFifo->db = db;
 }
 
 /*
@@ -64,12 +65,13 @@ int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
   FifoPage *pPage;
   pPage = pFifo->pLast;
   if( pPage==0 ){
-    pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(FIFOSIZE_FIRST);
+    pPage = pFifo->pLast = pFifo->pFirst =
+         allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
     if( pPage==0 ){
       return SQLITE_NOMEM;
     }
   }else if( pPage->iWrite>=pPage->nSlot ){
-    pPage->pNext = allocateFifoPage(pFifo->nEntry);
+    pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
     if( pPage->pNext==0 ){
       return SQLITE_NOMEM;
     }
@@ -101,7 +103,7 @@ int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
   pFifo->nEntry--;
   if( pPage->iRead>=pPage->iWrite ){
     pFifo->pFirst = pPage->pNext;
-    sqlite3_free(pPage);
+    sqlite3DbFree(pFifo->db, pPage);
     if( pFifo->nEntry==0 ){
       assert( pFifo->pLast==pPage );
       pFifo->pLast = 0;
@@ -122,7 +124,7 @@ void sqlite3VdbeFifoClear(Fifo *pFifo){
   FifoPage *pPage, *pNextPage;
   for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
     pNextPage = pPage->pNext;
-    sqlite3_free(pPage);
+    sqlite3DbFree(pFifo->db, pPage);
   }
-  sqlite3VdbeFifoInit(pFifo);
+  sqlite3VdbeFifoInit(pFifo, pFifo->db);
 }
index a8a2129f972d3cbce7d95e5875d125575580f6c9..184195c3ba98d695921ece6b3dae8ff0280fa2b7 100644 (file)
@@ -15,7 +15,7 @@
 ** only within the VDBE.  Interface routines refer to a Mem using the
 ** name sqlite_value
 **
-** $Id: vdbemem.c,v 1.118 2008/07/09 16:51:51 drh Exp $
+** $Id: vdbemem.c,v 1.119 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -83,7 +83,7 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
   );
 
   if( n<32 ) n = 32;
-  if( sqlite3MallocSize(pMem->zMalloc)<n ){
+  if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
     if( preserve && pMem->z==pMem->zMalloc ){
       pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
       if( !pMem->z ){
@@ -91,7 +91,7 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
       }
       preserve = 0;
     }else{
-      sqlite3_free(pMem->zMalloc);
+      sqlite3DbFree(pMem->db, pMem->zMalloc);
       pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
     }
   }
@@ -255,7 +255,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
     ctx.isError = 0;
     pFunc->xFinalize(&ctx);
     assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
-    sqlite3_free(pMem->zMalloc);
+    sqlite3DbFree(pMem->db, pMem->zMalloc);
     *pMem = ctx.s;
     rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
   }
@@ -286,7 +286,7 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
 */
 void sqlite3VdbeMemRelease(Mem *p){
   sqlite3VdbeMemReleaseExternal(p);
-  sqlite3_free(p->zMalloc);
+  sqlite3DbFree(p->db, p->zMalloc);
   p->z = 0;
   p->zMalloc = 0;
   p->xDel = 0;
@@ -631,11 +631,21 @@ int sqlite3VdbeMemSetStr(
       return SQLITE_NOMEM;
     }
     memcpy(pMem->z, z, nAlloc);
+  }else if( xDel==SQLITE_DYNAMIC ){
+    sqlite3VdbeMemRelease(pMem);
+    pMem->zMalloc = pMem->z = (char *)z;
+    pMem->xDel = 0;
   }else{
     sqlite3VdbeMemRelease(pMem);
     pMem->z = (char *)z;
-    pMem->xDel = xDel;
-    flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
+    if( xDel==SQLITE_DYNAMIC ){
+      pMem->zMalloc = pMem->z;
+      pMem->xDel = 0;
+      flags |= MEM_Dyn;
+    }else{
+      pMem->xDel = xDel;
+      flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
+    }
   }
 
   pMem->n = nByte;
@@ -966,11 +976,11 @@ int sqlite3ValueFromExpr(
   op = pExpr->op;
 
   if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
-    zVal = sqlite3StrNDup((char*)pExpr->token.z, pExpr->token.n);
+    zVal = sqlite3DbStrNDup(db, (char*)pExpr->token.z, pExpr->token.n);
     pVal = sqlite3ValueNew(db);
     if( !zVal || !pVal ) goto no_mem;
     sqlite3Dequote(zVal);
-    sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3_free);
+    sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
     if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
       sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
     }else{
@@ -993,7 +1003,7 @@ int sqlite3ValueFromExpr(
     nVal = pExpr->token.n - 3;
     zVal = (char*)pExpr->token.z + 2;
     sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
-                         0, sqlite3_free);
+                         0, SQLITE_DYNAMIC);
   }
 #endif
 
@@ -1002,7 +1012,7 @@ int sqlite3ValueFromExpr(
 
 no_mem:
   db->mallocFailed = 1;
-  sqlite3_free(zVal);
+  sqlite3DbFree(db, zVal);
   sqlite3ValueFree(pVal);
   *ppVal = 0;
   return SQLITE_NOMEM;
@@ -1027,7 +1037,7 @@ void sqlite3ValueSetStr(
 void sqlite3ValueFree(sqlite3_value *v){
   if( !v ) return;
   sqlite3VdbeMemRelease((Mem *)v);
-  sqlite3_free(v);
+  sqlite3DbFree(((Mem*)v)->db, v);
 }
 
 /*
index 2c71215dec62b5fcfbb70cfdc735bd117711b12f..c9ff4e0bdd8b342fff3d72361f4d4836bb6e682e 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.71 2008/07/23 18:17:32 drh Exp $
+** $Id: vtab.c,v 1.72 2008/07/28 19:34:54 drh Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #include "sqliteInt.h"
@@ -41,7 +41,7 @@ static int createModule(
     if( pDel && pDel->xDestroy ){
       pDel->xDestroy(pDel->pAux);
     }
-    sqlite3_free(pDel);
+    sqlite3DbFree(db, pDel);
     if( pDel==pMod ){
       db->mallocFailed = 1;
     }
@@ -116,17 +116,18 @@ void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){
 */
 void sqlite3VtabClear(Table *p){
   sqlite3_vtab *pVtab = p->pVtab;
+  sqlite3 *db = p->db;
   if( pVtab ){
     assert( p->pMod && p->pMod->pModule );
-    sqlite3VtabUnlock(p->pSchema->db, pVtab);
+    sqlite3VtabUnlock(db, pVtab);
     p->pVtab = 0;
   }
   if( p->azModuleArg ){
     int i;
     for(i=0; i<p->nModuleArg; i++){
-      sqlite3_free(p->azModuleArg[i]);
+      sqlite3DbFree(db, p->azModuleArg[i]);
     }
-    sqlite3_free(p->azModuleArg);
+    sqlite3DbFree(db, p->azModuleArg);
   }
 }
 
@@ -144,10 +145,10 @@ static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
   if( azModuleArg==0 ){
     int j;
     for(j=0; j<i; j++){
-      sqlite3_free(pTable->azModuleArg[j]);
+      sqlite3DbFree(db, pTable->azModuleArg[j]);
     }
-    sqlite3_free(zArg);
-    sqlite3_free(pTable->azModuleArg);
+    sqlite3DbFree(db, zArg);
+    sqlite3DbFree(db, pTable->azModuleArg);
     pTable->nModuleArg = 0;
   }else{
     azModuleArg[i] = zArg;
@@ -278,7 +279,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
       zStmt,
       pParse->regRowid
     );
-    sqlite3_free(zStmt);
+    sqlite3DbFree(db, zStmt);
     v = sqlite3GetVdbe(pParse);
     sqlite3ChangeCookie(pParse, iDb);
 
@@ -377,7 +378,7 @@ static int vtabCallConstructor(
       *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
     }else {
       *pzErr = sqlite3MPrintf(db, "%s", zErr);
-      sqlite3_free(zErr);
+      sqlite3DbFree(db, zErr);
     }
   }else if( db->pVTab ){
     const char *zFormat = "vtable constructor did not declare schema: %s";
@@ -388,7 +389,7 @@ static int vtabCallConstructor(
     rc = rc2;
   }
   db->pVTab = 0;
-  sqlite3_free(zModuleName);
+  sqlite3DbFree(db, zModuleName);
 
   /* If everything went according to plan, loop through the columns
   ** of the table to see if any of them contain the token "hidden".
@@ -457,7 +458,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
     if( rc!=SQLITE_OK ){
       sqlite3ErrorMsg(pParse, "%s", zErr);
     }
-    sqlite3_free(zErr);
+    sqlite3DbFree(db, zErr);
   }
 
   return rc;
@@ -493,7 +494,7 @@ static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
 **
 ** If an error occurs, *pzErr is set to point an an English language
 ** description of the error and an SQLITE_XXX error code is returned.
-** In this case the caller must call sqlite3_free() on *pzErr.
+** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
 */
 int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
   int rc = SQLITE_OK;
@@ -562,7 +563,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
     db->pVTab = 0;
   } else {
     sqlite3Error(db, SQLITE_ERROR, zErr);
-    sqlite3_free(zErr);
+    sqlite3DbFree(db, zErr);
     rc = SQLITE_ERROR;
   }
   sParse.declareVtab = 0;
@@ -632,7 +633,7 @@ static void callFinaliser(sqlite3 *db, int offset){
       if( x ) x(pVtab);
       sqlite3VtabUnlock(db, pVtab);
     }
-    sqlite3_free(db->aVTrans);
+    sqlite3DbFree(db, db->aVTrans);
     db->nVTrans = 0;
     db->aVTrans = 0;
   }
@@ -787,7 +788,7 @@ FuncDef *sqlite3VtabOverloadFunction(
       *z = sqlite3UpperToLower[*z];
     }
     rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
-    sqlite3_free(zLowerName);
+    sqlite3DbFree(db, zLowerName);
     sqlite3VtabTransferError(db, rc, pVtab);
   }
   if( rc==0 ){
@@ -835,7 +836,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
 void sqlite3VtabTransferError(sqlite3 *db, int rc, sqlite3_vtab *pVtab){
   if( pVtab->zErrMsg ){
     sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
-    sqlite3_free(pVtab->zErrMsg);
+    sqlite3DbFree(db, pVtab->zErrMsg);
     pVtab->zErrMsg = 0;
   }
 }
index 5971028b58646bca200c9e91c59e3c31ac700dce..dac5161b83dfee8499439c420d0e9b4caef4063b 100644 (file)
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.317 2008/07/12 14:52:20 drh Exp $
+** $Id: where.c,v 1.318 2008/07/28 19:34:54 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -92,7 +92,7 @@ struct WhereTerm {
 /*
 ** Allowed values of WhereTerm.flags
 */
-#define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(pExpr) */
+#define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
 #define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
 #define TERM_CODED      0x04   /* This term is already coded */
 #define TERM_COPIED     0x08   /* Has a child */
@@ -203,13 +203,14 @@ static void whereClauseInit(
 static void whereClauseClear(WhereClause *pWC){
   int i;
   WhereTerm *a;
+  sqlite3 *db = pWC->pParse->db;
   for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
     if( a->flags & TERM_DYNAMIC ){
-      sqlite3ExprDelete(a->pExpr);
+      sqlite3ExprDelete(db, a->pExpr);
     }
   }
   if( pWC->a!=pWC->aStatic ){
-    sqlite3_free(pWC->a);
+    sqlite3DbFree(db, pWC->a);
   }
 }
 
@@ -230,18 +231,18 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
   int idx;
   if( pWC->nTerm>=pWC->nSlot ){
     WhereTerm *pOld = pWC->a;
-    pWC->a = sqlite3Malloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
+    sqlite3 *db = pWC->pParse->db;
+    pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
     if( pWC->a==0 ){
-      pWC->pParse->db->mallocFailed = 1;
       if( flags & TERM_DYNAMIC ){
-        sqlite3ExprDelete(p);
+        sqlite3ExprDelete(db, p);
       }
       pWC->a = pOld;
       return 0;
     }
     memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
     if( pOld!=pWC->aStatic ){
-      sqlite3_free(pOld);
+      sqlite3DbFree(db, pOld);
     }
     pWC->nSlot *= 2;
   }
@@ -773,7 +774,7 @@ static void exprAnalyze(
         int idxNew;
         pDup = sqlite3ExprDup(db, pExpr);
         if( db->mallocFailed ){
-          sqlite3ExprDelete(pDup);
+          sqlite3ExprDelete(db, pDup);
           return;
         }
         idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
@@ -889,7 +890,7 @@ static void exprAnalyze(
         pWC->a[idxNew].iParent = idxTerm;
         pTerm->nChild = 1;
       }else{
-        sqlite3ExprListDelete(pList);
+        sqlite3ExprListDelete(db, pList);
       }
     }
 or_not_possible:
@@ -1908,14 +1909,15 @@ static int nQPlan = 0;              /* Next free slow in _query_plan[] */
 static void whereInfoFree(WhereInfo *pWInfo){
   if( pWInfo ){
     int i;
+    sqlite3 *db = pWInfo->pParse->db;
     for(i=0; i<pWInfo->nLevel; i++){
       sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
       if( pInfo ){
         assert( pInfo->needToFreeIdxStr==0 );
-        sqlite3_free(pInfo);
+        sqlite3DbFree(db, pInfo);
       }
     }
-    sqlite3_free(pWInfo);
+    sqlite3DbFree(db, pWInfo);
   }
 }
 
@@ -2248,22 +2250,22 @@ WhereInfo *sqlite3WhereBegin(
       struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
       zMsg = sqlite3MPrintf(db, "TABLE %s", pItem->zName);
       if( pItem->zAlias ){
-        zMsg = sqlite3MPrintf(db, "%z AS %s", zMsg, pItem->zAlias);
+        zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
       }
       if( (pIx = pLevel->pIdx)!=0 ){
-        zMsg = sqlite3MPrintf(db, "%z WITH INDEX %s", zMsg, pIx->zName);
+        zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s", zMsg, pIx->zName);
       }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
-        zMsg = sqlite3MPrintf(db, "%z USING PRIMARY KEY", zMsg);
+        zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg);
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
       else if( pLevel->pBestIdx ){
         sqlite3_index_info *pBestIdx = pLevel->pBestIdx;
-        zMsg = sqlite3MPrintf(db, "%z VIRTUAL TABLE INDEX %d:%s", zMsg,
+        zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
                     pBestIdx->idxNum, pBestIdx->idxStr);
       }
 #endif
       if( pLevel->flags & WHERE_ORDERBY ){
-        zMsg = sqlite3MPrintf(db, "%z ORDER BY", zMsg);
+        zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
       }
       sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
     }
@@ -2779,14 +2781,16 @@ whereBeginNoMem:
 ** sqlite3WhereBegin() for additional information.
 */
 void sqlite3WhereEnd(WhereInfo *pWInfo){
-  Vdbe *v = pWInfo->pParse->pVdbe;
+  Parse *pParse = pWInfo->pParse;
+  Vdbe *v = pParse->pVdbe;
   int i;
   WhereLevel *pLevel;
   SrcList *pTabList = pWInfo->pTabList;
+  sqlite3 *db = pParse->db;
 
   /* Generate loop termination code.
   */
-  sqlite3ExprClearColumnCache(pWInfo->pParse, -1);
+  sqlite3ExprClearColumnCache(pParse, -1);
   for(i=pTabList->nSrc-1; i>=0; i--){
     pLevel = &pWInfo->a[i];
     sqlite3VdbeResolveLabel(v, pLevel->cont);
@@ -2802,7 +2806,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
         sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->topAddr);
         sqlite3VdbeJumpHere(v, pIn->topAddr-1);
       }
-      sqlite3_free(pLevel->aInLoop);
+      sqlite3DbFree(db, pLevel->aInLoop);
     }
     sqlite3VdbeResolveLabel(v, pLevel->brk);
     if( pLevel->iLeftJoin ){
index 7061798c9576115d02cbec8d0e5723be58a5e349..0c0b12b7a6944561ae041db5007eb996aef85cdf 100644 (file)
@@ -11,7 +11,7 @@
 #
 # This file contains tests of the memory allocation subsystem
 #
-# $Id: memsubsys1.test,v 1.5 2008/07/25 13:39:08 drh Exp $
+# $Id: memsubsys1.test,v 1.6 2008/07/28 19:34:54 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -26,6 +26,7 @@ proc build_test_db {testname pragmas} {
   catch {db close}
   file delete -force test.db test.db-journal
   sqlite3 db test.db
+  sqlite3_db_config_lookaside db 0 0
   db eval $pragmas
   db eval {
     CREATE TABLE t1(x, y);
@@ -49,6 +50,7 @@ proc build_test_db {testname pragmas} {
 #
 db close
 sqlite3_shutdown
+sqlite3_config_lookaside 0 0
 sqlite3_initialize
 build_test_db memsubsys1-1 {PRAGMA page_size=1024}
 do_test memsubsys1-1.3 {
@@ -224,6 +226,7 @@ db close
 sqlite3_shutdown
 sqlite3_config_pagecache 0 0
 sqlite3_config_scratch 0 0
+sqlite3_config_lookaside 100 500
 sqlite3_initialize
 autoinstall_test_functions
 finish_test
index dcee0733a74100de0c892e4ba2345eada30c1fc1..ba0d8c154775435f7fad258cda2e3667c3eb9dba 100644 (file)
 # This file implements regression tests for SQLite library.  The
 # focus of this script is measuring executing speed.
 #
-# $Id: speed1.test,v 1.6 2008/07/24 23:34:07 drh Exp $
+# $Id: speed1.test,v 1.7 2008/07/28 19:34:54 drh Exp $
 #
 
 sqlite3_shutdown
 sqlite3_config_scratch 29000 1
+sqlite3_config_lookaside 1000 300
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 speed_trial_init speed1
index 94ca5498032d8ac9a353c26d1513bdbc23b4e096..155fdbc018d341796af34d0a63ae90b2a2ad849a 100644 (file)
@@ -3147,7 +3147,7 @@ int *lineno;
  }else if( sp->destructor ){
    cp = sp->destructor;
    fprintf(out,"{\n"); (*lineno)++;
-   tplt_linedir(out,sp->destLineno,lemp->outname); (*lineno)++;
+   tplt_linedir(out,sp->destLineno,lemp->filename); (*lineno)++;
  }else if( lemp->vardest ){
    cp = lemp->vardest;
    if( cp==0 ) return;
index 061331f6780d0fb13266bfebcd7057adedbd092e..f5fafd4c28b583058a3267ca69fb07dfc03df969 100644 (file)
@@ -273,7 +273,12 @@ void *ParseAlloc(void *(*mallocProc)(size_t)){
 ** "yymajor" is the symbol code, and "yypminor" is a pointer to
 ** the value.
 */
-static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
+static void yy_destructor(
+  yyParser *yypParser,    /* The parser */
+  YYCODETYPE yymajor,     /* Type code for object to destroy */
+  YYMINORTYPE *yypminor   /* The object to be destroyed */
+){
+  ParseARG_FETCH;
   switch( yymajor ){
     /* Here is inserted the actions which take place when a
     ** terminal or non-terminal is destroyed.  This can happen
@@ -311,7 +316,7 @@ static int yy_pop_parser_stack(yyParser *pParser){
   }
 #endif
   yymajor = yytos->major;
-  yy_destructor( yymajor, &yytos->minor);
+  yy_destructor(pParser, yymajor, &yytos->minor);
   pParser->yyidx--;
   return yymajor;
 }
@@ -758,7 +763,7 @@ void Parse(
              yyTracePrompt,yyTokenName[yymajor]);
         }
 #endif
-        yy_destructor(yymajor,&yyminorunion);
+        yy_destructor(yypParser, yymajor,&yyminorunion);
         yymajor = YYNOCODE;
       }else{
          while(
@@ -771,7 +776,7 @@ void Parse(
           yy_pop_parser_stack(yypParser);
         }
         if( yypParser->yyidx < 0 || yymajor==0 ){
-          yy_destructor(yymajor,&yyminorunion);
+          yy_destructor(yypParser,yymajor,&yyminorunion);
           yy_parse_failed(yypParser);
           yymajor = YYNOCODE;
         }else if( yymx!=YYERRORSYMBOL ){
@@ -796,7 +801,7 @@ void Parse(
         yy_syntax_error(yypParser,yymajor,yyminorunion);
       }
       yypParser->yyerrcnt = 3;
-      yy_destructor(yymajor,&yyminorunion);
+      yy_destructor(yypParser,yymajor,&yyminorunion);
       if( yyendofinput ){
         yy_parse_failed(yypParser);
       }