Compare commits

...

25 Commits

Author SHA1 Message Date
drh 24076fd97d Add a prototype implementation of stdio-like routines for accessing the VFS.
This is intended as documentation.  The code is untested. There is no
guarantee that any of this will ever make it into trunk.  Substantial
revision is possible prior to reaching trunk, if it ever does.

FossilOrigin-Name: 8936542b225836f5f4a789e1ecc1451f6a1e120d
2011-12-01 02:32:12 +00:00
drh d4e244ad56 Remove unused fields from the Parse object. Documentation and formatting
improvements on data structure definitions.

FossilOrigin-Name: 431556cac0b2c86d7f6a60412ff1023feeaafedf
2011-11-29 15:40:32 +00:00
drh 76a3acacea Remove unused boolean fields from the UnpackedRecord object.
FossilOrigin-Name: b10d091ec02e94643e865743129e2a21147b3136
2011-11-29 15:04:12 +00:00
drh 4dd65e0f0c Removed the unused "type" field from the CollSeq (collating sequence) object.
FossilOrigin-Name: ab89b047e82efdf59ed91a38b5195341a3743cbf
2011-11-29 14:46:56 +00:00
drh 5c0c56b89c Update the version number to 3.7.10.
FossilOrigin-Name: ed0151ba8379a6c95304c9a8f9fe47e741fb80a3
2011-11-25 21:51:03 +00:00
drh 814d6a7ba7 Fix a typo in the documentation for sqlite3_stmt_busy().
FossilOrigin-Name: 7812626d1da1e19f2fc54a045c9fe2741ce68699
2011-11-25 17:51:52 +00:00
drh 2fb6693e02 Add the sqlite3_stmt_busy() interface.
FossilOrigin-Name: 95cc4af686dc9bf85cb7224aecde27c9ca14ad5c
2011-11-25 17:21:47 +00:00
drh 5e4461b261 Change the multiplexor to use a 3-digit suffix.
FossilOrigin-Name: 0b7edc44757660c8a5ae3b91cbcc3e6afd419b28
2011-11-18 13:10:51 +00:00
drh 21495ba8a3 Improvements to the documentation of the sqlite3_db_filename() interface.
FossilOrigin-Name: 1c45b2a0c055f6fc5da9d00ae2e9171099d904d4
2011-11-17 11:49:58 +00:00
drh 070ad6b6fe Restore the test for sqlite3OsFullPathname() failure that was mistakenly
removed when [ceee03c79a] was backed out by [69ec53fc1c].

FossilOrigin-Name: 4d3cf9e1d8ac356db5a708913f614e42a6a56b94
2011-11-17 11:43:19 +00:00
drh 283829cb20 Add the sqlite3_db_filename() interface.
FossilOrigin-Name: 93a947989b57959aacc37007a143fdf3921793ab
2011-11-17 00:56:20 +00:00
drh f20fb8c6f3 Back out the [ceee03c79a] change.
FossilOrigin-Name: 69ec53fc1c60b07bf4aaa983dcd5bf3164fb1ea5
2011-11-16 23:29:37 +00:00
drh 09419b4bae Add the sqlite3_db_release_memory() interface and the shrink_memory pragma.
FossilOrigin-Name: 3f58e7c8895d1252eff56282c08b1a6f1194452c
2011-11-16 19:29:17 +00:00
drh 870c0178f7 Merge the PCACHE2 changes into trunk.
FossilOrigin-Name: 457513f21f2438c61b1a214716e338a4e3eeaafa
2011-11-16 18:08:07 +00:00
drh 81ef0f97ef Add a version number to the sqlite3_pcache_methods2 object. Other PCACHE2
documentation improvements.

FossilOrigin-Name: 9f839ac05a9f3cfe587d2ccdccd50dac41baedbe
2011-11-13 21:44:03 +00:00
drh f923f82118 Attempt to modify btree.c so that it assumes that calls to sqlite3PagerWrite()
will reallocate the page buffer.  As there is not good way to test this
assumption yet, probably a few spots were missed.

FossilOrigin-Name: ceee03c79a55ea39866758aa76b78b10e5f4246d
2011-11-12 23:10:13 +00:00
drh c90747313e Pull over all the latest changes from trunk.
FossilOrigin-Name: 1bbbf8574a820c5f787a937f02a8e2a91264ace0
2011-11-11 14:12:36 +00:00
drh 61a4bd5c6c Follow-on to the previous check-in to prevent a division by zero if the
lookahead slot size is something goofy like 6 on a 32-bit machine.

FossilOrigin-Name: 6bda711f93e753dd0be8d896a007b3f7b5064787
2011-11-10 02:39:28 +00:00
drh 8225d66be6 Use sqlite3MallocSize() to get the actual size of the memory allocation
used for lookaside cache and increase the size of the cache to use the
full allocation.

FossilOrigin-Name: 0e53ecad9468d0a13d155a4462551d4c234a7d5c
2011-11-10 02:24:11 +00:00
mistachkin 32121199be When compiling with MSVC, use the _msize function.
FossilOrigin-Name: 797a147934743a565c6f1f9dd4d41574690b4c2b
2011-11-09 17:01:40 +00:00
drh e73c91496f Minor changes needed to restore full branch test coverage.
FossilOrigin-Name: bc10a753579b65ba4604867204b7b3d8383f3ac7
2011-11-09 16:12:24 +00:00
drh 3b42abb35b A negative value N for the cache_size pragma adjusts the number of cache
pages to use approximately N kibibytes of memory.

FossilOrigin-Name: b3faa680aedc94ed8aa2819228c0d304b181cc51
2011-11-09 14:23:04 +00:00
drh 6a8ab6d9cb For the mem1.c system malloc implementation, use the malloc_usable_size()
function if the HAVE_MALLOC_USABLE_SIZE macro is defined.  Update autoconf
to look for that function when configuring.

FossilOrigin-Name: 2e8ab3cedfebc33a831837792b523d1aa7cdc6b7
2011-11-09 01:53:25 +00:00
drh e5c40b18e3 Update the API documentation for the new pcache2 interface. Change the
order of parameters on the xCreate method of pcache2.

FossilOrigin-Name: 4da7095683ec821414e255419d63a24dbd9d726d
2011-11-09 00:06:05 +00:00
dan 22e21ff4fc Experimental change to the pcache interface to allow page buffers to be allocated separately from their associated container structures.
FossilOrigin-Name: c275c9d323cb1dccb031b199d413ac3a0b244fea
2011-11-08 20:08:44 +00:00
35 changed files with 1377 additions and 476 deletions
+3
View File
@@ -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.
+1 -1
View File
@@ -1 +1 @@
3.7.9
3.7.10
+3
View File
@@ -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
Vendored
+213 -190
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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...)
+40 -39
View File
@@ -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
View File
@@ -1 +1 @@
06e0cdaf9112f722c23692e25c5b1f99b61c2d78
8936542b225836f5f4a789e1ecc1451f6a1e120d
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
/*
+232
View File
@@ -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 */
+7
View File
@@ -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
+1
View File
@@ -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);
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+4
View File
@@ -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);
}
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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},
+8
View File
@@ -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
View File
@@ -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;
}
+6 -4
View File
@@ -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
View File
@@ -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;
}
+8
View File
@@ -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
+19
View File
@@ -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
View File
@@ -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
+5
View File
@@ -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.
+6 -4
View File
@@ -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
View File
@@ -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
+42
View File
@@ -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