1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Simplifications to the symbol table implementation in hash.c. For very small

symbol tables (less than 10 entries) a simple linked list is used instead
of a hash table.  Number of hash table buckets is limited to prevent large
allocations. (CVS 6559)

FossilOrigin-Name: 5c737835dec9e6038b304c198aa14337a6f23c1c
This commit is contained in:
drh
2009-04-28 15:43:45 +00:00
parent ebb329397c
commit 8a1e594c9f
6 changed files with 124 additions and 109 deletions

View File

@ -1,5 +1,5 @@
C Have\ssqlite3_create_collation()\sreturn\sMISUSE\sif\spassed\san\sencoding\svalue\sother\sthan\sSQLITE_UTF8,\sSQLITE_UTF16LE,\sSQLITE_UTF16BE,\sSQLITE_UTF16\sor\sSQLITE_UTF16_ALIGNED.\s(CVS\s6558) C Simplifications\sto\sthe\ssymbol\stable\simplementation\sin\shash.c.\s\sFor\svery\ssmall\nsymbol\stables\s(less\sthan\s10\sentries)\sa\ssimple\slinked\slist\sis\sused\sinstead\nof\sa\shash\stable.\s\sNumber\sof\shash\stable\sbuckets\sis\slimited\sto\sprevent\slarge\nallocations.\s(CVS\s6559)
D 2009-04-28T15:35:39 D 2009-04-28T15:43:45
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -118,8 +118,8 @@ F src/expr.c dd763d6dc8f8329e895440d436c28aa7b5b3595e
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c f667fe886309707c7178542073bb0ced00a9fae7 F src/func.c f667fe886309707c7178542073bb0ced00a9fae7
F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
F src/hash.c 15d39cbe87de9b9991054750bd3e0861888b7b06 F src/hash.c 407e5ca13cab32db529e2c364463a2512fb4d554
F src/hash.h 28f38ebb1006a5beedcb013bcdfe31befe7437ae F src/hash.h a63395d62fe898662cb9cdbedbcd2675f16c0410
F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb
F src/insert.c 71286d081a919a27ef22eaeccbe2718f93dc6aa9 F src/insert.c 71286d081a919a27ef22eaeccbe2718f93dc6aa9
F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0 F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0
@ -162,7 +162,7 @@ F src/select.c 40748e8044b79d41ba04ce1014ae45434ed452d3
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
F src/sqlite.h.in 4028ba942fa43afa7f8ade88fa9acedaa024ddeb F src/sqlite.h.in 4028ba942fa43afa7f8ade88fa9acedaa024ddeb
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h d34f80cf38227ce8ed5c519e748375bd9b40d8f7 F src/sqliteInt.h 61be3597d7dce6b3d360a7185c760c3e4e968a59
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
@ -558,7 +558,7 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3 F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
F test/table.test bf1bc3d9634342a3470bdf64b6190e7445b6b8a6 F test/table.test e47c9323396976389a15fa0cd22ce3a405433186
F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c
F test/tclsqlite.test 8b1150d0486c4848c70d96422513a91c5342be0e F test/tclsqlite.test 8b1150d0486c4848c70d96422513a91c5342be0e
F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1 F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
@ -725,7 +725,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 23d67af39227aeade2ea0292e1b8844eea580993 P 7975b6f2ec7736b3656a264c2f7e7e95ce7a78e4
R fcd591943dcfa775dbae9e00324b29d3 R 104f4e6ccdfa7d3d3e3f8da9a9d08fd5
U danielk1977 U drh
Z c812cbe48ecf60026f66cd5f41f509d1 Z b7cd4fee6ba60d43a3b23bd76deb0ece

View File

@ -1 +1 @@
7975b6f2ec7736b3656a264c2f7e7e95ce7a78e4 5c737835dec9e6038b304c198aa14337a6f23c1c

View File

@ -12,7 +12,7 @@
** This is the implementation of generic hash-tables ** This is the implementation of generic hash-tables
** used in SQLite. ** used in SQLite.
** **
** $Id: hash.c,v 1.34 2009/04/28 13:01:09 drh Exp $ ** $Id: hash.c,v 1.35 2009/04/28 15:43:45 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <assert.h> #include <assert.h>
@ -60,7 +60,7 @@ void sqlite3HashClear(Hash *pH){
/* /*
** Hash and comparison functions when the mode is SQLITE_HASH_STRING ** Hash and comparison functions when the mode is SQLITE_HASH_STRING
*/ */
static int strHash(const void *pKey, int nKey){ static unsigned int strHash(const void *pKey, int nKey){
const char *z = (const char *)pKey; const char *z = (const char *)pKey;
int h = 0; int h = 0;
assert( nKey>0 ); assert( nKey>0 );
@ -68,7 +68,7 @@ static int strHash(const void *pKey, int nKey){
h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
nKey--; nKey--;
} }
return h & 0x7fffffff; return h;
} }
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){ static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( n1!=n2 ) return 1; if( n1!=n2 ) return 1;
@ -76,7 +76,8 @@ static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
} }
/* Link an element into the hash table /* Link pNew element into the hash table pH. If pEntry!=0 then also
** insert pNew into the pEntry hash bucket.
*/ */
static void insertElement( static void insertElement(
Hash *pH, /* The complete hash table */ Hash *pH, /* The complete hash table */
@ -84,7 +85,13 @@ static void insertElement(
HashElem *pNew /* The element to be inserted */ HashElem *pNew /* The element to be inserted */
){ ){
HashElem *pHead; /* First element already in pEntry */ HashElem *pHead; /* First element already in pEntry */
pHead = pEntry->chain; if( pEntry ){
pHead = pEntry->count ? pEntry->chain : 0;
pEntry->count++;
pEntry->chain = pNew;
}else{
pHead = 0;
}
if( pHead ){ if( pHead ){
pNew->next = pHead; pNew->next = pHead;
pNew->prev = pHead->prev; pNew->prev = pHead->prev;
@ -97,44 +104,45 @@ static void insertElement(
pNew->prev = 0; pNew->prev = 0;
pH->first = pNew; pH->first = pNew;
} }
pEntry->count++;
pEntry->chain = pNew;
} }
/* Resize the hash table so that it cantains "new_size" buckets. /* Resize the hash table so that it cantains "new_size" buckets.
** "new_size" must be a power of 2. The hash table might fail **
** to resize if sqlite3_malloc() fails. ** The hash table might fail to resize if sqlite3_malloc() fails or
** if the new size is the same as the prior size.
** Return TRUE if the resize occurs and false if not.
*/ */
static void rehash(Hash *pH, int new_size){ static int rehash(Hash *pH, unsigned int new_size){
struct _ht *new_ht; /* The new hash table */ struct _ht *new_ht; /* The new hash table */
HashElem *elem, *next_elem; /* For looping over existing elements */ HashElem *elem, *next_elem; /* For looping over existing elements */
#ifdef SQLITE_MALLOC_SOFT_LIMIT #if SQLITE_MALLOC_SOFT_LIMIT>0
if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
} }
if( new_size==pH->htsize ) return; if( new_size==pH->htsize ) return 0;
#endif #endif
/* There is a call to sqlite3_malloc() inside rehash(). If there is /* The inability to allocates space for a larger hash table is
** already an allocation at pH->ht, then if this malloc() fails it ** a performance hit but it is not a fatal error. So mark the
** is benign (since failing to resize a hash table is a performance ** allocation as a benign.
** hit only, not a fatal error).
*/ */
if( pH->htsize>0 ) sqlite3BeginBenignMalloc(); sqlite3BeginBenignMalloc();
new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) ); new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
if( pH->htsize>0 ) sqlite3EndBenignMalloc(); sqlite3EndBenignMalloc();
if( new_ht==0 ) return; if( new_ht==0 ) return 0;
sqlite3_free(pH->ht); sqlite3_free(pH->ht);
pH->ht = new_ht; pH->ht = new_ht;
pH->htsize = new_size; pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
memset(new_ht, 0, new_size*sizeof(struct _ht));
for(elem=pH->first, pH->first=0; elem; elem = next_elem){ for(elem=pH->first, pH->first=0; elem; elem = next_elem){
int h = strHash(elem->pKey, elem->nKey) & (new_size-1); unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
next_elem = elem->next; next_elem = elem->next;
insertElement(pH, &new_ht[h], elem); insertElement(pH, &new_ht[h], elem);
} }
return 1;
} }
/* This function (for internal use only) locates an element in an /* This function (for internal use only) locates an element in an
@ -144,8 +152,8 @@ static void rehash(Hash *pH, int new_size){
static HashElem *findElementGivenHash( static HashElem *findElementGivenHash(
const Hash *pH, /* The pH to be searched */ const Hash *pH, /* The pH to be searched */
const void *pKey, /* The key we are searching for */ const void *pKey, /* The key we are searching for */
int nKey, int nKey, /* Bytes in key (not counting zero terminator) */
int h /* The hash for this key. */ unsigned int h /* The hash for this key. */
){ ){
HashElem *elem; /* Used to loop thru the element list */ HashElem *elem; /* Used to loop thru the element list */
int count; /* Number of elements left to test */ int count; /* Number of elements left to test */
@ -154,12 +162,15 @@ static HashElem *findElementGivenHash(
struct _ht *pEntry = &pH->ht[h]; struct _ht *pEntry = &pH->ht[h];
elem = pEntry->chain; elem = pEntry->chain;
count = pEntry->count; count = pEntry->count;
while( count-- && elem ){ }else{
if( strCompare(elem->pKey,elem->nKey,pKey,nKey)==0 ){ elem = pH->first;
return elem; count = pH->count;
} }
elem = elem->next; while( count-- && ALWAYS(elem) ){
if( strCompare(elem->pKey,elem->nKey,pKey,nKey)==0 ){
return elem;
} }
elem = elem->next;
} }
return 0; return 0;
} }
@ -170,7 +181,7 @@ static HashElem *findElementGivenHash(
static void removeElementGivenHash( static void removeElementGivenHash(
Hash *pH, /* The pH containing "elem" */ Hash *pH, /* The pH containing "elem" */
HashElem* elem, /* The element to be removed from the pH */ HashElem* elem, /* The element to be removed from the pH */
int h /* Hash value for the element */ unsigned int h /* Hash value for the element */
){ ){
struct _ht *pEntry; struct _ht *pEntry;
if( elem->prev ){ if( elem->prev ){
@ -181,13 +192,13 @@ static void removeElementGivenHash(
if( elem->next ){ if( elem->next ){
elem->next->prev = elem->prev; elem->next->prev = elem->prev;
} }
pEntry = &pH->ht[h]; if( pH->ht ){
if( pEntry->chain==elem ){ pEntry = &pH->ht[h];
pEntry->chain = elem->next; if( pEntry->chain==elem ){
} pEntry->chain = elem->next;
pEntry->count--; }
if( pEntry->count<=0 ){ pEntry->count--;
pEntry->chain = 0; assert( pEntry->count>=0 );
} }
if( pH->copyKey ){ if( pH->copyKey ){
sqlite3_free(elem->pKey); sqlite3_free(elem->pKey);
@ -201,28 +212,23 @@ static void removeElementGivenHash(
} }
} }
/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey. Return a pointer to the corresponding
** HashElem structure for this element if it is found, or NULL
** otherwise.
*/
HashElem *sqlite3HashFindElem(const Hash *pH, const void *pKey, int nKey){
int h; /* A hash on key */
HashElem *elem; /* The element that matches key */
if( pH==0 || pH->ht==0 ) return 0;
h = strHash(pKey,nKey);
elem = findElementGivenHash(pH,pKey,nKey, h % pH->htsize);
return elem;
}
/* Attempt to locate an element of the hash table pH with a key /* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey. Return the data for this element if it is ** that matches pKey,nKey. Return the data for this element if it is
** found, or NULL if there is no match. ** found, or NULL if there is no match.
*/ */
void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){ void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
HashElem *elem; /* The element that matches key */ HashElem *elem; /* The element that matches key */
elem = sqlite3HashFindElem(pH, pKey, nKey); unsigned int h; /* A hash on key */
assert( pH!=0 );
assert( pKey!=0 );
assert( nKey>0 );
if( pH->ht ){
h = strHash(pKey, nKey) % pH->htsize;
}else{
h = 0;
}
elem = findElementGivenHash(pH, pKey, nKey, h);
return elem ? elem->data : 0; return elem ? elem->data : 0;
} }
@ -242,34 +248,36 @@ void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
** element corresponding to "key" is removed from the hash table. ** element corresponding to "key" is removed from the hash table.
*/ */
void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
int hraw; /* Raw hash value of the key */ unsigned int h; /* the hash of the key modulo hash table size */
int h; /* the hash of the key modulo hash table size */
HashElem *elem; /* Used to loop thru the element list */ HashElem *elem; /* Used to loop thru the element list */
HashElem *new_elem; /* New element added to the pH */ HashElem *new_elem; /* New element added to the pH */
assert( pH!=0 ); assert( pH!=0 );
hraw = strHash(pKey, nKey); assert( pKey!=0 );
assert( nKey>0 );
if( pH->htsize ){ if( pH->htsize ){
h = hraw % pH->htsize; h = strHash(pKey, nKey) % pH->htsize;
elem = findElementGivenHash(pH,pKey,nKey,h); }else{
if( elem ){ h = 0;
void *old_data = elem->data; }
if( data==0 ){ elem = findElementGivenHash(pH,pKey,nKey,h);
removeElementGivenHash(pH,elem,h); if( elem ){
}else{ void *old_data = elem->data;
elem->data = data; if( data==0 ){
if( !pH->copyKey ){ removeElementGivenHash(pH,elem,h);
elem->pKey = (void *)pKey; }else{
} elem->data = data;
assert(nKey==elem->nKey); if( !pH->copyKey ){
elem->pKey = (void *)pKey;
} }
return old_data; assert(nKey==elem->nKey);
} }
return old_data;
} }
if( data==0 ) return 0; if( data==0 ) return 0;
new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
if( new_elem==0 ) return data; if( new_elem==0 ) return data;
if( pH->copyKey && pKey!=0 ){ if( pH->copyKey ){
new_elem->pKey = sqlite3Malloc( nKey ); new_elem->pKey = sqlite3Malloc( nKey );
if( new_elem->pKey==0 ){ if( new_elem->pKey==0 ){
sqlite3_free(new_elem); sqlite3_free(new_elem);
@ -280,24 +288,17 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
new_elem->pKey = (void*)pKey; new_elem->pKey = (void*)pKey;
} }
new_elem->nKey = nKey; new_elem->nKey = nKey;
new_elem->data = data;
pH->count++; pH->count++;
if( pH->htsize==0 ){ if( pH->count>=10 && pH->count > 2*pH->htsize ){
rehash(pH, 128/sizeof(pH->ht[0])); if( rehash(pH, pH->count*2) && pH->htsize ){
if( pH->htsize==0 ){ h = strHash(pKey, nKey) % pH->htsize;
pH->count = 0;
if( pH->copyKey ){
sqlite3_free(new_elem->pKey);
}
sqlite3_free(new_elem);
return data;
} }
} }
if( pH->count > pH->htsize ){ if( pH->ht ){
rehash(pH,pH->htsize*2); insertElement(pH, &pH->ht[h], new_elem);
}else{
insertElement(pH, 0, new_elem);
} }
assert( pH->htsize>0 );
h = hraw % pH->htsize;
insertElement(pH, &pH->ht[h], new_elem);
new_elem->data = data;
return 0; return 0;
} }

View File

@ -12,7 +12,7 @@
** This is the header file for the generic hash-table implemenation ** This is the header file for the generic hash-table implemenation
** used in SQLite. ** used in SQLite.
** **
** $Id: hash.h,v 1.12 2008/10/10 17:41:29 drh Exp $ ** $Id: hash.h,v 1.13 2009/04/28 15:43:45 drh Exp $
*/ */
#ifndef _SQLITE_HASH_H_ #ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_ #define _SQLITE_HASH_H_
@ -25,12 +25,25 @@ typedef struct HashElem HashElem;
** The internals of this structure are intended to be opaque -- client ** The internals of this structure are intended to be opaque -- client
** code should not attempt to access or modify the fields of this structure ** code should not attempt to access or modify the fields of this structure
** directly. Change this structure only by using the routines below. ** directly. Change this structure only by using the routines below.
** However, many of the "procedures" and "functions" for modifying and ** However, some of the "procedures" and "functions" for modifying and
** accessing this structure are really macros, so we can't really make ** accessing this structure are really macros, so we can't really make
** this structure opaque. ** this structure opaque.
**
** All elements of the hash table are on a single doubly-linked list.
** Hash.first points to the head of this list.
**
** There are Hash.htsize buckets. Each bucket points to a spot in
** the global doubly-linked list. The contents of the bucket are the
** element pointed to plus the next _ht.count-1 elements in the list.
**
** Hash.htsize and Hash.ht may be zero. In that case lookup is done
** by a linear search of the global list. For small tables, the
** Hash.ht table is never allocated because if there are few elements
** in the table, it is faster to do a linear search than to manage
** the hash table.
*/ */
struct Hash { struct Hash {
unsigned int copyKey: 1; /* True if copy of key made on insert */ unsigned int copyKey : 1; /* True if copy of key made on insert */
unsigned int htsize : 31; /* Number of buckets in the hash table */ unsigned int htsize : 31; /* Number of buckets in the hash table */
unsigned int count; /* Number of entries in this table */ unsigned int count; /* Number of entries in this table */
HashElem *first; /* The first element of the array */ HashElem *first; /* The first element of the array */
@ -76,12 +89,12 @@ void sqlite3HashClear(Hash*);
#define sqliteHashFirst(H) ((H)->first) #define sqliteHashFirst(H) ((H)->first)
#define sqliteHashNext(E) ((E)->next) #define sqliteHashNext(E) ((E)->next)
#define sqliteHashData(E) ((E)->data) #define sqliteHashData(E) ((E)->data)
#define sqliteHashKey(E) ((E)->pKey) /* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */
#define sqliteHashKeysize(E) ((E)->nKey) /* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
/* /*
** Number of entries in a hash table ** Number of entries in a hash table
*/ */
#define sqliteHashCount(H) ((H)->count) /* #define sqliteHashCount(H) ((H)->count) // NOT USED */
#endif /* _SQLITE_HASH_H_ */ #endif /* _SQLITE_HASH_H_ */

View File

@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.861 2009/04/24 15:46:22 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.862 2009/04/28 15:43:45 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@ -145,10 +145,10 @@
#endif #endif
/* /*
** If SQLITE_MALLOC_SOFT_LIMIT is defined, then try to keep the ** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
** sizes of memory allocations below this value where possible. ** sizes of memory allocations below this value where possible.
*/ */
#if defined(SQLITE_POW2_MEMORY_SIZE) && !defined(SQLITE_MALLOC_SOFT_LIMIT) #if !defined(SQLITE_MALLOC_SOFT_LIMIT)
# define SQLITE_MALLOC_SOFT_LIMIT 1024 # define SQLITE_MALLOC_SOFT_LIMIT 1024
#endif #endif

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE TABLE statement. # focus of this file is testing the CREATE TABLE statement.
# #
# $Id: table.test,v 1.50 2009/03/14 08:37:24 danielk1977 Exp $ # $Id: table.test,v 1.51 2009/04/28 15:43:45 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -112,15 +112,16 @@ do_test table-2.1e {
catchsql {CREATE TABLE IF NOT EXISTS test2(x UNIQUE, y TEXT PRIMARY KEY)} catchsql {CREATE TABLE IF NOT EXISTS test2(x UNIQUE, y TEXT PRIMARY KEY)}
} {0 {}} } {0 {}}
do_test table-2.1f { do_test table-2.1f {
breakpoint
execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'} execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
} {} } {}
# Verify that we cannot make a table with the same name as an index # Verify that we cannot make a table with the same name as an index
# #
do_test table-2.2a { do_test table-2.2a {
execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)} execsql {CREATE TABLE test2(one text)}
set v [catch {execsql {CREATE TABLE test3(two text)}} msg] execsql {CREATE INDEX test3 ON test2(one)}
lappend v $msg catchsql {CREATE TABLE test3(two text)}
} {1 {there is already an index named test3}} } {1 {there is already an index named test3}}
do_test table-2.2b { do_test table-2.2b {
db close db close