Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 24076fd97d | |||
| d4e244ad56 | |||
| 76a3acacea | |||
| 4dd65e0f0c | |||
| 5c0c56b89c | |||
| 814d6a7ba7 | |||
| 2fb6693e02 | |||
| 5e4461b261 | |||
| 21495ba8a3 | |||
| 070ad6b6fe | |||
| 283829cb20 | |||
| f20fb8c6f3 | |||
| 09419b4bae | |||
| 870c0178f7 | |||
| 81ef0f97ef | |||
| f923f82118 | |||
| c90747313e | |||
| 61a4bd5c6c | |||
| 8225d66be6 | |||
| 32121199be | |||
| e73c91496f | |||
| 3b42abb35b | |||
| 6a8ab6d9cb | |||
| e5c40b18e3 | |||
| 22e21ff4fc |
@@ -49,6 +49,9 @@ BCC = cl.exe
|
||||
#
|
||||
TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
|
||||
|
||||
# We always have the _msize function available when using MSVC.
|
||||
TCC = $(TCC) -DHAVE_MALLOC_USABLE_SIZE -Dmalloc_usable_size=_msize
|
||||
|
||||
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
|
||||
# any extension header files by default. For non-amalgamation
|
||||
# builds, we need to make sure the compiler can find these.
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
/* Define to 1 if you have the `localtime_s' function. */
|
||||
#undef HAVE_LOCALTIME_S
|
||||
|
||||
/* Define to 1 if you have the `malloc_usable_size' function. */
|
||||
#undef HAVE_MALLOC_USABLE_SIZE
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h])
|
||||
#########
|
||||
# Figure out whether or not we have these functions
|
||||
#
|
||||
AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime])
|
||||
AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size])
|
||||
|
||||
#########
|
||||
# By default, we use the amalgamation (this may be changed below...)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C Change\sthe\smultiplexor\ssuffix\sfrom\s2\sto\s3\sdigits.
|
||||
D 2011-11-16T17:32:28.704
|
||||
C Add\sa\sprototype\simplementation\sof\sstdio-like\sroutines\sfor\saccessing\sthe\sVFS.\nThis\sis\sintended\sas\sdocumentation.\s\sThe\scode\sis\suntested.\sThere\sis\sno\nguarantee\sthat\sany\sof\sthis\swill\sever\smake\sit\sinto\strunk.\s\sSubstantial\nrevision\sis\spossible\sprior\sto\sreaching\strunk,\sif\sit\sever\sdoes.
|
||||
D 2011-12-01T02:32:12.196
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d
|
||||
F Makefile.msc 3bd3641a345d488a9601c0cc7f9d35aeede5d12b
|
||||
F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
F VERSION bb37c274b503bbe73f00ea4f374eb817cba4b171
|
||||
F VERSION af03cd6400f9d71d38bdb7a9d66a1aefdc2f3e0d
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
|
||||
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
||||
@@ -21,10 +21,10 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 405a958bdb3af382a809dccb08a44694923ddd61
|
||||
F config.h.in 31cc8c4943f56e60c4aa4fba929c9d4c70e418b4
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 806c06aef5895860da49600ce098dbe4d5a8435c x
|
||||
F configure.ac 298a759c086e72c013da459c2aec02a104f4224f
|
||||
F configure cdfb8a907ded1f8e75b6967e3e3bd35718884aff x
|
||||
F configure.ac 75323bdac56fb0e69f6a3fc5b23f24359550b9d9
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549
|
||||
F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e
|
||||
@@ -133,12 +133,12 @@ F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c ff68e5ef23aee08c0ff528f699a19397ed8bbed8
|
||||
F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112
|
||||
F src/expr.c fbf116f90cabc917ae50bba24a73a0b55519a0c8
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
|
||||
F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9
|
||||
F src/global.c e230227de13601714b29f9363028514aada5ae2f
|
||||
F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1
|
||||
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
@@ -147,10 +147,10 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
||||
F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f
|
||||
F src/main.c df06f5229b8046f85dde253dfd7fe35ae9e4902e
|
||||
F src/main.c 8be1ee70dd90ef7562c801dbe946a4f9f93bb128
|
||||
F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
||||
F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4
|
||||
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
|
||||
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
|
||||
F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f
|
||||
@@ -162,34 +162,34 @@ F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f
|
||||
F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579
|
||||
F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9
|
||||
F src/os.c c2dcf314db63a0ea06af00fcf087750a1852bbbc
|
||||
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
|
||||
F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f
|
||||
F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803
|
||||
F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54
|
||||
F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d
|
||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||
F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce
|
||||
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
||||
F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197
|
||||
F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7
|
||||
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
||||
F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539
|
||||
F src/pager.h 5cd760857707529b403837d813d86b68938d6183
|
||||
F src/parse.y d02cc7bdb9ba11fb7aa212f55f99e59e4ee55439
|
||||
F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c
|
||||
F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f
|
||||
F src/pcache1.c 9d735349ac87ef08076c6b1230f04cd83b15c6da
|
||||
F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583
|
||||
F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e
|
||||
F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
|
||||
F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6
|
||||
F src/sqlite.h.in b7a4e8d428e467d820cbb4c1d275fdda88b4d7ab
|
||||
F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8
|
||||
F src/sqlite.h.in 6ab24133ed28e094dc67981cd9279d7bd8b31cf6
|
||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||
F src/sqliteInt.h ce631f204a67ae35b817928e3931484bda0963bc
|
||||
F src/sqliteInt.h 6f28b69d77356b1e45c024a6c103a1e0f0ec9f62
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0
|
||||
F src/test1.c 0f41b7c67719207a5de24b009e172c4dcf189827
|
||||
F src/test1.c fe455fc1be1b0dbf4ce45b11c255900e8ae18da3
|
||||
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
|
||||
F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
|
||||
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
|
||||
@@ -202,24 +202,24 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
|
||||
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
|
||||
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
|
||||
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
|
||||
F src/test_config.c bc8826296a7b3a86eeaba1ac2af5551d1c20c35b
|
||||
F src/test_config.c a036a69b550ebc477ab9ca2b37269201f888436e
|
||||
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
||||
F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254
|
||||
F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a
|
||||
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
|
||||
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
|
||||
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
||||
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
|
||||
F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5
|
||||
F src/test_multiplex.c 6a65dd5006117d26718110a8e00b0118aa5c98a1
|
||||
F src/test_multiplex.c 185378cade15fa9012bd17d9d5b04783d4478f79
|
||||
F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
|
||||
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
|
||||
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
|
||||
F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32
|
||||
F src/test_pcache.c 335285416eb7a5c3a0f4daffb796912011ebbf6e
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419
|
||||
F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1
|
||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||
@@ -242,7 +242,7 @@ F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
|
||||
F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889
|
||||
F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755
|
||||
F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176
|
||||
F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546
|
||||
F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd
|
||||
F src/vdbeaux.c 45713a5f8f4f36195f503b30153ddef292323f88
|
||||
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
|
||||
F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56
|
||||
@@ -274,7 +274,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
|
||||
F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c
|
||||
F test/attach.test 0e6f8de2589f11a5f474ef57fe5af2877e61c0e8
|
||||
F test/attach.test 0d112b7713611fdf0340260192749737135fda5f
|
||||
F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966
|
||||
F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
@@ -315,7 +315,7 @@ F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360
|
||||
F test/capi3.test 7200dff6acb17b9a4b6f9918f554eaae04968ddd
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test ccf0acf045dbacd09f6229aa4efed670aaba76a9
|
||||
F test/capi3d.test cd36571f014f34bdc4421967f6453cbb597d5d16
|
||||
F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1
|
||||
F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
F test/check.test db2b29d557544347d28e25b8406f5d5ecc3d1bc3
|
||||
@@ -361,7 +361,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff
|
||||
F test/dbstatus.test 9eb484ba837c6f3f9bbcaecc29e6060a8c3ba6d2
|
||||
F test/dbstatus.test 179575499759241bf92ca2fb86bd3ccc8a562aac
|
||||
F test/dbstatus2.test dc57b0d9610851c0ff58a8e1b5b191678398b72a
|
||||
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
|
||||
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
|
||||
@@ -592,7 +592,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test c0db8a1e99f4fa07cb858900c55bad9547899aa8
|
||||
F test/memsubsys1.test a8f9e37567453a5d1d9d37ec102d4d88ab6be33f
|
||||
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
||||
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
|
||||
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
|
||||
@@ -627,7 +627,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/permutations.test 522823b47238cb1754198f80817fe9f9158ede55
|
||||
F test/pragma.test 1ea0c85be853135bb7468e6eed48ee12b04794d4
|
||||
F test/pragma.test 7fa35e53085812dac94c2bfcbb02c2a4ad35df5e
|
||||
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
|
||||
@@ -678,6 +678,7 @@ F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
|
||||
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
|
||||
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/shrink.test 28165922bfea5c003c51a2d02bce69c4141ef013
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||
F test/softheap1.test c16709a16ad79fa43b32929b2e623d1d117ccf53
|
||||
@@ -975,10 +976,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
P a5418c7fc216a30abf7b2fa8c579aee586393a91
|
||||
R 6f660080d5c293528a113cc8cdb20026
|
||||
T *branch * 3-digit-multiplex-suffix
|
||||
T *sym-3-digit-multiplex-suffix *
|
||||
P 431556cac0b2c86d7f6a60412ff1023feeaafedf
|
||||
R 0398714a93656ee1bfce81727b47b578
|
||||
T *branch * vfs-stdio
|
||||
T *sym-vfs-stdio *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 8b5e0625a534e1e664db241b7f45d292
|
||||
Z 536ed89e4d5b4e5e1bbeee8dbaae70fb
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
06e0cdaf9112f722c23692e25c5b1f99b61c2d78
|
||||
8936542b225836f5f4a789e1ecc1451f6a1e120d
|
||||
@@ -148,7 +148,6 @@ Expr *sqlite3LimitWhere(
|
||||
*/
|
||||
if( pOrderBy && (pLimit == 0) ) {
|
||||
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
|
||||
pParse->parseError = 1;
|
||||
goto limit_where_cleanup_2;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
500, /* nLookaside */
|
||||
{0,0,0,0,0,0,0,0}, /* m */
|
||||
{0,0,0,0,0,0,0,0,0}, /* mutex */
|
||||
{0,0,0,0,0,0,0,0,0,0,0}, /* pcache */
|
||||
{0,0,0,0,0,0,0,0,0,0,0}, /* pcache2 */
|
||||
(void*)0, /* pHeap */
|
||||
0, /* nHeap */
|
||||
0, 0, /* mnHeap, mxHeap */
|
||||
|
||||
+58
-33
@@ -365,16 +365,25 @@ int sqlite3_config(int op, ...){
|
||||
}
|
||||
|
||||
case SQLITE_CONFIG_PCACHE: {
|
||||
/* Specify an alternative page cache implementation */
|
||||
sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*);
|
||||
/* no-op */
|
||||
break;
|
||||
}
|
||||
case SQLITE_CONFIG_GETPCACHE: {
|
||||
/* now an error */
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_CONFIG_GETPCACHE: {
|
||||
if( sqlite3GlobalConfig.pcache.xInit==0 ){
|
||||
case SQLITE_CONFIG_PCACHE2: {
|
||||
/* Specify an alternative page cache implementation */
|
||||
sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
|
||||
break;
|
||||
}
|
||||
case SQLITE_CONFIG_GETPCACHE2: {
|
||||
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
|
||||
sqlite3PCacheSetDefault();
|
||||
}
|
||||
*va_arg(ap, sqlite3_pcache_methods*) = sqlite3GlobalConfig.pcache;
|
||||
*va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -473,21 +482,21 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
||||
if( db->lookaside.bMalloced ){
|
||||
sqlite3_free(db->lookaside.pStart);
|
||||
}
|
||||
/* The size of a lookaside slot needs to be larger than a pointer
|
||||
** to be useful.
|
||||
/* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
|
||||
** than a pointer to be useful.
|
||||
*/
|
||||
sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
|
||||
if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
|
||||
if( cnt<0 ) cnt = 0;
|
||||
if( sz==0 || cnt==0 ){
|
||||
sz = 0;
|
||||
pStart = 0;
|
||||
}else if( pBuf==0 ){
|
||||
sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
|
||||
sqlite3BeginBenignMalloc();
|
||||
pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */
|
||||
sqlite3EndBenignMalloc();
|
||||
if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
|
||||
}else{
|
||||
sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
|
||||
pStart = pBuf;
|
||||
}
|
||||
db->lookaside.pStart = pStart;
|
||||
@@ -521,6 +530,24 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
|
||||
return db->mutex;
|
||||
}
|
||||
|
||||
/*
|
||||
** Free up as much memory as we can from the given database
|
||||
** connection.
|
||||
*/
|
||||
int sqlite3_db_release_memory(sqlite3 *db){
|
||||
int i;
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( pBt ){
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
sqlite3PagerShrink(pPager);
|
||||
}
|
||||
}
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Configuration settings for an individual database connection
|
||||
*/
|
||||
@@ -1628,7 +1655,6 @@ static int createCollation(
|
||||
sqlite3* db,
|
||||
const char *zName,
|
||||
u8 enc,
|
||||
u8 collType,
|
||||
void* pCtx,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*),
|
||||
void(*xDel)(void*)
|
||||
@@ -1693,7 +1719,6 @@ static int createCollation(
|
||||
pColl->pUser = pCtx;
|
||||
pColl->xDel = xDel;
|
||||
pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
|
||||
pColl->type = collType;
|
||||
sqlite3Error(db, SQLITE_OK, 0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -2154,14 +2179,10 @@ static int openDatabase(
|
||||
** and UTF-16, so add a version for each to avoid any unnecessary
|
||||
** conversions. The only error that can occur here is a malloc() failure.
|
||||
*/
|
||||
createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0,
|
||||
binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0,
|
||||
binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16LE, SQLITE_COLL_BINARY, 0,
|
||||
binCollFunc, 0);
|
||||
createCollation(db, "RTRIM", SQLITE_UTF8, SQLITE_COLL_USER, (void*)1,
|
||||
binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
|
||||
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
|
||||
if( db->mallocFailed ){
|
||||
goto opendb_out;
|
||||
}
|
||||
@@ -2169,8 +2190,7 @@ static int openDatabase(
|
||||
assert( db->pDfltColl!=0 );
|
||||
|
||||
/* Also add a UTF-8 case-insensitive collation sequence. */
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0,
|
||||
nocaseCollatingFunc, 0);
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
||||
|
||||
/* Parse the filename/URI argument. */
|
||||
db->openFlags = flags;
|
||||
@@ -2363,7 +2383,7 @@ int sqlite3_create_collation(
|
||||
int rc;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
assert( !db->mallocFailed );
|
||||
rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
|
||||
rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
@@ -2383,7 +2403,7 @@ int sqlite3_create_collation_v2(
|
||||
int rc;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
assert( !db->mallocFailed );
|
||||
rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel);
|
||||
rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
@@ -2406,7 +2426,7 @@ int sqlite3_create_collation16(
|
||||
assert( !db->mallocFailed );
|
||||
zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
|
||||
if( zName8 ){
|
||||
rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
|
||||
rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0);
|
||||
sqlite3DbFree(db, zName8);
|
||||
}
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
@@ -2889,15 +2909,6 @@ int sqlite3_test_control(int op, ...){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_PGHDRSZ)
|
||||
**
|
||||
** Return the size of a pcache header in bytes.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_PGHDRSZ: {
|
||||
rc = sizeof(PgHdr);
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree);
|
||||
**
|
||||
** Pass pFree into sqlite3ScratchFree().
|
||||
@@ -2952,3 +2963,17 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the filename of the database associated with a database
|
||||
** connection.
|
||||
*/
|
||||
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
|
||||
int i;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt && sqlite3StrICmp(zDbName, db->aDb[i].zName)==0 ){
|
||||
return sqlite3BtreeGetFilename(db->aDb[i].pBt);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+32
@@ -26,6 +26,10 @@
|
||||
*/
|
||||
#ifdef SQLITE_SYSTEM_MALLOC
|
||||
|
||||
#ifdef HAVE_MALLOC_USABLE_SIZE
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Like malloc(), but remember the size of the allocation
|
||||
** so that we can find it later using sqlite3MemSize().
|
||||
@@ -35,6 +39,14 @@
|
||||
** routines.
|
||||
*/
|
||||
static void *sqlite3MemMalloc(int nByte){
|
||||
#ifdef HAVE_MALLOC_USABLE_SIZE
|
||||
void *p = malloc( nByte );
|
||||
if( p==0 ){
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
|
||||
}
|
||||
return p;
|
||||
#else
|
||||
sqlite3_int64 *p;
|
||||
assert( nByte>0 );
|
||||
nByte = ROUND8(nByte);
|
||||
@@ -47,6 +59,7 @@ static void *sqlite3MemMalloc(int nByte){
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
|
||||
}
|
||||
return (void *)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -58,10 +71,14 @@ static void *sqlite3MemMalloc(int nByte){
|
||||
** by higher-level routines.
|
||||
*/
|
||||
static void sqlite3MemFree(void *pPrior){
|
||||
#if HAVE_MALLOC_USABLE_SIZE
|
||||
free(pPrior);
|
||||
#else
|
||||
sqlite3_int64 *p = (sqlite3_int64*)pPrior;
|
||||
assert( pPrior!=0 );
|
||||
p--;
|
||||
free(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -69,11 +86,15 @@ static void sqlite3MemFree(void *pPrior){
|
||||
** or xRealloc().
|
||||
*/
|
||||
static int sqlite3MemSize(void *pPrior){
|
||||
#if HAVE_MALLOC_USABLE_SIZE
|
||||
return pPrior ? (int)malloc_usable_size(pPrior) : 0;
|
||||
#else
|
||||
sqlite3_int64 *p;
|
||||
if( pPrior==0 ) return 0;
|
||||
p = (sqlite3_int64*)pPrior;
|
||||
p--;
|
||||
return (int)p[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -87,6 +108,16 @@ static int sqlite3MemSize(void *pPrior){
|
||||
** routines and redirected to xFree.
|
||||
*/
|
||||
static void *sqlite3MemRealloc(void *pPrior, int nByte){
|
||||
#if HAVE_MALLOC_USABLE_SIZE
|
||||
void *p = realloc(pPrior, nByte);
|
||||
if( p==0 ){
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM,
|
||||
"failed memory resize %u to %u bytes",
|
||||
malloc_usable_size(pPrior), nByte);
|
||||
}
|
||||
return p;
|
||||
#else
|
||||
sqlite3_int64 *p = (sqlite3_int64*)pPrior;
|
||||
assert( pPrior!=0 && nByte>0 );
|
||||
assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
|
||||
@@ -102,6 +133,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
|
||||
sqlite3MemSize(pPrior), nByte);
|
||||
}
|
||||
return (void*)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -340,3 +340,235 @@ int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
|
||||
sqlite3_mutex_leave(mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_VFS_STDIO
|
||||
/*****************************************************************************
|
||||
** The remainder of this file contains a simplified stdio-like interface
|
||||
** to the VFS layer.
|
||||
*/
|
||||
|
||||
/*
|
||||
** An instance of the following object records the state of an
|
||||
** open file. This object is opaque to all users - the internal
|
||||
** structure is only visible to the functions below.
|
||||
*/
|
||||
struct sqlite3_FILE {
|
||||
char *zFilename; /* Full pathname of the open file */
|
||||
sqlite3_int64 iOfst; /* Current offset into the file */
|
||||
sqlite3_vfs *pVfs; /* The VFS used for this file */
|
||||
u8 alwaysAppend; /* Always append if true */
|
||||
sqlite3_file sFile; /* Open file. MUST BE LAST */
|
||||
};
|
||||
|
||||
/*
|
||||
** This is a helper routine used to translate a URI into a full pathname
|
||||
** and a pointer to the appropriate VFS.
|
||||
*/
|
||||
static int getFilename(const char *zURI, sqlite3_vfs **ppVfs, char **pzName){
|
||||
int rc;
|
||||
char *zOpen = 0;
|
||||
char *zFullname = 0;
|
||||
unsigned int flags;
|
||||
char *zErrmsg = 0;
|
||||
sqlite3_vfs *pVfs = 0;
|
||||
|
||||
rc = sqlite3ParseUri(0, zURI, &flags, &pVfs, &zOpen, &zErrmsg);
|
||||
sqlite3_free(zErrmsg);
|
||||
if( rc ) goto getFilename_error;
|
||||
zFullname = sqlite3_malloc( pVfs->mxPathname+1 );
|
||||
if( zFullname==0 ){ rc = SQLITE_NOMEM; goto getFilename_error; }
|
||||
rc = pVfs->xFullPathname(pVfs, zOpen, pVfs->mxPathname, zFullname);
|
||||
if( rc ) goto getFilename_error;
|
||||
sqlite3_free(zOpen);
|
||||
zOpen = 0;
|
||||
*pzName = sqlite3_realloc(zFullname, sqlite3Strlen30(zFullname)+1);
|
||||
if( *pzName==0 ) goto getFilename_error;
|
||||
zFullname = 0;
|
||||
*ppVfs = pVfs;
|
||||
return SQLITE_OK;
|
||||
|
||||
getFilename_error:
|
||||
sqlite3_free(zOpen);
|
||||
sqlite3_free(zFullname);
|
||||
*pzName = 0;
|
||||
*ppVfs = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Open a file for stdio-like reading and writing. The file is identified
|
||||
** by the URI in the first parameter. The access mode can be "r", "r+",
|
||||
** "w", "w+", "a", or "a+" with the usual meanings.
|
||||
**
|
||||
** On success, a pointer to a new sqlite3_FILE object is returned. On
|
||||
** failure, NULL is returned. Unfortunately, there is no way to recover
|
||||
** detailed error information after a failure.
|
||||
*/
|
||||
sqlite3_FILE *sqlite3_fopen(const char *zURI, const char *zMode){
|
||||
char *zFile = 0;
|
||||
sqlite3_vfs *pVfs = 0;
|
||||
int rc;
|
||||
int openFlags;
|
||||
int doTruncate = 0;
|
||||
int seekEnd = 0;
|
||||
int alwaysAppend = 0;
|
||||
int nToAlloc;
|
||||
sqlite3_FILE *p;
|
||||
|
||||
if( zMode[0]==0 ) return 0;
|
||||
if( zMode[0]=='r' ){
|
||||
if( zMode[1]=='+' ){
|
||||
openFlags = SQLITE_OPEN_READWRITE;
|
||||
}else{
|
||||
openFlags = SQLITE_OPEN_READONLY;
|
||||
}
|
||||
}else if( zMode[0]=='w' ){
|
||||
openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
||||
doTruncate = 1;
|
||||
}else if( zMode[0]=='a' ){
|
||||
openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
||||
if( zMode[1]=='+' ){
|
||||
alwaysAppend = 1;
|
||||
}else{
|
||||
seekEnd = 1;
|
||||
}
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
rc = getFilename(zURI, &pVfs, &zFile);
|
||||
if( rc ) return 0;
|
||||
nToAlloc = sizeof(*p) + ROUND8(pVfs->szOsFile);
|
||||
p = sqlite3_malloc( nToAlloc );
|
||||
if( p==0 ){
|
||||
sqlite3_free(zFile);
|
||||
return 0;
|
||||
}
|
||||
memset(p, 0, nToAlloc);
|
||||
p->zFilename = zFile;
|
||||
rc = pVfs->xOpen(pVfs, zFile, &p->sFile, openFlags, &openFlags);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(zFile);
|
||||
sqlite3_free(p);
|
||||
return 0;
|
||||
}
|
||||
p->pVfs = pVfs;
|
||||
p->alwaysAppend = alwaysAppend;
|
||||
if( seekEnd ) sqlite3_fseek(p, 0, SQLITE_SEEK_END);
|
||||
if( doTruncate ) sqlite3_ftruncate(p, 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a file perviously opened by sqlite3_fopen().
|
||||
*/
|
||||
int sqlite3_fclose(sqlite3_FILE *p){
|
||||
p->sFile.pMethods->xClose(&p->sFile);
|
||||
sqlite3_free(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read iAmt bytes from the file p into pBuf.
|
||||
**
|
||||
** Return 0 on success or an error code if the full amount could
|
||||
** not be read.
|
||||
*/
|
||||
int sqlite3_fread(
|
||||
void *pBuf, /* Write content read into this buffer */
|
||||
sqlite3_int64 iAmt, /* Number of bytes to read */
|
||||
sqlite3_FILE *p /* Read from this file */
|
||||
){
|
||||
int rc = p->sFile.pMethods->xRead(&p->sFile, pBuf, iAmt, p->iOfst);
|
||||
if( rc==SQLITE_OK ){
|
||||
p->iOfst += iAmt;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Write iAmt bytes from buffer pBuf into the file p.
|
||||
**
|
||||
** Return 0 on success or an error code if anything goes wrong.
|
||||
*/
|
||||
int sqlite3_fwrite(
|
||||
const void *pBuf, /* Take content to be written from this buffer */
|
||||
sqlite3_int64 iAmt, /* Number of bytes to write */
|
||||
sqlite3_FILE *p /* Write into this file */
|
||||
){
|
||||
int rc;
|
||||
|
||||
if( p->alwaysAppend ) sqlite3_fseek(p, 0, SQLITE_SEEK_END);
|
||||
rc = p->sFile.pMethods->xWrite(&p->sFile, pBuf, iAmt, p->iOfst);
|
||||
if( rc==SQLITE_OK ){
|
||||
p->iOfst += iAmt;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Truncate an open file to newSize bytes.
|
||||
*/
|
||||
int sqlite3_ftruncate(sqlite3_FILE *p, sqlite3_int64 newSize){
|
||||
int rc;
|
||||
rc = p->sFile.pMethods->xTruncate(&p->sFile, newSize);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current position of the file pointer.
|
||||
*/
|
||||
sqlite3_int64 sqlite3_ftell(sqlite3_FILE *p){
|
||||
return p->iOfst;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move the file pointer to a new position in the file.
|
||||
*/
|
||||
int sqlite3_fseek(sqlite3_FILE *p, sqlite3_int64 ofst, int whence){
|
||||
int rc = SQLITE_OK;
|
||||
if( whence==SQLITE_SEEK_SET ){
|
||||
p->iOfst = ofst;
|
||||
}else if( whence==SQLITE_SEEK_CUR ){
|
||||
p->iOfst += ofst;
|
||||
}else{
|
||||
sqlite3_int64 iCur = 0;
|
||||
rc = p->sFile.pMethods->xFileSize(&p->sFile, &iCur);
|
||||
if( rc==SQLITE_OK ){
|
||||
p->iOfst = iCur + ofst;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Rewind the file pointer to the beginning of the file.
|
||||
*/
|
||||
int sqlite3_rewind(sqlite3_FILE *p){
|
||||
p->iOfst = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush the content of OS cache buffers to disk. (fsync())
|
||||
*/
|
||||
int sqlite3_fflush(sqlite3_FILE *p){
|
||||
return p->sFile.pMethods->xSync(&p->sFile, SQLITE_SYNC_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
** Delete the file identified by the URI in the first parameter
|
||||
*/
|
||||
int sqlite3_remove(const char *zURI){
|
||||
sqlite3_vfs *pVfs = 0;
|
||||
char *zFilename = 0;
|
||||
int rc;
|
||||
|
||||
rc = getFilename(zURI, &pVfs, &zFilename);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = pVfs->xDelete(pVfs, zFilename, 0);
|
||||
}
|
||||
sqlite3_free(zFilename);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_VFS_STDIO */
|
||||
|
||||
@@ -3294,6 +3294,13 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
|
||||
sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
|
||||
}
|
||||
|
||||
/*
|
||||
** Free as much memory as possible from the pager.
|
||||
*/
|
||||
void sqlite3PagerShrink(Pager *pPager){
|
||||
sqlite3PcacheShrink(pPager->pPCache);
|
||||
}
|
||||
|
||||
/*
|
||||
** Adjust the robustness of the database to damage due to OS crashes
|
||||
** or power failures by changing the number of syncs()s when writing
|
||||
|
||||
@@ -103,6 +103,7 @@ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
|
||||
int sqlite3PagerSetPagesize(Pager*, u32*, int);
|
||||
int sqlite3PagerMaxPageCount(Pager*, int);
|
||||
void sqlite3PagerSetCachesize(Pager*, int);
|
||||
void sqlite3PagerShrink(Pager*);
|
||||
void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
|
||||
int sqlite3PagerLockingMode(Pager *, int);
|
||||
int sqlite3PagerSetJournalMode(Pager *, int);
|
||||
|
||||
@@ -33,12 +33,10 @@
|
||||
UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
|
||||
assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */
|
||||
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
|
||||
pParse->parseError = 1;
|
||||
}
|
||||
%stack_overflow {
|
||||
UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
|
||||
sqlite3ErrorMsg(pParse, "parser stack overflow");
|
||||
pParse->parseError = 1;
|
||||
}
|
||||
|
||||
// The name of the generated procedure that implements the parser
|
||||
|
||||
+66
-41
@@ -20,7 +20,7 @@ struct PCache {
|
||||
PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
|
||||
PgHdr *pSynced; /* Last synced page in dirty page list */
|
||||
int nRef; /* Number of referenced pages */
|
||||
int nMax; /* Configured cache size */
|
||||
int szCache; /* Configured cache size */
|
||||
int szPage; /* Size of every page in this cache */
|
||||
int szExtra; /* Size of extra space for each page */
|
||||
int bPurgeable; /* True if pages are on backing store */
|
||||
@@ -131,7 +131,7 @@ static void pcacheUnpin(PgHdr *p){
|
||||
if( p->pgno==1 ){
|
||||
pCache->pPage1 = 0;
|
||||
}
|
||||
sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 0);
|
||||
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,18 +141,18 @@ static void pcacheUnpin(PgHdr *p){
|
||||
** functions are threadsafe.
|
||||
*/
|
||||
int sqlite3PcacheInitialize(void){
|
||||
if( sqlite3GlobalConfig.pcache.xInit==0 ){
|
||||
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
|
||||
/* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
|
||||
** built-in default page cache is used instead of the application defined
|
||||
** page cache. */
|
||||
sqlite3PCacheSetDefault();
|
||||
}
|
||||
return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg);
|
||||
return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
|
||||
}
|
||||
void sqlite3PcacheShutdown(void){
|
||||
if( sqlite3GlobalConfig.pcache.xShutdown ){
|
||||
if( sqlite3GlobalConfig.pcache2.xShutdown ){
|
||||
/* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
|
||||
sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg);
|
||||
sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ void sqlite3PcacheOpen(
|
||||
p->bPurgeable = bPurgeable;
|
||||
p->xStress = xStress;
|
||||
p->pStress = pStress;
|
||||
p->nMax = 100;
|
||||
p->szCache = 100;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -191,13 +191,24 @@ void sqlite3PcacheOpen(
|
||||
void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
|
||||
assert( pCache->nRef==0 && pCache->pDirty==0 );
|
||||
if( pCache->pCache ){
|
||||
sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache);
|
||||
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
|
||||
pCache->pCache = 0;
|
||||
pCache->pPage1 = 0;
|
||||
}
|
||||
pCache->szPage = szPage;
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute the number of pages of cache requested.
|
||||
*/
|
||||
static int numberOfCachePages(PCache *p){
|
||||
if( p->szCache>=0 ){
|
||||
return p->szCache;
|
||||
}else{
|
||||
return (-1024*p->szCache)/(p->szPage+p->szExtra);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Try to obtain a page from the cache.
|
||||
*/
|
||||
@@ -207,7 +218,8 @@ int sqlite3PcacheFetch(
|
||||
int createFlag, /* If true, create page if it does not exist already */
|
||||
PgHdr **ppPage /* Write the page here */
|
||||
){
|
||||
PgHdr *pPage = 0;
|
||||
sqlite3_pcache_page *pPage = 0;
|
||||
PgHdr *pPgHdr = 0;
|
||||
int eCreate;
|
||||
|
||||
assert( pCache!=0 );
|
||||
@@ -219,19 +231,19 @@ int sqlite3PcacheFetch(
|
||||
*/
|
||||
if( !pCache->pCache && createFlag ){
|
||||
sqlite3_pcache *p;
|
||||
int nByte;
|
||||
nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr);
|
||||
p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable);
|
||||
p = sqlite3GlobalConfig.pcache2.xCreate(
|
||||
pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
|
||||
);
|
||||
if( !p ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax);
|
||||
sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache));
|
||||
pCache->pCache = p;
|
||||
}
|
||||
|
||||
eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
|
||||
if( pCache->pCache ){
|
||||
pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate);
|
||||
pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
|
||||
}
|
||||
|
||||
if( !pPage && eCreate==1 ){
|
||||
@@ -258,7 +270,7 @@ int sqlite3PcacheFetch(
|
||||
"spill page %d making room for %d - cache used: %d/%d",
|
||||
pPg->pgno, pgno,
|
||||
sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
|
||||
pCache->nMax);
|
||||
numberOfCachePages(pCache));
|
||||
#endif
|
||||
rc = pCache->xStress(pCache->pStress, pPg);
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
|
||||
@@ -266,33 +278,36 @@ int sqlite3PcacheFetch(
|
||||
}
|
||||
}
|
||||
|
||||
pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2);
|
||||
pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
|
||||
}
|
||||
|
||||
if( pPage ){
|
||||
if( !pPage->pData ){
|
||||
memset(pPage, 0, sizeof(PgHdr));
|
||||
pPage->pData = (void *)&pPage[1];
|
||||
pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage];
|
||||
memset(pPage->pExtra, 0, pCache->szExtra);
|
||||
pPage->pCache = pCache;
|
||||
pPage->pgno = pgno;
|
||||
}
|
||||
assert( pPage->pCache==pCache );
|
||||
assert( pPage->pgno==pgno );
|
||||
assert( pPage->pData==(void *)&pPage[1] );
|
||||
assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] );
|
||||
pPgHdr = (PgHdr *)pPage->pExtra;
|
||||
|
||||
if( 0==pPage->nRef ){
|
||||
if( !pPgHdr->pPage ){
|
||||
memset(pPgHdr, 0, sizeof(PgHdr));
|
||||
pPgHdr->pPage = pPage;
|
||||
pPgHdr->pData = pPage->pBuf;
|
||||
pPgHdr->pExtra = (void *)&pPgHdr[1];
|
||||
memset(pPgHdr->pExtra, 0, pCache->szExtra);
|
||||
pPgHdr->pCache = pCache;
|
||||
pPgHdr->pgno = pgno;
|
||||
}
|
||||
assert( pPgHdr->pCache==pCache );
|
||||
assert( pPgHdr->pgno==pgno );
|
||||
assert( pPgHdr->pData==pPage->pBuf );
|
||||
assert( pPgHdr->pExtra==(void *)&pPgHdr[1] );
|
||||
|
||||
if( 0==pPgHdr->nRef ){
|
||||
pCache->nRef++;
|
||||
}
|
||||
pPage->nRef++;
|
||||
pPgHdr->nRef++;
|
||||
if( pgno==1 ){
|
||||
pCache->pPage1 = pPage;
|
||||
pCache->pPage1 = pPgHdr;
|
||||
}
|
||||
}
|
||||
*ppPage = pPage;
|
||||
return (pPage==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
|
||||
*ppPage = pPgHdr;
|
||||
return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -339,7 +354,7 @@ void sqlite3PcacheDrop(PgHdr *p){
|
||||
if( p->pgno==1 ){
|
||||
pCache->pPage1 = 0;
|
||||
}
|
||||
sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1);
|
||||
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -397,7 +412,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
|
||||
PCache *pCache = p->pCache;
|
||||
assert( p->nRef>0 );
|
||||
assert( newPgno>0 );
|
||||
sqlite3GlobalConfig.pcache.xRekey(pCache->pCache, p, p->pgno, newPgno);
|
||||
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
|
||||
p->pgno = newPgno;
|
||||
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
|
||||
pcacheRemoveFromDirtyList(p);
|
||||
@@ -434,7 +449,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
|
||||
memset(pCache->pPage1->pData, 0, pCache->szPage);
|
||||
pgno = 1;
|
||||
}
|
||||
sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1);
|
||||
sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,7 +458,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
|
||||
*/
|
||||
void sqlite3PcacheClose(PCache *pCache){
|
||||
if( pCache->pCache ){
|
||||
sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache);
|
||||
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,7 +570,7 @@ int sqlite3PcachePageRefcount(PgHdr *p){
|
||||
int sqlite3PcachePagecount(PCache *pCache){
|
||||
int nPage = 0;
|
||||
if( pCache->pCache ){
|
||||
nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache);
|
||||
nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
|
||||
}
|
||||
return nPage;
|
||||
}
|
||||
@@ -565,7 +580,7 @@ int sqlite3PcachePagecount(PCache *pCache){
|
||||
** Get the suggested cache-size value.
|
||||
*/
|
||||
int sqlite3PcacheGetCachesize(PCache *pCache){
|
||||
return pCache->nMax;
|
||||
return numberOfCachePages(pCache);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -573,9 +588,19 @@ int sqlite3PcacheGetCachesize(PCache *pCache){
|
||||
** Set the suggested cache-size value.
|
||||
*/
|
||||
void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
|
||||
pCache->nMax = mxPage;
|
||||
pCache->szCache = mxPage;
|
||||
if( pCache->pCache ){
|
||||
sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage);
|
||||
sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
|
||||
numberOfCachePages(pCache));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Free up as much memory as possible from the page cache.
|
||||
*/
|
||||
void sqlite3PcacheShrink(PCache *pCache){
|
||||
if( pCache->pCache ){
|
||||
sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -23,7 +23,8 @@ typedef struct PCache PCache;
|
||||
** structure.
|
||||
*/
|
||||
struct PgHdr {
|
||||
void *pData; /* Content of this page */
|
||||
sqlite3_pcache_page *pPage; /* Pcache object page handle */
|
||||
void *pData; /* Page data */
|
||||
void *pExtra; /* Extra content */
|
||||
PgHdr *pDirty; /* Transient list of dirty pages */
|
||||
Pgno pgno; /* Page number for this page */
|
||||
@@ -141,6 +142,9 @@ void sqlite3PcacheSetCachesize(PCache *, int);
|
||||
int sqlite3PcacheGetCachesize(PCache *);
|
||||
#endif
|
||||
|
||||
/* Free up as much memory as possible from the page cache */
|
||||
void sqlite3PcacheShrink(PCache*);
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
/* Try to return memory used by the pcache module to the main memory heap */
|
||||
int sqlite3PcacheReleaseMemory(int);
|
||||
|
||||
+92
-47
@@ -24,7 +24,6 @@ typedef struct PgHdr1 PgHdr1;
|
||||
typedef struct PgFreeslot PgFreeslot;
|
||||
typedef struct PGroup PGroup;
|
||||
|
||||
|
||||
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
|
||||
** of one or more PCaches that are able to recycle each others unpinned
|
||||
** pages when they are under memory pressure. A PGroup is an instance of
|
||||
@@ -72,6 +71,7 @@ struct PCache1 {
|
||||
*/
|
||||
PGroup *pGroup; /* PGroup this cache belongs to */
|
||||
int szPage; /* Size of allocated pages in bytes */
|
||||
int szExtra; /* Size of extra space in bytes */
|
||||
int bPurgeable; /* True if cache is purgeable */
|
||||
unsigned int nMin; /* Minimum number of pages reserved */
|
||||
unsigned int nMax; /* Configured "cache_size" value */
|
||||
@@ -90,11 +90,12 @@ struct PCache1 {
|
||||
|
||||
/*
|
||||
** Each cache entry is represented by an instance of the following
|
||||
** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated
|
||||
** directly before this structure in memory (see the PGHDR1_TO_PAGE()
|
||||
** macro below).
|
||||
** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
|
||||
** PgHdr1.pCache->szPage bytes is allocated directly before this structure
|
||||
** in memory.
|
||||
*/
|
||||
struct PgHdr1 {
|
||||
sqlite3_pcache_page page;
|
||||
unsigned int iKey; /* Key value (page number) */
|
||||
PgHdr1 *pNext; /* Next in hash table chain */
|
||||
PCache1 *pCache; /* Cache that currently owns this page */
|
||||
@@ -144,21 +145,6 @@ static SQLITE_WSD struct PCacheGlobal {
|
||||
*/
|
||||
#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
|
||||
|
||||
/*
|
||||
** When a PgHdr1 structure is allocated, the associated PCache1.szPage
|
||||
** bytes of data are located directly before it in memory (i.e. the total
|
||||
** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The
|
||||
** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as
|
||||
** an argument and returns a pointer to the associated block of szPage
|
||||
** bytes. The PAGE_TO_PGHDR1() macro does the opposite: its argument is
|
||||
** a pointer to a block of szPage bytes of data and the return value is
|
||||
** a pointer to the associated PgHdr1 structure.
|
||||
**
|
||||
** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
|
||||
*/
|
||||
#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
|
||||
#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
|
||||
|
||||
/*
|
||||
** Macros to enter and leave the PCache LRU mutex.
|
||||
*/
|
||||
@@ -241,8 +227,9 @@ static void *pcache1Alloc(int nByte){
|
||||
/*
|
||||
** Free an allocated buffer obtained from pcache1Alloc().
|
||||
*/
|
||||
static void pcache1Free(void *p){
|
||||
if( p==0 ) return;
|
||||
static int pcache1Free(void *p){
|
||||
int nFreed = 0;
|
||||
if( p==0 ) return 0;
|
||||
if( p>=pcache1.pStart && p<pcache1.pEnd ){
|
||||
PgFreeslot *pSlot;
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
@@ -255,15 +242,15 @@ static void pcache1Free(void *p){
|
||||
assert( pcache1.nFreeSlot<=pcache1.nSlot );
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
}else{
|
||||
int iSize;
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
iSize = sqlite3MallocSize(p);
|
||||
nFreed = sqlite3MallocSize(p);
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
return nFreed;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
@@ -288,7 +275,6 @@ static int pcache1MemSize(void *p){
|
||||
** Allocate a new page object initially associated with cache pCache.
|
||||
*/
|
||||
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||
int nByte = sizeof(PgHdr1) + pCache->szPage;
|
||||
PgHdr1 *p = 0;
|
||||
void *pPg;
|
||||
|
||||
@@ -297,16 +283,29 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||
** this mutex is not held. */
|
||||
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
||||
pcache1LeaveMutex(pCache->pGroup);
|
||||
pPg = pcache1Alloc(nByte);
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
pPg = pcache1Alloc(pCache->szPage);
|
||||
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
|
||||
if( !pPg || !p ){
|
||||
pcache1Free(pPg);
|
||||
sqlite3_free(p);
|
||||
pPg = 0;
|
||||
}
|
||||
#else
|
||||
pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
|
||||
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
|
||||
#endif
|
||||
pcache1EnterMutex(pCache->pGroup);
|
||||
|
||||
if( pPg ){
|
||||
p = PAGE_TO_PGHDR1(pCache, pPg);
|
||||
p->page.pBuf = pPg;
|
||||
p->page.pExtra = &p[1];
|
||||
if( pCache->bPurgeable ){
|
||||
pCache->pGroup->nCurrentPage++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -320,7 +319,10 @@ static void pcache1FreePage(PgHdr1 *p){
|
||||
if( ALWAYS(p) ){
|
||||
PCache1 *pCache = p->pCache;
|
||||
assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
|
||||
pcache1Free(PGHDR1_TO_PAGE(p));
|
||||
pcache1Free(p->page.pBuf);
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
sqlite3_free(p);
|
||||
#endif
|
||||
if( pCache->bPurgeable ){
|
||||
pCache->pGroup->nCurrentPage--;
|
||||
}
|
||||
@@ -361,7 +363,7 @@ void sqlite3PageFree(void *p){
|
||||
** the heap even further.
|
||||
*/
|
||||
static int pcache1UnderMemoryPressure(PCache1 *pCache){
|
||||
if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){
|
||||
if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
|
||||
return pcache1.bUnderPressure;
|
||||
}else{
|
||||
return sqlite3HeapNearlyFull();
|
||||
@@ -552,7 +554,7 @@ static void pcache1Shutdown(void *NotUsed){
|
||||
**
|
||||
** Allocate a new cache.
|
||||
*/
|
||||
static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
||||
static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
|
||||
PCache1 *pCache; /* The newly created page cache */
|
||||
PGroup *pGroup; /* The group the new page cache will belong to */
|
||||
int sz; /* Bytes of memory required to allocate the new cache */
|
||||
@@ -575,6 +577,9 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
||||
int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
|
||||
#endif
|
||||
|
||||
assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
|
||||
assert( szExtra < 300 );
|
||||
|
||||
sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
|
||||
pCache = (PCache1 *)sqlite3_malloc(sz);
|
||||
if( pCache ){
|
||||
@@ -587,6 +592,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
||||
}
|
||||
pCache->pGroup = pGroup;
|
||||
pCache->szPage = szPage;
|
||||
pCache->szExtra = szExtra;
|
||||
pCache->bPurgeable = (bPurgeable ? 1 : 0);
|
||||
if( bPurgeable ){
|
||||
pCache->nMin = 10;
|
||||
@@ -618,6 +624,25 @@ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the sqlite3_pcache.xShrink method.
|
||||
**
|
||||
** Free up as much memory as possible.
|
||||
*/
|
||||
static void pcache1Shrink(sqlite3_pcache *p){
|
||||
PCache1 *pCache = (PCache1*)p;
|
||||
if( pCache->bPurgeable ){
|
||||
PGroup *pGroup = pCache->pGroup;
|
||||
int savedMaxPage;
|
||||
pcache1EnterMutex(pGroup);
|
||||
savedMaxPage = pGroup->nMaxPage;
|
||||
pGroup->nMaxPage = 0;
|
||||
pcache1EnforceMaxPage(pGroup);
|
||||
pGroup->nMaxPage = savedMaxPage;
|
||||
pcache1LeaveMutex(pGroup);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the sqlite3_pcache.xPagecount method.
|
||||
*/
|
||||
@@ -684,7 +709,11 @@ static int pcache1Pagecount(sqlite3_pcache *p){
|
||||
**
|
||||
** 5. Otherwise, allocate and return a new page buffer.
|
||||
*/
|
||||
static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
||||
static sqlite3_pcache_page *pcache1Fetch(
|
||||
sqlite3_pcache *p,
|
||||
unsigned int iKey,
|
||||
int createFlag
|
||||
){
|
||||
int nPinned;
|
||||
PCache1 *pCache = (PCache1 *)p;
|
||||
PGroup *pGroup;
|
||||
@@ -719,7 +748,6 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
||||
pGroup = pCache->pGroup;
|
||||
#endif
|
||||
|
||||
|
||||
/* Step 3: Abort if createFlag is 1 but the cache is nearly full */
|
||||
nPinned = pCache->nPage - pCache->nRecyclable;
|
||||
assert( nPinned>=0 );
|
||||
@@ -743,16 +771,24 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
||||
|| pGroup->nCurrentPage>=pGroup->nMaxPage
|
||||
|| pcache1UnderMemoryPressure(pCache)
|
||||
)){
|
||||
PCache1 *pOtherCache;
|
||||
PCache1 *pOther;
|
||||
pPage = pGroup->pLruTail;
|
||||
pcache1RemoveFromHash(pPage);
|
||||
pcache1PinPage(pPage);
|
||||
if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){
|
||||
pOther = pPage->pCache;
|
||||
|
||||
/* We want to verify that szPage and szExtra are the same for pOther
|
||||
** and pCache. Assert that we can verify this by comparing sums. */
|
||||
assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
|
||||
assert( pCache->szExtra<512 );
|
||||
assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
|
||||
assert( pOther->szExtra<512 );
|
||||
|
||||
if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
|
||||
pcache1FreePage(pPage);
|
||||
pPage = 0;
|
||||
}else{
|
||||
pGroup->nCurrentPage -=
|
||||
(pOtherCache->bPurgeable - pCache->bPurgeable);
|
||||
pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -773,7 +809,7 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
||||
pPage->pCache = pCache;
|
||||
pPage->pLruPrev = 0;
|
||||
pPage->pLruNext = 0;
|
||||
*(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
|
||||
*(void **)pPage->page.pExtra = 0;
|
||||
pCache->apHash[h] = pPage;
|
||||
}
|
||||
|
||||
@@ -782,7 +818,7 @@ fetch_out:
|
||||
pCache->iMaxKey = iKey;
|
||||
}
|
||||
pcache1LeaveMutex(pGroup);
|
||||
return (pPage ? PGHDR1_TO_PAGE(pPage) : 0);
|
||||
return &pPage->page;
|
||||
}
|
||||
|
||||
|
||||
@@ -791,9 +827,13 @@ fetch_out:
|
||||
**
|
||||
** Mark a page as unpinned (eligible for asynchronous recycling).
|
||||
*/
|
||||
static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
|
||||
static void pcache1Unpin(
|
||||
sqlite3_pcache *p,
|
||||
sqlite3_pcache_page *pPg,
|
||||
int reuseUnlikely
|
||||
){
|
||||
PCache1 *pCache = (PCache1 *)p;
|
||||
PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
|
||||
PgHdr1 *pPage = (PgHdr1 *)pPg;
|
||||
PGroup *pGroup = pCache->pGroup;
|
||||
|
||||
assert( pPage->pCache==pCache );
|
||||
@@ -829,12 +869,12 @@ static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
|
||||
*/
|
||||
static void pcache1Rekey(
|
||||
sqlite3_pcache *p,
|
||||
void *pPg,
|
||||
sqlite3_pcache_page *pPg,
|
||||
unsigned int iOld,
|
||||
unsigned int iNew
|
||||
){
|
||||
PCache1 *pCache = (PCache1 *)p;
|
||||
PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
|
||||
PgHdr1 *pPage = (PgHdr1 *)pPg;
|
||||
PgHdr1 **pp;
|
||||
unsigned int h;
|
||||
assert( pPage->iKey==iOld );
|
||||
@@ -903,7 +943,8 @@ static void pcache1Destroy(sqlite3_pcache *p){
|
||||
** already provided an alternative.
|
||||
*/
|
||||
void sqlite3PCacheSetDefault(void){
|
||||
static const sqlite3_pcache_methods defaultMethods = {
|
||||
static const sqlite3_pcache_methods2 defaultMethods = {
|
||||
1, /* iVersion */
|
||||
0, /* pArg */
|
||||
pcache1Init, /* xInit */
|
||||
pcache1Shutdown, /* xShutdown */
|
||||
@@ -914,9 +955,10 @@ void sqlite3PCacheSetDefault(void){
|
||||
pcache1Unpin, /* xUnpin */
|
||||
pcache1Rekey, /* xRekey */
|
||||
pcache1Truncate, /* xTruncate */
|
||||
pcache1Destroy /* xDestroy */
|
||||
pcache1Destroy, /* xDestroy */
|
||||
pcache1Shrink /* xShrink */
|
||||
};
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultMethods);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
@@ -937,7 +979,10 @@ int sqlite3PcacheReleaseMemory(int nReq){
|
||||
PgHdr1 *p;
|
||||
pcache1EnterMutex(&pcache1.grp);
|
||||
while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
|
||||
nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));
|
||||
nFree += pcache1MemSize(p->page.pBuf);
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
nFree += sqlite3MemSize(p);
|
||||
#endif
|
||||
pcache1PinPage(p);
|
||||
pcache1RemoveFromHash(p);
|
||||
pcache1FreePage(p);
|
||||
|
||||
+26
-12
@@ -346,7 +346,7 @@ void sqlite3Pragma(
|
||||
goto pragma_out;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
/*
|
||||
** PRAGMA [database.]default_cache_size
|
||||
** PRAGMA [database.]default_cache_size=N
|
||||
@@ -395,7 +395,9 @@ void sqlite3Pragma(
|
||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
||||
}
|
||||
}else
|
||||
#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
|
||||
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
/*
|
||||
** PRAGMA [database.]page_size
|
||||
** PRAGMA [database.]page_size=N
|
||||
@@ -416,7 +418,7 @@ void sqlite3Pragma(
|
||||
** buffer that the pager module resizes using sqlite3_realloc().
|
||||
*/
|
||||
db->nextPagesize = sqlite3Atoi(zRight);
|
||||
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
|
||||
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
}
|
||||
@@ -456,6 +458,10 @@ void sqlite3Pragma(
|
||||
** second form attempts to change this setting. Both
|
||||
** forms return the current setting.
|
||||
**
|
||||
** The absolute value of N is used. This is undocumented and might
|
||||
** change. The only purpose is to provide an easy way to test
|
||||
** the sqlite3AbsInt32() function.
|
||||
**
|
||||
** PRAGMA [database.]page_count
|
||||
**
|
||||
** Return the number of pages in the specified database.
|
||||
@@ -470,7 +476,8 @@ void sqlite3Pragma(
|
||||
if( sqlite3Tolower(zLeft[0])=='p' ){
|
||||
sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
|
||||
sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg,
|
||||
sqlite3AbsInt32(sqlite3Atoi(zRight)));
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
@@ -684,14 +691,11 @@ void sqlite3Pragma(
|
||||
** PRAGMA [database.]cache_size=N
|
||||
**
|
||||
** The first form reports the current local setting for the
|
||||
** page cache size. The local setting can be different from
|
||||
** the persistent cache size value that is stored in the database
|
||||
** file itself. The value returned is the maximum number of
|
||||
** pages in the page cache. The second form sets the local
|
||||
** page cache size value. It does not change the persistent
|
||||
** cache size stored on the disk so the cache size will revert
|
||||
** to its default value when the database is closed and reopened.
|
||||
** N should be a positive integer.
|
||||
** page cache size. The second form sets the local
|
||||
** page cache size value. If N is positive then that is the
|
||||
** number of pages in the cache. If N is negative, then the
|
||||
** number of pages is adjusted so that the cache uses -N kibibytes
|
||||
** of memory.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
@@ -699,7 +703,7 @@ void sqlite3Pragma(
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
|
||||
}else{
|
||||
int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
|
||||
int size = sqlite3Atoi(zRight);
|
||||
pDb->pSchema->cache_size = size;
|
||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
||||
}
|
||||
@@ -1434,6 +1438,16 @@ void sqlite3Pragma(
|
||||
}else
|
||||
#endif
|
||||
|
||||
/*
|
||||
** PRAGMA shrink_memory
|
||||
**
|
||||
** This pragma attempts to free as much memory as possible from the
|
||||
** current database connection.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
|
||||
sqlite3_db_release_memory(db);
|
||||
}else
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
/*
|
||||
** Report the current state of file logs for all databases
|
||||
|
||||
@@ -278,9 +278,13 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
pDb->pSchema->enc = ENC(db);
|
||||
|
||||
if( pDb->pSchema->cache_size==0 ){
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]);
|
||||
if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
|
||||
pDb->pSchema->cache_size = size;
|
||||
#else
|
||||
pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE;
|
||||
#endif
|
||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -2220,7 +2220,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
{ "reserve", SQLITE_TESTCTRL_RESERVE },
|
||||
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
|
||||
{ "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
|
||||
{ "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ },
|
||||
{ "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
|
||||
};
|
||||
int testctrl = -1;
|
||||
@@ -2265,7 +2264,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
case SQLITE_TESTCTRL_PRNG_SAVE:
|
||||
case SQLITE_TESTCTRL_PRNG_RESTORE:
|
||||
case SQLITE_TESTCTRL_PRNG_RESET:
|
||||
case SQLITE_TESTCTRL_PGHDRSZ:
|
||||
if( nArg==2 ){
|
||||
rc = sqlite3_test_control(testctrl);
|
||||
printf("%d (0x%08x)\n", rc, rc);
|
||||
|
||||
+330
-32
@@ -572,6 +572,10 @@ int sqlite3_exec(
|
||||
** for their own use. The pMethods entry is a pointer to an
|
||||
** [sqlite3_io_methods] object that defines methods for performing
|
||||
** I/O operations on the open file.
|
||||
**
|
||||
** Do not confuse the low-level sqlite3_file object described here
|
||||
** and used by the [VFS] with the high-level [sqlite3_FILE object]
|
||||
** that provides a stdio-like interface for use by application programs.
|
||||
*/
|
||||
typedef struct sqlite3_file sqlite3_file;
|
||||
struct sqlite3_file {
|
||||
@@ -1368,7 +1372,7 @@ struct sqlite3_mem_methods {
|
||||
** <dd> ^This option specifies a static memory buffer that SQLite can use for
|
||||
** the database page cache with the default page cache implementation.
|
||||
** This configuration should not be used if an application-define page
|
||||
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
|
||||
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
|
||||
** There are three arguments to this option: A pointer to 8-byte aligned
|
||||
** memory, the size of each page buffer (sz), and the number of pages (N).
|
||||
** The sz argument should be the size of the largest database page
|
||||
@@ -1437,15 +1441,15 @@ struct sqlite3_mem_methods {
|
||||
** verb to [sqlite3_db_config()] can be used to change the lookaside
|
||||
** configuration on individual connections.)^ </dd>
|
||||
**
|
||||
** [[SQLITE_CONFIG_PCACHE]] <dt>SQLITE_CONFIG_PCACHE</dt>
|
||||
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
|
||||
** <dd> ^(This option takes a single argument which is a pointer to
|
||||
** an [sqlite3_pcache_methods] object. This object specifies the interface
|
||||
** an [sqlite3_pcache_methods2] object. This object specifies the interface
|
||||
** to a custom page cache implementation.)^ ^SQLite makes a copy of the
|
||||
** object and uses it for page cache memory allocations.</dd>
|
||||
**
|
||||
** [[SQLITE_CONFIG_GETPCACHE]] <dt>SQLITE_CONFIG_GETPCACHE</dt>
|
||||
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
|
||||
** <dd> ^(This option takes a single argument which is a pointer to an
|
||||
** [sqlite3_pcache_methods] object. SQLite copies of the current
|
||||
** [sqlite3_pcache_methods2] object. SQLite copies of the current
|
||||
** page cache implementation into that object.)^ </dd>
|
||||
**
|
||||
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
|
||||
@@ -1478,6 +1482,11 @@ struct sqlite3_mem_methods {
|
||||
** database connection is opened. By default, URI handling is globally
|
||||
** disabled. The default value may be changed by compiling with the
|
||||
** [SQLITE_USE_URI] symbol defined.
|
||||
**
|
||||
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
|
||||
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE
|
||||
** <dd> These options are obsolete and should not be used by new code.
|
||||
** They are retained for backwards compatibility but are now no-ops.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
||||
@@ -1493,10 +1502,12 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
|
||||
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
|
||||
#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
|
||||
#define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */
|
||||
#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */
|
||||
#define SQLITE_CONFIG_PCACHE 14 /* no-op */
|
||||
#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */
|
||||
#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
|
||||
#define SQLITE_CONFIG_URI 17 /* int */
|
||||
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Database Connection Configuration Options
|
||||
@@ -2925,6 +2936,25 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt);
|
||||
*/
|
||||
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
|
||||
**
|
||||
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
|
||||
** [prepared statement] S has been stepped at least once using
|
||||
** [sqlite3_step(S)] but has not run to completion and/or has not
|
||||
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
|
||||
** interface returns false if S is a NULL pointer. If S is not a
|
||||
** NULL pointer and is not a pointer to a valid [prepared statement]
|
||||
** object, then the behavior is undefined and probably undesirable.
|
||||
**
|
||||
** This interface can be used in combination [sqlite3_next_stmt()]
|
||||
** to locate all prepared statements associated with a database
|
||||
** connection that are in need of being reset. This can be used,
|
||||
** for example, in diagnostic routines to search for prepared
|
||||
** statements that are holding a transaction open.
|
||||
*/
|
||||
int sqlite3_stmt_busy(sqlite3_stmt*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Dynamically Typed Value Object
|
||||
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
|
||||
@@ -4366,6 +4396,22 @@ int sqlite3_get_autocommit(sqlite3*);
|
||||
*/
|
||||
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Return The Filename For A Database Connection
|
||||
**
|
||||
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
|
||||
** associated with database N of connection D. ^The main database file
|
||||
** has the name "main". If there is no attached database N on the database
|
||||
** connection D, or if database N is a temporary or in-memory database, then
|
||||
** a NULL pointer is returned.
|
||||
**
|
||||
** ^The filename returned by this function is the output of the
|
||||
** xFullPathname method of the [VFS]. ^In other words, the filename
|
||||
** will be an absolute pathname, even if the filename used
|
||||
** to open the database originally was a URI or relative pathname.
|
||||
*/
|
||||
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Find the next prepared statement
|
||||
**
|
||||
@@ -4522,9 +4568,24 @@ int sqlite3_enable_shared_cache(int);
|
||||
** which might be more or less than the amount requested.
|
||||
** ^The sqlite3_release_memory() routine is a no-op returning zero
|
||||
** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
|
||||
**
|
||||
** See also: [sqlite3_db_release_memory()]
|
||||
*/
|
||||
int sqlite3_release_memory(int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Free Memory Used By A Database Connection
|
||||
**
|
||||
** ^The sqlite3_db_shrink(D) interface attempts to free as much heap
|
||||
** memory as possible from database connection D. Unlike the
|
||||
** [sqlite3_release_memory()] interface, this interface is effect even
|
||||
** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
|
||||
** omitted.
|
||||
**
|
||||
** See also: [sqlite3_release_memory()]
|
||||
*/
|
||||
int sqlite3_db_release_memory(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Impose A Limit On Heap Size
|
||||
**
|
||||
@@ -4555,7 +4616,7 @@ int sqlite3_release_memory(int);
|
||||
** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
|
||||
** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
|
||||
** <li> An alternative page cache implementation is specified using
|
||||
** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
|
||||
** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
|
||||
** <li> The page cache allocates from its own memory pool supplied
|
||||
** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
|
||||
** from the heap.
|
||||
@@ -5623,10 +5684,9 @@ int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_RESERVE 14
|
||||
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
|
||||
#define SQLITE_TESTCTRL_ISKEYWORD 16
|
||||
#define SQLITE_TESTCTRL_PGHDRSZ 17
|
||||
#define SQLITE_TESTCTRL_SCRATCHMALLOC 18
|
||||
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19
|
||||
#define SQLITE_TESTCTRL_LAST 19
|
||||
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
|
||||
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
|
||||
#define SQLITE_TESTCTRL_LAST 18
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQLite Runtime Status
|
||||
@@ -5928,17 +5988,33 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
||||
** sqlite3_pcache object except by holding and passing pointers
|
||||
** to the object.
|
||||
**
|
||||
** See [sqlite3_pcache_methods] for additional information.
|
||||
** See [sqlite3_pcache_methods2] for additional information.
|
||||
*/
|
||||
typedef struct sqlite3_pcache sqlite3_pcache;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Custom Page Cache Object
|
||||
**
|
||||
** The sqlite3_pcache_page object represents a single page in the
|
||||
** page cache. The page cache will allocate instances of this
|
||||
** object. Various methods of the page cache use pointers to instances
|
||||
** of this object as parameters or as their return value.
|
||||
**
|
||||
** See [sqlite3_pcache_methods2] for additional information.
|
||||
*/
|
||||
typedef struct sqlite3_pcache_page sqlite3_pcache_page;
|
||||
struct sqlite3_pcache_page {
|
||||
void *pBuf; /* The content of the page */
|
||||
void *pExtra; /* Extra information associated with the page */
|
||||
};
|
||||
|
||||
/*
|
||||
** CAPI3REF: Application Defined Page Cache.
|
||||
** KEYWORDS: {page cache}
|
||||
**
|
||||
** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
|
||||
** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can
|
||||
** register an alternative page cache implementation by passing in an
|
||||
** instance of the sqlite3_pcache_methods structure.)^
|
||||
** instance of the sqlite3_pcache_methods2 structure.)^
|
||||
** In many applications, most of the heap memory allocated by
|
||||
** SQLite is used for the page cache.
|
||||
** By implementing a
|
||||
@@ -5952,7 +6028,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
||||
** extreme measure that is only needed by the most demanding applications.
|
||||
** The built-in page cache is recommended for most uses.
|
||||
**
|
||||
** ^(The contents of the sqlite3_pcache_methods structure are copied to an
|
||||
** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an
|
||||
** internal buffer by SQLite within the call to [sqlite3_config]. Hence
|
||||
** the application may discard the parameter after the call to
|
||||
** [sqlite3_config()] returns.)^
|
||||
@@ -5987,18 +6063,16 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
||||
** ^SQLite invokes the xCreate() method to construct a new cache instance.
|
||||
** SQLite will typically create one cache instance for each open database file,
|
||||
** though this is not guaranteed. ^The
|
||||
** first parameter, szPage, is the size in bytes of the pages that must
|
||||
** be allocated by the cache. ^szPage will not be a power of two. ^szPage
|
||||
** will the page size of the database file that is to be cached plus an
|
||||
** increment (here called "R") of less than 250. SQLite will use the
|
||||
** extra R bytes on each page to store metadata about the underlying
|
||||
** database page on disk. The value of R depends
|
||||
** parameter parameter, szPage, is the size in bytes of the pages that must
|
||||
** be allocated by the cache. ^szPage will always a power of two. ^The
|
||||
** second parameter szExtra is a number of bytes of extra storage
|
||||
** associated with each page cache entry. ^The szExtra parameter will
|
||||
** a number less than 250. SQLite will use the
|
||||
** extra szExtra bytes on each page to store metadata about the underlying
|
||||
** database page on disk. The value passed into szExtra depends
|
||||
** on the SQLite version, the target platform, and how SQLite was compiled.
|
||||
** ^(R is constant for a particular build of SQLite. Except, there are two
|
||||
** distinct values of R when SQLite is compiled with the proprietary
|
||||
** ZIPVFS extension.)^ ^The second argument to
|
||||
** xCreate(), bPurgeable, is true if the cache being created will
|
||||
** be used to cache database pages of a file stored on disk, or
|
||||
** ^The third argument to xCreate(), bPurgeable, is true if the cache being
|
||||
** created will be used to cache database pages of a file stored on disk, or
|
||||
** false if it is used for an in-memory database. The cache implementation
|
||||
** does not have to do anything special based with the value of bPurgeable;
|
||||
** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will
|
||||
@@ -6022,11 +6096,16 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
||||
**
|
||||
** [[the xFetch() page cache methods]]
|
||||
** The xFetch() method locates a page in the cache and returns a pointer to
|
||||
** the page, or a NULL pointer.
|
||||
** A "page", in this context, means a buffer of szPage bytes aligned at an
|
||||
** 8-byte boundary. The page to be fetched is determined by the key. ^The
|
||||
** minimum key value is 1. After it has been retrieved using xFetch, the page
|
||||
** is considered to be "pinned".
|
||||
** an sqlite3_pcache_page object associated with that page, or a NULL pointer.
|
||||
** The pBuf element of the returned sqlite3_pcache_page object will be a
|
||||
** pointer to a buffer of szPage bytes used to store the content of a
|
||||
** single database page. The pExtra element of sqlite3_pcache_page will be
|
||||
** a pointer to the szExtra bytes of extra storage that SQLite has requested
|
||||
** for each entry in the page cache.
|
||||
**
|
||||
** The page to be fetched is determined by the key. ^The minimum key value
|
||||
** is 1. After it has been retrieved using xFetch, the page is considered
|
||||
** to be "pinned".
|
||||
**
|
||||
** If the requested page is already in the page cache, then the page cache
|
||||
** implementation must return a pointer to the page buffer with its content
|
||||
@@ -6081,6 +6160,35 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
||||
** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
|
||||
** handle invalid, and will not use it with any other sqlite3_pcache_methods
|
||||
** functions.
|
||||
**
|
||||
** [[the xShrink() page cache method]]
|
||||
** ^SQLite invokes the xShrink() method when it wants the page cache to
|
||||
** free up as much of heap memory as possible. The page cache implementation
|
||||
** is not obligated to free any memory, but well-behaved implementions should
|
||||
** do their best.
|
||||
*/
|
||||
typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
|
||||
struct sqlite3_pcache_methods2 {
|
||||
int iVersion;
|
||||
void *pArg;
|
||||
int (*xInit)(void*);
|
||||
void (*xShutdown)(void*);
|
||||
sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
|
||||
void (*xCachesize)(sqlite3_pcache*, int nCachesize);
|
||||
int (*xPagecount)(sqlite3_pcache*);
|
||||
sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
|
||||
void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
|
||||
void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
|
||||
unsigned oldKey, unsigned newKey);
|
||||
void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
|
||||
void (*xDestroy)(sqlite3_pcache*);
|
||||
void (*xShrink)(sqlite3_pcache*);
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the obsolete pcache_methods object that has now been replaced
|
||||
** by sqlite3_pcache_methods2. This object is not used by SQLite. It is
|
||||
** retained in the header file for backwards compatibility only.
|
||||
*/
|
||||
typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
|
||||
struct sqlite3_pcache_methods {
|
||||
@@ -6097,6 +6205,7 @@ struct sqlite3_pcache_methods {
|
||||
void (*xDestroy)(sqlite3_pcache*);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** CAPI3REF: Online Backup Object
|
||||
**
|
||||
@@ -6718,7 +6827,196 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
/* #define SQLITE_ABORT 4 // Also an error code */
|
||||
#define SQLITE_REPLACE 5
|
||||
|
||||
/*
|
||||
** CAPI3REF: Simplified Interface To The VFS
|
||||
** KEYWORDS: *sqlite3_FILE {*sqlite3_FILE object}
|
||||
**
|
||||
** An instance of this object represents an open file in a [VFS].
|
||||
** This object is used by simplified I/O routines such as
|
||||
** [sqlite3_fopen()] and [sqlite3_fread()] and [sqlite3_fwrite()].
|
||||
**
|
||||
** The sqlite3_FILE object provides a simple means to access
|
||||
** the filesystem through an SQLite [VFS]. This allows, for example,
|
||||
** ordinary file I/O to occur through VFS shims such as the quota or
|
||||
** multiplexor or vfstrace, or for I/O to occur on specialized
|
||||
** application-specific VFSes. The sqlite3_FILE object also provides
|
||||
** a safe way for the application to read directly from an SQLite database
|
||||
** file, without the risk of cancelling posix advisory locks when the
|
||||
** connection is closed, as would happen using stdio or direct OS
|
||||
** I/O interfaces.
|
||||
**
|
||||
** The simplified I/O routines a similar to the "fopen()" family
|
||||
** of I/O routines in the standard C library, though there are some
|
||||
** minor differences. Note in particular that [sqlite3_fread()] and
|
||||
** [sqlite3_fwrite()] have 3 instead of 4 parameters and return a
|
||||
** success code rather than the number of elements read or written.
|
||||
** Also, standard C library numeric datatypes such as size_t and off_t are
|
||||
** replaced in this interface with the 64-bit signed integer type
|
||||
** [sqlite3_int64].
|
||||
**
|
||||
** The sqlite3_FILE object is not intended to be a general-purpose
|
||||
** replacement for stdio, but it can be very useful in some
|
||||
** circumstances.
|
||||
**
|
||||
** Do not confuse the high-level sqlite3_FILE object described here
|
||||
** with the low-level [sqlite3_file] object used by the [VFS].
|
||||
**
|
||||
** See also:
|
||||
** [sqlite3_fopen()],
|
||||
** [sqlite3_fread()],
|
||||
** [sqlite3_fwrite()],
|
||||
** [sqlite3_fseek()],
|
||||
** [sqlite3_ftell()],
|
||||
** [sqlite3_rewind()],
|
||||
** [sqlite3_fflush()],
|
||||
** [sqlite3_ftruncate()],
|
||||
** [sqlite3_close()],
|
||||
** [sqlite3_remove()].
|
||||
*/
|
||||
typedef struct sqlite3_FILE sqlite3_FILE;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Open A File Object
|
||||
**
|
||||
** The sqlite3_fopen(F,M) routine opens an [sqlite3_FILE object] on the
|
||||
** the file identified by [URI filename] F with mode M. Return a pointer
|
||||
** to the [sqlite3_FILE object] created, or a NULL pointer if the open failed.
|
||||
**
|
||||
** The mode M can be one of the following:
|
||||
**
|
||||
** <dl>
|
||||
** <dt><b>"r"</b>
|
||||
** <dd>Open the file read-only. Fail if the file does not already exist.
|
||||
** <dt><b>"r+"</b>
|
||||
** <dd>Open the file read and writing, but fail if the file does not
|
||||
** already exist.
|
||||
** <dt><b>"w"</b>
|
||||
** <dd>Open for reading and writing. Create the file if it does not
|
||||
** already exist. If the file does already exist, truncate it to zero
|
||||
** bytes in size immediately after opening.
|
||||
** <dt><b>"w+"</b>
|
||||
** <dd>This works the same as "w".
|
||||
** <dt><b>"a"</b>
|
||||
** <dd>Open for reading and writing. Create the file if it does not
|
||||
** already exist. Set the file cursor to the end of the file so that
|
||||
** any write operations that occur prior to an [sqlite3_fseek()] or
|
||||
** [sqlite3_rewind()] will append to the file.
|
||||
** <dt><b>"a+"</b>
|
||||
** <dd>Open for reading and writing. Create the file if it does not
|
||||
** already exist. The file cursor is positioned at the beginning of
|
||||
** the file for reading purposes. However, any writes on the file
|
||||
** cause the file cursor to move to the end of the file prior to the
|
||||
** write (and thus append to the file).
|
||||
** </dl>
|
||||
**
|
||||
** Any value for the mode M other than those listed above cause the
|
||||
** sqlite3_fopen() call to fail.
|
||||
**
|
||||
** See also:
|
||||
** [sqlite3_fread()],
|
||||
** [sqlite3_fwrite()],
|
||||
** [sqlite3_fseek()],
|
||||
** [sqlite3_ftell()],
|
||||
** [sqlite3_rewind()],
|
||||
** [sqlite3_fflush()],
|
||||
** [sqlite3_close()],
|
||||
** [sqlite3_remove()].
|
||||
*/
|
||||
sqlite3_FILE *sqlite3_fopen(const char *zURI, const char *zMode);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Read and Write A File Object
|
||||
**
|
||||
** The [sqlite3_fread(B,N,P)] routine reads N bytes of content from
|
||||
** [sqlite3_FILE object] P and into buffer B.
|
||||
** The [sqlite3_fwrite(B,N,P)] routine writes N bytes of content from
|
||||
** buffer B into [sqlite3_FILE object] P. Both routines return
|
||||
** SQLITE_OK on success or an [error code] on failure.
|
||||
**
|
||||
** Reading and writing always occur beginning at the file cursor. The file
|
||||
** cursor is advanced by N if the read or write is successful and unchanged
|
||||
** if the read is not successful. Not that the file cursor is
|
||||
** unchanged by a partial read ([SQLITE_IOERR_SHORT_READ]).
|
||||
** If the mode from [sqlite3_fopen()] was "a+" then the file cursor is
|
||||
** always moved to the end of the file prior to every write.
|
||||
**
|
||||
** Note that these routines differ from stdio fread() and fwrite()
|
||||
** functions in two significant ways: These routines use 3 parameters
|
||||
** instead of 4; these routines always assume an element size of one byte.
|
||||
** And these routines return a success code, not the number of elements
|
||||
** read or written. With the routines described here, and unlike
|
||||
** fread() and fwrite(), a partial read or write is considered an error.
|
||||
*/
|
||||
int sqlite3_fread(void*, sqlite3_int64, sqlite3_FILE*);
|
||||
int sqlite3_fwrite(const void*, sqlite3_int64, sqlite3_FILE*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Whence Parameter For sqlite3_fseek()
|
||||
**
|
||||
** The 3rd parameter to [sqlite3_fseek(P,N,W)] can take on any of the
|
||||
** following values.
|
||||
*/
|
||||
#define SQLITE_SEEK_SET 0
|
||||
#define SQLITE_SEEK_CUR 1
|
||||
#define SQLITE_SEEK_END 2
|
||||
|
||||
/*
|
||||
** CAPI3REF: Position The Cursor For An sqlite3_FILE object
|
||||
**
|
||||
** This routines move the current cursor position in an [sqlite3_FILE object].
|
||||
** The sqlite3_fseek(P,N,W) call move the [sqlite3_FILE object] P to a new
|
||||
** position N relative to W. W is [SQLITE_SEEK_SET] for the beginning of
|
||||
** the file, [SQLITE_SEEK_CUR] for the cursor position prior to the current
|
||||
** move, or [SQLITE_SEEK_END] for the end of the file.
|
||||
**
|
||||
** The sqlite3_rewind(P) call move the cursor position to the beginning
|
||||
** of the file. It is equivalent to sqlite3_fseek(P,0,SQLITE_SEEK_SET).
|
||||
**
|
||||
** The sqlite3_ftell(P) call returns the current cursor position.
|
||||
*/
|
||||
int sqlite3_fseek(sqlite3_FILE*, sqlite3_int64, int whence);
|
||||
int sqlite3_rewind(sqlite3_FILE*);
|
||||
sqlite3_int64 sqlite3_ftell(sqlite3_FILE*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flush OS File Cache Buffers
|
||||
**
|
||||
** A call to sqlite3_fflush(P) causes any writes previously made against
|
||||
** [sqlite3_FILE object] P to be flushed from the operating-system cache
|
||||
** to nonvolatile storage.
|
||||
*/
|
||||
int sqlite3_fflush(sqlite3_FILE*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Truncate An sqlite3_FILE object
|
||||
**
|
||||
** The sqlite3_ftruncate(P,N) interface calls the [sqlite3_FILE object] P
|
||||
** to be truncated to N bytes in size.
|
||||
**
|
||||
** It is undefined what happens if N is larger than the current file size.
|
||||
** Some [VFS] implementations will extend the file. Others will fail.
|
||||
** Still others will leave the file in an inconsistent state.
|
||||
*/
|
||||
int sqlite3_ftruncate(sqlite3_FILE*, sqlite3_int64);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Close an sqlite3_FILE object
|
||||
**
|
||||
** Every successful call to [sqlite3_fopen()] should be eventually followed
|
||||
** by a call to this routine to destroy the [sqlite3_FILE object] that
|
||||
** [sqlite3_fopen()] created. After calling this routine, the
|
||||
** [sqlite3_FILE object] must not be used again.
|
||||
*/
|
||||
int sqlite3_fclose(sqlite3_FILE*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Remove A File
|
||||
**
|
||||
** The sqlite3_remove(U) interface attempts to delete the file identified
|
||||
** by the [URI filename] U. Query parameters on U can specify a particular
|
||||
** [VFS] to use to do the deletion.
|
||||
*/
|
||||
int sqlite3_remove(const char *zURI);
|
||||
|
||||
/*
|
||||
** Undo the hack that converts floating point types to integer for
|
||||
|
||||
+14
-28
@@ -1144,20 +1144,11 @@ struct Column {
|
||||
struct CollSeq {
|
||||
char *zName; /* Name of the collating sequence, UTF-8 encoded */
|
||||
u8 enc; /* Text encoding handled by xCmp() */
|
||||
u8 type; /* One of the SQLITE_COLL_... values below */
|
||||
void *pUser; /* First argument to xCmp() */
|
||||
int (*xCmp)(void*,int, const void*, int, const void*);
|
||||
void (*xDel)(void*); /* Destructor for pUser */
|
||||
};
|
||||
|
||||
/*
|
||||
** Allowed values of CollSeq.type:
|
||||
*/
|
||||
#define SQLITE_COLL_BINARY 1 /* The default memcmp() collating sequence */
|
||||
#define SQLITE_COLL_NOCASE 2 /* The built-in NOCASE collating sequence */
|
||||
#define SQLITE_COLL_REVERSE 3 /* The built-in REVERSE collating sequence */
|
||||
#define SQLITE_COLL_USER 0 /* Any other user-defined collating sequence */
|
||||
|
||||
/*
|
||||
** A sort order can be either ASC or DESC.
|
||||
*/
|
||||
@@ -1443,7 +1434,7 @@ struct KeyInfo {
|
||||
struct UnpackedRecord {
|
||||
KeyInfo *pKeyInfo; /* Collation and sort-order information */
|
||||
u16 nField; /* Number of entries in apMem[] */
|
||||
u16 flags; /* Boolean settings. UNPACKED_... below */
|
||||
u8 flags; /* Boolean settings. UNPACKED_... below */
|
||||
i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */
|
||||
Mem *aMem; /* Values */
|
||||
};
|
||||
@@ -1451,11 +1442,9 @@ struct UnpackedRecord {
|
||||
/*
|
||||
** Allowed values of UnpackedRecord.flags
|
||||
*/
|
||||
#define UNPACKED_NEED_FREE 0x0001 /* Memory is from sqlite3Malloc() */
|
||||
#define UNPACKED_NEED_DESTROY 0x0002 /* apMem[]s should all be destroyed */
|
||||
#define UNPACKED_INCRKEY 0x0008 /* Make this key an epsilon larger */
|
||||
#define UNPACKED_PREFIX_MATCH 0x0010 /* A prefix match is considered OK */
|
||||
#define UNPACKED_PREFIX_SEARCH 0x0020 /* A prefix match is considered OK */
|
||||
#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
|
||||
#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
|
||||
#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */
|
||||
|
||||
/*
|
||||
** Each SQL index is represented in memory by an
|
||||
@@ -2083,13 +2072,13 @@ struct Select {
|
||||
** Allowed values for Select.selFlags. The "SF" prefix stands for
|
||||
** "Select Flag".
|
||||
*/
|
||||
#define SF_Distinct 0x0001 /* Output should be DISTINCT */
|
||||
#define SF_Resolved 0x0002 /* Identifiers have been resolved */
|
||||
#define SF_Aggregate 0x0004 /* Contains aggregate functions */
|
||||
#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
|
||||
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
|
||||
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
|
||||
#define SF_UseSorter 0x0040 /* Sort using a sorter */
|
||||
#define SF_Distinct 0x01 /* Output should be DISTINCT */
|
||||
#define SF_Resolved 0x02 /* Identifiers have been resolved */
|
||||
#define SF_Aggregate 0x04 /* Contains aggregate functions */
|
||||
#define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */
|
||||
#define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */
|
||||
#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */
|
||||
#define SF_UseSorter 0x40 /* Sort using a sorter */
|
||||
|
||||
|
||||
/*
|
||||
@@ -2204,10 +2193,8 @@ struct Parse {
|
||||
char *zErrMsg; /* An error message */
|
||||
Vdbe *pVdbe; /* An engine for executing database bytecode */
|
||||
u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */
|
||||
u8 nameClash; /* A permanent table name clashes with temp table name */
|
||||
u8 checkSchema; /* Causes schema cookie check after an error */
|
||||
u8 nested; /* Number of nested calls to the parser/code generator */
|
||||
u8 parseError; /* True after a parsing error. Ticket #1794 */
|
||||
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
|
||||
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
|
||||
int aTempReg[8]; /* Holding area for temporary registers */
|
||||
@@ -2220,8 +2207,8 @@ struct Parse {
|
||||
int ckBase; /* Base register of data during check constraints */
|
||||
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
|
||||
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
|
||||
u8 nColCache; /* Number of entries in the column cache */
|
||||
u8 iColCache; /* Next entry of the cache to replace */
|
||||
u8 nColCache; /* Number of entries in aColCache[] */
|
||||
u8 iColCache; /* Next entry in aColCache[] to replace */
|
||||
struct yColCache {
|
||||
int iTable; /* Table cursor number */
|
||||
int iColumn; /* Table column number */
|
||||
@@ -2263,7 +2250,6 @@ struct Parse {
|
||||
char **azVar; /* Pointers to names of parameters */
|
||||
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
|
||||
int nAlias; /* Number of aliased result set columns */
|
||||
int nAliasAlloc; /* Number of allocated slots for aAlias[] */
|
||||
int *aAlias; /* Register used to hold aliased result */
|
||||
u8 explain; /* True if the EXPLAIN flag is found on the query */
|
||||
Token sNameToken; /* Token with unqualified schema object name */
|
||||
@@ -2458,7 +2444,7 @@ struct Sqlite3Config {
|
||||
int nLookaside; /* Default lookaside buffer count */
|
||||
sqlite3_mem_methods m; /* Low-level memory allocation interface */
|
||||
sqlite3_mutex_methods mutex; /* Low-level mutex interface */
|
||||
sqlite3_pcache_methods pcache; /* Low-level page-cache interface */
|
||||
sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */
|
||||
void *pHeap; /* Heap storage space */
|
||||
int nHeap; /* Size of pHeap[] */
|
||||
int mnReq, mxReq; /* Min and max heap requests sizes */
|
||||
|
||||
+78
@@ -2330,6 +2330,33 @@ static int test_stmt_readonly(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_stmt_busy STMT
|
||||
**
|
||||
** Return true if STMT is a non-NULL pointer to a statement
|
||||
** that has been stepped but not to completion.
|
||||
*/
|
||||
static int test_stmt_busy(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
rc = sqlite3_stmt_busy(pStmt);
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: uses_stmt_journal STMT
|
||||
**
|
||||
@@ -4593,6 +4620,54 @@ static int test_release_memory(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_db_release_memory DB
|
||||
**
|
||||
** Attempt to release memory currently held by database DB. Return the
|
||||
** result code (which in the current implementation is always zero).
|
||||
*/
|
||||
static int test_db_release_memory(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
rc = sqlite3_db_release_memory(db);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_db_filename DB DBNAME
|
||||
**
|
||||
** Return the name of a file associated with a database.
|
||||
*/
|
||||
static int test_db_filename(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zDbName;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zDbName = Tcl_GetString(objv[2]);
|
||||
Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_soft_heap_limit ?N?
|
||||
**
|
||||
@@ -5912,9 +5987,12 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_sql", test_sql ,0 },
|
||||
{ "sqlite3_next_stmt", test_next_stmt ,0 },
|
||||
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 },
|
||||
{ "sqlite3_stmt_busy", test_stmt_busy ,0 },
|
||||
{ "uses_stmt_journal", uses_stmt_journal ,0 },
|
||||
|
||||
{ "sqlite3_release_memory", test_release_memory, 0},
|
||||
{ "sqlite3_db_release_memory", test_db_release_memory, 0},
|
||||
{ "sqlite3_db_filename", test_db_filename, 0},
|
||||
{ "sqlite3_soft_heap_limit", test_soft_heap_limit, 0},
|
||||
{ "sqlite3_thread_cleanup", test_thread_cleanup, 0},
|
||||
{ "sqlite3_pager_refcounts", test_pager_refcounts, 0},
|
||||
|
||||
@@ -37,6 +37,14 @@
|
||||
** procedures use this to determine when tests should be omitted.
|
||||
*/
|
||||
static void set_options(Tcl_Interp *interp){
|
||||
#ifdef HAVE_MALLOC_USABLE_SIZE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "1",
|
||||
TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "0",
|
||||
TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_32BIT_ROWID
|
||||
Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
||||
+18
-13
@@ -30,9 +30,9 @@
|
||||
#include <tcl.h>
|
||||
|
||||
static struct Wrapped {
|
||||
sqlite3_pcache_methods pcache;
|
||||
sqlite3_mem_methods mem;
|
||||
sqlite3_mutex_methods mutex;
|
||||
sqlite3_pcache_methods2 pcache;
|
||||
sqlite3_mem_methods mem;
|
||||
sqlite3_mutex_methods mutex;
|
||||
|
||||
int mem_init; /* True if mem subsystem is initalized */
|
||||
int mem_fail; /* True to fail mem subsystem inialization */
|
||||
@@ -123,8 +123,8 @@ static void wrPCacheShutdown(void *pArg){
|
||||
wrapped.pcache_init = 0;
|
||||
}
|
||||
|
||||
static sqlite3_pcache *wrPCacheCreate(int a, int b){
|
||||
return wrapped.pcache.xCreate(a, b);
|
||||
static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
|
||||
return wrapped.pcache.xCreate(a, b, c);
|
||||
}
|
||||
static void wrPCacheCachesize(sqlite3_pcache *p, int n){
|
||||
wrapped.pcache.xCachesize(p, n);
|
||||
@@ -132,13 +132,18 @@ static void wrPCacheCachesize(sqlite3_pcache *p, int n){
|
||||
static int wrPCachePagecount(sqlite3_pcache *p){
|
||||
return wrapped.pcache.xPagecount(p);
|
||||
}
|
||||
static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
|
||||
static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
|
||||
return wrapped.pcache.xFetch(p, a, b);
|
||||
}
|
||||
static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){
|
||||
static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
|
||||
wrapped.pcache.xUnpin(p, a, b);
|
||||
}
|
||||
static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){
|
||||
static void wrPCacheRekey(
|
||||
sqlite3_pcache *p,
|
||||
sqlite3_pcache_page *a,
|
||||
unsigned b,
|
||||
unsigned c
|
||||
){
|
||||
wrapped.pcache.xRekey(p, a, b, c);
|
||||
}
|
||||
static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
|
||||
@@ -154,8 +159,8 @@ static void installInitWrappers(void){
|
||||
wrMutexFree, wrMutexEnter, wrMutexTry,
|
||||
wrMutexLeave, wrMutexHeld, wrMutexNotheld
|
||||
};
|
||||
sqlite3_pcache_methods pcachemethods = {
|
||||
0,
|
||||
sqlite3_pcache_methods2 pcachemethods = {
|
||||
1, 0,
|
||||
wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
|
||||
wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
|
||||
wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate,
|
||||
@@ -173,10 +178,10 @@ static void installInitWrappers(void){
|
||||
sqlite3_shutdown();
|
||||
sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
|
||||
sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache);
|
||||
sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
|
||||
sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
|
||||
}
|
||||
|
||||
static int init_wrapper_install(
|
||||
@@ -218,7 +223,7 @@ static int init_wrapper_uninstall(
|
||||
sqlite3_shutdown();
|
||||
sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,12 +96,14 @@
|
||||
# define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112
|
||||
#endif
|
||||
|
||||
/* Default limit on number of chunks.
|
||||
** May be changed by calling
|
||||
** the xFileControl() interface.
|
||||
/* This used to be the default limit on number of chunks, but
|
||||
** it is no longer enforced. There is currently no limit to the
|
||||
** number of chunks.
|
||||
**
|
||||
** May be changed by calling the xFileControl() interface.
|
||||
*/
|
||||
#ifndef SQLITE_MULTIPLEX_MAX_CHUNKS
|
||||
# define SQLITE_MULTIPLEX_MAX_CHUNKS 32
|
||||
# define SQLITE_MULTIPLEX_MAX_CHUNKS 12
|
||||
#endif
|
||||
|
||||
/************************ Object Definitions ******************************/
|
||||
|
||||
+30
-20
@@ -100,15 +100,16 @@ static void testpcacheShutdown(void *pArg){
|
||||
typedef struct testpcache testpcache;
|
||||
struct testpcache {
|
||||
int szPage; /* Size of each page. Multiple of 8. */
|
||||
int szExtra; /* Size of extra data that accompanies each page */
|
||||
int bPurgeable; /* True if the page cache is purgeable */
|
||||
int nFree; /* Number of unused slots in a[] */
|
||||
int nPinned; /* Number of pinned slots in a[] */
|
||||
unsigned iRand; /* State of the PRNG */
|
||||
unsigned iMagic; /* Magic number for sanity checking */
|
||||
struct testpcachePage {
|
||||
sqlite3_pcache_page page; /* Base class */
|
||||
unsigned key; /* The key for this page. 0 means unallocated */
|
||||
int isPinned; /* True if the page is pinned */
|
||||
void *pData; /* Data for this page */
|
||||
} a[TESTPCACHE_NPAGE]; /* All pages in the cache */
|
||||
};
|
||||
|
||||
@@ -129,27 +130,33 @@ static unsigned testpcacheRandom(testpcache *p){
|
||||
/*
|
||||
** Allocate a new page cache instance.
|
||||
*/
|
||||
static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){
|
||||
static sqlite3_pcache *testpcacheCreate(
|
||||
int szPage,
|
||||
int szExtra,
|
||||
int bPurgeable
|
||||
){
|
||||
int nMem;
|
||||
char *x;
|
||||
testpcache *p;
|
||||
int i;
|
||||
assert( testpcacheGlobal.pDummy!=0 );
|
||||
szPage = (szPage+7)&~7;
|
||||
nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*szPage;
|
||||
nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra);
|
||||
p = sqlite3_malloc( nMem );
|
||||
if( p==0 ) return 0;
|
||||
x = (char*)&p[1];
|
||||
p->szPage = szPage;
|
||||
p->szExtra = szExtra;
|
||||
p->nFree = TESTPCACHE_NPAGE;
|
||||
p->nPinned = 0;
|
||||
p->iRand = testpcacheGlobal.prngSeed;
|
||||
p->bPurgeable = bPurgeable;
|
||||
p->iMagic = TESTPCACHE_VALID;
|
||||
for(i=0; i<TESTPCACHE_NPAGE; i++, x += szPage){
|
||||
for(i=0; i<TESTPCACHE_NPAGE; i++, x += (szPage+szExtra)){
|
||||
p->a[i].key = 0;
|
||||
p->a[i].isPinned = 0;
|
||||
p->a[i].pData = (void*)x;
|
||||
p->a[i].page.pBuf = (void*)x;
|
||||
p->a[i].page.pExtra = (void*)&x[szPage];
|
||||
}
|
||||
testpcacheGlobal.nInstance++;
|
||||
return (sqlite3_pcache*)p;
|
||||
@@ -180,7 +187,7 @@ static int testpcachePagecount(sqlite3_pcache *pCache){
|
||||
/*
|
||||
** Fetch a page.
|
||||
*/
|
||||
static void *testpcacheFetch(
|
||||
static sqlite3_pcache_page *testpcacheFetch(
|
||||
sqlite3_pcache *pCache,
|
||||
unsigned key,
|
||||
int createFlag
|
||||
@@ -199,7 +206,7 @@ static void *testpcacheFetch(
|
||||
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
||||
p->a[i].isPinned = 1;
|
||||
}
|
||||
return p->a[i].pData;
|
||||
return &p->a[i].page;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,11 +243,12 @@ static void *testpcacheFetch(
|
||||
if( p->a[j].key==0 ){
|
||||
p->a[j].key = key;
|
||||
p->a[j].isPinned = 1;
|
||||
memset(p->a[j].pData, 0, p->szPage);
|
||||
memset(p->a[j].page.pBuf, 0, p->szPage);
|
||||
memset(p->a[j].page.pExtra, 0, p->szExtra);
|
||||
p->nPinned++;
|
||||
p->nFree--;
|
||||
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
||||
return p->a[j].pData;
|
||||
return &p->a[j].page;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +270,11 @@ static void *testpcacheFetch(
|
||||
if( p->a[j].key>0 && p->a[j].isPinned==0 ){
|
||||
p->a[j].key = key;
|
||||
p->a[j].isPinned = 1;
|
||||
memset(p->a[j].pData, 0, p->szPage);
|
||||
memset(p->a[j].page.pBuf, 0, p->szPage);
|
||||
memset(p->a[j].page.pExtra, 0, p->szExtra);
|
||||
p->nPinned++;
|
||||
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
||||
return p->a[j].pData;
|
||||
return &p->a[j].page;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +288,7 @@ static void *testpcacheFetch(
|
||||
*/
|
||||
static void testpcacheUnpin(
|
||||
sqlite3_pcache *pCache,
|
||||
void *pOldPage,
|
||||
sqlite3_pcache_page *pOldPage,
|
||||
int discard
|
||||
){
|
||||
testpcache *p = (testpcache*)pCache;
|
||||
@@ -299,7 +308,7 @@ static void testpcacheUnpin(
|
||||
}
|
||||
|
||||
for(i=0; i<TESTPCACHE_NPAGE; i++){
|
||||
if( p->a[i].pData==pOldPage ){
|
||||
if( &p->a[i].page==pOldPage ){
|
||||
/* The pOldPage pointer always points to a pinned page */
|
||||
assert( p->a[i].isPinned );
|
||||
p->a[i].isPinned = 0;
|
||||
@@ -324,7 +333,7 @@ static void testpcacheUnpin(
|
||||
*/
|
||||
static void testpcacheRekey(
|
||||
sqlite3_pcache *pCache,
|
||||
void *pOldPage,
|
||||
sqlite3_pcache_page *pOldPage,
|
||||
unsigned oldKey,
|
||||
unsigned newKey
|
||||
){
|
||||
@@ -353,7 +362,7 @@ static void testpcacheRekey(
|
||||
for(i=0; i<TESTPCACHE_NPAGE; i++){
|
||||
if( p->a[i].key==oldKey ){
|
||||
/* The oldKey and pOldPage parameters match */
|
||||
assert( p->a[i].pData==pOldPage );
|
||||
assert( &p->a[i].page==pOldPage );
|
||||
/* Page to be rekeyed must be pinned */
|
||||
assert( p->a[i].isPinned );
|
||||
p->a[i].key = newKey;
|
||||
@@ -421,7 +430,8 @@ void installTestPCache(
|
||||
unsigned prngSeed, /* Seed for the PRNG */
|
||||
unsigned highStress /* Call xStress agressively */
|
||||
){
|
||||
static const sqlite3_pcache_methods testPcache = {
|
||||
static const sqlite3_pcache_methods2 testPcache = {
|
||||
1,
|
||||
(void*)&testpcacheGlobal,
|
||||
testpcacheInit,
|
||||
testpcacheShutdown,
|
||||
@@ -434,7 +444,7 @@ void installTestPCache(
|
||||
testpcacheTruncate,
|
||||
testpcacheDestroy,
|
||||
};
|
||||
static sqlite3_pcache_methods defaultPcache;
|
||||
static sqlite3_pcache_methods2 defaultPcache;
|
||||
static int isInstalled = 0;
|
||||
|
||||
assert( testpcacheGlobal.nInstance==0 );
|
||||
@@ -445,12 +455,12 @@ void installTestPCache(
|
||||
testpcacheGlobal.highStress = highStress;
|
||||
if( installFlag!=isInstalled ){
|
||||
if( installFlag ){
|
||||
sqlite3_config(SQLITE_CONFIG_GETPCACHE, &defaultPcache);
|
||||
sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache);
|
||||
assert( defaultPcache.xCreate!=testpcacheCreate );
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &testPcache);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache);
|
||||
}else{
|
||||
assert( defaultPcache.xCreate!=0 );
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultPcache);
|
||||
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache);
|
||||
}
|
||||
isInstalled = installFlag;
|
||||
}
|
||||
|
||||
@@ -1277,6 +1277,14 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
|
||||
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the prepared statement is in need of being reset.
|
||||
*/
|
||||
int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the next prepared statement after pStmt associated
|
||||
** with database connection pDb. If pStmt is NULL, return the first
|
||||
|
||||
@@ -51,6 +51,25 @@ do_test attach-1.3 {
|
||||
SELECT * FROM two.t2;
|
||||
}
|
||||
} {1 x 2 y}
|
||||
|
||||
# Tests for the sqlite3_db_filename interface
|
||||
#
|
||||
do_test attach-1.3.1 {
|
||||
file tail [sqlite3_db_filename db main]
|
||||
} {test.db}
|
||||
do_test attach-1.3.2 {
|
||||
file tail [sqlite3_db_filename db MAIN]
|
||||
} {test.db}
|
||||
do_test attach-1.3.3 {
|
||||
file tail [sqlite3_db_filename db temp]
|
||||
} {}
|
||||
do_test attach-1.3.4 {
|
||||
file tail [sqlite3_db_filename db two]
|
||||
} {test2.db}
|
||||
do_test attach-1.3.5 {
|
||||
file tail [sqlite3_db_filename db three]
|
||||
} {}
|
||||
|
||||
do_test attach-1.4 {
|
||||
execsql {
|
||||
SELECT * FROM t2;
|
||||
|
||||
+25
-1
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# This file is devoted to testing the sqlite3_next_stmt and
|
||||
# sqlite3_stmt_readonly interfaces.
|
||||
# sqlite3_stmt_readonly and sqlite3_stmt_busy interfaces.
|
||||
#
|
||||
# $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $
|
||||
#
|
||||
@@ -112,5 +112,29 @@ do_test capi3-2.99 {
|
||||
sqlite3_stmt_readonly 0
|
||||
} 1
|
||||
|
||||
# Tests for sqlite3_stmt_busy
|
||||
#
|
||||
do_test capi3d-3.1 {
|
||||
db eval {INSERT INTO t1 VALUES(6); INSERT INTO t1 VALUES(7);}
|
||||
set STMT [sqlite3_prepare db {SELECT * FROM t1} -1 TAIL]
|
||||
sqlite3_stmt_busy $STMT
|
||||
} {0}
|
||||
do_test capi3d-3.2 {
|
||||
sqlite3_step $STMT
|
||||
sqlite3_stmt_busy $STMT
|
||||
} {1}
|
||||
do_test capi3d-3.3 {
|
||||
sqlite3_step $STMT
|
||||
sqlite3_stmt_busy $STMT
|
||||
} {1}
|
||||
do_test capi3d-3.4 {
|
||||
sqlite3_reset $STMT
|
||||
sqlite3_stmt_busy $STMT
|
||||
} {0}
|
||||
|
||||
do_test capi3d-3.99 {
|
||||
sqlite3_finalize $STMT
|
||||
sqlite3_stmt_busy 0
|
||||
} {0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -62,6 +62,11 @@ ifcapable stat3 {
|
||||
set STAT3 0
|
||||
}
|
||||
|
||||
ifcapable malloc_usable_size {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the dbstatus-2 and dbstatus-3 tests with several of different
|
||||
# lookaside buffer sizes.
|
||||
|
||||
@@ -68,7 +68,7 @@ proc reset_highwater_marks {} {
|
||||
sqlite3_status SQLITE_STATUS_PARSER_STACK 1
|
||||
}
|
||||
|
||||
set xtra_size 272
|
||||
set xtra_size 290
|
||||
|
||||
# Test 1: Both PAGECACHE and SCRATCH are shut down.
|
||||
#
|
||||
@@ -97,9 +97,11 @@ reset_highwater_marks
|
||||
build_test_db memsubsys1-2 {PRAGMA page_size=1024}
|
||||
#show_memstats
|
||||
set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
|
||||
do_test memsubsys1-2.3 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
|
||||
ifcapable !malloc_usable_size {
|
||||
do_test memsubsys1-2.3 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
|
||||
}
|
||||
do_test memsubsys1-2.4 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
} 20
|
||||
|
||||
+2
-2
@@ -99,7 +99,7 @@ do_test pragma-1.5 {
|
||||
PRAGMA default_cache_size;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} [list 4321 $DFLT_CACHE_SZ 0]
|
||||
} [list -4321 $DFLT_CACHE_SZ 0]
|
||||
do_test pragma-1.6 {
|
||||
execsql {
|
||||
PRAGMA synchronous=ON;
|
||||
@@ -107,7 +107,7 @@ do_test pragma-1.6 {
|
||||
PRAGMA default_cache_size;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} [list 4321 $DFLT_CACHE_SZ 1]
|
||||
} [list -4321 $DFLT_CACHE_SZ 1]
|
||||
do_test pragma-1.7 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# 2011 November 16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file contains test cases for sqlite3_db_release_memory and
|
||||
# the PRAGMA shrink_memory statement.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
unset -nocomplain baseline
|
||||
do_test shrink-1.1 {
|
||||
db eval {
|
||||
CREATE TABLE t1(x,y);
|
||||
INSERT INTO t1 VALUES(randomblob(1000000),1);
|
||||
}
|
||||
set ::baseline sqlite3_memory_used
|
||||
sqlite3_db_release_memory db
|
||||
expr {$::baseline > [sqlite3_memory_used]+500000}
|
||||
} {1}
|
||||
do_test shrink-1.2 {
|
||||
set baseline [sqlite3_memory_used]
|
||||
db eval {
|
||||
UPDATE t1 SET y=y+1;
|
||||
}
|
||||
expr {$::baseline+500000 < [sqlite3_memory_used]}
|
||||
} {1}
|
||||
do_test shrink-1.3 {
|
||||
set baseline [sqlite3_memory_used]
|
||||
db eval {PRAGMA shrink_memory}
|
||||
expr {$::baseline > [sqlite3_memory_used]+500000}
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
Reference in New Issue
Block a user