1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Merge experimental changes into trunk.

FossilOrigin-Name: aa092ac928dc19bd356d25a1dfd3f432dc145ce6
This commit is contained in:
dan
2010-08-11 06:04:19 +00:00
23 changed files with 1948 additions and 1031 deletions

View File

@@ -1,5 +1,5 @@
C Changes\sto\sdebugging\scode\sin\smutex_unix.c\sand\smutex_w32.c\sto\smake\san\sassert()\sstatement\sthreadsafe. C Merge\sexperimental\schanges\sinto\strunk.
D 2010-08-10T07:12:27 D 2010-08-11T06:04:19
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -154,9 +154,9 @@ F src/os.c 60178f518c4d6c0dcb59f7292232281d7bea2dcf
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248 F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
F src/pager.c 202e3dcb3f36c858d4339c0f6fa3d04d67258127 F src/pager.c b3db762350ee71f5f8bde04f21ca2ffcccded483
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5 F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
@@ -170,14 +170,14 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 4b8f481406c7fd2672abf715a2acaed8f9cde046 F src/select.c 4b8f481406c7fd2672abf715a2acaed8f9cde046
F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056 F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
F src/sqlite.h.in 1d29cd776795b0daa925fa5e8082ad79ba8e4ac4 F src/sqlite.h.in 2d72a6242df41c517e38eec8791abcf5484a36f1
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h e33b15e8176442bf7484f0e716edfd1ce03b2979 F src/sqliteInt.h e33b15e8176442bf7484f0e716edfd1ce03b2979
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3 F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 5cd96419fb6c771006f064196ccc70c29d01bec7 F src/tclsqlite.c 5cd96419fb6c771006f064196ccc70c29d01bec7
F src/test1.c ff3b4533fc4d78d1bff2ef831a5791db55096ed3 F src/test1.c 0bfcda72f9f8ab5c0e90fac05cc22c1c21131ddf
F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94 F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee
@@ -198,16 +198,16 @@ F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
F src/test_journal.c 424a334cdfdc8a6f975abe3641440147bded3185 F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 058e41dc853b1fa8ccd1083e9571018a74aeb3a7 F src/test_malloc.c 09a88f0c111201dc4f8c20470aa1b5f611d59200
F src/test_mutex.c ce06b59aca168cd8c520b77159a24352a7469bd3 F src/test_mutex.c ce06b59aca168cd8c520b77159a24352a7469bd3
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c
F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8 F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
F src/test_stat.c 6ebaf2a86d01ccda24e49c148f1d33e8badda06e F src/test_stat.c dcabb7d39da058cbfc9ddc427cd92fbf14822b28
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234 F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234
@@ -227,8 +227,8 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
F src/vdbemem.c e5673f81a2381b35c60e73ef0a8502be2ab1041e F src/vdbemem.c e5673f81a2381b35c60e73ef0a8502be2ab1041e
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
F src/vtab.c 82200af3881fa4e1c9cf07cf31d98c09d437e3ab F src/vtab.c 82200af3881fa4e1c9cf07cf31d98c09d437e3ab
F src/wal.c 0925601f3299c2941a67c9cfff41ee710f70ca82 F src/wal.c 582acbaa606c748675fafff516ec1b34a7bdae62
F src/wal.h 906c85760598b18584921fe08008435aa4eeeeb2 F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 7db3e41c2a846f9deeb24f1bbb75461b4010b7b5 F src/where.c 7db3e41c2a846f9deeb24f1bbb75461b4010b7b5
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -241,7 +241,7 @@ F test/alter4.test 9386ffd1e9c7245f43eca412b2058d747509cc1f
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/analyze.test bf692e7db414f268a136bade16c03a1bdbb9240c F test/analyze.test bf692e7db414f268a136bade16c03a1bdbb9240c
F test/analyze2.test 59dac6c399c0c5d1a90a11ee7cc606743fb6db93 F test/analyze2.test 59dac6c399c0c5d1a90a11ee7cc606743fb6db93
F test/analyze3.test 535bf0762f49fa96885efe8568738276c2204a2a F test/analyze3.test 6d4f4b0929545a9d1af803a0608a0c51b92a3537
F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3 F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6 F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
@@ -330,7 +330,7 @@ F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/date.test 6354b883f922c38046a8efbad187cc95df6da023 F test/date.test 6354b883f922c38046a8efbad187cc95df6da023
F test/dbstatus.test f3c88a3f8d15716e6ae73567a78ee96420c294a3 F test/dbstatus.test ba072efbd7fcbeb4da324bfbdf1e596d994c159e
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
F test/delete.test f7629d9eb245dfca170169cc5c7a735dec34aeb4 F test/delete.test f7629d9eb245dfca170169cc5c7a735dec34aeb4
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
@@ -347,10 +347,11 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test 5fe18e10a159342dd52ca14b1554e33f98734267 F test/exclusive.test b1f9012cabc124af947165d15ffa62ad20f63db8
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68 F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
F test/filefmt.test f77c92141960b7933bc6691631d2ad62257ef40a F test/filefmt.test f77c92141960b7933bc6691631d2ad62257ef40a
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
@@ -470,7 +471,7 @@ F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19 F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
F test/journal2.test 50a3604768494d4a337f194f0a9480e7c57dcb72 F test/journal2.test 50a3604768494d4a337f194f0a9480e7c57dcb72
F test/journal3.test ff175219be1b02d2f7e54297ad7e491b7533edb6 F test/journal3.test ff175219be1b02d2f7e54297ad7e491b7533edb6
F test/jrnlmode.test 2d5a8b6d68de8512f522532731d90ca96912f3b7 F test/jrnlmode.test e3fe6c4a2c3213d285650dc8e33aab7eaaa5ce53
F test/jrnlmode2.test a19e28de1a6ec898067e46a122f1b71c9323bf00 F test/jrnlmode2.test a19e28de1a6ec898067e46a122f1b71c9323bf00
F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710 F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05 F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
@@ -540,13 +541,14 @@ F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
F test/pager1.test d8e4b2bc8164c920e6ea0572c9e13576d6e4f3fa F test/pager1.test d8e4b2bc8164c920e6ea0572c9e13576d6e4f3fa
F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pagerfault.test c1d176326ce244db157ce9c3ba128be2a9b172d6 F test/pagerfault.test c1d176326ce244db157ce9c3ba128be2a9b172d6
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401 F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test 3fe47c21c32b294b2354e702a25bfbff65747bb1 F test/permutations.test 17498d1219f922d5a6da893a94c4dc7766fb2426
F test/pragma.test ed78d200f65c6998df51196cb8c39d5300570f24 F test/pragma.test ed78d200f65c6998df51196cb8c39d5300570f24
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
@@ -630,7 +632,7 @@ F test/thread2.test e08034b83fe9693ade77049732518e5b3d2d700d
F test/thread_common.tcl 2aa6f2fdcd4d6e461169c3e5ca098eebf643b863 F test/thread_common.tcl 2aa6f2fdcd4d6e461169c3e5ca098eebf643b863
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9 F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
F test/threadtest3.c f7e21a9bcddff1499d46a1fc68d1ba31e4063be4 F test/threadtest3.c 58df1e3c060f534fd7fb0702331b0acc41c381d8
F test/tkt-02a8e81d44.test 58494de77be2cf249228ada3f313fa399821c6ab F test/tkt-02a8e81d44.test 58494de77be2cf249228ada3f313fa399821c6ab
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
@@ -781,8 +783,8 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
F test/wal.test 1891e6f72dd437a1c2a48091aa9182ba17a8f780 F test/wal.test 1891e6f72dd437a1c2a48091aa9182ba17a8f780
F test/wal2.test 8dcebda41587e0b2b57194d03fd8700e01e85656 F test/wal2.test 223f3e14d475730af772a7f5862d4bcfa7565c3a
F test/wal3.test d2ae7e66f973bd6b58ce49e546b2c00f44fe0485 F test/wal3.test 695ea0f6c516423c611891df9a285aacd33344e3
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30 F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
F test/wal_common.tcl 895d76138043b86bdccf36494054bdabcf65837b F test/wal_common.tcl 895d76138043b86bdccf36494054bdabcf65837b
F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4 F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
@@ -792,7 +794,7 @@ F test/walcrash.test e763841551d6b23677ccb419797c1589dcbdbaf5
F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142 F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
F test/walfault.test 05c470688d742688e455dd56816bd6bcffa298f8 F test/walfault.test 05c470688d742688e455dd56816bd6bcffa298f8
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 5dc3008ef71988ecdd949ea16e5750e325b92b54 F test/walmode.test 4ecd37284f245247f7935896ab66f6943f0432a0
F test/walshared.test 985b4a3406b2b2dace1d52a42d26a11dd6900981 F test/walshared.test 985b4a3406b2b2dace1d52a42d26a11dd6900981
F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933 F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c
@@ -841,7 +843,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 9cebaf2dca6dc35e489537fe7c55474e1029a98e P e82e32bd431ccacd276df8241592eb5519d87122 42ba43ac690dc800fb8b969ae257a79942918342
R da77b0ae4e15ab90a6a323c7de4ca438 R 905d488f0b9b28e6cb7ddb8f6f378b5f
U dan U dan
Z ef5f61caa72edd66e82b2e19ff2bf16a Z cd4d4135a3c0d3f56327a6ac460d7792

View File

@@ -1 +1 @@
e82e32bd431ccacd276df8241592eb5519d87122 aa092ac928dc19bd356d25a1dfd3f432dc145ce6

View File

@@ -210,6 +210,7 @@ struct unixFile {
int fileFlags; /* Miscellanous flags */ int fileFlags; /* Miscellanous flags */
const char *zPath; /* Name of the file */ const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */ unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
#if SQLITE_ENABLE_LOCKING_STYLE #if SQLITE_ENABLE_LOCKING_STYLE
int openFlags; /* The flags specified at open() */ int openFlags; /* The flags specified at open() */
#endif #endif
@@ -2763,6 +2764,7 @@ static int unixWrite(
} }
SimulateIOError(( wrote=(-1), amt=1 )); SimulateIOError(( wrote=(-1), amt=1 ));
SimulateDiskfullError(( wrote=0, amt=1 )); SimulateDiskfullError(( wrote=0, amt=1 ));
if( amt>0 ){ if( amt>0 ){
if( wrote<0 ){ if( wrote<0 ){
/* lastErrno set by seekAndWrite */ /* lastErrno set by seekAndWrite */
@@ -2772,6 +2774,7 @@ static int unixWrite(
return SQLITE_FULL; return SQLITE_FULL;
} }
} }
return SQLITE_OK; return SQLITE_OK;
} }
@@ -2973,12 +2976,23 @@ static int unixSync(sqlite3_file *id, int flags){
** Truncate an open file to a specified size ** Truncate an open file to a specified size
*/ */
static int unixTruncate(sqlite3_file *id, i64 nByte){ static int unixTruncate(sqlite3_file *id, i64 nByte){
unixFile *pFile = (unixFile *)id;
int rc; int rc;
assert( id ); assert( pFile );
SimulateIOError( return SQLITE_IOERR_TRUNCATE ); SimulateIOError( return SQLITE_IOERR_TRUNCATE );
rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
/* If the user has configured a chunk-size for this file, truncate the
** file so that it consists of an integer number of chunks (i.e. the
** actual file size after the operation may be larger than the requested
** size).
*/
if( pFile->szChunk ){
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
}
rc = ftruncate(pFile->h, (off_t)nByte);
if( rc ){ if( rc ){
((unixFile*)id)->lastErrno = errno; pFile->lastErrno = errno;
return SQLITE_IOERR_TRUNCATE; return SQLITE_IOERR_TRUNCATE;
}else{ }else{
#ifndef NDEBUG #ifndef NDEBUG
@@ -2989,8 +3003,8 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
** when restoring a database using the backup API from a zero-length ** when restoring a database using the backup API from a zero-length
** source. ** source.
*/ */
if( ((unixFile*)id)->inNormalWrite && nByte==0 ){ if( pFile->inNormalWrite && nByte==0 ){
((unixFile*)id)->transCntrChng = 1; pFile->transCntrChng = 1;
} }
#endif #endif
@@ -3033,6 +3047,54 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
static int proxyFileControl(sqlite3_file*,int,void*); static int proxyFileControl(sqlite3_file*,int,void*);
#endif #endif
/*
** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
** file-control operation.
**
** If the user has configured a chunk-size for this file, it could be
** that the file needs to be extended at this point. Otherwise, the
** SQLITE_FCNTL_SIZE_HINT operation is a no-op for Unix.
*/
static int fcntlSizeHint(unixFile *pFile, i64 nByte){
if( pFile->szChunk ){
i64 nSize; /* Required file size */
struct stat buf; /* Used to hold return values of fstat() */
if( fstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
if( nSize>(i64)buf.st_size ){
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
if( posix_fallocate(pFile->h, buf.st_size, nSize-buf.st_size) ){
return SQLITE_IOERR_WRITE;
}
#else
/* If the OS does not have posix_fallocate(), fake it. First use
** ftruncate() to set the file size, then write a single byte to
** the last byte in each block within the extended region. This
** is the same technique used by glibc to implement posix_fallocate()
** on systems that do not have a real fallocate() system call.
*/
int nBlk = buf.st_blksize; /* File-system block size */
i64 iWrite; /* Next offset to write to */
int nWrite; /* Return value from seekAndWrite() */
if( ftruncate(pFile->h, nSize) ){
pFile->lastErrno = errno;
return SQLITE_IOERR_TRUNCATE;
}
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
do {
nWrite = seekAndWrite(pFile, iWrite, "", 1);
iWrite += nBlk;
} while( nWrite==1 && iWrite<nSize );
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
#endif
}
}
return SQLITE_OK;
}
/* /*
** Information and control of an open file handle. ** Information and control of an open file handle.
@@ -3047,14 +3109,13 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(int*)pArg = ((unixFile*)id)->lastErrno; *(int*)pArg = ((unixFile*)id)->lastErrno;
return SQLITE_OK; return SQLITE_OK;
} }
case SQLITE_FCNTL_SIZE_HINT: { case SQLITE_FCNTL_CHUNK_SIZE: {
#if 0 /* No performance advantage seen on Linux */ ((unixFile*)id)->szChunk = *(int *)pArg;
sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
unixFile *pFile = (unixFile*)id;
ftruncate(pFile->h, szFile);
#endif
return SQLITE_OK; return SQLITE_OK;
} }
case SQLITE_FCNTL_SIZE_HINT: {
return fcntlSizeHint((unixFile *)id, *(i64 *)pArg);
}
#ifndef NDEBUG #ifndef NDEBUG
/* The pager calls this method to signal that it has done /* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and ** a rollback and that the database is therefore unchanged and

View File

@@ -108,6 +108,7 @@ struct winFile {
DWORD sectorSize; /* Sector size of the device file is on */ DWORD sectorSize; /* Sector size of the device file is on */
winShm *pShm; /* Instance of shared memory on this file */ winShm *pShm; /* Instance of shared memory on this file */
const char *zPath; /* Full pathname of this file */ const char *zPath; /* Full pathname of this file */
int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */
#if SQLITE_OS_WINCE #if SQLITE_OS_WINCE
WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
HANDLE hMutex; /* Mutex used to control access to shared lock */ HANDLE hMutex; /* Mutex used to control access to shared lock */
@@ -620,6 +621,42 @@ static BOOL winceLockFileEx(
** by the sqlite3_io_methods object. ** by the sqlite3_io_methods object.
******************************************************************************/ ******************************************************************************/
/*
** Some microsoft compilers lack this definition.
*/
#ifndef INVALID_SET_FILE_POINTER
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
/*
** Move the current position of the file handle passed as the first
** argument to offset iOffset within the file. If successful, return 0.
** Otherwise, set pFile->lastErrno and return non-zero.
*/
static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
LONG upperBits; /* Most sig. 32 bits of new offset */
LONG lowerBits; /* Least sig. 32 bits of new offset */
DWORD dwRet; /* Value returned by SetFilePointer() */
upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
lowerBits = (LONG)(iOffset & 0xffffffff);
/* API oddity: If successful, SetFilePointer() returns a dword
** containing the lower 32-bits of the new file-offset. Or, if it fails,
** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
** whether an error has actually occured, it is also necessary to call
** GetLastError().
*/
dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
pFile->lastErrno = GetLastError();
return 1;
}
return 0;
}
/* /*
** Close a file. ** Close a file.
** **
@@ -662,13 +699,6 @@ static int winClose(sqlite3_file *id){
return rc ? SQLITE_OK : SQLITE_IOERR; return rc ? SQLITE_OK : SQLITE_IOERR;
} }
/*
** Some microsoft compilers lack this definition.
*/
#ifndef INVALID_SET_FILE_POINTER
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
/* /*
** Read data from a file into a buffer. Return SQLITE_OK if all ** Read data from a file into a buffer. Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes ** bytes were read successfully and SQLITE_IOERR if anything goes
@@ -680,32 +710,27 @@ static int winRead(
int amt, /* Number of bytes to read */ int amt, /* Number of bytes to read */
sqlite3_int64 offset /* Begin reading at this offset */ sqlite3_int64 offset /* Begin reading at this offset */
){ ){
LONG upperBits = (LONG)((offset>>32) & 0x7fffffff); winFile *pFile = (winFile*)id; /* file handle */
LONG lowerBits = (LONG)(offset & 0xffffffff); DWORD nRead; /* Number of bytes actually read from file */
DWORD rc;
winFile *pFile = (winFile*)id;
DWORD error;
DWORD got;
assert( id!=0 ); assert( id!=0 );
SimulateIOError(return SQLITE_IOERR_READ); SimulateIOError(return SQLITE_IOERR_READ);
OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ if( seekWinFile(pFile, offset) ){
pFile->lastErrno = error;
return SQLITE_FULL; return SQLITE_FULL;
} }
if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
return SQLITE_IOERR_READ; return SQLITE_IOERR_READ;
} }
if( got==(DWORD)amt ){ if( nRead<(DWORD)amt ){
return SQLITE_OK;
}else{
/* Unread parts of the buffer must be zero-filled */ /* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[got], 0, amt-got); memset(&((char*)pBuf)[nRead], 0, amt-nRead);
return SQLITE_IOERR_SHORT_READ; return SQLITE_IOERR_SHORT_READ;
} }
return SQLITE_OK;
} }
/* /*
@@ -713,47 +738,42 @@ static int winRead(
** or some other error code on failure. ** or some other error code on failure.
*/ */
static int winWrite( static int winWrite(
sqlite3_file *id, /* File to write into */ sqlite3_file *id, /* File to write into */
const void *pBuf, /* The bytes to be written */ const void *pBuf, /* The bytes to be written */
int amt, /* Number of bytes to write */ int amt, /* Number of bytes to write */
sqlite3_int64 offset /* Offset into the file to begin writing at */ sqlite3_int64 offset /* Offset into the file to begin writing at */
){ ){
LONG upperBits = (LONG)((offset>>32) & 0x7fffffff); int rc; /* True if error has occured, else false */
LONG lowerBits = (LONG)(offset & 0xffffffff); winFile *pFile = (winFile*)id; /* File handle */
DWORD rc;
winFile *pFile = (winFile*)id;
DWORD error;
DWORD wrote = 0;
assert( id!=0 ); assert( amt>0 );
assert( pFile );
SimulateIOError(return SQLITE_IOERR_WRITE); SimulateIOError(return SQLITE_IOERR_WRITE);
SimulateDiskfullError(return SQLITE_FULL); SimulateDiskfullError(return SQLITE_FULL);
OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ rc = seekWinFile(pFile, offset);
pFile->lastErrno = error; if( rc==0 ){
if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
return SQLITE_FULL; int nRem = amt; /* Number of bytes yet to be written */
}else{ DWORD nWrite; /* Bytes written by each WriteFile() call */
return SQLITE_IOERR_WRITE;
while( nRem>0 && WriteFile(pFile->h, aRem, nRem, &nWrite, 0) && nWrite>0 ){
aRem += nWrite;
nRem -= nWrite;
}
if( nRem>0 ){
pFile->lastErrno = GetLastError();
rc = 1;
} }
} }
assert( amt>0 );
while( if( rc ){
amt>0
&& (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
&& wrote>0
){
amt -= wrote;
pBuf = &((char*)pBuf)[wrote];
}
if( !rc || amt>(int)wrote ){
pFile->lastErrno = GetLastError();
if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
return SQLITE_FULL; return SQLITE_FULL;
}else{
return SQLITE_IOERR_WRITE;
} }
return SQLITE_IOERR_WRITE;
} }
return SQLITE_OK; return SQLITE_OK;
} }
@@ -762,26 +782,32 @@ static int winWrite(
** Truncate an open file to a specified size ** Truncate an open file to a specified size
*/ */
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff); winFile *pFile = (winFile*)id; /* File handle object */
LONG lowerBits = (LONG)(nByte & 0xffffffff); int rc = SQLITE_OK; /* Return code for this function */
DWORD dwRet;
winFile *pFile = (winFile*)id; assert( pFile );
DWORD error;
int rc = SQLITE_OK;
assert( id!=0 );
OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte)); OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
SimulateIOError(return SQLITE_IOERR_TRUNCATE); SimulateIOError(return SQLITE_IOERR_TRUNCATE);
dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
if( dwRet==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ /* If the user has configured a chunk-size for this file, truncate the
pFile->lastErrno = error; ** file so that it consists of an integer number of chunks (i.e. the
** actual file size after the operation may be larger than the requested
** size).
*/
if( pFile->szChunk ){
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
}
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
if( seekWinFile(pFile, nByte) ){
rc = SQLITE_IOERR_TRUNCATE; rc = SQLITE_IOERR_TRUNCATE;
/* SetEndOfFile will fail if nByte is negative */ }else if( 0==SetEndOfFile(pFile->h) ){
}else if( !SetEndOfFile(pFile->h) ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
rc = SQLITE_IOERR_TRUNCATE; rc = SQLITE_IOERR_TRUNCATE;
} }
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc==SQLITE_OK ? "ok" : "failed"));
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
return rc; return rc;
} }
@@ -1146,6 +1172,10 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
*(int*)pArg = (int)((winFile*)id)->lastErrno; *(int*)pArg = (int)((winFile*)id)->lastErrno;
return SQLITE_OK; return SQLITE_OK;
} }
case SQLITE_FCNTL_CHUNK_SIZE: {
((winFile*)id)->szChunk = *(int *)pArg;
return SQLITE_OK;
}
case SQLITE_FCNTL_SIZE_HINT: { case SQLITE_FCNTL_SIZE_HINT: {
sqlite3_int64 sz = *(sqlite3_int64*)pArg; sqlite3_int64 sz = *(sqlite3_int64*)pArg;
SimulateIOErrorBenign(1); SimulateIOErrorBenign(1);

File diff suppressed because it is too large Load Diff

View File

@@ -690,12 +690,21 @@ struct sqlite3_io_methods {
** is often close. The underlying VFS might choose to preallocate database ** is often close. The underlying VFS might choose to preallocate database
** file space based on this hint in order to help writes to the database ** file space based on this hint in order to help writes to the database
** file run faster. ** file run faster.
**
** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
** extends and truncates the database file in chunks of a size specified
** by the user. The fourth argument to [sqlite3_file_control()] should
** point to an integer (type int) containing the new chunk-size to use
** for the nominated database. Allocating database file space in large
** chunks (say 1MB at a time), may reduce file-system fragmentation and
** improve performance on some systems.
*/ */
#define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_GET_LOCKPROXYFILE 2
#define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_SET_LOCKPROXYFILE 3
#define SQLITE_LAST_ERRNO 4 #define SQLITE_LAST_ERRNO 4
#define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_SIZE_HINT 5
#define SQLITE_FCNTL_CHUNK_SIZE 6
/* /*
** CAPI3REF: Mutex Handle ** CAPI3REF: Mutex Handle

View File

@@ -4613,6 +4613,44 @@ static int file_control_lasterrno_test(
return TCL_OK; return TCL_OK;
} }
/*
** tclcmd: file_control_chunksize_test DB DBNAME SIZE
**
** This TCL command runs the sqlite3_file_control interface and
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
** SQLITE_SET_LOCKPROXYFILE verbs.
*/
static int file_control_chunksize_test(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
int nSize; /* New chunk size */
char *zDb; /* Db name ("main", "temp" etc.) */
sqlite3 *db; /* Database handle */
int rc; /* file_control() return code */
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
|| Tcl_GetIntFromObj(interp, objv[3], &nSize)
){
return TCL_ERROR;
}
zDb = Tcl_GetString(objv[2]);
if( zDb[0]=='\0' ) zDb = NULL;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
if( rc ){
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
return TCL_ERROR;
}
return TCL_OK;
}
/* /*
** tclcmd: file_control_lockproxy_test DB PWD ** tclcmd: file_control_lockproxy_test DB PWD
** **
@@ -5106,6 +5144,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_test", file_control_test, 0 }, { "file_control_test", file_control_test, 0 },
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 }, { "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 }, { "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_vfs_list", vfs_list, 0 },
/* Functions from os.h */ /* Functions from os.h */

View File

@@ -361,6 +361,7 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){
sqlite3_file *p = pMain->pReal; sqlite3_file *p = pMain->pReal;
int rc = SQLITE_OK; int rc = SQLITE_OK;
closeTransaction(pMain);
aData = sqlite3_malloc(pMain->nPagesize); aData = sqlite3_malloc(pMain->nPagesize);
pMain->pWritable = sqlite3BitvecCreate(pMain->nPage); pMain->pWritable = sqlite3BitvecCreate(pMain->nPage);
pMain->aCksum = sqlite3_malloc(sizeof(u32) * (pMain->nPage + 1)); pMain->aCksum = sqlite3_malloc(sizeof(u32) * (pMain->nPage + 1));
@@ -379,6 +380,15 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){
** leaf to the jt_file.pWritable bitvec. ** leaf to the jt_file.pWritable bitvec.
*/ */
rc = sqlite3OsRead(p, aData, pMain->nPagesize, 0); rc = sqlite3OsRead(p, aData, pMain->nPagesize, 0);
if( rc==SQLITE_OK ){
u32 nDbsize = decodeUint32(&aData[28]);
if( nDbsize>0 && memcmp(&aData[24], &aData[92], 4)==0 ){
u32 iPg;
for(iPg=nDbsize+1; iPg<=pMain->nPage; iPg++){
sqlite3BitvecSet(pMain->pWritable, iPg);
}
}
}
iTrunk = decodeUint32(&aData[32]); iTrunk = decodeUint32(&aData[32]);
while( rc==SQLITE_OK && iTrunk>0 ){ while( rc==SQLITE_OK && iTrunk>0 ){
u32 nLeaf; u32 nLeaf;
@@ -492,7 +502,6 @@ finish_rjf:
return rc; return rc;
} }
/* /*
** Write data to an jt-file. ** Write data to an jt-file.
*/ */

View File

@@ -728,7 +728,10 @@ static int test_memdebug_settitle(
return TCL_OK; return TCL_OK;
} }
#define MALLOC_LOG_FRAMES 10 #define MALLOC_LOG_FRAMES 10
#define MALLOC_LOG_KEYINTS ( \
10 * ((sizeof(int)>=sizeof(void*)) ? 1 : sizeof(void*)/sizeof(int)) \
)
static Tcl_HashTable aMallocLog; static Tcl_HashTable aMallocLog;
static int mallocLogEnabled = 0; static int mallocLogEnabled = 0;
@@ -745,8 +748,8 @@ static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
Tcl_HashEntry *pEntry; Tcl_HashEntry *pEntry;
int isNew; int isNew;
int aKey[MALLOC_LOG_FRAMES]; int aKey[MALLOC_LOG_KEYINTS];
int nKey = sizeof(int)*MALLOC_LOG_FRAMES; int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
memset(aKey, 0, nKey); memset(aKey, 0, nKey);
if( (sizeof(void*)*nFrame)<nKey ){ if( (sizeof(void*)*nFrame)<nKey ){
@@ -781,7 +784,7 @@ static void test_memdebug_log_clear(void){
Tcl_Free((char *)pLog); Tcl_Free((char *)pLog);
} }
Tcl_DeleteHashTable(&aMallocLog); Tcl_DeleteHashTable(&aMallocLog);
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES); Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
} }
static int test_memdebug_log( static int test_memdebug_log(
@@ -804,7 +807,7 @@ static int test_memdebug_log(
void (*xBacktrace)(int, int, void **)); void (*xBacktrace)(int, int, void **));
sqlite3MemdebugBacktraceCallback(test_memdebug_callback); sqlite3MemdebugBacktraceCallback(test_memdebug_callback);
#endif #endif
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES); Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
isInit = 1; isInit = 1;
} }
@@ -827,7 +830,7 @@ static int test_memdebug_log(
Tcl_HashEntry *pEntry; Tcl_HashEntry *pEntry;
Tcl_Obj *pRet = Tcl_NewObj(); Tcl_Obj *pRet = Tcl_NewObj();
assert(sizeof(int)==sizeof(void*)); assert(sizeof(Tcl_WideInt)>=sizeof(void*));
for( for(
pEntry=Tcl_FirstHashEntry(&aMallocLog, &search); pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
@@ -836,13 +839,13 @@ static int test_memdebug_log(
){ ){
Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2]; Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2];
MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry); MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
int *aKey = (int *)Tcl_GetHashKey(&aMallocLog, pEntry); Tcl_WideInt *aKey = (Tcl_WideInt *)Tcl_GetHashKey(&aMallocLog, pEntry);
int ii; int ii;
apElem[0] = Tcl_NewIntObj(pLog->nCall); apElem[0] = Tcl_NewIntObj(pLog->nCall);
apElem[1] = Tcl_NewIntObj(pLog->nByte); apElem[1] = Tcl_NewIntObj(pLog->nByte);
for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){ for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){
apElem[ii+2] = Tcl_NewIntObj(aKey[ii]); apElem[ii+2] = Tcl_NewWideIntObj(aKey[ii]);
} }
Tcl_ListObjAppendElement(interp, pRet, Tcl_ListObjAppendElement(interp, pRet,

View File

@@ -376,7 +376,13 @@ static int statNext(sqlite3_vtab_cursor *pCursor){
if( pCsr->aPage[0].pPg==0 ){ if( pCsr->aPage[0].pPg==0 ){
rc = sqlite3_step(pCsr->pStmt); rc = sqlite3_step(pCsr->pStmt);
if( rc==SQLITE_ROW ){ if( rc==SQLITE_ROW ){
int nPage;
u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1); u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1);
sqlite3PagerPagecount(pPager, &nPage);
if( nPage==0 ){
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
}
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg); rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
pCsr->aPage[0].iPgno = iRoot; pCsr->aPage[0].iPgno = iRoot;
pCsr->aPage[0].iCell = 0; pCsr->aPage[0].iCell = 0;
@@ -486,17 +492,9 @@ static int statFilter(
int idxNum, const char *idxStr, int idxNum, const char *idxStr,
int argc, sqlite3_value **argv int argc, sqlite3_value **argv
){ ){
sqlite3 *db = ((StatTable *)(pCursor->pVtab))->db;
StatCursor *pCsr = (StatCursor *)pCursor; StatCursor *pCsr = (StatCursor *)pCursor;
int nPage = 0;
statResetCsr((StatCursor *)pCursor); statResetCsr((StatCursor *)pCursor);
sqlite3PagerPagecount(sqlite3BtreePager(db->aDb[0].pBt), &nPage);
if( nPage==0 ){
pCsr->isEof = 1;
return SQLITE_OK;
}
return statNext(pCursor); return statNext(pCursor);
} }

View File

@@ -1521,6 +1521,7 @@ static int walCheckpoint(
u32 iDbpage = 0; /* Next database page to write */ u32 iDbpage = 0; /* Next database page to write */
u32 iFrame = 0; /* Wal frame containing data for iDbpage */ u32 iFrame = 0; /* Wal frame containing data for iDbpage */
u32 mxSafeFrame; /* Max frame that can be backfilled */ u32 mxSafeFrame; /* Max frame that can be backfilled */
u32 mxPage; /* Max database page to write */
int i; /* Loop counter */ int i; /* Loop counter */
volatile WalCkptInfo *pInfo; /* The checkpoint status information */ volatile WalCkptInfo *pInfo; /* The checkpoint status information */
@@ -1545,6 +1546,7 @@ static int walCheckpoint(
** cannot be backfilled from the WAL. ** cannot be backfilled from the WAL.
*/ */
mxSafeFrame = pWal->hdr.mxFrame; mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
pInfo = walCkptInfo(pWal); pInfo = walCkptInfo(pWal);
for(i=1; i<WAL_NREADER; i++){ for(i=1; i<WAL_NREADER; i++){
u32 y = pInfo->aReadMark[i]; u32 y = pInfo->aReadMark[i];
@@ -1565,6 +1567,7 @@ static int walCheckpoint(
if( pInfo->nBackfill<mxSafeFrame if( pInfo->nBackfill<mxSafeFrame
&& (rc = walLockExclusive(pWal, WAL_READ_LOCK(0), 1))==SQLITE_OK && (rc = walLockExclusive(pWal, WAL_READ_LOCK(0), 1))==SQLITE_OK
){ ){
i64 nSize; /* Current size of database file */
u32 nBackfill = pInfo->nBackfill; u32 nBackfill = pInfo->nBackfill;
/* Sync the WAL to disk */ /* Sync the WAL to disk */
@@ -1572,11 +1575,22 @@ static int walCheckpoint(
rc = sqlite3OsSync(pWal->pWalFd, sync_flags); rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
} }
/* If the database file may grow as a result of this checkpoint, hint
** about the eventual size of the db file to the VFS layer.
*/
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSize<nReq ){
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
}
}
/* Iterate through the contents of the WAL, copying data to the db file. */ /* Iterate through the contents of the WAL, copying data to the db file. */
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
i64 iOffset; i64 iOffset;
assert( walFramePgno(pWal, iFrame)==iDbpage ); assert( walFramePgno(pWal, iFrame)==iDbpage );
if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue; if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
@@ -2031,6 +2045,7 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
** read-lock. ** read-lock.
*/ */
void sqlite3WalEndReadTransaction(Wal *pWal){ void sqlite3WalEndReadTransaction(Wal *pWal){
sqlite3WalEndWriteTransaction(pWal);
if( pWal->readLock>=0 ){ if( pWal->readLock>=0 ){
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
pWal->readLock = -1; pWal->readLock = -1;
@@ -2153,11 +2168,13 @@ int sqlite3WalRead(
/* /*
** Set *pPgno to the size of the database file (or zero, if unknown). ** Return the size of the database in pages (or zero, if unknown).
*/ */
void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno){ Pgno sqlite3WalDbsize(Wal *pWal){
assert( pWal->readLock>=0 || pWal->lockError ); if( pWal && pWal->readLock>=0 ){
*pPgno = pWal->hdr.nPage; return pWal->hdr.nPage;
}
return 0;
} }

View File

@@ -25,7 +25,7 @@
# define sqlite3WalBeginReadTransaction(y,z) 0 # define sqlite3WalBeginReadTransaction(y,z) 0
# define sqlite3WalEndReadTransaction(z) # define sqlite3WalEndReadTransaction(z)
# define sqlite3WalRead(v,w,x,y,z) 0 # define sqlite3WalRead(v,w,x,y,z) 0
# define sqlite3WalDbsize(y,z) # define sqlite3WalDbsize(y) 0
# define sqlite3WalBeginWriteTransaction(y) 0 # define sqlite3WalBeginWriteTransaction(y) 0
# define sqlite3WalEndWriteTransaction(x) 0 # define sqlite3WalEndWriteTransaction(x) 0
# define sqlite3WalUndo(x,y,z) 0 # define sqlite3WalUndo(x,y,z) 0
@@ -61,9 +61,8 @@ void sqlite3WalEndReadTransaction(Wal *pWal);
/* Read a page from the write-ahead log, if it is present. */ /* Read a page from the write-ahead log, if it is present. */
int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut); int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
/* Return the size of the database as it existed at the beginning /* If the WAL is not empty, return the size of the database. */
** of the snapshot */ Pgno sqlite3WalDbsize(Wal *pWal);
void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno);
/* Obtain or release the WRITER lock. */ /* Obtain or release the WRITER lock. */
int sqlite3WalBeginWriteTransaction(Wal *pWal); int sqlite3WalBeginWriteTransaction(Wal *pWal);

View File

@@ -403,7 +403,6 @@ do_test analyze3-3.6.5 {
} {SQLITE_OK} } {SQLITE_OK}
do_test analyze3-3.7.1 { do_test analyze3-3.7.1 {
breakpoint
set S [sqlite3_prepare_v2 db { set S [sqlite3_prepare_v2 db {
SELECT * FROM t1 WHERE a IN ( SELECT * FROM t1 WHERE a IN (
?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33, ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,

View File

@@ -55,6 +55,12 @@ proc lookaside {db} {
# #
foreach ::lookaside_buffer_size {0 64 120} { foreach ::lookaside_buffer_size {0 64 120} {
# Do not run any of these tests if there is SQL configured to run
# as part of the [sqlite3] command. This prevents the script from
# configuring the size of the lookaside buffer after [sqlite3] has
# returned.
if {[presql] != ""} break
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Tests for SQLITE_DBSTATUS_SCHEMA_USED. # Tests for SQLITE_DBSTATUS_SCHEMA_USED.
# #
@@ -317,6 +323,7 @@ foreach ::lookaside_buffer_size {0 64 120} {
# implementation using sqlite3_mprintf() is technically considered # implementation using sqlite3_mprintf() is technically considered
# external and so is not counted as "statement memory". # external and so is not counted as "statement memory".
# #
puts "$nStmt1 $nFree"
if {[string match *x $tn]} { if {[string match *x $tn]} {
do_test dbstatus-3.$tn.bx { expr $nStmt1<=$nFree } {1} do_test dbstatus-3.$tn.bx { expr $nStmt1<=$nFree } {1}
} else { } else {

View File

@@ -253,6 +253,11 @@ db2 close
# from being inspected externally. # from being inspected externally.
# #
if {$tcl_platform(platform) != "windows"} { if {$tcl_platform(platform) != "windows"} {
# Return a list of two booleans (either 0 or 1). The first is true
# if the named file exists. The second is true only if the file
# exists and the first 28 bytes contain at least one non-zero byte.
#
proc filestate {fname} { proc filestate {fname} {
set exists 0 set exists 0
set content 0 set content 0
@@ -263,6 +268,7 @@ if {$tcl_platform(platform) != "windows"} {
} }
list $exists $content list $exists $content
} }
do_test exclusive-3.0 { do_test exclusive-3.0 {
filestate test.db-journal filestate test.db-journal
} {0 0} } {0 0}

146
test/fallocate.test Normal file
View File

@@ -0,0 +1,146 @@
# 2010 July 28
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
file_control_chunksize_test db main [expr 1024*1024]
do_test fallocate-1.1 {
execsql {
PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 1;
CREATE TABLE t1(a, b);
}
file size test.db
} [expr 1*1024*1024]
do_test fallocate-1.2 {
execsql { INSERT INTO t1 VALUES(1, zeroblob(1024*900)) }
file size test.db
} [expr 1*1024*1024]
do_test fallocate-1.3 {
execsql { INSERT INTO t1 VALUES(2, zeroblob(1024*900)) }
file size test.db
} [expr 2*1024*1024]
do_test fallocate-1.4 {
execsql { DELETE FROM t1 WHERE a = 1 }
file size test.db
} [expr 1*1024*1024]
do_test fallocate-1.5 {
execsql { DELETE FROM t1 WHERE a = 2 }
file size test.db
} [expr 1*1024*1024]
do_test fallocate-1.6 {
execsql { PRAGMA freelist_count }
} {0}
# Start a write-transaction and read the "database file size" field from
# the journal file. This field should be set to the number of pages in
# the database file based on the size of the file on disk, not the actual
# logical size of the database within the file.
#
# We need to check this to verify that if in the unlikely event a rollback
# causes a database file to grow, the database grows to its previous size
# on disk, not to the minimum size required to hold the database image.
#
do_test fallocate-1.7 {
execsql { BEGIN; INSERT INTO t1 VALUES(1, 2); }
if {[permutation] != "inmemory_journal"} {
hexio_get_int [hexio_read test.db-journal 16 4]
} else {
set {} 1024
}
} {1024}
do_test fallocate-1.8 { execsql { COMMIT } } {}
#-------------------------------------------------------------------------
# The following tests - fallocate-2.* - test that things work in WAL
# mode as well.
#
set skipwaltests [expr {
[permutation]=="journaltest" || [permutation]=="inmemory_journal"
}]
ifcapable !wal { set skipwaltests 1 }
if {!$skipwaltests} {
db close
file delete -force test.db
sqlite3 db test.db
file_control_chunksize_test db main [expr 32*1024]
do_test fallocate-2.1 {
execsql {
PRAGMA page_size = 1024;
PRAGMA journal_mode = WAL;
CREATE TABLE t1(a, b);
}
file size test.db
} [expr 32*1024]
do_test fallocate-2.2 {
execsql { INSERT INTO t1 VALUES(1, zeroblob(35*1024)) }
execsql { PRAGMA wal_checkpoint }
file size test.db
} [expr 64*1024]
do_test fallocate-2.3 {
execsql { DELETE FROM t1 }
execsql { VACUUM }
file size test.db
} [expr 64*1024]
do_test fallocate-2.4 {
execsql { PRAGMA wal_checkpoint }
file size test.db
} [expr 32*1024]
do_test fallocate-2.5 {
execsql {
INSERT INTO t1 VALUES(2, randomblob(35*1024));
PRAGMA wal_checkpoint;
INSERT INTO t1 VALUES(3, randomblob(128));
DELETE FROM t1 WHERE a = 2;
VACUUM;
}
file size test.db
} [expr 64*1024]
do_test fallocate-2.6 {
sqlite3 db2 test.db
execsql { BEGIN ; SELECT count(a) FROM t1 } db2
execsql {
INSERT INTO t1 VALUES(4, randomblob(128));
PRAGMA wal_checkpoint;
}
file size test.db
} [expr 64*1024]
do_test fallocate-2.7 {
execsql { SELECT count(b) FROM t1 } db2
} {1}
do_test fallocate-2.8 {
execsql { COMMIT } db2
execsql { PRAGMA wal_checkpoint }
file size test.db
} [expr 32*1024]
}
finish_test

View File

@@ -524,4 +524,35 @@ ifcapable pragma {
do_test jrnlmode-7.2 { file size test.db } {1024} do_test jrnlmode-7.2 { file size test.db } {1024}
} }
do_execsql_test jrnlmode-8.1 { PRAGMA locking_mode=EXCLUSIVE } {exclusive}
do_execsql_test jrnlmode-8.2 { CREATE TABLE t1(x) } {}
do_execsql_test jrnlmode-8.3 { INSERT INTO t1 VALUES(123) } {}
do_execsql_test jrnlmode-8.4 { SELECT * FROM t1 } {123}
do_execsql_test jrnlmode-8.5 { PRAGMA journal_mode=PERSIST } {persist}
do_execsql_test jrnlmode-8.6 { PRAGMA journal_mode=DELETE } {delete}
do_execsql_test jrnlmode-8.7 { PRAGMA journal_mode=TRUNCATE } {truncate}
do_execsql_test jrnlmode-8.8 { PRAGMA journal_mode=DELETE } {delete}
do_execsql_test jrnlmode-8.9 { CREATE TABLE t2(y) } {}
do_execsql_test jrnlmode-8.10 { INSERT INTO t2 VALUES(456) } {}
do_execsql_test jrnlmode-8.11 { SELECT * FROM t1, t2 } {123 456}
do_execsql_test jrnlmode-8.12 { PRAGMA locking_mode=NORMAL } {normal}
do_execsql_test jrnlmode-8.13 { PRAGMA journal_mode=PERSIST } {persist}
do_execsql_test jrnlmode-8.14 { PRAGMA journal_mode=TRUNCATE } {truncate}
do_execsql_test jrnlmode-8.15 { PRAGMA journal_mode=PERSIST } {persist}
do_execsql_test jrnlmode-8.16 { PRAGMA journal_mode=DELETE } {delete}
do_execsql_test jrnlmode-8.17 { PRAGMA journal_mode=TRUNCATE } {truncate}
do_execsql_test jrnlmode-8.18 { PRAGMA locking_mode=EXCLUSIVE } {exclusive}
do_execsql_test jrnlmode-8.19 { CREATE TABLE t3(z) } {}
do_execsql_test jrnlmode-8.20 { BEGIN IMMEDIATE } {}
do_execsql_test jrnlmode-8.21 { PRAGMA journal_mode=DELETE } {delete}
do_execsql_test jrnlmode-8.22 { COMMIT } {}
do_execsql_test jrnlmode-8.23 { PRAGMA journal_mode=DELETE } {delete}
do_execsql_test jrnlmode-8.24 { PRAGMA journal_mode=TRUNCATE } {truncate}
do_execsql_test jrnlmode-8.25 { PRAGMA locking_mode=NORMAL } {normal}
do_execsql_test jrnlmode-8.26 { CREATE TABLE t4(w) } {}
do_execsql_test jrnlmode-8.27 { BEGIN IMMEDIATE } {}
do_execsql_test jrnlmode-8.28 { PRAGMA journal_mode=DELETE } {delete}
do_execsql_test jrnlmode-8.29 { COMMIT } {}
do_execsql_test jrnlmode-8.30 { PRAGMA journal_mode=DELETE } {delete}
finish_test finish_test

33
test/pager3.test Normal file
View File

@@ -0,0 +1,33 @@
# 2010 June 15
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
foreach {tn sql res j} {
1 "PRAGMA journal_mode = DELETE" delete 0
2 "CREATE TABLE t1(a, b)" {} 0
3 "PRAGMA locking_mode=EXCLUSIVE" {exclusive} 0
4 "INSERT INTO t1 VALUES(1, 2)" {} 1
5 "PRAGMA locking_mode=NORMAL" {normal} 1
6 "SELECT * FROM t1" {1 2} 0
} {
do_execsql_test pager3-1.$tn.1 $sql $res
do_test pager3-1.$tn.2 { file exists test.db-journal } $j
}
finish_test

View File

@@ -129,7 +129,7 @@ test_suite "veryquick" -prefix "" -description {
This test suite is the same as the "quick" tests, except that some files This test suite is the same as the "quick" tests, except that some files
that test malloc and IO errors are omitted. that test malloc and IO errors are omitted.
} -files [ } -files [
test_set $allquicktests -exclude *malloc* *ioerr* *fault* test_set $allquicktests -exclude *malloc* *ioerr* *fault*
] ]
test_suite "quick" -prefix "" -description { test_suite "quick" -prefix "" -description {

View File

@@ -517,6 +517,7 @@ static void opendb_x(
pDb->db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize pDb->db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize
); );
sqlite3_busy_handler(pDb->db, busyhandler, 0); sqlite3_busy_handler(pDb->db, busyhandler, 0);
sqlite3_exec(pDb->db, "PRAGMA synchronous=OFF", 0, 0, 0);
} }
} }
} }
@@ -1219,6 +1220,58 @@ static void walthread5(int nMs){
print_and_free_err(&err); print_and_free_err(&err);
} }
/*------------------------------------------------------------------------
** Test case "cgt_pager_1"
*/
#define CALLGRINDTEST1_NROW 10000
static void cgt_pager_1_populate(Error *pErr, Sqlite *pDb){
const char *zInsert = "INSERT INTO t1 VALUES(:iRow, zeroblob(:iBlob))";
i64 iRow;
sql_script(pErr, pDb, "BEGIN");
for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
i64 iBlob = 600 + (iRow%300);
execsql(pErr, pDb, zInsert, &iRow, &iBlob);
}
sql_script(pErr, pDb, "COMMIT");
}
static void cgt_pager_1_update(Error *pErr, Sqlite *pDb){
const char *zUpdate = "UPDATE t1 SET b = zeroblob(:iBlob) WHERE a = :iRow";
i64 iRow;
sql_script(pErr, pDb, "BEGIN");
for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
i64 iBlob = 600 + ((iRow+100)%300);
execsql(pErr, pDb, zUpdate, &iBlob, &iRow);
}
sql_script(pErr, pDb, "COMMIT");
}
static void cgt_pager_1_read(Error *pErr, Sqlite *pDb){
i64 iRow;
sql_script(pErr, pDb, "BEGIN");
for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
execsql(pErr, pDb, "SELECT * FROM t1 WHERE a = :iRow", &iRow);
}
sql_script(pErr, pDb, "COMMIT");
}
static void cgt_pager_1(int nMs){
void (*xSub)(Error *, Sqlite *);
Error err = {0};
Sqlite db = {0};
opendb(&err, &db, "test.db", 1);
sql_script(&err, &db,
"PRAGMA cache_size = 2000;"
"PRAGMA page_size = 1024;"
"CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);"
);
xSub = cgt_pager_1_populate; xSub(&err, &db);
xSub = cgt_pager_1_update; xSub(&err, &db);
xSub = cgt_pager_1_read; xSub(&err, &db);
closedb(&err, &db);
print_and_free_err(&err);
}
int main(int argc, char **argv){ int main(int argc, char **argv){
struct ThreadTest { struct ThreadTest {
void (*xTest)(int); void (*xTest)(int);
@@ -1230,6 +1283,9 @@ int main(int argc, char **argv){
{ walthread3, "walthread3", 20000 }, { walthread3, "walthread3", 20000 },
{ walthread4, "walthread4", 20000 }, { walthread4, "walthread4", 20000 },
{ walthread5, "walthread5", 1000 }, { walthread5, "walthread5", 1000 },
{ walthread5, "walthread5", 1000 },
{ cgt_pager_1, "cgt_pager_1", 0 },
}; };
int i; int i;

View File

@@ -456,7 +456,7 @@ do_test wal2-6.1.5 {
SELECT * FROM t1; SELECT * FROM t1;
PRAGMA lock_status; PRAGMA lock_status;
} }
} {1 2 main exclusive temp closed} } {1 2 main shared temp closed}
do_test wal2-6.1.6 { do_test wal2-6.1.6 {
execsql { execsql {
INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(3, 4);
@@ -522,7 +522,7 @@ do_test wal2-6.2.8 {
SELECT * FROM t1; SELECT * FROM t1;
pragma lock_status; pragma lock_status;
} }
} {1 2 3 4 main exclusive temp closed} } {1 2 3 4 main shared temp closed}
do_test wal2-6.2.9 { do_test wal2-6.2.9 {
execsql { execsql {
INSERT INTO t1 VALUES(5, 6); INSERT INTO t1 VALUES(5, 6);
@@ -608,6 +608,11 @@ set READMARK1_SET {
set READMARK1_READ { set READMARK1_READ {
{4 1 lock shared} {4 1 unlock shared} {4 1 lock shared} {4 1 unlock shared}
} }
set READMARK1_WRITE {
{4 1 lock shared}
{0 1 lock exclusive} {0 1 unlock exclusive}
{4 1 unlock shared}
}
foreach {tn sql res expected_locks} { foreach {tn sql res expected_locks} {
2 { 2 {
@@ -664,13 +669,9 @@ foreach {tn sql res expected_locks} {
9 { 9 {
SELECT * FROM t1 ORDER BY x SELECT * FROM t1 ORDER BY x
} {Arthur {Julius Henry} Karl Leonard} { } } {Arthur {Julius Henry} Karl Leonard} $READMARK1_READ
10 { 10 { DELETE FROM t1 } {} $READMARK1_WRITE
DELETE FROM t1
} {} {
$READMARK1_READ
}
11 { 11 {
SELECT * FROM t1 SELECT * FROM t1
@@ -942,7 +943,6 @@ do_test wal2-10.2.2 {
set hdr [set_tvfs_hdr $::filename] set hdr [set_tvfs_hdr $::filename]
lindex $hdr 0 lindex $hdr 0
} {3007000} } {3007000}
breakpoint
do_test wal2-10.2.3 { do_test wal2-10.2.3 {
lset hdr 0 3007001 lset hdr 0 3007001
wal_fix_walindex_cksum hdr wal_fix_walindex_cksum hdr
@@ -1005,7 +1005,7 @@ if {$::tcl_version>=8.5} {
catchsql { SELECT * FROM t1 } db2 catchsql { SELECT * FROM t1 } db2
} {1 {database disk image is malformed}} } {1 {database disk image is malformed}}
} }
db close db close
db2 close db2 close
tvfs delete tvfs delete

View File

@@ -110,6 +110,11 @@ for {set i 1} {$i < 50} {incr i} {
db2 close db2 close
} }
proc byte_is_zero {file offset} {
if {[file size test.db] <= $offset} { return 1 }
expr { [hexio_read $file $offset 1] == "00" }
}
do_multiclient_test i { do_multiclient_test i {
set testname(1) multiproc set testname(1) multiproc
@@ -158,22 +163,24 @@ do_multiclient_test i {
COMMIT; COMMIT;
PRAGMA wal_checkpoint; PRAGMA wal_checkpoint;
} }
file size test.db byte_is_zero test.db [expr $AUTOVACUUM ? 4*1024 : 3*1024]
} [expr $AUTOVACUUM ? 4*1024 : 3*1024] } {1}
do_test wal3-2.$tn.5 { do_test wal3-2.$tn.5 {
sql2 { sql2 {
COMMIT; COMMIT;
PRAGMA wal_checkpoint; PRAGMA wal_checkpoint;
} }
file size test.db list [byte_is_zero test.db [expr $AUTOVACUUM ? 4*1024 : 3*1024]] \
} [expr $AUTOVACUUM ? 5*1024 : 4*1024] [byte_is_zero test.db [expr $AUTOVACUUM ? 5*1024 : 4*1024]]
} {0 1}
do_test wal3-2.$tn.6 { do_test wal3-2.$tn.6 {
sql3 { sql3 {
COMMIT; COMMIT;
PRAGMA wal_checkpoint; PRAGMA wal_checkpoint;
} }
file size test.db list [byte_is_zero test.db [expr $AUTOVACUUM ? 4*1024 : 3*1024]] \
} [expr $AUTOVACUUM ? 5*1024 : 4*1024] [byte_is_zero test.db [expr $AUTOVACUUM ? 5*1024 : 4*1024]]
} {0 1}
} }
catch {db close} catch {db close}
@@ -700,6 +707,7 @@ do_test wal3-9.0 {
file delete -force test.db test.db-journal test.db wal file delete -force test.db test.db-journal test.db wal
sqlite3 db test.db sqlite3 db test.db
execsql { execsql {
PRAGMA page_size = 1024;
PRAGMA journal_mode = WAL; PRAGMA journal_mode = WAL;
CREATE TABLE whoami(x); CREATE TABLE whoami(x);
INSERT INTO whoami VALUES('nobody'); INSERT INTO whoami VALUES('nobody');
@@ -722,15 +730,19 @@ for {set i 0} {$i < 50} {incr i} {
execsql { SELECT * FROM whoami } $c execsql { SELECT * FROM whoami } $c
} $c } $c
} }
set sz [expr 1024 * (2+$AUTOVACUUM)]
do_test wal3-9.3 { do_test wal3-9.3 {
for {set i 0} {$i < 49} {incr i} { db$i close } for {set i 0} {$i < 49} {incr i} { db$i close }
execsql { PRAGMA wal_checkpoint } execsql { PRAGMA wal_checkpoint }
set sz1 [file size test.db] byte_is_zero test.db [expr $sz-1024]
} {1}
do_test wal3-9.4 {
db49 close db49 close
execsql { PRAGMA wal_checkpoint } execsql { PRAGMA wal_checkpoint }
set sz2 [file size test.db] set sz2 [file size test.db]
expr {$sz2 > $sz1} byte_is_zero test.db [expr $sz-1024]
} {1} } {0}
db close db close

View File

@@ -377,4 +377,11 @@ sqlite3 db2 test.db2
do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 } {wal} do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 } {wal}
db2 close db2 close
do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {delete}
do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {delete}
do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL } {wal}
do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {wal}
do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {wal}
finish_test finish_test