]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge the latest trunk enhancements into the begin-concurrent-report branch. begin-concurrent-report
authordrh <>
Wed, 21 Dec 2022 20:17:13 +0000 (20:17 +0000)
committerdrh <>
Wed, 21 Dec 2022 20:17:13 +0000 (20:17 +0000)
FossilOrigin-Name: 397fb07bb4bc404d7c44f01e18811ecf2f84d22601f14363e442e8fe63f64b7b

16 files changed:
1  2 
manifest
manifest.uuid
src/btree.c
src/btree.h
src/btreeInt.h
src/insert.c
src/main.c
src/pager.c
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c
src/wherecode.c

diff --cc manifest
index dee1a574f7129ed8da3cbbc036ad6e4eb6233b64,4b8afd8bd75ee934749e1ac94d866d39c34b4e76..c6301226f5af7ccb0df2bbf085bad7676b1f3fc1
+++ b/manifest
@@@ -1,5 -1,5 +1,5 @@@
- C Merge\sthe\s3.40.0\srelease\schanges\sinto\sthe\sbegin-concurrent-report\sbranch.
- D 2022-11-16T16:05:47.749
 -C Update\sthe\sbegin-concurrent\sbranch\swith\sthe\slatest\senhancements\son\strunk.
 -D 2022-12-21T20:07:58.718
++C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sbegin-concurrent-report\sbranch.
++D 2022-12-21T20:17:13.365
  F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
  F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
  F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@@ -579,13 -586,13 +587,13 @@@ F src/alter.c 0390ca1d69ec3626cfa9f1531
  F src/analyze.c d2fce73f6a024897593012c6ca25368629fa4aeb49960d88a52fac664582e483
  F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8
  F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
 -F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
 -F src/bitvec.c 3907fcbe8a0c8c2db58d97087d15cdabbf2842adb9125df9ab9ff87d3db16775
 +F src/backup.c 7c69378cf826e20778df98b33b80dd1976e96ad3cf6f2a0bc17e6e6b018148c6
 +F src/bitvec.c e67e4ebed581b5f0aa9155abd88177ed8b63eb40e9266b1483ce7f6eb9257477
  F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
- F src/btree.c 634ac44e75d44eefbaf098d6e423a9b22d861a035328b50e185e7fc41ec5eb40
- F src/btree.h 1c1508834794c0d15fe15d23792cd42deefd8140ad782899eab258d081a0adfc
- F src/btreeInt.h ed074f13b5464ea021fed9f8de2dc5cf45c7e5fa58ec98550fdc24229b11d25e
- F src/build.c dd4b69d26a9e18467dc3d3612f472ba0c5ad4b34de45e1c3b367b5c64c993066
 -F src/btree.c 295645736414c89b825ad1ca369bcc0beb26f1e58a9dffec1210cd02c2b8d48e
 -F src/btree.h b89e1a7cf3345ea1b411831929e45fe39e8a93e28eabd2ea1071c432366f4859
 -F src/btreeInt.h 429769e739b67133db190b514d427cb3acbb8c7b475c15bd4e8c91e88b2692fa
++F src/btree.c b07494870ed286a5a851d3062893715804348f9bb55b82cbd21b340782d087e8
++F src/btree.h a1d3565d03a66528e2c2ebbdf5e43c07ba95c88929537f2d5b433e471707e0ed
++F src/btreeInt.h 9075b713ec63672cd3df63068a7b3f1eb5706833b82358aa3e0e0773d04f57df
+ F src/build.c 022afee249807f77fdd3cd7ca23b60c0336a6e724d0b1c1506c7298823d0b0a6
  F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a
  F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
  F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
@@@ -600,14 -607,14 +608,14 @@@ F src/func.c 98feef981f41a00feb96af8165
  F src/global.c e06ff8e0acd85aec13563c9ecb44fbbf38232ccf73594998fd880b92d619594b
  F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
  F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
- F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
+ F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7
  F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
- F src/insert.c 9d9d1d47df761c17ee97ba9f46f841201042f17e63ea96ae2c7913ea441448cb
 -F src/insert.c 1b11a2e33ee52db93c02fddac67e39d00161d61b69fac2675b82f2aa68c1b61c
++F src/insert.c 6c7ba09ff4005a066522ba0dd67d2680e22860d2cbb757b59930741a79b4bb52
  F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
  F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
- F src/loadext.c 8086232d10e51e183a7f64199815bad1c579896354db69435347665f62f481e9
- F src/main.c f78f4dba74467aab3a0c446cd94011edd73be945c032a7063d98c99910ee2afa
- F src/malloc.c dfddca1e163496c0a10250cedeafaf56dff47673e0f15888fb0925340a8e3f90
+ F src/loadext.c 25663175950c5c4404b9377840b7b4c6fe5c53b415caf43634c62f442c02a9a7
 -F src/main.c 997fc865c9bf19cd65b2398b9d053cbcdbe865c6bd9cdab32197b7cc46d505e7
++F src/main.c 87fd9d4f6c634bf7e7e94680750263663f818743f3de2137e6871d645acea1aa
+ F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
  F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
  F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
  F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75
@@@ -624,14 -631,14 +632,14 @@@ F src/mutex_w32.c caa50e1c0258ac4443f52
  F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6
  F src/os.c 81c9c1c52eab711e27e33fd51fe5788488d3a02bc1a71439857abbee5d0d2c97
  F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
- F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
- F src/os_kv.c 0e59600d25b72034c7666b8b7dcc527f039b5d9c16f24a7eca4c08c66f63c364
+ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
+ F src/os_kv.c 73f89ab97ecdb3216857d2acc8395103f89164eaadac87cce4e9e16445c89541
  F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
- F src/os_unix.c b036cebe7344894e7c6ec26eeb9912699c9475242858555c1aa9dd99fae2d5a1
+ F src/os_unix.c da76727158b8b963fc0b47ede94031593abae650f988c645f79b5173abd7ae4b
  F src/os_win.c 295fe45f18bd86f2477f4cd79f3377c6f883ceb941b1f46808665c73747f2345
  F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
- F src/pager.c 994f3aeb406974702b888df3e869fa26e3c376677d82e0d9f4a1a32c3c47bb41
 -F src/pager.c f0b3fd5a9d2e9342ef6cc25a205eecf22eb211ebf63979f4d31a211c95c34600
 -F src/pager.h 7b2ec7bba30b21a97b68d5bdc0dbb82a75f48c4b1457180988f9d409fb789e16
++F src/pager.c 134ceaedfa4c9ae085143f0b55d07e05ccbe70c80fe500990de8d3aff9889c8a
 +F src/pager.h 03ea09dddd4852990d9151746a62b94ed1486f04abe5acc9ee0e80d8381bfcd9
  F src/parse.y 17c50d262d92083badeb60b3ebe4725e19c76548f90aea898ab07d4f2940a7d8
  F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
  F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
@@@ -643,18 -650,18 +651,18 @@@ F src/printf.c ff4b05e38bf928ff1b80d3dd
  F src/random.c a3e70f8515721ff24d2c0e6afd83923e8faab5ab79ececea4c1bf9fe4049fbb2
  F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
  F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
- F src/select.c 363bef2cd043d0ba070ffcaabac6b52a209c2aa59eb34935b547db7eb8268139
- F src/shell.c.in 458cb3de9d548342fc645b699620b1af3de770d2ceec09ac71f86c19bd244064
- F src/sqlite.h.in 7b3b93d69c076bcdc6e7a2e1a6ae22ecb1d8fd6d05eb4553aef267eaa70256b1
+ F src/select.c e0ec5c22fe0b0ca4fa94732d6d16af6df9f77dfde245ac462c50a3f1123d4ff4
+ F src/shell.c.in 24e0c75947dd8a3426473d90dfc4887f42553c8b57dff02a6865f04c5efcf864
 -F src/sqlite.h.in 6e33b6c208f01d746c2bd7fe8747dbe8469877c3b3abb601c0251e137105028a
++F src/sqlite.h.in 2a37d8ab045c2d66cae2818440503f8c8c7bff23e191303eca2a736f211c666a
  F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
  F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f
- F src/sqliteInt.h dee38fa7f58f084f788b41a60e801de5672835154727ded19f420292ea7145fa
 -F src/sqliteInt.h 0bb7efbc278277c402809485e0ed489c63c6a05ee211c46739f4158d7a22c9a0
++F src/sqliteInt.h 4fc61615b0662abffbef979d1a324a064e52dc20c574fdbaa53d69ea916396aa
  F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
  F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
  F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
  F src/tclsqlite.c 4e64ba300a5a26e0f1170e09032429faeb65e45e8f3d1a7833e8edb69fc2979e
- F src/test1.c 144867d41cfffd4905ed439a62660da8b8fd49ec5616855767e02a50bee55bd9
 -F src/test1.c 741d7a904a01ded100ee021023886b12ad16f704481a470e5a5403013defef2f
 -F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef
++F src/test1.c 1418416c4b23ead892c7abfe4aca9f92ed22b238f65f863e43980a4e48f6d407
 +F src/test2.c fd13437e053100a838646ceda05a7b12b1c1ef61a9da2dbd96b5c4b94a0e0e45
  F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
  F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
  F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
@@@ -708,18 -715,18 +716,18 @@@ F src/test_window.c cdae419fdcea5bad6dc
  F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
  F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
  F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
- F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
- F src/trigger.c 4163ada044af89d51caba1cb713a73165347b2ec05fe84a283737c134d61fcd5
- F src/update.c aebd5b9f352e82b3fea709e97079c4723f2acd29d2b5d88058bcc205b77e7f0c
+ F src/treeview.c 29b1dc7e0f84ba090734febe27393d4719682af0cae1b902d5ebf0236ecebea4
+ F src/trigger.c 5e68b790f022b8dafbfb0eb244786512a95c9575fc198719d2557d73e5795858
+ F src/update.c 1a1073dd3519d2a073d62e5243d8bedf8f1c8e751d0a593588a97b9637cd7d3d
  F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
  F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
- F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
+ F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050
  F src/vacuum.c f6e47729554e0d2c576bb710c415d5bc414935be0d7a70f38d1f58ffa7a6d8c0
- F src/vdbe.c 8d54e2809b4e26926a8b67ea0005c5ed46494e85e70499f86bcefc6e28e7bc82
- F src/vdbe.h 58675f47dcf3105bab182c3ad3726efd60ffd003e954386904ac9107d0d2b743
- F src/vdbeInt.h 8d2f014eb068d69b23abe12b3dcc56a980dfa8ace5db732feb00dc33f7e26df4
- F src/vdbeapi.c 807e68bc0f643113517c4e039f13ab33e07d252339898ac0370a8d85cd0aa9aa
- F src/vdbeaux.c f859f37ebad75d2d639bd03b37a24b314b55e1e757a816a34f81a49fa558041d
 -F src/vdbe.c 69bfbf1f0697c169f2854270cc4ae56f41c0a952ace76380701f9c97ef23e938
++F src/vdbe.c 02978bda89618a582a53effc976be4a3ea9f070a47fa6619a0b8ec5c3c4f4182
+ F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c
 -F src/vdbeInt.h 8651e4c4e04d1860d0bdcf330cb8294e3778a9d4222be30ce4c490d9220af783
 -F src/vdbeapi.c df3f73a4d0a487f2068e3c84776cd6e3fba5ae80ff612659dcfda4307686420b
 -F src/vdbeaux.c 2eee24133b51fd721bbbd01b5a99bc76afc6d37f334d6c5bdb20bab2a077047e
++F src/vdbeInt.h bfcd69627a07e8fb41cebadeb6c5371e3dc78b8fe8ab0e4b32b5490e26d37b4d
++F src/vdbeapi.c 32297e58f25557343b0ffb1ee20c237e8740f2446121253ca184e811c4252216
++F src/vdbeaux.c ecd6688ee1e0593da316cbcfc27ce877825ada7e65986333de23a071e4cde605
  F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
  F src/vdbemem.c 6cfed43758d57b6e3b99d9cdedfeccd86e45a07e427b22d8487cbdbebb6c522a
  F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
@@@ -730,14 -737,14 +738,14 @@@ F src/vxworks.h d2988f4e5a61a4dfe82c652
  F src/wal.c 419c0a98dd65b9419fd07bdd4f9facc61143c33d57b0dbeffd83cf38a2e0e33e
  F src/wal.h 7ffe787437f20a098af347011967a6d3bb8e5c3dc645e6be59eff44d2b2c5297
  F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
- F src/where.c 1ef5aae7fac877057b9f360f06b26d4275888460d8fb6e92bbb9e70e07afe946
- F src/whereInt.h df0c79388c0b71b4a91f480d02791679fe0345d40410435c541c8893e95a4d3f
- F src/wherecode.c b5827f38fcbc79eab7f9f4ec375e807d7623aa0cd28f9fe19ca824fae2bd40ee
+ F src/where.c d0d8e3cb2c11e77ba0f8f9ed8eada9d84dbd377167cdcf387b8eeb824c35a3ad
+ F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c
 -F src/wherecode.c 76bca3379219880d2527493b71a3be49e696f75396d3481e4de5d4ceec7886b2
++F src/wherecode.c fe70baaee70dc1bac9310b44b675d8b0c1de1060f6d426111700ad7ccd478c38
  F src/whereexpr.c 05295b44b54eea76d1ba766f0908928d0e20e990c249344c9521454d3d09c7ae
- F src/window.c 928e215840e2f2d9a2746e018c9643ef42c66c4ab6630ef0df7fa388fa145e86
+ F src/window.c 14836767adb26573b50f528eb37f8b1336f2c430ab38de7cead1e5c546bb4d8c
  F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
  F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
- F test/affinity3.test b5c19d504dec222c0dc66642673d23dce915d35737b68e74d9f237b80493eb53
+ F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
  F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
  F test/aggnested.test 7269d07ac879fce161cb26c8fabe65cba5715742fac8a1fccac570dcdaf28f00
  F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
@@@ -2073,8 -2083,8 +2085,8 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9
  F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
  F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
  F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P 4d3f2531a96eeca17a7e00f386c512be721785bdfccaff962931902f3ee4ba02 a06d57ee9e2862b2c67dc97e3702c00339341ba308d6558b7694e5b9e47231ac
- R f464d069898866ccdbb46b49f278ebbb
 -P a06d57ee9e2862b2c67dc97e3702c00339341ba308d6558b7694e5b9e47231ac 371f9b88387a44a5f820279d79733d1deb7eafc72f320ec47a11679bbdbb49ef
 -R 86b38a0acfb02a8499e4768a9a084653
++P 9fc6241017fa7212974ae1070496a76b3a4c4f6d54f597abbf8c0340d172fa68 0c198aee53d35cf0999f880c433140c3dfc6bd620c30920b08d7534c0f905e05
++R e60201fec803cc908a82fc3006aa1a52
  U drh
- Z 5c833d5f3c90d3af46d3c9d1fa073cfe
 -Z 41f88f8b005a3dfbf678e68c0eda1543
++Z 8a2eb1704e2959c410685e42bd1120c1
  # Remove this line to create a well-formed Fossil manifest.
diff --cc manifest.uuid
index 8a1ed8ea193e04729e356e2573ce6de405e19ef3,d3e1ba33e6881d7fba0945ad4d091d7558aa1705..1532c2d9464ddf70eda0f1a8a27ac368457b7118
@@@ -1,1 -1,1 +1,1 @@@
- 9fc6241017fa7212974ae1070496a76b3a4c4f6d54f597abbf8c0340d172fa68
 -0c198aee53d35cf0999f880c433140c3dfc6bd620c30920b08d7534c0f905e05
++397fb07bb4bc404d7c44f01e18811ecf2f84d22601f14363e442e8fe63f64b7b
diff --cc src/btree.c
index 700c055fb53d8a0c7118031e80fb56450a7d7623,b7a61d66d7288f8f479d3b0c1f17145084157f34..f1974e2cb3ba34aa4870d04cd3a3cabcd0e3db8a
@@@ -5993,542 -5998,9 +6014,526 @@@ int sqlite3BtreeLast(BtCursor *pCur, in
      *pRes = 0;
      return SQLITE_OK;
    }
-   rc = moveToRoot(pCur);
-   if( rc==SQLITE_OK ){
-     assert( pCur->eState==CURSOR_VALID );
-     *pRes = 0;
-     rc = moveToRightmost(pCur);
-     if( rc==SQLITE_OK ){
-       pCur->curFlags |= BTCF_AtLast;
-     }else{
-       pCur->curFlags &= ~BTCF_AtLast;
-     }
-   }else if( rc==SQLITE_EMPTY ){
-     assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
-     *pRes = 1;
-     rc = SQLITE_OK;
-   }
-   return rc;
+   return btreeLast(pCur, pRes);
  }
  
 +#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.
  **
diff --cc src/btree.h
Simple merge
diff --cc src/btreeInt.h
Simple merge
diff --cc src/insert.c
Simple merge
diff --cc src/main.c
Simple merge
diff --cc src/pager.c
Simple merge
diff --cc src/sqlite.h.in
Simple merge
diff --cc src/sqliteInt.h
Simple merge
diff --cc src/test1.c
Simple merge
diff --cc src/vdbe.c
index ce5ffac19f4c0891fa3892c798b7d1f968128f0a,19922cadd781f41a157aeb7433f79e32e67ca3bc..c134f88caf1fc175223733d460769522161a0abe
@@@ -2126,13 -2119,7 +2119,12 @@@ case OP_Ge: {             /* same as TK
    flags1 = pIn1->flags;
    flags3 = pIn3->flags;
    if( (flags1 & flags3 & MEM_Int)!=0 ){
-     assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
      /* Common case of comparison of two integers */
 +    if( pOp->p4type==P4_INT32 ){
 +      sqlite3BtreeScanLimit(
 +          p->apCsr[pOp->p4.i]->uc.pCursor, 0, pIn1->u.i, pOp->opcode
 +      );
 +    }
      if( pIn3->u.i > pIn1->u.i ){
        if( sqlite3aGTb[pOp->opcode] ){
          VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
diff --cc src/vdbeInt.h
Simple merge
diff --cc src/vdbeapi.c
Simple merge
diff --cc src/vdbeaux.c
Simple merge
diff --cc src/wherecode.c
Simple merge