1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

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:
drh
2008-08-21 18:49:27 +00:00
parent 801880f66c
commit 70a8ca3c1e
11 changed files with 146 additions and 265 deletions

View 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) ){