The callback on sqlite3_trace() is invoked the first time sqlite3_step()
is called after sqlite3_prepare() or sqlite3_reset(). Ticket #900. (CVS 1960) FossilOrigin-Name: 0cc2f40e6afa157ead45140c4e28a9a33c469b73
This commit is contained in:
parent
fd241b0ea4
commit
c16a03b54b
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
|||||||
C Remove\sthe\sencode/decode\sfrom\sthe\sversion\s3.0\ssource\stree.\s(CVS\s1959)
|
C The\scallback\son\ssqlite3_trace()\sis\sinvoked\sthe\sfirst\stime\ssqlite3_step()\nis\scalled\safter\ssqlite3_prepare()\sor\ssqlite3_reset().\s\sTicket\s#900.\s(CVS\s1960)
|
||||||
D 2004-09-13T13:46:01
|
D 2004-09-15T13:38:11
|
||||||
F Makefile.in 9cdfc3af2647055085969968ca2394f24c3c6166
|
F Makefile.in 9cdfc3af2647055085969968ca2394f24c3c6166
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -30,7 +30,7 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
|||||||
F src/auth.c 65408baa7e6621520882478dfa1e6b8c1d6c1850
|
F src/auth.c 65408baa7e6621520882478dfa1e6b8c1d6c1850
|
||||||
F src/btree.c 470e00b08688f065c2e62a6dcd3fb18880e8e309
|
F src/btree.c 470e00b08688f065c2e62a6dcd3fb18880e8e309
|
||||||
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
||||||
F src/build.c 662f4e56a64aacadc97c481492b08c842b9ec0f4
|
F src/build.c c5ecf114af4ebc2963a03142b6bd6f2284ee35fc
|
||||||
F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b
|
F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b
|
||||||
F src/delete.c e887f44aae1e33da1643df58abe86cd9cde45ad1
|
F src/delete.c e887f44aae1e33da1643df58abe86cd9cde45ad1
|
||||||
F src/expr.c 9130794d8c86af2cbf2b8cdc66f2158167fd15b1
|
F src/expr.c 9130794d8c86af2cbf2b8cdc66f2158167fd15b1
|
||||||
@ -39,7 +39,7 @@ F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
|||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c bfd21070c28dd94e58ae918260a6985d2b5e4477
|
F src/insert.c bfd21070c28dd94e58ae918260a6985d2b5e4477
|
||||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||||
F src/main.c ac302ed646bdb256b78c87385627b3142357eced
|
F src/main.c 82a952ef3e5f7bacaa1b20060d0588f8767a6774
|
||||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||||
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
|
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
|
||||||
F src/os_common.h cd7eb025fdab7dc91e0e97bf6310f1648205857f
|
F src/os_common.h cd7eb025fdab7dc91e0e97bf6310f1648205857f
|
||||||
@ -77,8 +77,8 @@ F src/vacuum.c 819a3f411cb8d2d714e55f0805e8c23a642dd7ba
|
|||||||
F src/vdbe.c b19de04c57b4136a8e0203d5e3b76dd82bded1b5
|
F src/vdbe.c b19de04c57b4136a8e0203d5e3b76dd82bded1b5
|
||||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||||
F src/vdbeInt.h e09362d6323a725de3c30b0cc381a691e86ed697
|
F src/vdbeInt.h e09362d6323a725de3c30b0cc381a691e86ed697
|
||||||
F src/vdbeapi.c 20bf8901592c7f38e8aabb448a913327ab19f0a7
|
F src/vdbeapi.c c7208bb89fc4efc605e20328099a540175e2dae6
|
||||||
F src/vdbeaux.c 066766b06836d6dbb8d7ad5d87b539f383e0f10d
|
F src/vdbeaux.c 0fbc50cf7aed1ea30c89839ad316446b839cc645
|
||||||
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
|
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
|
||||||
F src/where.c 12e214870c84546858ddb9f121165a1fbfce6811
|
F src/where.c 12e214870c84546858ddb9f121165a1fbfce6811
|
||||||
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
|
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
|
||||||
@ -175,7 +175,7 @@ F test/tester.tcl 1ff1170dd4203d87f572871080cdb64330dade99
|
|||||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||||
F test/threadtest2.c 97a830d53c24c42290501fdfba4a6e5bdd34748b
|
F test/threadtest2.c 97a830d53c24c42290501fdfba4a6e5bdd34748b
|
||||||
F test/trace.test 0ed72787440d97c6de6b6ecb4c022e6f78d5d94a
|
F test/trace.test b6fb0931e4ac802414977a09109c0b02ee446202
|
||||||
F test/trans.test 29645b344d2b9b6792793562b12340177ddd8f96
|
F test/trans.test 29645b344d2b9b6792793562b12340177ddd8f96
|
||||||
F test/trigger1.test dc015c410161f1a6109fd52638dfac852e2a34de
|
F test/trigger1.test dc015c410161f1a6109fd52638dfac852e2a34de
|
||||||
F test/trigger2.test a5d06e6e8e1e773cfcb5aaa75ab381b2ff35de63
|
F test/trigger2.test a5d06e6e8e1e773cfcb5aaa75ab381b2ff35de63
|
||||||
@ -216,7 +216,7 @@ F www/arch2b.fig d22a2c9642d584b89d4088b1e51e2bb0f7c04bed
|
|||||||
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
|
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
|
||||||
F www/c_interface.tcl 83b39203e1ded4c2dab97f42edf31279a308efcb
|
F www/c_interface.tcl 83b39203e1ded4c2dab97f42edf31279a308efcb
|
||||||
F www/capi3.tcl 5c1cb163f4d2a54e2d0e22dcc399dd71245c8b89
|
F www/capi3.tcl 5c1cb163f4d2a54e2d0e22dcc399dd71245c8b89
|
||||||
F www/capi3ref.tcl aa6ea82ea34ff71357300b8f1ab9fd8232a9eec8
|
F www/capi3ref.tcl 893977e2b1c8ae47a441335bc124cdc6d5fdbe95
|
||||||
F www/changes.tcl 3641bc28b86b40c82d546727da45ea0f0aa9a9f4
|
F www/changes.tcl 3641bc28b86b40c82d546727da45ea0f0aa9a9f4
|
||||||
F www/common.tcl f786e6be86fb2627ceb30e770e9efa83b9c67a3a
|
F www/common.tcl f786e6be86fb2627ceb30e770e9efa83b9c67a3a
|
||||||
F www/conflict.tcl fb8a2ba83746c7fdfd9e52fa7f6aaf5c422b8246
|
F www/conflict.tcl fb8a2ba83746c7fdfd9e52fa7f6aaf5c422b8246
|
||||||
@ -247,7 +247,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P dd62224ae8d1047db388acdc4b91eb56fb9e966a
|
P c1f1320be5ce0b6e52491577078ba2b939882fbd
|
||||||
R b72a839b56c08880706fc5af1e49a3b1
|
R aecc6b7d054a0a0bc5b475a58b060454
|
||||||
U drh
|
U drh
|
||||||
Z 55b7cec5724fd9cc6c0ba5706bebd5ec
|
Z 08c3c5131edf3b7397865edadac24eb1
|
||||||
|
@ -1 +1 @@
|
|||||||
c1f1320be5ce0b6e52491577078ba2b939882fbd
|
0cc2f40e6afa157ead45140c4e28a9a33c469b73
|
@ -23,7 +23,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.252 2004/09/08 15:09:41 drh Exp $
|
** $Id: build.c,v 1.253 2004/09/15 13:38:11 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -81,13 +81,13 @@ void sqlite3FinishCoding(Parse *pParse){
|
|||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/* Add a No-op that contains the complete text of the compiled SQL
|
/* Add a No-op that contains the complete text of the compiled SQL
|
||||||
** statement as its P3 argument. This does not change the functionality
|
** statement as its P3 argument. This does not change the functionality
|
||||||
** of the program. But it does make it easier to debug.
|
** of the program.
|
||||||
|
**
|
||||||
|
** This is used to implement sqlite3_trace() functionality.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
|
sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
36
src/main.c
36
src/main.c
@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.259 2004/09/06 17:24:13 drh Exp $
|
** $Id: main.c,v 1.260 2004/09/15 13:38:11 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -981,40 +981,6 @@ int sqlite3_prepare(
|
|||||||
sParse.db = db;
|
sParse.db = db;
|
||||||
sqlite3RunParser(&sParse, zSql, &zErrMsg);
|
sqlite3RunParser(&sParse, zSql, &zErrMsg);
|
||||||
|
|
||||||
if( db->xTrace && !db->init.busy ){
|
|
||||||
/* Trace only the statment that was compiled.
|
|
||||||
** Make a copy of that part of the SQL string since zSQL is const
|
|
||||||
** and we must pass a zero terminated string to the trace function
|
|
||||||
** The copy is unnecessary if the tail pointer is pointing at the
|
|
||||||
** beginning or end of the SQL string.
|
|
||||||
*/
|
|
||||||
if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){
|
|
||||||
char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql);
|
|
||||||
if( tmpSql ){
|
|
||||||
db->xTrace(db->pTraceArg, tmpSql);
|
|
||||||
sqliteFree(tmpSql);
|
|
||||||
}else{
|
|
||||||
/* If a memory error occurred during the copy,
|
|
||||||
** trace entire SQL string and fall through to the
|
|
||||||
** sqlite3_malloc_failed test to report the error.
|
|
||||||
*/
|
|
||||||
db->xTrace(db->pTraceArg, zSql);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
db->xTrace(db->pTraceArg, zSql);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 && sParse.zTail && sParse.zTail!=zSql ){
|
|
||||||
sqlite3DebugPrintf("SQL-trace: %.*s\n", sParse.zTail - zSql, zSql);
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_DEBUG */
|
|
||||||
|
|
||||||
|
|
||||||
if( sqlite3_malloc_failed ){
|
if( sqlite3_malloc_failed ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
sqlite3RollbackAll(db);
|
sqlite3RollbackAll(db);
|
||||||
|
@ -150,6 +150,30 @@ int sqlite3_step(sqlite3_stmt *pStmt){
|
|||||||
return SQLITE_MISUSE;
|
return SQLITE_MISUSE;
|
||||||
}
|
}
|
||||||
if( p->pc<0 ){
|
if( p->pc<0 ){
|
||||||
|
/* Invoke the trace callback if there is one
|
||||||
|
*/
|
||||||
|
if( (db = p->db)->xTrace && !db->init.busy ){
|
||||||
|
assert( p->nOp>0 );
|
||||||
|
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
||||||
|
assert( p->aOp[p->nOp-1].p3!=0 );
|
||||||
|
assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
|
||||||
|
sqlite3SafetyOff(db);
|
||||||
|
db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3);
|
||||||
|
if( sqlite3SafetyOn(db) ){
|
||||||
|
p->rc = SQLITE_MISUSE;
|
||||||
|
return SQLITE_MISUSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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].p3);
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_DEBUG */
|
||||||
|
|
||||||
db->activeVdbeCnt++;
|
db->activeVdbeCnt++;
|
||||||
p->pc = 0;
|
p->pc = 0;
|
||||||
}
|
}
|
||||||
|
@ -528,8 +528,8 @@ void sqlite3VdbePrintSql(Vdbe *p){
|
|||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
int nOp = p->nOp;
|
int nOp = p->nOp;
|
||||||
VdbeOp *pOp;
|
VdbeOp *pOp;
|
||||||
if( nOp<2 ) return;
|
if( nOp<1 ) return;
|
||||||
pOp = &p->aOp[nOp-2];
|
pOp = &p->aOp[nOp-1];
|
||||||
if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
|
if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
|
||||||
const char *z = pOp->p3;
|
const char *z = pOp->p3;
|
||||||
while( isspace(*(u8*)z) ) z++;
|
while( isspace(*(u8*)z) ) z++;
|
||||||
@ -559,11 +559,9 @@ void sqlite3VdbeMakeReady(
|
|||||||
assert( p!=0 );
|
assert( p!=0 );
|
||||||
assert( p->magic==VDBE_MAGIC_INIT );
|
assert( p->magic==VDBE_MAGIC_INIT );
|
||||||
|
|
||||||
/* Add a HALT instruction to the very end of the program.
|
/* There should be at least one opcode.
|
||||||
*/
|
*/
|
||||||
if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
|
assert( p->nOp>0 );
|
||||||
sqlite3VdbeAddOp(p, OP_Halt, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No instruction ever pushes more than a single element onto the
|
/* No instruction ever pushes more than a single element onto the
|
||||||
** stack. And the stack never grows on successive executions of the
|
** stack. And the stack never grows on successive executions of the
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#
|
#
|
||||||
# This file implements tests for the "sqlite3_trace()" API.
|
# This file implements tests for the "sqlite3_trace()" API.
|
||||||
#
|
#
|
||||||
# $Id: trace.test,v 1.2 2004/06/30 02:35:51 danielk1977 Exp $
|
# $Id: trace.test,v 1.3 2004/09/15 13:38:11 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -38,10 +38,43 @@ do_test trace-1.3 {
|
|||||||
} {1 2}
|
} {1 2}
|
||||||
do_test trace-1.4 {
|
do_test trace-1.4 {
|
||||||
set ::stmtlist
|
set ::stmtlist
|
||||||
} {{CREATE TABLE t1(a,b);} {INSERT INTO t1 VALUES(1,2);} {SELECT * FROM t1;} {}}
|
} {{CREATE TABLE t1(a,b);} {INSERT INTO t1 VALUES(1,2);} {SELECT * FROM t1;}}
|
||||||
do_test trace-1.5 {
|
do_test trace-1.5 {
|
||||||
db trace {}
|
db trace {}
|
||||||
db trace
|
db trace
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
# If we prepare a statement and execute it multiple times, the trace
|
||||||
|
# happens on each execution.
|
||||||
|
#
|
||||||
|
db close
|
||||||
|
set DB [sqlite3 db test.db]
|
||||||
|
do_test trace-2.1 {
|
||||||
|
set STMT [sqlite3_prepare $DB {INSERT INTO t1 VALUES(2,3)} -1 TAIL]
|
||||||
|
db trace trace_proc
|
||||||
|
proc trace_proc sql {
|
||||||
|
global TRACE_OUT
|
||||||
|
set TRACE_OUT $sql
|
||||||
|
}
|
||||||
|
set TRACE_OUT {}
|
||||||
|
sqlite3_step $STMT
|
||||||
|
set TRACE_OUT
|
||||||
|
} {INSERT INTO t1 VALUES(2,3)}
|
||||||
|
do_test trace-2.2 {
|
||||||
|
set TRACE_OUT {}
|
||||||
|
sqlite3_reset $STMT
|
||||||
|
set TRACE_OUT
|
||||||
|
} {}
|
||||||
|
do_test trace-2.3 {
|
||||||
|
sqlite3_step $STMT
|
||||||
|
set TRACE_OUT
|
||||||
|
} {INSERT INTO t1 VALUES(2,3)}
|
||||||
|
do_test trace-2.4 {
|
||||||
|
execsql {SELECT * FROM t1}
|
||||||
|
} {1 2 2 3 2 3}
|
||||||
|
do_test trace-2.5 {
|
||||||
|
set TRACE_OUT
|
||||||
|
} {SELECT * FROM t1}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
set rcsid {$Id: capi3ref.tcl,v 1.11 2004/09/07 16:19:54 drh Exp $}
|
set rcsid {$Id: capi3ref.tcl,v 1.12 2004/09/15 13:38:11 drh Exp $}
|
||||||
source common.tcl
|
source common.tcl
|
||||||
header {C/C++ Interface For SQLite Version 3}
|
header {C/C++ Interface For SQLite Version 3}
|
||||||
puts {
|
puts {
|
||||||
@ -1006,9 +1006,11 @@ int sqlite3_step(sqlite3_stmt*);
|
|||||||
api {} {
|
api {} {
|
||||||
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
|
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
|
||||||
} {
|
} {
|
||||||
Register a function that is called at every invocation of sqlite3_exec()
|
Register a function that is called each time an SQL statement is evaluated.
|
||||||
or sqlite3_prepare(). This function can be used (for example) to generate
|
The callback function is invoked on the first call to sqlite3_step() after
|
||||||
a log file of all SQL executed against a database. This is frequently
|
calls to sqlite3_prepare() or sqlite3_reset().
|
||||||
|
This function can be used (for example) to generate
|
||||||
|
a log file of all SQL executed against a database. This can be
|
||||||
useful when debugging an application that uses SQLite.
|
useful when debugging an application that uses SQLite.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user