mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-10 01:02:56 +03:00
Fix the application-defined function logic so that functions with a variable
number of parameters can be replaced or deleted correctly. Also refactor some of the function-finder code for clarity of presentation. FossilOrigin-Name: 09d5581c81fb6a9bf6a369d0abf5ef6b54637576
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Update\ssqlite3_analyzer\sto\scorrectly\sfind\sall\sdatabase\sfiles\swhen\sthe\nmultiplexor\sis\sbeing\sused.
|
C Fix\sthe\sapplication-defined\sfunction\slogic\sso\sthat\sfunctions\swith\sa\svariable\nnumber\sof\sparameters\scan\sbe\sreplaced\sor\sdeleted\scorrectly.\s\sAlso\srefactor\nsome\sof\sthe\sfunction-finder\scode\sfor\sclarity\sof\spresentation.
|
||||||
D 2012-04-06T00:09:27.071
|
D 2012-04-07T00:09:21.842
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
|
F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -130,7 +130,7 @@ F src/btree.c df800f10896bc2ddaa1125c532d6e7a7b9efc532
|
|||||||
F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
|
F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
|
||||||
F src/btreeInt.h 38a639c0542c29fe8331a221c4aed0cb8686249e
|
F src/btreeInt.h 38a639c0542c29fe8331a221c4aed0cb8686249e
|
||||||
F src/build.c 987c6933ea170e443dc6a79d52f8d2506206b12b
|
F src/build.c 987c6933ea170e443dc6a79d52f8d2506206b12b
|
||||||
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
|
||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
|
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
|
||||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||||
@@ -179,13 +179,13 @@ F src/pragma.c e708b3bb5704605816f617e0b1d63a5488060715
|
|||||||
F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e
|
F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e
|
||||||
F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699
|
F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40
|
F src/resolve.c 969ec2bc52db1b068054ecf5ddc74f244102a71d
|
||||||
F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1
|
F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1
|
||||||
F src/select.c 5e0e481c7d215d3c7ca8ccae1e688aa30163c6c1
|
F src/select.c 5e0e481c7d215d3c7ca8ccae1e688aa30163c6c1
|
||||||
F src/shell.c ce4d41582182b8fad3be364e2fa295b70bc342ab
|
F src/shell.c ce4d41582182b8fad3be364e2fa295b70bc342ab
|
||||||
F src/sqlite.h.in 11a883919b0baf4ffaa7550cfeef99be613ec2bf
|
F src/sqlite.h.in 11a883919b0baf4ffaa7550cfeef99be613ec2bf
|
||||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||||
F src/sqliteInt.h d701123ab4c8774ee2837cd4ade84e370d665f87
|
F src/sqliteInt.h ce7d8404f15db6cbe73cf196d3d6198aaa4e3924
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
|
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -1000,7 +1000,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
|||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
P 1b08fef9451f4d59148548faed115d1a5d0bcd98
|
P 1bfc30cb0fdc4b9def989eea2d78f6ac851633fa
|
||||||
R 220148404893713f89fb8c5c7ad54b6d
|
R 7617876a091e2e4cf9376c46017f187f
|
||||||
U drh
|
U drh
|
||||||
Z 737b7c44e8ad27216e6474b5a72beb32
|
Z 1d4ad19c22a54f0c05282a803680a670
|
||||||
|
@@ -1 +1 @@
|
|||||||
1bfc30cb0fdc4b9def989eea2d78f6ac851633fa
|
09d5581c81fb6a9bf6a369d0abf5ef6b54637576
|
@@ -223,38 +223,57 @@ CollSeq *sqlite3FindCollSeq(
|
|||||||
** that uses encoding enc. The value returned indicates how well the
|
** that uses encoding enc. The value returned indicates how well the
|
||||||
** request is matched. A higher value indicates a better match.
|
** 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:
|
** 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.
|
** 0: Not a match.
|
||||||
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
|
** 1: UTF8/16 conversion required and function takes any number of arguments.
|
||||||
** encoding is requested, or vice versa.
|
** 2: UTF16 byte order change required and function takes any number of args.
|
||||||
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
|
** 3: encoding matches and function takes any number of arguments
|
||||||
** requested, or vice versa.
|
** 4: UTF8/16 conversion required - argument count matches exactly
|
||||||
** 3: A variable arguments function using the same text encoding.
|
** 5: UTF16 byte order conversion required - argument count matches exactly
|
||||||
** 4: A function with the exact number of arguments requested that
|
** 6: Perfect match: encoding and argument count match exactly.
|
||||||
** 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.
|
|
||||||
**
|
**
|
||||||
|
** 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){
|
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
|
||||||
int match = 0;
|
static int matchQuality(
|
||||||
if( p->nArg==-1 || p->nArg==nArg
|
FuncDef *p, /* The function we are evaluating for match quality */
|
||||||
|| (nArg==-1 && (p->xFunc!=0 || p->xStep!=0))
|
int nArg, /* Desired number of arguments. (-1)==any */
|
||||||
|
u8 enc /* Desired text encoding */
|
||||||
){
|
){
|
||||||
match = 1;
|
int match;
|
||||||
if( p->nArg==nArg || nArg==-1 ){
|
|
||||||
|
/* 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;
|
match = 4;
|
||||||
|
}else{
|
||||||
|
match = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bonus points if the text encoding matches */
|
||||||
if( enc==p->iPrefEnc ){
|
if( enc==p->iPrefEnc ){
|
||||||
match += 2;
|
match += 2; /* Exact encoding match */
|
||||||
}
|
}else if( (enc & p->iPrefEnc & 2)!=0 ){
|
||||||
else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
|
match += 1; /* Both are UTF16, but with different byte orders */
|
||||||
(enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
|
|
||||||
match += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,13 +329,12 @@ void sqlite3FuncDefInsert(
|
|||||||
**
|
**
|
||||||
** If the createFlag argument is true, then a new (blank) FuncDef
|
** If the createFlag argument is true, then a new (blank) FuncDef
|
||||||
** structure is created and liked into the "db" structure if a
|
** structure is created and liked into the "db" structure if a
|
||||||
** no matching function previously existed. When createFlag is true
|
** no matching function previously existed.
|
||||||
** and the nArg parameter is -1, then only a function that accepts
|
|
||||||
** any number of arguments will be returned.
|
|
||||||
**
|
**
|
||||||
** If createFlag is false and nArg is -1, then the first valid
|
** If nArg is -2, then the first valid function found is returned. A
|
||||||
** function found is returned. A function is valid if either xFunc
|
** function is valid if either xFunc or xStep is non-zero. The nArg==(-2)
|
||||||
** or xStep is non-zero.
|
** 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
|
** 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
|
** number of arguments may be returned even if the eTextRep flag does not
|
||||||
@@ -328,14 +346,15 @@ FuncDef *sqlite3FindFunction(
|
|||||||
int nName, /* Number of characters in the name */
|
int nName, /* Number of characters in the name */
|
||||||
int nArg, /* Number of arguments. -1 means any number */
|
int nArg, /* Number of arguments. -1 means any number */
|
||||||
u8 enc, /* Preferred text encoding */
|
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 *p; /* Iterator variable */
|
||||||
FuncDef *pBest = 0; /* Best match found so far */
|
FuncDef *pBest = 0; /* Best match found so far */
|
||||||
int bestScore = 0; /* Score of best match */
|
int bestScore = 0; /* Score of best match */
|
||||||
int h; /* Hash value */
|
int h; /* Hash value */
|
||||||
|
|
||||||
|
assert( nArg>=(-2) );
|
||||||
|
assert( nArg>=(-1) || createFlag==0 );
|
||||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||||
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
|
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
|
||||||
|
|
||||||
@@ -381,7 +400,7 @@ FuncDef *sqlite3FindFunction(
|
|||||||
** exact match for the name, number of arguments and encoding, then add a
|
** exact match for the name, number of arguments and encoding, then add a
|
||||||
** new entry to the hash table and return it.
|
** 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 = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
|
||||||
pBest->zName = (char *)&pBest[1];
|
pBest->zName = (char *)&pBest[1];
|
||||||
pBest->nArg = (u16)nArg;
|
pBest->nArg = (u16)nArg;
|
||||||
|
@@ -533,7 +533,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|||||||
nId = sqlite3Strlen30(zId);
|
nId = sqlite3Strlen30(zId);
|
||||||
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
|
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
|
||||||
if( pDef==0 ){
|
if( pDef==0 ){
|
||||||
pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
|
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
|
||||||
if( pDef==0 ){
|
if( pDef==0 ){
|
||||||
no_such_func = 1;
|
no_such_func = 1;
|
||||||
}else{
|
}else{
|
||||||
|
@@ -2845,7 +2845,7 @@ SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
|
|||||||
IdList *sqlite3IdListDup(sqlite3*,IdList*);
|
IdList *sqlite3IdListDup(sqlite3*,IdList*);
|
||||||
Select *sqlite3SelectDup(sqlite3*,Select*,int);
|
Select *sqlite3SelectDup(sqlite3*,Select*,int);
|
||||||
void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
|
void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
|
||||||
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
|
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
|
||||||
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
||||||
void sqlite3RegisterDateTimeFunctions(void);
|
void sqlite3RegisterDateTimeFunctions(void);
|
||||||
void sqlite3RegisterGlobalFunctions(void);
|
void sqlite3RegisterGlobalFunctions(void);
|
||||||
|
Reference in New Issue
Block a user