]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make sure the rootpage values in the symbol table are correctly updated
authordrh <drh@noemail.net>
Fri, 24 Mar 2006 03:36:26 +0000 (03:36 +0000)
committerdrh <drh@noemail.net>
Fri, 24 Mar 2006 03:36:26 +0000 (03:36 +0000)
when dropping tables and indices in autocommit mode.  Ticket #1728. (CVS 3150)

FossilOrigin-Name: 1c582dd11304f4421da2fa451f52b313b541270e

manifest
manifest.uuid
src/build.c
test/autovacuum.test

index 9a43cd185d509c3f9ea25917ea57a482656260f5..f1f5eb0ec5524e7978a4d8d7c11fbe1dfccc11eb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improvements\sto\scomments\sin\sbuild.c.\s(CVS\s3149)
-D 2006-03-23T23:33:27
+C Make\ssure\sthe\srootpage\svalues\sin\sthe\ssymbol\stable\sare\scorrectly\supdated\nwhen\sdropping\stables\sand\sindices\sin\sautocommit\smode.\s\sTicket\s#1728.\s(CVS\s3150)
+D 2006-03-24T03:36:26
 F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b
 F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -36,7 +36,7 @@ F src/attach.c d73a3505de3fb9e373d0a158978116c4212031d0
 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
 F src/btree.c 582f0fb985c3dc209d2904639dd2c3c4544ba90e
 F src/btree.h 40055cfc09defd1146bc5b922399c035f969e56d
-F src/build.c b8437e81e1e10a8fedda0b6209bb05c83e93a844
+F src/build.c be0629119df8c1e09050a8fcbf182112f00e3b14
 F src/callback.c d8c5ab1cd6f3b7182b2ee63bf53f1b69c0f74306
 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
@@ -113,7 +113,7 @@ F test/attach3.test 63013383adc4380af69779f34f4af19bd49f7cbe
 F test/attachmalloc.test cdb26c42850f04698377ccec05f5fa89d987837c
 F test/auth.test 9776ab43de94801f0fa6787b3f3e803686ffa0ff
 F test/autoinc.test 60005a676e3e4e17dfa9dbd08aa0b76587ff97e3
-F test/autovacuum.test 12bb130cf7ee5b9cf9672bc82655b5f4391e1d15
+F test/autovacuum.test eee7e67d80f7839d11435660ae0a5566a9f7558c
 F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31
 F test/autovacuum_ioerr.test c46a76869cb6eddbbb40b419b2b6c4c001766b1f
 F test/autovacuum_ioerr2.test 2f8a3fb31f833fd0ca86ad4ad98913c73e807572
@@ -355,7 +355,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 21446df6420df00468867f1131c28604a1ae91a3
-R 5732f7c7668c3772e0c25148e3d40aa1
+P 986208a364ce0ba81456b54e6561a277fb19309c
+R 2e778dd94b82fbaeaf00aeb2c0a3a8c9
 U drh
-Z 7ebd5a18779bf0f0d04ac1a12eb7a3df
+Z 5880b394a81520a397b49dc9bfcb72dd
index f37fd68355d2500f20d9b26f6e1000bb8bb2135b..035242f4d3888d8f6b5eaf71cbc61f5215ac6757 100644 (file)
@@ -1 +1 @@
-986208a364ce0ba81456b54e6561a277fb19309c
\ No newline at end of file
+1c582dd11304f4421da2fa451f52b313b541270e
\ No newline at end of file
index cdf8c19af90d6532ff9ec6442bf4425ada3a50e9..8e6d7fdf58e3927c6fd963b82b5dd6952f237f90 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.392 2006/03/23 23:33:27 drh Exp $
+** $Id: build.c,v 1.393 2006/03/24 03:36:26 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1727,6 +1727,17 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){
 ** used by SQLite when the btree layer moves a table root page. The
 ** root-page of a table or index in database iDb has changed from iFrom
 ** to iTo.
+**
+** Ticket #1728:  The symbol table might still contain information
+** on tables and/or indices that are the process of being deleted.
+** If you are unlucky, one of those deleted indices or tables might
+** have the same rootpage number as the real table or index that is
+** being moved.  So we cannot stop searching after the first match 
+** because the first match might be for one of the deleted indices
+** or tables and not the table/index that is actually being moved.
+** We must continue looping until all tables and indices with
+** rootpage==iFrom have been converted to have a rootpage of iTo
+** in order to be certain that we got the right one.
 */
 #ifndef SQLITE_OMIT_AUTOVACUUM
 void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
@@ -1738,7 +1749,6 @@ void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
     Table *pTab = sqliteHashData(pElem);
     if( pTab->tnum==iFrom ){
       pTab->tnum = iTo;
-      return;
     }
   }
   pHash = &pDb->pSchema->idxHash;
@@ -1746,10 +1756,8 @@ void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
     Index *pIdx = sqliteHashData(pElem);
     if( pIdx->tnum==iFrom ){
       pIdx->tnum = iTo;
-      return;
     }
   }
-  assert(0);
 }
 #endif
 
index 30694349674688d609d0d00d6410e6d856dbd576..bd0979c2e9291127beb36f81974cb67c50f0231d 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: autovacuum.test,v 1.21 2006/03/23 23:29:04 drh Exp $
+# $Id: autovacuum.test,v 1.22 2006/03/24 03:36:26 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -538,4 +538,37 @@ do_test autovacuum-5.1 {
   }
 } ok
 
+# Ticket #1728.
+#
+# In autovacuum mode, when tables or indices are deleted, the rootpage
+# values in the symbol table have to be updated.  There was a bug in this
+# logic so that if an index/table was moved twice, the second move might
+# not occur.  This would leave the internal symbol table in an inconsistent
+# state causing subsequent statements to fail.
+#
+# The problem is difficult to reproduce.  The sequence of statements in
+# the following test are carefully designed make it occur and thus to
+# verify that this very obscure bug has been resolved.
+# 
+do_test autovacuum-6.1 {
+  db close
+  sqlite3 db :memory:
+  db eval {
+    PRAGMA auto_vacuum=1;
+    CREATE TABLE t1(a, b);
+    CREATE INDEX i1 ON t1(a);
+    CREATE TABLE t2(a);
+    CREATE INDEX i2 ON t2(a);
+    CREATE TABLE t3(a);
+    CREATE INDEX i3 ON t2(a);
+    CREATE INDEX x ON t1(b);
+    DROP TABLE t3;
+    PRAGMA integrity_check;
+    DROP TABLE t2;
+    PRAGMA integrity_check;
+    DROP TABLE t1;
+    PRAGMA integrity_check;
+  }
+} {ok ok ok}
+
 finish_test