1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sql/SQLite364/callback.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,451 @@
1.4 +/*
1.5 +** 2005 May 23
1.6 +**
1.7 +** The author disclaims copyright to this source code. In place of
1.8 +** a legal notice, here is a blessing:
1.9 +**
1.10 +** May you do good and not evil.
1.11 +** May you find forgiveness for yourself and forgive others.
1.12 +** May you share freely, never taking more than you give.
1.13 +**
1.14 +*************************************************************************
1.15 +**
1.16 +** This file contains functions used to access the internal hash tables
1.17 +** of user defined functions and collation sequences.
1.18 +**
1.19 +** $Id: callback.c,v 1.32 2008/10/10 17:41:29 drh Exp $
1.20 +*/
1.21 +
1.22 +#include "sqliteInt.h"
1.23 +
1.24 +/*
1.25 +** Invoke the 'collation needed' callback to request a collation sequence
1.26 +** in the database text encoding of name zName, length nName.
1.27 +** If the collation sequence
1.28 +*/
1.29 +static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
1.30 + assert( !db->xCollNeeded || !db->xCollNeeded16 );
1.31 + if( nName<0 ) nName = sqlite3Strlen(db, zName);
1.32 + if( db->xCollNeeded ){
1.33 + char *zExternal = sqlite3DbStrNDup(db, zName, nName);
1.34 + if( !zExternal ) return;
1.35 + db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
1.36 + sqlite3DbFree(db, zExternal);
1.37 + }
1.38 +#ifndef SQLITE_OMIT_UTF16
1.39 + if( db->xCollNeeded16 ){
1.40 + char const *zExternal;
1.41 + sqlite3_value *pTmp = sqlite3ValueNew(db);
1.42 + sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
1.43 + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
1.44 + if( zExternal ){
1.45 + db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
1.46 + }
1.47 + sqlite3ValueFree(pTmp);
1.48 + }
1.49 +#endif
1.50 +}
1.51 +
1.52 +/*
1.53 +** This routine is called if the collation factory fails to deliver a
1.54 +** collation function in the best encoding but there may be other versions
1.55 +** of this collation function (for other text encodings) available. Use one
1.56 +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
1.57 +** possible.
1.58 +*/
1.59 +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
1.60 + CollSeq *pColl2;
1.61 + char *z = pColl->zName;
1.62 + int n = strlen(z);
1.63 + int i;
1.64 + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
1.65 + for(i=0; i<3; i++){
1.66 + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
1.67 + if( pColl2->xCmp!=0 ){
1.68 + memcpy(pColl, pColl2, sizeof(CollSeq));
1.69 + pColl->xDel = 0; /* Do not copy the destructor */
1.70 + return SQLITE_OK;
1.71 + }
1.72 + }
1.73 + return SQLITE_ERROR;
1.74 +}
1.75 +
1.76 +/*
1.77 +** This function is responsible for invoking the collation factory callback
1.78 +** or substituting a collation sequence of a different encoding when the
1.79 +** requested collation sequence is not available in the database native
1.80 +** encoding.
1.81 +**
1.82 +** If it is not NULL, then pColl must point to the database native encoding
1.83 +** collation sequence with name zName, length nName.
1.84 +**
1.85 +** The return value is either the collation sequence to be used in database
1.86 +** db for collation type name zName, length nName, or NULL, if no collation
1.87 +** sequence can be found.
1.88 +*/
1.89 +CollSeq *sqlite3GetCollSeq(
1.90 + sqlite3* db,
1.91 + CollSeq *pColl,
1.92 + const char *zName,
1.93 + int nName
1.94 +){
1.95 + CollSeq *p;
1.96 +
1.97 + p = pColl;
1.98 + if( !p ){
1.99 + p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
1.100 + }
1.101 + if( !p || !p->xCmp ){
1.102 + /* No collation sequence of this type for this encoding is registered.
1.103 + ** Call the collation factory to see if it can supply us with one.
1.104 + */
1.105 + callCollNeeded(db, zName, nName);
1.106 + p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
1.107 + }
1.108 + if( p && !p->xCmp && synthCollSeq(db, p) ){
1.109 + p = 0;
1.110 + }
1.111 + assert( !p || p->xCmp );
1.112 + return p;
1.113 +}
1.114 +
1.115 +/*
1.116 +** This routine is called on a collation sequence before it is used to
1.117 +** check that it is defined. An undefined collation sequence exists when
1.118 +** a database is loaded that contains references to collation sequences
1.119 +** that have not been defined by sqlite3_create_collation() etc.
1.120 +**
1.121 +** If required, this routine calls the 'collation needed' callback to
1.122 +** request a definition of the collating sequence. If this doesn't work,
1.123 +** an equivalent collating sequence that uses a text encoding different
1.124 +** from the main database is substituted, if one is available.
1.125 +*/
1.126 +int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
1.127 + if( pColl ){
1.128 + const char *zName = pColl->zName;
1.129 + CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
1.130 + if( !p ){
1.131 + if( pParse->nErr==0 ){
1.132 + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
1.133 + }
1.134 + pParse->nErr++;
1.135 + return SQLITE_ERROR;
1.136 + }
1.137 + assert( p==pColl );
1.138 + }
1.139 + return SQLITE_OK;
1.140 +}
1.141 +
1.142 +
1.143 +
1.144 +/*
1.145 +** Locate and return an entry from the db.aCollSeq hash table. If the entry
1.146 +** specified by zName and nName is not found and parameter 'create' is
1.147 +** true, then create a new entry. Otherwise return NULL.
1.148 +**
1.149 +** Each pointer stored in the sqlite3.aCollSeq hash table contains an
1.150 +** array of three CollSeq structures. The first is the collation sequence
1.151 +** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
1.152 +**
1.153 +** Stored immediately after the three collation sequences is a copy of
1.154 +** the collation sequence name. A pointer to this string is stored in
1.155 +** each collation sequence structure.
1.156 +*/
1.157 +static CollSeq *findCollSeqEntry(
1.158 + sqlite3 *db,
1.159 + const char *zName,
1.160 + int nName,
1.161 + int create
1.162 +){
1.163 + CollSeq *pColl;
1.164 + if( nName<0 ) nName = sqlite3Strlen(db, zName);
1.165 + pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
1.166 +
1.167 + if( 0==pColl && create ){
1.168 + pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
1.169 + if( pColl ){
1.170 + CollSeq *pDel = 0;
1.171 + pColl[0].zName = (char*)&pColl[3];
1.172 + pColl[0].enc = SQLITE_UTF8;
1.173 + pColl[1].zName = (char*)&pColl[3];
1.174 + pColl[1].enc = SQLITE_UTF16LE;
1.175 + pColl[2].zName = (char*)&pColl[3];
1.176 + pColl[2].enc = SQLITE_UTF16BE;
1.177 + memcpy(pColl[0].zName, zName, nName);
1.178 + pColl[0].zName[nName] = 0;
1.179 + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
1.180 +
1.181 + /* If a malloc() failure occured in sqlite3HashInsert(), it will
1.182 + ** return the pColl pointer to be deleted (because it wasn't added
1.183 + ** to the hash table).
1.184 + */
1.185 + assert( pDel==0 || pDel==pColl );
1.186 + if( pDel!=0 ){
1.187 + db->mallocFailed = 1;
1.188 + sqlite3DbFree(db, pDel);
1.189 + pColl = 0;
1.190 + }
1.191 + }
1.192 + }
1.193 + return pColl;
1.194 +}
1.195 +
1.196 +/*
1.197 +** Parameter zName points to a UTF-8 encoded string nName bytes long.
1.198 +** Return the CollSeq* pointer for the collation sequence named zName
1.199 +** for the encoding 'enc' from the database 'db'.
1.200 +**
1.201 +** If the entry specified is not found and 'create' is true, then create a
1.202 +** new entry. Otherwise return NULL.
1.203 +**
1.204 +** A separate function sqlite3LocateCollSeq() is a wrapper around
1.205 +** this routine. sqlite3LocateCollSeq() invokes the collation factory
1.206 +** if necessary and generates an error message if the collating sequence
1.207 +** cannot be found.
1.208 +*/
1.209 +CollSeq *sqlite3FindCollSeq(
1.210 + sqlite3 *db,
1.211 + u8 enc,
1.212 + const char *zName,
1.213 + int nName,
1.214 + int create
1.215 +){
1.216 + CollSeq *pColl;
1.217 + if( zName ){
1.218 + pColl = findCollSeqEntry(db, zName, nName, create);
1.219 + }else{
1.220 + pColl = db->pDfltColl;
1.221 + }
1.222 + assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
1.223 + assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
1.224 + if( pColl ) pColl += enc-1;
1.225 + return pColl;
1.226 +}
1.227 +
1.228 +/* During the search for the best function definition, this procedure
1.229 +** is called to test how well the function passed as the first argument
1.230 +** matches the request for a function with nArg arguments in a system
1.231 +** that uses encoding enc. The value returned indicates how well the
1.232 +** request is matched. A higher value indicates a better match.
1.233 +**
1.234 +** The returned value is always between 1 and 6, as follows:
1.235 +**
1.236 +** 1: A variable arguments function that prefers UTF-8 when a UTF-16
1.237 +** encoding is requested, or vice versa.
1.238 +** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
1.239 +** requested, or vice versa.
1.240 +** 3: A variable arguments function using the same text encoding.
1.241 +** 4: A function with the exact number of arguments requested that
1.242 +** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
1.243 +** 5: A function with the exact number of arguments requested that
1.244 +** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
1.245 +** 6: An exact match.
1.246 +**
1.247 +*/
1.248 +static int matchQuality(FuncDef *p, int nArg, u8 enc){
1.249 + int match = 0;
1.250 + if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
1.251 + match = 1;
1.252 + if( p->nArg==nArg || nArg==-1 ){
1.253 + match = 4;
1.254 + }
1.255 + if( enc==p->iPrefEnc ){
1.256 + match += 2;
1.257 + }
1.258 + else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
1.259 + (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
1.260 + match += 1;
1.261 + }
1.262 + }
1.263 + return match;
1.264 +}
1.265 +
1.266 +/*
1.267 +** Search a FuncDefHash for a function with the given name. Return
1.268 +** a pointer to the matching FuncDef if found, or 0 if there is no match.
1.269 +*/
1.270 +static FuncDef *functionSearch(
1.271 + FuncDefHash *pHash, /* Hash table to search */
1.272 + int h, /* Hash of the name */
1.273 + const char *zFunc, /* Name of function */
1.274 + int nFunc /* Number of bytes in zFunc */
1.275 +){
1.276 + FuncDef *p;
1.277 + for(p=pHash->a[h]; p; p=p->pHash){
1.278 + if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
1.279 + return p;
1.280 + }
1.281 + }
1.282 + return 0;
1.283 +}
1.284 +
1.285 +/*
1.286 +** Insert a new FuncDef into a FuncDefHash hash table.
1.287 +*/
1.288 +void sqlite3FuncDefInsert(
1.289 + FuncDefHash *pHash, /* The hash table into which to insert */
1.290 + FuncDef *pDef /* The function definition to insert */
1.291 +){
1.292 + FuncDef *pOther;
1.293 + int nName = strlen(pDef->zName);
1.294 + u8 c1 = (u8)pDef->zName[0];
1.295 + int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
1.296 + pOther = functionSearch(pHash, h, pDef->zName, nName);
1.297 + if( pOther ){
1.298 + pDef->pNext = pOther->pNext;
1.299 + pOther->pNext = pDef;
1.300 + }else{
1.301 + pDef->pNext = 0;
1.302 + pDef->pHash = pHash->a[h];
1.303 + pHash->a[h] = pDef;
1.304 + }
1.305 +}
1.306 +
1.307 +
1.308 +
1.309 +/*
1.310 +** Locate a user function given a name, a number of arguments and a flag
1.311 +** indicating whether the function prefers UTF-16 over UTF-8. Return a
1.312 +** pointer to the FuncDef structure that defines that function, or return
1.313 +** NULL if the function does not exist.
1.314 +**
1.315 +** If the createFlag argument is true, then a new (blank) FuncDef
1.316 +** structure is created and liked into the "db" structure if a
1.317 +** no matching function previously existed. When createFlag is true
1.318 +** and the nArg parameter is -1, then only a function that accepts
1.319 +** any number of arguments will be returned.
1.320 +**
1.321 +** If createFlag is false and nArg is -1, then the first valid
1.322 +** function found is returned. A function is valid if either xFunc
1.323 +** or xStep is non-zero.
1.324 +**
1.325 +** If createFlag is false, then a function with the required name and
1.326 +** number of arguments may be returned even if the eTextRep flag does not
1.327 +** match that requested.
1.328 +*/
1.329 +FuncDef *sqlite3FindFunction(
1.330 + sqlite3 *db, /* An open database */
1.331 + const char *zName, /* Name of the function. Not null-terminated */
1.332 + int nName, /* Number of characters in the name */
1.333 + int nArg, /* Number of arguments. -1 means any number */
1.334 + u8 enc, /* Preferred text encoding */
1.335 + int createFlag /* Create new entry if true and does not otherwise exist */
1.336 +){
1.337 + FuncDef *p; /* Iterator variable */
1.338 + FuncDef *pBest = 0; /* Best match found so far */
1.339 + int bestScore = 0; /* Score of best match */
1.340 + int h; /* Hash value */
1.341 +
1.342 +
1.343 + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
1.344 + if( nArg<-1 ) nArg = -1;
1.345 + h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
1.346 +
1.347 + /* First search for a match amongst the application-defined functions.
1.348 + */
1.349 + p = functionSearch(&db->aFunc, h, zName, nName);
1.350 + while( p ){
1.351 + int score = matchQuality(p, nArg, enc);
1.352 + if( score>bestScore ){
1.353 + pBest = p;
1.354 + bestScore = score;
1.355 + }
1.356 + p = p->pNext;
1.357 + }
1.358 +
1.359 + /* If no match is found, search the built-in functions.
1.360 + **
1.361 + ** Except, if createFlag is true, that means that we are trying to
1.362 + ** install a new function. Whatever FuncDef structure is returned will
1.363 + ** have fields overwritten with new information appropriate for the
1.364 + ** new function. But the FuncDefs for built-in functions are read-only.
1.365 + ** So we must not search for built-ins when creating a new function.
1.366 + */
1.367 + if( !createFlag && !pBest ){
1.368 + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
1.369 + p = functionSearch(pHash, h, zName, nName);
1.370 + while( p ){
1.371 + int score = matchQuality(p, nArg, enc);
1.372 + if( score>bestScore ){
1.373 + pBest = p;
1.374 + bestScore = score;
1.375 + }
1.376 + p = p->pNext;
1.377 + }
1.378 + }
1.379 +
1.380 + /* If the createFlag parameter is true and the search did not reveal an
1.381 + ** exact match for the name, number of arguments and encoding, then add a
1.382 + ** new entry to the hash table and return it.
1.383 + */
1.384 + if( createFlag && (bestScore<6 || pBest->nArg!=nArg) &&
1.385 + (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
1.386 + pBest->zName = (char *)&pBest[1];
1.387 + pBest->nArg = nArg;
1.388 + pBest->iPrefEnc = enc;
1.389 + memcpy(pBest->zName, zName, nName);
1.390 + pBest->zName[nName] = 0;
1.391 + sqlite3FuncDefInsert(&db->aFunc, pBest);
1.392 + }
1.393 +
1.394 + if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
1.395 + return pBest;
1.396 + }
1.397 + return 0;
1.398 +}
1.399 +
1.400 +/*
1.401 +** Free all resources held by the schema structure. The void* argument points
1.402 +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
1.403 +** pointer itself, it just cleans up subsiduary resources (i.e. the contents
1.404 +** of the schema hash tables).
1.405 +**
1.406 +** The Schema.cache_size variable is not cleared.
1.407 +*/
1.408 +void sqlite3SchemaFree(void *p){
1.409 + Hash temp1;
1.410 + Hash temp2;
1.411 + HashElem *pElem;
1.412 + Schema *pSchema = (Schema *)p;
1.413 +
1.414 + temp1 = pSchema->tblHash;
1.415 + temp2 = pSchema->trigHash;
1.416 + sqlite3HashInit(&pSchema->trigHash, 0);
1.417 + sqlite3HashClear(&pSchema->aFKey);
1.418 + sqlite3HashClear(&pSchema->idxHash);
1.419 + for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
1.420 + sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
1.421 + }
1.422 + sqlite3HashClear(&temp2);
1.423 + sqlite3HashInit(&pSchema->tblHash, 0);
1.424 + for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
1.425 + Table *pTab = sqliteHashData(pElem);
1.426 + sqlite3DeleteTable(pTab);
1.427 + }
1.428 + sqlite3HashClear(&temp1);
1.429 + pSchema->pSeqTab = 0;
1.430 + pSchema->flags &= ~DB_SchemaLoaded;
1.431 +}
1.432 +
1.433 +/*
1.434 +** Find and return the schema associated with a BTree. Create
1.435 +** a new one if necessary.
1.436 +*/
1.437 +Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
1.438 + Schema * p;
1.439 + if( pBt ){
1.440 + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree);
1.441 + }else{
1.442 + p = (Schema *)sqlite3MallocZero(sizeof(Schema));
1.443 + }
1.444 + if( !p ){
1.445 + db->mallocFailed = 1;
1.446 + }else if ( 0==p->file_format ){
1.447 + sqlite3HashInit(&p->tblHash, 0);
1.448 + sqlite3HashInit(&p->idxHash, 0);
1.449 + sqlite3HashInit(&p->trigHash, 0);
1.450 + sqlite3HashInit(&p->aFKey, 1);
1.451 + p->enc = SQLITE_UTF8;
1.452 + }
1.453 + return p;
1.454 +}