/ Check-in [99ee7ee5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the sqlite3_expanded_sql() interface. Refinements to the sqlite3_trace_v2() interface to make it more useful.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sqlite3_trace_v2
Files: files | file ages | folders
SHA1:99ee7ee58d45b29a0000492306ddc0b90563ff51
User & Date: drh 2016-07-14 01:09:08
Context
2016-07-14
01:13
Fix a parameter misordering on sqlite3_trace_v2() in the loadable extension interface. check-in: 989de2d5 user: drh tags: sqlite3_trace_v2
01:09
Add the sqlite3_expanded_sql() interface. Refinements to the sqlite3_trace_v2() interface to make it more useful. check-in: 99ee7ee5 user: drh tags: sqlite3_trace_v2
2016-07-13
23:18
Legacy tests now passing. check-in: f33526a3 user: drh tags: sqlite3_trace_v2
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832

1833
1834
1835
1836
1837
1838
1839
1840
** is returned.  
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** 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;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pOld = db->pTraceArg;
  db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
  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







|











|









|
<
|
>
|







1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830

1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
** is returned.  
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** 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;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pOld = db->pTraceArg;
  db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
  db->xTrace = (int(*)(u32,void*,void*,void*))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 */

  unsigned mTrace,                           /* Mask of events to be traced */
  int(*xTrace)(unsigned,void*,void*,void*),  /* Callback to invoke */
  void *pArg                                 /* Context */
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif

Changes to src/sqlite.h.in.

2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
....
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
....
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887

2888
2889
2890
2891
2892
2893
2894
....
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511


















3512
3513

3514
3515
3516
3517
3518
3519
3520
**
** New tracing constants may be added in future releases.
**
** A trace callback has four arguments: xCallback(T,C,P,X).
** The T argument is one of the integer type codes above.
** 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 64-bit integer whose meaning also
** depends on T.
**
** <dl>
** [[SQLITE_TRACE_SQL]] <dt>SQLITE_TRACE_SQL</dt>
** <dd>An SQLITE_TRACE_SQL callback provides the same functionality
** as the legacy [sqlite3_trace()] callback.
** The P argument is a pointer to the constant UTF-8 string that is text
** describing an SQL statement that is starting to run with all
** [bound parameter] expanded.  The X argument is unused.  The size
** of the expansion of [bound parameters] is limited by the
** [SQLITE_TRACE_SIZE_LIMIT] compile-time option.
**
** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
** <dd>An SQLITE_TRACE_STMT callback is invoked on the same occasions
** as SQLITE_TRACE_SQL.  The difference is that the P argument is a
** pointer to the [prepared statement] rather than an SQL string.
** The X argument is unused.
**
** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
** <dd>An SQLITE_TRACE_PROFILE callback provides approximately the same
** information as is provided by the [sqlite3_profile()] callback.
** The P argument is a pointer to the [prepared statement] and the
** X argument is an estimate of the number of nanosecond for which
** the prepared statement ran.  The SQLITE_TRACE_PROFILE callback is
** invoked when the statement finishes.
**
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
** <dd>An SQLITE_TRACE_ROW callback is invoked whenever a prepared
** statement generates a single row of result.  
** The P argument is a pointer to the [prepared statement] and the
** X argument is unused.
**
................................................................................
** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
** <dd>An SQLITE_TRACE_CLOSE callback is invoked when a database
** connection closes.
** The P argument is a pointer to the [database connection] object
** and the X argument is unused.
** </dl>
*/
#define SQLITE_TRACE_SQL        0x0001
#define SQLITE_TRACE_STMT       0x0002
#define SQLITE_TRACE_PROFILE    0x0004
#define SQLITE_TRACE_ROW        0x0008
#define SQLITE_TRACE_CLOSE      0x0010

/*
** CAPI3REF: SQL Trace Hook
** METHOD: sqlite3
**
** The sqlite3_trace_v2(D,X,M,P) interface registers a trace callback
** function X against [database connection] D, using property mask M
** and context pointer P.  If the X callback is
** NULL or if the M mask is zero, then tracing is disabled.  The
** M argument must be one or more of the [SQLITE_TRACE]
** constants.
**
** Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides 
................................................................................
** ignored, though this may change in future releases.  Callback
** implementations should return zero to ensure future compatibility.
**
** A trace callback is invoked with four arguments: callback(T,C,P,X).
** 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 a 64-bit integer
** whose meanings depend on T.
**
** The sqlite3_trace_v2() interface is intended to replace the legacy
** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
** are deprecated.
*/
int sqlite3_trace_v2(
  sqlite3*,
  int(*xCallback)(unsigned,void*,void*,sqlite3_int64),
  unsigned uMask,

  void *pCtx
);

/*
** CAPI3REF: Query Progress Callbacks
** METHOD: sqlite3
**
................................................................................
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);

/*
** CAPI3REF: Retrieving Statement SQL
** METHOD: sqlite3_stmt
**
** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].


















*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);


/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to







|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<





|
|
|







 







<
|
|
|
|





|







 







<
|







<

>







 







|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>







2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817








2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
....
2833
2834
2835
2836
2837
2838
2839

2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
....
2861
2862
2863
2864
2865
2866
2867

2868
2869
2870
2871
2872
2873
2874
2875

2876
2877
2878
2879
2880
2881
2882
2883
2884
....
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
**
** New tracing constants may be added in future releases.
**
** A trace callback has four arguments: xCallback(T,C,P,X).
** The T argument is one of the integer type codes above.
** The C argument is a copy of the context pointer passed in as the
** fourth argument to [sqlite3_trace_v2()].
** The P and X arguments are pointers whose meanings depend on T.
**
** <dl>
** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
** <dd>An SQLITE_TRACE_STMT callback is invoked when a prepared statement
** first begins running and possibly at other times during the
** execution of the prepared statement, such as at the start of each
** trigger subprogram.  The P argument is a pointer to the
** [prepared statement].  The X argument is a pointer to a string which
** is the expanded SQL text of the prepared statement or a comment that
** indicates the invocation of a trigger.








**
** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
** <dd>An SQLITE_TRACE_PROFILE callback provides approximately the same
** information as is provided by the [sqlite3_profile()] callback.
** The P argument is a pointer to the [prepared statement] and the
** X argument points to a 64-bit integer which is the estimated of
** the number of nanosecond that the prepared statement took to run.
** The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
**
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
** <dd>An SQLITE_TRACE_ROW callback is invoked whenever a prepared
** statement generates a single row of result.  
** The P argument is a pointer to the [prepared statement] and the
** X argument is unused.
**
................................................................................
** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
** <dd>An SQLITE_TRACE_CLOSE callback is invoked when a database
** connection closes.
** The P argument is a pointer to the [database connection] object
** and the X argument is unused.
** </dl>
*/

#define SQLITE_TRACE_STMT       0x01
#define SQLITE_TRACE_PROFILE    0x02
#define SQLITE_TRACE_ROW        0x04
#define SQLITE_TRACE_CLOSE      0x08

/*
** CAPI3REF: SQL Trace Hook
** METHOD: sqlite3
**
** The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
** function X against [database connection] D, using property mask M
** and context pointer P.  If the X callback is
** NULL or if the M mask is zero, then tracing is disabled.  The
** M argument must be one or more of the [SQLITE_TRACE]
** constants.
**
** Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides 
................................................................................
** ignored, though this may change in future releases.  Callback
** implementations should return zero to ensure future compatibility.
**
** A trace callback is invoked with four arguments: callback(T,C,P,X).
** 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 pointers whose meanings depend on T.
**
** The sqlite3_trace_v2() interface is intended to replace the legacy
** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
** are deprecated.
*/
int sqlite3_trace_v2(
  sqlite3*,

  unsigned uMask,
  int(*xCallback)(unsigned,void*,void*,void*),
  void *pCtx
);

/*
** CAPI3REF: Query Progress Callbacks
** METHOD: sqlite3
**
................................................................................
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);

/*
** CAPI3REF: Retrieving Statement SQL
** METHOD: sqlite3_stmt
**
** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
** SQL text used to create [prepared statement] P if P was
** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
** string containing the SQL text of prepared statement P with
** [bound parameters] expanded.
**
** For example, if a prepared statement is created using the SQL
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
** and parameter :xyz is unbound, then sqlite3_sql() will return
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
** will return "SELECT 2345,NULL".
**
** The [SQLITE_TRACE_SIZE_LIMIT] setting limits the size of a 
** bound parameter expansion.
**
** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
** automatically freed when the prepared statement is finalized.
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to

Changes to src/sqlite3ext.h.

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
...
527
528
529
530
531
532
533

534
535
536
537
538
539
540
  /* Version 3.10.0 and later */
  int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
  int (*strlike)(const char*,const char*,unsigned int);
  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*);
};

/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
................................................................................
#define sqlite3_status64               sqlite3_api->status64
#define sqlite3_strlike                sqlite3_api->strlike
#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)
  /* This case when the file really is being compiled as a loadable 
  ** extension */
# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;







|
|







 







>







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
  /* Version 3.10.0 and later */
  int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
  int (*strlike)(const char*,const char*,unsigned int);
  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*,void*),unsigned,void*);
  char *(*expanded_sql)(sqlite3_stmt*);
};

/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
................................................................................
#define sqlite3_status64               sqlite3_api->status64
#define sqlite3_strlike                sqlite3_api->strlike
#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
#define sqlite3_expanded_sql           sqlite3_api->expanded_sql
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */

#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  /* This case when the file really is being compiled as a loadable 
  ** extension */
# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/sqliteInt.h.

1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  int nVdbeActive;              /* Number of VDBEs currently running */
  int nVdbeRead;                /* Number of active VDBEs that read or write */
  int nVdbeWrite;               /* Number of active VDBEs that read and write */
  int nVdbeExec;                /* Number of nested calls to VdbeExec() */
  int nVDestroy;                /* Number of active OP_VDestroy operations */
  int nExtension;               /* Number of loaded extensions */
  void **aExtension;            /* Array of shared library handles */
  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 */
  void *pCommitArg;                 /* Argument to xCommitCallback() */
  int (*xCommitCallback)(void*);    /* Invoked at every commit. */
  void *pRollbackArg;               /* Argument to xRollbackCallback() */
  void (*xRollbackCallback)(void*); /* Invoked at every commit. */







|







1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  int nVdbeActive;              /* Number of VDBEs currently running */
  int nVdbeRead;                /* Number of active VDBEs that read or write */
  int nVdbeWrite;               /* Number of active VDBEs that read and write */
  int nVdbeExec;                /* Number of nested calls to VdbeExec() */
  int nVDestroy;                /* Number of active OP_VDestroy operations */
  int nExtension;               /* Number of loaded extensions */
  void **aExtension;            /* Array of shared library handles */
  int (*xTrace)(u32,void*,void*,void*);     /* Trace function */
  void *pTraceArg;                          /* Argument to the trace function */
  void (*xProfile)(void*,const char*,u64);  /* Profiling function */
  void *pProfileArg;                        /* Argument to profile function */
  void *pCommitArg;                 /* Argument to xCommitCallback() */
  int (*xCommitCallback)(void*);    /* Invoked at every commit. */
  void *pRollbackArg;               /* Argument to xRollbackCallback() */
  void (*xRollbackCallback)(void*); /* Invoked at every commit. */

Changes to src/test1.c.

4382
4383
4384
4385
4386
4387
4388




















4389
4390
4391
4392
4393
4394
4395
....
7272
7273
7274
7275
7276
7277
7278

7279
7280
7281
7282
7283
7284
7285
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
  return TCL_OK;
}





















/*
** Usage: sqlite3_column_count STMT 
**
** Return the number of columns returned by the sql statement STMT.
*/
static int test_column_count(
................................................................................
     { "sqlite3_stmt_status",           test_stmt_status   ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },
     { "sqlite3_sql",                   test_sql           ,0 },

     { "sqlite3_next_stmt",             test_next_stmt     ,0 },
     { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
     { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
     { "uses_stmt_journal",             uses_stmt_journal ,0 },

     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_db_release_memory",     test_db_release_memory,  0},







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
....
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
  return TCL_OK;
}
static int test_ex_sql(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_stmt *pStmt;
  char *z;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "STMT");
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  z = sqlite3_expanded_sql(pStmt);
  Tcl_SetResult(interp, z, TCL_VOLATILE);
  sqlite3_free(z);
  return TCL_OK;
}

/*
** Usage: sqlite3_column_count STMT 
**
** Return the number of columns returned by the sql statement STMT.
*/
static int test_column_count(
................................................................................
     { "sqlite3_stmt_status",           test_stmt_status   ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },
     { "sqlite3_sql",                   test_sql           ,0 },
     { "sqlite3_expanded_sql",          test_ex_sql        ,0 },
     { "sqlite3_next_stmt",             test_next_stmt     ,0 },
     { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
     { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
     { "uses_stmt_journal",             uses_stmt_journal ,0 },

     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_db_release_memory",     test_db_release_memory,  0},

Changes to src/vdbe.c.

6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808

6809
6810
6811
6812
6813
6814
6815
** If P2 is not zero, jump to instruction P2.
*/
case OP_Init: {          /* jump */
  char *zTrace;
  char *z;

#ifndef SQLITE_OMIT_TRACE
  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
  ){
    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);
  if( zTrace ){
    int i;
    for(i=0; i<db->nDb; i++){
      if( DbMaskTest(p->btreeMask, i)==0 ) continue;







|



<
|

|
<
|
|
|

|
<
<
<
<
<
|

>







6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791

6792
6793
6794

6795
6796
6797
6798
6799





6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
** If P2 is not zero, jump to instruction P2.
*/
case OP_Init: {          /* jump */
  char *zTrace;
  char *z;

#ifndef SQLITE_OMIT_TRACE
  if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
   && !p->doingRerun
   && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
  ){

    z = sqlite3VdbeExpandSql(p, zTrace);
#ifndef SQLITE_OMIT_DEPRECATED
    if( db->mTrace & SQLITE_TRACE_LEGACY ){

      void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace;
      x(db->pTraceArg, z);
    }else
#endif
    {





      (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,z);
    }
    sqlite3_free(z);
  }
#ifdef SQLITE_USE_FCNTL_TRACE
  zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
  if( zTrace ){
    int i;
    for(i=0; i<db->nDb; i++){
      if( DbMaskTest(p->btreeMask, i)==0 ) continue;

Changes to src/vdbeapi.c.

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  assert( p->zSql!=0 );
  sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
  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;
}
/*
** The checkProfileCallback(DB,P) macro checks to see if a profile callback
** is needed, and it invokes the callback if it is needed.
*/







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  assert( p->zSql!=0 );
  sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
  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, (void*)&iElapse);
  }
  p->startTime = 0;
}
/*
** The checkProfileCallback(DB,P) macro checks to see if a profile callback
** is needed, and it invokes the callback if it is needed.
*/

Changes to src/vdbeaux.c.

67
68
69
70
71
72
73















74
75
76
77
78
79
80
/*
** Return the SQL associated with a prepared statement
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe *)pStmt;
  return p ? p->zSql : 0;
}
















/*
** Swap all content between two VDBE structures.
*/
void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
  Vdbe tmp, *pTmp;
  char *zTmp;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
** Return the SQL associated with a prepared statement
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe *)pStmt;
  return p ? p->zSql : 0;
}

/*
** Return the SQL associated with a prepared statement with
** bound parameters expanded.  Space to hold the returned string is
** obtained from sqlite3_malloc().  The caller is responsible for
** freeing the returned string by passing it to sqlite3_free().
**
** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
** expanded bound parameters.
*/
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe *)pStmt;
  return p ? sqlite3VdbeExpandSql(p, p->zSql) : 0;
  if( p->zSql==0 ) return 0;
}

/*
** Swap all content between two VDBE structures.
*/
void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
  Vdbe tmp, *pTmp;
  char *zTmp;

Changes to src/vdbetrace.c.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  int nToken;              /* Length of the parameter token */
  int i;                   /* Loop counter */
  Mem *pVar;               /* Value of a host parameter */
  StrAccum out;            /* Accumulate the output here */
  char zBase[100];         /* Initial working space */

  db = p->db;
  sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), 
                      db->aLimit[SQLITE_LIMIT_LENGTH]);
  if( db->nVdbeExec>1 ){
    while( *zRawSql ){
      const char *zStart = zRawSql;
      while( *(zRawSql++)!='\n' && *zRawSql );
      sqlite3StrAccumAppend(&out, "-- ", 3);
      assert( (zRawSql - zStart) > 0 );







|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  int nToken;              /* Length of the parameter token */
  int i;                   /* Loop counter */
  Mem *pVar;               /* Value of a host parameter */
  StrAccum out;            /* Accumulate the output here */
  char zBase[100];         /* Initial working space */

  db = p->db;
  sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), 
                      db->aLimit[SQLITE_LIMIT_LENGTH]);
  if( db->nVdbeExec>1 ){
    while( *zRawSql ){
      const char *zStart = zRawSql;
      while( *(zRawSql++)!='\n' && *zRawSql );
      sqlite3StrAccumAppend(&out, "-- ", 3);
      assert( (zRawSql - zStart) > 0 );