Index: third_party/sqlite/src/src/callback.c |
diff --git a/third_party/sqlite/src/src/callback.c b/third_party/sqlite/src/src/callback.c |
index ce849085c22d2b41b315ce9810f3754239269a7d..cd213b4b28bee0af16c4d4e57c0017cacf6faeff 100644 |
--- a/third_party/sqlite/src/src/callback.c |
+++ b/third_party/sqlite/src/src/callback.c |
@@ -75,17 +75,18 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ |
** |
** The return value is either the collation sequence to be used in database |
** db for collation type name zName, length nName, or NULL, if no collation |
-** sequence can be found. |
+** sequence can be found. If no collation is found, leave an error message. |
** |
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() |
*/ |
CollSeq *sqlite3GetCollSeq( |
- sqlite3* db, /* The database connection */ |
+ Parse *pParse, /* Parsing context */ |
u8 enc, /* The desired encoding for the collating sequence */ |
CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ |
const char *zName /* Collating sequence name */ |
){ |
CollSeq *p; |
+ sqlite3 *db = pParse->db; |
p = pColl; |
if( !p ){ |
@@ -102,6 +103,9 @@ CollSeq *sqlite3GetCollSeq( |
p = 0; |
} |
assert( !p || p->xCmp ); |
+ if( p==0 ){ |
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); |
+ } |
return p; |
} |
@@ -120,10 +124,8 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ |
if( pColl ){ |
const char *zName = pColl->zName; |
sqlite3 *db = pParse->db; |
- CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName); |
+ CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); |
if( !p ){ |
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); |
- pParse->nErr++; |
return SQLITE_ERROR; |
} |
assert( p==pColl ); |
@@ -140,7 +142,7 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ |
** |
** Each pointer stored in the sqlite3.aCollSeq hash table contains an |
** array of three CollSeq structures. The first is the collation sequence |
-** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. |
+** preferred for UTF-8, the second UTF-16le, and the third UTF-16be. |
** |
** Stored immediately after the three collation sequences is a copy of |
** the collation sequence name. A pointer to this string is stored in |
@@ -152,11 +154,11 @@ static CollSeq *findCollSeqEntry( |
int create /* Create a new entry if true */ |
){ |
CollSeq *pColl; |
- int nName = sqlite3Strlen30(zName); |
- pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); |
+ pColl = sqlite3HashFind(&db->aCollSeq, zName); |
if( 0==pColl && create ){ |
- pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); |
+ int nName = sqlite3Strlen30(zName); |
+ pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1); |
if( pColl ){ |
CollSeq *pDel = 0; |
pColl[0].zName = (char*)&pColl[3]; |
@@ -167,7 +169,7 @@ static CollSeq *findCollSeqEntry( |
pColl[2].enc = SQLITE_UTF16BE; |
memcpy(pColl[0].zName, zName, nName); |
pColl[0].zName[nName] = 0; |
- pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); |
+ pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); |
/* If a malloc() failure occurred in sqlite3HashInsert(), it will |
** return the pColl pointer to be deleted (because it wasn't added |
@@ -223,38 +225,57 @@ CollSeq *sqlite3FindCollSeq( |
** that uses encoding enc. The value returned indicates how well the |
** request is matched. A higher value indicates a better match. |
** |
+** If nArg is -1 that means to only return a match (non-zero) if p->nArg |
+** is also -1. In other words, we are searching for a function that |
+** takes a variable number of arguments. |
+** |
+** If nArg is -2 that means that we are searching for any function |
+** regardless of the number of arguments it uses, so return a positive |
+** match score for any |
+** |
** The returned value is always between 0 and 6, as follows: |
** |
-** 0: Not a match, or if nArg<0 and the function is has no implementation. |
-** 1: A variable arguments function that prefers UTF-8 when a UTF-16 |
-** encoding is requested, or vice versa. |
-** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is |
-** requested, or vice versa. |
-** 3: A variable arguments function using the same text encoding. |
-** 4: A function with the exact number of arguments requested that |
-** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. |
-** 5: A function with the exact number of arguments requested that |
-** prefers UTF-16LE when UTF-16BE is requested, or vice versa. |
-** 6: An exact match. |
+** 0: Not a match. |
+** 1: UTF8/16 conversion required and function takes any number of arguments. |
+** 2: UTF16 byte order change required and function takes any number of args. |
+** 3: encoding matches and function takes any number of arguments |
+** 4: UTF8/16 conversion required - argument count matches exactly |
+** 5: UTF16 byte order conversion required - argument count matches exactly |
+** 6: Perfect match: encoding and argument count match exactly. |
** |
+** If nArg==(-2) then any function with a non-null xStep or xFunc is |
+** a perfect match and any function with both xStep and xFunc NULL is |
+** a non-match. |
*/ |
-static int matchQuality(FuncDef *p, int nArg, u8 enc){ |
- int match = 0; |
- if( p->nArg==-1 || p->nArg==nArg |
- || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0)) |
- ){ |
+#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ |
+static int matchQuality( |
+ FuncDef *p, /* The function we are evaluating for match quality */ |
+ int nArg, /* Desired number of arguments. (-1)==any */ |
+ u8 enc /* Desired text encoding */ |
+){ |
+ int match; |
+ |
+ /* nArg of -2 is a special case */ |
+ if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH; |
+ |
+ /* Wrong number of arguments means "no match" */ |
+ if( p->nArg!=nArg && p->nArg>=0 ) return 0; |
+ |
+ /* Give a better score to a function with a specific number of arguments |
+ ** than to function that accepts any number of arguments. */ |
+ if( p->nArg==nArg ){ |
+ match = 4; |
+ }else{ |
match = 1; |
- if( p->nArg==nArg || nArg==-1 ){ |
- match = 4; |
- } |
- if( enc==p->iPrefEnc ){ |
- match += 2; |
- } |
- else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || |
- (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ |
- match += 1; |
- } |
} |
+ |
+ /* Bonus points if the text encoding matches */ |
+ if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){ |
+ match += 2; /* Exact encoding match */ |
+ }else if( (enc & p->funcFlags & 2)!=0 ){ |
+ match += 1; /* Both are UTF16, but with different byte orders */ |
+ } |
+ |
return match; |
} |
@@ -310,13 +331,12 @@ void sqlite3FuncDefInsert( |
** |
** If the createFlag argument is true, then a new (blank) FuncDef |
** structure is created and liked into the "db" structure if a |
-** no matching function previously existed. When createFlag is true |
-** and the nArg parameter is -1, then only a function that accepts |
-** any number of arguments will be returned. |
+** no matching function previously existed. |
** |
-** If createFlag is false and nArg is -1, then the first valid |
-** function found is returned. A function is valid if either xFunc |
-** or xStep is non-zero. |
+** If nArg is -2, then the first valid function found is returned. A |
+** function is valid if either xFunc or xStep is non-zero. The nArg==(-2) |
+** case is used to see if zName is a valid function name for some number |
+** of arguments. If nArg is -2, then createFlag must be 0. |
** |
** If createFlag is false, then a function with the required name and |
** number of arguments may be returned even if the eTextRep flag does not |
@@ -328,15 +348,15 @@ FuncDef *sqlite3FindFunction( |
int nName, /* Number of characters in the name */ |
int nArg, /* Number of arguments. -1 means any number */ |
u8 enc, /* Preferred text encoding */ |
- int createFlag /* Create new entry if true and does not otherwise exist */ |
+ u8 createFlag /* Create new entry if true and does not otherwise exist */ |
){ |
FuncDef *p; /* Iterator variable */ |
FuncDef *pBest = 0; /* Best match found so far */ |
int bestScore = 0; /* Score of best match */ |
int h; /* Hash value */ |
- |
- assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); |
+ assert( nArg>=(-2) ); |
+ assert( nArg>=(-1) || createFlag==0 ); |
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); |
/* First search for a match amongst the application-defined functions. |
@@ -381,11 +401,11 @@ FuncDef *sqlite3FindFunction( |
** exact match for the name, number of arguments and encoding, then add a |
** new entry to the hash table and return it. |
*/ |
- if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && |
+ if( createFlag && bestScore<FUNC_PERFECT_MATCH && |
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ |
pBest->zName = (char *)&pBest[1]; |
pBest->nArg = (u16)nArg; |
- pBest->iPrefEnc = enc; |
+ pBest->funcFlags = enc; |
memcpy(pBest->zName, zName, nName); |
pBest->zName[nName] = 0; |
sqlite3FuncDefInsert(&db->aFunc, pBest); |
@@ -427,9 +447,9 @@ void sqlite3SchemaClear(void *p){ |
sqlite3HashClear(&temp1); |
sqlite3HashClear(&pSchema->fkeyHash); |
pSchema->pSeqTab = 0; |
- if( pSchema->flags & DB_SchemaLoaded ){ |
+ if( pSchema->schemaFlags & DB_SchemaLoaded ){ |
pSchema->iGeneration++; |
- pSchema->flags &= ~DB_SchemaLoaded; |
+ pSchema->schemaFlags &= ~DB_SchemaLoaded; |
} |
} |