1fd9a0a45Sdanielk1977 /* 2fd9a0a45Sdanielk1977 ** 2005 May 23 3fd9a0a45Sdanielk1977 ** 4fd9a0a45Sdanielk1977 ** The author disclaims copyright to this source code. In place of 5fd9a0a45Sdanielk1977 ** a legal notice, here is a blessing: 6fd9a0a45Sdanielk1977 ** 7fd9a0a45Sdanielk1977 ** May you do good and not evil. 8fd9a0a45Sdanielk1977 ** May you find forgiveness for yourself and forgive others. 9fd9a0a45Sdanielk1977 ** May you share freely, never taking more than you give. 10fd9a0a45Sdanielk1977 ** 11fd9a0a45Sdanielk1977 ************************************************************************* 12fd9a0a45Sdanielk1977 ** 13fd9a0a45Sdanielk1977 ** This file contains functions used to access the internal hash tables 14fd9a0a45Sdanielk1977 ** of user defined functions and collation sequences. 15fd9a0a45Sdanielk1977 ** 16*7aaa8786Sdrh ** $Id: callback.c,v 1.41 2009/05/20 02:40:46 drh Exp $ 17fd9a0a45Sdanielk1977 */ 18fd9a0a45Sdanielk1977 19fd9a0a45Sdanielk1977 #include "sqliteInt.h" 20fd9a0a45Sdanielk1977 21fd9a0a45Sdanielk1977 /* 224dade037Sdanielk1977 ** Invoke the 'collation needed' callback to request a collation sequence 234dade037Sdanielk1977 ** in the database text encoding of name zName, length nName. 244dade037Sdanielk1977 ** If the collation sequence 254dade037Sdanielk1977 */ 26c4a64facSdrh static void callCollNeeded(sqlite3 *db, const char *zName){ 274dade037Sdanielk1977 assert( !db->xCollNeeded || !db->xCollNeeded16 ); 284dade037Sdanielk1977 if( db->xCollNeeded ){ 29c4a64facSdrh char *zExternal = sqlite3DbStrDup(db, zName); 304dade037Sdanielk1977 if( !zExternal ) return; 3114db2665Sdanielk1977 db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal); 32633e6d57Sdrh sqlite3DbFree(db, zExternal); 334dade037Sdanielk1977 } 344dade037Sdanielk1977 #ifndef SQLITE_OMIT_UTF16 354dade037Sdanielk1977 if( db->xCollNeeded16 ){ 364dade037Sdanielk1977 char const *zExternal; 371e536953Sdanielk1977 sqlite3_value *pTmp = sqlite3ValueNew(db); 38c4a64facSdrh sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); 39b21c8cd4Sdrh zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); 4026abcb1eSdrh if( zExternal ){ 4114db2665Sdanielk1977 db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); 424dade037Sdanielk1977 } 4326abcb1eSdrh sqlite3ValueFree(pTmp); 4426abcb1eSdrh } 454dade037Sdanielk1977 #endif 464dade037Sdanielk1977 } 474dade037Sdanielk1977 484dade037Sdanielk1977 /* 494dade037Sdanielk1977 ** This routine is called if the collation factory fails to deliver a 504dade037Sdanielk1977 ** collation function in the best encoding but there may be other versions 514dade037Sdanielk1977 ** of this collation function (for other text encodings) available. Use one 524dade037Sdanielk1977 ** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if 534dade037Sdanielk1977 ** possible. 544dade037Sdanielk1977 */ 554dade037Sdanielk1977 static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ 564dade037Sdanielk1977 CollSeq *pColl2; 574dade037Sdanielk1977 char *z = pColl->zName; 584dade037Sdanielk1977 int i; 594dade037Sdanielk1977 static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; 604dade037Sdanielk1977 for(i=0; i<3; i++){ 61c4a64facSdrh pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); 624dade037Sdanielk1977 if( pColl2->xCmp!=0 ){ 634dade037Sdanielk1977 memcpy(pColl, pColl2, sizeof(CollSeq)); 64a9808b31Sdanielk1977 pColl->xDel = 0; /* Do not copy the destructor */ 654dade037Sdanielk1977 return SQLITE_OK; 664dade037Sdanielk1977 } 674dade037Sdanielk1977 } 684dade037Sdanielk1977 return SQLITE_ERROR; 694dade037Sdanielk1977 } 704dade037Sdanielk1977 714dade037Sdanielk1977 /* 724dade037Sdanielk1977 ** This function is responsible for invoking the collation factory callback 734dade037Sdanielk1977 ** or substituting a collation sequence of a different encoding when the 744dade037Sdanielk1977 ** requested collation sequence is not available in the database native 754dade037Sdanielk1977 ** encoding. 764dade037Sdanielk1977 ** 774dade037Sdanielk1977 ** If it is not NULL, then pColl must point to the database native encoding 784dade037Sdanielk1977 ** collation sequence with name zName, length nName. 794dade037Sdanielk1977 ** 804dade037Sdanielk1977 ** The return value is either the collation sequence to be used in database 814dade037Sdanielk1977 ** db for collation type name zName, length nName, or NULL, if no collation 824dade037Sdanielk1977 ** sequence can be found. 83c4a64facSdrh ** 84c4a64facSdrh ** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() 854dade037Sdanielk1977 */ 864dade037Sdanielk1977 CollSeq *sqlite3GetCollSeq( 87c4a64facSdrh sqlite3* db, /* The database connection */ 88c4a64facSdrh CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ 89c4a64facSdrh const char *zName /* Collating sequence name */ 904dade037Sdanielk1977 ){ 914dade037Sdanielk1977 CollSeq *p; 924dade037Sdanielk1977 934dade037Sdanielk1977 p = pColl; 944dade037Sdanielk1977 if( !p ){ 95c4a64facSdrh p = sqlite3FindCollSeq(db, ENC(db), zName, 0); 964dade037Sdanielk1977 } 974dade037Sdanielk1977 if( !p || !p->xCmp ){ 984dade037Sdanielk1977 /* No collation sequence of this type for this encoding is registered. 994dade037Sdanielk1977 ** Call the collation factory to see if it can supply us with one. 1004dade037Sdanielk1977 */ 101c4a64facSdrh callCollNeeded(db, zName); 102c4a64facSdrh p = sqlite3FindCollSeq(db, ENC(db), zName, 0); 1034dade037Sdanielk1977 } 1044dade037Sdanielk1977 if( p && !p->xCmp && synthCollSeq(db, p) ){ 1054dade037Sdanielk1977 p = 0; 1064dade037Sdanielk1977 } 1074dade037Sdanielk1977 assert( !p || p->xCmp ); 1084dade037Sdanielk1977 return p; 1094dade037Sdanielk1977 } 1104dade037Sdanielk1977 1114dade037Sdanielk1977 /* 1124dade037Sdanielk1977 ** This routine is called on a collation sequence before it is used to 1134dade037Sdanielk1977 ** check that it is defined. An undefined collation sequence exists when 1144dade037Sdanielk1977 ** a database is loaded that contains references to collation sequences 1154dade037Sdanielk1977 ** that have not been defined by sqlite3_create_collation() etc. 1164dade037Sdanielk1977 ** 1174dade037Sdanielk1977 ** If required, this routine calls the 'collation needed' callback to 1184dade037Sdanielk1977 ** request a definition of the collating sequence. If this doesn't work, 1194dade037Sdanielk1977 ** an equivalent collating sequence that uses a text encoding different 1204dade037Sdanielk1977 ** from the main database is substituted, if one is available. 1214dade037Sdanielk1977 */ 1224dade037Sdanielk1977 int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ 1234dade037Sdanielk1977 if( pColl ){ 1244dade037Sdanielk1977 const char *zName = pColl->zName; 125c4a64facSdrh CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName); 1264dade037Sdanielk1977 if( !p ){ 1274dade037Sdanielk1977 if( pParse->nErr==0 ){ 1284dade037Sdanielk1977 sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); 1294dade037Sdanielk1977 } 1304dade037Sdanielk1977 pParse->nErr++; 1314dade037Sdanielk1977 return SQLITE_ERROR; 1324dade037Sdanielk1977 } 133b3bf556eSdanielk1977 assert( p==pColl ); 1344dade037Sdanielk1977 } 1354dade037Sdanielk1977 return SQLITE_OK; 1364dade037Sdanielk1977 } 1374dade037Sdanielk1977 1384dade037Sdanielk1977 1394dade037Sdanielk1977 1404dade037Sdanielk1977 /* 141fd9a0a45Sdanielk1977 ** Locate and return an entry from the db.aCollSeq hash table. If the entry 142fd9a0a45Sdanielk1977 ** specified by zName and nName is not found and parameter 'create' is 143fd9a0a45Sdanielk1977 ** true, then create a new entry. Otherwise return NULL. 144fd9a0a45Sdanielk1977 ** 145fd9a0a45Sdanielk1977 ** Each pointer stored in the sqlite3.aCollSeq hash table contains an 146fd9a0a45Sdanielk1977 ** array of three CollSeq structures. The first is the collation sequence 147fd9a0a45Sdanielk1977 ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. 148fd9a0a45Sdanielk1977 ** 149fd9a0a45Sdanielk1977 ** Stored immediately after the three collation sequences is a copy of 150fd9a0a45Sdanielk1977 ** the collation sequence name. A pointer to this string is stored in 151fd9a0a45Sdanielk1977 ** each collation sequence structure. 152fd9a0a45Sdanielk1977 */ 153fd9a0a45Sdanielk1977 static CollSeq *findCollSeqEntry( 154c4a64facSdrh sqlite3 *db, /* Database connection */ 155c4a64facSdrh const char *zName, /* Name of the collating sequence */ 156c4a64facSdrh int create /* Create a new entry if true */ 157fd9a0a45Sdanielk1977 ){ 158fd9a0a45Sdanielk1977 CollSeq *pColl; 159c4a64facSdrh int nName = sqlite3Strlen30(zName); 160fd9a0a45Sdanielk1977 pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); 161fd9a0a45Sdanielk1977 162fd9a0a45Sdanielk1977 if( 0==pColl && create ){ 16317435752Sdrh pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); 164fd9a0a45Sdanielk1977 if( pColl ){ 165fd9a0a45Sdanielk1977 CollSeq *pDel = 0; 166fd9a0a45Sdanielk1977 pColl[0].zName = (char*)&pColl[3]; 167fd9a0a45Sdanielk1977 pColl[0].enc = SQLITE_UTF8; 168fd9a0a45Sdanielk1977 pColl[1].zName = (char*)&pColl[3]; 169fd9a0a45Sdanielk1977 pColl[1].enc = SQLITE_UTF16LE; 170fd9a0a45Sdanielk1977 pColl[2].zName = (char*)&pColl[3]; 171fd9a0a45Sdanielk1977 pColl[2].enc = SQLITE_UTF16BE; 172fd9a0a45Sdanielk1977 memcpy(pColl[0].zName, zName, nName); 173fd9a0a45Sdanielk1977 pColl[0].zName[nName] = 0; 174fd9a0a45Sdanielk1977 pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); 175fd9a0a45Sdanielk1977 176be217793Sshane /* If a malloc() failure occurred in sqlite3HashInsert(), it will 177fd9a0a45Sdanielk1977 ** return the pColl pointer to be deleted (because it wasn't added 178fd9a0a45Sdanielk1977 ** to the hash table). 179fd9a0a45Sdanielk1977 */ 180f3a65f7eSdrh assert( pDel==0 || pDel==pColl ); 181f3a65f7eSdrh if( pDel!=0 ){ 182f3a65f7eSdrh db->mallocFailed = 1; 183633e6d57Sdrh sqlite3DbFree(db, pDel); 18491171cdeSdrh pColl = 0; 18591171cdeSdrh } 186fd9a0a45Sdanielk1977 } 187fd9a0a45Sdanielk1977 } 188fd9a0a45Sdanielk1977 return pColl; 189fd9a0a45Sdanielk1977 } 190fd9a0a45Sdanielk1977 191fd9a0a45Sdanielk1977 /* 192fd9a0a45Sdanielk1977 ** Parameter zName points to a UTF-8 encoded string nName bytes long. 193fd9a0a45Sdanielk1977 ** Return the CollSeq* pointer for the collation sequence named zName 194fd9a0a45Sdanielk1977 ** for the encoding 'enc' from the database 'db'. 195fd9a0a45Sdanielk1977 ** 196fd9a0a45Sdanielk1977 ** If the entry specified is not found and 'create' is true, then create a 197fd9a0a45Sdanielk1977 ** new entry. Otherwise return NULL. 198a34001c9Sdrh ** 199a34001c9Sdrh ** A separate function sqlite3LocateCollSeq() is a wrapper around 200a34001c9Sdrh ** this routine. sqlite3LocateCollSeq() invokes the collation factory 201a34001c9Sdrh ** if necessary and generates an error message if the collating sequence 202a34001c9Sdrh ** cannot be found. 203c4a64facSdrh ** 204c4a64facSdrh ** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() 205fd9a0a45Sdanielk1977 */ 206fd9a0a45Sdanielk1977 CollSeq *sqlite3FindCollSeq( 207fd9a0a45Sdanielk1977 sqlite3 *db, 208fd9a0a45Sdanielk1977 u8 enc, 209fd9a0a45Sdanielk1977 const char *zName, 210fd9a0a45Sdanielk1977 int create 211fd9a0a45Sdanielk1977 ){ 212b3bf556eSdanielk1977 CollSeq *pColl; 213b3bf556eSdanielk1977 if( zName ){ 214c4a64facSdrh pColl = findCollSeqEntry(db, zName, create); 215b3bf556eSdanielk1977 }else{ 216b3bf556eSdanielk1977 pColl = db->pDfltColl; 217b3bf556eSdanielk1977 } 218fd9a0a45Sdanielk1977 assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); 219fd9a0a45Sdanielk1977 assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); 220fd9a0a45Sdanielk1977 if( pColl ) pColl += enc-1; 221fd9a0a45Sdanielk1977 return pColl; 222fd9a0a45Sdanielk1977 } 223fd9a0a45Sdanielk1977 2248c0a791aSdanielk1977 /* During the search for the best function definition, this procedure 2258c0a791aSdanielk1977 ** is called to test how well the function passed as the first argument 2268c0a791aSdanielk1977 ** matches the request for a function with nArg arguments in a system 2278c0a791aSdanielk1977 ** that uses encoding enc. The value returned indicates how well the 2288c0a791aSdanielk1977 ** request is matched. A higher value indicates a better match. 2298c0a791aSdanielk1977 ** 230dfbc3a8aSdrh ** The returned value is always between 0 and 6, as follows: 2318c0a791aSdanielk1977 ** 232dfbc3a8aSdrh ** 0: Not a match, or if nArg<0 and the function is has no implementation. 2338c0a791aSdanielk1977 ** 1: A variable arguments function that prefers UTF-8 when a UTF-16 2348c0a791aSdanielk1977 ** encoding is requested, or vice versa. 2358c0a791aSdanielk1977 ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is 2368c0a791aSdanielk1977 ** requested, or vice versa. 2378c0a791aSdanielk1977 ** 3: A variable arguments function using the same text encoding. 2388c0a791aSdanielk1977 ** 4: A function with the exact number of arguments requested that 2398c0a791aSdanielk1977 ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. 2408c0a791aSdanielk1977 ** 5: A function with the exact number of arguments requested that 2418c0a791aSdanielk1977 ** prefers UTF-16LE when UTF-16BE is requested, or vice versa. 2428c0a791aSdanielk1977 ** 6: An exact match. 2438c0a791aSdanielk1977 ** 2448c0a791aSdanielk1977 */ 2458c0a791aSdanielk1977 static int matchQuality(FuncDef *p, int nArg, u8 enc){ 2468c0a791aSdanielk1977 int match = 0; 247dfbc3a8aSdrh if( p->nArg==-1 || p->nArg==nArg 248dfbc3a8aSdrh || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0)) 249dfbc3a8aSdrh ){ 2508c0a791aSdanielk1977 match = 1; 2518c0a791aSdanielk1977 if( p->nArg==nArg || nArg==-1 ){ 2528c0a791aSdanielk1977 match = 4; 2538c0a791aSdanielk1977 } 2548c0a791aSdanielk1977 if( enc==p->iPrefEnc ){ 2558c0a791aSdanielk1977 match += 2; 2568c0a791aSdanielk1977 } 2578c0a791aSdanielk1977 else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || 2588c0a791aSdanielk1977 (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ 2598c0a791aSdanielk1977 match += 1; 2608c0a791aSdanielk1977 } 2618c0a791aSdanielk1977 } 2628c0a791aSdanielk1977 return match; 2638c0a791aSdanielk1977 } 2648c0a791aSdanielk1977 265fd9a0a45Sdanielk1977 /* 26670a8ca3cSdrh ** Search a FuncDefHash for a function with the given name. Return 26770a8ca3cSdrh ** a pointer to the matching FuncDef if found, or 0 if there is no match. 26870a8ca3cSdrh */ 26970a8ca3cSdrh static FuncDef *functionSearch( 27070a8ca3cSdrh FuncDefHash *pHash, /* Hash table to search */ 27170a8ca3cSdrh int h, /* Hash of the name */ 27270a8ca3cSdrh const char *zFunc, /* Name of function */ 27370a8ca3cSdrh int nFunc /* Number of bytes in zFunc */ 27470a8ca3cSdrh ){ 27570a8ca3cSdrh FuncDef *p; 27670a8ca3cSdrh for(p=pHash->a[h]; p; p=p->pHash){ 27770a8ca3cSdrh if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){ 27870a8ca3cSdrh return p; 27970a8ca3cSdrh } 28070a8ca3cSdrh } 28170a8ca3cSdrh return 0; 28270a8ca3cSdrh } 28370a8ca3cSdrh 28470a8ca3cSdrh /* 28570a8ca3cSdrh ** Insert a new FuncDef into a FuncDefHash hash table. 28670a8ca3cSdrh */ 28770a8ca3cSdrh void sqlite3FuncDefInsert( 28870a8ca3cSdrh FuncDefHash *pHash, /* The hash table into which to insert */ 28970a8ca3cSdrh FuncDef *pDef /* The function definition to insert */ 29070a8ca3cSdrh ){ 29170a8ca3cSdrh FuncDef *pOther; 292ea678832Sdrh int nName = sqlite3Strlen30(pDef->zName); 29370a8ca3cSdrh u8 c1 = (u8)pDef->zName[0]; 29470a8ca3cSdrh int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a); 29570a8ca3cSdrh pOther = functionSearch(pHash, h, pDef->zName, nName); 29670a8ca3cSdrh if( pOther ){ 297*7aaa8786Sdrh assert( pOther!=pDef && pOther->pNext!=pDef ); 29870a8ca3cSdrh pDef->pNext = pOther->pNext; 29970a8ca3cSdrh pOther->pNext = pDef; 30070a8ca3cSdrh }else{ 30170a8ca3cSdrh pDef->pNext = 0; 30270a8ca3cSdrh pDef->pHash = pHash->a[h]; 30370a8ca3cSdrh pHash->a[h] = pDef; 30470a8ca3cSdrh } 30570a8ca3cSdrh } 30670a8ca3cSdrh 30770a8ca3cSdrh 30870a8ca3cSdrh 30970a8ca3cSdrh /* 310fd9a0a45Sdanielk1977 ** Locate a user function given a name, a number of arguments and a flag 311fd9a0a45Sdanielk1977 ** indicating whether the function prefers UTF-16 over UTF-8. Return a 312fd9a0a45Sdanielk1977 ** pointer to the FuncDef structure that defines that function, or return 313fd9a0a45Sdanielk1977 ** NULL if the function does not exist. 314fd9a0a45Sdanielk1977 ** 315fd9a0a45Sdanielk1977 ** If the createFlag argument is true, then a new (blank) FuncDef 316fd9a0a45Sdanielk1977 ** structure is created and liked into the "db" structure if a 317fd9a0a45Sdanielk1977 ** no matching function previously existed. When createFlag is true 318fd9a0a45Sdanielk1977 ** and the nArg parameter is -1, then only a function that accepts 319fd9a0a45Sdanielk1977 ** any number of arguments will be returned. 320fd9a0a45Sdanielk1977 ** 321fd9a0a45Sdanielk1977 ** If createFlag is false and nArg is -1, then the first valid 322fd9a0a45Sdanielk1977 ** function found is returned. A function is valid if either xFunc 323fd9a0a45Sdanielk1977 ** or xStep is non-zero. 324fd9a0a45Sdanielk1977 ** 325fd9a0a45Sdanielk1977 ** If createFlag is false, then a function with the required name and 326fd9a0a45Sdanielk1977 ** number of arguments may be returned even if the eTextRep flag does not 327fd9a0a45Sdanielk1977 ** match that requested. 328fd9a0a45Sdanielk1977 */ 329fd9a0a45Sdanielk1977 FuncDef *sqlite3FindFunction( 330fd9a0a45Sdanielk1977 sqlite3 *db, /* An open database */ 331fd9a0a45Sdanielk1977 const char *zName, /* Name of the function. Not null-terminated */ 332fd9a0a45Sdanielk1977 int nName, /* Number of characters in the name */ 333fd9a0a45Sdanielk1977 int nArg, /* Number of arguments. -1 means any number */ 334fd9a0a45Sdanielk1977 u8 enc, /* Preferred text encoding */ 335fd9a0a45Sdanielk1977 int createFlag /* Create new entry if true and does not otherwise exist */ 336fd9a0a45Sdanielk1977 ){ 337fd9a0a45Sdanielk1977 FuncDef *p; /* Iterator variable */ 338fd9a0a45Sdanielk1977 FuncDef *pBest = 0; /* Best match found so far */ 33970a8ca3cSdrh int bestScore = 0; /* Score of best match */ 34070a8ca3cSdrh int h; /* Hash value */ 341fd9a0a45Sdanielk1977 342fd9a0a45Sdanielk1977 343fd9a0a45Sdanielk1977 assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); 344fd9a0a45Sdanielk1977 if( nArg<-1 ) nArg = -1; 34570a8ca3cSdrh h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); 346fd9a0a45Sdanielk1977 347e3602be8Sdrh /* First search for a match amongst the application-defined functions. 348e3602be8Sdrh */ 34970a8ca3cSdrh p = functionSearch(&db->aFunc, h, zName, nName); 35070a8ca3cSdrh while( p ){ 35170a8ca3cSdrh int score = matchQuality(p, nArg, enc); 35270a8ca3cSdrh if( score>bestScore ){ 353fd9a0a45Sdanielk1977 pBest = p; 35470a8ca3cSdrh bestScore = score; 355fd9a0a45Sdanielk1977 } 35670a8ca3cSdrh p = p->pNext; 357fd9a0a45Sdanielk1977 } 3588c0a791aSdanielk1977 359e3602be8Sdrh /* If no match is found, search the built-in functions. 360e3602be8Sdrh ** 361e3602be8Sdrh ** Except, if createFlag is true, that means that we are trying to 362e3602be8Sdrh ** install a new function. Whatever FuncDef structure is returned will 363e3602be8Sdrh ** have fields overwritten with new information appropriate for the 364e3602be8Sdrh ** new function. But the FuncDefs for built-in functions are read-only. 365e3602be8Sdrh ** So we must not search for built-ins when creating a new function. 3668c0a791aSdanielk1977 */ 3678c0a791aSdanielk1977 if( !createFlag && !pBest ){ 368075c23afSdanielk1977 FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); 369075c23afSdanielk1977 p = functionSearch(pHash, h, zName, nName); 37070a8ca3cSdrh while( p ){ 37170a8ca3cSdrh int score = matchQuality(p, nArg, enc); 37270a8ca3cSdrh if( score>bestScore ){ 37370a8ca3cSdrh pBest = p; 37470a8ca3cSdrh bestScore = score; 3758c0a791aSdanielk1977 } 37670a8ca3cSdrh p = p->pNext; 3778c0a791aSdanielk1977 } 378fd9a0a45Sdanielk1977 } 379fd9a0a45Sdanielk1977 380e3602be8Sdrh /* If the createFlag parameter is true and the search did not reveal an 381fd9a0a45Sdanielk1977 ** exact match for the name, number of arguments and encoding, then add a 382fd9a0a45Sdanielk1977 ** new entry to the hash table and return it. 383fd9a0a45Sdanielk1977 */ 384e3602be8Sdrh if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && 3858c0a791aSdanielk1977 (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ 3868c0a791aSdanielk1977 pBest->zName = (char *)&pBest[1]; 3871bd10f8aSdrh pBest->nArg = (u16)nArg; 388fd9a0a45Sdanielk1977 pBest->iPrefEnc = enc; 389fd9a0a45Sdanielk1977 memcpy(pBest->zName, zName, nName); 390fd9a0a45Sdanielk1977 pBest->zName[nName] = 0; 39170a8ca3cSdrh sqlite3FuncDefInsert(&db->aFunc, pBest); 392fd9a0a45Sdanielk1977 } 393fd9a0a45Sdanielk1977 394fd9a0a45Sdanielk1977 if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ 395fd9a0a45Sdanielk1977 return pBest; 396fd9a0a45Sdanielk1977 } 397fd9a0a45Sdanielk1977 return 0; 398fd9a0a45Sdanielk1977 } 39903b808a6Sdrh 40003b808a6Sdrh /* 40103b808a6Sdrh ** Free all resources held by the schema structure. The void* argument points 402633e6d57Sdrh ** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the 40303b808a6Sdrh ** pointer itself, it just cleans up subsiduary resources (i.e. the contents 40403b808a6Sdrh ** of the schema hash tables). 4058cf6c554Sdanielk1977 ** 4068cf6c554Sdanielk1977 ** The Schema.cache_size variable is not cleared. 40703b808a6Sdrh */ 40803b808a6Sdrh void sqlite3SchemaFree(void *p){ 40903b808a6Sdrh Hash temp1; 41003b808a6Sdrh Hash temp2; 41103b808a6Sdrh HashElem *pElem; 41203b808a6Sdrh Schema *pSchema = (Schema *)p; 41303b808a6Sdrh 41403b808a6Sdrh temp1 = pSchema->tblHash; 41503b808a6Sdrh temp2 = pSchema->trigHash; 416e61922a6Sdrh sqlite3HashInit(&pSchema->trigHash); 41703b808a6Sdrh sqlite3HashClear(&pSchema->idxHash); 41803b808a6Sdrh for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ 419633e6d57Sdrh sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); 42003b808a6Sdrh } 42103b808a6Sdrh sqlite3HashClear(&temp2); 422e61922a6Sdrh sqlite3HashInit(&pSchema->tblHash); 42303b808a6Sdrh for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ 42403b808a6Sdrh Table *pTab = sqliteHashData(pElem); 425d9da78a2Sdrh assert( pTab->dbMem==0 ); 426a04a34ffSdanielk1977 sqlite3DeleteTable(pTab); 42703b808a6Sdrh } 42803b808a6Sdrh sqlite3HashClear(&temp1); 42903b808a6Sdrh pSchema->pSeqTab = 0; 43003b808a6Sdrh pSchema->flags &= ~DB_SchemaLoaded; 43103b808a6Sdrh } 43203b808a6Sdrh 43303b808a6Sdrh /* 43403b808a6Sdrh ** Find and return the schema associated with a BTree. Create 43503b808a6Sdrh ** a new one if necessary. 43603b808a6Sdrh */ 43717435752Sdrh Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ 43803b808a6Sdrh Schema * p; 43903b808a6Sdrh if( pBt ){ 44003b808a6Sdrh p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree); 44103b808a6Sdrh }else{ 442a1644fd8Sdanielk1977 p = (Schema *)sqlite3MallocZero(sizeof(Schema)); 44303b808a6Sdrh } 444a1644fd8Sdanielk1977 if( !p ){ 445a1644fd8Sdanielk1977 db->mallocFailed = 1; 446a1644fd8Sdanielk1977 }else if ( 0==p->file_format ){ 447e61922a6Sdrh sqlite3HashInit(&p->tblHash); 448e61922a6Sdrh sqlite3HashInit(&p->idxHash); 449e61922a6Sdrh sqlite3HashInit(&p->trigHash); 450f012ea3bSdrh p->enc = SQLITE_UTF8; 45103b808a6Sdrh } 45203b808a6Sdrh return p; 45303b808a6Sdrh } 454