-C Bug\sfixes.\s\sTrying\sto\smake\sit\sgo\sfaster.\s(CVS\s254)
-D 2001-09-18T02:02:23
+C Fix\sa\sproblem\sin\sGROUP\sBY\swith\smultiple\scolumns.\s(CVS\s255)
+D 2001-09-18T22:17:44
F Makefile.in a7053596881af6f2590a816ad4eb8fbbf20724a7
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
F VERSION 3861a21803fcd9eb92a403027b0da2bb7add4de1
F src/test3.c f46bad555db7a6a25be332a96ac99e4d68a1b0c5
F src/tokenize.c 2adf0568edf41b3d3c2fcb541ac49bd6e662da0c
F src/update.c a1952ad5d53379fa2b2d12efae5993ddb85a1ddb
-F src/util.c a09c3c12aa0259c12e7385313f527895ba3cdbf9
-F src/vdbe.c 21f5d1c5418cbf740eefec10b875632e848eb7c1
+F src/util.c 2cd0bb9693e1c538a5c6f152b7d45cc8567e6724
+F src/vdbe.c efe564f482c94d361843c5975e2a5724cf0ca8af
F src/vdbe.h 900b59b46afdfb9c048a2a31a4478f380ab8504e
F src/where.c cce952b6a2459ac2296e3432876a4252d2fe3b87
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
F test/lock.test 5b4d969ab92c88f8dc10d1b870a2e5fe51ee7f5f
F test/main.test 085ece17913a487caacbc0a392638c958c83a75d
F test/malloc.test f1400a8d002eb96f1ca0a34abe56d2ab3e324740
+F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6
F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077
F test/printf.test 93ecd43cc48e863a325560f36c3b2741f5fe0308
F test/quick.test b6ec50f808efc06595fd324bf4f3fabadb9c7e9c
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
-P b30f2b5e150a219c374f88d13386dbda190ad9ed
-R 07bb1a4a448dedf9e2b45c7aa5ee5ac1
+P 8f28a83abac59a2161d486c96386b8df726468d0
+R 716384b1a17cd98ef2ff77fe086995d1
U drh
-Z ba1b972f8330f9b56b7e933eb997f9fb
+Z 8f168bc49c168254b9355cae69013087
-8f28a83abac59a2161d486c96386b8df726468d0
\ No newline at end of file
+22132ce18cad31482cdb9b380cedc3f53bc532b8
\ No newline at end of file
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.25 2001/09/16 00:13:27 drh Exp $
+** $Id: util.c,v 1.26 2001/09/18 22:17:44 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
*/
int sqliteHashNoCase(const char *z, int n){
int h = 0;
- int c;
if( n<=0 ) n = strlen(z);
- while( n-- > 0 && (c = *z++)!=0 ){
- h = (h<<3) ^ h ^ UpperToLower[c];
+ while( n > 0 ){
+ h = (h<<3) ^ h ^ UpperToLower[*z++];
+ n--;
}
if( h<0 ) h = -h;
return h;
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.71 2001/09/18 02:02:23 drh Exp $
+** $Id: vdbe.c,v 1.72 2001/09/18 22:17:44 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
};
struct AggElem {
char *zKey; /* The key to this AggElem */
+ int nKey; /* Number of bytes in the key, including '\0' at end */
AggElem *pHash; /* Next AggElem with the same hash on zKey */
AggElem *pNext; /* Next AggElem in a list of them all */
Mem aMem[1]; /* The values for this AggElem */
** Add the given AggElem to the hash array
*/
static void AggEnhash(Agg *p, AggElem *pElem){
- int h = sqliteHashNoCase(pElem->zKey, 0) % p->nHash;
+ int h = sqliteHashNoCase(pElem->zKey, pElem->nKey) % p->nHash;
pElem->pHash = p->apHash[h];
p->apHash[h] = pElem;
}
**
** Return 0 on success and 1 if memory is exhausted.
*/
-static int AggInsert(Agg *p, char *zKey){
+static int AggInsert(Agg *p, char *zKey, int nKey){
AggElem *pElem;
int i;
if( p->nHash <= p->nElem*2 ){
AggRehash(p, p->nElem*2 + 19);
}
if( p->nHash==0 ) return 1;
- pElem = sqliteMalloc( sizeof(AggElem) + strlen(zKey) + 1 +
+ pElem = sqliteMalloc( sizeof(AggElem) + nKey +
(p->nMem-1)*sizeof(pElem->aMem[0]) );
if( pElem==0 ) return 1;
pElem->zKey = (char*)&pElem->aMem[p->nMem];
- strcpy(pElem->zKey, zKey);
+ memcpy(pElem->zKey, zKey, nKey);
+ pElem->nKey = nKey;
AggEnhash(p, pElem);
pElem->pNext = p->pFirst;
p->pFirst = pElem;
if( pFocus ){
p->pCurrent = pFocus;
}else{
- AggInsert(p,"");
+ AggInsert(p,"",1);
pFocus = p->pCurrent = p->pFirst;
}
return pFocus;
if( VERIFY( i<0 || i>=p->nCursor || ) p->aCsr[i].pCursor==0 ){
v = 0;
}else{
+ /* A probablistic algorithm is used to locate an unused rowid.
+ ** We select a rowid at random and see if it exists in the table.
+ ** If it does not exist, we have succeeded. If the random rowid
+ ** does exist, we select a new one and try again, up to 1000 times.
+ **
+ ** For a table with less than 2 billion entries, the probability
+ ** of not finding a unused rowid is about 1.0e-300. This is a
+ ** non-zero probability, but it is still vanishingly small and should
+ ** never cause a problem. You are much, much more likely to have a
+ ** hardware failure than for this algorithm to fail.
+ **
+ ** To promote locality of reference for repetitive inserts, the
+ ** first few attempts at chosing a rowid pick values just a little
+ ** larger than the previous rowid. This has been shown experimentally
+ ** to double the speed of the COPY operation.
+ */
int res, rx, cnt;
static int x = 0;
union {
} ux;
cnt = 0;
do{
- if( x==0 || cnt>5 ){
+ if( cnt>5 ){
x = sqliteRandomInteger();
}else{
x += sqliteRandomByte() + 1;
v = ux.i;
rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, &v, sizeof(v), &res);
cnt++;
- }while( cnt<200 && rx==SQLITE_OK && res==0 );
+ }while( cnt<1000 && rx==SQLITE_OK && res==0 );
if( rx==SQLITE_OK && res==0 ){
rc = SQLITE_FULL;
goto abort_due_to_error;
if( p->agg.nHash<=0 ){
pElem = 0;
}else{
- int h = sqliteHashNoCase(zKey, nKey-1) % p->agg.nHash;
+ int h = sqliteHashNoCase(zKey, nKey) % p->agg.nHash;
for(pElem=p->agg.apHash[h]; pElem; pElem=pElem->pHash){
- if( strcmp(pElem->zKey, zKey)==0 ) break;
+ if( pElem->nKey==nKey && memcmp(pElem->zKey, zKey, nKey)==0 ) break;
}
}
if( pElem ){
p->agg.pCurrent = pElem;
pc = pOp->p2 - 1;
}else{
- AggInsert(&p->agg, zKey);
+ AggInsert(&p->agg, zKey, nKey);
if( sqlite_malloc_failed ) goto no_mem;
}
POPSTACK;
--- /dev/null
+# 2001 September 15
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+# This file implements tests for miscellanous features that were
+# left out of other test files.
+#
+# $Id: misc1.test,v 1.1 2001/09/18 22:17:45 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Test the creation and use of tables that have a large number
+# of columns.
+#
+do_test misc1-1.1 {
+ set cmd "CREATE TABLE manycol(x0 text"
+ for {set i 1} {$i<=99} {incr i} {
+ append cmd ",x$i text"
+ }
+ append cmd ")";
+ execsql $cmd
+ set cmd "INSERT INTO manycol VALUES(0"
+ for {set i 1} {$i<=99} {incr i} {
+ append cmd ",$i"
+ }
+ append cmd ")";
+ execsql $cmd
+ execsql "SELECT x99 FROM manycol"
+} 99
+do_test misc1-1.2 {
+ execsql {SELECT x0, x10, x25, x50, x75 FROM manycol}
+} {0 10 25 50 75}
+do_test misc1-1.3 {
+ for {set j 100} {$j<=1000} {incr j 100} {
+ set cmd "INSERT INTO manycol VALUES($j"
+ for {set i 1} {$i<=99} {incr i} {
+ append cmd ",[expr {$i+$j}]"
+ }
+ append cmd ")"
+ execsql $cmd
+ }
+ execsql {SELECT x50 FROM manycol ORDER BY x80}
+} {50 150 250 350 450 550 650 750 850 950 1050}
+do_test misc1-1.4 {
+ execsql {SELECT x75 FROM manycol WHERE x50=350}
+} 375
+do_test misc1-1.5 {
+ execsql {SELECT x50 FROM manycol WHERE x99=599}
+} 550
+do_test misc1-1.6 {
+ execsql {CREATE INDEX manycol_idx1 ON manycol(x99)}
+ execsql {SELECT x50 FROM manycol WHERE x99=899}
+} 850
+do_test misc1-1.7 {
+ execsql {SELECT count(*) FROM manycol}
+} 11
+do_test misc1-1.8 {
+ execsql {DELETE FROM manycol WHERE x98=1234}
+ execsql {SELECT count(*) FROM manycol}
+} 11
+do_test misc1-1.9 {
+ execsql {DELETE FROM manycol WHERE x98=998}
+ execsql {SELECT count(*) FROM manycol}
+} 10
+do_test misc1-1.10 {
+ execsql {DELETE FROM manycol WHERE x99=500}
+ execsql {SELECT count(*) FROM manycol}
+} 10
+do_test misc1-1.11 {
+ execsql {DELETE FROM manycol WHERE x99=599}
+ execsql {SELECT count(*) FROM manycol}
+} 9
+
+# Check GROUP BY expressions that name two or more columns.
+#
+do_test misc1-2.1 {
+ execsql {
+ BEGIN TRANSACTION;
+ CREATE TABLE agger(one text, two text, three text, four text);
+ INSERT INTO agger VALUES(1, 'one', 'hello', 'yes');
+ INSERT INTO agger VALUES(2, 'two', 'howdy', 'no');
+ INSERT INTO agger VALUES(3, 'thr', 'howareya', 'yes');
+ INSERT INTO agger VALUES(4, 'two', 'lothere', 'yes');
+ INSERT INTO agger VALUES(5, 'one', 'atcha', 'yes');
+ INSERT INTO agger VALUES(6, 'two', 'hello', 'no');
+ COMMIT
+ }
+ execsql {SELECT count(*) FROM agger}
+} 6
+do_test misc1-2.2 {
+ execsql {SELECT sum(one), two, four FROM agger
+ GROUP BY two, four ORDER BY sum(one) desc}
+} {8 two no 6 one yes 4 two yes 3 thr yes}
+
+finish_test