From cd7b91a7f16274bd4dc9ee2d6bf8976a99e7f6a7 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 13 May 2013 18:23:15 +0000 Subject: [PATCH 01/11] Candidate fixes for problems revealed by notify2.test. Notify2.test is still failing at this point. FossilOrigin-Name: ea0428f9b6e63066e7444a2ba2f8c12a2e3ab7e4 --- manifest | 18 +++++--- manifest.uuid | 2 +- src/main.c | 4 +- test/sharedA.test | 115 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 test/sharedA.test diff --git a/manifest b/manifest index 525586f02f..008ee4a3df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sassert()s\sto\sthe\simplementation\sof\sxRead()\sin\sthe\sbuilt-in\sVFSes\sto\s\nverify\sthat\sthe\soffset\sparameter\sis\salways\snon-negative. -D 2013-05-09T18:12:40.898 +C Candidate\sfixes\sfor\sproblems\srevealed\sby\snotify2.test.\sNotify2.test\sis\sstill\sfailing\sat\sthis\spoint. +D 2013-05-13T18:23:15.893 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -159,7 +159,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2 -F src/main.c 7531758e3167006f55cd65678d9c72a3c1a6759a +F src/main.c 2ef7316bae009d8b1cf218a52f25abda50712aab F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -737,6 +737,7 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 +F test/sharedA.test 2dad757bb388779d6bda8c05ec52e39e9981a135 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038 @@ -1062,7 +1063,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 1128575d0ab24f7023a0f6e6ce4828b9a09a7c6c -R 1cad29e868ca8cf8d5b7d354acd90934 -U drh -Z 3b3f34da85296e9879a826be138cb510 +P cf5c3642247fdd34d87f0368594cd7b8f081636a +R 9334ad7d318214aee7b701f9959b5d6e +T *branch * shared-cache-fixes +T *sym-shared-cache-fixes * +T -sym-trunk * +U dan +Z 816ab4789f48f56b3bf310736184e47d diff --git a/manifest.uuid b/manifest.uuid index 03a8fec162..133cb8b794 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf5c3642247fdd34d87f0368594cd7b8f081636a \ No newline at end of file +ea0428f9b6e63066e7444a2ba2f8c12a2e3ab7e4 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 3b6cd9e821..6f674cf4a3 100644 --- a/src/main.c +++ b/src/main.c @@ -836,7 +836,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ ** SQL statements below, as the v-table implementation may be storing ** some prepared statements internally. */ - sqlite3VtabRollback(db); + sqlite3RollbackAll(db, SQLITE_ABORT); /* Legacy behavior (sqlite3_close() behavior) is to return ** SQLITE_BUSY if the connection can not be closed immediately. @@ -1002,6 +1002,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); + sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ @@ -1019,6 +1020,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ sqlite3ExpirePreparedStatements(db); sqlite3ResetAllSchemasOfConnection(db); } + sqlite3BtreeLeaveAll(db); /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; diff --git a/test/sharedA.test b/test/sharedA.test new file mode 100644 index 0000000000..675041408b --- /dev/null +++ b/test/sharedA.test @@ -0,0 +1,115 @@ +# 2013 May 14 +# +# 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. +# +#*********************************************************************** +# +# Test some specific circumstances to do with shared cache mode. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +db close +set ::testprefix x + +set ::enable_shared_cache [sqlite3_enable_shared_cache 1] + +#------------------------------------------------------------------------- +# +do_test 1.1 { + sqlite3 db1 test.db + sqlite3 db2 test.db + db2 eval { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(123); + } + db1 eval { + SELECT * FROM t1; + CREATE INDEX i1 ON t1(x); + } +} {123} + +do_test 1.2 { + db2 eval { SELECT * FROM t1 ORDER BY x; } + + db1 eval { + BEGIN; DROP INDEX i1; + } + db1 close + + db2 eval { SELECT * FROM t1 ORDER BY x; } +} {123} + +do_test 1.3 { + db2 close +} {} + +#------------------------------------------------------------------------- +# +testvfs tvfs +tvfs filter xRead +tvfs script read_callback +proc read_callback {args} { } + +do_test 2.1 { + forcedelete test.db test.db2 + sqlite3 db1 test.db -vfs tvfs + db1 eval { ATTACH 'test.db2' AS two } + + db1 eval { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(3); + CREATE TABLE two.t2(x); + INSERT INTO t2 SELECT * FROM t1; + } + + sqlite3 db2 test.db -vfs tvfs + db2 eval { SELECT * FROM t1 } +} {1 2 3} + +do_test 2.2 { + set ::STMT [sqlite3_prepare db2 "CREATE INDEX i1 ON t1(x)" -1 tail] + set {} {} +} {} + +do_test 2.3 { + db1 eval { + BEGIN; + CREATE INDEX i1 ON t1(x); + INSERT INTO t2 VALUES('value!'); + } +} {} + +set ::bFired 0 +proc read_callback {call file args} { + if { $::bFired==0 && [string match *test.db2-journal $file] } { + sqlthread spawn ::thread_result [subst -nocommands { + sqlite3_step $::STMT + set rc [sqlite3_finalize $::STMT] + }] + after 1000 { set ::bFired 1 } + vwait ::bFired + } +} +do_test 2.4 { db1 eval ROLLBACK } {} + +if {[info exists ::thread_result]==0} { vwait ::thread_result } +do_test 2.5 { + list $::thread_result [sqlite3_errmsg db2] +} {SQLITE_SCHEMA {database schema has changed}} + +db1 close +db2 close +tvfs delete + +sqlite3_enable_shared_cache $::enable_shared_cache +finish_test + From bf0e57a7d0dc4d73744d523ccf299d3d1cf961d7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2013 20:36:31 +0000 Subject: [PATCH 02/11] Avoid deleting a b-tree "has-content" vector belonging to another shared-cache connection from within sqlite3_close(). FossilOrigin-Name: 93462df78247f5634b9f53752cf80056bbfe9aac --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/btree.c | 3 ++- test/sharedA.test | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 008ee4a3df..52879ddaa4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Candidate\sfixes\sfor\sproblems\srevealed\sby\snotify2.test.\sNotify2.test\sis\sstill\sfailing\sat\sthis\spoint. -D 2013-05-13T18:23:15.893 +C Avoid\sdeleting\sa\sb-tree\s"has-content"\svector\sbelonging\sto\sanother\sshared-cache\sconnection\sfrom\swithin\ssqlite3_close(). +D 2013-05-14T20:36:31.591 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -137,7 +137,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c b266767351ae2d847716c56fcb2a1fea7c761c03 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 480a6d255cc4f066029daf23dd54acf152cd0e13 +F src/btree.c e42631ac1fe6d0d3a0a5e36330b203f69052be21 F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 F src/build.c 083da8466fd7e481cb8bd5264398f537507f6176 @@ -737,7 +737,7 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 -F test/sharedA.test 2dad757bb388779d6bda8c05ec52e39e9981a135 +F test/sharedA.test 113664fa64ab0538c7dc77f4b6fc1ff904561cec F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038 @@ -1063,10 +1063,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cf5c3642247fdd34d87f0368594cd7b8f081636a -R 9334ad7d318214aee7b701f9959b5d6e -T *branch * shared-cache-fixes -T *sym-shared-cache-fixes * -T -sym-trunk * +P ea0428f9b6e63066e7444a2ba2f8c12a2e3ab7e4 +R f68931e6fbc759d31073a5961092df76 U dan -Z 816ab4789f48f56b3bf310736184e47d +Z c980c1bd80d8d5755c03b6b85fccf1ca diff --git a/manifest.uuid b/manifest.uuid index 133cb8b794..b122e3091d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea0428f9b6e63066e7444a2ba2f8c12a2e3ab7e4 \ No newline at end of file +93462df78247f5634b9f53752cf80056bbfe9aac \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 616d403681..d0441790fc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3255,7 +3255,6 @@ static void btreeEndTransaction(Btree *p){ #ifndef SQLITE_OMIT_AUTOVACUUM pBt->bDoTruncate = 0; #endif - btreeClearHasContent(pBt); if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ /* If there are other active statements that belong to this database ** handle, downgrade to a read-only transaction. The other statements @@ -3330,6 +3329,7 @@ int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ return rc; } pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); } btreeEndTransaction(p); @@ -3453,6 +3453,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode){ } assert( countWriteCursors(pBt)==0 ); pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); } btreeEndTransaction(p); diff --git a/test/sharedA.test b/test/sharedA.test index 675041408b..67d6fef9f6 100644 --- a/test/sharedA.test +++ b/test/sharedA.test @@ -16,10 +16,46 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl db close -set ::testprefix x +set ::testprefix sharedA set ::enable_shared_cache [sqlite3_enable_shared_cache 1] +#------------------------------------------------------------------------- +# +do_test 0.1 { + sqlite3 db1 test.db + sqlite3 db2 test.db + + db1 eval { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(randomblob(100)); + INSERT INTO t1 SELECT randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100) FROM t1; + CREATE INDEX i1 ON t1(x); + } + + db1 eval { + BEGIN; + DROP INDEX i1; + } + + db2 close + + db1 eval { + INSERT INTO t1 SELECT randomblob(100) FROM t1; + ROLLBACK; + PRAGMA integrity_check; + } +} {ok} + +db1 close +forcedelete test.db + + #------------------------------------------------------------------------- # do_test 1.1 { From 85ec3b63d896bb0227c6f2363c3f944de0eb2d9f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 14 May 2013 23:12:06 +0000 Subject: [PATCH 03/11] Fix an assert() in unlockBtreeIfUnused() so that it checks for the existance of an untripped cursor, not for the existance of any cursor at all. FossilOrigin-Name: a6f851d0fe01d8c8d44a2fe0b716ff7a5194c63b --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/btree.c | 48 +++++++++++++++++++++++++----------------------- test/misuse.test | 2 +- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 008ee4a3df..0764d64e6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Candidate\sfixes\sfor\sproblems\srevealed\sby\snotify2.test.\sNotify2.test\sis\sstill\sfailing\sat\sthis\spoint. -D 2013-05-13T18:23:15.893 +C Fix\san\sassert()\sin\sunlockBtreeIfUnused()\sso\sthat\sit\schecks\sfor\sthe\sexistance\nof\san\suntripped\scursor,\snot\sfor\sthe\sexistance\sof\sany\scursor\sat\sall. +D 2013-05-14T23:12:06.185 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -137,7 +137,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c b266767351ae2d847716c56fcb2a1fea7c761c03 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 480a6d255cc4f066029daf23dd54acf152cd0e13 +F src/btree.c 34ea83e16ece6d666214c7d0c3a39ce92fe292fd F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 F src/build.c 083da8466fd7e481cb8bd5264398f537507f6176 @@ -646,7 +646,7 @@ F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test dd82ec9250b89178b96cd28b2aca70639d21e5b3 -F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 +F test/misuse.test 9e580d30f94968ebb57878de3503608dc9f0f226 F test/mmap1.test 8696aa1b0bd88961c2f16af2a3f7a69d701cea50 F test/mmap2.test a5ba639f90b5fc487400a49e158e14e465943e98 F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256 @@ -1063,10 +1063,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cf5c3642247fdd34d87f0368594cd7b8f081636a -R 9334ad7d318214aee7b701f9959b5d6e -T *branch * shared-cache-fixes -T *sym-shared-cache-fixes * -T -sym-trunk * -U dan -Z 816ab4789f48f56b3bf310736184e47d +P ea0428f9b6e63066e7444a2ba2f8c12a2e3ab7e4 +R 2410ec7fd380116c79746c720dac4cd6 +U drh +Z 5ded41815869fd9a599b4926f7c8b138 diff --git a/manifest.uuid b/manifest.uuid index 133cb8b794..fc052d359f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea0428f9b6e63066e7444a2ba2f8c12a2e3ab7e4 \ No newline at end of file +a6f851d0fe01d8c8d44a2fe0b716ff7a5194c63b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 616d403681..297b0a7f8e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2517,6 +2517,29 @@ page1_init_failed: return rc; } +#ifndef NDEBUG +/* +** Return the number of cursors open on pBt. This is for use +** in assert() expressions, so it is only compiled if NDEBUG is not +** defined. +** +** Only write cursors are counted if wrOnly is true. If wrOnly is +** false then all cursors are counted. +** +** For the purposes of this routine, a cursor is any cursor that +** is capable of reading or writing to the databse. Cursors that +** have been tripped into the CURSOR_FAULT state are not counted. +*/ +static int countValidCursors(BtShared *pBt, int wrOnly){ + BtCursor *pCur; + int r = 0; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; + } + return r; +} +#endif + /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then @@ -2527,7 +2550,7 @@ page1_init_failed: */ static void unlockBtreeIfUnused(BtShared *pBt){ assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE ); + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ assert( pBt->pPage1->aData ); assert( sqlite3PagerRefcount(pBt->pPager)==1 ); @@ -3351,27 +3374,6 @@ int sqlite3BtreeCommit(Btree *p){ return rc; } -#ifndef NDEBUG -/* -** Return the number of write-cursors open on this handle. This is for use -** in assert() expressions, so it is only compiled if NDEBUG is not -** defined. -** -** For the purposes of this routine, a write-cursor is any cursor that -** is capable of writing to the databse. That means the cursor was -** originally opened for writing and the cursor has not be disabled -** by having its state changed to CURSOR_FAULT. -*/ -static int countWriteCursors(BtShared *pBt){ - BtCursor *pCur; - int r = 0; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; - } - return r; -} -#endif - /* ** This routine sets the state to CURSOR_FAULT and the error ** code to errCode for every cursor on BtShared that pBtree @@ -3451,7 +3453,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode){ pBt->nPage = nPage; releasePage(pPage1); } - assert( countWriteCursors(pBt)==0 ); + assert( countValidCursors(pBt, 1)==0 ); pBt->inTransaction = TRANS_READ; } diff --git a/test/misuse.test b/test/misuse.test index 71ee0118c8..84ead1c669 100644 --- a/test/misuse.test +++ b/test/misuse.test @@ -170,7 +170,7 @@ do_test misuse-4.3 { } } msg] lappend v $msg $r -} {0 {} SQLITE_BUSY} +} {1 {callback requested query abort} SQLITE_BUSY} do_test misuse-4.4 { # Flush the TCL statement cache here, otherwise the sqlite3_close() will # fail because there are still un-finalized() VDBEs. From 6743081784c2bee472ddec5573bd4486960e1f67 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 May 2013 10:21:50 +0000 Subject: [PATCH 04/11] When closing a connection, avoid tripping active cursors belonging to a different shared-cache client. Also, if sqlite3_close() is called while there are still active statements belonging to the connection, return SQLITE_BUSY and do not roll back any active transaction. FossilOrigin-Name: 6071b7cce067c807e040283fc4b7449dc6eca498 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 8 +++++++- test/misuse.test | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 86930fe5cb..ef447dfc40 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\stogether\sthe\sfork\sin\sthis\sbranch. -D 2013-05-14T23:13:41.194 +C When\sclosing\sa\sconnection,\savoid\stripping\sactive\scursors\sbelonging\sto\sa\sdifferent\sshared-cache\sclient.\sAlso,\sif\ssqlite3_close()\sis\scalled\swhile\sthere\sare\sstill\sactive\sstatements\sbelonging\sto\sthe\sconnection,\sreturn\sSQLITE_BUSY\sand\sdo\snot\sroll\sback\sany\sactive\stransaction. +D 2013-05-15T10:21:50.290 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -159,7 +159,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2 -F src/main.c 2ef7316bae009d8b1cf218a52f25abda50712aab +F src/main.c ccbac976228cd21209ede2bdc82bbf22b0ddf197 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -646,7 +646,7 @@ F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test dd82ec9250b89178b96cd28b2aca70639d21e5b3 -F test/misuse.test 9e580d30f94968ebb57878de3503608dc9f0f226 +F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/mmap1.test 8696aa1b0bd88961c2f16af2a3f7a69d701cea50 F test/mmap2.test a5ba639f90b5fc487400a49e158e14e465943e98 F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256 @@ -1063,7 +1063,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 93462df78247f5634b9f53752cf80056bbfe9aac a6f851d0fe01d8c8d44a2fe0b716ff7a5194c63b -R fd9716795d11f0f9b0e245778ae3dfdf -U drh -Z 207682ad3d629f4d5a07b6ee61017db7 +P 164e3d4da20cc16d2a04d602b5a8229e0db99d9d +R 243e9c6eef6644304141719b7b365651 +U dan +Z 161ee496080958759a84c8cf6005b67f diff --git a/manifest.uuid b/manifest.uuid index 6b647583c4..71bd9bddb9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -164e3d4da20cc16d2a04d602b5a8229e0db99d9d \ No newline at end of file +6071b7cce067c807e040283fc4b7449dc6eca498 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 6f674cf4a3..763adbfe8e 100644 --- a/src/main.c +++ b/src/main.c @@ -836,7 +836,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ ** SQL statements below, as the v-table implementation may be storing ** some prepared statements internally. */ - sqlite3RollbackAll(db, SQLITE_ABORT); + sqlite3VtabRollback(db); /* Legacy behavior (sqlite3_close() behavior) is to return ** SQLITE_BUSY if the connection can not be closed immediately. @@ -848,6 +848,12 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ return SQLITE_BUSY; } + /* If a transaction is open, roll it back. This also ensures that if + ** any database schemas have been modified by the current transaction + ** they are reset. And that the required b-tree mutex is held to make + ** the the pager rollback and schema reset an atomic operation. */ + sqlite3RollbackAll(db, SQLITE_OK); + #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ /* Closing the handle. Fourth parameter is passed the value 2. */ diff --git a/test/misuse.test b/test/misuse.test index 84ead1c669..71ee0118c8 100644 --- a/test/misuse.test +++ b/test/misuse.test @@ -170,7 +170,7 @@ do_test misuse-4.3 { } } msg] lappend v $msg $r -} {1 {callback requested query abort} SQLITE_BUSY} +} {0 {} SQLITE_BUSY} do_test misuse-4.4 { # Flush the TCL statement cache here, otherwise the sqlite3_close() will # fail because there are still un-finalized() VDBEs. From 15912e70b7d4cfa9ce5dc722dcaa0710df866980 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 May 2013 13:05:03 +0000 Subject: [PATCH 05/11] Add the rot13.c loadable extension. FossilOrigin-Name: 8f9bd8e7a88eb11fb17d29954fa4b8c2840a5019 --- ext/misc/rot13.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++ manifest | 11 ++--- manifest.uuid | 2 +- 3 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 ext/misc/rot13.c diff --git a/ext/misc/rot13.c b/ext/misc/rot13.c new file mode 100644 index 0000000000..68fdf60b0f --- /dev/null +++ b/ext/misc/rot13.c @@ -0,0 +1,114 @@ +/* +** 2013-05-15 +** +** 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 SQLite extension implements a rot13() function and a rot13 +** collating sequence. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +/* +** Perform rot13 encoding on a single ASCII character. +*/ +static unsigned char rot13(unsigned char c){ + if( c>='a' && c<='z' ){ + c += 13; + if( c>'z' ) c -= 26; + }else if( c>='A' && c<='Z' ){ + c += 13; + if( c>'Z' ) c -= 26; + } + return c; +} + +/* +** Implementation of the rot13() function. +** +** Rotate ASCII alphabetic characters by 13 character positions. +** Non-ASCII characters are unchanged. rot13(rot13(X)) should always +** equal X. +*/ +static void rot13func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zIn; + int nIn; + unsigned char *zOut; + char *zToFree = 0; + int i; + char zTemp[100]; + assert( argc==1 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + zIn = (const unsigned char*)sqlite3_value_text(argv[0]); + nIn = sqlite3_value_bytes(argv[0]); + if( nIn Date: Wed, 15 May 2013 15:16:50 +0000 Subject: [PATCH 06/11] When loading a database schema that contains an index definition that includes a COLLATE clause for which the collation sequence is unavailable, do not assume that that index uses BINARY instead. Fix for [0fc59f908b]. FossilOrigin-Name: 6dae62c4e505a9a1a22c2771ef3e1921407c4748 --- manifest | 16 ++++----- manifest.uuid | 2 +- src/build.c | 18 ++++------ test/collate3.test | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 7f1b8da745..9f70a70848 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\srot13.c\sloadable\sextension. -D 2013-05-15T13:05:03.677 +C When\sloading\sa\sdatabase\sschema\sthat\scontains\san\sindex\sdefinition\sthat\sincludes\sa\sCOLLATE\sclause\sfor\swhich\sthe\scollation\ssequence\sis\sunavailable,\sdo\snot\sassume\sthat\sthat\sindex\suses\sBINARY\sinstead.\sFix\sfor\s[0fc59f908b]. +D 2013-05-15T15:16:50.069 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -141,7 +141,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 480a6d255cc4f066029daf23dd54acf152cd0e13 F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c 083da8466fd7e481cb8bd5264398f537507f6176 +F src/build.c 92ef9483189389828966153c5950f2e5a49c1182 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@ -342,7 +342,7 @@ F test/closure01.test 6194a899cdbba561d0439c0d6cc7bcdf4fc413e7 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 -F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c +F test/collate3.test a6cf2127340e8f5b9ceb2a95d97811210cfc4627 F test/collate4.test 031f7265c13308b724ba3c49f41cc04612bd92b1 F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 @@ -1063,7 +1063,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cf5c3642247fdd34d87f0368594cd7b8f081636a -R 44b4748622864d8325bfa1188d6d5de6 -U drh -Z 1bcbc481bbe6dde5c937a1d1c9d5e280 +P 8f9bd8e7a88eb11fb17d29954fa4b8c2840a5019 +R c30a5ff0c8f241909590b400195b0165 +U dan +Z 12265815702aee04d3178d81300c6ea1 diff --git a/manifest.uuid b/manifest.uuid index 732cf754ac..38a7b3188e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f9bd8e7a88eb11fb17d29954fa4b8c2840a5019 \ No newline at end of file +6dae62c4e505a9a1a22c2771ef3e1921407c4748 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5920ade059..3c91cdcfdb 100644 --- a/src/build.c +++ b/src/build.c @@ -2659,10 +2659,8 @@ Index *sqlite3CreateIndex( for(i=0; inExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr ){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); - if( pColl ){ - nExtra += (1 + sqlite3Strlen30(pColl->zName)); - } + assert( pExpr->op==TK_COLLATE ); + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); } } @@ -2723,7 +2721,6 @@ Index *sqlite3CreateIndex( const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; - CollSeq *pColl; /* Collating sequence */ char *zColl; /* Collation sequence name */ for(j=0, pTabCol=pTab->aCol; jnCol; j++, pTabCol++){ @@ -2736,11 +2733,10 @@ Index *sqlite3CreateIndex( goto exit_create_index; } pIndex->aiColumn[i] = j; - if( pListItem->pExpr - && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0 - ){ + if( pListItem->pExpr ){ int nColl; - zColl = pColl->zName; + assert( pListItem->pExpr->op==TK_COLLATE ); + zColl = pListItem->pExpr->u.zToken; nColl = sqlite3Strlen30(zColl) + 1; assert( nExtra>=nColl ); memcpy(zExtra, zColl, nColl); @@ -2749,9 +2745,7 @@ Index *sqlite3CreateIndex( nExtra -= nColl; }else{ zColl = pTab->aCol[j].zColl; - if( !zColl ){ - zColl = "BINARY"; - } + if( !zColl ) zColl = "BINARY"; } if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; diff --git a/test/collate3.test b/test/collate3.test index c4dbfbe4cf..831526f364 100644 --- a/test/collate3.test +++ b/test/collate3.test @@ -55,6 +55,96 @@ execsql { DROP TABLE collate3t1; } +proc caseless {a b} { string compare -nocase $a $b } +do_test collate3-1.4 { + db collate caseless caseless + execsql { + CREATE TABLE t1(a COLLATE caseless); + INSERT INTO t1 VALUES('Abc2'); + INSERT INTO t1 VALUES('abc1'); + INSERT INTO t1 VALUES('aBc3'); + } + execsql { SELECT * FROM t1 ORDER BY a } +} {abc1 Abc2 aBc3} + +do_test collate3-1.5 { + db close + sqlite3 db test.db + catchsql { SELECT * FROM t1 ORDER BY a } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.6.1 { + db collate caseless caseless + execsql { CREATE INDEX i1 ON t1(a) } + execsql { SELECT * FROM t1 ORDER BY a } +} {abc1 Abc2 aBc3} + +do_test collate3-1.6.2 { + db close + sqlite3 db test.db + catchsql { SELECT * FROM t1 ORDER BY a } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.6.3 { + db close + sqlite3 db test.db + catchsql { PRAGMA integrity_check } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.6.4 { + db close + sqlite3 db test.db + catchsql { REINDEX } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.7.1 { + db collate caseless caseless + execsql { + DROP TABLE t1; + CREATE TABLE t1(a); + CREATE INDEX i1 ON t1(a COLLATE caseless); + INSERT INTO t1 VALUES('Abc2'); + INSERT INTO t1 VALUES('abc1'); + INSERT INTO t1 VALUES('aBc3'); + SELECT * FROM t1 ORDER BY a COLLATE caseless; + } +} {abc1 Abc2 aBc3} + +do_test collate3-1.7.2 { + db close + sqlite3 db test.db + catchsql { SELECT * FROM t1 ORDER BY a COLLATE caseless} +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.7.4 { + db close + sqlite3 db test.db + catchsql { REINDEX } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.7.3 { + db close + sqlite3 db test.db + catchsql { PRAGMA integrity_check } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.7.4 { + db close + sqlite3 db test.db + catchsql { REINDEX } +} {1 {no such collation sequence: caseless}} + +do_test collate3-1.7.5 { + db close + sqlite3 db test.db + db collate caseless caseless + catchsql { PRAGMA integrity_check } +} {0 ok} + +do_test collate3-1.7.6 { + execsql { DROP TABLE t1 } +} {} + # # Create a table with a default collation sequence, then close # and re-open the database without re-registering the collation From d5dd3305a10a5ddbbf309fe1bfce73d50ebe0e2a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 May 2013 15:53:52 +0000 Subject: [PATCH 07/11] Do not run sharedA.test if the system is not threadsafe. FossilOrigin-Name: d484eaf8d6dfaf2c1065b93b2a52a6db91c09fa4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/sharedA.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e86986a31d..024b7eeade 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\swith\sthis\sbranch. -D 2013-05-15T15:42:14.167 +C Do\snot\srun\ssharedA.test\sif\sthe\ssystem\sis\snot\sthreadsafe. +D 2013-05-15T15:53:52.221 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -738,7 +738,7 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 -F test/sharedA.test 113664fa64ab0538c7dc77f4b6fc1ff904561cec +F test/sharedA.test 8eddeda2407bdcd335ec8b8ba731aefc0e3e8232 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038 @@ -1064,7 +1064,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 6071b7cce067c807e040283fc4b7449dc6eca498 6dae62c4e505a9a1a22c2771ef3e1921407c4748 -R 28b38b6c18b562db57488c615db697dc +P 47dd65a890955f333d431e275f3f4d95d34a5ba5 +R 7b8246f3bd54a0ac6d93356e2396ef91 U dan -Z 6489a58ca2c2a2f6dd59b9b4bee3a760 +Z d923d1c201be4d3e0bbb63e5d84a5ca9 diff --git a/manifest.uuid b/manifest.uuid index 925a4ff77c..7ab7a5a608 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47dd65a890955f333d431e275f3f4d95d34a5ba5 \ No newline at end of file +d484eaf8d6dfaf2c1065b93b2a52a6db91c09fa4 \ No newline at end of file diff --git a/test/sharedA.test b/test/sharedA.test index 67d6fef9f6..e0031ccc03 100644 --- a/test/sharedA.test +++ b/test/sharedA.test @@ -15,6 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +if {[run_thread_tests]==0} { finish_test ; return } db close set ::testprefix sharedA From 2ab2d55f017b0945a8722ccb0d6e5133b0df15a4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 May 2013 16:08:33 +0000 Subject: [PATCH 08/11] Fix the sharedA.test module so that it does not attempt to run TCL callbacks on a different thread from where the interpreter was originally created. FossilOrigin-Name: 65ff754e3521aa8ee9135d235166cac2a8f57ebd --- manifest | 14 +++++------ manifest.uuid | 2 +- test/sharedA.test | 64 ++++++++++++++++++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 024b7eeade..cda4f88975 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\ssharedA.test\sif\sthe\ssystem\sis\snot\sthreadsafe. -D 2013-05-15T15:53:52.221 +C Fix\sthe\ssharedA.test\smodule\sso\sthat\sit\sdoes\snot\sattempt\sto\srun\sTCL\scallbacks\non\sa\sdifferent\sthread\sfrom\swhere\sthe\sinterpreter\swas\soriginally\screated. +D 2013-05-15T16:08:33.601 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -738,7 +738,7 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 -F test/sharedA.test 8eddeda2407bdcd335ec8b8ba731aefc0e3e8232 +F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038 @@ -1064,7 +1064,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 47dd65a890955f333d431e275f3f4d95d34a5ba5 -R 7b8246f3bd54a0ac6d93356e2396ef91 -U dan -Z d923d1c201be4d3e0bbb63e5d84a5ca9 +P d484eaf8d6dfaf2c1065b93b2a52a6db91c09fa4 +R 2b3d38cfaeff54ce7cad59c19d675f6e +U drh +Z adae8d677b3886690161b439bdcd47db diff --git a/manifest.uuid b/manifest.uuid index 7ab7a5a608..2eaef6834a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d484eaf8d6dfaf2c1065b93b2a52a6db91c09fa4 \ No newline at end of file +65ff754e3521aa8ee9135d235166cac2a8f57ebd \ No newline at end of file diff --git a/test/sharedA.test b/test/sharedA.test index e0031ccc03..146fb26be0 100644 --- a/test/sharedA.test +++ b/test/sharedA.test @@ -89,11 +89,31 @@ do_test 1.3 { #------------------------------------------------------------------------- # +# sqlite3RollbackAll() loops through all attached b-trees and rolls +# back each one separately. Then if the SQLITE_InternChanges flag is +# set, it resets the schema. Both of the above steps must be done +# while holding a mutex, otherwise another thread might slip in and +# try to use the new schema with the old data. +# +# The following sequence of tests attempt to verify that the actions +# taken by sqlite3RollbackAll() are thread-atomic (that they cannot be +# interrupted by a separate thread.) +# +# Note that a TCL interpreter can only be used within the thread in which +# it was originally created (because it uses thread-local-storage). +# The tvfs callbacks must therefore only run on the main thread. +# There is some trickery in the read_callback procedure to ensure that +# this is the case. +# testvfs tvfs -tvfs filter xRead -tvfs script read_callback -proc read_callback {args} { } +# Set up two databases and two database connections. +# +# db1: main(test.db), two(test2.db) +# db2: main(test.db) +# +# The cache for test.db is shared between db1 and db2. +# do_test 2.1 { forcedelete test.db test.db2 sqlite3 db1 test.db -vfs tvfs @@ -112,12 +132,12 @@ do_test 2.1 { db2 eval { SELECT * FROM t1 } } {1 2 3} +# Create a prepared statement on db2 that will attempt a schema change +# in test.db. Meanwhile, start a transaction on db1 that changes +# the schema of test.db and that creates a rollback journal on test2.db +# do_test 2.2 { set ::STMT [sqlite3_prepare db2 "CREATE INDEX i1 ON t1(x)" -1 tail] - set {} {} -} {} - -do_test 2.3 { db1 eval { BEGIN; CREATE INDEX i1 ON t1(x); @@ -125,21 +145,38 @@ do_test 2.3 { } } {} -set ::bFired 0 +# Set up a callback that will cause db2 to try to execute its +# schema change when db1 accesses the journal file of test2.db. +# +# This callback will be invoked after the content of test.db has +# be rolled back but before the schema has been reset. If the +# sqlite3RollbackAll() operation is not thread-atomic, then the +# db2 statement in the callback will see old content with the newer +# schema, which is wrong. +# +tvfs filter xRead +tvfs script read_callback +unset -nocomplain ::some_time_laster +unset -nocomplain ::thread_result proc read_callback {call file args} { - if { $::bFired==0 && [string match *test.db2-journal $file] } { + if {[string match *test.db2-journal $file]} { + tvfs filter {} ;# Ensure that tvfs callbacks to do run on the + # child thread sqlthread spawn ::thread_result [subst -nocommands { sqlite3_step $::STMT set rc [sqlite3_finalize $::STMT] }] - after 1000 { set ::bFired 1 } - vwait ::bFired + after 1000 { set ::some_time_later 1 } + vwait ::some_time_later } } -do_test 2.4 { db1 eval ROLLBACK } {} +do_test 2.3 { db1 eval ROLLBACK } {} +# Verify that the db2 statement invoked by the callback detected the +# schema change. +# if {[info exists ::thread_result]==0} { vwait ::thread_result } -do_test 2.5 { +do_test 2.4 { list $::thread_result [sqlite3_errmsg db2] } {SQLITE_SCHEMA {database schema has changed}} @@ -149,4 +186,3 @@ tvfs delete sqlite3_enable_shared_cache $::enable_shared_cache finish_test - From f2614145ec0226c417f85eac5ae5c056ce03affd Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 May 2013 16:16:25 +0000 Subject: [PATCH 09/11] Add main.c to the list of files compiled with SQLITE_TEST defined when building testfixture. FossilOrigin-Name: a58af81483a5facb09d2a80385fc8815b259a10d --- main.mk | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/main.mk b/main.mk index 30add69e29..912ebb4045 100644 --- a/main.mk +++ b/main.mk @@ -293,6 +293,7 @@ TESTSRC2 = \ $(TOP)/src/func.c \ $(TOP)/src/insert.c \ $(TOP)/src/wal.c \ + $(TOP)/src/main.c \ $(TOP)/src/mem5.c \ $(TOP)/src/os.c \ $(TOP)/src/os_unix.c \ diff --git a/manifest b/manifest index 9f70a70848..827d98037d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sloading\sa\sdatabase\sschema\sthat\scontains\san\sindex\sdefinition\sthat\sincludes\sa\sCOLLATE\sclause\sfor\swhich\sthe\scollation\ssequence\sis\sunavailable,\sdo\snot\sassume\sthat\sthat\sindex\suses\sBINARY\sinstead.\sFix\sfor\s[0fc59f908b]. -D 2013-05-15T15:16:50.069 +C Add\smain.c\sto\sthe\slist\sof\sfiles\scompiled\swith\sSQLITE_TEST\sdefined\swhen\sbuilding\stestfixture. +D 2013-05-15T16:16:25.168 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -114,7 +114,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 3f820e18c43504b25da40ff4b4cdb66dc4c4907e -F main.mk 1b25be82452366abc27cc9ab2acf3244a773d5a1 +F main.mk a8ebdf910e2cc10db1f9f54ec316f637458e8001 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -1063,7 +1063,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 8f9bd8e7a88eb11fb17d29954fa4b8c2840a5019 -R c30a5ff0c8f241909590b400195b0165 +P 6dae62c4e505a9a1a22c2771ef3e1921407c4748 +R 487fc7dc27dc4b82b7020b1b301782dd U dan -Z 12265815702aee04d3178d81300c6ea1 +Z e9d416a6022ae3cc41d820704187cebf diff --git a/manifest.uuid b/manifest.uuid index 38a7b3188e..8bcee2c560 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6dae62c4e505a9a1a22c2771ef3e1921407c4748 \ No newline at end of file +a58af81483a5facb09d2a80385fc8815b259a10d \ No newline at end of file From d58792e0f03829c18413c840251761659b86f199 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 May 2013 16:24:46 +0000 Subject: [PATCH 10/11] Extra test for commit [6dae62c4e5]. FossilOrigin-Name: b10b9e758b171b0f514592bba70c3ecd17c8c47f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/collate3.test | 8 ++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 827d98037d..29f23cf1c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smain.c\sto\sthe\slist\sof\sfiles\scompiled\swith\sSQLITE_TEST\sdefined\swhen\sbuilding\stestfixture. -D 2013-05-15T16:16:25.168 +C Extra\stest\sfor\scommit\s[6dae62c4e5]. +D 2013-05-15T16:24:46.069 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -342,7 +342,7 @@ F test/closure01.test 6194a899cdbba561d0439c0d6cc7bcdf4fc413e7 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 -F test/collate3.test a6cf2127340e8f5b9ceb2a95d97811210cfc4627 +F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f F test/collate4.test 031f7265c13308b724ba3c49f41cc04612bd92b1 F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 @@ -1063,7 +1063,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 6dae62c4e505a9a1a22c2771ef3e1921407c4748 -R 487fc7dc27dc4b82b7020b1b301782dd +P a58af81483a5facb09d2a80385fc8815b259a10d +R a1ee9dbf5bdc0c85e6d04c16bdc50678 U dan -Z e9d416a6022ae3cc41d820704187cebf +Z c734661d059ffa1379084a528d255758 diff --git a/manifest.uuid b/manifest.uuid index 8bcee2c560..f58cb6a5af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a58af81483a5facb09d2a80385fc8815b259a10d \ No newline at end of file +b10b9e758b171b0f514592bba70c3ecd17c8c47f \ No newline at end of file diff --git a/test/collate3.test b/test/collate3.test index 831526f364..2c051cb9a7 100644 --- a/test/collate3.test +++ b/test/collate3.test @@ -141,7 +141,15 @@ do_test collate3-1.7.5 { catchsql { PRAGMA integrity_check } } {0 ok} +proc needed {nm} { db collate caseless caseless } do_test collate3-1.7.6 { + db close + sqlite3 db test.db + db collation_needed needed + catchsql { PRAGMA integrity_check } +} {0 ok} + +do_test collate3-1.8 { execsql { DROP TABLE t1 } } {} From 6fdd3d8aa001c584c07096429a73d2bd8e52cb23 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 May 2013 17:47:12 +0000 Subject: [PATCH 11/11] The sqlite3ExprCollSeq() function can no longer be called while parse the schema, so remove the code path inside of sqlite3ExprCollSeq() that dealt with that case. FossilOrigin-Name: 867b3e3b29a357f68e48f0898bf323c5dd0575a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 7 +------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index a89e78f7e8..af0d36f61c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sshared-cache-fixes\sbranch\sinto\strunk. -D 2013-05-15T17:08:46.108 +C The\ssqlite3ExprCollSeq()\sfunction\scan\sno\slonger\sbe\scalled\swhile\sparse\nthe\sschema,\sso\sremove\sthe\scode\spath\sinside\sof\ssqlite3ExprCollSeq()\sthat\ndealt\swith\sthat\scase. +D 2013-05-15T17:47:12.088 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778 -F src/expr.c 437c03d5bb4fe3a53ecab3ad0286d6c5260da7ed +F src/expr.c e40d198a719aba1d2514f6e1541f9154f976ceb6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e16942bd5c8a868ac53287886464a5ed0e72b179 F src/func.c d3fdcff9274bc161152e67ed3f626841c247f4b9 @@ -1064,7 +1064,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P b10b9e758b171b0f514592bba70c3ecd17c8c47f 65ff754e3521aa8ee9135d235166cac2a8f57ebd -R 26e2acdf1151011acbca5696e65a3adb +P 5cc1cc55d28a73d390d51fdf6f2c026f1cab1d75 +R e7ec9db939b43c1fb3d0a5a8ccbae374 U drh -Z e5ba39f32795e7a7bb7657dbeb366ef9 +Z 1e4ce829f36f461fad5816fc545c080f diff --git a/manifest.uuid b/manifest.uuid index 5adb8d1dc7..58d9438daf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5cc1cc55d28a73d390d51fdf6f2c026f1cab1d75 \ No newline at end of file +867b3e3b29a357f68e48f0898bf323c5dd0575a4 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a974c5a61f..660397e078 100644 --- a/src/expr.c +++ b/src/expr.c @@ -116,12 +116,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ } assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); if( op==TK_COLLATE ){ - if( db->init.busy ){ - /* Do not report errors when parsing while the schema */ - pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0); - }else{ - pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); - } + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } if( p->pTab!=0