Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c0fb9cf80 | |||
| 8f09f4b264 | |||
| 719506f9af | |||
| 7774fc010a | |||
| 47061b9d57 | |||
| 16fc5e67a0 | |||
| d4cc4d02cb | |||
| 362c181913 | |||
| 21b1c6ddac | |||
| e7c23433fb | |||
| e4e1af5efb | |||
| cfb5249622 | |||
| 37bbcb48a9 | |||
| 8cb63f5a5e | |||
| 6ac9a5cf5a | |||
| 33d28ab4cf | |||
| e8837211bc | |||
| eaad533e54 | |||
| 71c3ea7523 | |||
| 5f25627a1c | |||
| 9b2adcc3d1 | |||
| f76d287742 | |||
| 90385ddcf1 | |||
| be2d6fdd71 | |||
| 662bebb6bd | |||
| 075201e50f | |||
| 48b4bf269c | |||
| 9ce554baf7 | |||
| 60a2fc8244 | |||
| 7bf3d01a83 | |||
| 1bbfc6744c |
+1
-1
@@ -111,7 +111,7 @@ static const char jsonIsSpace[] = {
|
||||
# endif
|
||||
# define testcase(X)
|
||||
#endif
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
|
||||
# define VVA(X)
|
||||
#else
|
||||
# define VVA(X) X
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Add\sphase\sand\serror\snumber\sto\sCLI\serror\smessages.
|
||||
D 2021-10-26T16:57:09.903
|
||||
C Fix\sa\sminor\stypo\sin\sa\scomment.
|
||||
D 2021-11-02T10:54:39.370
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -306,7 +306,7 @@ F ext/misc/fileio.c 57fefd0efc535e62bb8b07fa146875171481da81a759bbfbe2fc91bab900
|
||||
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
|
||||
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
|
||||
F ext/misc/ieee754.c 91a5594071143a4ab79c638fe9f059af1db09932faf2e704c3e29216a7d4f511
|
||||
F ext/misc/json1.c 2ff65a8f97c9b8ae03124fe89a1b74197e68958882cb533daac8a694d1b81c57
|
||||
F ext/misc/json1.c 1ad9d8f04f60f7a7c99e6a22ecf84d8f9bc0881782bed6c3d3a7bc6bf0213e2d
|
||||
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
|
||||
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
|
||||
F ext/misc/memvfs.c 7dffa8cc89c7f2d73da4bd4ccea1bcbd2bd283e3bb4cea398df7c372a197291b
|
||||
@@ -490,7 +490,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
|
||||
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 004c647dfb5332ee4b56385f3ac264ebea781cb00f7a1561a48f4a45b78fed61
|
||||
F src/btree.c 2c8a52a7fd84b1aec4a79e7861b6368aecbf011a43247cc7d9a2946c7f0ae5ea
|
||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||
F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7
|
||||
F src/build.c 8bdda90f9b1189c7b0813575171b3c6b2d74b3ade57c11cb4383776781ea9335
|
||||
@@ -501,7 +501,7 @@ F src/date.c fa928630fecf1d436cdc7a7a5c950c781709023ca782c21b7a43cc7361a9451e
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
|
||||
F src/delete.c 0c151975fa99560767d7747f9b60543d0093d9f8b89f13d2d6058e9c83ad19e7
|
||||
F src/expr.c 529f7eca2821e874a375b1b318e697d62cb28f56069677c93f587f2de5dceb54
|
||||
F src/expr.c b882787df249b7de2f62c5c240ca8af2111839c761f1a5e9b8f501f940a9d92e
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 187b67af20c5795953a592832c5d985e4313fe503ebd8f95e3e9e9ad5a730bb5
|
||||
F src/func.c 1cfb09d7ffca81238eccefdb0293e1f5b7cfebbd1816dfad5ec6024742a7496b
|
||||
@@ -510,17 +510,17 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c b32e2dcbca838cb8acd4777a59243db4bcea53089e3181b0ea3e4dc75b43aeff
|
||||
F src/insert.c 3f2892de7820d8e0b34a90bff8a3e2f879bc528683fa2ebb9e779ae56b64b741
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e
|
||||
F src/main.c bfe067d61ebbd0e6eb023f1fb6b353021e621cf1657e061d629064a740bfbf6f
|
||||
F src/loadext.c e1dcff1c916bf6834e150b492eddda5d9792453182d2ad64294d2266b6e93c4c
|
||||
F src/main.c 546dd2418c4f5d59aced76c68e55290735feb420ee305051fbd55ab8fff0d255
|
||||
F src/malloc.c ef796bcc0e81d845d59a469f1cf235056caf9024172fd524e32136e65593647b
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75
|
||||
F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c ca36b36c497558abe8bf1fa6b6ad974db2275312ce30fc44e578e160688a7503
|
||||
F src/memdb.c a6c2bb1257c3398b4dd058f81888d647472b140bb1d262d47be50606eed75d55
|
||||
F src/memjournal.c a85f0dc5c02a42453d0bc3819ecfb5666cb6433e5deefcd93ccbe05c9f088b83
|
||||
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
|
||||
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
|
||||
@@ -529,7 +529,7 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c dd2b3f1cc1863079bc1349ac0fec395a500090c4fe4e11ab775310a49f2f956d
|
||||
F src/mutex_w32.c caa50e1c0258ac4443f52e00fe8aaea73b6d0728bd8856bedfff822cae418541
|
||||
F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6
|
||||
F src/os.c 91fc69f95ef0528368174dca20f01e1d8f82934f719e1cb50fd0260b18c028a6
|
||||
F src/os.c b1c4f2d485961e9a5b6b648c36687d25047c252222e9660b7cc25a6e1ea436ab
|
||||
F src/os.h 26890f540b475598cd9881dcc68931377b8d429d3ea3e2eeb64470cde64199f8
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
@@ -550,16 +550,16 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
||||
F src/resolve.c ae65c88f5d0d4bc0052b203773d407efa2387c2bd6b202f87178006c7bb8632c
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 32d25b5af6c708aa63373c78c2e59681910387a7a78c08ec3086cadc77d41627
|
||||
F src/shell.c.in 6aefb37d9c87da9e33ae7d3541d07a24c8b74a4bc7b805a2a367d92fe5709108
|
||||
F src/sqlite.h.in f0c1ecb5af508aa8e970cd8bc0ec851e6c380b81825038d458846c2fcdfcef50
|
||||
F src/shell.c.in de92da03b04734618508a968d719e30e4c4bcc53ec7f341cdbf6a3d68ce9721c
|
||||
F src/sqlite.h.in 99786216caf1c57aa3d70f95a7f84566dff6a9eeb50174799ea3b387eafd2a22
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
|
||||
F src/sqliteInt.h 317bbdf926ec7c391fb00bcaa1f82799836a1151568bd9d343f43c2cdf1a48b9
|
||||
F src/sqlite3ext.h d8f6f67ae9ad990a70dd03c093bcdc8883e159ff4bfd16a496f8fb80c6840b5a
|
||||
F src/sqliteInt.h 02f7ccc971d67d8641707f219b9c304113d43a9a128b73a39d1fcaa036c885b7
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 428e813dabf82804bc13196af35a0c3c6ef4347fe557fa6717c5c66bba6e8520
|
||||
F src/test1.c 63761c2be2607f1b425fde991beda48aed384f8d67f2b4ee549174c88b433009
|
||||
F src/test1.c bd1c3c2637db35c0a69513e008c0e6a177b360ccae7689e0bf69f15b55e24bae
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
|
||||
@@ -588,7 +588,7 @@ F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c 21121ea85b49ec0bdb69995847cef9036ef9beca3ce63bbb776e4ea2ecc44b97
|
||||
F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
|
||||
F src/test_multiplex.c 2ccf35551c094e353af20b0cdfac053a37bf3e96e10e7cf9f4abd1d279890a78
|
||||
F src/test_multiplex.c 1b23782212a01349fac382913ef82b8de4ae8a4cb46556602c2ee733edabbbc9
|
||||
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
||||
F src/test_mutex.c abf486e91bd65e2448027d4bb505e7cce6ba110e1afb9bd348d1996961cadf0d
|
||||
F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4
|
||||
@@ -620,20 +620,20 @@ F src/update.c 69c4c10bc6873a80c0a77cb578f9fc60ee90003d03f9530bc3370fa24615772d
|
||||
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 30df8356e231dad33be10bb27897655002668343280004ba28c734489414a167
|
||||
F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45
|
||||
F src/vdbe.c a80943ed189ed5f4215636bde0aa7901319b051baffc0706f93a786bdf49ffcf
|
||||
F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
|
||||
F src/vdbe.c 54089e5ebb02d35e52d6b3d51061b79b8923c70e839df4ca4ff7bd9bcb9b9708
|
||||
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
|
||||
F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b
|
||||
F src/vdbeapi.c 7b83468feb1d42a09d4c2e5241a3eaa3d1f138e289a843cba9fd3f1dad95ca67
|
||||
F src/vdbeaux.c a57c760d1897f1b72f6fae26983df363db7a2c42d88721187e907f2c84862b42
|
||||
F src/vdbeblob.c 292e96c01c4219fca71d74e1002906d43eb232af4bd83f7552a3faec741f3eb8
|
||||
F src/vdbemem.c 8be0af1060012520381d3296fcb1718e80cd5b99ce04f51f7e1c4dba4072caac
|
||||
F src/vdbesort.c 04292f8c569dc9ad2afc1d56d118f2cfab36ca65a3f02eef0b5b92bda01560be
|
||||
F src/vdbemem.c 71a449c57be10a66a8a5620e5c5a67ebb9ca70121556dc631ffd4c4458708d8c
|
||||
F src/vdbesort.c 513b481c8bab4a6578c92194a60cf3bc3b48736e4a53f8d2d7918121c5b594e7
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
|
||||
F src/vtab.c d07cc24dd84b0b51bf05adb187b0d2e6b0cac56cfbc0197995a26d4f8fa5c7e2
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c
|
||||
F src/wal.c 6ae14d4797f31c67fc2be659d24fbc6e1a6f5f423bdfb5ef831ea171bce42320
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c ecabef93b0f14442a73eca205fc960428984d75fbdc7d60226b7fc9cac127187
|
||||
@@ -705,7 +705,8 @@ F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
F test/autoindex3.test 2d13958a5617e987624a428d7aed91bf51f322b49b476e3573fadec697ce6da5
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autoindex5.test 2ee94f033b87ca0160e08d81034c507aff8e230df2627f0304fa309b2fee19a3
|
||||
F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9
|
||||
F test/autovacuum.test 00671369bbf96c6a49989a9425f5b78b94075d6a4b031e5e00000c2c32f365df
|
||||
F test/autovacuum2.test 76f7eb4fe6a6bf6d33a196a7141dba98886d2fb53a268d7feca285d5da4759d7
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avfs.test 0c3a38e03cccb0fc3127838462dc05dc3f4c1480d770c084b388304c25de3652
|
||||
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
|
||||
@@ -1055,7 +1056,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c 5773a888c10080da4a3174b19136631a787735a0ee44aa1bc0078384b2caeb13
|
||||
F test/fuzzcheck.c 7a07718e3c017f31e88b56a891bb79a3eb42a413a811fd65b89a7b09fdd1adbd
|
||||
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1063,7 +1064,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
|
||||
F test/fuzzdata8.db e12b57c30566b9511ed8760eeccfb23e6361db9c43092032252e922ed942d67c
|
||||
F test/fuzzdata8.db ea80e98f115387b052effb7194899cc9780a81f15606bc4641051342352020cc
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
|
||||
@@ -1222,7 +1223,7 @@ F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e
|
||||
F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93
|
||||
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
|
||||
F test/mmapwarm.test 2272005969cd17a910077bd5082f70bc1fefad9a875afec7fc9af483898ecaf3
|
||||
F test/multiplex.test dc0d67b66f84b484a83cb8bbdf3f0a7f49562ccd
|
||||
F test/multiplex.test d74c034e52805f6de8cc5432cef8c9eb774bb64ec29b83a22effc8ca4dac1f08
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
|
||||
@@ -1380,10 +1381,10 @@ F test/shell1.test c354008b27c904f0166c2138abd7382013ea070b41114114ecbdfb32c726a
|
||||
F test/shell2.test f00a0501c00583cbc46f7510e1d713366326b2b3e63d06d15937284171a8787c
|
||||
F test/shell3.test cb4b835a901742c9719437a89171172ecc4a8823ad97349af8e4e841e6f82566
|
||||
F test/shell4.test 3ed6c4b42fd695efcbc25d69ef759dbb15855ca8e52ba6c5ee076f8b435f48be
|
||||
F test/shell5.test 84a30b55722a95a5b72989e691c469a999ca7591e7aa00b7fabc783ea5c9a6fe
|
||||
F test/shell5.test 6e4aa0e531dcb8dcf74b7920a2a7442c6712d4dff8422bbc81f768f9dee8a0e3
|
||||
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
|
||||
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
|
||||
F test/shell8.test 96be02ea0c21f05b24c1883d7b711a1fa8525a68ab7b636aacf6057876941013
|
||||
F test/shell8.test 388471d16e4de767333107e30653983f186232c0e863f4490bb230419e830aae
|
||||
F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
@@ -1681,7 +1682,7 @@ F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568
|
||||
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
|
||||
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
|
||||
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
|
||||
F test/vacuum-into.test 48f4cec354fb6f27c98ef58d2fe49a11b71ff131af0cd9140efacc9858b9f670
|
||||
F test/vacuum-into.test c4c25dcf8ca909e33c1f5f0bb0f54b990c2c1dcbee7a4995843e79e40681a894
|
||||
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||
F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520
|
||||
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
||||
@@ -1929,10 +1930,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 4b41535b096dec4b15a85e657102a72d4288728da6103f3fdcbe0e6f244c673a
|
||||
R 0e943f95c783da0ea080484e06b0d01a
|
||||
T *branch * detail_cli_errors
|
||||
T *sym-detail_cli_errors *
|
||||
T -sym-trunk *
|
||||
U larrybr
|
||||
Z 75e901f51a636f4c844fe34247eb3a80
|
||||
P 13fb74ac5e7578ab612af2ccc8147569d60dc35af84f496bcc5d648d223d6d6e
|
||||
R 4ce534086d91ce8438a18251677b33c8
|
||||
U drh
|
||||
Z fc893d2685db3ae6f19a712413bc458d
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
7f87a298688c37bbad8fd2e1cf0e8fbcc36f0c211dcfa3685298525648dbe21b
|
||||
06a5bf4348d3125bb5407fe9b7d451800b113a91fd1a9dff7d840e2317a7284d
|
||||
+40
-13
@@ -3939,16 +3939,18 @@ int sqlite3BtreeIncrVacuum(Btree *p){
|
||||
/*
|
||||
** This routine is called prior to sqlite3PagerCommit when a transaction
|
||||
** is committed for an auto-vacuum database.
|
||||
**
|
||||
** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
|
||||
** the database file should be truncated to during the commit process.
|
||||
** i.e. the database has been reorganized so that only the first *pnTrunc
|
||||
** pages are in use.
|
||||
*/
|
||||
static int autoVacuumCommit(BtShared *pBt){
|
||||
static int autoVacuumCommit(Btree *p){
|
||||
int rc = SQLITE_OK;
|
||||
Pager *pPager = pBt->pPager;
|
||||
VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
|
||||
Pager *pPager;
|
||||
BtShared *pBt;
|
||||
sqlite3 *db;
|
||||
VVA_ONLY( int nRef );
|
||||
|
||||
assert( p!=0 );
|
||||
pBt = p->pBt;
|
||||
pPager = pBt->pPager;
|
||||
VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); )
|
||||
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
invalidateAllOverflowCache(pBt);
|
||||
@@ -3956,6 +3958,7 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
if( !pBt->incrVacuum ){
|
||||
Pgno nFin; /* Number of pages in database after autovacuuming */
|
||||
Pgno nFree; /* Number of pages on the freelist initially */
|
||||
Pgno nVac; /* Number of pages to vacuum */
|
||||
Pgno iFree; /* The next page to be freed */
|
||||
Pgno nOrig; /* Database size before freeing */
|
||||
|
||||
@@ -3969,18 +3972,42 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
}
|
||||
|
||||
nFree = get4byte(&pBt->pPage1->aData[36]);
|
||||
nFin = finalDbSize(pBt, nOrig, nFree);
|
||||
db = p->db;
|
||||
if( db->xAutovacPages ){
|
||||
int iDb;
|
||||
for(iDb=0; ALWAYS(iDb<db->nDb); iDb++){
|
||||
if( db->aDb[iDb].pBt==p ) break;
|
||||
}
|
||||
nVac = db->xAutovacPages(
|
||||
db->pAutovacPagesArg,
|
||||
db->aDb[iDb].zDbSName,
|
||||
nOrig,
|
||||
nFree,
|
||||
pBt->pageSize
|
||||
);
|
||||
if( nVac>nFree ){
|
||||
nVac = nFree;
|
||||
}
|
||||
if( nVac==0 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}else{
|
||||
nVac = nFree;
|
||||
}
|
||||
nFin = finalDbSize(pBt, nOrig, nVac);
|
||||
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
|
||||
if( nFin<nOrig ){
|
||||
rc = saveAllCursors(pBt, 0, 0);
|
||||
}
|
||||
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
|
||||
rc = incrVacuumStep(pBt, nFin, iFree, 1);
|
||||
rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree);
|
||||
}
|
||||
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
put4byte(&pBt->pPage1->aData[32], 0);
|
||||
put4byte(&pBt->pPage1->aData[36], 0);
|
||||
if( nVac==nFree ){
|
||||
put4byte(&pBt->pPage1->aData[32], 0);
|
||||
put4byte(&pBt->pPage1->aData[36], 0);
|
||||
}
|
||||
put4byte(&pBt->pPage1->aData[28], nFin);
|
||||
pBt->bDoTruncate = 1;
|
||||
pBt->nPage = nFin;
|
||||
@@ -4031,7 +4058,7 @@ int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){
|
||||
sqlite3BtreeEnter(p);
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( pBt->autoVacuum ){
|
||||
rc = autoVacuumCommit(pBt);
|
||||
rc = autoVacuumCommit(p);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3BtreeLeave(p);
|
||||
return rc;
|
||||
|
||||
+1
-1
@@ -1748,7 +1748,7 @@ Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
|
||||
return pRet;
|
||||
}
|
||||
#else
|
||||
Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
|
||||
Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
|
||||
assert( p==0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
+5
-3
@@ -2327,7 +2327,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
|
||||
assert( onError==OE_Replace );
|
||||
nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
|
||||
assert( nConflictCk>0 );
|
||||
assert( nConflictCk>0 || db->mallocFailed );
|
||||
testcase( nConflictCk<=0 );
|
||||
testcase( nConflictCk>1 );
|
||||
if( regTrigCnt ){
|
||||
sqlite3MultiWrite(pParse);
|
||||
@@ -2613,8 +2614,9 @@ int sqlite3OpenTableAndIndices(
|
||||
assert( op==OP_OpenWrite || p5==0 );
|
||||
if( IsVirtual(pTab) ){
|
||||
/* This routine is a no-op for virtual tables. Leave the output
|
||||
** variables *piDataCur and *piIdxCur uninitialized so that valgrind
|
||||
** can detect if they are used by mistake in the caller. */
|
||||
** variables *piDataCur and *piIdxCur set to illegal cursor numbers
|
||||
** for improved error detection. */
|
||||
*piDataCur = *piIdxCur = -999;
|
||||
return 0;
|
||||
}
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
|
||||
|
||||
@@ -483,6 +483,8 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_changes64,
|
||||
sqlite3_total_changes64,
|
||||
/* Version 3.37.0 and later */
|
||||
sqlite3_autovacuum_pages,
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
|
||||
+31
@@ -1403,6 +1403,9 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
** structure?
|
||||
*/
|
||||
sqlite3DbFree(db, db->aDb[1].pSchema);
|
||||
if( db->xAutovacDestr ){
|
||||
db->xAutovacDestr(db->pAutovacPagesArg);
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
db->eOpenState = SQLITE_STATE_CLOSED;
|
||||
sqlite3_mutex_free(db->mutex);
|
||||
@@ -2304,6 +2307,34 @@ void *sqlite3_preupdate_hook(
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
/*
|
||||
** Register a function to be invoked prior to each autovacuum that
|
||||
** determines the number of pages to vacuum.
|
||||
*/
|
||||
int sqlite3_autovacuum_pages(
|
||||
sqlite3 *db, /* Attach the hook to this database */
|
||||
unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
|
||||
void *pArg, /* Argument to the function */
|
||||
void (*xDestructor)(void*) /* Destructor for pArg */
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
if( xDestructor ) xDestructor(pArg);
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( db->xAutovacDestr ){
|
||||
db->xAutovacDestr(db->pAutovacPagesArg);
|
||||
}
|
||||
db->xAutovacPages = xCallback;
|
||||
db->pAutovacPagesArg = pArg;
|
||||
db->xAutovacDestr = xDestructor;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
|
||||
|
||||
@@ -505,6 +505,7 @@ static int memdbOpen(
|
||||
MemFile *pFile = (MemFile*)pFd;
|
||||
MemStore *p = 0;
|
||||
int szName;
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
|
||||
memset(pFile, 0, sizeof(*pFile));
|
||||
szName = sqlite3Strlen30(zName);
|
||||
|
||||
@@ -316,12 +316,15 @@ int sqlite3OsOpenMalloc(
|
||||
rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pFile);
|
||||
*ppFile = 0;
|
||||
}else{
|
||||
*ppFile = pFile;
|
||||
}
|
||||
}else{
|
||||
*ppFile = 0;
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
assert( *ppFile!=0 || rc!=SQLITE_OK );
|
||||
return rc;
|
||||
}
|
||||
void sqlite3OsCloseFree(sqlite3_file *pFile){
|
||||
|
||||
+84
-19
@@ -3965,6 +3965,7 @@ static const char *(azHelp[]) = {
|
||||
" -c, --create Create a new archive",
|
||||
" -u, --update Add or update files with changed mtime",
|
||||
" -i, --insert Like -u but always add even if unchanged",
|
||||
" -r, --remove Remove files from archive",
|
||||
" -t, --list List contents of archive",
|
||||
" -x, --extract Extract files from archive",
|
||||
" Optional arguments:",
|
||||
@@ -3972,6 +3973,7 @@ static const char *(azHelp[]) = {
|
||||
" -f FILE, --file FILE Use archive FILE (default is current db)",
|
||||
" -a FILE, --append FILE Open FILE using the apndvfs VFS",
|
||||
" -C DIR, --directory DIR Read/extract files from directory DIR",
|
||||
" -g, --glob Use glob matching for names in archive",
|
||||
" -n, --dryrun Show the SQL that would have occurred",
|
||||
" Examples:",
|
||||
" .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
|
||||
@@ -6132,6 +6134,7 @@ struct ArCommand {
|
||||
u8 bZip; /* True if the archive is a ZIP */
|
||||
u8 bDryRun; /* True if --dry-run */
|
||||
u8 bAppend; /* True if --append */
|
||||
u8 bGlob; /* True if --glob */
|
||||
u8 fromCmdLine; /* Run from -A instead of .archive */
|
||||
int nArg; /* Number of command arguments */
|
||||
char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
|
||||
@@ -6179,21 +6182,24 @@ static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
|
||||
#define AR_CMD_EXTRACT 4
|
||||
#define AR_CMD_LIST 5
|
||||
#define AR_CMD_HELP 6
|
||||
#define AR_CMD_REMOVE 7
|
||||
|
||||
/*
|
||||
** Other (non-command) switches.
|
||||
*/
|
||||
#define AR_SWITCH_VERBOSE 7
|
||||
#define AR_SWITCH_FILE 8
|
||||
#define AR_SWITCH_DIRECTORY 9
|
||||
#define AR_SWITCH_APPEND 10
|
||||
#define AR_SWITCH_DRYRUN 11
|
||||
#define AR_SWITCH_VERBOSE 8
|
||||
#define AR_SWITCH_FILE 9
|
||||
#define AR_SWITCH_DIRECTORY 10
|
||||
#define AR_SWITCH_APPEND 11
|
||||
#define AR_SWITCH_DRYRUN 12
|
||||
#define AR_SWITCH_GLOB 13
|
||||
|
||||
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
|
||||
switch( eSwitch ){
|
||||
case AR_CMD_CREATE:
|
||||
case AR_CMD_EXTRACT:
|
||||
case AR_CMD_LIST:
|
||||
case AR_CMD_REMOVE:
|
||||
case AR_CMD_UPDATE:
|
||||
case AR_CMD_INSERT:
|
||||
case AR_CMD_HELP:
|
||||
@@ -6206,6 +6212,9 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
|
||||
case AR_SWITCH_DRYRUN:
|
||||
pAr->bDryRun = 1;
|
||||
break;
|
||||
case AR_SWITCH_GLOB:
|
||||
pAr->bGlob = 1;
|
||||
break;
|
||||
case AR_SWITCH_VERBOSE:
|
||||
pAr->bVerbose = 1;
|
||||
break;
|
||||
@@ -6244,6 +6253,7 @@ static int arParseCommand(
|
||||
{ "extract", 'x', AR_CMD_EXTRACT, 0 },
|
||||
{ "insert", 'i', AR_CMD_INSERT, 0 },
|
||||
{ "list", 't', AR_CMD_LIST, 0 },
|
||||
{ "remove", 'r', AR_CMD_REMOVE, 0 },
|
||||
{ "update", 'u', AR_CMD_UPDATE, 0 },
|
||||
{ "help", 'h', AR_CMD_HELP, 0 },
|
||||
{ "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
|
||||
@@ -6251,6 +6261,7 @@ static int arParseCommand(
|
||||
{ "append", 'a', AR_SWITCH_APPEND, 1 },
|
||||
{ "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
|
||||
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
|
||||
{ "glob", 'g', AR_SWITCH_GLOB, 0 },
|
||||
};
|
||||
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
|
||||
struct ArSwitch *pEnd = &aSwitch[nSwitch];
|
||||
@@ -6367,11 +6378,13 @@ static int arParseCommand(
|
||||
|
||||
/*
|
||||
** This function assumes that all arguments within the ArCommand.azArg[]
|
||||
** array refer to archive members, as for the --extract or --list commands.
|
||||
** It checks that each of them are present. If any specified file is not
|
||||
** present in the archive, an error is printed to stderr and an error
|
||||
** code returned. Otherwise, if all specified arguments are present in
|
||||
** the archive, SQLITE_OK is returned.
|
||||
** array refer to archive members, as for the --extract, --list or --remove
|
||||
** commands. It checks that each of them are "present". If any specified
|
||||
** file is not present in the archive, an error is printed to stderr and an
|
||||
** error code returned. Otherwise, if all specified arguments are present
|
||||
** in the archive, SQLITE_OK is returned. Here, "present" means either an
|
||||
** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
|
||||
** when pAr->bGlob is true.
|
||||
**
|
||||
** This function strips any trailing '/' characters from each argument.
|
||||
** This is consistent with the way the [tar] command seems to work on
|
||||
@@ -6382,11 +6395,11 @@ static int arCheckEntries(ArCommand *pAr){
|
||||
if( pAr->nArg ){
|
||||
int i, j;
|
||||
sqlite3_stmt *pTest = 0;
|
||||
const char *zSel = (pAr->bGlob)
|
||||
? "SELECT name FROM %s WHERE glob($name,name)"
|
||||
: "SELECT name FROM %s WHERE name=$name";
|
||||
|
||||
shellPreparePrintf(pAr->db, &rc, &pTest,
|
||||
"SELECT name FROM %s WHERE name=$name",
|
||||
pAr->zSrcTable
|
||||
);
|
||||
shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
|
||||
j = sqlite3_bind_parameter_index(pTest, "$name");
|
||||
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
||||
char *z = pAr->azArg[i];
|
||||
@@ -6414,14 +6427,16 @@ static int arCheckEntries(ArCommand *pAr){
|
||||
** identify all archive members that match the command arguments held
|
||||
** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
|
||||
** The caller is responsible for eventually calling sqlite3_free() on
|
||||
** any non-NULL (*pzWhere) value.
|
||||
** any non-NULL (*pzWhere) value. Here, "match" means strict equality
|
||||
** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
|
||||
*/
|
||||
static void arWhereClause(
|
||||
int *pRc,
|
||||
ArCommand *pAr,
|
||||
ArCommand *pAr,
|
||||
char **pzWhere /* OUT: New WHERE clause */
|
||||
){
|
||||
char *zWhere = 0;
|
||||
const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
|
||||
if( *pRc==SQLITE_OK ){
|
||||
if( pAr->nArg==0 ){
|
||||
zWhere = sqlite3_mprintf("1");
|
||||
@@ -6431,8 +6446,8 @@ static void arWhereClause(
|
||||
for(i=0; i<pAr->nArg; i++){
|
||||
const char *z = pAr->azArg[i];
|
||||
zWhere = sqlite3_mprintf(
|
||||
"%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
|
||||
zWhere, zSep, z, strlen30(z)+1, z
|
||||
"%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
|
||||
zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
|
||||
);
|
||||
if( zWhere==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
@@ -6486,6 +6501,47 @@ static int arListCommand(ArCommand *pAr){
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Implementation of .ar "Remove" command.
|
||||
*/
|
||||
static int arRemoveCommand(ArCommand *pAr){
|
||||
int rc = 0;
|
||||
char *zSql = 0;
|
||||
char *zWhere = 0;
|
||||
|
||||
if( pAr->nArg ){
|
||||
/* Verify that args actually exist within the archive before proceeding.
|
||||
** And formulate a WHERE clause to match them. */
|
||||
rc = arCheckEntries(pAr);
|
||||
arWhereClause(&rc, pAr, &zWhere);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
|
||||
pAr->zSrcTable, zWhere);
|
||||
if( pAr->bDryRun ){
|
||||
utf8_printf(pAr->p->out, "%s\n", zSql);
|
||||
}else{
|
||||
char *zErr = 0;
|
||||
rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
|
||||
}else{
|
||||
rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
|
||||
}
|
||||
}
|
||||
if( zErr ){
|
||||
utf8_printf(stdout, "ERROR: %s\n", zErr);
|
||||
sqlite3_free(zErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_free(zWhere);
|
||||
sqlite3_free(zSql);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of .ar "eXtract" command.
|
||||
*/
|
||||
@@ -6738,7 +6794,7 @@ static int arDotCommand(
|
||||
int flags;
|
||||
if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
|
||||
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
|
||||
|| cmd.eCmd==AR_CMD_UPDATE ){
|
||||
|| cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
|
||||
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||
}else{
|
||||
flags = SQLITE_OPEN_READONLY;
|
||||
@@ -6794,6 +6850,10 @@ static int arDotCommand(
|
||||
rc = arCreateOrUpdateCommand(&cmd, 1, 0);
|
||||
break;
|
||||
|
||||
case AR_CMD_REMOVE:
|
||||
rc = arRemoveCommand(&cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( cmd.eCmd==AR_CMD_UPDATE );
|
||||
rc = arCreateOrUpdateCommand(&cmd, 1, 1);
|
||||
@@ -8282,6 +8342,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
failIfSafeMode(p, "cannot run .import in safe mode");
|
||||
memset(&sCtx, 0, sizeof(sCtx));
|
||||
sCtx.z = sqlite3_malloc64(120);
|
||||
if( sCtx.z==0 ){
|
||||
import_cleanup(&sCtx);
|
||||
shell_out_of_memory();
|
||||
}
|
||||
if( p->mode==MODE_Ascii ){
|
||||
xRead = ascii_read_one_field;
|
||||
}else{
|
||||
|
||||
@@ -6406,6 +6406,72 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
|
||||
void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
|
||||
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Autovacuum Compaction Amount Callback
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
|
||||
** function C that is invoked prior to each autovacuum of the database
|
||||
** file. ^The callback is passed a copy of the generic data pointer (P),
|
||||
** the schema-name of the attached database that is being autovacuumed,
|
||||
** the the size of the database file in pages, the number of free pages,
|
||||
** and the number of bytes per page, respectively. The callback should
|
||||
** return the number of free pages that should be removed by the
|
||||
** autovacuum. ^If the callback returns zero, then no autovacuum happens.
|
||||
** ^If the value returned is greater than or equal to the number of
|
||||
** free pages, then a complete autovacuum happens.
|
||||
**
|
||||
** <p>^If there are multiple ATTACH-ed database files that are being
|
||||
** modified as part of a transaction commit, then the autovacuum pages
|
||||
** callback is invoked separately for each file.
|
||||
**
|
||||
** <p><b>The callback is not reentrant.</b> The callback function should
|
||||
** not attempt to invoke any other SQLite interface. If it does, bad
|
||||
** things may happen, including segmentation faults and corrupt database
|
||||
** files. The callback function should be a simple function that
|
||||
** does some arithmetic on its input parameters and returns a result.
|
||||
**
|
||||
** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
|
||||
** destructor for the P parameter. ^If X is not NULL, then X(P) is
|
||||
** invoked whenever the database connection closes or when the callback
|
||||
** is overwritten by another invocation of sqlite3_autovacuum_pages().
|
||||
**
|
||||
** <p>^There is only one autovacuum pages callback per database connection.
|
||||
** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
|
||||
** previous invocations for that database connection. ^If the callback
|
||||
** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
|
||||
** then the autovacuum steps callback is cancelled. The return value
|
||||
** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
|
||||
** be some other error code if something goes wrong. The current
|
||||
** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
|
||||
** return codes might be added in future releases.
|
||||
**
|
||||
** <p>If no autovacuum pages callback is specified (the usual case) or
|
||||
** a NULL pointer is provided for the callback,
|
||||
** then the default behavior is to vacuum all free pages. So, in other
|
||||
** words, the default behavior is the same as if the callback function
|
||||
** were something like this:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** unsigned int demonstration_autovac_pages_callback(
|
||||
** void *pClientData,
|
||||
** const char *zSchema,
|
||||
** unsigned int nDbPage,
|
||||
** unsigned int nFreePage,
|
||||
** unsigned int nBytePerPage
|
||||
** ){
|
||||
** return nFreePage;
|
||||
** }
|
||||
** </pre></blockquote>
|
||||
*/
|
||||
int sqlite3_autovacuum_pages(
|
||||
sqlite3 *db,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*,
|
||||
void(*)(void*)
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
** CAPI3REF: Data Change Notification Callbacks
|
||||
** METHOD: sqlite3
|
||||
|
||||
@@ -340,6 +340,10 @@ struct sqlite3_api_routines {
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_int64 (*changes64)(sqlite3*);
|
||||
sqlite3_int64 (*total_changes64)(sqlite3*);
|
||||
/* Version 3.37.0 and later */
|
||||
int (*autovacuum_pages)(sqlite3*,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*, void(*)(void*));
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -646,6 +650,11 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
/* Version 3.36.1 and later */
|
||||
#define sqlite3_changes64 sqlite3_api->changes64
|
||||
#define sqlite3_total_changes64 sqlite3_api->total_changes64
|
||||
* Version 3.37.0 and later */
|
||||
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
@@ -1566,6 +1566,9 @@ struct sqlite3 {
|
||||
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
|
||||
void *pUpdateArg;
|
||||
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
|
||||
void *pAutovacPagesArg; /* Client argument to autovac_pages */
|
||||
void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
|
||||
unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
|
||||
Parse *pParse; /* Current parse */
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
|
||||
|
||||
+91
@@ -8233,6 +8233,96 @@ static int SQLITE_TCLAPI test_decode_hexdb(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Client data for the autovacuum_pages callback.
|
||||
*/
|
||||
struct AutovacPageData {
|
||||
Tcl_Interp *interp;
|
||||
char *zScript;
|
||||
};
|
||||
typedef struct AutovacPageData AutovacPageData;
|
||||
|
||||
/*
|
||||
** Callback functions for sqlite3_autovacuum_pages
|
||||
*/
|
||||
static unsigned int test_autovacuum_pages_callback(
|
||||
void *pClientData,
|
||||
const char *zSchema,
|
||||
unsigned int nFilePages,
|
||||
unsigned int nFreePages,
|
||||
unsigned int nBytePerPage
|
||||
){
|
||||
AutovacPageData *pData = (AutovacPageData*)pClientData;
|
||||
Tcl_DString str;
|
||||
unsigned int x;
|
||||
char zBuf[100];
|
||||
Tcl_DStringInit(&str);
|
||||
Tcl_DStringAppend(&str, pData->zScript, -1);
|
||||
Tcl_DStringAppendElement(&str, zSchema);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%u", nFilePages);
|
||||
Tcl_DStringAppendElement(&str, zBuf);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%u", nFreePages);
|
||||
Tcl_DStringAppendElement(&str, zBuf);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%u", nBytePerPage);
|
||||
Tcl_DStringAppendElement(&str, zBuf);
|
||||
Tcl_ResetResult(pData->interp);
|
||||
Tcl_Eval(pData->interp, Tcl_DStringValue(&str));
|
||||
Tcl_DStringFree(&str);
|
||||
x = nFreePages;
|
||||
(void)Tcl_GetIntFromObj(0, Tcl_GetObjResult(pData->interp), (int*)&x);
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_autovacuum_pages DB SCRIPT
|
||||
**
|
||||
** Add an autovacuum-pages callback to database connection DB. The callback
|
||||
** will invoke SCRIPT, after appending parameters.
|
||||
**
|
||||
** If SCRIPT is an empty string or is omitted, then the callback is
|
||||
** cancelled.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_autovacuum_pages(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
AutovacPageData *pData;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
const char *zScript;
|
||||
if( objc!=2 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB ?SCRIPT?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zScript = objc==3 ? Tcl_GetString(objv[2]) : 0;
|
||||
if( zScript ){
|
||||
size_t nScript = strlen(zScript);
|
||||
pData = sqlite3_malloc64( sizeof(*pData) + nScript + 1 );
|
||||
if( pData==0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pData->interp = interp;
|
||||
pData->zScript = (char*)&pData[1];
|
||||
memcpy(pData->zScript, zScript, nScript+1);
|
||||
rc = sqlite3_autovacuum_pages(db,test_autovacuum_pages_callback,
|
||||
pData, sqlite3_free);
|
||||
}else{
|
||||
rc = sqlite3_autovacuum_pages(db, 0, 0, 0);
|
||||
}
|
||||
if( rc ){
|
||||
char zBuf[1000];
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf,
|
||||
"sqlite3_autovacuum_pages() returns %d", rc);
|
||||
Tcl_AppendResult(interp, zBuf, (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
@@ -8524,6 +8614,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "atomic_batch_write", test_atomic_batch_write, 0 },
|
||||
{ "sqlite3_mmap_warm", test_mmap_warm, 0 },
|
||||
{ "sqlite3_config_sorterref", test_config_sorterref, 0 },
|
||||
{ "sqlite3_autovacuum_pages", test_autovacuum_pages, 0 },
|
||||
{ "decode_hexdb", test_decode_hexdb, 0 },
|
||||
{ "test_write_db", test_write_db, 0 },
|
||||
{ "sqlite3_register_cksumvfs", test_register_cksumvfs, 0 },
|
||||
|
||||
+72
-19
@@ -962,26 +962,79 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|
||||
** element is the argument to the pragma or NULL if the pragma has no
|
||||
** argument.
|
||||
*/
|
||||
if( aFcntl[1] && sqlite3_stricmp(aFcntl[1],"multiplex_truncate")==0 ){
|
||||
if( aFcntl[2] && aFcntl[2][0] ){
|
||||
if( sqlite3_stricmp(aFcntl[2], "on")==0
|
||||
|| sqlite3_stricmp(aFcntl[2], "1")==0 ){
|
||||
pGroup->bTruncate = 1;
|
||||
}else
|
||||
if( sqlite3_stricmp(aFcntl[2], "off")==0
|
||||
|| sqlite3_stricmp(aFcntl[2], "0")==0 ){
|
||||
pGroup->bTruncate = 0;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-27806-26076 The handler for an SQLITE_FCNTL_PRAGMA
|
||||
** file control can optionally make the first element of the char**
|
||||
** argument point to a string obtained from sqlite3_mprintf() or the
|
||||
** equivalent and that string will become the result of the pragma
|
||||
** or the error message if the pragma fails.
|
||||
if( aFcntl[1] && sqlite3_strnicmp(aFcntl[1],"multiplex_",10)==0 ){
|
||||
sqlite3_int64 sz = 0;
|
||||
(void)multiplexFileSize(pConn, &sz);
|
||||
/*
|
||||
** PRAGMA multiplex_truncate=BOOLEAN;
|
||||
** PRAGMA multiplex_truncate;
|
||||
**
|
||||
** Turn the multiplexor truncate feature on or off. Return either
|
||||
** "on" or "off" to indicate the new setting. If the BOOLEAN argument
|
||||
** is omitted, just return the current value for the truncate setting.
|
||||
*/
|
||||
aFcntl[0] = sqlite3_mprintf(pGroup->bTruncate ? "on" : "off");
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
if( sqlite3_stricmp(aFcntl[1],"multiplex_truncate")==0 ){
|
||||
if( aFcntl[2] && aFcntl[2][0] ){
|
||||
if( sqlite3_stricmp(aFcntl[2], "on")==0
|
||||
|| sqlite3_stricmp(aFcntl[2], "1")==0 ){
|
||||
pGroup->bTruncate = 1;
|
||||
}else
|
||||
if( sqlite3_stricmp(aFcntl[2], "off")==0
|
||||
|| sqlite3_stricmp(aFcntl[2], "0")==0 ){
|
||||
pGroup->bTruncate = 0;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-27806-26076 The handler for an SQLITE_FCNTL_PRAGMA
|
||||
** file control can optionally make the first element of the char**
|
||||
** argument point to a string obtained from sqlite3_mprintf() or the
|
||||
** equivalent and that string will become the result of the pragma
|
||||
** or the error message if the pragma fails.
|
||||
*/
|
||||
aFcntl[0] = sqlite3_mprintf(pGroup->bTruncate ? "on" : "off");
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
** PRAGMA multiplex_enabled;
|
||||
**
|
||||
** Return 0 or 1 depending on whether the multiplexor is enabled or
|
||||
** disabled, respectively.
|
||||
*/
|
||||
if( sqlite3_stricmp(aFcntl[1],"multiplex_enabled")==0 ){
|
||||
aFcntl[0] = sqlite3_mprintf("%d", pGroup->bEnabled!=0);
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
** PRAGMA multiplex_chunksize;
|
||||
**
|
||||
** Return the chunksize for the multiplexor, or no-op if the
|
||||
** multiplexor is not active.
|
||||
*/
|
||||
if( sqlite3_stricmp(aFcntl[1],"multiplex_chunksize")==0
|
||||
&& pGroup->bEnabled
|
||||
){
|
||||
aFcntl[0] = sqlite3_mprintf("%u", pGroup->szChunk);
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
** PRAGMA multiplex_filecount;
|
||||
**
|
||||
** Return the number of disk files currently in use by the
|
||||
** multiplexor. This should be the total database size size
|
||||
** divided by the chunksize and rounded up.
|
||||
*/
|
||||
if( sqlite3_stricmp(aFcntl[1],"multiplex_filecount")==0 ){
|
||||
int n = 0;
|
||||
int ii;
|
||||
for(ii=0; ii<pGroup->nReal; ii++){
|
||||
if( pGroup->aReal[ii].p!=0 ) n++;
|
||||
}
|
||||
aFcntl[0] = sqlite3_mprintf("%d", n);
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If the multiplexor does not handle the pragma, pass it through
|
||||
** into the default case. */
|
||||
|
||||
+3
-1
@@ -250,7 +250,9 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
|
||||
/* Do not attempt to change the page size for a WAL database */
|
||||
if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
|
||||
==PAGER_JOURNALMODE_WAL ){
|
||||
==PAGER_JOURNALMODE_WAL
|
||||
&& pOut==0
|
||||
){
|
||||
db->nextPagesize = 0;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -3656,6 +3656,7 @@ case OP_Transaction: {
|
||||
assert( pOp->p2>=0 && pOp->p2<=2 );
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, pOp->p1) );
|
||||
assert( rc==SQLITE_OK );
|
||||
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
|
||||
rc = SQLITE_READONLY;
|
||||
goto abort_due_to_error;
|
||||
@@ -3699,7 +3700,8 @@ case OP_Transaction: {
|
||||
}
|
||||
}
|
||||
assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
|
||||
if( pOp->p5
|
||||
if( rc==SQLITE_OK
|
||||
&& pOp->p5
|
||||
&& (iMeta!=pOp->p3
|
||||
|| db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
|
||||
){
|
||||
|
||||
@@ -374,6 +374,8 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
||||
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
|
||||
return SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
assert( pMem->z!=0 );
|
||||
assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
|
||||
|
||||
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
|
||||
pMem->n += pMem->u.nZero;
|
||||
|
||||
@@ -2007,6 +2007,7 @@ static int vdbeIncrMergerNew(
|
||||
vdbeMergeEngineFree(pMerger);
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
assert( *ppOut!=0 || rc!=SQLITE_OK );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -620,9 +620,13 @@ struct WalIterator {
|
||||
** so. It is safe to enlarge the wal-index if pWal->writeLock is true
|
||||
** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
|
||||
**
|
||||
** If this call is successful, *ppPage is set to point to the wal-index
|
||||
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
|
||||
** then an SQLite error code is returned and *ppPage is set to 0.
|
||||
** Three possible result scenarios:
|
||||
**
|
||||
** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
|
||||
** (2) rc>=SQLITE_ERROR and *ppPage==NULL
|
||||
** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0
|
||||
**
|
||||
** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
|
||||
*/
|
||||
static SQLITE_NOINLINE int walIndexPageRealloc(
|
||||
Wal *pWal, /* The WAL context */
|
||||
@@ -655,7 +659,9 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
|
||||
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
|
||||
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
|
||||
);
|
||||
assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
|
||||
assert( pWal->apWiData[iPage]!=0
|
||||
|| rc!=SQLITE_OK
|
||||
|| (pWal->writeLock==0 && iPage==0) );
|
||||
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
|
||||
if( rc==SQLITE_OK ){
|
||||
if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
|
||||
@@ -994,8 +1000,8 @@ struct WalHashLoc {
|
||||
** slot in the hash table is set to N, it refers to frame number
|
||||
** (pLoc->iZero+N) in the log.
|
||||
**
|
||||
** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
|
||||
** first frame indexed by the hash table, frame (pLoc->iZero+1).
|
||||
** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the
|
||||
** first frame indexed by the hash table, frame (pLoc->iZero).
|
||||
*/
|
||||
static int walHashGet(
|
||||
Wal *pWal, /* WAL handle */
|
||||
@@ -1007,7 +1013,7 @@ static int walHashGet(
|
||||
rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
|
||||
assert( rc==SQLITE_OK || iHash>0 );
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pLoc->aPgno ){
|
||||
pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
|
||||
if( iHash==0 ){
|
||||
pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
|
||||
@@ -1015,7 +1021,8 @@ static int walHashGet(
|
||||
}else{
|
||||
pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
|
||||
}
|
||||
pLoc->aPgno = &pLoc->aPgno[-1];
|
||||
}else if( NEVER(rc==SQLITE_OK) ){
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1097,8 +1104,9 @@ static void walCleanupHash(Wal *pWal){
|
||||
/* Zero the entries in the aPgno array that correspond to frames with
|
||||
** frame numbers greater than pWal->hdr.mxFrame.
|
||||
*/
|
||||
nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
|
||||
memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
|
||||
nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]);
|
||||
assert( nByte>=0 );
|
||||
memset((void *)&sLoc.aPgno[iLimit], 0, nByte);
|
||||
|
||||
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
/* Verify that the every entry in the mapping region is still reachable
|
||||
@@ -1107,11 +1115,11 @@ static void walCleanupHash(Wal *pWal){
|
||||
if( iLimit ){
|
||||
int j; /* Loop counter */
|
||||
int iKey; /* Hash key */
|
||||
for(j=1; j<=iLimit; j++){
|
||||
for(j=0; j<iLimit; j++){
|
||||
for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
|
||||
if( sLoc.aHash[iKey]==j ) break;
|
||||
if( sLoc.aHash[iKey]==j+1 ) break;
|
||||
}
|
||||
assert( sLoc.aHash[iKey]==j );
|
||||
assert( sLoc.aHash[iKey]==j+1 );
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
|
||||
@@ -1143,9 +1151,9 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
|
||||
** entire hash table and aPgno[] array before proceeding.
|
||||
*/
|
||||
if( idx==1 ){
|
||||
int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
|
||||
- (u8 *)&sLoc.aPgno[1]);
|
||||
memset((void*)&sLoc.aPgno[1], 0, nByte);
|
||||
int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno);
|
||||
assert( nByte>=0 );
|
||||
memset((void*)sLoc.aPgno, 0, nByte);
|
||||
}
|
||||
|
||||
/* If the entry in aPgno[] is already set, then the previous writer
|
||||
@@ -1154,9 +1162,9 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
|
||||
** Remove the remnants of that writers uncommitted transaction from
|
||||
** the hash-table before writing any new entries.
|
||||
*/
|
||||
if( sLoc.aPgno[idx] ){
|
||||
if( sLoc.aPgno[idx-1] ){
|
||||
walCleanupHash(pWal);
|
||||
assert( !sLoc.aPgno[idx] );
|
||||
assert( !sLoc.aPgno[idx-1] );
|
||||
}
|
||||
|
||||
/* Write the aPgno[] array entry and the hash-table slot. */
|
||||
@@ -1164,7 +1172,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
|
||||
for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
|
||||
if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
sLoc.aPgno[idx] = iPage;
|
||||
sLoc.aPgno[idx-1] = iPage;
|
||||
AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
|
||||
|
||||
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
@@ -1185,19 +1193,18 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
|
||||
*/
|
||||
if( (idx&0x3ff)==0 ){
|
||||
int i; /* Loop counter */
|
||||
for(i=1; i<=idx; i++){
|
||||
for(i=0; i<idx; i++){
|
||||
for(iKey=walHash(sLoc.aPgno[i]);
|
||||
sLoc.aHash[iKey];
|
||||
iKey=walNextHash(iKey)){
|
||||
if( sLoc.aHash[iKey]==i ) break;
|
||||
if( sLoc.aHash[iKey]==i+1 ) break;
|
||||
}
|
||||
assert( sLoc.aHash[iKey]==i );
|
||||
assert( sLoc.aHash[iKey]==i+1 );
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1318,7 +1325,8 @@ static int walIndexRecover(Wal *pWal){
|
||||
u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
|
||||
u32 nHdr, nHdr32;
|
||||
rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
|
||||
if( rc ) break;
|
||||
assert( aShare!=0 || rc!=SQLITE_OK );
|
||||
if( aShare==0 ) break;
|
||||
pWal->apWiData[iPg] = aPrivate;
|
||||
|
||||
for(iFrame=iFirst; iFrame<=iLast; iFrame++){
|
||||
@@ -1815,7 +1823,6 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
|
||||
int nEntry; /* Number of entries in this segment */
|
||||
ht_slot *aIndex; /* Sorted index for this segment */
|
||||
|
||||
sLoc.aPgno++;
|
||||
if( (i+1)==nSegment ){
|
||||
nEntry = (int)(iLast - sLoc.iZero);
|
||||
}else{
|
||||
@@ -2954,7 +2961,8 @@ int sqlite3WalSnapshotRecover(Wal *pWal){
|
||||
|
||||
rc = walHashGet(pWal, walFramePage(i), &sLoc);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
pgno = sLoc.aPgno[i-sLoc.iZero];
|
||||
assert( i - sLoc.iZero - 1 >=0 );
|
||||
pgno = sLoc.aPgno[i-sLoc.iZero-1];
|
||||
iDbOff = (i64)(pgno-1) * szPage;
|
||||
|
||||
if( iDbOff+szPage<=szDb ){
|
||||
@@ -3187,7 +3195,7 @@ int sqlite3WalFindFrame(
|
||||
iKey = walHash(pgno);
|
||||
while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
|
||||
u32 iFrame = iH + sLoc.iZero;
|
||||
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
|
||||
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){
|
||||
assert( iFrame>iRead || CORRUPT_DB );
|
||||
iRead = iFrame;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the SELECT statement.
|
||||
# focus of this file is testing the autovacuum feature.
|
||||
#
|
||||
# $Id: autovacuum.test,v 1.29 2009/04/06 17:50:03 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# 2021-10-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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the sqlite3_autovacuum_pages() interface
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# If this build of the library does not support auto-vacuum, omit this
|
||||
# whole file.
|
||||
ifcapable {!autovacuum || !pragma} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# Demonstrate basic sqlite3_autovacuum_pages functionality
|
||||
#
|
||||
do_execsql_test autovacuum2-1.0 {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA auto_vacuum=FULL;
|
||||
CREATE TABLE t1(x);
|
||||
VACUUM;
|
||||
INSERT INTO t1(x) VALUES(zeroblob(10000));
|
||||
PRAGMA page_count;
|
||||
} {12}
|
||||
proc autovac_page_callback {schema filesize freesize pagesize} {
|
||||
global autovac_callback_data
|
||||
lappend autovac_callback_data $schema $filesize $freesize $pagesize
|
||||
return [expr {$freesize/2}]
|
||||
}
|
||||
sqlite3_autovacuum_pages db autovac_page_callback
|
||||
set autovac_callback_data {}
|
||||
do_execsql_test autovacuum2-1.1 {
|
||||
BEGIN;
|
||||
DELETE FROM t1;
|
||||
PRAGMA freelist_count;
|
||||
PRAGMA page_count;
|
||||
} {9 12}
|
||||
do_execsql_test autovacuum2-1.2 {
|
||||
COMMIT;
|
||||
} {}
|
||||
do_test autovacuum2-1.3 {
|
||||
set autovac_callback_data
|
||||
} {main 12 9 1024}
|
||||
do_execsql_test autovacuum2-1.4 {
|
||||
PRAGMA freelist_count;
|
||||
PRAGMA page_count;
|
||||
} {5 8}
|
||||
do_execsql_test autovacuum2-1.5 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# Disable the autovacuum-pages callback. Then do any transaction.
|
||||
# The database should shrink to minimal size
|
||||
#
|
||||
sqlite3_autovacuum_pages db
|
||||
do_execsql_test autovacuum2-1.10 {
|
||||
CREATE TABLE t2(x);
|
||||
PRAGMA freelist_count;
|
||||
} {0}
|
||||
|
||||
# Rig the autovacuum-pages callback to always return zero. No
|
||||
# autovacuum will happen.
|
||||
#
|
||||
proc autovac_page_callback_off {schema filesize freesize pagesize} {
|
||||
return 0
|
||||
}
|
||||
sqlite3_autovacuum_pages db autovac_page_callback_off
|
||||
do_execsql_test autovacuum2-1.20 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(x) VALUES(zeroblob(10000));
|
||||
DELETE FROM t1;
|
||||
PRAGMA freelist_count;
|
||||
COMMIT;
|
||||
PRAGMA freelist_count;
|
||||
} {9 9}
|
||||
|
||||
finish_test
|
||||
+188
-26
@@ -302,6 +302,108 @@ static VFile *createVFile(const char *zName, int sz, unsigned char *pData){
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/* Return true if the line is all zeros */
|
||||
static int allZero(unsigned char *aLine){
|
||||
int i;
|
||||
for(i=0; i<16 && aLine[i]==0; i++){}
|
||||
return i==16;
|
||||
}
|
||||
|
||||
/*
|
||||
** Render a database and query as text that can be input into
|
||||
** the CLI.
|
||||
*/
|
||||
static void renderDbSqlForCLI(
|
||||
FILE *out, /* Write to this file */
|
||||
const char *zFile, /* Name of the database file */
|
||||
unsigned char *aDb, /* Database content */
|
||||
int nDb, /* Number of bytes in aDb[] */
|
||||
unsigned char *zSql, /* SQL content */
|
||||
int nSql /* Bytes of SQL */
|
||||
){
|
||||
fprintf(out, ".print ******* %s *******\n", zFile);
|
||||
if( nDb>100 ){
|
||||
int i, j; /* Loop counters */
|
||||
int pgsz; /* Size of each page */
|
||||
int lastPage = 0; /* Last page number shown */
|
||||
int iPage; /* Current page number */
|
||||
unsigned char *aLine; /* Single line to display */
|
||||
unsigned char buf[16]; /* Fake line */
|
||||
unsigned char bShow[256]; /* Characters ok to display */
|
||||
|
||||
memset(bShow, '.', sizeof(bShow));
|
||||
for(i=' '; i<='~'; i++){
|
||||
if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = i;
|
||||
}
|
||||
pgsz = (aDb[16]<<8) | aDb[17];
|
||||
if( pgsz==0 ) pgsz = 65536;
|
||||
if( pgsz<512 || (pgsz&(pgsz-1))!=0 ) pgsz = 4096;
|
||||
fprintf(out,".open --hexdb\n");
|
||||
fprintf(out,"| size %d pagesize %d filename %s\n",nDb,pgsz,zFile);
|
||||
for(i=0; i<nDb; i += 16){
|
||||
if( i+16>nDb ){
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, aDb+i, nDb-i);
|
||||
aLine = buf;
|
||||
}else{
|
||||
aLine = aDb + i;
|
||||
}
|
||||
if( allZero(aLine) ) continue;
|
||||
iPage = i/pgsz + 1;
|
||||
if( lastPage!=iPage ){
|
||||
fprintf(out,"| page %d offset %d\n", iPage, (iPage-1)*pgsz);
|
||||
lastPage = iPage;
|
||||
}
|
||||
fprintf(out,"| %5d:", i-(iPage-1)*pgsz);
|
||||
for(j=0; j<16; j++) fprintf(out," %02x", aLine[j]);
|
||||
fprintf(out," ");
|
||||
for(j=0; j<16; j++){
|
||||
unsigned char c = (unsigned char)aLine[j];
|
||||
fputc( bShow[c], stdout);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
fprintf(out,"| end %s\n", zFile);
|
||||
}else{
|
||||
fprintf(out,".open :memory:\n");
|
||||
}
|
||||
fprintf(out,".testctrl prng_seed 1 db\n");
|
||||
fprintf(out,".testctrl internal_functions\n");
|
||||
fprintf(out,"%.*s", nSql, zSql);
|
||||
if( nSql>0 && zSql[nSql-1]!='\n' ) fprintf(out, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the complete content of a file into memory. Add a 0x00 terminator
|
||||
** and return a pointer to the result.
|
||||
**
|
||||
** The file content is held in memory obtained from sqlite_malloc64() which
|
||||
** should be freed by the caller.
|
||||
*/
|
||||
static char *readFile(const char *zFilename, long *sz){
|
||||
FILE *in;
|
||||
long nIn;
|
||||
unsigned char *pBuf;
|
||||
|
||||
*sz = 0;
|
||||
if( zFilename==0 ) return 0;
|
||||
in = fopen(zFilename, "rb");
|
||||
if( in==0 ) return 0;
|
||||
fseek(in, 0, SEEK_END);
|
||||
*sz = nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc64( nIn+1 );
|
||||
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
|
||||
pBuf[nIn] = 0;
|
||||
fclose(in);
|
||||
return (char*)pBuf;
|
||||
}
|
||||
sqlite3_free(pBuf);
|
||||
*sz = 0;
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Implementation of the "readfile(X)" SQL function. The entire content
|
||||
@@ -313,25 +415,15 @@ static void readfileFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const char *zName;
|
||||
FILE *in;
|
||||
long nIn;
|
||||
void *pBuf;
|
||||
const char *zName = (const char*)sqlite3_value_text(argv[0]);
|
||||
|
||||
zName = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zName==0 ) return;
|
||||
in = fopen(zName, "rb");
|
||||
if( in==0 ) return;
|
||||
fseek(in, 0, SEEK_END);
|
||||
nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc64( nIn );
|
||||
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
|
||||
pBuf = readFile(zName, &nIn);
|
||||
if( pBuf ){
|
||||
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pBuf);
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -855,7 +947,13 @@ static int runDbSql(sqlite3 *db, const char *zSql){
|
||||
}
|
||||
|
||||
/* Invoke this routine to run a single test case */
|
||||
int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte, int iTimeout){
|
||||
int runCombinedDbSqlInput(
|
||||
const uint8_t *aData, /* Combined DB+SQL content */
|
||||
size_t nByte, /* Size of aData in bytes */
|
||||
int iTimeout, /* Use this timeout */
|
||||
int bScript, /* If true, just render CLI output */
|
||||
int iSqlId /* SQL identifier */
|
||||
){
|
||||
int rc; /* SQLite API return value */
|
||||
int iSql; /* Index in aData[] of start of SQL */
|
||||
unsigned char *aDb = 0; /* Decoded database content */
|
||||
@@ -881,6 +979,14 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte, int iTimeout){
|
||||
iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
|
||||
if( iSql<0 ) return 0;
|
||||
nSql = (int)(nByte - iSql);
|
||||
if( bScript ){
|
||||
char zName[100];
|
||||
sqlite3_snprintf(sizeof(zName),zName,"dbsql%06d.db",iSqlId);
|
||||
renderDbSqlForCLI(stdout, zName, aDb, nDb,
|
||||
(unsigned char*)(aData+iSql), nSql);
|
||||
sqlite3_free(aDb);
|
||||
return 0;
|
||||
}
|
||||
if( eVerbosity>=3 ){
|
||||
printf(
|
||||
"****** %d-byte input, %d-byte database, %d-byte script "
|
||||
@@ -984,7 +1090,7 @@ testrun_finished:
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stdout, "sqlite3_close() returns %d\n", rc);
|
||||
}
|
||||
if( eVerbosity>=2 ){
|
||||
if( eVerbosity>=2 && !bScript ){
|
||||
fprintf(stdout, "Peak memory usages: %f MB\n",
|
||||
sqlite3_memory_highwater(1) / 1000000.0);
|
||||
}
|
||||
@@ -1458,6 +1564,7 @@ static void showHelp(void){
|
||||
" -q|--quiet Reduced output\n"
|
||||
" --rebuild Rebuild and vacuum the database file\n"
|
||||
" --result-trace Show the results of each SQL command\n"
|
||||
" --script Output CLI script instead of running tests\n"
|
||||
" --skip N Skip the first N test cases\n"
|
||||
" --spinner Use a spinner to show progress\n"
|
||||
" --sqlid N Use only SQL where sqlid=N\n"
|
||||
@@ -1487,6 +1594,7 @@ int main(int argc, char **argv){
|
||||
int vdbeLimitFlag = 0; /* --limit-vdbe */
|
||||
int infoFlag = 0; /* --info */
|
||||
int nSkip = 0; /* --skip */
|
||||
int bScript = 0; /* --script */
|
||||
int bSpinner = 0; /* True for --spinner */
|
||||
int timeoutTest = 0; /* undocumented --timeout-test flag */
|
||||
int runFlags = 0; /* Flags sent to runSql() */
|
||||
@@ -1585,7 +1693,7 @@ int main(int argc, char **argv){
|
||||
}else
|
||||
if( strcmp(z,"load-dbsql")==0 ){
|
||||
zInsSql = "INSERT INTO xsql(sqltext)"
|
||||
"VALUES(CAST(readtextfile(?1) AS text))";
|
||||
"VALUES(readfile(?1))";
|
||||
iFirstInsArg = i+1;
|
||||
openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||
dbSqlOnly = 1;
|
||||
@@ -1621,6 +1729,9 @@ int main(int argc, char **argv){
|
||||
if( strcmp(z,"result-trace")==0 ){
|
||||
runFlags |= SQL_OUTPUT;
|
||||
}else
|
||||
if( strcmp(z,"script")==0 ){
|
||||
bScript = 1;
|
||||
}else
|
||||
if( strcmp(z,"skip")==0 ){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
nSkip = atoi(argv[++i]);
|
||||
@@ -1669,6 +1780,16 @@ int main(int argc, char **argv){
|
||||
}
|
||||
return 0;
|
||||
}else
|
||||
if( strcmp(z,"is-dbsql")==0 ){
|
||||
i++;
|
||||
for(i++; i<argc; i++){
|
||||
long nData;
|
||||
char *aData = readFile(argv[i], &nData);
|
||||
printf("%d %s\n", isDbSql((unsigned char*)aData,nData), argv[i]);
|
||||
sqlite3_free(aData);
|
||||
}
|
||||
exit(0);
|
||||
}else
|
||||
{
|
||||
fatalError("unknown option: %s", argv[i]);
|
||||
}
|
||||
@@ -1690,12 +1811,21 @@ int main(int argc, char **argv){
|
||||
|
||||
/* Process each source database separately */
|
||||
for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
|
||||
char *zRawData = 0;
|
||||
long nRawData = 0;
|
||||
g.zDbFile = azSrcDb[iSrcDb];
|
||||
rc = sqlite3_open_v2(azSrcDb[iSrcDb], &db,
|
||||
openFlags4Data, pDfltVfs->zName);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_exec(db, "SELECT count(*) FROM sqlite_schema", 0, 0, 0);
|
||||
}
|
||||
if( rc ){
|
||||
fatalError("cannot open source database %s - %s",
|
||||
azSrcDb[iSrcDb], sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
zRawData = readFile(azSrcDb[iSrcDb], &nRawData);
|
||||
if( zRawData==0 ){
|
||||
fatalError("input file \"%s\" is not recognized\n", azSrcDb[iSrcDb]);
|
||||
}
|
||||
sqlite3_open(":memory:", &db);
|
||||
}
|
||||
|
||||
/* Print the description, if there is one */
|
||||
@@ -1730,6 +1860,7 @@ int main(int argc, char **argv){
|
||||
sqlite3_finalize(pStmt);
|
||||
printf("\n");
|
||||
sqlite3_close(db);
|
||||
sqlite3_free(zRawData);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1754,6 +1885,21 @@ int main(int argc, char **argv){
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) fatalError("cannot change description: %s", sqlite3_errmsg(db));
|
||||
}
|
||||
if( zRawData ){
|
||||
zInsSql = "INSERT INTO xsql(sqltext) VALUES(?1)";
|
||||
rc = sqlite3_prepare_v2(db, zInsSql, -1, &pStmt, 0);
|
||||
if( rc ) fatalError("cannot prepare statement [%s]: %s",
|
||||
zInsSql, sqlite3_errmsg(db));
|
||||
sqlite3_bind_text(pStmt, 1, zRawData, nRawData, SQLITE_STATIC);
|
||||
sqlite3_step(pStmt);
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( rc ) fatalError("insert failed for %s", argv[i]);
|
||||
sqlite3_finalize(pStmt);
|
||||
rebuild_database(db, dbSqlOnly);
|
||||
zInsSql = 0;
|
||||
sqlite3_free(zRawData);
|
||||
zRawData = 0;
|
||||
}
|
||||
ossFuzzThisDb = ossFuzz;
|
||||
|
||||
/* If the CONFIG(name,value) table exists, read db-specific settings
|
||||
@@ -1884,7 +2030,7 @@ int main(int argc, char **argv){
|
||||
}
|
||||
|
||||
/* Print the description, if there is one */
|
||||
if( !quietFlag ){
|
||||
if( !quietFlag && !bScript ){
|
||||
zDbName = azSrcDb[iSrcDb];
|
||||
i = (int)strlen(zDbName) - 1;
|
||||
while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; }
|
||||
@@ -1941,12 +2087,16 @@ int main(int argc, char **argv){
|
||||
|
||||
/* Run a test using each SQL script against each database.
|
||||
*/
|
||||
if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
|
||||
if( !verboseFlag && !quietFlag && !bSpinner && !bScript ){
|
||||
printf("%s:", zDbName);
|
||||
}
|
||||
for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
|
||||
tmStart = timeOfDay();
|
||||
if( isDbSql(pSql->a, pSql->sz) ){
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
|
||||
if( bSpinner ){
|
||||
if( bScript ){
|
||||
/* No progress output */
|
||||
}else if( bSpinner ){
|
||||
int nTotal =g.nSql;
|
||||
int idx = pSql->seq;
|
||||
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
|
||||
@@ -1967,10 +2117,10 @@ int main(int argc, char **argv){
|
||||
if( nSkip>0 ){
|
||||
nSkip--;
|
||||
}else{
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout);
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout, bScript, pSql->id);
|
||||
}
|
||||
nTest++;
|
||||
if( bTimer ){
|
||||
if( bTimer && !bScript ){
|
||||
sqlite3_int64 tmEnd = timeOfDay();
|
||||
printf("%lld %s\n", tmEnd - tmStart, g.zTestName);
|
||||
}
|
||||
@@ -1983,7 +2133,9 @@ int main(int argc, char **argv){
|
||||
const char *zVfs = "inmem";
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
|
||||
pSql->id, pDb->id);
|
||||
if( bSpinner ){
|
||||
if( bScript ){
|
||||
/* No progress output */
|
||||
}else if( bSpinner ){
|
||||
int nTotal = g.nDb*g.nSql;
|
||||
int idx = pSql->seq*g.nDb + pDb->id - 1;
|
||||
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
|
||||
@@ -2005,6 +2157,14 @@ int main(int argc, char **argv){
|
||||
nSkip--;
|
||||
continue;
|
||||
}
|
||||
if( bScript ){
|
||||
char zName[100];
|
||||
sqlite3_snprintf(sizeof(zName), zName, "db%06d.db",
|
||||
pDb->id>1 ? pDb->id : pSql->id);
|
||||
renderDbSqlForCLI(stdout, zName,
|
||||
pDb->a, pDb->sz, pSql->a, pSql->sz);
|
||||
continue;
|
||||
}
|
||||
createVFile("main.db", pDb->sz, pDb->a);
|
||||
sqlite3_randomness(0,0);
|
||||
if( ossFuzzThisDb ){
|
||||
@@ -2077,7 +2237,9 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
}
|
||||
if( bSpinner ){
|
||||
if( bScript ){
|
||||
/* No progress output */
|
||||
}else if( bSpinner ){
|
||||
int nTotal = g.nDb*g.nSql;
|
||||
printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal);
|
||||
}else if( !quietFlag && !verboseFlag ){
|
||||
@@ -2093,7 +2255,7 @@ int main(int argc, char **argv){
|
||||
|
||||
} /* End loop over all source databases */
|
||||
|
||||
if( !quietFlag ){
|
||||
if( !quietFlag && !bScript ){
|
||||
sqlite3_int64 iElapse = timeOfDay() - iBegin;
|
||||
printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\n"
|
||||
"SQLite %s %s\n",
|
||||
|
||||
Binary file not shown.
@@ -182,6 +182,11 @@ do_test multiplex-2.1.3 { file size [multiplex_name test.x 0] } {4096}
|
||||
do_test multiplex-2.1.4 {
|
||||
execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
|
||||
} {}
|
||||
do_execsql_test multiplex-2.1.5 {
|
||||
PRAGMA multiplex_enabled;
|
||||
PRAGMA multiplex_filecount;
|
||||
PRAGMA multiplex_chunksize;
|
||||
} {1 1 2147418112}
|
||||
|
||||
do_test multiplex-2.2.1 {
|
||||
execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
|
||||
@@ -267,6 +272,18 @@ do_test multiplex-2.5.8 {
|
||||
|
||||
do_test multiplex-2.5.9 { file size [multiplex_name test.x 0] } [list $g_chunk_size]
|
||||
do_test multiplex-2.5.10 { file size [multiplex_name test.x 1] } [list $g_chunk_size]
|
||||
do_execsql_test multiplex-2.5.11 {
|
||||
PRAGMA multiplex_enabled;
|
||||
PRAGMA multiplex_filecount;
|
||||
PRAGMA multiplex_chunksize;
|
||||
} {1 3 65536}
|
||||
sqlite3 db test.x
|
||||
do_execsql_test multiplex-2.5.12 {
|
||||
PRAGMA multiplex_filecount;
|
||||
PRAGMA multiplex_chunksize;
|
||||
} {3 65536}
|
||||
|
||||
|
||||
|
||||
do_test multiplex-2.5.99 {
|
||||
db close
|
||||
|
||||
@@ -456,4 +456,19 @@ CREATE TABLE t7(a, b, c);
|
||||
db eval { SELECT * FROM t7 ORDER BY a }
|
||||
} {1 2 3 4 5 {} 6 7 8}
|
||||
|
||||
do_test shell5-4.3 {
|
||||
forcedelete shell5.csv
|
||||
set fd [open shell5.csv w]
|
||||
puts $fd ",,"
|
||||
puts $fd "1,2,3"
|
||||
close $fd
|
||||
catchcmd test.db [string trim {
|
||||
.mode csv
|
||||
CREATE TABLE t8(a, b, c);
|
||||
.import -skip 1 shell5.csv t8
|
||||
.nullvalue #
|
||||
}]
|
||||
db eval { SELECT * FROM t8 }
|
||||
} {1 2 3}
|
||||
|
||||
finish_test
|
||||
|
||||
+22
-3
@@ -44,6 +44,10 @@ proc populate_dir {dirname spec} {
|
||||
}
|
||||
}
|
||||
|
||||
proc dir_content {dirname} {
|
||||
lsort [glob -nocomplain $dirname/*]
|
||||
}
|
||||
|
||||
proc dir_to_list {dirname {n -1}} {
|
||||
if {$n<0} {set n [llength [file split $dirname]]}
|
||||
|
||||
@@ -170,8 +174,23 @@ foreach {tn tcl} {
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
do_test 2.1.1 {
|
||||
populate_dir ar2 {
|
||||
file1 "abcd"
|
||||
file2 "efgh"
|
||||
junk1 "j1"
|
||||
junk2 "j2"
|
||||
dir1/file3 "ijkl"
|
||||
}
|
||||
populate_dir ar4 {
|
||||
file2 "efgh"
|
||||
}
|
||||
catchcmd shell8.db {.ar -c}
|
||||
catchcmd shell8.db {.ar -C ar2 -i .}
|
||||
catchcmd shell8.db {.ar -r ./file2 ./dir1}
|
||||
catchcmd shell8.db {.ar -g -r ./ju*2}
|
||||
catchcmd shell8.db {.ar -C ar4 -x .}
|
||||
regsub -all {ar4} [dir_content ar4] ar2
|
||||
} {ar2/file1 ar2/file2 ar2/junk1}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -100,4 +100,35 @@ do_test vacuum-into-510 {
|
||||
db2 close
|
||||
db close
|
||||
|
||||
# Change the page-size on a VACUUM INTO even if the original
|
||||
# database is in WAL mode.
|
||||
#
|
||||
forcedelete test.db
|
||||
forcedelete test.db2
|
||||
do_test vacuum-into-600 {
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
PRAGMA page_size=4096;
|
||||
PRAGMA journal_mode=WAL;
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES(19);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {wal ok}
|
||||
do_execsql_test vacuum-into-610 {
|
||||
PRAGMA page_size;
|
||||
} {4096}
|
||||
do_execsql_test vacuum-into-620 {
|
||||
PRAGMA page_size=1024;
|
||||
VACUUM INTO 'test.db2';
|
||||
} {}
|
||||
do_test vacuum-into-630 {
|
||||
sqlite3 db test.db2
|
||||
db eval {
|
||||
PRAGMA page_size;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {1024 ok}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user