Annotation of embedaddon/sqlite3/src/callback.c, revision 1.1.1.1
1.1 misho 1: /*
2: ** 2005 May 23
3: **
4: ** The author disclaims copyright to this source code. In place of
5: ** a legal notice, here is a blessing:
6: **
7: ** May you do good and not evil.
8: ** May you find forgiveness for yourself and forgive others.
9: ** May you share freely, never taking more than you give.
10: **
11: *************************************************************************
12: **
13: ** This file contains functions used to access the internal hash tables
14: ** of user defined functions and collation sequences.
15: */
16:
17: #include "sqliteInt.h"
18:
19: /*
20: ** Invoke the 'collation needed' callback to request a collation sequence
21: ** in the encoding enc of name zName, length nName.
22: */
23: static void callCollNeeded(sqlite3 *db, int enc, const char *zName){
24: assert( !db->xCollNeeded || !db->xCollNeeded16 );
25: if( db->xCollNeeded ){
26: char *zExternal = sqlite3DbStrDup(db, zName);
27: if( !zExternal ) return;
28: db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
29: sqlite3DbFree(db, zExternal);
30: }
31: #ifndef SQLITE_OMIT_UTF16
32: if( db->xCollNeeded16 ){
33: char const *zExternal;
34: sqlite3_value *pTmp = sqlite3ValueNew(db);
35: sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
36: zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
37: if( zExternal ){
38: db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
39: }
40: sqlite3ValueFree(pTmp);
41: }
42: #endif
43: }
44:
45: /*
46: ** This routine is called if the collation factory fails to deliver a
47: ** collation function in the best encoding but there may be other versions
48: ** of this collation function (for other text encodings) available. Use one
49: ** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
50: ** possible.
51: */
52: static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
53: CollSeq *pColl2;
54: char *z = pColl->zName;
55: int i;
56: static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
57: for(i=0; i<3; i++){
58: pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
59: if( pColl2->xCmp!=0 ){
60: memcpy(pColl, pColl2, sizeof(CollSeq));
61: pColl->xDel = 0; /* Do not copy the destructor */
62: return SQLITE_OK;
63: }
64: }
65: return SQLITE_ERROR;
66: }
67:
68: /*
69: ** This function is responsible for invoking the collation factory callback
70: ** or substituting a collation sequence of a different encoding when the
71: ** requested collation sequence is not available in the desired encoding.
72: **
73: ** If it is not NULL, then pColl must point to the database native encoding
74: ** collation sequence with name zName, length nName.
75: **
76: ** The return value is either the collation sequence to be used in database
77: ** db for collation type name zName, length nName, or NULL, if no collation
78: ** sequence can be found.
79: **
80: ** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
81: */
82: CollSeq *sqlite3GetCollSeq(
83: sqlite3* db, /* The database connection */
84: u8 enc, /* The desired encoding for the collating sequence */
85: CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
86: const char *zName /* Collating sequence name */
87: ){
88: CollSeq *p;
89:
90: p = pColl;
91: if( !p ){
92: p = sqlite3FindCollSeq(db, enc, zName, 0);
93: }
94: if( !p || !p->xCmp ){
95: /* No collation sequence of this type for this encoding is registered.
96: ** Call the collation factory to see if it can supply us with one.
97: */
98: callCollNeeded(db, enc, zName);
99: p = sqlite3FindCollSeq(db, enc, zName, 0);
100: }
101: if( p && !p->xCmp && synthCollSeq(db, p) ){
102: p = 0;
103: }
104: assert( !p || p->xCmp );
105: return p;
106: }
107:
108: /*
109: ** This routine is called on a collation sequence before it is used to
110: ** check that it is defined. An undefined collation sequence exists when
111: ** a database is loaded that contains references to collation sequences
112: ** that have not been defined by sqlite3_create_collation() etc.
113: **
114: ** If required, this routine calls the 'collation needed' callback to
115: ** request a definition of the collating sequence. If this doesn't work,
116: ** an equivalent collating sequence that uses a text encoding different
117: ** from the main database is substituted, if one is available.
118: */
119: int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
120: if( pColl ){
121: const char *zName = pColl->zName;
122: sqlite3 *db = pParse->db;
123: CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
124: if( !p ){
125: sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
126: pParse->nErr++;
127: return SQLITE_ERROR;
128: }
129: assert( p==pColl );
130: }
131: return SQLITE_OK;
132: }
133:
134:
135:
136: /*
137: ** Locate and return an entry from the db.aCollSeq hash table. If the entry
138: ** specified by zName and nName is not found and parameter 'create' is
139: ** true, then create a new entry. Otherwise return NULL.
140: **
141: ** Each pointer stored in the sqlite3.aCollSeq hash table contains an
142: ** array of three CollSeq structures. The first is the collation sequence
143: ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
144: **
145: ** Stored immediately after the three collation sequences is a copy of
146: ** the collation sequence name. A pointer to this string is stored in
147: ** each collation sequence structure.
148: */
149: static CollSeq *findCollSeqEntry(
150: sqlite3 *db, /* Database connection */
151: const char *zName, /* Name of the collating sequence */
152: int create /* Create a new entry if true */
153: ){
154: CollSeq *pColl;
155: int nName = sqlite3Strlen30(zName);
156: pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
157:
158: if( 0==pColl && create ){
159: pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
160: if( pColl ){
161: CollSeq *pDel = 0;
162: pColl[0].zName = (char*)&pColl[3];
163: pColl[0].enc = SQLITE_UTF8;
164: pColl[1].zName = (char*)&pColl[3];
165: pColl[1].enc = SQLITE_UTF16LE;
166: pColl[2].zName = (char*)&pColl[3];
167: pColl[2].enc = SQLITE_UTF16BE;
168: memcpy(pColl[0].zName, zName, nName);
169: pColl[0].zName[nName] = 0;
170: pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
171:
172: /* If a malloc() failure occurred in sqlite3HashInsert(), it will
173: ** return the pColl pointer to be deleted (because it wasn't added
174: ** to the hash table).
175: */
176: assert( pDel==0 || pDel==pColl );
177: if( pDel!=0 ){
178: db->mallocFailed = 1;
179: sqlite3DbFree(db, pDel);
180: pColl = 0;
181: }
182: }
183: }
184: return pColl;
185: }
186:
187: /*
188: ** Parameter zName points to a UTF-8 encoded string nName bytes long.
189: ** Return the CollSeq* pointer for the collation sequence named zName
190: ** for the encoding 'enc' from the database 'db'.
191: **
192: ** If the entry specified is not found and 'create' is true, then create a
193: ** new entry. Otherwise return NULL.
194: **
195: ** A separate function sqlite3LocateCollSeq() is a wrapper around
196: ** this routine. sqlite3LocateCollSeq() invokes the collation factory
197: ** if necessary and generates an error message if the collating sequence
198: ** cannot be found.
199: **
200: ** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
201: */
202: CollSeq *sqlite3FindCollSeq(
203: sqlite3 *db,
204: u8 enc,
205: const char *zName,
206: int create
207: ){
208: CollSeq *pColl;
209: if( zName ){
210: pColl = findCollSeqEntry(db, zName, create);
211: }else{
212: pColl = db->pDfltColl;
213: }
214: assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
215: assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
216: if( pColl ) pColl += enc-1;
217: return pColl;
218: }
219:
220: /* During the search for the best function definition, this procedure
221: ** is called to test how well the function passed as the first argument
222: ** matches the request for a function with nArg arguments in a system
223: ** that uses encoding enc. The value returned indicates how well the
224: ** request is matched. A higher value indicates a better match.
225: **
226: ** The returned value is always between 0 and 6, as follows:
227: **
228: ** 0: Not a match, or if nArg<0 and the function is has no implementation.
229: ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
230: ** encoding is requested, or vice versa.
231: ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
232: ** requested, or vice versa.
233: ** 3: A variable arguments function using the same text encoding.
234: ** 4: A function with the exact number of arguments requested that
235: ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
236: ** 5: A function with the exact number of arguments requested that
237: ** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
238: ** 6: An exact match.
239: **
240: */
241: static int matchQuality(FuncDef *p, int nArg, u8 enc){
242: int match = 0;
243: if( p->nArg==-1 || p->nArg==nArg
244: || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0))
245: ){
246: match = 1;
247: if( p->nArg==nArg || nArg==-1 ){
248: match = 4;
249: }
250: if( enc==p->iPrefEnc ){
251: match += 2;
252: }
253: else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
254: (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
255: match += 1;
256: }
257: }
258: return match;
259: }
260:
261: /*
262: ** Search a FuncDefHash for a function with the given name. Return
263: ** a pointer to the matching FuncDef if found, or 0 if there is no match.
264: */
265: static FuncDef *functionSearch(
266: FuncDefHash *pHash, /* Hash table to search */
267: int h, /* Hash of the name */
268: const char *zFunc, /* Name of function */
269: int nFunc /* Number of bytes in zFunc */
270: ){
271: FuncDef *p;
272: for(p=pHash->a[h]; p; p=p->pHash){
273: if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
274: return p;
275: }
276: }
277: return 0;
278: }
279:
280: /*
281: ** Insert a new FuncDef into a FuncDefHash hash table.
282: */
283: void sqlite3FuncDefInsert(
284: FuncDefHash *pHash, /* The hash table into which to insert */
285: FuncDef *pDef /* The function definition to insert */
286: ){
287: FuncDef *pOther;
288: int nName = sqlite3Strlen30(pDef->zName);
289: u8 c1 = (u8)pDef->zName[0];
290: int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
291: pOther = functionSearch(pHash, h, pDef->zName, nName);
292: if( pOther ){
293: assert( pOther!=pDef && pOther->pNext!=pDef );
294: pDef->pNext = pOther->pNext;
295: pOther->pNext = pDef;
296: }else{
297: pDef->pNext = 0;
298: pDef->pHash = pHash->a[h];
299: pHash->a[h] = pDef;
300: }
301: }
302:
303:
304:
305: /*
306: ** Locate a user function given a name, a number of arguments and a flag
307: ** indicating whether the function prefers UTF-16 over UTF-8. Return a
308: ** pointer to the FuncDef structure that defines that function, or return
309: ** NULL if the function does not exist.
310: **
311: ** If the createFlag argument is true, then a new (blank) FuncDef
312: ** structure is created and liked into the "db" structure if a
313: ** no matching function previously existed. When createFlag is true
314: ** and the nArg parameter is -1, then only a function that accepts
315: ** any number of arguments will be returned.
316: **
317: ** If createFlag is false and nArg is -1, then the first valid
318: ** function found is returned. A function is valid if either xFunc
319: ** or xStep is non-zero.
320: **
321: ** If createFlag is false, then a function with the required name and
322: ** number of arguments may be returned even if the eTextRep flag does not
323: ** match that requested.
324: */
325: FuncDef *sqlite3FindFunction(
326: sqlite3 *db, /* An open database */
327: const char *zName, /* Name of the function. Not null-terminated */
328: int nName, /* Number of characters in the name */
329: int nArg, /* Number of arguments. -1 means any number */
330: u8 enc, /* Preferred text encoding */
331: int createFlag /* Create new entry if true and does not otherwise exist */
332: ){
333: FuncDef *p; /* Iterator variable */
334: FuncDef *pBest = 0; /* Best match found so far */
335: int bestScore = 0; /* Score of best match */
336: int h; /* Hash value */
337:
338:
339: assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
340: h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
341:
342: /* First search for a match amongst the application-defined functions.
343: */
344: p = functionSearch(&db->aFunc, h, zName, nName);
345: while( p ){
346: int score = matchQuality(p, nArg, enc);
347: if( score>bestScore ){
348: pBest = p;
349: bestScore = score;
350: }
351: p = p->pNext;
352: }
353:
354: /* If no match is found, search the built-in functions.
355: **
356: ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
357: ** functions even if a prior app-defined function was found. And give
358: ** priority to built-in functions.
359: **
360: ** Except, if createFlag is true, that means that we are trying to
361: ** install a new function. Whatever FuncDef structure is returned it will
362: ** have fields overwritten with new information appropriate for the
363: ** new function. But the FuncDefs for built-in functions are read-only.
364: ** So we must not search for built-ins when creating a new function.
365: */
366: if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
367: FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
368: bestScore = 0;
369: p = functionSearch(pHash, h, zName, nName);
370: while( p ){
371: int score = matchQuality(p, nArg, enc);
372: if( score>bestScore ){
373: pBest = p;
374: bestScore = score;
375: }
376: p = p->pNext;
377: }
378: }
379:
380: /* If the createFlag parameter is true and the search did not reveal an
381: ** exact match for the name, number of arguments and encoding, then add a
382: ** new entry to the hash table and return it.
383: */
384: if( createFlag && (bestScore<6 || pBest->nArg!=nArg) &&
385: (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
386: pBest->zName = (char *)&pBest[1];
387: pBest->nArg = (u16)nArg;
388: pBest->iPrefEnc = enc;
389: memcpy(pBest->zName, zName, nName);
390: pBest->zName[nName] = 0;
391: sqlite3FuncDefInsert(&db->aFunc, pBest);
392: }
393:
394: if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
395: return pBest;
396: }
397: return 0;
398: }
399:
400: /*
401: ** Free all resources held by the schema structure. The void* argument points
402: ** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
403: ** pointer itself, it just cleans up subsidiary resources (i.e. the contents
404: ** of the schema hash tables).
405: **
406: ** The Schema.cache_size variable is not cleared.
407: */
408: void sqlite3SchemaClear(void *p){
409: Hash temp1;
410: Hash temp2;
411: HashElem *pElem;
412: Schema *pSchema = (Schema *)p;
413:
414: temp1 = pSchema->tblHash;
415: temp2 = pSchema->trigHash;
416: sqlite3HashInit(&pSchema->trigHash);
417: sqlite3HashClear(&pSchema->idxHash);
418: for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
419: sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
420: }
421: sqlite3HashClear(&temp2);
422: sqlite3HashInit(&pSchema->tblHash);
423: for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
424: Table *pTab = sqliteHashData(pElem);
425: sqlite3DeleteTable(0, pTab);
426: }
427: sqlite3HashClear(&temp1);
428: sqlite3HashClear(&pSchema->fkeyHash);
429: pSchema->pSeqTab = 0;
430: if( pSchema->flags & DB_SchemaLoaded ){
431: pSchema->iGeneration++;
432: pSchema->flags &= ~DB_SchemaLoaded;
433: }
434: }
435:
436: /*
437: ** Find and return the schema associated with a BTree. Create
438: ** a new one if necessary.
439: */
440: Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
441: Schema * p;
442: if( pBt ){
443: p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear);
444: }else{
445: p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
446: }
447: if( !p ){
448: db->mallocFailed = 1;
449: }else if ( 0==p->file_format ){
450: sqlite3HashInit(&p->tblHash);
451: sqlite3HashInit(&p->idxHash);
452: sqlite3HashInit(&p->trigHash);
453: sqlite3HashInit(&p->fkeyHash);
454: p->enc = SQLITE_UTF8;
455: }
456: return p;
457: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>