diff --git a/manifest b/manifest index 129fa8c22e..a5fe5d7d0f 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index ad28fd3e93..fb116ff964 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bffca90f37a69c5bd26b719a964408e0e518a7dc \ No newline at end of file +67f8af377c8a92ac155f55afc75e9957bec4e787 \ No newline at end of file diff --git a/src/dbbe.c b/src/dbbe.c index 48c37ba388..e34ffd91d6 100644 --- a/src/dbbe.c +++ b/src/dbbe.c @@ -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 @@ -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); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1b84eb1167..ae67ac479c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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 */ }; diff --git a/src/vdbe.c b/src/vdbe.c index 34240b7d3d..4850506855 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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 @@ -2143,17 +2143,23 @@ int sqliteVdbeExec( if( i>=0 && inCursor && (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; j1 ){ + k = *(aIdx++); + if( k>nIdx-1 ) k = nIdx-1; + }else{ + k = nIdx; + } + for(j=p->aCsr[i].index; jaStack[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( kaStack[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 && inCursor && (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 ) 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); diff --git a/test/index.test b/test/index.test index 47b14ee3a1..b72c556432 100644 --- a/test/index.test +++ b/test/index.test @@ -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 diff --git a/www/changes.tcl b/www/changes.tcl index 012447ec17..c16b46cdf2 100644 --- a/www/changes.tcl +++ b/www/changes.tcl @@ -17,6 +17,13 @@ proc chng {date desc} { puts "

    $desc

" } +chng {2000 Aug 2} { +
  • 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. + ** Incompatible Change **
  • +} + chng {2000 Aug 1} {
  • The parser's stack was overflowing on a very long UPDATE statement. This is now fixed.
  • diff --git a/www/fileformat.tcl b/www/fileformat.tcl index 203aab3586..d519e8d0e5 100644 --- a/www/fileformat.tcl +++ b/www/fileformat.tcl @@ -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 { @@ -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.

    +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.

    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.

    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 a columns of table t1. 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 t1 table that has the corresponding value for the a column.

    +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 { diff --git a/www/index.tcl b/www/index.tcl index 5dc4f6fd1d..ad48ed56d9 100644 --- a/www/index.tcl +++ b/www/index.tcl @@ -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 { SQLite: An SQL Database Engine Built Atop GDBM @@ -13,23 +13,6 @@ puts "This page was last modified on [lrange $rcsid 3 4] GMT
    " puts "The SQLite source code was last modifed on [exec cat last_change] GMT" puts {

    } -if 0 { -puts { -

    News

    -

    -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 -gcov. -There are currently no known errors in the code.

    - -

    If you find bugs or missing features, please submit a comment -to the SQLite mailing list.

    -} -} - puts {

    Introduction

    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.

    +

    Important News Flash!

    +

    +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 sqlite utility to "old-sqlite" and +change the name of the old database directory to "old-db", then +you can reconstruct the database as follows:

    + +
    +echo .dump | old-sqlite old-db | sqlite db
    +
    + +

    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.

    +

    Features