From 70a8ca3c1e3ceb0446908fea3e15ef06587b570a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Aug 2008 18:49:27 +0000 Subject: [PATCH] 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 --- Makefile.in | 13 +--- main.mk | 17 ++-- manifest | 29 ++++--- manifest.uuid | 2 +- src/callback.c | 87 +++++++++++++++------ src/func.c | 12 ++- src/global.c | 10 ++- src/main.c | 24 +++--- src/sqliteInt.h | 29 +++++-- tool/mkfunction.c | 186 -------------------------------------------- tool/mksqlite3c.tcl | 2 +- 11 files changed, 146 insertions(+), 265 deletions(-) delete mode 100644 tool/mkfunction.c diff --git a/Makefile.in b/Makefile.in index 4b5713de49..5144a29865 100644 --- a/Makefile.in +++ b/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 diff --git a/main.mk b/main.mk index d96773fb0d..ec8b0ed49a 100644 --- a/main.mk +++ b/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 diff --git a/manifest b/manifest index 6b57f59827..1e0005680e 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index 42cb63edad..e7958b43b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2091d9a5260b1d7e27ff5ca93e60dae1e3b12081 \ No newline at end of file +ef6936e50adb9ebea39c890167403fff01bbb5ed \ No newline at end of file diff --git a/src/callback.c b/src/callback.c index 90d9e594d8..d25836b435 100644 --- a/src/callback.c +++ b/src/callback.c @@ -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; ibestmatch ){ - 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) ){ diff --git a/src/func.c b/src/func.c index 975f7dc811..0f4f0a6e13 100644 --- a/src/func.c +++ b/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 @@ -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; jaFunc.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); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1d1474a285..167b21cf46 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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*); diff --git a/tool/mkfunction.c b/tool/mkfunction.c deleted file mode 100644 index b1ddb0a10d..0000000000 --- a/tool/mkfunction.c +++ /dev/null @@ -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 -#include -#include - -/* -** 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=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; jjzName, zName, nName) ){\n" - " pFunc = &aBuiltinFunc[iKey = aNext[iKey]];\n" - " }\n" - "\n" - " *paFunc = pFunc;\n" - " return anFunc[iKey];\n" - "}\n" - ); - - return 0; -} diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index fbad3f6d73..e89e233fcf 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -256,7 +256,7 @@ foreach file { build.c callback.c delete.c - func2.c + func.c insert.c legacy.c loadext.c