]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The sqlite3_trace() callback now prints a message as each trigger fires
authordrh <drh@noemail.net>
Sat, 12 Jan 2008 21:35:57 +0000 (21:35 +0000)
committerdrh <drh@noemail.net>
Sat, 12 Jan 2008 21:35:57 +0000 (21:35 +0000)
within a statement. (CVS 4709)

FossilOrigin-Name: 110c000d86bd4a0b4b946c62d11a435426b02d16

manifest
manifest.uuid
src/build.c
src/pragma.c
src/select.c
src/trigger.c
src/vdbe.c
src/vdbeapi.c
src/vdbeaux.c
test/trace.test

index 4f67a8b48282619b9d3b86c7f4f11988c5a46cc0..84b6a5a032089f37ff051c5426ae7ee4d6c3468c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Continuing\swork\stoward\sconverting\sthe\sVM\sto\sa\sregister\smachine.\s(CVS\s4708)
-D 2008-01-12T19:03:49
+C The\ssqlite3_trace()\scallback\snow\sprints\sa\smessage\sas\seach\strigger\sfires\nwithin\sa\sstatement.\s(CVS\s4709)
+D 2008-01-12T21:35:57
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -86,7 +86,7 @@ F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
 F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
 F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
 F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
-F src/build.c 353cce0f4e773b0889d94663dca6dc99598d6b3d
+F src/build.c c0f9dba7028d415fb8d282e34a8ebcf69614befd
 F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
@@ -127,11 +127,11 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429
 F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
 F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1
-F src/pragma.c 1d3d9deefcf325e14a99b94f9f506f1a90a9232b
+F src/pragma.c b4e77e057990bb2c295c63327406d9bcbf6c9c08
 F src/prepare.c c31a879d6795f4765fd0b113675c6debbc96b7fd
 F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c fc9cebb2033a84b31472405114ad36d73c30b967
+F src/select.c 34c138d90771a5919fa181f7ddde75277d6a9fc6
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
 F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
@@ -163,16 +163,16 @@ F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5
 F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
 F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
-F src/trigger.c 69df777f7626507d04ef23b9cb185d31ebd8e91a
+F src/trigger.c da3e11df34d34c4341d9417d8033facbae16d9e8
 F src/update.c aad823f97a930e6982264299863837d4c6107d3b
 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
 F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
-F src/vdbe.c a05947fba057311149cb0635cccdee9bed42f3cb
+F src/vdbe.c f36700465fe35af303d33d59fef03779d93b2570
 F src/vdbe.h a9166e1601f5b74c20516a74182773a20baee43e
 F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
-F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
-F src/vdbeaux.c db33a4c2477546da05e772352be43896d24d51d5
+F src/vdbeapi.c cb8c427a3ab646490c83204a98e94eff03ee2e89
+F src/vdbeaux.c ac5d274b175e078eb90b1ad7c8f45419c485e92b
 F src/vdbeblob.c e386d49d8354aa5a58f0a7f2794303442c149120
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c a86119b5ccc41ab8653e4746f83d591ff0ae892e
@@ -486,7 +486,7 @@ F test/tkt2820.test 017fdee33aaef7abc092beab6088816f1942304b
 F test/tkt2822.test 8b1526b1e5b0d38a1a993f7828fbb81759093686
 F test/tkt2832.test cd56dc66bb31898b7eb2146baa5bde2eb80f96fe
 F test/tkt2854.test aebd5a9904d36d1ef7a074fc5e7c7da3ab00c32a
-F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
+F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00
 F test/trans.test b73289992b46d38d9479ecc4fdc03d8edb2413dc
 F test/trigger1.test 7c13f39ca36f529bf856e05c7d004fc0531d48b4
 F test/trigger2.test 33bf8ae9b788013be194efe5f66c04a202facbb4
@@ -606,7 +606,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P a6dddebcc5ccbbf3009c9d06163a8b59036331de
-R 537e4808d9b23703b914b666ccd36884
+P 426f31ecdd05d1179a2e49c2ca1666011cede9c6
+R 3435d52d4f2b4750bec1183c99c98b94
 U drh
-Z 1569ded7274b37b8c39c0600e4142054
+Z 0d14628a3647710d605d98d6d56b6e09
index 85bc50ea1d53af535b779c513c3ddb3a1f198741..a8a5ebd4e0558f3e0b80fbd7363254201e252605 100644 (file)
@@ -1 +1 @@
-426f31ecdd05d1179a2e49c2ca1666011cede9c6
\ No newline at end of file
+110c000d86bd4a0b4b946c62d11a435426b02d16
\ No newline at end of file
index 12a330df6a80eca983f74472c59c539b223a771f..26ae87d221ca3ff88458df65dcf3e9487664a824 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.464 2008/01/12 12:48:08 drh Exp $
+** $Id: build.c,v 1.465 2008/01/12 21:35:57 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -184,14 +184,15 @@ void sqlite3FinishCoding(Parse *pParse){
     }
 
 #ifndef SQLITE_OMIT_TRACE
-    /* Add a No-op that contains the complete text of the compiled SQL
-    ** statement as its P4 argument.  This does not change the functionality
-    ** of the program. 
-    **
-    ** This is used to implement sqlite3_trace().
-    */
-    sqlite3VdbeAddOp4(v, OP_Noop, 0, 0, 0,
-                      pParse->zSql, pParse->zTail-pParse->zSql);
+    if( !db->init.busy ){
+      /* Change the P4 argument of the first opcode (which will always be
+      ** an OP_Trace) to be the complete text of the current SQL statement.
+      */
+      VdbeOp *pOp = sqlite3VdbeGetOp(v, 0);
+      if( pOp && pOp->opcode==OP_Trace ){
+        sqlite3VdbeChangeP4(v, 0, pParse->zSql, pParse->zTail-pParse->zSql);
+      }
+    }
 #endif /* SQLITE_OMIT_TRACE */
   }
 
index 9fffdfff246cd332ef71dfd57c7692014e559587..e362f76179f0db00a5559d0edae7a7b7e83589d7 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.165 2008/01/10 23:50:11 drh Exp $
+** $Id: pragma.c,v 1.166 2008/01/12 21:35:57 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -250,7 +250,7 @@ void sqlite3Pragma(
   int iDb;               /* Database index for <database> */
   sqlite3 *db = pParse->db;
   Db *pDb;
-  Vdbe *v = sqlite3GetVdbe(pParse);
+  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);
   if( v==0 ) return;
   pParse->nMem = 1;
 
index 0ae6af2f07de9d5085242353e969ca419c4a35e5..f5547aa8cf35a379a09dcee02854db7989787af7 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.399 2008/01/12 19:03:49 drh Exp $
+** $Id: select.c,v 1.400 2008/01/12 21:35:57 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -1722,6 +1722,11 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){
   Vdbe *v = pParse->pVdbe;
   if( v==0 ){
     v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
+#ifndef SQLITE_OMIT_TRACE
+    if( v ){
+      sqlite3VdbeAddOp0(v, OP_Trace);
+    }
+#endif
   }
   return v;
 }
index 0204cae1808bc0ddde66a9145646c740bee27b1b..3d3348d7596cb1a300832af0f78de0f79ad84ac0 100644 (file)
@@ -806,6 +806,11 @@ int sqlite3CodeRowTrigger(
       AuthContext sContext;
       NameContext sNC;
 
+#ifndef SQLITE_OMIT_TRACE
+      sqlite3VdbeAddOp4(pParse->pVdbe, OP_Trace, 0, 0, 0,
+                        sqlite3_mprintf("-- TRIGGER %s", p->name),
+                        P4_DYNAMIC);
+#endif
       memset(&sNC, 0, sizeof(sNC));
       sNC.pParse = pParse;
 
index d9936dbccde55ee612cab143461f48c8901563fd..8b62db8b32223cadd69bac1bf3f11acd9cb4829b 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.694 2008/01/12 19:03:49 drh Exp $
+** $Id: vdbe.c,v 1.695 2008/01/12 21:35:57 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -5059,6 +5059,27 @@ case OP_VUpdate: {   /* no-push */
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
+#ifndef SQLITE_OMIT_TRACE
+/* Opcode: Trace * * * P4 *
+**
+** If tracing is enabled (by the sqlite3_trace()) interface, then
+** the UTF-8 string contained in P4 is emitted on the trace callback.
+*/
+case OP_Trace: {
+  if( pOp->p4.z ){
+    if( db->xTrace ){
+      db->xTrace(db->pTraceArg, pOp->p4.z);
+    }
+#ifdef SQLITE_DEBUG
+    if( (db->flags & SQLITE_SqlTrace)!=0 ){
+      sqlite3DebugPrintf("SQL-trace: %s\n", pOp->p4.z);
+    }
+#endif /* SQLITE_DEBUG */
+  }
+  break;
+}
+#endif
+
 /* An other opcode is illegal...
 */
 default: {
index 05a8718c0fbf48a8d30206df155d19954ce1dc49..ae9af1674cf95affafe01d740f0c1fa0bf654aa3 100644 (file)
@@ -288,20 +288,6 @@ static int sqlite3Step(Vdbe *p){
     }
 
 #ifndef SQLITE_OMIT_TRACE
-    /* Invoke the trace callback if there is one
-    */
-    if( db->xTrace && !db->init.busy ){
-      assert( p->nOp>0 );
-      assert( p->aOp[p->nOp-1].opcode==OP_Noop );
-      assert( p->aOp[p->nOp-1].p4.z!=0 );
-      assert( p->aOp[p->nOp-1].p4type==P4_DYNAMIC );
-      sqlite3SafetyOff(db);
-      db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p4.z);
-      if( sqlite3SafetyOn(db) ){
-        p->rc = SQLITE_MISUSE;
-        return SQLITE_MISUSE;
-      }
-    }
     if( db->xProfile && !db->init.busy ){
       double rNow;
       sqlite3OsCurrentTime(db->pVfs, &rNow);
@@ -309,15 +295,6 @@ static int sqlite3Step(Vdbe *p){
     }
 #endif
 
-    /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned
-    ** on in debugging mode.
-    */
-#ifdef SQLITE_DEBUG
-    if( (db->flags & SQLITE_SqlTrace)!=0 ){
-      sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p4.z);
-    }
-#endif /* SQLITE_DEBUG */
-
     db->activeVdbeCnt++;
     p->pc = 0;
   }
@@ -337,17 +314,14 @@ static int sqlite3Step(Vdbe *p){
 #ifndef SQLITE_OMIT_TRACE
   /* Invoke the profile callback if there is one
   */
-  if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){
+  if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->nOp>0
+           && p->aOp[0].opcode==OP_Trace && p->aOp[0].p4.z!=0 ){
     double rNow;
     u64 elapseTime;
 
     sqlite3OsCurrentTime(db->pVfs, &rNow);
     elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
-    assert( p->nOp>0 );
-    assert( p->aOp[p->nOp-1].opcode==OP_Noop );
-    assert( p->aOp[p->nOp-1].p4.z!=0 );
-    assert( p->aOp[p->nOp-1].p4type==P4_DYNAMIC );
-    db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p4.z, elapseTime);
+    db->xProfile(db->pProfileArg, p->aOp[0].p4.z, elapseTime);
   }
 #endif
 
index 39bbcd0dfa642f00e5b62e7fb9b592868d3134c3..53abc35b2122692ccf475514856f62d50b1395c3 100644 (file)
@@ -681,7 +681,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
 #endif
     default: {
       zP4 = pOp->p4.z;
-      if( zP4==0 || pOp->opcode==OP_Noop ){
+      if( zP4==0 ){
         zP4 = zTemp;
         zTemp[0] = 0;
       }
@@ -854,8 +854,8 @@ void sqlite3VdbePrintSql(Vdbe *p){
   int nOp = p->nOp;
   VdbeOp *pOp;
   if( nOp<1 ) return;
-  pOp = &p->aOp[nOp-1];
-  if( pOp->opcode==OP_Noop && pOp->p4.z!=0 ){
+  pOp = &p->aOp[0];
+  if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
     const char *z = pOp->p4.z;
     while( isspace(*(u8*)z) ) z++;
     printf("SQL: [%s]\n", z);
@@ -872,11 +872,11 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
   VdbeOp *pOp;
   if( sqlite3_io_trace==0 ) return;
   if( nOp<1 ) return;
-  pOp = &p->aOp[nOp-1];
-  if( pOp->opcode==OP_Noop && pOp->p4.p!=0 ){
+  pOp = &p->aOp[0];
+  if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
     int i, j;
     char z[1000];
-    sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.p);
+    sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);
     for(i=0; isspace((unsigned char)z[i]); i++){}
     for(j=0; z[i]; i++){
       if( isspace((unsigned char)z[i]) ){
index 2cdd9619aa2839cda16b61a2764e6a8cb37ef014..67ad0e3786c9182bfee701ce1bfeae57f20914da 100644 (file)
@@ -12,7 +12,7 @@
 #
 # This file implements tests for the "sqlite3_trace()" API.
 #
-# $Id: trace.test,v 1.6 2006/01/03 00:33:50 drh Exp $
+# $Id: trace.test,v 1.7 2008/01/12 21:35:57 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -145,4 +145,25 @@ do_test trace-4.5 {
 } {SELECT * FROM t1}
 catch {sqlite3_finalize $STMT}
 
+# Trigger tracing.
+#
+do_test trace-5.1 {
+  db eval {
+    CREATE TRIGGER r1t1 AFTER UPDATE ON t1 BEGIN
+      UPDATE t2 SET a=new.a WHERE rowid=new.rowid;
+    END;
+    CREATE TRIGGER r1t2 AFTER UPDATE ON t2 BEGIN
+      SELECT 'hello';
+    END;
+  }
+  set TRACE_OUT {}
+  proc trace_proc cmd {
+    lappend ::TRACE_OUT [string trim $cmd]
+  }
+  db eval {
+    UPDATE t1 SET a=a+1;
+  }
+  set TRACE_OUT
+} {{UPDATE t1 SET a=a+1;} {-- TRIGGER r1t1} {-- TRIGGER r1t2} {-- TRIGGER r1t1} {-- TRIGGER r1t2} {-- TRIGGER r1t1} {-- TRIGGER r1t2}}
+
 finish_test