From: drh Date: Sat, 3 Jan 2009 14:04:38 +0000 (+0000) Subject: When the commit_hook calls a query recursively, make sure the commit_hook X-Git-Tag: version-3.6.10~77 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=853799a26ecf2b094501c69d84ac21355d3fa217;p=thirdparty%2Fsqlite.git When the commit_hook calls a query recursively, make sure the commit_hook is not invoked recursively. Ticket #3564. (CVS 6107) FossilOrigin-Name: 27ae406537c07073db46ecde40c65c78fbb73170 --- diff --git a/manifest b/manifest index fecc1ba2af..581acee2b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment.\s(CVS\s6106) -D 2009-01-03T12:55:18 +C When\sthe\scommit_hook\scalls\sa\squery\srecursively,\smake\ssure\sthe\scommit_hook\nis\snot\sinvoked\srecursively.\s\sTicket\s#3564.\s(CVS\s6107) +D 2009-01-03T14:04:39 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 05461a9b5803d5ad10c79f989801e9fd2cc3e592 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -158,7 +158,7 @@ F src/select.c 6c2a5675c21bef11d8160f3dc97e1adfbf26bbb9 F src/shell.c 65d19f8996a160f288087e31810f24025439c62a F src/sqlite.h.in 6cd2489e40fe97ba58c60044a4ced377e08b6d09 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 -F src/sqliteInt.h 9f8fa19d36c62bd52f4421058547957bec085f24 +F src/sqliteInt.h 8279b14cc8ed403efd7b902854be97a4f6c0f613 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/table.c 23db1e5f27c03160987c122a078b4bb51ef0b2f8 @@ -202,7 +202,7 @@ F src/vdbe.c 687e481528acc92a42959accafa8e41dfa46f95d F src/vdbe.h 03516f28bf5aca00a53c4dccd6c313f96adb94f6 F src/vdbeInt.h e6e80a99ce634983b7cc2498843b4d2e5540900a F src/vdbeapi.c 85c33cfbfa56249cbe627831610afafba754477d -F src/vdbeaux.c 6f9b43870a92056fb02d8c19ac5c3a861a15cc26 +F src/vdbeaux.c f8bf57ba0f7ec1fc1fe3997be1cb30d08553fa5c F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935 F src/vdbemem.c f9c859ac17e2e05a0f249868ce4f191f69edd31d F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43 @@ -377,7 +377,7 @@ F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb F test/fuzz3.test 3856b9340b801671424ff0c581ef74342962aa7d F test/fuzz_common.tcl ff4bc2dfc465f6878f8e2d819620914365382731 F test/fuzz_malloc.test 4eca9d345f06d5b0b0105f7a2ef9e7f22658827b -F test/hook.test e17d4ed2843ba4ef9b234aa63e6f056bf88f9a19 +F test/hook.test a9961ccfcf7271cd7fc72352de77aff822359e66 F test/icu.test f51d0f4407ff8bb1e872f51a0e8b08fdc5a6897e F test/in.test d49419c6df515852f477fa513f3317181d46bc92 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -692,7 +692,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 2946fbb7183d597b4db1db203eb5fd57c9762dc4 -R ccda20803e4cdd800ec83fb76606b129 +P 50f57cd1456f18919a8c90efa05da446ae12788d +R 7224ef793d5f6387bd34cf62f3dc2850 U drh -Z 877aa6f9be566bb3a1b0cf9f2dffeecd +Z 4f061edd82220a513e722f7b8cfb9dc6 diff --git a/manifest.uuid b/manifest.uuid index 35b323449c..2d7d1f5483 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50f57cd1456f18919a8c90efa05da446ae12788d \ No newline at end of file +27ae406537c07073db46ecde40c65c78fbb73170 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c7bdd0aaa2..f068537e58 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.819 2009/01/03 12:55:18 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.820 2009/01/03 14:04:39 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -810,6 +810,7 @@ struct sqlite3 { #define SQLITE_RecoveryMode 0x00040000 /* Ignore schema errors */ #define SQLITE_SharedCache 0x00080000 /* Cache sharing is enabled */ #define SQLITE_Vtab 0x00100000 /* There exists a virtual table */ +#define SQLITE_CommitBusy 0x00200000 /* In the process of committing */ /* ** Possible values for the sqlite.magic field. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 537e8cffc5..b1a7e47f6e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.428 2008/12/16 17:20:38 shane Exp $ +** $Id: vdbeaux.c,v 1.429 2009/01/03 14:04:39 drh Exp $ */ #include "sqliteInt.h" #include @@ -1276,9 +1276,12 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ /* If there are any write-transactions at all, invoke the commit hook */ if( needXcommit && db->xCommitCallback ){ + assert( (db->flags & SQLITE_CommitBusy)==0 ); + db->flags |= SQLITE_CommitBusy; (void)sqlite3SafetyOff(db); rc = db->xCommitCallback(db->pCommitArg); (void)sqlite3SafetyOn(db); + db->flags &= ~SQLITE_CommitBusy; if( rc ){ return SQLITE_CONSTRAINT; } @@ -1594,6 +1597,7 @@ int sqlite3VdbeHalt(Vdbe *p){ if( !sqlite3VtabInSync(db) && db->autoCommit && db->writeVdbeCnt==(p->readOnly==0) + && (db->flags & SQLITE_CommitBusy)==0 ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ /* The auto-commit flag is true, and the vdbe program was diff --git a/test/hook.test b/test/hook.test index 39892b3231..33eeefc704 100644 --- a/test/hook.test +++ b/test/hook.test @@ -17,7 +17,7 @@ # sqlite_update_hook (tests hook-4-*) # sqlite_rollback_hook (tests hook-5.*) # -# $Id: hook.test,v 1.13 2008/01/19 20:11:26 drh Exp $ +# $Id: hook.test,v 1.14 2009/01/03 14:04:39 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -92,6 +92,27 @@ do_test hook-3.9 { set ::commit_cnt } {} +# Ticket #3564. +# +do_test hook-3.10 { + file delete -force test2.db test2.db-journal + sqlite3 db2 test2.db + proc commit_hook {} { + set y [db2 one {SELECT y FROM t3 WHERE y>10}] + return [expr {$y>10}] + } + db2 eval {CREATE TABLE t3(x,y)} + db2 commit_hook commit_hook + catchsql {INSERT INTO t3 VALUES(1,2)} db2 + catchsql {INSERT INTO t3 VALUES(11,12)} db2 + catchsql {INSERT INTO t3 VALUES(3,4)} db2 + db2 eval { + SELECT * FROM t3 ORDER BY x; + } +} {1 2 3 4} +db2 close + + #---------------------------------------------------------------------------- # Tests for the update-hook. #