]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge recent trunk enhancements into the begin-concurrent-report branch.
authordrh <>
Tue, 3 Aug 2021 17:05:35 +0000 (17:05 +0000)
committerdrh <>
Tue, 3 Aug 2021 17:05:35 +0000 (17:05 +0000)
FossilOrigin-Name: 385e3b4e9d7245e892f54a4d69fa7a78b1eeb565ae01a6fbabb5b7396ea07d17

1  2 
manifest
manifest.uuid
src/btree.c
src/btree.h
src/insert.c
src/main.c
src/sqlite.h.in
src/sqliteInt.h
src/vdbe.c
src/vdbeInt.h
src/wherecode.c

diff --cc manifest
index 4782edf829b8d1a78b6baf7139573155aef0313b,e02de3e5c817f969d914d436067d09ad48c9481e..e8158e62dac7109e2da6c8cc752867dcc36f2bf4
+++ b/manifest
@@@ -1,5 -1,5 +1,5 @@@
- C Merge\srecent\strunk\senhancements\sinto\sbegin-concurrent-report\svia\sbegin-concurrent-pnu.
- D 2021-06-17T17:38:13.609
 -C Merge\srecent\strunk\schanges\sinto\sthe\sbegin-concurrent-pnu\sbranch.
 -D 2021-08-03T16:49:31.193
++C Merge\srecent\strunk\senhancements\sinto\sthe\sbegin-concurrent-report\sbranch.
++D 2021-08-03T17:05:35.401
  F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
  F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
  F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@@ -484,20 -483,20 +484,20 @@@ F spec.template 86a4a43b99ebb3e75e6b9a7
  F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
  F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
  F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
- F src/alter.c 774a2a175ec747b55046ec62f5c1208d730ee22b10bdad5f182591fa247946a8
- F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
+ F src/alter.c 3ce23a6f06a789de05e0bfd581f9dd6367a50135def2688cfd0af78675cae676
+ F src/analyze.c abbaaf7dca79d1c31c713500324fc0b55bf3eeac5b7b07001452a3d0f210de4f
  F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929
- F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
+ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
 -F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
 -F src/bitvec.c 8433d9e98dd6f2ea3286e0d2fe5d65de1bfc18a706486eb2026b01be066b5806
 +F src/backup.c 0d3f5004d5c85f257add00aee97687d40790a471a5d56306043ed9a7b53d6994
 +F src/bitvec.c a012cfe503cddd1df1a75c139baf4586acc32f25c66f79039caf1d06474434f2
  F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
- F src/btree.c 183bb926c8b9be6b6099612f50cc0735e8d4300ea58e08617592210a78101107
- F src/btree.h 888d9cea384478728e1e475e1660bd4138e3ec635f1b430e3f57e88d9c81d2fe
 -F src/btree.c 0003bd8a3a04dea14edc0343d37a1a2eeb44b297a2d6d37930417b09a2fbc8f1
 -F src/btree.h 900067641b64d619e6e2a93bd115c952a52f41d3bee32e551e2a4ceee05fc431
 -F src/btreeInt.h 1e9f10107a4ec5d2940ae5b859242ae83b81402986724bed08b8491a5ea64a4d
++F src/btree.c fc2953cb196793714f7c76ab4618c286e1b2586cdd85d3108421047370843d32
++F src/btree.h 1c1508834794c0d15fe15d23792cd42deefd8140ad782899eab258d081a0adfc
 +F src/btreeInt.h b8c4dee39e4cbe127a6cf479f32e345e186db63923e937b5f42807c76bfd8e9d
- F src/build.c 22e91195f1fafdde9e181167a983efe859232947bf40f173e1b82f02c6ad21a0
+ F src/build.c 71d07b1b5eef2cb4ca3f0eafbb92d9faf56661db6e2dcc3a442f839bcd2c06fe
  F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
  F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
- F src/ctime.c 3052b6b05ed9ef547a3dd66b8e01bfa9d582e78752ad6ed327da84652641e038
+ F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1
  F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
  F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
  F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
@@@ -511,10 -510,10 +511,10 @@@ F src/hash.c 8d7dda241d0ebdafb6ffdeda31
  F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
  F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
  F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
- F src/insert.c 7c7ef7b00c58443b5a3832eb4a963377fa9216682d992d5bc96310fb00625496
 -F src/insert.c c6419bc4b447f3d4cdb7b1167690baaea3b796a80cea48e7cf26da65487d430d
++F src/insert.c a09ec15e70ccd680811f1762c9b3f3508897a9c2dcde49054f1e0492069155bd
  F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
- F src/loadext.c 12684b3f19cd103cea97cdf14d0758196d0c646e12a898d7245141a9abfde9a4
- F src/main.c 73ef695cbb6d7d52603dad58129e1901df70e632fc47df996cb034729cc2e0cc
+ F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e
 -F src/main.c 46e139128fbcec8c20f32a49afd6b6f8593b2f76cf85ea63b27459c822fa3099
++F src/main.c 8496edcec37d935e836dfc6e15ab0a549487989ba804f31d74d9e49fbe42eaa6
  F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b
  F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
  F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@@ -534,12 -533,12 +534,12 @@@ F src/os.c 59ed1f503347e8b5434c0ce7d7d0
  F src/os.h 26890f540b475598cd9881dcc68931377b8d429d3ea3e2eeb64470cde64199f8
  F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
  F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
- F src/os_unix.c 5d4a80fe497e48d87078e67ea88e9e44cd714dc02b9f1f20f40831883f81411d
+ F src/os_unix.c 20614e98809738c27daeb38d8a298b748508059879300e5a20f6d20fa4103257
  F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
  F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 -F src/pager.c 12b7e6f061247cc7e24d81dddd0161ba9e317ef3c3b93f0a299873746a07d989
 -F src/pager.h fdc30693c403aa9b4293d0b126346db7e450f8f0e5d2c1bb8355acb1cb8da6fd
 +F src/pager.c 8302eb7aab26c8f0120c714d5f0505ba41140790b76fc62ff8163ca00b7122d7
 +F src/pager.h ed1f7bc91ceae75fa918d51f7c2ad071a5458cc3dc0085ca7577f8d51bf2d7cb
- F src/parse.y a52d0c9a7485121232ecbfcd2086e9f9ddf12449c9fa38fda9be4932e402e3c3
+ F src/parse.y 9aff0654f0a70f45324330d3eb89164add73258343382c046fdf603786f60e6b
  F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
  F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
  F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
@@@ -548,20 -547,20 +548,20 @@@ F src/pragma.h cc4eb73536553008c4442f38
  F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67
  F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
  F src/random.c c6e61d041f230d46c658e6dfe7165fc1ecb0093d5fe28cfe74f389d261dc3af8
- F src/resolve.c 35630effd4d16d2373caa41bae40a3d71f853f3ad0cb4f572f2ed4b8c350c1e9
+ F src/resolve.c 42b94d37a54200707a95566eff4f7e8a380e32d080016b699f23bd79a73a5028
  F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
- F src/select.c 3e7dcf9289592d1a3f73a3a1d480afe460df21c921c63665f71cffb21d91a62f
- F src/shell.c.in f3e91c697f33daae14923355dcadfc26bb0c1eabdb343e5508706893e017a0a6
- F src/sqlite.h.in 50379147536f54ed2c366eafe651ff3d6ea48a00bc7c1f26cfadc8aaedefac3e
+ F src/select.c c265649aed27697c89fcb9390f872bd39a41d882d4bfe48bbbbcedc4d7de9e95
+ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e3
 -F src/sqlite.h.in 838e545b26809e5b3e7af4ad8ec014a0f5761f3bf531857e001d256f150b9d1a
++F src/sqlite.h.in ac8e6211a3caaf39645fcde0a2e9139c167653192e078d9c4b6ec94dcc237761
  F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
- F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
- F src/sqliteInt.h 154e4306489e1e88542106459e9a31f690cf00dbea3f439862cc1d2fa18b1829
+ F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
 -F src/sqliteInt.h e7c3298aafee4cc2dc4c12270ec18de24afb50132480acf8eb15b1eeec5afebc
++F src/sqliteInt.h a898f4971895543557d0cb39e3c05df568d841618da2bf83e5357ab636d862d5
  F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
  F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
  F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
- F src/tclsqlite.c 97645e4a15dde6a6ad6de8d81057ff9869413b866015a89e208fedacd709493e
+ F src/tclsqlite.c 05663f6b5010b044eac0ef22fc8fb5ea3406d2502700a898261683258042c88b
 -F src/test1.c bb6fe83c5a0e255930c14cc6f0b29414410661839fcdd95015abed823df636b4
 -F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 +F src/test1.c 460024efcc596adf9a4a860de53806a2ac013532af846e6f978d7c434af27d69
 +F src/test2.c cb988be1ee1b972dc471e6b076087cfa9cb9ce5c2aa31e98ecf41c3256a72a53
  F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
  F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
  F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
@@@ -615,33 -614,33 +615,33 @@@ F src/test_window.c cdae419fdcea5bad6dc
  F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
  F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
  F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
- F src/treeview.c 21449a944d5abd3ac07b7eab76f7221e20c9480d06f01798f8dc66d9bc361769
- F src/trigger.c e0fd347b2571a2d956318cdc6d011ccca7ce862d10a0ca04188a37920ef5440c
- F src/update.c 22ea2b03f3d269251d554f18d0119ea48dbacf117da4d44274417f9077eb0a2e
- F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
+ F src/treeview.c 43f88d0fd19976a60aee6867959213b438593276f1e8179048df85f416a1ab19
+ F src/trigger.c 3f612ce5f0858b6c23460a3c799d01f408b49b0b29d931d8b8e6fc224a8667de
+ F src/update.c 440b9aae32b930fc8c40beff27cdc6060a2fc4c99d911e415f92bb8a4e6eab68
+ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
  F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
- F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
- F src/vacuum.c 9d6ac090ff36d80f0a2c5bfc63994b714c464bfc44efa5056c457a6a4163dc99
- F src/vdbe.c 9e932e19be0c61db591bd4f35242c6ccf3f72e31ac83a865f43a438b8ea687e5
+ F src/util.c b18a971c8936e9299fecc00474269a11135989d6fe9bd91b1e52137d6f27bd8c
+ F src/vacuum.c a02ce4cb7c45741675bac31528b4bb7b8821727cf3306ade2b06361b4704b248
 -F src/vdbe.c d17e7a89b8da8cd72c02c86808ab8b7406d0e9b104c1e793cf0df59744a409d0
++F src/vdbe.c aa6648a16752c5fe0cb20eb689c83aa4074410e88b3eb96d999040b25ca07be4
  F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
- F src/vdbeInt.h 2678f1f42643fac4a285fac998ceacd346863bba40fb221bd072a4e979c573db
 -F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b
 -F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5
++F src/vdbeInt.h 0086b9b03472950687445458219ad99e89b87a0d78631835c708bedba772eff6
 +F src/vdbeapi.c af2e512c90e751a4617252d162ad2c56978bd6a6e77ebb269899e1c4333dee59
- F src/vdbeaux.c 708f3479a4b1f895f654e29b4fa597ee4c2927ecde3a27ed07dda964a3a12b3a
- F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193
+ F src/vdbeaux.c 6570e0d95dc7489775efa8a7cdccdc3c86a15a00281bda953edc26250009c78d
+ F src/vdbeblob.c 60a7694760e35b2bba166cf49eb6a1eb0b31581102b49de78008ca3032406065
  F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64
  F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2
  F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724
  F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
- F src/vtab.c b928405ccb66040fc6c3a11eaa93ddb02cbf20f9ab6860b301b222b9b50dc089
+ F src/vtab.c 75bdaec808be883b8bb69a1f0a479c3a359823c5a85a26497cd5d90d3c30b74b
  F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
- F src/wal.c 59ad6d70c32f6e52d9695b081a429b5c2ed76b116bee5dcfed88d3e78148164a
+ F src/wal.c e3a21abbd23d5c8f30fb03e545ba292d3640890968e62ef1604c4ff30c0f043a
  F src/wal.h 7ffe787437f20a098af347011967a6d3bb8e5c3dc645e6be59eff44d2b2c5297
  F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
- F src/where.c 4caf843825c6292440113258fefaa6f747fd570c6915628957e42e39529988f5
+ F src/where.c 99b6e13664a7bd9a553c554978d0e253066995dade621f44cffa8928c8b493b5
  F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
- F src/wherecode.c 116a1964eda2d6489186d7a2de8c34e38a868c488dfb987c1e4d3a9ee3a2f233
- F src/whereexpr.c 5a9c9f5d2dac4bcdcaae3035034b4667523f731df228e0bb1d4efc669efa9da5
- F src/window.c a6d624d83b2d5b3cfb82bb437a2fbae759c928d47dc9ad1338a9419269181bb2
 -F src/wherecode.c ef36790a797fa679f58dbd51930e3ee7ef7cb6c906ae412032e4d319a36a2eef
++F src/wherecode.c 401e98037f3ad39051df2c4ac9e3c66ad848b4fe78fdcffa887442de5ca8195a
+ F src/whereexpr.c 3a9144a9d52e110efdc012a73b1574e7b2b4df4bf98949387cb620295eba0975
+ F src/window.c 420167512050a0dfc0f0115b9f0c7d299da9759c9bb2ae83a61fb8d730a5707f
  F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
  F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
  F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
@@@ -1936,7 -1936,7 +1938,7 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9
  F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
  F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
  F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P a485d1a1b8a6a8255cd5177b6a8fa375e1b7281030170152819d5ee85b2b2334 229107b196abe5ab458ce84361d4b1e40d9d077effab7ebe9caac475fb96f7c0
- R 206c3ba8474a1bfbf5ec7772c623eca7
 -P 229107b196abe5ab458ce84361d4b1e40d9d077effab7ebe9caac475fb96f7c0 8b781dcaf68e0cf12a844708c82eee00193e340195cbca915d077e4846983bf3
 -R 6e8a076deaa5f96183b2c50282f660d8
++P 204dbc15a682125c517150f824d32e0bf1fce1db3daab4db9225a44bded4c50b 2c25f25b22fe8e9c0da8a6ff5f2f117bd1716900c03acc8ed3ee8fce2286e15b
++R 78ce34ec04527a31a4c0573e9c671a99
  U drh
- Z a69058283890e0aafc2df3edd6548f93
 -Z 7abb0669693129015ca62af888f39e55
++Z 3c70ae9fe6c7295e7dfa5e3d017c0201
diff --cc manifest.uuid
index 1da213fae1180b61bf9042d9c353e248eb714b92,fc805d5b027a1e215d4cbdab334c6941eda414b6..fc266c93488cf512ae85016fa3cad0f28dcdcb84
@@@ -1,1 -1,1 +1,1 @@@
- 204dbc15a682125c517150f824d32e0bf1fce1db3daab4db9225a44bded4c50b
 -2c25f25b22fe8e9c0da8a6ff5f2f117bd1716900c03acc8ed3ee8fce2286e15b
++385e3b4e9d7245e892f54a4d69fa7a78b1eeb565ae01a6fbabb5b7396ea07d17
diff --cc src/btree.c
index 6860a75c0bdc3ce8eae2c167639858f2c3b3ab83,17c1ee368c89618e2e61c7d5c987febcd1b51296..a8ad9b4385a4514042511a2d76db6827d59ec649
@@@ -5895,529 -5877,8 +5893,525 @@@ int sqlite3BtreeLast(BtCursor *pCur, in
    return rc;
  }
  
- /* Move the cursor so that it points to an entry near the key 
- ** specified by pIdxKey or intKey.   Return a success code.
- **
- ** For INTKEY tables, the intKey parameter is used.  pIdxKey 
- ** must be NULL.  For index tables, pIdxKey is used and intKey
- ** is ignored.
 +#include "vdbeInt.h"
 +
 +static void btreeScanFormatKey(
 +  sqlite3 *db,
 +  StrAccum *pAcc, 
 +  u8 *aKey,
 +  i64 nKey
 +){
 +  if( aKey==0 ){
 +    sqlite3_str_appendf(pAcc, "%lld", nKey);
 +  }else{
 +    int ii;
 +    KeyInfo ki;
 +    UnpackedRecord rec;
 +    Mem aMem[6];
 +    memset(&ki, 0, sizeof(ki));
 +    memset(&rec, 0, sizeof(rec));
 +    memset(aMem, 0, sizeof(aMem));
 +
 +    ki.db = db;
 +    ki.enc = ENC(db);
 +    ki.nKeyField = ArraySize(aMem);
 +    rec.aMem = aMem;
 +    rec.nField = ArraySize(aMem);
 +
 +    sqlite3VdbeRecordUnpack(&ki, nKey, aKey, &rec);
 +    sqlite3_str_appendf(pAcc, "{");
 +    for(ii=0; ii<rec.nField; ii++){
 +      Mem *pMem = &rec.aMem[ii];
 +      if( pMem->flags & MEM_Null ){
 +        sqlite3_str_appendf(pAcc, "NULL");
 +      }else
 +      if( pMem->flags & MEM_Int ){
 +        sqlite3_str_appendf(pAcc, "%lld", pMem->u.i);
 +      }else
 +      if( pMem->flags & MEM_Real ){
 +        sqlite3_str_appendf(pAcc, "%f", pMem->u.r);
 +      }else 
 +      if( pMem->flags & MEM_Str ){
 +        sqlite3_str_appendf(pAcc, "%.*Q", pMem->n, pMem->z);
 +      }else{
 +        int jj;
 +        sqlite3_str_appendf(pAcc, "X'");
 +        for(jj=0; jj<pMem->n; jj++){
 +          sqlite3_str_appendf(pAcc, "%.2X", (u8)pMem->z[jj]);
 +        }
 +        sqlite3_str_appendf(pAcc, "'");
 +      }
 +      if( ii!=rec.nField-1 ){
 +        sqlite3_str_appendf(pAcc, ",");
 +      }
 +    }
 +    sqlite3_str_appendf(pAcc, "}");
 +  }
 +}
 +
 +/*
 +** Compare scan keys (aKey1/nKey1) and (aKey2/nKey2). Return an integer
 +** less than 0, equal to 0, or greater than 0 if key1 is less than, equal
 +** to or greater than key2. i.e. a value with the same sign and zeroness
 +** as:
 +**
 +**     (aKey1/nKey1) - (aKey2/nKey2)
 +*/
 +static int btreeScanCompare(
 +  sqlite3 *db,
 +  CursorScan *pScan,
 +  const u8 *aKey1, i64 nKey1,
 +  const u8 *aKey2, i64 nKey2
 +){
 +  int res = 0;
 +  assert( (aKey1==0)==(aKey2==0) );
 +  if( aKey1 ){
 +    UnpackedRecord rec;
 +    Mem aMem[32];
 +    memset(&rec, 0, sizeof(rec));
 +    memset(aMem, 0, sizeof(aMem));
 +
 +    rec.aMem = aMem;
 +    rec.nField = pScan->pKeyInfo->nAllField;
 +    rec.pKeyInfo = pScan->pKeyInfo;
 +    sqlite3VdbeRecordUnpack(pScan->pKeyInfo, nKey2, aKey2, &rec);
 +    res = sqlite3VdbeRecordCompare(nKey1, aKey1, &rec);
 +  }else{
 +    if( nKey1<nKey2 ) res = -1;
 +    if( nKey1>nKey2 ) res = +1;
 +  }
 +  return res;
 +}
 +
 +void sqlite3_begin_concurrent_report_enable(sqlite3 *db, int bEnable){
 +  db->bConcurrentReport = bEnable;
 +}
 +
 +const char *sqlite3_begin_concurrent_report(sqlite3 *db){
 +  sqlite3DbFree(db, db->zBCReport);
 +  db->zBCReport = 0;
 +  if( db->pCScanList ){
 +    CursorScan *p;
 +    StrAccum accum;
 +    sqlite3StrAccumInit(&accum, db, 0, 0, 64*1024*1024);
 +    for(p=db->pCScanList; p; p=p->pNext){
 +
 +      if( p->flags & (CURSORSCAN_PGWRITE|CURSORSCAN_PGFAIL) ){
 +        u32 *aPg = (u32*)p->aMax;
 +        int nPg = p->iMax;
 +        int i;
 +        if( aPg ){
 +          sqlite3_str_appendf(&accum, "W:{%d", (int)aPg[0]);
 +          for(i=1; i<nPg; i++){
 +            sqlite3_str_appendf(&accum, " %d", (int)aPg[i]);
 +          }
 +          sqlite3_str_appendf(&accum, "}\n");
 +        }
 +
 +        aPg = (u32*)p->aMin;
 +        nPg = p->iMin;
 +        sqlite3_str_appendf(&accum, "%s:{%d", (p->aMax?"R":"F"), (int)aPg[0]);
 +        for(i=1; i<nPg; i++){
 +          sqlite3_str_appendf(&accum, " %d", (int)aPg[i]);
 +        }
 +        sqlite3_str_appendf(&accum, "}\n");
 +      }else
 +      if( p->flags & CURSORSCAN_WRITE ){
 +        sqlite3_str_appendf(&accum, "%d<-(%lld)", p->tnum, p->iMin);
 +        btreeScanFormatKey(db, &accum, p->aLimit, p->iLimit);
 +        sqlite3_str_appendf(&accum, "\n");
 +      }else{
 +        if( p->flags & CURSORSCAN_LIMITVALID ){
 +          if( p->flags & CURSORSCAN_LIMITMAX ){
 +            if( (p->flags & CURSORSCAN_MAXVALID)==0 
 +             || btreeScanCompare(db,p,p->aLimit,p->iLimit,p->aMax,p->iMax)<=0
 +            ){
 +              sqlite3_free(p->aMax);
 +              p->iMax = p->iLimit;
 +              p->aMax = p->aLimit;
 +              p->aLimit = 0;
 +              p->flags &= ~CURSORSCAN_MAXINCL;
 +              p->flags |= (p->flags&CURSORSCAN_LIMITINCL)?CURSORSCAN_MAXINCL:0;
 +              p->flags |= CURSORSCAN_MAXVALID;
 +            }
 +          }else{
 +            if( (p->flags & CURSORSCAN_MINVALID)==0 
 +             || btreeScanCompare(db,p,p->aLimit,p->iLimit,p->aMin,p->iMin)>=0
 +            ){
 +              sqlite3_free(p->aMin);
 +              p->iMin = p->iLimit;
 +              p->aMin = p->aLimit;
 +              p->aLimit = 0;
 +              p->flags &= ~CURSORSCAN_MININCL;
 +              p->flags |= (p->flags&CURSORSCAN_LIMITINCL)?CURSORSCAN_MININCL:0;
 +              p->flags |= CURSORSCAN_MINVALID;
 +            }
 +          }
 +          p->flags &= ~CURSORSCAN_LIMITVALID;
 +        }
 +
 +        sqlite3_str_appendf(&accum, "%d:%s", p->tnum,
 +            (p->flags & CURSORSCAN_MININCL) ? "[" : "("
 +        );
 +        if( p->flags & CURSORSCAN_MINVALID ){
 +          btreeScanFormatKey(db, &accum, p->aMin, p->iMin);
 +        }else{
 +          sqlite3_str_appendf(&accum, "EOF");
 +        }
 +        sqlite3_str_appendf(&accum, "..");
 +        if( p->flags & CURSORSCAN_MAXVALID ){
 +          btreeScanFormatKey(db, &accum, p->aMax, p->iMax);
 +        }else{
 +          sqlite3_str_appendf(&accum, "EOF");
 +        }
 +        sqlite3_str_appendf(&accum, "%s\n", 
 +            (p->flags & CURSORSCAN_MAXINCL) ? "]" : ")"
 +        );
 +      }
 +    }
 +    db->zBCReport = sqlite3StrAccumFinish(&accum);
 +  }
 +  return db->zBCReport;
 +}
 +
 +static u32 btreeScanSerialType(Mem *pMem){
 +  if( pMem->flags & MEM_Int ) return 6;
 +  if( pMem->flags & MEM_Real ) return 7;
 +  if( pMem->flags & MEM_Str ) return (pMem->n * 2)+13;
 +  if( pMem->flags & MEM_Blob ) return (pMem->n * 2)+12;
 +  return 0;
 +}
 +
 +static void btreeScanSet(
 +  CursorScan *pNew, 
 +  UnpackedRecord *pKey, 
 +  i64 iKey,
 +  i64 *piKey,
 +  u8 **paKey
 +){
 +  if( pKey==0 ){
 +    assert( *paKey==0 );
 +    *piKey = iKey;
 +  }else{
 +    int ii;
 +    u8 *aRec = 0;
 +    int nByte = 0;
 +    int nHdr = 0;
 +    int nSize = 0;
 +
 +    sqlite3_free(*paKey);
 +    *paKey = 0;
 +
 +    for(ii=0; ii<pKey->nField; ii++){
 +      Mem *pMem = &pKey->aMem[ii];
 +      u32 serial_type = btreeScanSerialType(pMem);
 +      nByte += sqlite3VdbeSerialTypeLen(serial_type);
 +      nHdr += sqlite3VarintLen(serial_type);
 +    }
 +
 +    nSize = sqlite3VarintLen(nHdr);
 +    if( sqlite3VarintLen(nSize+nHdr)>nSize ) nSize++;
 +    nHdr += nSize;
 +
 +    aRec = (u8*)sqlite3_malloc(nHdr+nByte);
 +    if( aRec==0 ){
 +      pNew->flags |= CURSORSCAN_OOM;
 +    }else{
 +      int iOff = 0;
 +      iOff += sqlite3PutVarint(&aRec[iOff], nHdr);
 +      for(ii=0; ii<pKey->nField; ii++){
 +        u32 serial_type = btreeScanSerialType(&pKey->aMem[ii]);
 +        iOff += sqlite3PutVarint(&aRec[iOff], serial_type);
 +      }
 +      for(ii=0; ii<pKey->nField; ii++){
 +        Mem *pMem = &pKey->aMem[ii];
 +        u32 serial_type = btreeScanSerialType(pMem);
 +        iOff += sqlite3VdbeSerialPut(&aRec[iOff], pMem, serial_type);
 +      }
 +      assert( iOff==(nHdr+nByte) );
 +      *paKey = aRec;
 +      *piKey = iOff;
 +    }
 +  }
 +}
 +
 +static void btreeScanSetKey(BtCursor *pCsr, i64 *piKey, u8 **paKey){
 +  if( pCsr->curIntKey ){
 +    *piKey = sqlite3BtreeIntegerKey(pCsr);
 +  }else{
 +    int rc;
 +    u32 nKey = sqlite3BtreePayloadSize(pCsr);
 +    u8 *aKey = sqlite3_malloc(nKey);
 +    if( aKey==0 ){
 +      rc = SQLITE_NOMEM;
 +    }else{
 +      rc = sqlite3BtreePayload(pCsr, 0, nKey, aKey);
 +    }
 +    if( rc ){
 +      sqlite3_free(aKey);
 +      pCsr->pCScan->flags |= CURSORSCAN_OOM;
 +    }else{
 +      sqlite3_free(*paKey);
 +      *piKey = nKey;
 +      *paKey = aKey;
 +    }
 +  }
 +}
 +
 +static void btreeScanNext(BtCursor *pCsr, int bPrev){
 +  CursorScan *pCScan = pCsr->pCScan;
 +  if( pCScan ){
 +    if( bPrev ){
 +      if( sqlite3BtreeEof(pCsr) ){
 +        pCScan->flags &= ~(CURSORSCAN_MINVALID|CURSORSCAN_MININCL);
 +      }else{
 +        btreeScanSetKey(pCsr, &pCScan->iMin, &pCScan->aMin);
 +        pCScan->flags |= CURSORSCAN_MINVALID|CURSORSCAN_MININCL;
 +      }
 +    }else{
 +      if( sqlite3BtreeEof(pCsr) ){
 +        pCScan->flags &= ~(CURSORSCAN_MAXVALID|CURSORSCAN_MAXINCL);
 +      }else{
 +        btreeScanSetKey(pCsr, &pCScan->iMax, &pCScan->aMax);
 +        pCScan->flags |= CURSORSCAN_MAXVALID|CURSORSCAN_MAXINCL;
 +      }
 +    }
 +  }
 +}
 +
 +int sqlite3BtreeScanLimit(
 +  BtCursor *pCsr, 
 +  UnpackedRecord *pKey, 
 +  i64 iKey, 
 +  int opcode
 +){
 +  CursorScan *pScan = pCsr->pCScan;
 +  if( pScan && (pScan->flags & CURSORSCAN_LIMITVALID)==0 ){
 +    btreeScanSet(pScan, pKey, iKey, &pScan->iLimit, &pScan->aLimit);
 +    pScan->flags |= CURSORSCAN_LIMITVALID;
 +    switch( opcode ){
 +      case OP_IdxLT:
 +      case OP_Lt:
 +        pScan->flags |= CURSORSCAN_LIMITINCL;
 +      case OP_IdxLE:
 +      case OP_Le:
 +        break;
 +
 +      case OP_IdxGT:
 +      case OP_Gt:
 +        pScan->flags |= CURSORSCAN_LIMITINCL;
 +      case OP_IdxGE:
 +      case OP_Ge:
 +        pScan->flags |= CURSORSCAN_LIMITMAX;
 +        break;
 +    }
 +  }
 +  return SQLITE_OK;
 +}
 +
 +static void btreeScanCopy(
 +  CursorScan *p, 
 +  i64 *piOut, u8 **apOut,
 +  i64 iIn, u8 *aIn
 +){
 +  *piOut = iIn;
 +  if( aIn ){
 +    (*apOut) = (u8*)sqlite3_malloc(iIn);
 +    if( 0==(*apOut) ){
 +      p->flags |= CURSORSCAN_OOM;
 +    }else{
 +      memcpy(*apOut, aIn, iIn);
 +    }
 +  }
 +}
 +
 +int sqlite3BtreeScanStart(
 +  BtCursor *pCsr, 
 +  UnpackedRecord *pKey, 
 +  i64 iKey,
 +  int opcode,
 +  int eqOnly
 +){
 +  Btree *pBtree = pCsr->pBtree;
 +  sqlite3 *db = pBtree->db;
 +  if( db->bConcurrentReport
 +   && db->eConcurrent 
 +   && db->aDb[0].pBt==pBtree
 +   && sqlite3PagerIsWal(pBtree->pBt->pPager) 
 +  ){
 +    CursorScan *pNew;
 +    pNew = (CursorScan*)sqlite3MallocZero(sizeof(CursorScan));
 +    if( pNew==0 ) return SQLITE_NOMEM;
 +    pNew->pKeyInfo = sqlite3KeyInfoRef(pCsr->pKeyInfo);
 +    pNew->tnum = (int)pCsr->pgnoRoot;
 +
 +    if( pCsr->pCScan ){
 +      sqlite3BtreeScanDeref(pCsr->pCScan);
 +    }
 +    pCsr->pCScan = pNew;
 +    pNew->pNext = db->pCScanList;
 +    db->pCScanList = pNew;
 +    pNew->nRef = 2;
 +    switch( opcode ){
 +      case OP_Rewind:
 +        btreeScanNext(pCsr, 0);
 +        break;
 +
 +      case OP_Last:
 +        btreeScanNext(pCsr, 1);
 +        break;
 +
 +      case OP_SeekLE:
 +        pNew->flags |= CURSORSCAN_MAXINCL;
 +      case OP_SeekLT:
 +        pNew->flags |= CURSORSCAN_MAXVALID;
 +        btreeScanSet(pNew, pKey, iKey, &pNew->iMax, &pNew->aMax);
 +        if( eqOnly ){
 +          btreeScanCopy(
 +              pNew, &pNew->iLimit, &pNew->aLimit, pNew->iMax, pNew->aMax
 +          );
 +          pNew->flags |= CURSORSCAN_LIMITVALID|CURSORSCAN_LIMITINCL;
 +        }else{
 +          btreeScanNext(pCsr, 1);
 +        }
 +        break;
 +
 +      case OP_SeekGE:
 +        pNew->flags |= CURSORSCAN_MININCL;
 +      case OP_SeekGT:
 +        pNew->flags |= CURSORSCAN_MINVALID;
 +        btreeScanSet(pNew, pKey, iKey, &pNew->iMin, &pNew->aMin);
 +        if( eqOnly ){
 +          btreeScanCopy(
 +              pNew, &pNew->iLimit, &pNew->aLimit, pNew->iMin, pNew->aMin
 +          );
 +          pNew->flags |= CURSORSCAN_LIMITVALID|CURSORSCAN_LIMITINCL;
 +          pNew->flags |= CURSORSCAN_LIMITMAX;
 +        }else{
 +          btreeScanNext(pCsr, 0);
 +        }
 +        break;
 +
 +      case OP_SeekRowid:
 +      case OP_NotExists:
 +      case OP_DeferredSeek:
 +        assert( pKey==0 );
 +        pNew->iMin = pNew->iMax = iKey;
 +        pNew->flags |= (CURSORSCAN_MININCL|CURSORSCAN_MAXINCL);
 +        pNew->flags |= CURSORSCAN_MINVALID|CURSORSCAN_MAXVALID;
 +        break;
 +    }
 +  }
 +  return SQLITE_OK;
 +}
 +
 +void sqlite3BtreeScanDerefList(CursorScan *pList){
 +  CursorScan *p;
 +  CursorScan *pNext;
 +  for(p=pList; p; p=pNext){
 +    pNext = p->pNext;
 +    sqlite3BtreeScanDeref(p);
 +  }
 +}
 +
 +int sqlite3BtreeScanDirty(Btree *pBtree, Bitvec *pRead, PgHdr *pList){
 +  int rc = SQLITE_OK;
 +  sqlite3 *db = pBtree->db;
 +  if( db->bConcurrentReport
 +   && db->eConcurrent 
 +   && db->aDb[0].pBt==pBtree
 +  ){
 +    CursorScan *pNew;
 +    u32 *aPg = 0;
 +    PgHdr *p;
 +    int nPg = 0;
 +
 +    assert( sqlite3PagerIsWal(pBtree->pBt->pPager) );
 +
 +    pNew = (CursorScan*)sqlite3MallocZero(sizeof(CursorScan));
 +    if( pNew==0 ) return SQLITE_NOMEM;
 +    for(p=pList; p; p=p->pDirty) nPg++;
 +    if( pList ){
 +      aPg = sqlite3MallocZero(sizeof(u32*)*nPg);
 +    }
 +
 +    if( pList && aPg==0 ){
 +      rc = SQLITE_NOMEM;
 +    }else{
 +      int nMin;
 +      nPg = 0;
 +      for(p=pList; p; p=p->pDirty){
 +        aPg[nPg++] = p->pgno;
 +      }
 +      pNew->iMax = nPg;
 +      pNew->aMax = (u8*)aPg;
 +
 +      rc = sqlite3BitvecArray(pRead, (u32**)&pNew->aMin, &nMin);
 +      pNew->iMin = (i64)nMin;
 +    }
 +
 +    pNew->nRef = 1;
 +    pNew->flags |= pList ? CURSORSCAN_PGWRITE : CURSORSCAN_PGFAIL;
 +    pNew->pNext = pBtree->db->pCScanList;
 +    pBtree->db->pCScanList = pNew;
 +  }
 +  return rc;
 +}
 +
 +int sqlite3BtreeScanWrite(
 +  BtCursor *pCsr, 
 +  int op, 
 +  i64 rowid, 
 +  const u8 *a, 
 +  int n
 +){
 +  int rc = SQLITE_OK;
 +  Btree *pBtree = pCsr->pBtree;
 +  sqlite3 *db = pBtree->db;
 +  if( db->bConcurrentReport
 +   && db->eConcurrent 
 +   && db->aDb[0].pBt==pBtree
 +   && sqlite3PagerIsWal(pBtree->pBt->pPager) 
 +  ){
 +    sqlite3 *db = pCsr->pBtree->db;
 +    CursorScan *pNew;
 +    pNew = (CursorScan*)sqlite3MallocZero(sizeof(CursorScan));
 +    if( pNew==0 ) return SQLITE_NOMEM;
 +    pNew->tnum = (int)pCsr->pgnoRoot;
 +    pNew->pNext = db->pCScanList;
 +    db->pCScanList = pNew;
 +    pNew->nRef = 1;
 +    pNew->flags = CURSORSCAN_WRITE;
 +    pNew->iMin = (pCsr->curIntKey ? rowid : 0);
 +
 +    if( a ){
 +      pNew->aLimit = sqlite3_malloc(n);
 +      if( pNew->aLimit==0 ){
 +        pNew->flags |= CURSORSCAN_OOM;
 +        rc = SQLITE_NOMEM;
 +      }else{
 +        memcpy(pNew->aLimit, a, n);
 +        pNew->iLimit = n;
 +      }
 +    }else{
 +      pNew->iLimit = sqlite3BtreePayloadSize(pCsr);
 +      pNew->aLimit = sqlite3_malloc(pNew->iLimit);
 +      if( pNew->aLimit==0 ){
 +        rc = SQLITE_NOMEM;
 +      }else{
 +        rc = sqlite3BtreePayload(pCsr, 0, pNew->iLimit, pNew->aLimit);
 +      }
 +      if( rc ){
 +        pNew->flags |= CURSORSCAN_OOM;
 +      }
 +    }
 +  }
 +  return rc;
 +}
 +
 +
+ /* Move the cursor so that it points to an entry in a table (a.k.a INTKEY)
+ ** table near the key intKey.   Return a success code.
  **
  ** If an exact match is not found, then the cursor is always
  ** left pointing at a leaf page which would hold the entry if it
diff --cc src/btree.h
Simple merge
diff --cc src/insert.c
Simple merge
diff --cc src/main.c
Simple merge
diff --cc src/sqlite.h.in
Simple merge
diff --cc src/sqliteInt.h
Simple merge
diff --cc src/vdbe.c
index 45f0046860cdc17b952dd1acc6ab37a8c879e139,6b2ee266e28403c4f2517a84fa38efbb6a7fa69d..a9c2cf8e9ff12488679cd6c864b9842d553a38a0
@@@ -4352,8 -4347,7 +4356,8 @@@ case OP_SeekGT: {       /* jump, in3, g
          if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
        }
      }
-     rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
+     rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)iKey, 0, &res);
 +    sqlite3BtreeScanStart(pC->uc.pCursor, 0, iKey, pOp->opcode, 0);
      pC->movetoTarget = iKey;  /* Used by OP_Delete */
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
  #endif
      r.eqSeen = 0;
-     rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, &r, 0, 0, &res);
+     rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res);
 +    sqlite3BtreeScanStart(pC->uc.pCursor, &r, 0, pOp->opcode, eqOnly);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
@@@ -4929,8 -4922,7 +4933,8 @@@ notExistsWithKey
    pCrsr = pC->uc.pCursor;
    assert( pCrsr!=0 );
    res = 0;
-   rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
+   rc = sqlite3BtreeTableMoveto(pCrsr, iKey, 0, &res);
 +  sqlite3BtreeScanStart(pCrsr, 0, iKey, pOp->opcode, 0);
    assert( rc==SQLITE_OK || res==0 );
    pC->movetoTarget = iKey;  /* Used by OP_Delete */
    pC->nullRow = 0;
diff --cc src/vdbeInt.h
Simple merge
diff --cc src/wherecode.c
Simple merge