]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a bug that was emptying shared-schema tables during an ATTACH. (CVS 2867)
authordanielk1977 <danielk1977@noemail.net>
Fri, 6 Jan 2006 06:33:12 +0000 (06:33 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 6 Jan 2006 06:33:12 +0000 (06:33 +0000)
FossilOrigin-Name: 752a2754879becc32da9f9b910f3330f8c7145e4

manifest
manifest.uuid
src/btree.c
src/build.c
src/main.c
src/util.c
test/shared.test

index 0d8eee7060677f0cda16278ba180a9c5f0ce33bc..6efbaf3a6de62b675cfeb14732d609604b556d53 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enable\sasync\stesting.\s\sModify\sthe\sOS\slayer\sinterface.\s\sAdd\sthe\ssqlite3_aux.h\sinclude\sfile.\s\sAdd\stests\sfor\sboolean\svalue\srepresentation\sin\sfile\sformat\s4.\s(CVS\s2866)
-D 2006-01-06T03:29:57
+C Fix\sa\sbug\sthat\swas\semptying\sshared-schema\stables\sduring\san\sATTACH.\s(CVS\s2867)
+D 2006-01-06T06:33:12
 F Makefile.in 899551ac1dfad4131a4480176eab9e03c64b71ea
 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -34,9 +34,9 @@ F src/alter.c e9deb3f4fd7c663a0d1f235d541bc5ea1f2cfa8b
 F src/analyze.c d821684cdb4d0403e327e4a3440a832e9e54fa3a
 F src/attach.c 999104c56a60b88eab11ef9c8f40dedf1650b287
 F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f
-F src/btree.c 88a60d2af49daed01316cafbe93777d4d9ba2800
+F src/btree.c d1402f4e1cfc500b31d13990f36dd8d3d27443bc
 F src/btree.h 96b8c00c6e11ff92f8d3d6a7a0ff358bd10d8f19
-F src/build.c 6b14101f1ed5328c815e12baec11dcec97eed096
+F src/build.c 715ac7d49bbfcae5f3fdfd60885397b2133c283b
 F src/callback.c 62066afd516f220575e81b1a1239ab92a2eae252
 F src/complete.c df1681cef40dec33a286006981845f87b194e7a4
 F src/date.c bb079317bff6a2b78aba5c0d2ddae5f6f03acfb7
@@ -48,7 +48,7 @@ F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 F src/insert.c d167f9d41932ddaff9162f116e2abc514b0680b6
 F src/legacy.c 59757d857ab95fcbb0ac27692d3201e35f093dd7
-F src/main.c c1d8d2022a65104c847880882fbce9ba32381530
+F src/main.c 244a346ae0d1953c4c872b3429b8712b32f590a1
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
 F src/os.c a1953975771e1afa161a96e720e58a6f77f946e4
 F src/os.h 1f825a8ec854abe8f4cd3a1851c5f6c43e58fbf8
@@ -84,7 +84,7 @@ F src/tokenize.c 7a3a3d3cc734f684a77c4dfd09eb46fcee25394c
 F src/trigger.c 858c0a4974035b002fd2192399c6076ac7b75e1f
 F src/update.c c72e9cbbc0adf8d728c1c39ace03d4adb29b5cfb
 F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
-F src/util.c a690bbf549fc5c465384f624e90c009935b6d18b
+F src/util.c f79eb05721e7b20d1d323f903ea866ed2670c2a4
 F src/vacuum.c fbfdd3967fd34e2f260fafed88dcbf3c10856b94
 F src/vdbe.c 4dab34666edca29b937180965ad32120e98c8054
 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
@@ -223,7 +223,7 @@ F test/select4.test c239f516aa31f42f2ef7c6d7cd01105f08f934ca
 F test/select5.test 07a90ab3c7e3f0a241a9cdea1d997b2c8a89ff0b
 F test/select6.test f459a19bdac0501c4d3eb1a4df4b7a76f1bb8ad4
 F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6
-F test/shared.test aa054381c8fe21d7f46dc1d460ac85f675297b26
+F test/shared.test ee5a4154d257e4c2ce1ae418783b87847473de90
 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
 F test/subquery.test e6de53332c0301b3cfa34edc3f3cd5fa1e859efd
 F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2
@@ -338,7 +338,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P f1922da2d20c5091678e47cc4f43a2a9d141a3b1
-R cef6c464b1bd96d585319f7184eaa0c9
-U drh
-Z 3e96ca4b789b1816bc110ed7eb3a7071
+P b8332aa8b83142898779972b3dff13cbe3c78623
+R cf41b9057439725670e2ff912b4af45d
+U danielk1977
+Z c046cce8ff38eee9570320533f1a9c01
index 1483c938e8356e84ad47a1e68979b47fce69d879..bfefadee9e6f6e1f18b2e4b85541c215c6c413b9 100644 (file)
@@ -1 +1 @@
-b8332aa8b83142898779972b3dff13cbe3c78623
\ No newline at end of file
+752a2754879becc32da9f9b910f3330f8c7145e4
\ No newline at end of file
index 7af9fc4b15099a1cdca6a245f87bb06e985804ef..79de82c8d581599f57e98ee8bc5ddeda1730226f 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.280 2006/01/06 01:42:58 drh Exp $
+** $Id: btree.c,v 1.281 2006/01/06 06:33:12 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -1722,6 +1722,7 @@ int sqlite3BtreeClose(Btree *p){
   if( pBt->xFreeSchema && pBt->pSchema ){
     pBt->xFreeSchema(pBt->pSchema);
   }
+  sqliteFree(pBt->pSchema);
   sqliteFree(pBt);
   return SQLITE_OK;
 }
index 3170bcf2d88d15672b2199bb97fc9728a140d43c..528058a597b3373f4b74987e926cdbadbae45c82 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.367 2006/01/05 11:34:34 danielk1977 Exp $
+** $Id: build.c,v 1.368 2006/01/06 06:33:13 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -258,7 +258,6 @@ static void sqliteDeleteIndex(sqlite3 *db, Index *p){
   Index *pOld;
   const char *zName = p->zName;
 
-  assert( db!=0 && zName!=0 );
   pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0);
   assert( pOld==0 || pOld==p );
   freeIndex(p);
@@ -304,9 +303,6 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
 ** single file indicated.
 */
 void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
-  HashElem *pElem;
-  Hash temp1;
-  Hash temp2;
   int i, j;
 
   assert( iDb>=0 && iDb<db->nDb );
@@ -314,23 +310,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
   for(i=iDb; i<db->nDb; i++){
     Db *pDb = &db->aDb[i];
     if( pDb->pSchema ){
-      temp1 = pDb->pSchema->tblHash;
-      temp2 = pDb->pSchema->trigHash;
-      sqlite3HashInit(&pDb->pSchema->trigHash, SQLITE_HASH_STRING, 0);
-      sqlite3HashClear(&pDb->pSchema->aFKey);
-      sqlite3HashClear(&pDb->pSchema->idxHash);
-      for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
-        sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
-      }
-      sqlite3HashClear(&temp2);
-      sqlite3HashInit(&pDb->pSchema->tblHash, SQLITE_HASH_STRING, 0);
-      for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
-        Table *pTab = sqliteHashData(pElem);
-        sqlite3DeleteTable(db, pTab);
-      }
-      sqlite3HashClear(&temp1);
-      pDb->pSchema->pSeqTab = 0;
-      DbClearProperty(db, i, DB_SchemaLoaded);
+      sqlite3SchemaFree(pDb->pSchema);
     }
     if( iDb>0 ) return;
   }
@@ -427,6 +407,8 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
   Index *pIndex, *pNext;
   FKey *pFKey, *pNextFKey;
 
+  db = 0;
+
   if( pTable==0 ) return;
 
   /* Do not delete the table until the reference count reaches zero. */
@@ -450,7 +432,6 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
   */
   for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
     pNextFKey = pFKey->pNextFrom;
-    assert( sqlite3SchemaToIndex(db, pTable->pSchema)<db->nDb );
     assert( sqlite3HashFind(&pTable->pSchema->aFKey,
                            pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
     sqliteFree(pFKey);
index ebf2a3480c550fef31c0a2a56659d94f07e2363f..6f4a2c07bfbb5cfe0e358a71179b8efcfea747c9 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.315 2006/01/05 13:48:29 danielk1977 Exp $
+** $Id: main.c,v 1.316 2006/01/06 06:33:13 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -96,10 +96,34 @@ int sqlite3_total_changes(sqlite3 *db){
 }
 
 /*
-** Free a schema structure.
+** Free all resources held by the schema structure. The void* argument points
+** at a DbSchema struct. This function does not call sqliteFree() on the 
+** pointer itself, it just cleans up subsiduary resources (i.e. the contents
+** of the schema hash tables).
 */
 void sqlite3SchemaFree(void *p){
-  sqliteFree(p);
+  Hash temp1;
+  Hash temp2;
+  HashElem *pElem;
+  DbSchema *pSchema = (DbSchema *)p;
+
+  temp1 = pSchema->tblHash;
+  temp2 = pSchema->trigHash;
+  sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
+  sqlite3HashClear(&pSchema->aFKey);
+  sqlite3HashClear(&pSchema->idxHash);
+  for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
+    sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
+  }
+  sqlite3HashClear(&temp2);
+  sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
+  for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
+    Table *pTab = sqliteHashData(pElem);
+    sqlite3DeleteTable(0, pTab);
+  }
+  sqlite3HashClear(&temp1);
+  pSchema->pSeqTab = 0;
+  pSchema->flags &= ~DB_SchemaLoaded;
 }
 
 DbSchema *sqlite3SchemaGet(Btree *pBt){
@@ -109,7 +133,7 @@ DbSchema *sqlite3SchemaGet(Btree *pBt){
   }else{
     p = (DbSchema *)sqliteMalloc(sizeof(DbSchema));
   }
-  if( p ){
+  if( p && 0==p->file_format ){
     sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
     sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
     sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
index 898d3dedb7046d4423ea43821adb336834dfb7dc..82fe9ecf01dd895b687cac7fe97a20b6b91ad4c1 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.159 2005/12/29 01:11:37 drh Exp $
+** $Id: util.c,v 1.160 2006/01/06 06:33:13 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -289,6 +289,10 @@ static void applyGuards(u32 *p)
   checkGuards(p);
 }
 
+/*
+** The argument is a malloc()ed pointer as returned by the test-wrapper.
+** Return a pointer to the Os level allocation.
+*/
 static void *getOsPointer(void *p)
 {
   char *z = (char *)p;
index 0abadc3ef80bcbb1a8267691199c9ffb85b63d4b..cc32aa0190160bfc04a5ed93165f1524716b6371 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the SELECT statement.
 #
-# $Id: shared.test,v 1.2 2006/01/05 11:34:34 danielk1977 Exp $
+# $Id: shared.test,v 1.3 2006/01/06 06:33:13 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -32,6 +32,8 @@ set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
 #             external locking protocol is still working.
 # shared-3.*: Simple test of read-uncommitted mode.
 #
+# shared-4.*: Check that the schema is locked and unlocked correctly.
+#
 
 do_test shared-1.1 {
   # Open a second database on the file test.db. It should use the same pager
@@ -218,6 +220,58 @@ catch {db close}
 catch {db2 close}
 catch {db3 close}
 
+#--------------------------------------------------------------------------
+# Tests shared-4.* test that the schema locking rules are applied 
+# correctly. i.e.:
+#
+# 1. All transactions require a read-lock on the schemas of databases they
+#    access.
+# 2. Transactions that modify a database schema require a write-lock on that
+#    schema.
+# 3. It is not possible to compile a statement while another handle has a 
+#    write-lock on the schema.
+#
+
+# Open two database handles db and db2. Each has a single attach database
+# (as well as main):
+#
+#     db.main   ->   ./test.db
+#     db.test2  ->   ./test2.db
+#     db2.main  ->   ./test2.db
+#     db2.test  ->   ./test.db
+#
+file delete -force test.db
+file delete -force test2.db
+file delete -force test2.db-journal
+sqlite3 db  test.db
+sqlite3 db2 test2.db
+do_test shared-4.1.1 {
+  set sqlite_open_file_count
+} {2}
+do_test shared-4.1.2 {
+  execsql {ATTACH 'test2.db' AS test2}
+  set sqlite_open_file_count
+} {2}
+do_test shared-4.1.3 {
+  execsql {ATTACH 'test.db' AS test} db2
+  set sqlite_open_file_count
+} {2}
+
+do_test shared-4.2.1 {
+  execsql {
+    CREATE TABLE abc(a, b, c);
+    INSERT INTO abc VALUES('i', 'ii', 'iii');
+  }
+} {}
+do_test shared-4.2.2 {
+  execsql {
+    SELECT * FROM test.abc;
+  } db2
+} {i ii iii}
+
+catch {db2 close}
+catch {db close}
+
 finish_test
 sqlite3_enable_shared_cache $::enable_shared_cache