-C Change\ssqlite3StrAccumAppend()\sto\suse\srealloc\sinstead\sof\smalloc.
-D 2011-01-21T18:25:30
+C Modify\sthe\strace\scallback\smechanism\sso\sthat\sSQL\scommands\sexecuted\sfrom\swithin\svirtual\stable\sor\suser\sfunction\scallbacks\sare\spassed\sto\sthe\strace\scallback\swithout\sparameter\sexpansion\sand\senclosed\sin\sSQL\scomments.
+D 2011-01-22T13:32:30
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in de6498556d536ae60bb8bb10e8c1ba011448658c
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
-F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
+F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk 05d0f3475dd331896bd607cfb45c5e21b94589ad
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F src/shell.c 83c6f0cc5a79a081c7b9ddfe4f557b47e0bad976
F src/sqlite.h.in 45ae5d463b5b341420b3cbc236fb1dfb5c0cd1a8
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
-F src/sqliteInt.h 3ef5fc89a4c9755a08a68de107493785a284e27c
+F src/sqliteInt.h 45926deaf59b1ce3f55d21d5f91a8cecb6a7eb4c
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/vdbe.c 5d310eaf1a4d8383602126fa82e01291ab7d3cf3
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0
-F src/vdbeapi.c 69c82283ab2b64c0c37a07799d771d4058330743
+F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d
F src/vdbeaux.c 33448d23b857654dd69ed2103611f5c733606f68
F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c
F src/vdbemem.c 411649a35686f54268ccabeda175322c4697f5a6
-F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
+F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5
F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
F src/wal.c dbca424f71678f663a286ab2a98f947af1d412a7
F src/wal.h c1aac6593a0b02b15dc625987e619edeab39292e
F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/trace.test 4b36a41a3e9c7842151af6da5998f5080cdad9e5
+F test/trace2.test 092bc2c5776272700450d60a36919921095bdc21
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
F test/trans3.test d728abaa318ca364dc370e06576aa7e5fbed7e97
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 503ad889da675b3dd83da7338e2902e42f69acac
-R 581c91bca4bed9e9c246127dfff2a86d
+P 380f61df0754ceec6b3f6a758d04e951cce8c3d9
+R 90a5119ad79fbdf46155bfdda925f6c3
U dan
-Z 1951ee9d42233f0fe4bd03e6cd0ae9e1
+Z 22ba801a4079136db1b6273b2820344e
-380f61df0754ceec6b3f6a758d04e951cce8c3d9
\ No newline at end of file
+a764915b87564fa91ee68e9b1f41394ce0f1fc7e
\ No newline at end of file
struct Vdbe *pVdbe; /* List of active virtual machines */
int activeVdbeCnt; /* Number of VDBEs currently executing */
int writeVdbeCnt; /* Number of active VDBEs that are writing */
+ int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
void (*xTrace)(void*,const char*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */
}else
#endif /* SQLITE_OMIT_EXPLAIN */
{
+ db->vdbeExecCnt++;
rc = sqlite3VdbeExec(p);
+ db->vdbeExecCnt--;
}
#ifndef SQLITE_OMIT_TRACE
}
/*
-** Return a pointer to a string in memory obtained form sqlite3DbMalloc() which
-** holds a copy of zRawSql but with host parameters expanded to their
-** current bindings.
+** This function returns a pointer to a nul-terminated string in memory
+** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
+** string contains a copy of zRawSql but with host parameters expanded to
+** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1,
+** then the returned string holds a copy of zRawSql with "-- " prepended
+** to each line of text.
**
** The calling function is responsible for making sure the memory returned
** is eventually freed.
sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
out.db = db;
- while( zRawSql[0] ){
- n = findNextHostParameter(zRawSql, &nToken);
- assert( n>0 );
- sqlite3StrAccumAppend(&out, zRawSql, n);
- zRawSql += n;
- assert( zRawSql[0] || nToken==0 );
- if( nToken==0 ) break;
- if( zRawSql[0]=='?' ){
- if( nToken>1 ){
- assert( sqlite3Isdigit(zRawSql[1]) );
- sqlite3GetInt32(&zRawSql[1], &idx);
+ if( db->vdbeExecCnt>1 ){
+ while( *zRawSql ){
+ const char *zStart = zRawSql;
+ while( *(zRawSql++)!='\n' && *zRawSql );
+ sqlite3StrAccumAppend(&out, "-- ", 3);
+ sqlite3StrAccumAppend(&out, zStart, zRawSql-zStart);
+ }
+ }else{
+ while( zRawSql[0] ){
+ n = findNextHostParameter(zRawSql, &nToken);
+ assert( n>0 );
+ sqlite3StrAccumAppend(&out, zRawSql, n);
+ zRawSql += n;
+ assert( zRawSql[0] || nToken==0 );
+ if( nToken==0 ) break;
+ if( zRawSql[0]=='?' ){
+ if( nToken>1 ){
+ assert( sqlite3Isdigit(zRawSql[1]) );
+ sqlite3GetInt32(&zRawSql[1], &idx);
+ }else{
+ idx = nextIndex;
+ }
}else{
- idx = nextIndex;
+ assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
+ testcase( zRawSql[0]==':' );
+ testcase( zRawSql[0]=='$' );
+ testcase( zRawSql[0]=='@' );
+ idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
+ assert( idx>0 );
}
- }else{
- assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
- testcase( zRawSql[0]==':' );
- testcase( zRawSql[0]=='$' );
- testcase( zRawSql[0]=='@' );
- idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
- assert( idx>0 );
- }
- zRawSql += nToken;
- nextIndex = idx + 1;
- assert( idx>0 && idx<=p->nVar );
- pVar = &p->aVar[idx-1];
- if( pVar->flags & MEM_Null ){
- sqlite3StrAccumAppend(&out, "NULL", 4);
- }else if( pVar->flags & MEM_Int ){
- sqlite3XPrintf(&out, "%lld", pVar->u.i);
- }else if( pVar->flags & MEM_Real ){
- sqlite3XPrintf(&out, "%!.15g", pVar->r);
- }else if( pVar->flags & MEM_Str ){
+ zRawSql += nToken;
+ nextIndex = idx + 1;
+ assert( idx>0 && idx<=p->nVar );
+ pVar = &p->aVar[idx-1];
+ if( pVar->flags & MEM_Null ){
+ sqlite3StrAccumAppend(&out, "NULL", 4);
+ }else if( pVar->flags & MEM_Int ){
+ sqlite3XPrintf(&out, "%lld", pVar->u.i);
+ }else if( pVar->flags & MEM_Real ){
+ sqlite3XPrintf(&out, "%!.15g", pVar->r);
+ }else if( pVar->flags & MEM_Str ){
#ifndef SQLITE_OMIT_UTF16
- u8 enc = ENC(db);
- if( enc!=SQLITE_UTF8 ){
- Mem utf8;
- memset(&utf8, 0, sizeof(utf8));
- utf8.db = db;
- sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
- sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
- sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
- sqlite3VdbeMemRelease(&utf8);
- }else
+ u8 enc = ENC(db);
+ if( enc!=SQLITE_UTF8 ){
+ Mem utf8;
+ memset(&utf8, 0, sizeof(utf8));
+ utf8.db = db;
+ sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
+ sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
+ sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
+ sqlite3VdbeMemRelease(&utf8);
+ }else
#endif
- {
- sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
- }
- }else if( pVar->flags & MEM_Zero ){
- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
- }else{
- assert( pVar->flags & MEM_Blob );
- sqlite3StrAccumAppend(&out, "x'", 2);
- for(i=0; i<pVar->n; i++){
- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+ {
+ sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
+ }
+ }else if( pVar->flags & MEM_Zero ){
+ sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
+ }else{
+ assert( pVar->flags & MEM_Blob );
+ sqlite3StrAccumAppend(&out, "x'", 2);
+ for(i=0; i<pVar->n; i++){
+ sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+ }
+ sqlite3StrAccumAppend(&out, "'", 1);
}
- sqlite3StrAccumAppend(&out, "'", 1);
}
}
return sqlite3StrAccumFinish(&out);
--- /dev/null
+# 2011 Jan 21
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+# This file implements tests for the "sqlite3_trace()" API. Specifically,
+# it tests the special handling of nested SQL statements (those executed
+# by virtual table or user function callbacks). These statements are treated
+# differently in two respects:
+#
+# 1. Each line of the statement is prefixed with "-- " to turn it into
+# an SQL comment.
+#
+# 2. Parameter expansion is not performed.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+ifcapable !trace { finish_test ; return }
+set ::testprefix trace2
+
+proc sql {zSql} { db one $zSql }
+proc trace {zSql} { lappend ::trace $zSql }
+
+db func sql sql
+db trace trace
+
+proc do_trace_test {tn sql expected} {
+ # Test that the list of string passed to the trace callback when $sql
+ # is executed is equivalent to the list of strings in $expected.
+ #
+ set ::trace [list]
+ execsql $sql
+ uplevel do_test $tn [list {set ::trace}] [list [list {*}$expected]]
+}
+
+proc do_trace_select_test {tn sql expected} {
+
+ uplevel [list do_trace_test ${tn}.a $sql $expected]
+
+ # Now execute each SQL statement passed to the trace callback in the
+ # block above. Check that this causes the same set of strings to be
+ # passed to the trace callback again. i.e. that executing the output
+ # of the trace callback is equivalent to the SQL script in $sql.
+ #
+ set sqllist $::trace
+ set ::trace [list]
+ foreach item $sqllist { execsql $item }
+ uplevel do_test $tn.b [list {set ::trace}] [list $sqllist]
+}
+
+do_trace_select_test 1.1 {
+ SELECT 1, 2, 3;
+} {
+ "SELECT 1, 2, 3;"
+}
+
+do_trace_select_test 1.2 {
+ SELECT sql('SELECT 1, 2, 3');
+} {
+ "SELECT sql('SELECT 1, 2, 3');"
+ "-- SELECT 1, 2, 3"
+}
+
+do_trace_select_test 1.3 {
+ SELECT sql('SELECT 1,
+ 2,
+ 3'
+ );
+} {
+ "SELECT sql('SELECT 1,
+ 2,
+ 3'
+ );"
+ "-- SELECT 1,
+-- 2,
+-- 3"
+}
+
+do_trace_select_test 1.4 {
+ SELECT sql('SELECT 1,
+
+
+ 3'
+ );
+} {
+ "SELECT sql('SELECT 1,
+
+
+ 3'
+ );"
+ "-- SELECT 1,
+--
+--
+-- 3"
+}
+
+do_trace_select_test 1.5 {
+ SELECT $var, sql('SELECT 1,
+ $var,
+ 3'
+ );
+} {
+ "SELECT NULL, sql('SELECT 1,
+ $var,
+ 3'
+ );"
+ "-- SELECT 1,
+-- $var,
+-- 3"
+}
+
+ifcapable fts3 {
+ do_execsql_test 2.1 {
+ CREATE VIRTUAL TABLE x1 USING fts4;
+ INSERT INTO x1 VALUES('Cloudy, with a high near 16');
+ INSERT INTO x1 VALUES('Wind chill values as low as -13');
+ }
+
+ do_trace_test 2.2 {
+ INSERT INTO x1 VALUES('North northwest wind between 8 and 14 mph');
+ } {
+ "INSERT INTO x1 VALUES('North northwest wind between 8 and 14 mph');"
+ "-- INSERT INTO 'main'.'x1_content' VALUES(?,?)"
+ "-- REPLACE INTO 'main'.'x1_docsize' VALUES(?,?)"
+ "-- SELECT value FROM 'main'.'x1_stat' WHERE id=0"
+ "-- REPLACE INTO 'main'.'x1_stat' VALUES(0,?)"
+ "-- SELECT (SELECT max(idx) FROM 'main'.'x1_segdir' WHERE level = ?) + 1"
+ "-- SELECT coalesce((SELECT max(blockid) FROM 'main'.'x1_segments') + 1, 1)"
+ "-- INSERT INTO 'main'.'x1_segdir' VALUES(?,?,?,?,?,?)"
+ }
+
+ do_trace_test 2.3 {
+ INSERT INTO x1(x1) VALUES('optimize');
+ } {
+ "INSERT INTO x1(x1) VALUES('optimize');"
+ "-- SELECT count(*), max(level) FROM 'main'.'x1_segdir'"
+ "-- SELECT idx, start_block, leaves_end_block, end_block, root FROM 'main'.'x1_segdir' ORDER BY level DESC, idx ASC"
+ "-- SELECT coalesce((SELECT max(blockid) FROM 'main'.'x1_segments') + 1, 1)"
+ "-- DELETE FROM 'main'.'x1_segdir'"
+ "-- INSERT INTO 'main'.'x1_segdir' VALUES(?,?,?,?,?,?)"
+ }
+}
+
+finish_test