From 5a1da0ae1bac995707f1a4dee41c7935f538a51c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Oct 2026 17:27:17 +0000 Subject: [PATCH] When a b-tree cell is deleted, zero the cursor's cell-info cache as the cell it describes no longer exists, even if the cursor position is being preserved. Report [bugs:/info/2026-10-18T16:11:58Z | 2026-10-18T16:11:58Z]. FossilOrigin-Name: 07ed30558ee7da460ed0ca2b36cd555aeb5caa91f0971b2cf83adc08524ca9b7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 6 ++++++ test/delete4.test | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f7f4d75a2c..f7f55fce4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sa\sreal\svalue\sis\sspecified\sas\sa\sdefault\sfor\sa\stext\scolumn,\savoid\svarious\sinconsistencies\sby\sensuring\sthat\sit\sis\salways\sconverted\sto\san\sIEEE\sdouble\sand\sthen\sback\sto\stext\sbefore\suse,\sas\sis\salready\sdone\sfor\sinteger\svalues.\sReport\s[bugs:/info/2026-10-05T16:22:00Z\s|\s2026-10-05T16:22:00Z]. -D 2026-10-20T16:11:44.491 +C When\sa\sb-tree\scell\sis\sdeleted,\szero\sthe\scursor's\scell-info\scache\sas\sthe\scell\sit\sdescribes\sno\slonger\sexists,\seven\sif\sthe\scursor\sposition\sis\sbeing\spreserved.\sReport\s[bugs:/info/2026-10-18T16:11:58Z\s|\s2026-10-18T16:11:58Z]. +D 2026-10-20T17:27:17.523 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -742,7 +742,7 @@ F src/auth.c b5ece4e1edccad082c0332fa0087df225473bae0feea9269f824312201377185 F src/backup.c f6a1490f4ef86cca51f0f93158bbc140b5822406e0c50ec61731e3fcdc1242a2 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 0022d783b0dde6cd4e89c29ab134008e54798077233a4480e40d3620f533f6e2 +F src/btree.c e1c8600ff35025fd7866e8eb80caab122f2d6a51d570e6a830c5f0137597782c F src/btree.h 2ee0ddfdf4f8530ad1d46afffd7da21a0e243bfab10973011ac6f6b7fb4109a1 F src/btreeInt.h df956bca48cd49d2a38886bc3b02045c039e8a16353f86fccd116c6487f79d82 F src/build.c 1406d252bc5b2c3f2150edd4426e5981eabf1000944be8db8d470b96eb64ee07 @@ -1125,7 +1125,7 @@ F test/default.test a4c9e41318d25e3e6d6adfbb3fbbc198b9c6a3f42b1abd4e24a900dcc6e6 F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab -F test/delete4.test 2bcf66fe9978206e8fad1bacb69c00fe05dd1a3f2036c421420f6360f7d18b53 +F test/delete4.test 6345f819cd0a841186c93c95ebf42957bca5b295c753a45d24bfbdf9b8b1f40e F test/delete_db.test 096d828493c7907f9ea11a7098ea6a0f73edba89406487d5d6cc2228dc4ab8b0 F test/descidx1.test edc8adee58d491b06c7157c50364eaf1c3605c9c19f8093cb1ea2b6184f3ac13 F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad78298 @@ -2287,8 +2287,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 480d6e1a39a2057685260cf8386a3dbef4f391c6d1766a6cded5f8cc4d1a0ec4 -R 8b48dd9331a57f37881ef866fc3ca01a +P d140ada6488a27342c6baf0d8e44adf38f91b37a657c2bcc0efa9ecf437b414c +R 2dd9ec1001750ac3d92d4b1541658965 U dan -Z cba637d31d681339c101f8a950537158 +Z e363b3a3bc64eb242bfbbd40a6d0950b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ee2647ba7e..b6770f8c20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d140ada6488a27342c6baf0d8e44adf38f91b37a657c2bcc0efa9ecf437b414c +07ed30558ee7da460ed0ca2b36cd555aeb5caa91f0971b2cf83adc08524ca9b7 diff --git a/src/btree.c b/src/btree.c index 420ba409ce..64bb095137 100644 --- a/src/btree.c +++ b/src/btree.c @@ -10060,6 +10060,12 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ }else{ pCur->skipNext = 1; } + /* The pCur->info structure is currently populated with the details + ** of the cell that was just removed. But pCur->ix now points to a + ** different cell in the b-tree. So zero info.nSize here so that if + ** saveCursorPosition() is called on this cursor it does not trust + ** the contents of pCur->info. */ + pCur->info.nSize = 0; }else{ rc = moveToRoot(pCur); if( bPreserve ){ diff --git a/test/delete4.test b/test/delete4.test index 34151446b1..d9321e7d5d 100644 --- a/test/delete4.test +++ b/test/delete4.test @@ -268,5 +268,43 @@ do_execsql_test 7.3.3 { SELECT * FROM t3; } {} +#------------------------------------------------------------------------- +# Report +# +foreach {tn expr res} { + 1 {a > 8} {0 1 1 40 2 40 3 40 4 40 5 40 6 40 7 40 8 40} + 2 {a = 5} {0 1 1 40 2 40 3 40 4 40 6 40 7 40 8 40 9 1300} + 3 {a = 1} {0 1 2 40 3 40 4 40 5 40 6 40 7 40 8 40 9 1300} +} { + reset_db + + do_execsql_test 8.$tn.0 " + PRAGMA page_size = 512; + CREATE TABLE t(a PRIMARY KEY, b, c) WITHOUT ROWID; + CREATE INDEX tc ON t(c); + INSERT INTO t VALUES + (1, zeroblob(40), 1), (2, zeroblob(40), 2), + (3, zeroblob(40), 3), (4, zeroblob(40), 4), + (5, zeroblob(40), 5), (6, zeroblob(40), 6), + (7, zeroblob(40), 7), (8, zeroblob(40), 8), + (9, zeroblob(1300), 9); + + CREATE TABLE u(x); + + CREATE TRIGGER r AFTER INSERT ON u BEGIN + DELETE FROM t WHERE c IS NULL OR $expr ; + INSERT INTO t VALUES (0, 0, 0); + END; + + PRAGMA integrity_check; + " {ok} + + + do_execsql_test 8.$tn.1 { INSERT INTO u VALUES (1) } + do_execsql_test 8.$tn.2 { SELECT a, length(b) FROM t; } $res + do_execsql_test 8.$tn.3 { PRAGMA integrity_check } {ok} +} + + finish_test