Initialize the global built-in function table at start-time
instead of at compile-time. This is less prone to malfunction when compile-time parameters very. (CVS 5583) FossilOrigin-Name: ef6936e50adb9ebea39c890167403fff01bbb5ed
This commit is contained in:
parent
801880f66c
commit
70a8ca3c1e
13
Makefile.in
13
Makefile.in
@ -157,7 +157,7 @@ NAWK = @AWK@
|
||||
#
|
||||
OBJS0 = alter.lo analyze.lo attach.lo auth.lo bitvec.lo btmutex.lo \
|
||||
btree.lo build.lo callback.lo complete.lo date.lo \
|
||||
delete.lo expr.lo fault.lo func2.lo global.lo \
|
||||
delete.lo expr.lo fault.lo func.lo global.lo \
|
||||
hash.lo journal.lo insert.lo loadext.lo \
|
||||
main.lo malloc.lo mem1.lo mem2.lo mem3.lo mem4.lo mem5.lo mem6.lo \
|
||||
mutex.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
|
||||
@ -198,6 +198,7 @@ SRC = \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/global.c \
|
||||
$(TOP)/src/hash.c \
|
||||
$(TOP)/src/hash.h \
|
||||
@ -265,7 +266,6 @@ SRC = \
|
||||
# Generated source code files
|
||||
#
|
||||
SRC += \
|
||||
func2.c \
|
||||
keywordhash.h \
|
||||
opcodes.c \
|
||||
opcodes.h \
|
||||
@ -521,8 +521,8 @@ expr.lo: $(TOP)/src/expr.c $(HDR)
|
||||
fault.lo: $(TOP)/src/fault.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/fault.c
|
||||
|
||||
func2.lo: func2.c $(HDR)
|
||||
$(LTCOMPILE) -c func2.c
|
||||
func.lo: $(TOP)/src/func.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/func.c
|
||||
|
||||
global.lo: $(TOP)/src/global.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/global.c
|
||||
@ -616,11 +616,6 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
|
||||
mv parse.h parse.h.temp
|
||||
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
|
||||
|
||||
func2.c: $(TOP)/src/func.c $(HDR)
|
||||
$(BCC) -o mkfunction$(BEXE) $(OPTS) $(OPT_FEATURE_FLAGS) $(TOP)/tool/mkfunction.c -I$(TOP)/src -I.
|
||||
cat $(TOP)/src/func.c > func2.c
|
||||
./mkfunction$(BEXE) >> func2.c
|
||||
|
||||
pragma.lo: $(TOP)/src/pragma.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/pragma.c
|
||||
|
||||
|
17
main.mk
17
main.mk
@ -51,7 +51,7 @@ TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) -I$(TOP)/ext/rtree
|
||||
LIBOBJ+= alter.o analyze.o attach.o auth.o \
|
||||
bitvec.o btmutex.o btree.o build.o \
|
||||
callback.o complete.o date.o delete.o \
|
||||
expr.o fault.o func2.o global.o hash.o \
|
||||
expr.o fault.o func.o global.o hash.o \
|
||||
icu.o insert.o journal.o legacy.o loadext.o \
|
||||
main.o malloc.o mem1.o mem2.o mem3.o mem4.o mem5.o mem6.o \
|
||||
mutex.o mutex_os2.o mutex_unix.o mutex_w32.o \
|
||||
@ -83,6 +83,7 @@ SRC = \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/global.c \
|
||||
$(TOP)/src/hash.c \
|
||||
$(TOP)/src/hash.h \
|
||||
@ -142,7 +143,6 @@ SRC = \
|
||||
$(TOP)/src/vdbeblob.c \
|
||||
$(TOP)/src/vdbefifo.c \
|
||||
$(TOP)/src/vdbemem.c \
|
||||
$(TOP)/src/pcache.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/walker.c \
|
||||
@ -193,7 +193,6 @@ SRC += \
|
||||
opcodes.h \
|
||||
parse.c \
|
||||
parse.h \
|
||||
func2.c \
|
||||
sqlite3.h
|
||||
|
||||
|
||||
@ -231,7 +230,7 @@ TESTSRC = \
|
||||
|
||||
TESTSRC2 = \
|
||||
$(TOP)/src/attach.c $(TOP)/src/btree.c $(TOP)/src/build.c $(TOP)/src/date.c \
|
||||
$(TOP)/src/expr.c func2.c $(TOP)/src/insert.c $(TOP)/src/os.c \
|
||||
$(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c \
|
||||
$(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
|
||||
$(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \
|
||||
@ -349,12 +348,8 @@ opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
|
||||
sort -n -b -k 3 opcodes.h | $(NAWK) -f $(TOP)/mkopcodec.awk >opcodes.c
|
||||
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
|
||||
cat parse.h $(TOP)/src/vdbe.c |$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
|
||||
|
||||
func2.c: $(TOP)/src/func.c $(HDR)
|
||||
$(BCC) -o mkfunction $(OPTS) $(TOP)/tool/mkfunction.c -I$(TOP)/src -I.
|
||||
cat $(TOP)/src/func.c > func2.c
|
||||
./mkfunction >> func2.c
|
||||
cat parse.h $(TOP)/src/vdbe.c | \
|
||||
$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
|
||||
|
||||
# Rules to build parse.c and parse.h - the outputs of lemon.
|
||||
#
|
||||
@ -497,4 +492,4 @@ clean:
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf tsrc target_source
|
||||
rm -f testloadext.dll libtestloadext.so
|
||||
rm -f sqlite3.c fts?amal.c tclsqlite3.c func2.c
|
||||
rm -f sqlite3.c fts?amal.c tclsqlite3.c
|
||||
|
29
manifest
29
manifest
@ -1,7 +1,7 @@
|
||||
C Fix\ssoft-heap-limit\srelated\stest\ssuite\sfailures.\s(CVS\s5582)
|
||||
D 2008-08-21T15:54:01
|
||||
C Initialize\sthe\sglobal\sbuilt-in\sfunction\stable\sat\sstart-time\ninstead\sof\sat\scompile-time.\s\sThis\sis\sless\sprone\sto\smalfunction\swhen\ncompile-time\sparameters\svery.\s(CVS\s5583)
|
||||
D 2008-08-21T18:49:28
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 0b1c022000f55221454a7846022f11674d8024bf
|
||||
F Makefile.in 51b727303f84cf055e29514d8248e5eaf9701379
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
F README b974cdc3f9f12b87e851b04e75996d720ebf81ac
|
||||
F VERSION d1968c7d42b95f18d5fdb5cf7f4cef21797572fa
|
||||
@ -76,7 +76,7 @@ F ext/rtree/rtree_util.tcl ee0a0311eb12175319d78bfb37302320496cee6e
|
||||
F ext/rtree/viewrtree.tcl 09526398dae87a5a87c5aac2b3854dbaf8376869
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||
F ltmain.sh 09fe5815427dc7d0abb188bbcdf0e34896577210
|
||||
F main.mk 4bb354f1e952a13ee8a02b42837b37c4b198d9a7
|
||||
F main.mk 5ce1477b7fdc00f5c981f06e5708255dc217902c
|
||||
F mkdll.sh 79d1ed6ae221c10589dd969f130f8a3cccfffbb7
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||
@ -100,14 +100,14 @@ F src/btree.c 3078f7a5c7cde1e74d884dfa57410125d21586fb
|
||||
F src/btree.h 6371c5e599fab391a150c96afbc10062b276d107
|
||||
F src/btreeInt.h ab18c7b4980314e9e4b402e5dcde09f3c2545576
|
||||
F src/build.c 160c71acca8f643f436ed6c1ee2f684c88df4dfe
|
||||
F src/callback.c 1b1a5c580cdf7d83db24001bf8e5c09e2b08658f
|
||||
F src/callback.c 26f18b3cb5e44120390a8d2d97907889feb47bc5
|
||||
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
|
||||
F src/date.c 52a54811218a76da6235420f532ece841159a96d
|
||||
F src/delete.c 5105c67c741f934379722de5e11fdd73ea4d82b5
|
||||
F src/expr.c 4651d08422474f7e4bcb9a35da00c33ebe719a2d
|
||||
F src/fault.c 3638519d1e0b82bccfafcb9f5ff491918b28f8e1
|
||||
F src/func.c d97ff7b72f3ddcd88970048e2894954a3f5b01d8
|
||||
F src/global.c b9c96ee2317a6e1391763c7db1098a6473a91863
|
||||
F src/func.c f52c6d1b5d08b94ea348059e1bd067580490dd60
|
||||
F src/global.c 39350827d0bce0fe10cca8b13c5dfca3438b4f65
|
||||
F src/hash.c eb64e48f3781100e5934f759fbe72a63a8fe78cb
|
||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||
F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb
|
||||
@ -115,7 +115,7 @@ F src/insert.c 110cca7845ed5a66c08fdd413b02e706ae34455f
|
||||
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
||||
F src/legacy.c aac57bd984e666059011ea01ec4383892a253be3
|
||||
F src/loadext.c eb1fe4f44d7c8ff53fc0c6a4388ab79fbd34cd64
|
||||
F src/main.c aaf5af6ffe2c05f8ea4d75a850581a68ac529fa0
|
||||
F src/main.c 2513e9bb233a8ebc4aaa766a37528ef255cde7fb
|
||||
F src/malloc.c 7ccc630b359f57a47b6034af54e42eb838eebd46
|
||||
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
||||
F src/mem1.c 3a7fe31d8290baa3bb203af72f7dfd6323966bcd
|
||||
@ -149,7 +149,7 @@ F src/select.c e71462393fe0f9d2bf41378763b96659e8780e43
|
||||
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
|
||||
F src/sqlite.h.in 54e51c22e2294c5989156b0aec87aa44168ac1f0
|
||||
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
|
||||
F src/sqliteInt.h d1ddf30df8d7eb3e15e7d70ebe347e0c17255165
|
||||
F src/sqliteInt.h 15096ac72b783de470c7f89888560e2ddaa83898
|
||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||
F src/status.c 8caa772cd9310bc297280f7cf0ede4d69ed5b801
|
||||
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
|
||||
@ -605,10 +605,9 @@ F tool/lempar.c 770dc64b74429daf9611676f43bfbd7c1bed0152
|
||||
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
|
||||
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
|
||||
F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf
|
||||
F tool/mkfunction.c 72c656fbc1a20ec426a94cd80cda5eea5b7b8bc7
|
||||
F tool/mkkeywordhash.c ef93810fc41fb3d3dbacf9a33a29be88ea99ffa9
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
|
||||
F tool/mksqlite3c.tcl f5645b2e7ee71fa9633ca5c90ada3ae9120b4a3c
|
||||
F tool/mksqlite3c.tcl c4542127796826a26f89567c7bbaecafaf42a120
|
||||
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
|
||||
F tool/omittest.tcl 5a25ea687df5da8dd9b94bf1683f5cf2c210e51d
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
@ -623,7 +622,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P d68dad73d0a85c6213a96982d0366c790871b693
|
||||
R b1b9ce7ac833bb03734065aa230b3a65
|
||||
U danielk1977
|
||||
Z 442c477497b5c11bc6fcf9ea22d419f7
|
||||
P 2091d9a5260b1d7e27ff5ca93e60dae1e3b12081
|
||||
R b949ccba5219ea8fee93a425d2cbcc5d
|
||||
U drh
|
||||
Z f9a9c8cdda97c141f21d737763887781
|
||||
|
@ -1 +1 @@
|
||||
2091d9a5260b1d7e27ff5ca93e60dae1e3b12081
|
||||
ef6936e50adb9ebea39c890167403fff01bbb5ed
|
@ -13,7 +13,7 @@
|
||||
** This file contains functions used to access the internal hash tables
|
||||
** of user defined functions and collation sequences.
|
||||
**
|
||||
** $Id: callback.c,v 1.27 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
** $Id: callback.c,v 1.28 2008/08/21 18:49:28 drh Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@ -260,6 +260,49 @@ static int matchQuality(FuncDef *p, int nArg, u8 enc){
|
||||
return match;
|
||||
}
|
||||
|
||||
/*
|
||||
** Search a FuncDefHash for a function with the given name. Return
|
||||
** a pointer to the matching FuncDef if found, or 0 if there is no match.
|
||||
*/
|
||||
static FuncDef *functionSearch(
|
||||
FuncDefHash *pHash, /* Hash table to search */
|
||||
int h, /* Hash of the name */
|
||||
const char *zFunc, /* Name of function */
|
||||
int nFunc /* Number of bytes in zFunc */
|
||||
){
|
||||
FuncDef *p;
|
||||
for(p=pHash->a[h]; p; p=p->pHash){
|
||||
if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Insert a new FuncDef into a FuncDefHash hash table.
|
||||
*/
|
||||
void sqlite3FuncDefInsert(
|
||||
FuncDefHash *pHash, /* The hash table into which to insert */
|
||||
FuncDef *pDef /* The function definition to insert */
|
||||
){
|
||||
FuncDef *pOther;
|
||||
int nName = strlen(pDef->zName);
|
||||
u8 c1 = (u8)pDef->zName[0];
|
||||
int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
|
||||
pOther = functionSearch(pHash, h, pDef->zName, nName);
|
||||
if( pOther ){
|
||||
pDef->pNext = pOther->pNext;
|
||||
pOther->pNext = pDef;
|
||||
}else{
|
||||
pDef->pNext = 0;
|
||||
pDef->pHash = pHash->a[h];
|
||||
pHash->a[h] = pDef;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Locate a user function given a name, a number of arguments and a flag
|
||||
** indicating whether the function prefers UTF-16 over UTF-8. Return a
|
||||
@ -289,21 +332,24 @@ FuncDef *sqlite3FindFunction(
|
||||
int createFlag /* Create new entry if true and does not otherwise exist */
|
||||
){
|
||||
FuncDef *p; /* Iterator variable */
|
||||
FuncDef *pFirst; /* First function with this name */
|
||||
FuncDef *pBest = 0; /* Best match found so far */
|
||||
int bestmatch = 0;
|
||||
int bestScore = 0; /* Score of best match */
|
||||
int h; /* Hash value */
|
||||
|
||||
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
if( nArg<-1 ) nArg = -1;
|
||||
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
|
||||
|
||||
pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
|
||||
for(p=pFirst; p; p=p->pNext){
|
||||
int match = matchQuality(p, nArg, enc);
|
||||
if( match>bestmatch ){
|
||||
|
||||
p = functionSearch(&db->aFunc, h, zName, nName);
|
||||
while( p ){
|
||||
int score = matchQuality(p, nArg, enc);
|
||||
if( score>bestScore ){
|
||||
pBest = p;
|
||||
bestmatch = match;
|
||||
bestScore = score;
|
||||
}
|
||||
p = p->pNext;
|
||||
}
|
||||
|
||||
/* If the createFlag parameter is false and no match was found amongst
|
||||
@ -311,16 +357,14 @@ FuncDef *sqlite3FindFunction(
|
||||
** function to use.
|
||||
*/
|
||||
if( !createFlag && !pBest ){
|
||||
FuncDef *aFunc;
|
||||
int nFunc;
|
||||
int i;
|
||||
nFunc = sqlite3GetBuiltinFunction(zName, nName, &aFunc);
|
||||
for(i=0; i<nFunc; i++){
|
||||
int match = matchQuality(&aFunc[i], nArg, enc);
|
||||
if( match>bestmatch ){
|
||||
pBest = &aFunc[i];
|
||||
bestmatch = match;
|
||||
p = functionSearch(&sqlite3FuncBuiltins, h, zName, nName);
|
||||
while( p ){
|
||||
int score = matchQuality(p, nArg, enc);
|
||||
if( score>bestScore ){
|
||||
pBest = p;
|
||||
bestScore = score;
|
||||
}
|
||||
p = p->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,19 +372,14 @@ FuncDef *sqlite3FindFunction(
|
||||
** exact match for the name, number of arguments and encoding, then add a
|
||||
** new entry to the hash table and return it.
|
||||
*/
|
||||
if( createFlag && bestmatch<6 &&
|
||||
if( createFlag && bestScore<6 &&
|
||||
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
|
||||
pBest->zName = (char *)&pBest[1];
|
||||
pBest->nArg = nArg;
|
||||
pBest->pNext = pFirst;
|
||||
pBest->iPrefEnc = enc;
|
||||
memcpy(pBest->zName, zName, nName);
|
||||
pBest->zName[nName] = 0;
|
||||
if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
|
||||
db->mallocFailed = 1;
|
||||
sqlite3DbFree(db, pBest);
|
||||
return 0;
|
||||
}
|
||||
sqlite3FuncDefInsert(&db->aFunc, pBest);
|
||||
}
|
||||
|
||||
if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
|
||||
|
12
src/func.c
12
src/func.c
@ -16,7 +16,7 @@
|
||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
**
|
||||
** $Id: func.c,v 1.197 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
** $Id: func.c,v 1.198 2008/08/21 18:49:28 drh Exp $
|
||||
*/
|
||||
|
||||
#ifndef CREATE_BUILTIN_HASHTABLE
|
||||
@ -1422,3 +1422,13 @@ static FuncDef aBuiltinFunc[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** Build up the global built-in function table at initialization
|
||||
** time.
|
||||
*/
|
||||
void sqlite3RegisterGlobalFunctions(void){
|
||||
int i;
|
||||
for(i=0; i<ArraySize(aBuiltinFunc); i++){
|
||||
sqlite3FuncDefInsert(&sqlite3FuncBuiltins, &aBuiltinFunc[i]);
|
||||
}
|
||||
}
|
||||
|
10
src/global.c
10
src/global.c
@ -12,7 +12,7 @@
|
||||
**
|
||||
** This file contains definitions of global variables and contants.
|
||||
**
|
||||
** $Id: global.c,v 1.4 2008/07/28 19:34:53 drh Exp $
|
||||
** $Id: global.c,v 1.5 2008/08/21 18:49:28 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -75,3 +75,11 @@ struct Sqlite3Config sqlite3Config = {
|
||||
500, /* nLookaside */
|
||||
/* Other fields all default to zero */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Hash table for global functions - functions common to all
|
||||
** database connections. After initialization, this table is
|
||||
** read-only.
|
||||
*/
|
||||
FuncDefHash sqlite3FuncBuiltins;
|
||||
|
24
src/main.c
24
src/main.c
@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.491 2008/08/20 16:35:10 drh Exp $
|
||||
** $Id: main.c,v 1.492 2008/08/21 18:49:28 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -147,6 +147,8 @@ int sqlite3_initialize(void){
|
||||
sqlite3_mutex_enter(sqlite3Config.pInitMutex);
|
||||
if( sqlite3Config.isInit==0 && inProgress==0 ){
|
||||
inProgress = 1;
|
||||
memset(&sqlite3FuncBuiltins, 0, sizeof(sqlite3FuncBuiltins));
|
||||
sqlite3RegisterGlobalFunctions();
|
||||
rc = sqlite3_os_init();
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PcacheInitialize();
|
||||
@ -566,14 +568,17 @@ int sqlite3_close(sqlite3 *db){
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
assert( db->nDb<=2 );
|
||||
assert( db->aDb==db->aDbStatic );
|
||||
for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
|
||||
FuncDef *pFunc, *pNext;
|
||||
for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
|
||||
pNext = pFunc->pNext;
|
||||
sqlite3DbFree(db, pFunc);
|
||||
for(j=0; j<ArraySize(db->aFunc.a); j++){
|
||||
FuncDef *pNext, *pHash, *p;
|
||||
for(p=db->aFunc.a[j]; p; p=pHash){
|
||||
pHash = p->pHash;
|
||||
while( p ){
|
||||
pNext = p->pNext;
|
||||
sqlite3DbFree(db, p);
|
||||
p = pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
|
||||
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
|
||||
/* Invoke any destructors registered for collation sequence user data. */
|
||||
@ -596,7 +601,6 @@ int sqlite3_close(sqlite3 *db){
|
||||
sqlite3HashClear(&db->aModule);
|
||||
#endif
|
||||
|
||||
sqlite3HashClear(&db->aFunc);
|
||||
sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
|
||||
if( db->pErr ){
|
||||
sqlite3ValueFree(db->pErr);
|
||||
@ -1371,6 +1375,9 @@ static const int aHardLimit[] = {
|
||||
#if SQLITE_MAX_VARIABLE_NUMBER<1
|
||||
# error SQLITE_MAX_VARIABLE_NUMBER must be at least 1
|
||||
#endif
|
||||
#if SQLITE_MAX_COLUMN>32767
|
||||
# error SQLITE_MAX_COLUMN must not exceed 32767
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@ -1466,7 +1473,6 @@ static int openDatabase(
|
||||
| SQLITE_LoadExtension
|
||||
#endif
|
||||
;
|
||||
sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3HashInit(&db->aModule, SQLITE_HASH_STRING, 0);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.757 2008/08/20 16:35:10 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.758 2008/08/21 18:49:28 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -366,7 +366,7 @@ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
|
||||
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
|
||||
typedef INT16_TYPE i16; /* 2-byte signed integer */
|
||||
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
||||
typedef UINT8_TYPE i8; /* 1-byte signed integer */
|
||||
typedef INT8_TYPE i8; /* 1-byte signed integer */
|
||||
|
||||
/*
|
||||
** Macros to determine whether the machine is big or little endian,
|
||||
@ -455,6 +455,7 @@ typedef struct Expr Expr;
|
||||
typedef struct ExprList ExprList;
|
||||
typedef struct FKey FKey;
|
||||
typedef struct FuncDef FuncDef;
|
||||
typedef struct FuncDefHash FuncDefHash;
|
||||
typedef struct IdList IdList;
|
||||
typedef struct Index Index;
|
||||
typedef struct KeyClass KeyClass;
|
||||
@ -592,6 +593,16 @@ struct LookasideSlot {
|
||||
LookasideSlot *pNext; /* Next buffer in the list of free buffers */
|
||||
};
|
||||
|
||||
/*
|
||||
** A hash table for function definitions.
|
||||
**
|
||||
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
|
||||
** Collisions are on the FuncDef.pHash chain.
|
||||
*/
|
||||
struct FuncDefHash {
|
||||
FuncDef *a[23]; /* Hash table for functions */
|
||||
};
|
||||
|
||||
/*
|
||||
** Each database is an instance of the following structure.
|
||||
**
|
||||
@ -688,7 +699,7 @@ struct sqlite3 {
|
||||
sqlite3_vtab **aVTrans; /* Virtual tables with open transactions */
|
||||
int nVTrans; /* Allocated size of aVTrans */
|
||||
#endif
|
||||
Hash aFunc; /* All functions that can be in SQL exprs */
|
||||
FuncDefHash aFunc; /* Hash table of connection functions */
|
||||
Hash aCollSeq; /* All collating sequences */
|
||||
BusyHandler busyHandler; /* Busy callback */
|
||||
int busyTimeout; /* Busy handler timeout, in msec */
|
||||
@ -753,7 +764,7 @@ struct sqlite3 {
|
||||
** points to a linked list of these structures.
|
||||
*/
|
||||
struct FuncDef {
|
||||
i16 nArg; /* Number of arguments. -1 means unlimited */
|
||||
i8 nArg; /* Number of arguments. -1 means unlimited */
|
||||
u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
|
||||
u8 needCollSeq; /* True if sqlite3GetFuncCollSeq() might be called */
|
||||
u8 flags; /* Some combination of SQLITE_FUNC_* */
|
||||
@ -763,14 +774,15 @@ struct FuncDef {
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
|
||||
void (*xFinalize)(sqlite3_context*); /* Aggregate finializer */
|
||||
char *zName; /* SQL name of the function. */
|
||||
FuncDef *pHash; /* Next with a different name but the same hash */
|
||||
};
|
||||
|
||||
/*
|
||||
** Possible values for FuncDef.flags
|
||||
*/
|
||||
#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */
|
||||
#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
|
||||
#define SQLITE_FUNC_EPHEM 0x04 /* Ephermeral. Delete with VDBE */
|
||||
#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */
|
||||
#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
|
||||
#define SQLITE_FUNC_EPHEM 0x04 /* Ephermeral. Delete with VDBE */
|
||||
|
||||
/*
|
||||
** Each SQLite module (virtual table definition) is defined by an
|
||||
@ -2127,9 +2139,11 @@ ExprList *sqlite3ExprListDup(sqlite3*,ExprList*);
|
||||
SrcList *sqlite3SrcListDup(sqlite3*,SrcList*);
|
||||
IdList *sqlite3IdListDup(sqlite3*,IdList*);
|
||||
Select *sqlite3SelectDup(sqlite3*,Select*);
|
||||
void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
|
||||
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
|
||||
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
||||
void sqlite3RegisterDateTimeFunctions(sqlite3*);
|
||||
void sqlite3RegisterGlobalFunctions(void);
|
||||
int sqlite3GetBuiltinFunction(const char *, int, FuncDef **);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3SafetyOn(sqlite3*);
|
||||
@ -2268,6 +2282,7 @@ void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
extern const unsigned char sqlite3UpperToLower[];
|
||||
extern struct Sqlite3Config sqlite3Config;
|
||||
extern FuncDefHash sqlite3FuncBuiltins;
|
||||
#endif
|
||||
void sqlite3RootPageMoved(Db*, int, int);
|
||||
void sqlite3Reindex(Parse*, Token*, Token*);
|
||||
|
@ -1,186 +0,0 @@
|
||||
|
||||
/*
|
||||
** This file contains a standalone program used to generate C code that
|
||||
** implements a static hash table to store the definitions of built-in
|
||||
** SQL functions in SQLite.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
** The SQLite source file "func.c" is included below.
|
||||
**
|
||||
** By defining the 4 macros and typedef below before including "func.c",
|
||||
** most of the code is excluded. What is left is an array of constant
|
||||
** strings, aBuiltinFunc[], containing the names of SQLite's built-in
|
||||
** SQL functions. i.e.:
|
||||
**
|
||||
** const char aBuiltinFunc[] = { "like", "glob", "min", "max" ... };
|
||||
**
|
||||
** The data from aBuiltinFunc[] is used by this program to create the
|
||||
** static hash table.
|
||||
*/
|
||||
#define CREATE_BUILTIN_HASHTABLE 1
|
||||
#define FUNCTION(zName,w,x,y,z) #zName
|
||||
#define AGGREGATE(zName,v,w,x,y,z) #zName
|
||||
#define LIKEFUNC(zName,x,y,z) #zName
|
||||
#define FuncDef const char *
|
||||
|
||||
#include "func.c"
|
||||
|
||||
/* The number of buckets in the static hash table. */
|
||||
#define HASHSIZE 127
|
||||
|
||||
typedef unsigned char u8;
|
||||
|
||||
/* An array to map all upper-case characters into their corresponding
|
||||
** lower-case character.
|
||||
*/
|
||||
static const u8 sqlite3UpperToLower[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
|
||||
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
|
||||
122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
|
||||
108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
|
||||
126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
|
||||
162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
|
||||
180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
|
||||
198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
|
||||
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
|
||||
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
|
||||
252,253,254,255
|
||||
};
|
||||
#define UpperToLower sqlite3UpperToLower
|
||||
|
||||
int sqlite3StrICmp(const char *zLeft, const char *zRight){
|
||||
register unsigned char *a, *b;
|
||||
a = (unsigned char *)zLeft;
|
||||
b = (unsigned char *)zRight;
|
||||
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
||||
return UpperToLower[*a] - UpperToLower[*b];
|
||||
}
|
||||
|
||||
static int hashstring(const char *zName){
|
||||
int ii;
|
||||
unsigned int iKey = 0;
|
||||
for(ii=0; zName[ii]; ii++){
|
||||
iKey = (iKey<<3) + (u8)sqlite3UpperToLower[(u8)zName[ii]];
|
||||
}
|
||||
iKey = iKey%HASHSIZE;
|
||||
return iKey;
|
||||
}
|
||||
|
||||
static void printarray(const char *zName, u8 *aArray, int nArray){
|
||||
int ii;
|
||||
printf(" static u8 %s[%d] = {", zName, nArray);
|
||||
for(ii=0; ii<nArray; ii++){
|
||||
if( (ii%16)==0 ){
|
||||
printf("\n ");
|
||||
}
|
||||
printf("%2d, ", aArray[ii]);
|
||||
}
|
||||
printf("\n };\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int nFunc; /* Number of entries in the aBuiltinFunc array */
|
||||
|
||||
u8 anFunc[256];
|
||||
u8 aHash[HASHSIZE];
|
||||
u8 aNext[256];
|
||||
int ii;
|
||||
int iHead;
|
||||
|
||||
nFunc = (sizeof(aBuiltinFunc)/sizeof(const char *));
|
||||
assert(nFunc<256);
|
||||
|
||||
memset(aHash, (unsigned char)nFunc, sizeof(aHash));
|
||||
memset(aNext, (unsigned char)nFunc, sizeof(aNext));
|
||||
memset(anFunc, 0, sizeof(anFunc));
|
||||
|
||||
iHead = -1;
|
||||
for(ii=0; ii<nFunc; ii++){
|
||||
int iHash;
|
||||
|
||||
if( iHead>=0 && 0==sqlite3StrICmp(aBuiltinFunc[ii], aBuiltinFunc[iHead]) ){
|
||||
anFunc[iHead]++;
|
||||
continue;
|
||||
}else{
|
||||
/* The routine generated by this program assumes that if there are
|
||||
** two or more entries in the aBuiltinFunc[] array with the same
|
||||
** name (i.e. two versions of the "max" function), then they must
|
||||
** be stored in adjacent slots. The following block detects the
|
||||
** problem if this is not the case.
|
||||
*/
|
||||
int jj;
|
||||
for(jj=0; jj<ii; jj++){
|
||||
if( 0==sqlite3StrICmp(aBuiltinFunc[ii], aBuiltinFunc[jj]) ){
|
||||
fprintf(stderr, "Error in func.c\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
iHead = ii;
|
||||
anFunc[iHead] = 1;
|
||||
}
|
||||
|
||||
iHash = hashstring(aBuiltinFunc[ii]);
|
||||
if( aHash[iHash]!=nFunc ){
|
||||
int iNext = aHash[iHash];
|
||||
while( aNext[iNext]!=nFunc ){
|
||||
iNext = aNext[iNext];
|
||||
}
|
||||
aNext[iNext] = ii;
|
||||
}else{
|
||||
aHash[iHash] = ii;
|
||||
}
|
||||
}
|
||||
|
||||
printf(
|
||||
"/******* Automatically Generated code - do not edit **************/\n"
|
||||
"int sqlite3GetBuiltinFunction(\n"
|
||||
" const char *zName, \n"
|
||||
" int nName, \n"
|
||||
" FuncDef **paFunc\n"
|
||||
"){\n"
|
||||
);
|
||||
|
||||
printarray("aHash", aHash, HASHSIZE);
|
||||
printarray("anFunc", anFunc, nFunc);
|
||||
printarray("aNext", aNext, nFunc);
|
||||
printf(" FuncDef *pNoFunc = &aBuiltinFunc[%d];\n", nFunc);
|
||||
|
||||
printf(
|
||||
" unsigned int iKey = 0; /* Hash of case-insensitive string zName. */\n"
|
||||
" int ii;\n"
|
||||
" FuncDef *pFunc;\n"
|
||||
"\n"
|
||||
);
|
||||
printf(
|
||||
" assert( (sizeof(aBuiltinFunc)/sizeof(aBuiltinFunc[0]))==%d );\n", nFunc
|
||||
);
|
||||
printf(
|
||||
" /* Generate the hash of zName */\n"
|
||||
" for(ii=0; ii<nName; ii++){\n"
|
||||
" iKey = (iKey<<3) + (u8)sqlite3UpperToLower[(u8)zName[ii]];\n"
|
||||
" }\n"
|
||||
" iKey = iKey%%127;\n"
|
||||
"\n"
|
||||
" pFunc = &aBuiltinFunc[iKey = aHash[iKey]];\n"
|
||||
" while( pFunc!=pNoFunc && sqlite3StrNICmp(pFunc->zName, zName, nName) ){\n"
|
||||
" pFunc = &aBuiltinFunc[iKey = aNext[iKey]];\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" *paFunc = pFunc;\n"
|
||||
" return anFunc[iKey];\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
@ -256,7 +256,7 @@ foreach file {
|
||||
build.c
|
||||
callback.c
|
||||
delete.c
|
||||
func2.c
|
||||
func.c
|
||||
insert.c
|
||||
legacy.c
|
||||
loadext.c
|
||||
|
Loading…
Reference in New Issue
Block a user