From: dan Date: Mon, 10 Nov 2025 17:37:59 +0000 (+0000) Subject: Avoid dropping RETURNING triggers when the schema is reset while preparing a statement. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14fcb8252a25ec871f52ebf1400da8ebbed807a6;p=thirdparty%2Fsqlite.git Avoid dropping RETURNING triggers when the schema is reset while preparing a statement. FossilOrigin-Name: e26bcef7522a6f6ee8d55fa30e7fe06419566cf4e8c2df0c33c92a4c89f58c05 --- diff --git a/manifest b/manifest index 6f6610152b..77e1baca39 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smissing\sva_end()\scall\sin\sthe\sintckMprintf()\sfunction\sof\sthe\nincremental\sintegrity-check\sextension. -D 2025-11-10T11:05:36.073 +C Avoid\sdropping\sRETURNING\striggers\swhen\sthe\sschema\sis\sreset\swhile\spreparing\sa\sstatement. +D 2025-11-10T17:37:59.666 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -675,7 +675,7 @@ F src/btree.c 0ad524883ec4ccac3221c97bdc2c5d5f6e149504e14cf269bbed31362c3f4393 F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 611e07299d72ff04bbcb9e7109183467e30925d203c3e121ef9bb3cf6876289b -F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 +F src/callback.c afa59adfaa483f668260ce69f740c8273dee3e6fee9106846e0499ebdd1ac076 F src/carray.c ff6081a31878fc34df8fa1052a9cbf17ddc22652544dcb3e2326886ed1053b55 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2 @@ -687,8 +687,8 @@ F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b -F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7 -F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf +F src/hash.c e592527b97e99cd9046946a397d9ed63d8b466b385c8129249175a3bf22ee33c +F src/hash.h c5f4a02aaf1dca835a68b51c8b906af265c6ca3d8d53d255e0453f0abce561be F src/hwtime.h d4d1b98c1afdc56986a5c0eba882786ef017e2180a320da25b4231b8e7e463e8 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd @@ -1522,7 +1522,7 @@ F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2 F test/reservebytes.test 6163640b5a5120c0dee6591481e673a0fa0bf0d12d4da7513bad692c1a49a162 F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb -F test/returning1.test 212cd4111bb941a60abf608f20250db666c21eb1bc4d49217e96c87ff3ab9d1a +F test/returning1.test cd32517148948859db214dd814354597dd40e7489259590fac1a4f7bf44deb97 F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4 F test/rollback.test 952c4d805bca96adc2be76f621ea22115fe40b330015af36fcc8028c8547fcee F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f @@ -2167,8 +2167,11 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7a644178c8d289ca18631844b2d73b32fddc72afcc80906633dd38c14eba2ca9 -R bd6b05ffc04557a9ff7d69a81e6084d5 -U drh -Z a1230748ab427e1519659da8a04065cb +P 62ad2350e368dc337ba2d0fb6847d07c40a6f79520dd6414d22b5b54983b0b12 +R 43727fa3b19bd9f550a5daad80497dd6 +T *branch * returning-fix +T *sym-returning-fix * +T -sym-trunk * +U dan +Z 7df20ffae687bc1753586d20b75ba681 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.tags b/manifest.tags index bec971799f..3f06d6cb86 100644 --- a/manifest.tags +++ b/manifest.tags @@ -1,2 +1,2 @@ -branch trunk -tag trunk +branch returning-fix +tag returning-fix diff --git a/manifest.uuid b/manifest.uuid index 835eaab8b5..5bcbb58eaf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62ad2350e368dc337ba2d0fb6847d07c40a6f79520dd6414d22b5b54983b0b12 +e26bcef7522a6f6ee8d55fa30e7fe06419566cf4e8c2df0c33c92a4c89f58c05 diff --git a/src/callback.c b/src/callback.c index 6fe21a2956..9ea3616b38 100644 --- a/src/callback.c +++ b/src/callback.c @@ -504,8 +504,16 @@ void sqlite3SchemaClear(void *p){ temp2 = pSchema->trigHash; sqlite3HashInit(&pSchema->trigHash); sqlite3HashClear(&pSchema->idxHash); - for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem)); + for(pElem=sqliteHashFirst(&temp2); pElem; ){ + HashElem *pNext = sqliteHashNext(pElem); + Trigger *pTrig = (Trigger*)sqliteHashData(pElem); + if( pTrig->bReturning ){ + /* Do not remove RETURNING triggers from the temp-triggers hash */ + sqlite3HashTransfer(&pSchema->trigHash, &temp2, pElem); + }else{ + sqlite3DeleteTrigger(&xdb, pTrig); + } + pElem = pNext; } sqlite3HashClear(&temp2); sqlite3HashInit(&pSchema->tblHash); diff --git a/src/hash.c b/src/hash.c index 8cc6c09663..1984a463c2 100644 --- a/src/hash.c +++ b/src/hash.c @@ -270,3 +270,25 @@ void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem); return 0; } + +/* +** Parameter pElem is currently part of hash table pFrom. Add it to hash +** table pTo. +** +** This procedure corrupts hash table pFrom. Specifically, it removes element +** pElem from the list of all elements in the hash table, but may leave +** a pointer to it in one of the hash buckets of pFrom. This is not a problem +** because this function is only called if hash table pFrom will be cleared +** before any further lookups or inserts are attempted. +*/ +void sqlite3HashTransfer(Hash *pTo, Hash *pFrom, HashElem *pElem){ + if( pElem->prev ){ + pElem->prev->next = pElem->next; + }else{ + assert( pFrom->first==pElem ); + pFrom->first = pElem->next; + } + insertElement(pTo, pTo->ht ? &pTo->ht[pElem->h % pTo->htsize] : 0, pElem); +} + + diff --git a/src/hash.h b/src/hash.h index cff65d6e50..4cb1fbe47b 100644 --- a/src/hash.h +++ b/src/hash.h @@ -70,6 +70,7 @@ void sqlite3HashInit(Hash*); void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); void *sqlite3HashFind(const Hash*, const char *pKey); void sqlite3HashClear(Hash*); +void sqlite3HashTransfer(Hash*, Hash*, HashElem *pElem); /* ** Macros for looping over all elements of a hash table. The idiom is diff --git a/test/returning1.test b/test/returning1.test index e7be7c65a3..9ab646a3b7 100644 --- a/test/returning1.test +++ b/test/returning1.test @@ -544,4 +544,54 @@ do_catchsql_test 22.1 { } {1 {no such column: sqlite_master.name}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 23.0 { + PRAGMA recursive_triggers = 1; + CREATE TABLE t1(x, y); + CREATE TRIGGER t1insert AFTER INSERT ON t1 WHEN new.x<5 BEGIN + INSERT INTO t1 VALUES(new.x+1, new.y); + END; +} + +do_execsql_test 23.1 { + INSERT INTO t1 VALUES(1, 'one') RETURNING *; +} {1 one} + +do_execsql_test 23.2 { + SELECT * FROM t1 +} {1 one 2 one 3 one 4 one 5 one} + +#------------------------------------------------------------------------- +reset_db +ifcapable fts5 { + + do_execsql_test 24.0 { + CREATE VIRTUAL TABLE ft USING fts5(c); + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('x'); + } + + db close + + sqlite3 db test.db + sqlite3 db2 test.db + + do_execsql_test 24.1 { + SELECT * FROM t1 + } {x} + + do_execsql_test -db db2 24.2 { + CREATE TABLE t2(y); + INSERT INTO t2 VALUES('y'); + } {} + + db2 close + + do_execsql_test 24.3 { + INSERT INTO ft VALUES('hello world') RETURNING * + } {{hello world}} +} + + finish_test