]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Initialize the global built-in function table at start-time
authordrh <drh@noemail.net>
Thu, 21 Aug 2008 18:49:27 +0000 (18:49 +0000)
committerdrh <drh@noemail.net>
Thu, 21 Aug 2008 18:49:27 +0000 (18:49 +0000)
instead of at compile-time.  This is less prone to malfunction when
compile-time parameters very. (CVS 5583)

FossilOrigin-Name: ef6936e50adb9ebea39c890167403fff01bbb5ed

Makefile.in
main.mk
manifest
manifest.uuid
src/callback.c
src/func.c
src/global.c
src/main.c
src/sqliteInt.h
tool/mkfunction.c [deleted file]
tool/mksqlite3c.tcl

index 4b5713de490c92730030997f6f98291f182e5c39..5144a29865de0814d927c712ea6bf00dde63be2e 100644 (file)
@@ -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 d96773fb0d6f5ae54c7e5b613501583dc032ab21..ec8b0ed49ad326ec69dbdc0d1290dfdf9ce34158 100644 (file)
--- 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
index 6b57f59827b62c7a434a2780cc200794899d03de..1e0005680eebf24fe93668487bba131ee031094d 100644 (file)
--- 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
index 42cb63edadcc96ed773746686efb8524b566562c..e7958b43b988d71da2c805eb08e8b8a49b35b0cb 100644 (file)
@@ -1 +1 @@
-2091d9a5260b1d7e27ff5ca93e60dae1e3b12081
\ No newline at end of file
+ef6936e50adb9ebea39c890167403fff01bbb5ed
\ No newline at end of file
index 90d9e594d8803bcaf909777cf8ee059b30165f10..d25836b4357cda3c124f217024bc07e45ec30f87 100644 (file)
@@ -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) ){
index 975f7dc811fe37240b47169829639ce007b13072..0f4f0a6e1337cf55476b0f5db4fcef79330f7693 100644 (file)
@@ -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]);
+  }
+}
index fa59d4a8486a800d848987f1c87e3e2ed360d032..2f0782e3fad51c337da160e02e716cdfac84fcb7 100644 (file)
@@ -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;
index 42ca5cc13a1c2fef8eecb8031efc535c84a86b78..9421a08eca029c21b5e7003446c5532bd188f351 100644 (file)
@@ -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);
index 1d1474a285ab3225581b6d6786cda4c98266d3a0..167b21cf46280cf838a55a9617147a34c55c96cb 100644 (file)
@@ -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 (file)
index b1ddb0a..0000000
+++ /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 <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;
-}
index fbad3f6d73aeb80aa67492bcd99d166d9fdf9788..e89e233fcf093b11cccb48f7668a23c6105ec389 100644 (file)
@@ -256,7 +256,7 @@ foreach file {
    build.c
    callback.c
    delete.c
-   func2.c
+   func.c
    insert.c
    legacy.c
    loadext.c