diff options
author | dan <dan@noemail.net> | 2015-11-12 20:12:51 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2015-11-12 20:12:51 +0000 |
commit | d83f7ca1140e152f9bfa4ad2e07d78c167a5d203 (patch) | |
tree | 6adc82a760359ffa7e178179ed243f86ebbc259f | |
parent | c2e0dd4ddd81abbbb25200495df450afa794b9b6 (diff) | |
download | sqlite-d83f7ca1140e152f9bfa4ad2e07d78c167a5d203.tar.gz sqlite-d83f7ca1140e152f9bfa4ad2e07d78c167a5d203.zip |
Add support for the SQLITE_SQLLOG_CONDITIONAL environment variable to the logging code in test_sqllog.c. When defined, logging is only performed if the "<database>-sqllog" file is present in the file system when the main database is opened.
FossilOrigin-Name: cab8126be9f63dd596719b12704ba77c128282bc
-rw-r--r-- | manifest | 26 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 8 | ||||
-rw-r--r-- | src/test1.c | 25 | ||||
-rw-r--r-- | src/test_config.c | 6 | ||||
-rw-r--r-- | src/test_sqllog.c | 81 | ||||
-rw-r--r-- | test/sqllog.test | 116 | ||||
-rw-r--r-- | test/trigger7.test | 1 |
9 files changed, 239 insertions, 32 deletions
@@ -1,5 +1,5 @@ -C Enhance\sthe\s"PRAGMA\scache_spill"\sstatement\sto\saccept\san\sinteger\sargument\swhich\nis\sthe\sthreshold\sat\swhich\sspilling\swill\sbegin. -D 2015-11-12T16:44:40.812 +C Add\ssupport\sfor\sthe\sSQLITE_SQLLOG_CONDITIONAL\senvironment\svariable\sto\sthe\slogging\scode\sin\stest_sqllog.c.\sWhen\sdefined,\slogging\sis\sonly\sperformed\sif\sthe\s"<database>-sqllog"\sfile\sis\spresent\sin\sthe\sfile\ssystem\swhen\sthe\smain\sdatabase\sis\sopened. +D 2015-11-12T20:12:51.646 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -304,7 +304,7 @@ F src/insert.c 419a947f27ce2da18eebf440a5aa80cc825defae F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c f393acc6e5d604cbe0054376d62f668a5560b3f1 +F src/main.c bf26fbebab82069cd7d15c41a58110be8075c87e F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -344,12 +344,12 @@ F src/shell.c acefb4593a9bf0338a757c968f1f1bb05690d830 F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 -F src/sqliteInt.h bc6d24460fe544323517630b1e20539146379077 +F src/sqliteInt.h ebd88d3a2c03440f48145a47df51f0a502bbf24e F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 -F src/test1.c a719afff3144f7f01c6dc3f7d118ac31d15e7527 +F src/test1.c 05df2a9e4f483b2fb642162209e3aeb11c24b44f F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -363,7 +363,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c 426527fbb12fc23669a1e973ecdc8c5e92c2e2cf +F src/test_config.c 7523f8bd7604aec88a9d1c303d93c925bcfcc9f9 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -386,7 +386,7 @@ F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d F src/test_rtree.c 43fff4c5a01576d6d213f27472598801a247890c F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe -F src/test_sqllog.c b690c12933f50ff46491e0d56a251f84ae16e914 +F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa @@ -1038,6 +1038,7 @@ F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135 F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 F test/sqllimits1.test 89b3d5aad05b99f707ee3786bdd4416dccf83304 +F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953 F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 @@ -1226,7 +1227,7 @@ F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9 -F test/trigger7.test 200dd51e728c9cdc20c72d99d9e9d45c667248f8 +F test/trigger7.test 799c9d2561facef70340cc9e0dee98aee9b5bdfe F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4 F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41 F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332 @@ -1402,8 +1403,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f84e3085c87cfffe4aba0eb4c4a3298b4027db83 9a431362dccbc9b8f93375f30a3b8955903cca79 -R 5f87cb60f8f27cae7787baa81cd88247 -T +closed 9a431362dccbc9b8f93375f30a3b8955903cca79 -U drh -Z c0a66dbf9634d84e657f233ea4ee622f +P f79d264db24a470d1a4571e15a99cd3d68b5166c +R 832ba4972d7900eed0d1e5716cf55baa +U dan +Z 957802b71a98a3fb9167ff96a716895f diff --git a/manifest.uuid b/manifest.uuid index 9052b6aab..2eb3af561 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f79d264db24a470d1a4571e15a99cd3d68b5166c
\ No newline at end of file +cab8126be9f63dd596719b12704ba77c128282bc
\ No newline at end of file diff --git a/src/main.c b/src/main.c index 56d458849..138626746 100644 --- a/src/main.c +++ b/src/main.c @@ -220,6 +220,12 @@ int sqlite3_initialize(void){ if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); sqlite3GlobalConfig.inProgress = 1; +#ifdef SQLITE_INIT_SQLLOG + { + extern void SQLITE_INIT_SQLLOG(void); + SQLITE_INIT_SQLLOG(); + } +#endif memset(pHash, 0, sizeof(sqlite3GlobalFunctions)); sqlite3RegisterGlobalFunctions(); if( sqlite3GlobalConfig.isPCacheInit==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c65e0f205..fdd82f991 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -527,6 +527,14 @@ # define SQLITE_DEFAULT_PCACHE_INITSZ 100 #endif +/* +** If SQLITE_INIT_SQLLOG is defined, then SQLITE_ENABLE_SQLLOG is +** automatically defined as well. +*/ +#if defined(SQLITE_INIT_SQLLOG) && !defined(SQLITE_ENABLE_SQLLOG) +# define SQLITE_ENABLE_SQLLOG 1 +#endif + /* ** GCC does not define the offsetof() macro so we'll have to do it diff --git a/src/test1.c b/src/test1.c index 7ce4ed5a5..43feb2dc2 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2226,6 +2226,28 @@ static int test_stmt_scanstatus_reset( } #endif +#ifdef SQLITE_ENABLE_SQLLOG +/* +** Usage: sqlite3_config_sqllog +** +** Zero the SQLITE_CONFIG_SQLLOG configuration +*/ +static int test_config_sqllog( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; /* First argument */ + if( objc!=1 ){ + Tcl_WrongNumArgs(interp, 1, objv, ""); + return TCL_ERROR; + } + sqlite3_config(SQLITE_CONFIG_SQLLOG, 0, 0); + return TCL_OK; +} +#endif + /* ** Usage: sqlite3_next_stmt DB STMT ** @@ -7036,6 +7058,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 }, { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 }, #endif +#ifdef SQLITE_ENABLE_SQLLOG + { "sqlite3_config_sqllog", test_config_sqllog, 0 }, +#endif }; static int bitmask_size = sizeof(Bitmask)*8; diff --git a/src/test_config.c b/src/test_config.c index be43f87e7..4cb5c0057 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -657,6 +657,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_SQLLOG + Tcl_SetVar2(interp, "sqlite_options", "sqllog", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "sqllog", "0", TCL_GLOBAL_ONLY); +#endif + #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ diff --git a/src/test_sqllog.c b/src/test_sqllog.c index 6c0bf954b..31d5ad2f5 100644 --- a/src/test_sqllog.c +++ b/src/test_sqllog.c @@ -46,6 +46,12 @@ ** separate copy is taken each time the database file is opened or attached) ** by setting the environment variable SQLITE_SQLLOG_REUSE_FILES to 0. ** +** If the environment variable SQLITE_SQLLOG_CONDITIONAL is defined, then +** logging is only done for database connections if a file named +** "<database>-sqllog" exists in the same directly as the main database +** file when it is first opened ("<database>" is replaced by the actual +** name of the main database file). +** ** OUTPUT: ** ** The SQLITE_SQLLOG_DIR is populated with three types of files: @@ -88,6 +94,7 @@ static int getProcessId(void){ /* Names of environment variables to be used */ #define ENVIRONMENT_VARIABLE1_NAME "SQLITE_SQLLOG_DIR" #define ENVIRONMENT_VARIABLE2_NAME "SQLITE_SQLLOG_REUSE_FILES" +#define ENVIRONMENT_VARIABLE3_NAME "SQLITE_SQLLOG_CONDITIONAL" /* Assume that all database and database file names are shorted than this. */ #define SQLLOG_NAMESZ 512 @@ -116,6 +123,7 @@ static struct SLGlobal { int nConn; /* Size of aConn[] array */ /* Protected by SLGlobal.mutex */ + int bConditional; /* Only trace if *-sqllog file is present */ int bReuse; /* True to avoid extra copies of db files */ char zPrefix[SQLLOG_NAMESZ]; /* Prefix for all created files */ char zIdx[SQLLOG_NAMESZ]; /* Full path to *.idx file */ @@ -215,7 +223,7 @@ static char *sqllogFindFile(const char *zFile){ } static int sqllogFindAttached( - struct SLConn *p, /* Database connection */ + sqlite3 *db, /* Database connection */ const char *zSearch, /* Name to search for (or NULL) */ char *zName, /* OUT: Name of attached database */ char *zFile /* OUT: Name of attached file */ @@ -228,7 +236,7 @@ static int sqllogFindAttached( ** described by the last row returned. */ assert( sqllogglobal.bRec==0 ); sqllogglobal.bRec = 1; - rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, "PRAGMA database_list", -1, &pStmt, 0); if( rc==SQLITE_OK ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zVal1; int nVal1; @@ -236,7 +244,9 @@ static int sqllogFindAttached( zVal1 = (const char*)sqlite3_column_text(pStmt, 1); nVal1 = sqlite3_column_bytes(pStmt, 1); - memcpy(zName, zVal1, nVal1+1); + if( zName ){ + memcpy(zName, zVal1, nVal1+1); + } zVal2 = (const char*)sqlite3_column_text(pStmt, 2); nVal2 = sqlite3_column_bytes(pStmt, 2); @@ -285,7 +295,7 @@ static void sqllogCopydb(struct SLConn *p, const char *zSearch, int bLog){ char *zInit = 0; int rc; - rc = sqllogFindAttached(p, zSearch, zName, zFile); + rc = sqllogFindAttached(p->db, zSearch, zName, zFile); if( rc!=SQLITE_OK ) return; if( zFile[0]=='\0' ){ @@ -406,6 +416,35 @@ static void testSqllogStmt(struct SLConn *p, const char *zSql){ } /* +** The database handle passed as the only argument has just been opened. +** Return true if this module should log initial databases and SQL +** statements for this connection, or false otherwise. +** +** If an error occurs, sqlite3_log() is invoked to report it to the user +** and zero returned. +*/ +static int sqllogTraceDb(sqlite3 *db){ + int bRet = 1; + if( sqllogglobal.bConditional ){ + char zFile[SQLLOG_NAMESZ]; /* Attached database name */ + int rc = sqllogFindAttached(db, "main", 0, zFile); + if( rc==SQLITE_OK ){ + int nFile = strlen(zFile); + if( (SQLLOG_NAMESZ-nFile)<8 ){ + sqlite3_log(SQLITE_IOERR, + "sqllogTraceDb(): database name too long (%d bytes)", nFile + ); + bRet = 0; + }else{ + memcpy(&zFile[nFile], "-sqllog", 8); + bRet = !access(zFile, F_OK); + } + } + } + return bRet; +} + +/* ** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog(). ** ** The eType parameter has the following values: @@ -439,15 +478,19 @@ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){ if( sqllogglobal.mutex==0 ){ sqllogglobal.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); } - p = &sqllogglobal.aConn[sqllogglobal.nConn++]; - p->fd = 0; - p->db = db; - p->iLog = sqllogglobal.iNextLog++; sqlite3_mutex_leave(master); - /* Open the log and take a copy of the main database file */ sqlite3_mutex_enter(sqllogglobal.mutex); - if( sqllogglobal.bRec==0 ){ + if( sqllogglobal.bRec==0 && sqllogTraceDb(db) ){ + + sqlite3_mutex_enter(master); + p = &sqllogglobal.aConn[sqllogglobal.nConn++]; + p->fd = 0; + p->db = db; + p->iLog = sqllogglobal.iNextLog++; + sqlite3_mutex_leave(master); + + /* Open the log and take a copy of the main database file */ sqllogOpenlog(p); if( p->fd ) sqllogCopydb(p, "main", 0); } @@ -461,20 +504,21 @@ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){ p = &sqllogglobal.aConn[i]; if( p->db==db ) break; } - if( i==sqllogglobal.nConn ) return; /* A database handle close command */ if( eType==2 ){ sqlite3_mutex_enter(master); - if( p->fd ) fclose(p->fd); - p->db = 0; - p->fd = 0; + if( i<sqllogglobal.nConn ){ + if( p->fd ) fclose(p->fd); + p->db = 0; + p->fd = 0; + sqllogglobal.nConn--; + } - sqllogglobal.nConn--; if( sqllogglobal.nConn==0 ){ sqlite3_mutex_free(sqllogglobal.mutex); sqllogglobal.mutex = 0; - }else{ + }else if( i<sqllogglobal.nConn ){ int nShift = &sqllogglobal.aConn[sqllogglobal.nConn] - p; if( nShift>0 ){ memmove(p, &p[1], nShift*sizeof(struct SLConn)); @@ -483,7 +527,7 @@ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){ sqlite3_mutex_leave(master); /* An ordinary SQL command. */ - }else if( p->fd ){ + }else if( i<sqllogglobal.nConn && p->fd ){ sqlite3_mutex_enter(sqllogglobal.mutex); if( sqllogglobal.bRec==0 ){ testSqllogStmt(p, zSql); @@ -504,6 +548,9 @@ void sqlite3_init_sqllog(void){ if( SQLITE_OK==sqlite3_config(SQLITE_CONFIG_SQLLOG, testSqllog, 0) ){ memset(&sqllogglobal, 0, sizeof(sqllogglobal)); sqllogglobal.bReuse = 1; + if( getenv(ENVIRONMENT_VARIABLE3_NAME) ){ + sqllogglobal.bConditional = 1; + } } } } diff --git a/test/sqllog.test b/test/sqllog.test new file mode 100644 index 000000000..dca5781db --- /dev/null +++ b/test/sqllog.test @@ -0,0 +1,116 @@ +# 2015 November 13 +# +# 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. The +# focus of this file is testing the test_sqllog.c module. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix sqllog + +ifcapable !sqllog { + finish_test + return +} + +proc readfile {f} { + set fd [open $f] + set txt [read $fd] + close $fd + set txt +} + +proc delete_all_sqllog_files {} { + forcedelete {*}[glob -nocomplain sqllog_*.sql] + forcedelete {*}[glob -nocomplain sqllog_*.db] + forcedelete {*}[glob -nocomplain sqllog_*.idx] +} + +proc touch {f} { + set fd [open $f w+] + close $fd +} + +db close +sqlite3_shutdown +set ::env(SQLITE_SQLLOG_DIR) [pwd] + +delete_all_sqllog_files + +sqlite3 db test.db +set a a +set b b +do_execsql_test 1.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES($a, $b); + SELECT * FROM t1; +} {1 2 a b} +db close + +do_test 1.1 { + readfile [lindex [glob sqllog_*.sql] 0] +} [string trimleft { +/-- Main database is '.*/sqllog_.*_0.db' +CREATE TABLE t1\(x, y\);; -- clock=0 +INSERT INTO t1 VALUES\(1, 2\);; -- clock=1 +INSERT INTO t1 VALUES\('a', 'b'\);; -- clock=2 +SELECT . FROM t1;; -- clock=3 +/}] + +do_test 1.2 { + file size [lindex [glob sqllog_*_0.db] 0] +} 1024 + +#------------------------------------------------------------------------- +catch { db close } +sqlite3_shutdown +delete_all_sqllog_files +forcedelete test.db-sqllog + +set ::env(SQLITE_SQLLOG_CONDITIONAL) 1 +sqlite3 db test.db +do_execsql_test 2.1 { + INSERT INTO t1 VALUES(4, 5); + SELECT * FROM t1; +} {1 2 a b 4 5} + +do_test 2.2 { + glob -nocomplain sqllog_* +} {} + +db close +touch test.db-sqllog +sqlite3 db test.db +do_execsql_test 2.3 { + INSERT INTO t1 VALUES(6, 7); + SELECT * FROM t1; +} {1 2 a b 4 5 6 7} +db close + +do_test 2.4 { + readfile [lindex [glob sqllog_*.sql] 0] +} [string trimleft { +/-- Main database is '.*/sqllog_.*_0.db' +INSERT INTO t1 VALUES\(6, 7\);; -- clock=0 +SELECT . FROM t1;; -- clock=1 +/}] + +catch { db close } +sqlite3_shutdown +unset ::env(SQLITE_SQLLOG_DIR) +unset ::env(SQLITE_SQLLOG_CONDITIONAL) +sqlite3_config_sqllog +sqlite3_initialize +breakpoint +finish_test + + diff --git a/test/trigger7.test b/test/trigger7.test index 221962406..847d78cd7 100644 --- a/test/trigger7.test +++ b/test/trigger7.test @@ -21,7 +21,6 @@ ifcapable {!trigger} { return } - # Error messages resulting from qualified trigger names. # do_test trigger7-1.1 { |