]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
file format change (CVS 120)
authordrh <drh@noemail.net>
Wed, 2 Aug 2000 12:26:28 +0000 (12:26 +0000)
committerdrh <drh@noemail.net>
Wed, 2 Aug 2000 12:26:28 +0000 (12:26 +0000)
FossilOrigin-Name: 67f8af377c8a92ac155f55afc75e9957bec4e787

manifest
manifest.uuid
src/dbbe.c
src/sqliteInt.h
src/vdbe.c
test/index.test
www/changes.tcl
www/fileformat.tcl
www/index.tcl

index 129fa8c22e5186fbd37da7d952a81a6339b2248b..a5fe5d7d0f7f5a7d064c454a3aca0a0e1835a1b3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C fix\sparser\sstack\soverflow\s(CVS\s119)
-D 2000-08-01T09:56:27
+C file\sformat\schange\s(CVS\s120)
+D 2000-08-02T12:26:29
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
 F Makefile.in 670aa9413cb2cdcded23b328a9e255c845c41a1e
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -7,7 +7,7 @@ F configure 51063d594190fa085f909cefc9427241088bec4f x
 F configure.in a04f02ba61ed09a00e862b4f78b91b06a559e0b5
 F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
 F src/build.c ecb8ec724914780efed01d1739e6dd398d75af46
-F src/dbbe.c 1bc12590063a21e6098503b5821df87da20c1d8f
+F src/dbbe.c 5c69d68fe8d9461e56d066f9a7f693636c02d0c7
 F src/dbbe.h 8718b718b36d37584e9bbdfccec10588fa91271f
 F src/delete.c 4d491eaf61b515516749c7ed68fa3b2ee8a09065
 F src/expr.c 2fa63f086707176d09092e71832f9bbdc6a8ac85
@@ -17,12 +17,12 @@ F src/parse.y 5d199034de5d29ebedb42c1c51f34db4df40cbe5
 F src/select.c d382e96c2221d08367cc87976f2b574537c9de97
 F src/shell.c a5eb8ee9d5f90e735900a92e7fc364a54deb2cfb
 F src/sqlite.h 82ae53028e27919250f886ff9d7c4927de81978a
-F src/sqliteInt.h 74eb0e266e05d10278e2c20a2cd8fe9fd9fa0d1a
+F src/sqliteInt.h cbb973ffcbbefdfb59438fa5c1df0be768cc490c
 F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
 F src/tokenize.c 77ff8164a8751994bc9926ce282847f653ac0c16
 F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc
 F src/util.c b75b33e6bd5d47898bb7ed9fdd0dea4fe7c19b00
-F src/vdbe.c 4308e226d5b33a72dfe2c88a44eb0a63381fe24b
+F src/vdbe.c bdedf21230581f0cf73a2dcd8fe23f30cf30ebe6
 F src/vdbe.h 6c5653241633c583549c2d8097394ab52550eb63
 F src/where.c 420f666a38b405cd58bd7af832ed99f1dbc7d336
 F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
@@ -31,7 +31,7 @@ F test/dbbe.test 0a8e4293cf816e590dcbb01be4cd4e8f7f95bdc8
 F test/delete.test 402ee3ccb6e544582d24c573ef70b34d09583ae7
 F test/expr.test 09b55ccf81cb8cc2f9cd83d592a2ba187ee48ba8
 F test/in.test 2c560c0f55fb777029fd9bb5378f2997582aa603
-F test/index.test 620ceab7165dd078d1266bdc2cac6147f04534ac
+F test/index.test e5f4e7ad41e1709ef4426a3a4ce1bafe1afe1ee4
 F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c
 F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
 F test/lock.test 42a2d171eba1078cf3fd58ab64241eb8f1b08d69
@@ -59,16 +59,16 @@ F www/arch.fig 4e26e9dca3c49724fc8f554c695ddea9f2413156
 F www/arch.png c4d908b79065a72e7dcf19317f36d1324c550e87
 F www/arch.tcl 4f6a9afecc099a27bba17b4f8cc9561abc15dc40
 F www/c_interface.tcl 29593cf77025bab137b7ba64b9459eb5eb6b4873
-F www/changes.tcl bfd60af0af1cd81030a14dd072fb0214f44b1470
+F www/changes.tcl 0fe8d43635dd08a01479774520f54149550cdb74
 F www/crosscompile.tcl 19734ce7f18b16ff2ed8479412abf8aca56e1dcc
-F www/fileformat.tcl f3a70650e942262f8285d53097d48f0b3aa59862
-F www/index.tcl 8043911df3baacc5be42c40c9bd0883602e8a63a
+F www/fileformat.tcl 1c353d202cc75de55a916a1bab80e7b3cc5660ee
+F www/index.tcl ae93e74540d9198743009fe5a60b7c2c2e7885d6
 F www/lang.tcl 1645e9107d75709be4c6099b643db235bbe0a151
 F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
 F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
 F www/sqlite.tcl 69781eaffb02e17aa4af28b76a2bedb19baa8e9f
 F www/vdbe.tcl bcbfc33bcdd0ebad95eab31286adb9e1bc289520
-P 4132d4760f6a2cbcf853f82546987d932e76e3c1
-R 463a993a466cf480cd166cfd852b8351
+P bffca90f37a69c5bd26b719a964408e0e518a7dc
+R fb9083cf992b9bf32aa0798cc17db2e1
 U drh
-Z 9d9beee969b260700b91790c5774a3ef
+Z b90780147dd290d806a672cbfe65d916
index ad28fd3e9382e8c2cbe06f27afb6b163639208ab..fb116ff964ec20d216e2effeff825ddfb7d2a828 100644 (file)
@@ -1 +1 @@
-bffca90f37a69c5bd26b719a964408e0e518a7dc
\ No newline at end of file
+67f8af377c8a92ac155f55afc75e9957bec4e787
\ No newline at end of file
index 48c37ba38863be5c9c5c5d6da9a80838145b13a5..e34ffd91d69af8d819527ddc6b462f349fb5463d 100644 (file)
@@ -30,7 +30,7 @@
 ** relatively simple to convert to a different database such
 ** as NDBM, SDBM, or BerkeleyDB.
 **
-** $Id: dbbe.c,v 1.17 2000/07/31 13:38:26 drh Exp $
+** $Id: dbbe.c,v 1.18 2000/08/02 12:26:29 drh Exp $
 */
 #include "sqliteInt.h"
 #include <gdbm.h>
@@ -629,6 +629,7 @@ int sqliteDbbeNew(DbbeCursor *pCursr){
     for(i=0; i<4; i++){
       iKey = (iKey<<8) + rc4byte(pRc4);
     }
+    if( iKey==0 ) continue;
     key.dptr = (char*)&iKey;
     key.dsize = 4;
     go = gdbm_exists(pCursr->pFile->dbf, key);
index 1b84eb1167ecd46466c6818841e8a664193ea58e..ae67ac479ca1123d21e56097ff5a1d5bbc39a34d 100644 (file)
@@ -23,7 +23,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.27 2000/07/29 13:06:59 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.28 2000/08/02 12:26:29 drh Exp $
 */
 #include "sqlite.h"
 #include "dbbe.h"
@@ -123,7 +123,7 @@ struct sqlite {
   Dbbe *pBe;                 /* The backend driver */
   int flags;                 /* Miscellanous flags */
   void *pBusyArg;            /* 1st Argument to the busy callback */
-  int (*xBusyCallback)(void *,const char*,int);
+  int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
   Table *apTblHash[N_HASH];  /* All tables of the database */
   Index *apIdxHash[N_HASH];  /* All indices of the database */
 };
index 34240b7d3d2351d69f181a809fd3a5dd6052e6e8..48505068556ff4523e3bb0df2868530f9aa94604 100644 (file)
@@ -41,7 +41,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.37 2000/07/30 20:04:43 drh Exp $
+** $Id: vdbe.c,v 1.38 2000/08/02 12:26:29 drh Exp $
 */
 #include "sqliteInt.h"
 #include <unistd.h>
@@ -2143,17 +2143,23 @@ int sqliteVdbeExec(
         if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
           int *aIdx;
           int nIdx;
-          int j;
+          int j, k;
           nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
           aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
-          for(j=p->aCsr[i].index; j<nIdx; j++){
+          if( nIdx>1 ){
+            k = *(aIdx++);
+            if( k>nIdx-1 ) k = nIdx-1;
+          }else{
+            k = nIdx;
+          }
+          for(j=p->aCsr[i].index; j<k; j++){
             if( aIdx[j]!=0 ){
               p->aStack[tos].i = aIdx[j];
               p->aStack[tos].flags = STK_Int;
               break;
             }
           }
-          if( j>=nIdx ){
+          if( j>=k ){
             j = -1;
             pc = pOp->p2 - 1;
             PopStack(p, 1);
@@ -2193,14 +2199,38 @@ int sqliteVdbeExec(
             /* Extend the existing record */
             int nIdx;
             int *aIdx;
+            int k;
+            
             nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
-            aIdx = sqliteMalloc( sizeof(int)*(nIdx+1) );
-            if( aIdx==0 ) goto no_mem;
-            sqliteDbbeCopyData(pCrsr, 0, nIdx*sizeof(int), (char*)aIdx);
-            aIdx[nIdx] = newVal;
-            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
-                          sizeof(int)*(nIdx+1), (char*)aIdx);
-            sqliteFree(aIdx);
+            if( nIdx==1 ){
+              aIdx = sqliteMalloc( sizeof(int)*4 );
+              if( aIdx==0 ) goto no_mem;
+              aIdx[0] = 2;
+              sqliteDbbeCopyData(pCrsr, 0, sizeof(int), (char*)&aIdx[1]);
+              aIdx[2] = newVal;
+              sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
+                    sizeof(int)*4, (char*)aIdx);
+              sqliteFree(aIdx);
+            }else{
+              aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
+              k = aIdx[0];
+              if( k<nIdx-1 ){
+                aIdx[k+1] = newVal;
+                aIdx[0]++;
+                sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
+                    sizeof(int)*nIdx, (char*)aIdx);
+              }else{
+                nIdx *= 2;
+                aIdx = sqliteMalloc( sizeof(int)*nIdx );
+                if( aIdx==0 ) goto no_mem;
+                sqliteDbbeCopyData(pCrsr, 0, sizeof(int)*(k+1), (char*)aIdx);
+                aIdx[k+1] = newVal;
+                aIdx[0]++;
+                sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
+                      sizeof(int)*nIdx, (char*)aIdx);
+                sqliteFree(aIdx);
+              }
+            }              
           }
         }
         PopStack(p, 2);
@@ -2229,7 +2259,7 @@ int sqliteVdbeExec(
         if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
           int *aIdx;
           int nIdx;
-          int j;
+          int j, k;
           int r;
           int oldVal;
           Integerify(p, nos);
@@ -2239,14 +2269,20 @@ int sqliteVdbeExec(
           if( r==0 ) break;
           nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
           aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
-          for(j=0; j<nIdx && aIdx[j]!=oldVal; j++){}
-          if( j>=nIdx ) break;
-          aIdx[j] = aIdx[nIdx-1];
-          if( nIdx==1 ){
+          if( (nIdx==1 && aIdx[0]==oldVal) || (aIdx[0]==1 && aIdx[1]==oldVal) ){
             sqliteDbbeDelete(pCrsr, p->aStack[tos].n, p->zStack[tos]);
           }else{
+            k = aIdx[0];
+            for(j=1; j<=k && aIdx[j]!=oldVal; j++){}
+            if( j>k ) break;
+            aIdx[j] = aIdx[k];
+            aIdx[k] = 0;
+            aIdx[0]--;
+            if( aIdx[0]*3 + 1 < nIdx ){
+              nIdx /= 2;
+            }
             sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos], 
-                          sizeof(int)*(nIdx-1), (char*)aIdx);
+                          sizeof(int)*nIdx, (char*)aIdx);
           }
         }
         PopStack(p, 2);
index 47b14ee3a17013e6d610106f9fd89fbaf23d1d64..b72c556432d2948cfdf393600a331cb829582eb3 100644 (file)
@@ -23,7 +23,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.5 2000/06/17 13:12:40 drh Exp $
+# $Id: index.test,v 1.6 2000/08/02 12:26:30 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -281,11 +281,51 @@ do_test index-10.2 {
     SELECT b FROM t1 WHERE a=1 ORDER BY b;
   }
 } {2}
-do_test index-10.2 {
+do_test index-10.3 {
   execsql {
     DELETE FROM t1 WHERE b=2;
     SELECT b FROM t1 WHERE a=1 ORDER BY b;
   }
 } {}
+do_test index-10.4 {
+  execsql {
+    DELETE FROM t1;
+    INSERT INTO t1 VALUES (1,1);
+    INSERT INTO t1 VALUES (1,2);
+    INSERT INTO t1 VALUES (1,3);
+    INSERT INTO t1 VALUES (1,4);
+    INSERT INTO t1 VALUES (1,5);
+    INSERT INTO t1 VALUES (1,6);
+    INSERT INTO t1 VALUES (1,7);
+    INSERT INTO t1 VALUES (1,8);
+    INSERT INTO t1 VALUES (1,9);
+    INSERT INTO t1 VALUES (2,0);
+    SELECT b FROM t1 WHERE a=1 ORDER BY b;
+  }
+} {1 2 3 4 5 6 7 8 9}
+do_test index-10.5 {
+  execsql {
+    DELETE FROM t1 WHERE b IN (2, 4, 6, 8);
+    SELECT b FROM t1 WHERE a=1 ORDER BY b;
+  }
+} {1 3 5 7 9}
+do_test index-10.6 {
+  execsql {
+    DELETE FROM t1 WHERE b>2;
+    SELECT b FROM t1 WHERE a=1 ORDER BY b;
+  }
+} {1}
+do_test index-10.7 {
+  execsql {
+    DELETE FROM t1 WHERE b=1;
+    SELECT b FROM t1 WHERE a=1 ORDER BY b;
+  }
+} {}
+do_test index-10.8 {
+  execsql {
+    SELECT b FROM t1 ORDER BY b;
+  }
+} {0}
+
 
 finish_test
index 012447ec173bf5383c96a604681fcba18012f981..c16b46cdf22b0d46f614f81dc908ec5eef45f2b1 100644 (file)
@@ -17,6 +17,13 @@ proc chng {date desc} {
   puts "<DD><P><UL>$desc</UL></P></DD>"
 }
 
+chng {2000 Aug 2} {
+<li>The file format for indices was changed slightly in order to work
+    around an inefficiency that can sometimes come up with GDBM when
+    there are large indices having many entries with the same key.
+    <font color="red">** Incompatible Change **</font></li>
+}
+
 chng {2000 Aug 1} {
 <li>The parser's stack was overflowing on a very long UPDATE statement.
     This is now fixed.</li>
index 203aab3586542e504ca3111245ec152d8fdca3f5..d519e8d0e5b40eb19d64281d79bce3c4d8b5cb5d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the fileformat.html file.
 #
-set rcsid {$Id: fileformat.tcl,v 1.2 2000/06/23 17:02:09 drh Exp $}
+set rcsid {$Id: fileformat.tcl,v 1.3 2000/08/02 12:26:30 drh Exp $}
 
 puts {<html>
 <head>
@@ -109,11 +109,11 @@ sqlite> (((insert into t1 values(10,NULL,'hello!');)))
 sqlite> (((insert into t1 values(-11,'this is','a test');)))
 sqlite> (((.exit)))
 $ (((gdbmdump ex1/t1.tbl)))
-key  : 223100ae                                      "1..
+key  : 6d1a6e03                                      m.n.
 data : 0c000000 10000000 18000000 2d313100 74686973  ............-11.this
        20697300 61207465 737400                       is.a test.
 
-key  : a840e996                                      .@..
+key  : 6d3f90e2                                      m?..
 data : 0c000000 00000000 0f000000 31300068 656c6c6f  ............10.hello
        2100                                          !.
 
@@ -151,7 +151,12 @@ table that is being indexed.  The GDBM key is an
 arbitrary length null-terminated string which is SQL key that
 is used by the index.  The data is a list of integers that correspond
 to GDBM keys of entries in data table that have the corresponding
-SQL key.</p>
+SQL key.  If the data record of the index is exactly 4 bytes in size,
+then the data represents a single integer key.  If the data is greater
+than 4 bytes in size, then the first 4 bytes form an integer that
+tells us how many keys are in the data.  The index data record is
+always sized to be a power of 2.  Unused slots at the end of the
+index data record are filled with zero.</p>
 
 <p>To illustrate, we will create an index on the example table
 shown above, and add a new entry to this table that has a duplicate
@@ -191,10 +196,10 @@ GDBM key.</p>
 Code {
 $ (((gdbmdump ex1/i1.tbl)))
 key  : 313000                                        10.
-data : a840e996 c19e3119                             .@....1.
+data : 02000000 45b4f724 6d3f90e2 00000000           ....E..$m?......
 
 key  : 2d313100                                      -11.
-data : 223100ae                                      "1..
+data : 6d1a6e03                                      m.n.
 
 $
 }
@@ -207,6 +212,11 @@ are just the text values for <b>a</b> columns of table <b>t1</b>.
 The data for each record of the index is a list of integers
 where each integer is the GDBM key for an entry in the <b>t1</b>
 table that has the corresponding value for the <b>a</b> column.</p>
+The index entry for -11 contains only a single entry and is 4
+bytes in size.  The index entry for 10 is 16 bytes in size but
+contains only 2 entries.  The first integer is the number of
+entires.  The two integer keys follow.  The last 4 bytes unused
+and are set to zero.
 }
 
 puts {
index 5dc4f6fd1d51853626b71eeb489158b5984e7575..ad48ed56d98be64a53d23f97c28fe185c6a1c64c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this TCL script to generate HTML for the index.html file.
 #
-set rcsid {$Id: index.tcl,v 1.22 2000/08/01 09:56:27 drh Exp $}
+set rcsid {$Id: index.tcl,v 1.23 2000/08/02 12:26:30 drh Exp $}
 
 puts {<html>
 <head><title>SQLite: An SQL Database Engine Built Atop GDBM</title></head>
@@ -13,23 +13,6 @@ puts "This page was last modified on [lrange $rcsid 3 4] GMT<br>"
 puts "The SQLite source code was last modifed on [exec cat last_change] GMT"
 puts {</p>}
 
-if 0 {
-puts {
-<h2>News</h2>
-<p>
-The SQLite code base is being called "beta" only because it is
-relatively new.  It appears to be stable and usable.
-Most of the SQL language is now implemented and working.  
-The regression test suite
-provides good coverage, according to
-<a href="http://gcc.gnu.org/onlinedocs/gcov_1.html">gcov</a>.
-There are currently no known errors in the code.</p>
-
-<p>If you find bugs or missing features, please submit a comment
-to the <a href="#mailinglist">SQLite mailing list</a>.</p>
-}
-}
-
 puts {<h2>Introduction</h2>
 
 <p>SQLite is an SQL database engine built on top of the
@@ -41,6 +24,25 @@ that can be linked
 with a C/C++ program to provide SQL database access without
 an separate RDBMS.</p>
 
+<h2>Important News Flash!</h2>
+<p>
+The SQLite file format was changed in an incompatible way on
+Aug 2, 2000.  If you are updated the library and have databases
+built using the old version of the library, you should save your
+old databases into an ASCII fileformat then reimport those
+database using the new library.  For example, if you change the
+name of the old <b>sqlite</b> utility to "old-sqlite" and
+change the name of the old database directory to "old-db", then
+you can reconstruct the database as follows:</p>
+
+<blockquote><pre>
+echo .dump | old-sqlite old-db | sqlite db
+</pre></blockquote>
+
+<p>This file format change was made to work around a potential 
+inefficiency in GDBM that comes up when large indices are created 
+on tables where many entries in the table have the same key.</p>
+
 <h2>Features</h2>
 
 <p><ul>