]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When the commit_hook calls a query recursively, make sure the commit_hook
authordrh <drh@noemail.net>
Sat, 3 Jan 2009 14:04:38 +0000 (14:04 +0000)
committerdrh <drh@noemail.net>
Sat, 3 Jan 2009 14:04:38 +0000 (14:04 +0000)
is not invoked recursively.  Ticket #3564. (CVS 6107)

FossilOrigin-Name: 27ae406537c07073db46ecde40c65c78fbb73170

manifest
manifest.uuid
src/sqliteInt.h
src/vdbeaux.c
test/hook.test

index fecc1ba2aff9723c4d38bf270d63bffa91e185c4..581acee2b898ced37f99b1bc75f454191391fa86 100644 (file)
--- 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
index 35b323449cb725fdebde18c6b1a3aa9abed7b67d..2d7d1f5483542c0b57e28511c152107d5de7a7a7 100644 (file)
@@ -1 +1 @@
-50f57cd1456f18919a8c90efa05da446ae12788d
\ No newline at end of file
+27ae406537c07073db46ecde40c65c78fbb73170
\ No newline at end of file
index c7bdd0aaa2597bebc0a6455cc55dfe5d04d1c0f2..f068537e58763151337f227adfcc8405762aa4ee 100644 (file)
@@ -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.
index 537e8cffc5ca530b00631810e74f6ee824bb4f37..b1a7e47f6eb7acc0365384f789c68270951493c7 100644 (file)
@@ -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 <ctype.h>
@@ -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 
index 39892b32315eaffb545bc0a81bdca6cb2f00da56..33eeefc704bae0b7c2bb973a7ac5f46bbbabf07e 100644 (file)
@@ -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.
 #