]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the "PRAGMA integrity_check" command to verify that all indices are
authordrh <drh@noemail.net>
Sun, 15 Jun 2003 23:42:24 +0000 (23:42 +0000)
committerdrh <drh@noemail.net>
Sun, 15 Jun 2003 23:42:24 +0000 (23:42 +0000)
correctly constructed.  New calls to integrity_check are made in the test
suite. These changes are intended to prevent any future problems such
as seen in ticket #334. (CVS 1024)

FossilOrigin-Name: c9734c27074d2039a1896a8c6965c08d03711b13

21 files changed:
manifest
manifest.uuid
src/encode.c
src/pragma.c
src/vdbe.c
test/attach.test
test/conflict.test
test/delete.test
test/index.test
test/insert.test
test/intpkey.test
test/memdb.test
test/pragma.test
test/tester.tcl
test/trigger1.test
test/trigger2.test
test/trigger3.test
test/trigger4.test
test/unique.test
test/update.test
test/where.test

index c0db1a90dda861b9d4115c52cc4c075733646802..461eb5a96cd0952a76a678b2e323fe0b7f8f4a21 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Updated\ssqlite_encode_binary()\scomments\swith\stighter\sbounds\son\soutput\slength.\s(CVS\s1023)
-D 2003-06-15T10:35:05
+C Enhance\sthe\s"PRAGMA\sintegrity_check"\scommand\sto\sverify\sthat\sall\sindices\sare\ncorrectly\sconstructed.\s\sNew\scalls\sto\sintegrity_check\sare\smade\sin\sthe\stest\nsuite.\sThese\schanges\sare\sintended\sto\sprevent\sany\sfuture\sproblems\ssuch\nas\sseen\sin\sticket\s#334.\s(CVS\s1024)
+D 2003-06-15T23:42:24
 F Makefile.in 9ad23ed4ca97f9670c4496432e3fbd4b3760ebde
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -27,7 +27,7 @@ F src/btree_rb.c a0dd64f840417b13637160599bd2740c8a340366
 F src/build.c 936d10b33b326546280690bee7f20efaf19a6fe8
 F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73
 F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
-F src/encode.c a5fc03201e34b0015817202e9286bacf89e72048
+F src/encode.c d37cb398b4ada55dbecc35b32ca3927621f3c3c3
 F src/expr.c ebdb0f3ee039c8030de25935ce2df030966540a6
 F src/func.c 33bbce6acaf9578ac99aa1f689968ccaf2ce43a2
 F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
@@ -40,7 +40,7 @@ F src/os.h 9e5bbddff123187295e3d00d49af06192cd1cd49
 F src/pager.c 6c50e8dc861bb08f8c52b1fe9aabef6554d61c95
 F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
 F src/parse.y 917250e5d86bdee752355e6617ea2e8ee12438bf
-F src/pragma.c f439a6157fe7c8d66dc2c6bfde2abaf23e770e1d
+F src/pragma.c 3b4f5a800e7a2145bc1930f323232e297d4eb782
 F src/printf.c 12ab57e638c8201033c96717df7af59e06933314
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 F src/select.c 76b3a5cda76421cfe82d6a96c72308c2518cb2f9
@@ -59,11 +59,11 @@ F src/trigger.c 6ff205aaac4869e402d9902e528e1d22a85de14c
 F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
 F src/util.c 566c7780170dd11fb1ad5de3ba81f0dfea7cccf0
 F src/vacuum.c 0820984615786c9ccdaad8032a792309b354a8eb
-F src/vdbe.c 828123ca4a28b7b5432ca4dc39e4ad91484ddabf
+F src/vdbe.c b0118814124785cf9244f3cf7f389681ad46adac
 F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21
 F src/where.c 1e645d430cb4b347159c28c6085e9801160f2099
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
-F test/attach.test 71905b5e7a5a712e7ea47d249431740e617ec75e
+F test/attach.test eccea2937923ac0be8ad1072585fd3b4f0b85598
 F test/auth.test a618f0e96bb5baa7a5623eb939388e9ac5f5d9a2
 F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
@@ -74,25 +74,25 @@ F test/btree3rb.test 127efcf5cdfcc352054e7db12622b01cdd8b36ac
 F test/btree4.test fa955a3d7a8bc91d6084b7f494f9e5d1bdfb15b6
 F test/btree4rb.test ae6f0438512edcb45cf483471cd6070a765963a9
 F test/capi2.test dddfe84d41c876e5339efae41f8e688760454fba
-F test/conflict.test 70d38ff29b532813320c17740738a556ee0ec95d
+F test/conflict.test 0a66a573b8b4f8b781b2ebb7d4f27dcfd9e87312
 F test/copy.test c860847f1bd66175ef7cb724326a1700e0295820
-F test/delete.test 1586a00574e699a9913bc3403261813e8a93e6b9
+F test/delete.test 92256384f1801760180ded129f7427884cf28886
 F test/expr.test 48bc6400627532ec97e233809e33d336468bc84c
 F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
 F test/format3.test b05cb2968841553698290f2833f72894f156024e
 F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4
 F test/in.test 22de8a3eb27265aab723adc513bea0e76bef70c6
-F test/index.test 90ef4c426865f15937858bd433cc82b9c11af913
-F test/insert.test 8902df72b309164e4b99694aed3e12c2e37516ab
+F test/index.test 1962dbc8c0ef2467195776bdee18ef7cf3ce9b62
+F test/insert.test a17b7f7017097afb2727aa5b67ceeb7ab0a120a1
 F test/insert2.test c288375a64dad3295044714f0dfed4a193cf067f
-F test/intpkey.test 39f49fd993350f7f3ab255e5cfbf9a09d8f8800e
+F test/intpkey.test 9320af48415c594afd4e15f8ef0daa272e05502e
 F test/ioerr.test 5dbaf09f96b56ee01cf3edd762b96eb4ad2c9ca4
 F test/join.test 16c91ec27170c20e2a10796775e62c5c3dcbda44
 F test/limit.test 9ffb965a0f5bf7152187ef3d8d1249b96e5620bf
 F test/lock.test 388a3a10962d2d571c0c1821cc35bf069ee73473
 F test/main.test 6a851b5992c4881a725a3d9647e629199df8de9d
 F test/malloc.test 7ba32a9ebd3aeed52ae4aaa6d42ca37e444536fd
-F test/memdb.test ab1d16eb3179272016b1fe5fa3988e9c2f6c5594
+F test/memdb.test cd4580f466f34c42354612a375c5adb90447e4c4
 F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90
 F test/minmax.test b54ac3bc45460a4976b08ef363e05c032418726e
 F test/misc1.test c7dc2f2bd702d8283e885a64ec0714be26cfb051
@@ -100,7 +100,7 @@ F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
 F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd
 F test/pager.test dd31da9bee94a82e2e87e58cf286cfe809f8fc5f
-F test/pragma.test d45d130f532bfe86ebd5ba74862d88b36ded8998
+F test/pragma.test 4c707a6f7d3cbf72d46ed9d9eb0e1ea6e42dc3e4
 F test/printf.test a29b8afa24edb4411adfe473b12ac32c84098fce
 F test/quick.test c527bdb899b12a8cd8ceecce45f72922099f4095
 F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
@@ -117,18 +117,18 @@ F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4
 F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
 F test/tclsqlite.test d9bdfc0afca9ee605c50ecb39e94ae4dea8c222b
 F test/temptable.test c82bd6f800f10e8cf96921af6315e5f1c21e2692
-F test/tester.tcl d7a5835edaf118539241145d8188f0822b673488
+F test/tester.tcl 2671536d3650c29e7c105219f277568b0884cb58
 F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
-F test/trigger1.test 8e6c11a1b7962ae9dd89c124d36667f52568a4ac
-F test/trigger2.test 00ceb8aff6bddd511bbac7c837af2863fa0c9cb4
-F test/trigger3.test 870afef7997a5b86bf3ea893ce0c2e85d6356c72
-F test/trigger4.test f0092c8580cce3c7119b17eefd3cc766a7579557
-F test/unique.test 22a46df72a3e0a3fd1a2d39e96fb59f18448dd5f
-F test/update.test 198360dfa14e65354dbcc66d5b98d8070780e42b
+F test/trigger1.test 6efd402da3b74e2d9e6a42b8a97413575fbf48f6
+F test/trigger2.test b17223c35fe97bdca542a049774a2496afef0bb9
+F test/trigger3.test a95ccace88291449f5eae7139ec438a42f90654d
+F test/trigger4.test 542afce45774e8f8e1130b96b8675f414d6e4bd8
+F test/unique.test 426580d01af47d44bea67aaf66007bd41a63e841
+F test/update.test 3ddb0ece1f99ae4deeaa6e6798a0608e167f9444
 F test/vacuum.test 4d8c8af30338577af03e563bc815d7898ae65258
 F test/version.test 605fd0d7e7d571370c32b12dbf395b58953de246
 F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53
-F test/where.test d719129a052280fe245a2ddcbd09bcc0b8c17ce4
+F test/where.test cb3a2ed062ce4b5f08aff2d08027c6a46d68c47b
 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
 F tool/lemon.c 93db920de9479657d04ca73e9368db7fc2969990
 F tool/lempar.c 73a991cc3017fb34804250fa901488b5147b3717
@@ -165,7 +165,7 @@ F www/speed.tcl 296cc5632d069b56d3ef5409ca0df90f486c10fb
 F www/sqlite.tcl 4bd1729e320f5fa9125f0022b281fbe839192125
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 14fdcc7fe8a60a6ba8584903636db8dc37eef26a
-P 6c24dfbae56a16dd736de5297c1796818773df80
-R 58e24d713b97f4ba7b875ae8dce7497f
-U jplyon
-Z fb46334e21926a895547abc49f262bff
+P 826aab43d5967ece2a272c49ce62021fa4a2ceb3
+R 651f8eac1fc1c1d3257c65b978b3107e
+U drh
+Z 6d6fc61d18f82a7eddc9efe63cd1c9d0
index 617cb0330a523bef85ae3117cfd599ab8cc53458..e381b9aa02ee6e4c3ff4b76c8373d764c2a80f96 100644 (file)
@@ -1 +1 @@
-826aab43d5967ece2a272c49ce62021fa4a2ceb3
\ No newline at end of file
+c9734c27074d2039a1896a8c6965c08d03711b13
\ No newline at end of file
index b18564cb692049aa3d4a3dabc3e5db80c3c961d3..75d030f005824ba3ed8172af72b641e8e4c6f76e 100644 (file)
@@ -15,7 +15,7 @@
 ** data in an SQLite database.  The code in this file is not used by any other
 ** part of the SQLite library.
 **
-** $Id: encode.c,v 1.7 2003/06/15 10:35:05 jplyon Exp $
+** $Id: encode.c,v 1.8 2003/06/15 23:42:24 drh Exp $
 */
 #include <string.h>
 
@@ -38,7 +38,7 @@
 **
 ** If that were all the encoder did, it would work, but in certain cases
 ** it could double the size of the encoded string.  For example, to
-** encode a string of 100 0x27 character would require 100 instances of
+** encode a string of 100 0x27 characters would require 100 instances of
 ** the 0x01 0x03 escape sequence resulting in a 200-character output.
 ** We would prefer to keep the size of the encoded string smaller than
 ** this.
index 0aaae6968ebd15625a4b67312ae92f3235053769..593970b776a8a1f386228d2fcdc92542a44aad02 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.9 2003/06/04 15:48:33 drh Exp $
+** $Id: pragma.c,v 1.10 2003/06/15 23:42:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -509,28 +509,156 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
 #endif
 
   if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
+    int i, j, addr;
+
+    /* Code that initializes the integrity check program.  Set the
+    ** error message to an empty string and register the callback
+    ** column name.
+    */
+    static VdbeOp initCode[] = {
+      { OP_String,      0, 0,        ""},
+      { OP_MemStore,    0, 1,        0},
+      { OP_ColumnName,  0, 0,        "integrity_check"},
+    };
+
+    /* Code to do an BTree integrity check on a single database file.
+    */
     static VdbeOp checkDb[] = {
       { OP_SetInsert,   0, 0,        "2"},
-      { OP_Integer,     0, 0,        0},   
+      { OP_Integer,     0, 0,        0},    /* 1 */
       { OP_OpenRead,    0, 2,        0},
-      { OP_Rewind,      0, 7,        0},
+      { OP_Rewind,      0, 7,        0},    /* 3 */
       { OP_Column,      0, 3,        0},    /* 4 */
       { OP_SetInsert,   0, 0,        0},
-      { OP_Next,        0, 4,        0},
+      { OP_Next,        0, 4,        0},    /* 6 */
       { OP_IntegrityCk, 0, 0,        0},    /* 7 */
-      { OP_ColumnName,  0, 0,        "integrity_check"},
-      { OP_Callback,    1, 0,        0},
-      { OP_SetInsert,   1, 0,        "2"},
-      { OP_Integer,     1, 0,        0},
-      { OP_OpenRead,    1, 2,        0},
-      { OP_Rewind,      1, 17,       0},
-      { OP_Column,      1, 3,        0},    /* 14 */
-      { OP_SetInsert,   1, 0,        0},
-      { OP_Next,        1, 14,       0},
-      { OP_IntegrityCk, 1, 1,        0},    /* 17 */
+      { OP_Dup,         0, 1,        0},
+      { OP_String,      0, 0,        "ok"},
+      { OP_StrEq,       0, 12,       0},    /* 10 */
+      { OP_MemLoad,     0, 0,        0},
+      { OP_String,      0, 0,        "*** in database "},
+      { OP_String,      0, 0,        0},    /* 13 */
+      { OP_String,      0, 0,        " ***\n"},
+      { OP_Pull,        4, 0,        0},
+      { OP_Concat,      5, 1,        0},
+      { OP_MemStore,    0, 1,        0},
+      { OP_Integer,     0, 0,        0},
+      { OP_Pop,         1, 0,        0},
+    };
+
+    /* Code that appears at the end of the integrity check.  If no error
+    ** messages have been generated, output OK.  Otherwise output the
+    ** error message
+    */
+    static VdbeOp endCode[] = {
+      { OP_MemLoad,     0, 0,        0},
+      { OP_Dup,         0, 1,        0},
+      { OP_String,      0, 0,        ""},
+      { OP_StrNe,       0, 0,        0},    /* 3 */
+      { OP_Pop,         1, 0,        0},
+      { OP_String,      0, 0,        "ok"},
       { OP_Callback,    1, 0,        0},
     };
-    sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
+
+    /* Initialize the VDBE program */
+    sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
+
+    /* Do an integrity check on each database file */
+    for(i=0; i<db->nDb; i++){
+      HashElem *x;
+
+      /* Do an integrity check of the B-Tree
+      */
+      addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
+      sqliteVdbeChangeP1(v, addr+1, i);
+      sqliteVdbeChangeP2(v, addr+3, addr+7);
+      sqliteVdbeChangeP2(v, addr+6, addr+4);
+      sqliteVdbeChangeP2(v, addr+7, i);
+      sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb)-1);
+      sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
+
+      /* Make sure all the indices are constructed correctly.
+      */
+      sqliteCodeVerifySchema(pParse, i);
+      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
+        Table *pTab = sqliteHashData(x);
+        Index *pIdx;
+        int loopTop;
+
+        if( pTab->pIndex==0 ) continue;
+        sqliteVdbeAddOp(v, OP_Integer, i, 0);
+        sqliteVdbeAddOp(v, OP_OpenRead, 1, pTab->tnum);
+        sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+          if( pIdx->tnum==0 ) continue;
+          sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+          sqliteVdbeAddOp(v, OP_OpenRead, j+2, pIdx->tnum);
+          sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC);
+        }
+        sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+        sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
+        loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
+        sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+          int k, jmp2;
+          static VdbeOp idxErr[] = {
+            { OP_MemLoad,     0,  0,  0},
+            { OP_String,      0,  0,  "rowid "},
+            { OP_Recno,       1,  0,  0},
+            { OP_String,      0,  0,  " missing from index "},
+            { OP_String,      0,  0,  0},    /* 4 */
+            { OP_String,      0,  0,  "\n"},
+            { OP_Concat,      6,  0,  0},
+            { OP_MemStore,    0,  1,  0},
+          };
+          sqliteVdbeAddOp(v, OP_Recno, 1, 0);
+          for(k=0; k<pIdx->nColumn; k++){
+            int idx = pIdx->aiColumn[k];
+            if( idx==pTab->iPKey ){
+              sqliteVdbeAddOp(v, OP_Recno, 1, 0);
+            }else{
+              sqliteVdbeAddOp(v, OP_Column, 1, idx);
+            }
+          }
+          sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+          if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
+          jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
+          addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
+          sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
+          sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
+        }
+        sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
+        sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+          static VdbeOp cntIdx[] = {
+             { OP_Integer,      0,  0,  0},
+             { OP_MemStore,     2,  1,  0},
+             { OP_Rewind,       0,  0,  0},  /* 2 */
+             { OP_MemIncr,      2,  0,  0},
+             { OP_Next,         0,  0,  0},  /* 4 */
+             { OP_MemLoad,      1,  0,  0},
+             { OP_MemLoad,      2,  0,  0},
+             { OP_Eq,           0,  0,  0},  /* 7 */
+             { OP_MemLoad,      0,  0,  0},
+             { OP_String,       0,  0,  "wrong # of entries in index "},
+             { OP_String,       0,  0,  0},  /* 10 */
+             { OP_String,       0,  0,  "\n"},
+             { OP_Concat,       4,  0,  0},
+             { OP_MemStore,     0,  1,  0},
+          };
+          if( pIdx->tnum==0 ) continue;
+          addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
+          sqliteVdbeChangeP1(v, addr+2, j+2);
+          sqliteVdbeChangeP2(v, addr+2, addr+5);
+          sqliteVdbeChangeP1(v, addr+4, j+2);
+          sqliteVdbeChangeP2(v, addr+4, addr+3);
+          sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
+          sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
+        }
+      } 
+    }
+    addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
+    sqliteVdbeChangeP2(v, addr+3, addr+ArraySize(endCode)-1);
   }else
 
   {}
index 179556de595250fc3c7e5dcb43e133159873a6c8..c03d661989650ec07ebac35bdabda6977ade77d6 100644 (file)
@@ -36,7 +36,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.227 2003/06/07 11:33:45 drh Exp $
+** $Id: vdbe.c,v 1.228 2003/06/15 23:42:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -486,7 +486,6 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
   return addr;
 }
 
-#if 0 /* NOT USED */
 /*
 ** Change the value of the P1 operand for a specific instruction.
 ** This routine is useful when a large program is loaded from a
@@ -499,7 +498,6 @@ void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
     p->aOp[addr].p1 = val;
   }
 }
-#endif /* NOT USED */
 
 /*
 ** Change the value of the P2 operand for a specific instruction.
@@ -4627,7 +4625,9 @@ case OP_CreateTable: {
 ** If there are no errors, push a "ok" onto the stack.
 **
 ** P1 is the index of a set that contains the root page numbers
-** for all tables and indices in the main database file.
+** for all tables and indices in the main database file.  The set
+** is cleared by this opcode.  In other words, after this opcode
+** has executed, the set will be empty.
 **
 ** If P2 is not zero, the check is done on the auxiliary database
 ** file, not the main database file.
@@ -4653,6 +4653,8 @@ case OP_IntegrityCk: {
     toInt((char*)sqliteHashKey(i), &aRoot[j]);
   }
   aRoot[j] = 0;
+  sqliteHashClear(&pSet->hash);
+  pSet->prev = 0;
   z = sqliteBtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
   if( z==0 || z[0]==0 ){
     if( z ) sqliteFree(z);
index ad3b2032d910486733291d4b90e7657ab6061269..0813068c72e3b9f531f1776259e44dcc83fdd6db 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and related functionality.
 #
-# $Id: attach.test,v 1.9 2003/06/04 15:53:02 drh Exp $
+# $Id: attach.test,v 1.10 2003/06/15 23:42:25 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -145,12 +145,13 @@ do_test attach-1.19 {
     ATTACH 'test.db' as db12;
   }
 } {1 {too many attached databases - max 10}}
-do_test attach-1.20 {
+do_test attach-1.20.1 {
   execsql {
     DETACH db5;
   }
   db_list db
 } {0 main 1 temp 2 db2 3 db3 4 db4 5 db11 6 db6 7 db7 8 db8 9 db9 10 db10}
+integrity_check attach-1.20.2
 do_test attach-1.21 {
   catchsql {
     ATTACH 'test.db' as db12;
index 26dcbfe24c9addca34f1e5c42f5b21236567ce33..95b042d84b58ae483f9d9ae87119d9e49279170a 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the conflict resolution extension
 # to SQLite.
 #
-# $Id: conflict.test,v 1.17 2003/05/16 02:30:27 drh Exp $
+# $Id: conflict.test,v 1.18 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -689,4 +689,6 @@ do_test conflict-10.2 {
   execsql {SELECT * FROM t4}
 } {}
 
+integrity_check conflict-99.0
+
 finish_test
index cf8fa2470a5a3cffa233cf2bb2903b65330ae609..4b7277e82637befd44810b864edb7425554cae7c 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the DELETE FROM statement.
 #
-# $Id: delete.test,v 1.12 2003/05/04 20:42:56 drh Exp $
+# $Id: delete.test,v 1.13 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -60,6 +60,8 @@ do_test delete-3.1.6 {
 do_test delete-3.1.7 {
   execsql {SELECT * FROM table1 ORDER BY f1}
 } {1 2 4 16}
+integrity_check delete-3.2
+
 
 # Semantic errors in the WHERE clause
 #
@@ -73,6 +75,7 @@ do_test delete-4.2 {
   set v [catch {execsql {DELETE FROM table2 WHERE xyzzy(f1+4)}} msg]
   lappend v $msg
 } {1 {no such function: xyzzy}}
+integrity_check delete-4.3
 
 # Lots of deletes
 #
@@ -142,6 +145,8 @@ do_test delete-5.7 {
   execsql "DELETE FROM table1 WHERE f1!=48"
   execsql {SELECT f1 FROM table1 ORDER BY f1}
 } {48}
+integrity_check delete-5.8
+
 
 # Delete large quantities of data.  We want to test the List overflow
 # mechanism in the vdbe.
@@ -192,6 +197,7 @@ do_test delete-6.10 {
   execsql {INSERT INTO table2 VALUES(2,3)}
   execsql {SELECT f1 FROM table2}
 } {2}
+integrity_check delete-6.11
 
 do_test delete-7.1 {
   execsql {
@@ -240,6 +246,7 @@ do_test delete-7.6 {
     DELETE FROM t4;
   }
 } {4 4}
+integrity_check delete-7.7
 
 # Make sure error messages are consistent when attempting to delete
 # from a read-only database.  Ticket #304.
@@ -279,6 +286,6 @@ do_test delete-8.5 {
 do_test delete-8.6 {
   execsql {SELECT * FROM t3}
 } {123}
-
+integrity_check delete-8.7
 
 finish_test
index 26243c568337d0ac682e994028f69fe18b7cfa60..b28f8d35f7014c9da53f7a50d86533ffd0e97792 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the CREATE INDEX statement.
 #
-# $Id: index.test,v 1.22 2003/04/16 02:17:36 drh Exp $
+# $Id: index.test,v 1.23 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -154,6 +154,7 @@ do_test index-4.13 {
   execsql {DROP TABLE test1}
   execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
 } {}
+integrity_check index-4.14
 
 # Do not allow indices to be added to sqlite_master
 #
@@ -199,6 +200,8 @@ do_test index-6.4 {
     SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name;
   }
 } {}
+integrity_check index-6.5
+
 
 # Create a primary key
 #
@@ -222,6 +225,7 @@ do_test index-7.4 {
   execsql {DROP table test1}
   execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
 } {}
+integrity_check index-7.5
 
 # Make sure we cannot drop a non-existant index.
 #
@@ -242,6 +246,7 @@ do_test index-9.2 {
   execsql {CREATE INDEX idx1 ON tab1(a)}
   execsql {SELECT name FROM sqlite_master WHERE tbl_name='tab1' ORDER BY name}
 } {idx1 tab1}
+integrity_check index-9.3
 
 # Allow more than one entry with the same key.
 #
@@ -312,6 +317,7 @@ do_test index-10.8 {
     SELECT b FROM t1 ORDER BY b;
   }
 } {0}
+integrity_check index-10.9
 
 # Automatically create an index when we specify a primary key.
 #
@@ -330,6 +336,8 @@ do_test index-11.1 {
   set sqlite_search_count 0
   concat [execsql {SELECT c FROM t3 WHERE b==10}] $sqlite_search_count
 } {0.10 3}
+integrity_check index-11.2
+
 
 # Numeric strings should compare as if they were numbers.  So even if the
 # strings are not character-by-character the same, if they represent the
@@ -380,6 +388,7 @@ do_test index-12.7 {
     SELECT a FROM t4 WHERE a>-0.5 ORDER BY b
   }
 } {0.0 0.00 abc +1.0 0 00000}
+integrity_check index-12.8
 
 # Make sure we cannot drop an automatically created index.
 #
@@ -414,6 +423,7 @@ do_test index-13.4 {
     SELECT * FROM t5;
   }
 } {1 2 3 a b c}
+integrity_check index-13.5
 
 # Check the sort order of data in an index.
 #
@@ -479,6 +489,7 @@ do_test index-14.11 {
     SELECT c FROM t6 WHERE a<'';
   }
 } {3 5}
+integrity_check index-14.12
 
 do_test index-15.1 {
   execsql {
@@ -502,5 +513,6 @@ do_test index-15.2 {
     SELECT b FROM t1 ORDER BY a;
   }
 } {8 5 2 1 3 6 11 9 10 4 7}
+integrity_check index-15.1
 
 finish_test
index 4fe4ec46bc0432eaa1877d7f887cf4c804be9ea0..f2081c250f42d420419dd271632302b5c2042d67 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the INSERT statement.
 #
-# $Id: insert.test,v 1.14 2003/06/04 16:24:40 drh Exp $
+# $Id: insert.test,v 1.15 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -281,4 +281,6 @@ do_test insert-6.4 {
   }
 } {}
 
+integrity_check insert-99.0
+
 finish_test
index cb96cd87a7ee98573fa8e210e8a4fca241f9906e..8745848fafbf8041d79266887b9370705da1d0f2 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the special processing associated
 # with INTEGER PRIMARY KEY columns.
 #
-# $Id: intpkey.test,v 1.13 2003/03/07 19:50:08 drh Exp $
+# $Id: intpkey.test,v 1.14 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -482,4 +482,6 @@ do_test intpkey-11.1 {
   }
 } {}
 
+integrity_check intpkey-12.1
+
 finish_test
index ea3f4f3c9f52038e6393108ed1b911238f9213ac..b03d0caaa34785cf6668faa9eff2f8fabb98a0e4 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is in-memory database backend.
 #
-# $Id: memdb.test,v 1.4 2003/05/16 02:30:27 drh Exp $
+# $Id: memdb.test,v 1.5 2003/06/15 23:42:25 drh Exp $
 
 
 set testdir [file dirname $argv0]
@@ -116,7 +116,7 @@ do_test memdb-2.1 {
   execsql {
     PRAGMA integrity_check
   }
-} {ok ok}
+} {ok}
 
 do_test memdb-3.1 {
   execsql {
index 2b1153ee3c538ebedd6bc1a82f46e72ccbb57712..66d746b16f6f60f6cb3a6bc2659ded43638bc25b 100644 (file)
@@ -12,7 +12,7 @@
 #
 # This file implements tests for the PRAGMA command.
 #
-# $Id: pragma.test,v 1.4 2003/02/15 23:09:17 drh Exp $
+# $Id: pragma.test,v 1.5 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -227,7 +227,33 @@ do_test pragma-2.10 {
     SELECT d,e FROM t1 INTERSECT SELECT c,e FROM v1
   }
 } {WHATEVER BLOB}
-    
 
+# Construct a corrupted index and make sure the integrity_check
+# pragma finds it.
+#
+do_test pragma-3.1 {
+  execsql {
+    BEGIN;
+    CREATE TABLE t2(a,b,c);
+    CREATE INDEX i2 ON t2(a);
+    INSERT INTO t2 VALUES(11,2,3);
+    INSERT INTO t2 VALUES(22,3,4);
+    COMMIT;
+    SELECT rowid, * from t2;
+  }
+} {1 11 2 3 2 22 3 4}
+do_test pragma-3.2 {
+  set rootpage [execsql {SELECT rootpage FROM sqlite_master WHERE name='i2'}]
+  set db [btree_open test.db]
+  btree_begin_transaction $db
+  set c [btree_cursor $db $rootpage 1]
+  btree_first $c
+  btree_delete $c
+  btree_commit $db
+  btree_close $db
+  execsql {PRAGMA integrity_check}
+} {{rowid 1 missing from index i2
+wrong # of entries in index i2
+}}
 
 finish_test
index 788dda5bd7deffc7c08c99d836810d75fffdc441..fa3701f07910ff870e4bd9f9572a1dbaea7813f2 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements some common TCL routines used for regression
 # testing the SQLite library
 #
-# $Id: tester.tcl,v 1.25 2003/03/01 19:45:35 drh Exp $
+# $Id: tester.tcl,v 1.26 2003/06/15 23:42:25 drh Exp $
 
 # Make sure tclsqlite was compiled correctly.  Abort now with an
 # error message if not.
@@ -247,5 +247,5 @@ proc forcedelete {filename} {
 proc integrity_check {name} {
   do_test $name {
     execsql {PRAGMA integrity_check}
-  } {ok ok}
+  } {ok}
 }
index e0cf88ad0b80cefa7f20326d61e503977a4dd23b..cc53cec1f15cdc6932f1ec1cca029c26ef919fd3 100644 (file)
@@ -307,5 +307,6 @@ do_test trigger-4.4 {
   };
 } {3 4 7 8}
 
+integrity_check trigger-5.1
 
 finish_test
index 06aa11ce4d6aef31f9da6d5cbe04f7de11a9504b..b0bcfdc3d92690cedf7b8ed913f133d4bb9b42cb 100644 (file)
@@ -186,7 +186,7 @@ foreach tbl_defn {
     execsql {
       PRAGMA integrity_check;
     }
-  } {ok ok}
+  } {ok}
 }
 catchsql {
   DROP TABLE rlog;
@@ -308,7 +308,7 @@ foreach tr_program {
       execsql {
         PRAGMA integrity_check;
       }
-    } {ok ok}
+    } {ok}
 
   }
 }
@@ -384,7 +384,7 @@ do_test trigger2-3.3 {
   execsql {
     PRAGMA integrity_check;
   }
-} {ok ok}
+} {ok}
 
 # Simple cascaded trigger
 execsql {
@@ -714,6 +714,6 @@ do_test trigger2-8.6 {
 
 do_test trigger2-9.9 {
   execsql {PRAGMA integrity_check}
-} {ok ok}
+} {ok}
 
 finish_test
index 1da144e81780e6187041e4c723d7c5240844edea..a83c6343e7643871267391e96ddc557e83555835 100644 (file)
@@ -157,6 +157,8 @@ do_test trigger3-7.3 {
     }
 } {1 {View abort}}
 
+integrity_check trigger3-8.1
+
 catchsql { DROP TABLE tbl; } 
 catchsql { DROP TABLE tbl2; } 
 catchsql { DROP VIEW tbl_view; }
index f0fcb71c155d7ab920f9cd1da33aa7718da3679b..c1384b1c1a4376206a21ec9dc5a3645132f80d20 100644 (file)
@@ -122,4 +122,6 @@ do_test trigger4-3.7 {
   }
 } {7 99}
 
+integrity_check trigger4-4.1
+
 finish_test
index 4a18d2c418a5ee0bfde322cf92fa35aa6eab8b5b..b483b257138de72c1d630a8bd4f7a557d4f06349 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing the CREATE UNIQUE INDEX statement,
 # and primary keys, and the UNIQUE constraint on table columns
 #
-# $Id: unique.test,v 1.5 2003/01/29 18:46:54 drh Exp $
+# $Id: unique.test,v 1.6 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -73,6 +73,7 @@ do_test unique-1.8 {
     SELECT * FROM t1 ORDER BY a;
   }
 } {1 2 3 3 4 5}
+integrity_check unique-1.9
 
 do_test unique-2.0 {
   execsql {
@@ -129,6 +130,7 @@ do_test unique-2.9 {
     CREATE INDEX i2 ON t2(a);
   }
 } {0 {}}
+integrity_check unique-2.10
 
 # Test the UNIQUE keyword as used on two or more fields.
 #
@@ -161,6 +163,7 @@ do_test unique-3.4 {
     SELECT * FROM t3 ORDER BY a,b,c,d;
   }
 } {1 {uniqueness constraint failed}}
+integrity_check unique-3.5
 
 # Make sure NULLs are distinct as far as the UNIQUE tests are
 # concerned.
@@ -193,6 +196,6 @@ do_test unique-4.5 {
     SELECT * FROM t4
   }
 } {1 2 3 {} 2 {} {} 3 4 2 2 {}}
-
+integrity_check unique-4.6
 
 finish_test
index 4da54d08fce88d38c414928471864a3f604d8d27..c59a64039dc87b3d346cfba2f53fbfdbc250f280 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the UPDATE statement.
 #
-# $Id: update.test,v 1.12 2003/02/15 23:09:17 drh Exp $
+# $Id: update.test,v 1.13 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -496,4 +496,6 @@ do_test update-11.2 {
   }
 } {1 15 2 8}
 
+integrity_check update-12.1
+
 finish_test
index 427dcc27d0719c7a2f3150e18cb47c2e30b06906..13dd5445f47b4aa4f1603fde178f8f554888ebcf 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the use of indices in WHERE clases.
 #
-# $Id: where.test,v 1.16 2003/04/19 17:27:25 drh Exp $
+# $Id: where.test,v 1.17 2003/06/15 23:42:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -737,5 +737,6 @@ do_test where-10.4 {
   }
 } {50}
 
+integrity_check {where-99.0}
 
 finish_test