diff --git a/main.mk b/main.mk index e8f32b66dc..a1145bb6e8 100644 --- a/main.mk +++ b/main.mk @@ -356,11 +356,12 @@ testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) libsqlite3.a $(LIBTCL) $(THREADLIB) crashtest: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TOP)/src/os_test.c - $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o crashtest \ + $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 \ + -o crashtest \ $(TESTSRC) $(TOP)/src/os_test.c $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) -fulltest: testfixture$(EXE) sqlite3$(EXE) +fulltest: testfixture$(EXE) sqlite3$(EXE) crashtest ./testfixture$(EXE) $(TOP)/test/all.test test: testfixture$(EXE) sqlite3$(EXE) diff --git a/manifest b/manifest index 786ae4abd7..52b4c002cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fold\sin\sa\s64-bit\schange\sthat\scame\sfrom\sthe\sPHP\speople.\s(CVS\s1743) -D 2004-06-26T14:46:40 +C Coverage\stesting\sof\spragma.c.\s(CVS\s1744) +D 2004-06-26T19:35:30 F Makefile.in cb7a9889c38723f72b2506c4236ff30a05ff172b F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -17,7 +17,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826 -F main.mk 51cdc61a9eccc7e430acdb236991ba0dbafc0341 +F main.mk 5d21c17c2bf56915658f65e5d395c40f78e2ea6f F mkdll.sh 68d34a961a1fdfa15ef27fc4f4740be583112124 F publish.sh 4193d9022fb7cf9beecd313bed3d1d68b8386fbe F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b @@ -53,7 +53,7 @@ F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44 F src/pager.c 6240557abedaf6d888359a2365df45bce414c540 F src/pager.h fe818866f6d1adcffeed88705e8df7e588cbaf13 F src/parse.y e19e066e726a31d7b2d3e6475bdf55f7e339f8a3 -F src/pragma.c 16713c1bc440ccd9982a27fb4b38e1a1c95ffd29 +F src/pragma.c 2ca5ef7e27916f191a3b1201ad576ef6f8a8d72d F src/printf.c 3090c8ff397d549bc0de09b16d8ab7fd37a0c3f7 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c f02a65af34231031896e8442161cb5251e191e75 @@ -80,7 +80,7 @@ F src/vdbeapi.c d3659f3f2982e79c06ab8e338604a39e0ea0d2d3 F src/vdbeaux.c e7201e3f129439bc64d2ff79b54001adc2c95539 F src/vdbemem.c d37e4033f7350e542f715c061bffe23feb51bc9e F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e -F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 +F test/all.test d591e074013248176402a16a0fb6fc82d241bad5 F test/attach.test 3acdffccbf5f78b07746771b9490758718e28856 F test/attach2.test 3cd1d4a69e0ec307d0b68a44a96c9c8e1e253d65 F test/attach3.test c4cc0b806783ce3d860af6b80c947f93ffb14270 @@ -104,7 +104,7 @@ F test/collate4.test 0e9fc08ffcf6eddf72e354a15de06688fa86db31 F test/collate5.test 1dd5f0f508c46667f9d4606c7950c414b0bdc0d5 F test/collate6.test 2a45768914f04c1447a69d1358bbede376552675 F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87 -F test/crash.test 062a108997c3f58a72e9add04d48e766468daf04 +F test/crash.test 886d531d4057fe1bf3fae57166127a1ac82c39cb F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d F test/delete.test 4f0c86e2bebdc822d179c80697b1ceabe6bbcd07 @@ -141,7 +141,7 @@ F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0 F test/null.test 64730a1c32955e5cc510b7632fed6b9929a4029a F test/pager.test 059cc5c58d3b5a851343dff8c56cf7286425d03a F test/pager2.test 55469c7c1c1a54d6b32d7b3cc99001e90101a1ce -F test/pragma.test a0dac4320e130e31e855bbdb935645d7c45d6340 +F test/pragma.test 212d810e02a51c0ff9784a19d55e35d23382005d F test/printf.test 1eb584b7272d1abdfe117b2ef7cf3376ae8e4e06 F test/progress.test 7542a6ac7894a1b7730c1f9a27f3f8b9388a4d25 x F test/quick.test 4c0b3eabe2e0e606622d63d7d61ef6efb3ce156b @@ -229,7 +229,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 3c8512bc549e10ee131cb7f2d4e74d96e9de74a0 -R b3df37a9b31c0d3af047ea48e90adc06 +P b69b4fe8adff83a26e3566613bea8b477a26e8a4 +R 72fd52c0e274fc83fa1945dfd7a6deb8 U drh -Z ee2a09b86bd7a1a127412206343d53c2 +Z 03157110b37f81d3fef2f16d6fba5e75 diff --git a/manifest.uuid b/manifest.uuid index af18a81f57..53cf3f0628 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b69b4fe8adff83a26e3566613bea8b477a26e8a4 \ No newline at end of file +0f9c0f0aa9188c46c65cb92203687f37884f685a \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 54c9391ce9..469ccff054 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.53 2004/06/26 06:37:07 danielk1977 Exp $ +** $Id: pragma.c,v 1.54 2004/06/26 19:35:30 drh Exp $ */ #include "sqliteInt.h" #include @@ -96,11 +96,14 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ if( sqlite3StrICmp(zLeft, aPragma[i].zName)==0 ){ sqlite *db = pParse->db; Vdbe *v; - if( strcmp(zLeft,zRight)==0 && (v = sqlite3GetVdbe(pParse))!=0 ){ - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, aPragma[i].zName, P3_STATIC); - sqlite3VdbeAddOp(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0); - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); + if( zRight==0 ){ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, aPragma[i].zName, P3_STATIC); + sqlite3VdbeAddOp(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0); + sqlite3VdbeAddOp(v, OP_Callback, 1, 0); + } }else if( getBoolean(zRight) ){ db->flags |= aPragma[i].mask; }else{ @@ -112,6 +115,17 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ return 0; } +/* +** Check to make sure the schema is loaded. Return 1 if it is not. +*/ +static int checkSchema(Parse *pParse){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ + pParse->nErr++; + return 1; + } + return 0; +} + /* ** Process a pragma statement. ** @@ -184,10 +198,7 @@ void sqlite3Pragma( { OP_Callback, 1, 0, 0}, }; int addr; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC); @@ -228,10 +239,7 @@ void sqlite3Pragma( static VdbeOpList getCacheSize[] = { { OP_Callback, 1, 0, 0}, }; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; if( !zRight ){ int size = db->aDb[iDb].cache_size; assert( size>0 ); @@ -260,10 +268,7 @@ void sqlite3Pragma( static VdbeOpList getSync[] = { { OP_Callback, 1, 0, 0}, }; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC); @@ -280,7 +285,7 @@ void sqlite3Pragma( } }else -#ifndef NDEBUG +#if 0 /* Used once during development. No longer needed */ if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){ if( getBoolean(zRight) ){ sqlite3_always_code_trigger_setup = 1; @@ -306,12 +311,9 @@ void sqlite3Pragma( ** notnull: True if 'NOT NULL' is part of column declaration ** dflt_value: The default value for the column, if any. */ - if( sqlite3StrICmp(zLeft, "table_info")==0 ){ + if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ Table *pTab; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, 0); if( pTab ){ int i; @@ -337,13 +339,10 @@ void sqlite3Pragma( } }else - if( sqlite3StrICmp(zLeft, "index_info")==0 ){ + if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ Index *pIdx; Table *pTab; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; pIdx = sqlite3FindIndex(db, zRight, 0); if( pIdx ){ int i; @@ -363,13 +362,10 @@ void sqlite3Pragma( } }else - if( sqlite3StrICmp(zLeft, "index_list")==0 ){ + if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ Index *pIdx; Table *pTab; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, 0); if( pTab ){ v = sqlite3GetVdbe(pParse); @@ -392,13 +388,10 @@ void sqlite3Pragma( } }else - if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 ){ + if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ FKey *pFK; Table *pTab; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, 0); if( pTab ){ v = sqlite3GetVdbe(pParse); @@ -431,10 +424,7 @@ void sqlite3Pragma( if( sqlite3StrICmp(zLeft, "database_list")==0 ){ int i; - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 3); sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); @@ -453,10 +443,6 @@ void sqlite3Pragma( #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ extern void sqlite3ParserTrace(FILE*, char *); - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } if( getBoolean(zRight) ){ sqlite3ParserTrace(stdout, "parser: "); }else{ @@ -489,10 +475,7 @@ void sqlite3Pragma( }; /* Initialize the VDBE program */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC); sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode); @@ -639,10 +622,7 @@ void sqlite3Pragma( struct EncName *pEnc; encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE; if( !zRight ){ /* "PRAGMA encoding" */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ - pParse->nErr++; - goto pragma_out; - } + if( checkSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC); sqlite3VdbeAddOp(v, OP_String8, 0, 0); @@ -667,7 +647,7 @@ void sqlite3Pragma( } } if( !pEnc->zName ){ - sqlite3ErrorMsg(pParse, "Unsupported encoding: %s", zRight); + sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); } } } diff --git a/test/all.test b/test/all.test index 469910a4b5..eca80a71bd 100644 --- a/test/all.test +++ b/test/all.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: all.test,v 1.19 2003/02/16 22:21:33 drh Exp $ +# $Id: all.test,v 1.20 2004/06/26 19:35:30 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -20,7 +20,7 @@ proc finish_test {} {memleak_check} if {[file exists ./sqlite_test_count]} { set COUNT [exec cat ./sqlite_test_count] } else { - set COUNT 4 + set COUNT 3 } if {[llength $argv]>0} { @@ -49,6 +49,7 @@ set LeakList {} set EXCLUDE { all.test + crash.test quick.test malloc.test misuse.test @@ -57,7 +58,6 @@ set EXCLUDE { # btree2.test for {set Counter 0} {$Counter<$COUNT && $nErr==0} {incr Counter} { - set btree_native_byte_order [expr {($Counter>>1)&0x1}] if {$Counter%2} { set ::SETUP_SQL {PRAGMA default_synchronous=off;} } else { @@ -98,6 +98,12 @@ if {$LeakList!=""} { puts " Ok" } +# Run the crashtest only on unix and only once. +# +if {$tcl_platform(platform)=="unix"} { + source $testdir/crash.test +} + # Run the malloc tests and the misuse test after memory leak detection. # Both tests leak memory. # diff --git a/test/crash.test b/test/crash.test index 7130ce3f3f..12347b26ec 100644 --- a/test/crash.test +++ b/test/crash.test @@ -10,7 +10,17 @@ #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: crash.test,v 1.5 2004/06/26 09:50:12 danielk1977 Exp $ +# The focus of this file is testing the ability of the database to +# uses its rollback journal to recover intact (no database corruption) +# from a power failure during the middle of a COMMIT. The special test +# module "crashtest" compiled with the special "os_test.c" backend is used. +# The os_test.c simulates the kind of file corruption that can occur +# when writes are happening at the moment of power loss. +# +# The special crash-test module with its os_test.c backend only works +# on Unix. +# +# $Id: crash.test,v 1.6 2004/06/26 19:35:30 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -305,5 +315,3 @@ for {set i 1} {$i < 5} {incr i} { signature2 } $sig2 } - - diff --git a/test/pragma.test b/test/pragma.test index a0c7f37f7e..04704f016a 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -12,7 +12,7 @@ # # This file implements tests for the PRAGMA command. # -# $Id: pragma.test,v 1.14 2004/06/26 06:37:07 danielk1977 Exp $ +# $Id: pragma.test,v 1.15 2004/06/26 19:35:30 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -134,6 +134,48 @@ do_test pragma-1.12 { } } {123 123 2} +# Make sure the pragma handler understands numeric values in addition +# to keywords like "off" and "full". +# +do_test pragma-1.13 { + execsql { + PRAGMA synchronous=0; + PRAGMA synchronous; + } +} {0} +do_test pragma-1.14 { + execsql { + PRAGMA synchronous=2; + PRAGMA synchronous; + } +} {2} + +# Test turning "flag" pragmas on and off. +# +do_test pragma-1.15 { + execsql { + PRAGMA vdbe_listing=YES; + PRAGMA vdbe_listing; + } +} {1} +do_test pragma-1.16 { + execsql { + PRAGMA vdbe_listing=NO; + PRAGMA vdbe_listing; + } +} {0} +do_test pragma-1.17 { + execsql { + PRAGMA parser_trace=ON; + PRAGMA parser_trace=OFF; + } +} {} +do_test pragma-1.18 { + execsql { + PRAGMA bogus = -1234; -- Parsing of negative values + } +} {} + # Test modifying the safety_level of an attached database. do_test pragma-2.1 { file delete -force test2.db @@ -258,5 +300,64 @@ do_test pragma-5.2 { pragma synchronous; } } {2} +catchsql {COMMIT;} + +# Test schema-query pragmas +# +do_test pragma-6.1 { + foreach {idx name file} [execsql {pragma database_list}] { + lappend res $idx $name + } + set res +} {0 main 1 temp 2 aux} +do_test pragma-6.2 { + execsql { + pragma table_info(t2) + } +} {0 a numeric 0 {} 0 1 b numeric 0 {} 0 2 c numeric 0 {} 0} +do_test pragma-6.3 { + execsql { + CREATE TABLE t3(a int references t2(b), b UNIQUE); + pragma foreign_key_list(t3); + } +} {0 0 t2 a b} +do_test pragma-6.4 { + execsql { + pragma index_list(t3); + } +} {0 sqlite_autoindex_t3_1 1} +do_test pragma-6.5 { + execsql { + CREATE INDEX t3i1 ON t3(a,b); + pragma index_info(t3i1); + } +} {0 0 a 1 1 b} + +# Miscellaneous tests +# +do_test pragma-7.1 { + # Make sure a pragma knows to read the schema if it needs to + db close + sqlite3 db test.db + execsql { + pragma index_list(t3); + } +} {0 t3i1 0 1 sqlite_autoindex_t3_1 1} +do_test pragma-7.2 { + db close + sqlite3 db test.db + catchsql { + pragma encoding=bogus; + } +} {1 {unsupported encoding: bogus}} +do_test pragma-7.3 { + db close + sqlite3 db test.db + execsql { + pragma lock_status; + } +} {main unlocked temp closed} + + finish_test