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*b21c8cd4Sdrh ** $Id: callback.c,v 1.21 2007/08/21 19:33:56 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 */ 264dade037Sdanielk1977 static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ 274dade037Sdanielk1977 assert( !db->xCollNeeded || !db->xCollNeeded16 ); 284dade037Sdanielk1977 if( nName<0 ) nName = strlen(zName); 294dade037Sdanielk1977 if( db->xCollNeeded ){ 3017435752Sdrh char *zExternal = sqlite3DbStrNDup(db, zName, nName); 314dade037Sdanielk1977 if( !zExternal ) return; 3214db2665Sdanielk1977 db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal); 3317435752Sdrh sqlite3_free(zExternal); 344dade037Sdanielk1977 } 354dade037Sdanielk1977 #ifndef SQLITE_OMIT_UTF16 364dade037Sdanielk1977 if( db->xCollNeeded16 ){ 374dade037Sdanielk1977 char const *zExternal; 381e536953Sdanielk1977 sqlite3_value *pTmp = sqlite3ValueNew(db); 39*b21c8cd4Sdrh sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC); 40*b21c8cd4Sdrh zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); 4126abcb1eSdrh if( zExternal ){ 4214db2665Sdanielk1977 db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); 434dade037Sdanielk1977 } 4426abcb1eSdrh sqlite3ValueFree(pTmp); 4526abcb1eSdrh } 464dade037Sdanielk1977 #endif 474dade037Sdanielk1977 } 484dade037Sdanielk1977 494dade037Sdanielk1977 /* 504dade037Sdanielk1977 ** This routine is called if the collation factory fails to deliver a 514dade037Sdanielk1977 ** collation function in the best encoding but there may be other versions 524dade037Sdanielk1977 ** of this collation function (for other text encodings) available. Use one 534dade037Sdanielk1977 ** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if 544dade037Sdanielk1977 ** possible. 554dade037Sdanielk1977 */ 564dade037Sdanielk1977 static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ 574dade037Sdanielk1977 CollSeq *pColl2; 584dade037Sdanielk1977 char *z = pColl->zName; 594dade037Sdanielk1977 int n = strlen(z); 604dade037Sdanielk1977 int i; 614dade037Sdanielk1977 static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; 624dade037Sdanielk1977 for(i=0; i<3; i++){ 634dade037Sdanielk1977 pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0); 644dade037Sdanielk1977 if( pColl2->xCmp!=0 ){ 654dade037Sdanielk1977 memcpy(pColl, pColl2, sizeof(CollSeq)); 66a9808b31Sdanielk1977 pColl->xDel = 0; /* Do not copy the destructor */ 674dade037Sdanielk1977 return SQLITE_OK; 684dade037Sdanielk1977 } 694dade037Sdanielk1977 } 704dade037Sdanielk1977 return SQLITE_ERROR; 714dade037Sdanielk1977 } 724dade037Sdanielk1977 734dade037Sdanielk1977 /* 744dade037Sdanielk1977 ** This function is responsible for invoking the collation factory callback 754dade037Sdanielk1977 ** or substituting a collation sequence of a different encoding when the 764dade037Sdanielk1977 ** requested collation sequence is not available in the database native 774dade037Sdanielk1977 ** encoding. 784dade037Sdanielk1977 ** 794dade037Sdanielk1977 ** If it is not NULL, then pColl must point to the database native encoding 804dade037Sdanielk1977 ** collation sequence with name zName, length nName. 814dade037Sdanielk1977 ** 824dade037Sdanielk1977 ** The return value is either the collation sequence to be used in database 834dade037Sdanielk1977 ** db for collation type name zName, length nName, or NULL, if no collation 844dade037Sdanielk1977 ** sequence can be found. 854dade037Sdanielk1977 */ 864dade037Sdanielk1977 CollSeq *sqlite3GetCollSeq( 874dade037Sdanielk1977 sqlite3* db, 884dade037Sdanielk1977 CollSeq *pColl, 894dade037Sdanielk1977 const char *zName, 904dade037Sdanielk1977 int nName 914dade037Sdanielk1977 ){ 924dade037Sdanielk1977 CollSeq *p; 934dade037Sdanielk1977 944dade037Sdanielk1977 p = pColl; 954dade037Sdanielk1977 if( !p ){ 9614db2665Sdanielk1977 p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0); 974dade037Sdanielk1977 } 984dade037Sdanielk1977 if( !p || !p->xCmp ){ 994dade037Sdanielk1977 /* No collation sequence of this type for this encoding is registered. 1004dade037Sdanielk1977 ** Call the collation factory to see if it can supply us with one. 1014dade037Sdanielk1977 */ 1024dade037Sdanielk1977 callCollNeeded(db, zName, nName); 10314db2665Sdanielk1977 p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0); 1044dade037Sdanielk1977 } 1054dade037Sdanielk1977 if( p && !p->xCmp && synthCollSeq(db, p) ){ 1064dade037Sdanielk1977 p = 0; 1074dade037Sdanielk1977 } 1084dade037Sdanielk1977 assert( !p || p->xCmp ); 1094dade037Sdanielk1977 return p; 1104dade037Sdanielk1977 } 1114dade037Sdanielk1977 1124dade037Sdanielk1977 /* 1134dade037Sdanielk1977 ** This routine is called on a collation sequence before it is used to 1144dade037Sdanielk1977 ** check that it is defined. An undefined collation sequence exists when 1154dade037Sdanielk1977 ** a database is loaded that contains references to collation sequences 1164dade037Sdanielk1977 ** that have not been defined by sqlite3_create_collation() etc. 1174dade037Sdanielk1977 ** 1184dade037Sdanielk1977 ** If required, this routine calls the 'collation needed' callback to 1194dade037Sdanielk1977 ** request a definition of the collating sequence. If this doesn't work, 1204dade037Sdanielk1977 ** an equivalent collating sequence that uses a text encoding different 1214dade037Sdanielk1977 ** from the main database is substituted, if one is available. 1224dade037Sdanielk1977 */ 1234dade037Sdanielk1977 int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ 1244dade037Sdanielk1977 if( pColl ){ 1254dade037Sdanielk1977 const char *zName = pColl->zName; 1264dade037Sdanielk1977 CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1); 1274dade037Sdanielk1977 if( !p ){ 1284dade037Sdanielk1977 if( pParse->nErr==0 ){ 1294dade037Sdanielk1977 sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); 1304dade037Sdanielk1977 } 1314dade037Sdanielk1977 pParse->nErr++; 1324dade037Sdanielk1977 return SQLITE_ERROR; 1334dade037Sdanielk1977 } 134b3bf556eSdanielk1977 assert( p==pColl ); 1354dade037Sdanielk1977 } 1364dade037Sdanielk1977 return SQLITE_OK; 1374dade037Sdanielk1977 } 1384dade037Sdanielk1977 1394dade037Sdanielk1977 1404dade037Sdanielk1977 1414dade037Sdanielk1977 /* 142fd9a0a45Sdanielk1977 ** Locate and return an entry from the db.aCollSeq hash table. If the entry 143fd9a0a45Sdanielk1977 ** specified by zName and nName is not found and parameter 'create' is 144fd9a0a45Sdanielk1977 ** true, then create a new entry. Otherwise return NULL. 145fd9a0a45Sdanielk1977 ** 146fd9a0a45Sdanielk1977 ** Each pointer stored in the sqlite3.aCollSeq hash table contains an 147fd9a0a45Sdanielk1977 ** array of three CollSeq structures. The first is the collation sequence 148fd9a0a45Sdanielk1977 ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. 149fd9a0a45Sdanielk1977 ** 150fd9a0a45Sdanielk1977 ** Stored immediately after the three collation sequences is a copy of 151fd9a0a45Sdanielk1977 ** the collation sequence name. A pointer to this string is stored in 152fd9a0a45Sdanielk1977 ** each collation sequence structure. 153fd9a0a45Sdanielk1977 */ 154fd9a0a45Sdanielk1977 static CollSeq *findCollSeqEntry( 155fd9a0a45Sdanielk1977 sqlite3 *db, 156fd9a0a45Sdanielk1977 const char *zName, 157fd9a0a45Sdanielk1977 int nName, 158fd9a0a45Sdanielk1977 int create 159fd9a0a45Sdanielk1977 ){ 160fd9a0a45Sdanielk1977 CollSeq *pColl; 161fd9a0a45Sdanielk1977 if( nName<0 ) nName = strlen(zName); 162fd9a0a45Sdanielk1977 pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); 163fd9a0a45Sdanielk1977 164fd9a0a45Sdanielk1977 if( 0==pColl && create ){ 16517435752Sdrh pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); 166fd9a0a45Sdanielk1977 if( pColl ){ 167fd9a0a45Sdanielk1977 CollSeq *pDel = 0; 168fd9a0a45Sdanielk1977 pColl[0].zName = (char*)&pColl[3]; 169fd9a0a45Sdanielk1977 pColl[0].enc = SQLITE_UTF8; 170fd9a0a45Sdanielk1977 pColl[1].zName = (char*)&pColl[3]; 171fd9a0a45Sdanielk1977 pColl[1].enc = SQLITE_UTF16LE; 172fd9a0a45Sdanielk1977 pColl[2].zName = (char*)&pColl[3]; 173fd9a0a45Sdanielk1977 pColl[2].enc = SQLITE_UTF16BE; 174fd9a0a45Sdanielk1977 memcpy(pColl[0].zName, zName, nName); 175fd9a0a45Sdanielk1977 pColl[0].zName[nName] = 0; 176fd9a0a45Sdanielk1977 pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); 177fd9a0a45Sdanielk1977 178fd9a0a45Sdanielk1977 /* If a malloc() failure occured in sqlite3HashInsert(), it will 179fd9a0a45Sdanielk1977 ** return the pColl pointer to be deleted (because it wasn't added 180fd9a0a45Sdanielk1977 ** to the hash table). 181fd9a0a45Sdanielk1977 */ 18217435752Sdrh assert( !pDel || (db->mallocFailed && pDel==pColl) ); 18391171cdeSdrh if( pDel ){ 18417435752Sdrh sqlite3_free(pDel); 18591171cdeSdrh pColl = 0; 18691171cdeSdrh } 187fd9a0a45Sdanielk1977 } 188fd9a0a45Sdanielk1977 } 189fd9a0a45Sdanielk1977 return pColl; 190fd9a0a45Sdanielk1977 } 191fd9a0a45Sdanielk1977 192fd9a0a45Sdanielk1977 /* 193fd9a0a45Sdanielk1977 ** Parameter zName points to a UTF-8 encoded string nName bytes long. 194fd9a0a45Sdanielk1977 ** Return the CollSeq* pointer for the collation sequence named zName 195fd9a0a45Sdanielk1977 ** for the encoding 'enc' from the database 'db'. 196fd9a0a45Sdanielk1977 ** 197fd9a0a45Sdanielk1977 ** If the entry specified is not found and 'create' is true, then create a 198fd9a0a45Sdanielk1977 ** new entry. Otherwise return NULL. 199a34001c9Sdrh ** 200a34001c9Sdrh ** A separate function sqlite3LocateCollSeq() is a wrapper around 201a34001c9Sdrh ** this routine. sqlite3LocateCollSeq() invokes the collation factory 202a34001c9Sdrh ** if necessary and generates an error message if the collating sequence 203a34001c9Sdrh ** cannot be found. 204fd9a0a45Sdanielk1977 */ 205fd9a0a45Sdanielk1977 CollSeq *sqlite3FindCollSeq( 206fd9a0a45Sdanielk1977 sqlite3 *db, 207fd9a0a45Sdanielk1977 u8 enc, 208fd9a0a45Sdanielk1977 const char *zName, 209fd9a0a45Sdanielk1977 int nName, 210fd9a0a45Sdanielk1977 int create 211fd9a0a45Sdanielk1977 ){ 212b3bf556eSdanielk1977 CollSeq *pColl; 213b3bf556eSdanielk1977 if( zName ){ 214b3bf556eSdanielk1977 pColl = findCollSeqEntry(db, zName, nName, 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 224fd9a0a45Sdanielk1977 /* 225fd9a0a45Sdanielk1977 ** Locate a user function given a name, a number of arguments and a flag 226fd9a0a45Sdanielk1977 ** indicating whether the function prefers UTF-16 over UTF-8. Return a 227fd9a0a45Sdanielk1977 ** pointer to the FuncDef structure that defines that function, or return 228fd9a0a45Sdanielk1977 ** NULL if the function does not exist. 229fd9a0a45Sdanielk1977 ** 230fd9a0a45Sdanielk1977 ** If the createFlag argument is true, then a new (blank) FuncDef 231fd9a0a45Sdanielk1977 ** structure is created and liked into the "db" structure if a 232fd9a0a45Sdanielk1977 ** no matching function previously existed. When createFlag is true 233fd9a0a45Sdanielk1977 ** and the nArg parameter is -1, then only a function that accepts 234fd9a0a45Sdanielk1977 ** any number of arguments will be returned. 235fd9a0a45Sdanielk1977 ** 236fd9a0a45Sdanielk1977 ** If createFlag is false and nArg is -1, then the first valid 237fd9a0a45Sdanielk1977 ** function found is returned. A function is valid if either xFunc 238fd9a0a45Sdanielk1977 ** or xStep is non-zero. 239fd9a0a45Sdanielk1977 ** 240fd9a0a45Sdanielk1977 ** If createFlag is false, then a function with the required name and 241fd9a0a45Sdanielk1977 ** number of arguments may be returned even if the eTextRep flag does not 242fd9a0a45Sdanielk1977 ** match that requested. 243fd9a0a45Sdanielk1977 */ 244fd9a0a45Sdanielk1977 FuncDef *sqlite3FindFunction( 245fd9a0a45Sdanielk1977 sqlite3 *db, /* An open database */ 246fd9a0a45Sdanielk1977 const char *zName, /* Name of the function. Not null-terminated */ 247fd9a0a45Sdanielk1977 int nName, /* Number of characters in the name */ 248fd9a0a45Sdanielk1977 int nArg, /* Number of arguments. -1 means any number */ 249fd9a0a45Sdanielk1977 u8 enc, /* Preferred text encoding */ 250fd9a0a45Sdanielk1977 int createFlag /* Create new entry if true and does not otherwise exist */ 251fd9a0a45Sdanielk1977 ){ 252fd9a0a45Sdanielk1977 FuncDef *p; /* Iterator variable */ 253fd9a0a45Sdanielk1977 FuncDef *pFirst; /* First function with this name */ 254fd9a0a45Sdanielk1977 FuncDef *pBest = 0; /* Best match found so far */ 255fd9a0a45Sdanielk1977 int bestmatch = 0; 256fd9a0a45Sdanielk1977 257fd9a0a45Sdanielk1977 258fd9a0a45Sdanielk1977 assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); 259fd9a0a45Sdanielk1977 if( nArg<-1 ) nArg = -1; 260fd9a0a45Sdanielk1977 261fd9a0a45Sdanielk1977 pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName); 262fd9a0a45Sdanielk1977 for(p=pFirst; p; p=p->pNext){ 263fd9a0a45Sdanielk1977 /* During the search for the best function definition, bestmatch is set 264fd9a0a45Sdanielk1977 ** as follows to indicate the quality of the match with the definition 265fd9a0a45Sdanielk1977 ** pointed to by pBest: 266fd9a0a45Sdanielk1977 ** 267fd9a0a45Sdanielk1977 ** 0: pBest is NULL. No match has been found. 268fd9a0a45Sdanielk1977 ** 1: A variable arguments function that prefers UTF-8 when a UTF-16 269fd9a0a45Sdanielk1977 ** encoding is requested, or vice versa. 270fd9a0a45Sdanielk1977 ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is 271fd9a0a45Sdanielk1977 ** requested, or vice versa. 272fd9a0a45Sdanielk1977 ** 3: A variable arguments function using the same text encoding. 273fd9a0a45Sdanielk1977 ** 4: A function with the exact number of arguments requested that 274fd9a0a45Sdanielk1977 ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. 275fd9a0a45Sdanielk1977 ** 5: A function with the exact number of arguments requested that 276fd9a0a45Sdanielk1977 ** prefers UTF-16LE when UTF-16BE is requested, or vice versa. 277fd9a0a45Sdanielk1977 ** 6: An exact match. 278fd9a0a45Sdanielk1977 ** 279fd9a0a45Sdanielk1977 ** A larger value of 'matchqual' indicates a more desirable match. 280fd9a0a45Sdanielk1977 */ 281fd9a0a45Sdanielk1977 if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){ 282fd9a0a45Sdanielk1977 int match = 1; /* Quality of this match */ 283fd9a0a45Sdanielk1977 if( p->nArg==nArg || nArg==-1 ){ 284fd9a0a45Sdanielk1977 match = 4; 285fd9a0a45Sdanielk1977 } 286fd9a0a45Sdanielk1977 if( enc==p->iPrefEnc ){ 287fd9a0a45Sdanielk1977 match += 2; 288fd9a0a45Sdanielk1977 } 289fd9a0a45Sdanielk1977 else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || 290fd9a0a45Sdanielk1977 (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ 291fd9a0a45Sdanielk1977 match += 1; 292fd9a0a45Sdanielk1977 } 293fd9a0a45Sdanielk1977 294fd9a0a45Sdanielk1977 if( match>bestmatch ){ 295fd9a0a45Sdanielk1977 pBest = p; 296fd9a0a45Sdanielk1977 bestmatch = match; 297fd9a0a45Sdanielk1977 } 298fd9a0a45Sdanielk1977 } 299fd9a0a45Sdanielk1977 } 300fd9a0a45Sdanielk1977 301fd9a0a45Sdanielk1977 /* If the createFlag parameter is true, and the seach did not reveal an 302fd9a0a45Sdanielk1977 ** exact match for the name, number of arguments and encoding, then add a 303fd9a0a45Sdanielk1977 ** new entry to the hash table and return it. 304fd9a0a45Sdanielk1977 */ 305fd9a0a45Sdanielk1977 if( createFlag && bestmatch<6 && 30617435752Sdrh (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName))!=0 ){ 307fd9a0a45Sdanielk1977 pBest->nArg = nArg; 308fd9a0a45Sdanielk1977 pBest->pNext = pFirst; 309fd9a0a45Sdanielk1977 pBest->iPrefEnc = enc; 310fd9a0a45Sdanielk1977 memcpy(pBest->zName, zName, nName); 311fd9a0a45Sdanielk1977 pBest->zName[nName] = 0; 312fd9a0a45Sdanielk1977 if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ 31317435752Sdrh sqlite3_free(pBest); 314fd9a0a45Sdanielk1977 return 0; 315fd9a0a45Sdanielk1977 } 316fd9a0a45Sdanielk1977 } 317fd9a0a45Sdanielk1977 318fd9a0a45Sdanielk1977 if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ 319fd9a0a45Sdanielk1977 return pBest; 320fd9a0a45Sdanielk1977 } 321fd9a0a45Sdanielk1977 return 0; 322fd9a0a45Sdanielk1977 } 32303b808a6Sdrh 32403b808a6Sdrh /* 32503b808a6Sdrh ** Free all resources held by the schema structure. The void* argument points 32617435752Sdrh ** at a Schema struct. This function does not call sqlite3_free() on the 32703b808a6Sdrh ** pointer itself, it just cleans up subsiduary resources (i.e. the contents 32803b808a6Sdrh ** of the schema hash tables). 32903b808a6Sdrh */ 33003b808a6Sdrh void sqlite3SchemaFree(void *p){ 33103b808a6Sdrh Hash temp1; 33203b808a6Sdrh Hash temp2; 33303b808a6Sdrh HashElem *pElem; 33403b808a6Sdrh Schema *pSchema = (Schema *)p; 33503b808a6Sdrh 33603b808a6Sdrh temp1 = pSchema->tblHash; 33703b808a6Sdrh temp2 = pSchema->trigHash; 33803b808a6Sdrh sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0); 33903b808a6Sdrh sqlite3HashClear(&pSchema->aFKey); 34003b808a6Sdrh sqlite3HashClear(&pSchema->idxHash); 34103b808a6Sdrh for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ 34203b808a6Sdrh sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem)); 34303b808a6Sdrh } 34403b808a6Sdrh sqlite3HashClear(&temp2); 34503b808a6Sdrh sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0); 34603b808a6Sdrh for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ 34703b808a6Sdrh Table *pTab = sqliteHashData(pElem); 348a04a34ffSdanielk1977 sqlite3DeleteTable(pTab); 34903b808a6Sdrh } 35003b808a6Sdrh sqlite3HashClear(&temp1); 35103b808a6Sdrh pSchema->pSeqTab = 0; 35203b808a6Sdrh pSchema->flags &= ~DB_SchemaLoaded; 35303b808a6Sdrh } 35403b808a6Sdrh 35503b808a6Sdrh /* 35603b808a6Sdrh ** Find and return the schema associated with a BTree. Create 35703b808a6Sdrh ** a new one if necessary. 35803b808a6Sdrh */ 35917435752Sdrh Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ 36003b808a6Sdrh Schema * p; 36103b808a6Sdrh if( pBt ){ 36203b808a6Sdrh p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree); 36303b808a6Sdrh }else{ 36417435752Sdrh p = (Schema *)sqlite3DbMallocZero(db,sizeof(Schema)); 36503b808a6Sdrh } 36603b808a6Sdrh if( p && 0==p->file_format ){ 36703b808a6Sdrh sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0); 36803b808a6Sdrh sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0); 36903b808a6Sdrh sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0); 37003b808a6Sdrh sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1); 371f012ea3bSdrh p->enc = SQLITE_UTF8; 37203b808a6Sdrh } 37303b808a6Sdrh return p; 37403b808a6Sdrh } 375