xref: /sqlite-3.40.0/src/callback.c (revision 74217cc0)
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 ** $Id: callback.c,v 1.3 2005/08/14 01:20:38 drh Exp $
17 */
18 
19 #include "sqliteInt.h"
20 
21 /*
22 ** Invoke the 'collation needed' callback to request a collation sequence
23 ** in the database text encoding of name zName, length nName.
24 ** If the collation sequence
25 */
26 static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
27   assert( !db->xCollNeeded || !db->xCollNeeded16 );
28   if( nName<0 ) nName = strlen(zName);
29   if( db->xCollNeeded ){
30     char *zExternal = sqliteStrNDup(zName, nName);
31     if( !zExternal ) return;
32     db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
33     sqliteFree(zExternal);
34   }
35 #ifndef SQLITE_OMIT_UTF16
36   if( db->xCollNeeded16 ){
37     char const *zExternal;
38     sqlite3_value *pTmp = sqlite3GetTransientValue(db);
39     sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
40     zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
41     if( !zExternal ) return;
42     db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
43   }
44 #endif
45 }
46 
47 /*
48 ** This routine is called if the collation factory fails to deliver a
49 ** collation function in the best encoding but there may be other versions
50 ** of this collation function (for other text encodings) available. Use one
51 ** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
52 ** possible.
53 */
54 static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
55   CollSeq *pColl2;
56   char *z = pColl->zName;
57   int n = strlen(z);
58   int i;
59   static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
60   for(i=0; i<3; i++){
61     pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
62     if( pColl2->xCmp!=0 ){
63       memcpy(pColl, pColl2, sizeof(CollSeq));
64       return SQLITE_OK;
65     }
66   }
67   return SQLITE_ERROR;
68 }
69 
70 /*
71 ** This function is responsible for invoking the collation factory callback
72 ** or substituting a collation sequence of a different encoding when the
73 ** requested collation sequence is not available in the database native
74 ** encoding.
75 **
76 ** If it is not NULL, then pColl must point to the database native encoding
77 ** collation sequence with name zName, length nName.
78 **
79 ** The return value is either the collation sequence to be used in database
80 ** db for collation type name zName, length nName, or NULL, if no collation
81 ** sequence can be found.
82 */
83 CollSeq *sqlite3GetCollSeq(
84   sqlite3* db,
85   CollSeq *pColl,
86   const char *zName,
87   int nName
88 ){
89   CollSeq *p;
90 
91   p = pColl;
92   if( !p ){
93     p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
94   }
95   if( !p || !p->xCmp ){
96     /* No collation sequence of this type for this encoding is registered.
97     ** Call the collation factory to see if it can supply us with one.
98     */
99     callCollNeeded(db, zName, nName);
100     p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
101   }
102   if( p && !p->xCmp && synthCollSeq(db, p) ){
103     p = 0;
104   }
105   assert( !p || p->xCmp );
106   return p;
107 }
108 
109 /*
110 ** This routine is called on a collation sequence before it is used to
111 ** check that it is defined. An undefined collation sequence exists when
112 ** a database is loaded that contains references to collation sequences
113 ** that have not been defined by sqlite3_create_collation() etc.
114 **
115 ** If required, this routine calls the 'collation needed' callback to
116 ** request a definition of the collating sequence. If this doesn't work,
117 ** an equivalent collating sequence that uses a text encoding different
118 ** from the main database is substituted, if one is available.
119 */
120 int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
121   if( pColl ){
122     const char *zName = pColl->zName;
123     CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
124     if( !p ){
125       if( pParse->nErr==0 ){
126         sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
127       }
128       pParse->nErr++;
129       return SQLITE_ERROR;
130     }
131   }
132   return SQLITE_OK;
133 }
134 
135 
136 
137 /*
138 ** Locate and return an entry from the db.aCollSeq hash table. If the entry
139 ** specified by zName and nName is not found and parameter 'create' is
140 ** true, then create a new entry. Otherwise return NULL.
141 **
142 ** Each pointer stored in the sqlite3.aCollSeq hash table contains an
143 ** array of three CollSeq structures. The first is the collation sequence
144 ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
145 **
146 ** Stored immediately after the three collation sequences is a copy of
147 ** the collation sequence name. A pointer to this string is stored in
148 ** each collation sequence structure.
149 */
150 static CollSeq *findCollSeqEntry(
151   sqlite3 *db,
152   const char *zName,
153   int nName,
154   int create
155 ){
156   CollSeq *pColl;
157   if( nName<0 ) nName = strlen(zName);
158   pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
159 
160   if( 0==pColl && create ){
161     pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
162     if( pColl ){
163       CollSeq *pDel = 0;
164       pColl[0].zName = (char*)&pColl[3];
165       pColl[0].enc = SQLITE_UTF8;
166       pColl[1].zName = (char*)&pColl[3];
167       pColl[1].enc = SQLITE_UTF16LE;
168       pColl[2].zName = (char*)&pColl[3];
169       pColl[2].enc = SQLITE_UTF16BE;
170       memcpy(pColl[0].zName, zName, nName);
171       pColl[0].zName[nName] = 0;
172       pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
173 
174       /* If a malloc() failure occured in sqlite3HashInsert(), it will
175       ** return the pColl pointer to be deleted (because it wasn't added
176       ** to the hash table).
177       */
178       assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) );
179       sqliteFree(pDel);
180     }
181   }
182   return pColl;
183 }
184 
185 /*
186 ** Parameter zName points to a UTF-8 encoded string nName bytes long.
187 ** Return the CollSeq* pointer for the collation sequence named zName
188 ** for the encoding 'enc' from the database 'db'.
189 **
190 ** If the entry specified is not found and 'create' is true, then create a
191 ** new entry.  Otherwise return NULL.
192 */
193 CollSeq *sqlite3FindCollSeq(
194   sqlite3 *db,
195   u8 enc,
196   const char *zName,
197   int nName,
198   int create
199 ){
200   CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
201   assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
202   assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
203   if( pColl ) pColl += enc-1;
204   return pColl;
205 }
206 
207 /*
208 ** Locate a user function given a name, a number of arguments and a flag
209 ** indicating whether the function prefers UTF-16 over UTF-8.  Return a
210 ** pointer to the FuncDef structure that defines that function, or return
211 ** NULL if the function does not exist.
212 **
213 ** If the createFlag argument is true, then a new (blank) FuncDef
214 ** structure is created and liked into the "db" structure if a
215 ** no matching function previously existed.  When createFlag is true
216 ** and the nArg parameter is -1, then only a function that accepts
217 ** any number of arguments will be returned.
218 **
219 ** If createFlag is false and nArg is -1, then the first valid
220 ** function found is returned.  A function is valid if either xFunc
221 ** or xStep is non-zero.
222 **
223 ** If createFlag is false, then a function with the required name and
224 ** number of arguments may be returned even if the eTextRep flag does not
225 ** match that requested.
226 */
227 FuncDef *sqlite3FindFunction(
228   sqlite3 *db,       /* An open database */
229   const char *zName, /* Name of the function.  Not null-terminated */
230   int nName,         /* Number of characters in the name */
231   int nArg,          /* Number of arguments.  -1 means any number */
232   u8 enc,            /* Preferred text encoding */
233   int createFlag     /* Create new entry if true and does not otherwise exist */
234 ){
235   FuncDef *p;         /* Iterator variable */
236   FuncDef *pFirst;    /* First function with this name */
237   FuncDef *pBest = 0; /* Best match found so far */
238   int bestmatch = 0;
239 
240 
241   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
242   if( nArg<-1 ) nArg = -1;
243 
244   pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
245   for(p=pFirst; p; p=p->pNext){
246     /* During the search for the best function definition, bestmatch is set
247     ** as follows to indicate the quality of the match with the definition
248     ** pointed to by pBest:
249     **
250     ** 0: pBest is NULL. No match has been found.
251     ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
252     **    encoding is requested, or vice versa.
253     ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
254     **    requested, or vice versa.
255     ** 3: A variable arguments function using the same text encoding.
256     ** 4: A function with the exact number of arguments requested that
257     **    prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
258     ** 5: A function with the exact number of arguments requested that
259     **    prefers UTF-16LE when UTF-16BE is requested, or vice versa.
260     ** 6: An exact match.
261     **
262     ** A larger value of 'matchqual' indicates a more desirable match.
263     */
264     if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
265       int match = 1;          /* Quality of this match */
266       if( p->nArg==nArg || nArg==-1 ){
267         match = 4;
268       }
269       if( enc==p->iPrefEnc ){
270         match += 2;
271       }
272       else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
273                (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
274         match += 1;
275       }
276 
277       if( match>bestmatch ){
278         pBest = p;
279         bestmatch = match;
280       }
281     }
282   }
283 
284   /* If the createFlag parameter is true, and the seach did not reveal an
285   ** exact match for the name, number of arguments and encoding, then add a
286   ** new entry to the hash table and return it.
287   */
288   if( createFlag && bestmatch<6 &&
289       (pBest = sqliteMalloc(sizeof(*pBest)+nName)) ){
290     pBest->nArg = nArg;
291     pBest->pNext = pFirst;
292     pBest->iPrefEnc = enc;
293     memcpy(pBest->zName, zName, nName);
294     pBest->zName[nName] = 0;
295     if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
296       sqliteFree(pBest);
297       return 0;
298     }
299   }
300 
301   if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
302     return pBest;
303   }
304   return 0;
305 }
306