aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-07-13 22:55:01 +0000
committerdrh <drh@noemail.net>2016-07-13 22:55:01 +0000
commit3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77 (patch)
tree165c74f465692f09861bb4900041949dad8c125b /src
parented916ba02514b2714e61e91eb478e4d2d6f243df (diff)
downloadsqlite-3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77.tar.gz
sqlite-3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77.zip
First cut at implementing the new sqlite3_trace_v2() interface.
FossilOrigin-Name: cb0062feb018f52689938a58cb76886d431c33f0
Diffstat (limited to 'src')
-rw-r--r--src/main.c31
-rw-r--r--src/sqlite.h.in6
-rw-r--r--src/sqlite3ext.h5
-rw-r--r--src/sqliteInt.h12
-rw-r--r--src/vacuum.c6
-rw-r--r--src/vdbe.c26
-rw-r--r--src/vdbeapi.c14
7 files changed, 85 insertions, 15 deletions
diff --git a/src/main.c b/src/main.c
index 30370f8ca..d2f8bf799 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1033,6 +1033,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
+ if( db->mTrace & SQLITE_TRACE_CLOSE ){
+ db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
+ }
/* Force xDisconnect calls on all virtual tables */
disconnectAllVtab(db);
@@ -1801,6 +1804,7 @@ int sqlite3_overload_function(
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
+#ifndef SQLITE_OMIT_DEPRECATED
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld;
@@ -1812,11 +1816,36 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pTraceArg;
- db->xTrace = xTrace;
+ db->mTrace = SQLITE_TRACE_LEGACY;
+ db->xTrace = (int(*)(u32,void*,void*,i64))xTrace;
db->pTraceArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
+#endif /* SQLITE_OMIT_DEPRECATED */
+
+/* Register a trace callback using the version-2 interface.
+*/
+int sqlite3_trace_v2(
+ sqlite3 *db, /* Trace this connection */
+ int(*xTrace)(unsigned,void*,void*,sqlite3_int64), /* Callback to invoke */
+ unsigned mTrace, /* OPs to be traced */
+ void *pArg /* Context */
+){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ db->mTrace = mTrace;
+ db->xTrace = xTrace;
+ db->pTraceArg = pArg;
+ sqlite3_mutex_leave(db->mutex);
+ return SQLITE_OK;
+}
+
/*
** Register a profile function. The pArg from the previously registered
** profile function is returned.
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index a3b8f31f0..07d85b254 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -2805,7 +2805,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** The C argument is a copy of the context pointer passed in as the
** fourth argument to [sqlite3_trace_v2()].
** The P argument is a pointer whose meaning depends on T.
-** The X argument is an unsigned 64-bit integer whose meaning also
+** The X argument is an 64-bit integer whose meaning also
** depends on T.
**
** <dl>
@@ -2874,7 +2874,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** The T argument is one of the [SQLITE_TRACE]
** constants to indicate why the callback was invoked.
** The C argument is a copy of the context pointer.
-** The P and X arguments are a pointer and an unsigned 64-bit integer
+** The P and X arguments are a pointer and a 64-bit integer
** whose meanings depend on T.
**
** The sqlite3_trace_v2() interface is intended to replace the legacy
@@ -2883,7 +2883,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
*/
int sqlite3_trace_v2(
sqlite3*,
- int(*xCallback)(unsigned,void*,void*,sqlite3_uint64),
+ int(*xCallback)(unsigned,void*,void*,sqlite3_int64),
unsigned uMask,
void *pCtx
);
diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h
index 2d38e87ae..8bcfc6852 100644
--- a/src/sqlite3ext.h
+++ b/src/sqlite3ext.h
@@ -281,6 +281,9 @@ struct sqlite3_api_routines {
int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */
int (*system_errno)(sqlite3*);
+ /* Version 3.14.0 and later */
+ int (*trace_v2)(sqlite3*,int(*)(unsigned,void*,void*,sqlite3_uint64),
+ unsigned,void*);
};
/*
@@ -526,6 +529,8 @@ struct sqlite3_api_routines {
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno
+/* Version 3.14.0 and later */
+#define sqlite3_trace_v2 sqlite3_api->trace_v2
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 998a17dac..225d7b287 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1241,6 +1241,15 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
const char*);
#endif
+#ifndef SQLITE_OMIT_DEPRECATED
+/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
+** in the style of sqlite3_trace()
+*/
+#define SQLITE_TRACE_LEGACY 0x80
+#else
+#define SQLITE_TRACE_LEGACY 0
+#endif /* SQLITE_OMIT_DEPRECATED */
+
/*
** Each database connection is an instance of the following structure.
@@ -1270,6 +1279,7 @@ struct sqlite3 {
u8 suppressErr; /* Do not issue error messages if true */
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
+ u8 mTrace; /* zero or more SQLITE_TRACE flags */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */
@@ -1290,7 +1300,7 @@ struct sqlite3 {
int nVDestroy; /* Number of active OP_VDestroy operations */
int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */
- void (*xTrace)(void*,const char*); /* Trace function */
+ int (*xTrace)(u32,void*,void*,i64); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
diff --git a/src/vacuum.c b/src/vacuum.c
index bc7b5831b..93b438fb1 100644
--- a/src/vacuum.c
+++ b/src/vacuum.c
@@ -121,7 +121,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
int saved_flags; /* Saved value of the db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
- void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */
+ u8 saved_mTrace; /* Saved trace settings */
Db *pDb = 0; /* Database to detach at end of vacuum */
int isMemDb; /* True if vacuuming a :memory: database */
int nRes; /* Bytes of reserved space at the end of each page */
@@ -142,7 +142,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
saved_flags = db->flags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
- saved_xTrace = db->xTrace;
+ saved_mTrace = db->mTrace;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
db->xTrace = 0;
@@ -345,7 +345,7 @@ end_of_vacuum:
db->flags = saved_flags;
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
- db->xTrace = saved_xTrace;
+ db->mTrace = saved_mTrace;
sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
/* Currently there is an SQL level transaction open on the vacuum
diff --git a/src/vdbe.c b/src/vdbe.c
index 6adbcbbec..788353602 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -1383,6 +1383,10 @@ case OP_ResultRow: {
}
if( db->mallocFailed ) goto no_mem;
+ if( db->mTrace & SQLITE_TRACE_ROW ){
+ db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
+ }
+
/* Return SQLITE_ROW
*/
p->pc = (int)(pOp - aOp) + 1;
@@ -6781,13 +6785,27 @@ case OP_Init: { /* jump */
char *z;
#ifndef SQLITE_OMIT_TRACE
- if( db->xTrace
+ if( (db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
&& !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
- z = sqlite3VdbeExpandSql(p, zTrace);
- db->xTrace(db->pTraceArg, z);
- sqlite3DbFree(db, z);
+ if( db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_LEGACY) ){
+ z = sqlite3VdbeExpandSql(p, zTrace);
+#ifndef SQLITE_OMIT_DEPRECATED
+ if( SQLITE_TRACE_LEGACY ){
+ void (*x)(void*,const char*);
+ x = (void(*)(void*,const char*))db->xTrace;
+ x(db->pTraceArg, z);
+ }else
+#endif
+ {
+ db->xTrace(SQLITE_TRACE_SQL,db->pTraceArg,z,0);
+ }
+ sqlite3DbFree(db, z);
+ }
+ if( db->mTrace & SQLITE_TRACE_STMT ){
+ (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,0);
+ }
}
#ifdef SQLITE_USE_FCNTL_TRACE
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 83718eae3..a602fad38 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -60,12 +60,19 @@ static int vdbeSafetyNotNull(Vdbe *p){
*/
static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
sqlite3_int64 iNow;
+ sqlite3_int64 iElapse;
assert( p->startTime>0 );
- assert( db->xProfile!=0 );
+ assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
assert( db->init.busy==0 );
assert( p->zSql!=0 );
sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
- db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
+ iElapse = (iNow - p->startTime)*1000000;
+ if( db->xProfile ){
+ db->xProfile(db->pProfileArg, p->zSql, iElapse);
+ }
+ if( db->mTrace & SQLITE_TRACE_PROFILE ){
+ db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, iElapse);
+ }
p->startTime = 0;
}
/*
@@ -569,7 +576,8 @@ static int sqlite3Step(Vdbe *p){
);
#ifndef SQLITE_OMIT_TRACE
- if( db->xProfile && !db->init.busy && p->zSql ){
+ if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
+ && !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
}else{
assert( p->startTime==0 );