mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Store application-defined function names as lower-case to avoid the need
for case conversions before calling xFindFunction on virtual tables. Avoid using lookaside to store the destructors for application defined functions, as lookaside should be reserved for transient allocations. FossilOrigin-Name: 777189ce88799f93f393fd14fd716111c85bcdcb23690fd561f78ea2bd2ce5da
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sa\ssingle\ssentence\sof\sdocumentation\sabout\sthe\svirtual\stable\nscan\sflags.\s\sNo\schanges\sto\scode.
|
C Store\sapplication-defined\sfunction\snames\sas\slower-case\sto\savoid\sthe\sneed\nfor\scase\sconversions\sbefore\scalling\sxFindFunction\son\svirtual\stables.\nAvoid\susing\slookaside\sto\sstore\sthe\sdestructors\sfor\sapplication\sdefined\nfunctions,\sas\slookaside\sshould\sbe\sreserved\sfor\stransient\sallocations.
|
||||||
D 2018-05-26T13:55:04.513
|
D 2018-05-26T16:00:26.368
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
|
F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
|
||||||
@@ -439,7 +439,7 @@ F src/btree.c 8270813c8f0ca91b2802e88ded3755d04ee962a923d431c13bcb6cf3e0c18f63
|
|||||||
F src/btree.h 448f15b98ea85dcf7e4eb76f731cadb89636c676ad25dfaac6de77cd66556598
|
F src/btree.h 448f15b98ea85dcf7e4eb76f731cadb89636c676ad25dfaac6de77cd66556598
|
||||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||||
F src/build.c 50ff3e0fa07646b4d797aae0f773efcdb7602f6a5e2f5da27856503f35200889
|
F src/build.c 50ff3e0fa07646b4d797aae0f773efcdb7602f6a5e2f5da27856503f35200889
|
||||||
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
|
F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288
|
||||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||||
F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48
|
F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48
|
||||||
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||||
@@ -458,7 +458,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
|||||||
F src/insert.c 25f2e3cb93821944dec28921c4cfb7729b3ac6e75d860fd7cd934265404a35b0
|
F src/insert.c 25f2e3cb93821944dec28921c4cfb7729b3ac6e75d860fd7cd934265404a35b0
|
||||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||||
F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b
|
F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b
|
||||||
F src/main.c b56b2d62d5d11e3f5100b25fca34c13c62a0fe73941f6873454a7fa8a454170d
|
F src/main.c 0402e234155e0aad75fe6cd204864f492495be8605a50b4b3d4d72895cced3ce
|
||||||
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
|
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||||
@@ -499,7 +499,7 @@ F src/shell.c.in 51c100206f4b7f86cd9affd80b764825e0edc36ca0190c442e4ca7994611bfe
|
|||||||
F src/sqlite.h.in db327b5de56909e060da241ff89cc3726eadf98e9eb17386fc831bbce80e0820
|
F src/sqlite.h.in db327b5de56909e060da241ff89cc3726eadf98e9eb17386fc831bbce80e0820
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
|
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
|
||||||
F src/sqliteInt.h 5abdade4744cf3bd567afb65bb144bb3c61f6132f86813b995a5ca79c7b584e8
|
F src/sqliteInt.h d2bd297dba08f2390a91c31ff775e0964e9663df5b2910a569fe6f830b8b2beb
|
||||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||||
@@ -567,13 +567,13 @@ F src/vacuum.c 37730af7540033135909ecaee3667dddec043293428d8718546d0d64ba4a5025
|
|||||||
F src/vdbe.c 565f7ccc4153627ef316bcfc2da86cb0766fac4b7dcd07c45a175c347d480f0a
|
F src/vdbe.c 565f7ccc4153627ef316bcfc2da86cb0766fac4b7dcd07c45a175c347d480f0a
|
||||||
F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2
|
F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2
|
||||||
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
|
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
|
||||||
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
|
F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d
|
||||||
F src/vdbeaux.c 3b0650dbebebb196010d8af830551e61ea7dcc0e414a2b747f897305b0bd0b8f
|
F src/vdbeaux.c 3b0650dbebebb196010d8af830551e61ea7dcc0e414a2b747f897305b0bd0b8f
|
||||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||||
F src/vdbemem.c 0cbe9b9560e42b72983cf9e1bceba48f297e51142bfb6b57f3747cf60106b92d
|
F src/vdbemem.c 803323406d8623a7619ea5d5f74016697eeaed19c02b98ce9c3013e77dbe1c38
|
||||||
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
|
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
|
||||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||||
F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
|
F src/vtab.c 10ea07dec111de6fb0a4fc87a7ffa4c65fdc088a19dbfaf7d6f2b128f2e8eb7b
|
||||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||||
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
|
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
|
||||||
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
||||||
@@ -1729,7 +1729,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P b816023ce07d01024d5769e16db924374a49bf909edd12dc1344a0a1ef693db5
|
P 27b4fa5dd0defc6ddaf5d8cde6a1e1162b70d99bfdc69c1d2290621a6d23ed91
|
||||||
R b15b92c251ddbb4db7b9d545bb44f3e8
|
R d728fa434c4672bbeedeb70c9aae9549
|
||||||
U drh
|
U drh
|
||||||
Z 4edf1dbedf87b8720d2f7ca92e7eba80
|
Z 593bd01a2c2330ddb0f8d8891bce9a51
|
||||||
|
@@ -1 +1 @@
|
|||||||
27b4fa5dd0defc6ddaf5d8cde6a1e1162b70d99bfdc69c1d2290621a6d23ed91
|
777189ce88799f93f393fd14fd716111c85bcdcb23690fd561f78ea2bd2ce5da
|
@@ -406,10 +406,12 @@ FuncDef *sqlite3FindFunction(
|
|||||||
if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
|
if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
|
||||||
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
|
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
|
||||||
FuncDef *pOther;
|
FuncDef *pOther;
|
||||||
|
u8 *z;
|
||||||
pBest->zName = (const char*)&pBest[1];
|
pBest->zName = (const char*)&pBest[1];
|
||||||
pBest->nArg = (u16)nArg;
|
pBest->nArg = (u16)nArg;
|
||||||
pBest->funcFlags = enc;
|
pBest->funcFlags = enc;
|
||||||
memcpy((char*)&pBest[1], zName, nName+1);
|
memcpy((char*)&pBest[1], zName, nName+1);
|
||||||
|
for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z];
|
||||||
pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
|
pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
|
||||||
if( pOther==pBest ){
|
if( pOther==pBest ){
|
||||||
sqlite3DbFree(db, pBest);
|
sqlite3DbFree(db, pBest);
|
||||||
|
43
src/main.c
43
src/main.c
@@ -1808,11 +1808,13 @@ int sqlite3_create_function_v2(
|
|||||||
#endif
|
#endif
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
if( xDestroy ){
|
if( xDestroy ){
|
||||||
pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
|
pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor));
|
||||||
if( !pArg ){
|
if( !pArg ){
|
||||||
|
sqlite3OomFault(db);
|
||||||
xDestroy(p);
|
xDestroy(p);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
pArg->nRef = 0;
|
||||||
pArg->xDestroy = xDestroy;
|
pArg->xDestroy = xDestroy;
|
||||||
pArg->pUserData = p;
|
pArg->pUserData = p;
|
||||||
}
|
}
|
||||||
@@ -1820,7 +1822,7 @@ int sqlite3_create_function_v2(
|
|||||||
if( pArg && pArg->nRef==0 ){
|
if( pArg && pArg->nRef==0 ){
|
||||||
assert( rc!=SQLITE_OK );
|
assert( rc!=SQLITE_OK );
|
||||||
xDestroy(p);
|
xDestroy(p);
|
||||||
sqlite3DbFree(db, pArg);
|
sqlite3_free(pArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1858,6 +1860,28 @@ int sqlite3_create_function16(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The following is the implementation of an SQL function that always
|
||||||
|
** fails with an error message stating that the function is used in the
|
||||||
|
** wrong context. The sqlite3_overload_function() API might construct
|
||||||
|
** SQL function that use this routine so that the functions will exist
|
||||||
|
** for name resolution but are actually overloaded by the xFindFunction
|
||||||
|
** method of virtual tables.
|
||||||
|
*/
|
||||||
|
static void sqlite3InvalidFunction(
|
||||||
|
sqlite3_context *context, /* The function calling context */
|
||||||
|
int NotUsed, /* Number of arguments to the function */
|
||||||
|
sqlite3_value **NotUsed2 /* Value of each argument */
|
||||||
|
){
|
||||||
|
const char *zName = (const char*)sqlite3_user_data(context);
|
||||||
|
char *zErr;
|
||||||
|
UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
||||||
|
zErr = sqlite3_mprintf(
|
||||||
|
"unable to use function %s in the requested context", zName);
|
||||||
|
sqlite3_result_error(context, zErr, -1);
|
||||||
|
sqlite3_free(zErr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Declare that a function has been overloaded by a virtual table.
|
** Declare that a function has been overloaded by a virtual table.
|
||||||
**
|
**
|
||||||
@@ -1875,7 +1899,8 @@ int sqlite3_overload_function(
|
|||||||
const char *zName,
|
const char *zName,
|
||||||
int nArg
|
int nArg
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc;
|
||||||
|
char *zCopy;
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||||
if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
|
if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
|
||||||
@@ -1883,13 +1908,13 @@ int sqlite3_overload_function(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
|
rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0;
|
||||||
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
|
|
||||||
0, sqlite3InvalidFunction, 0, 0, 0);
|
|
||||||
}
|
|
||||||
rc = sqlite3ApiExit(db, rc);
|
|
||||||
sqlite3_mutex_leave(db->mutex);
|
sqlite3_mutex_leave(db->mutex);
|
||||||
return rc;
|
if( rc ) return SQLITE_OK;
|
||||||
|
zCopy = sqlite3_mprintf(zName);
|
||||||
|
if( zCopy==0 ) return SQLITE_NOMEM;
|
||||||
|
return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8,
|
||||||
|
zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRACE
|
#ifndef SQLITE_OMIT_TRACE
|
||||||
|
@@ -4166,6 +4166,7 @@ int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
|||||||
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
|
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
|
||||||
FuncDestructor *pDestructor
|
FuncDestructor *pDestructor
|
||||||
);
|
);
|
||||||
|
void sqlite3NoopDestructor(void*);
|
||||||
void sqlite3OomFault(sqlite3*);
|
void sqlite3OomFault(sqlite3*);
|
||||||
void sqlite3OomClear(sqlite3*);
|
void sqlite3OomClear(sqlite3*);
|
||||||
int sqlite3ApiExit(sqlite3 *db, int);
|
int sqlite3ApiExit(sqlite3 *db, int);
|
||||||
@@ -4268,7 +4269,6 @@ int sqlite3VtabCallConnect(Parse*, Table*);
|
|||||||
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
|
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
|
||||||
int sqlite3VtabBegin(sqlite3 *, VTable *);
|
int sqlite3VtabBegin(sqlite3 *, VTable *);
|
||||||
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
|
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
|
||||||
void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
|
|
||||||
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
|
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
|
||||||
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
|
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
|
||||||
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
|
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
|
||||||
|
@@ -787,28 +787,6 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
|
|||||||
return *piTime;
|
return *piTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** The following is the implementation of an SQL function that always
|
|
||||||
** fails with an error message stating that the function is used in the
|
|
||||||
** wrong context. The sqlite3_overload_function() API might construct
|
|
||||||
** SQL function that use this routine so that the functions will exist
|
|
||||||
** for name resolution but are actually overloaded by the xFindFunction
|
|
||||||
** method of virtual tables.
|
|
||||||
*/
|
|
||||||
void sqlite3InvalidFunction(
|
|
||||||
sqlite3_context *context, /* The function calling context */
|
|
||||||
int NotUsed, /* Number of arguments to the function */
|
|
||||||
sqlite3_value **NotUsed2 /* Value of each argument */
|
|
||||||
){
|
|
||||||
const char *zName = context->pFunc->zName;
|
|
||||||
char *zErr;
|
|
||||||
UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
|
||||||
zErr = sqlite3_mprintf(
|
|
||||||
"unable to use function %s in the requested context", zName);
|
|
||||||
sqlite3_result_error(context, zErr, -1);
|
|
||||||
sqlite3_free(zErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Create a new aggregate context for p and return a pointer to
|
** Create a new aggregate context for p and return a pointer to
|
||||||
** its pMem->z element.
|
** its pMem->z element.
|
||||||
|
@@ -800,7 +800,7 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* A no-op destructor */
|
/* A no-op destructor */
|
||||||
static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
|
void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the value stored in *pMem should already be a NULL.
|
** Set the value stored in *pMem should already be a NULL.
|
||||||
|
23
src/vtab.c
23
src/vtab.c
@@ -1049,9 +1049,6 @@ FuncDef *sqlite3VtabOverloadFunction(
|
|||||||
void *pArg = 0;
|
void *pArg = 0;
|
||||||
FuncDef *pNew;
|
FuncDef *pNew;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
char *zLowerName;
|
|
||||||
unsigned char *z;
|
|
||||||
|
|
||||||
|
|
||||||
/* Check to see the left operand is a column in a virtual table */
|
/* Check to see the left operand is a column in a virtual table */
|
||||||
if( NEVER(pExpr==0) ) return pDef;
|
if( NEVER(pExpr==0) ) return pDef;
|
||||||
@@ -1066,16 +1063,22 @@ FuncDef *sqlite3VtabOverloadFunction(
|
|||||||
if( pMod->xFindFunction==0 ) return pDef;
|
if( pMod->xFindFunction==0 ) return pDef;
|
||||||
|
|
||||||
/* Call the xFindFunction method on the virtual table implementation
|
/* Call the xFindFunction method on the virtual table implementation
|
||||||
** to see if the implementation wants to overload this function
|
** to see if the implementation wants to overload this function.
|
||||||
|
**
|
||||||
|
** Though undocumented, we have historically always invoked xFindFunction
|
||||||
|
** with an all lower-case function name. Continue in this tradition to
|
||||||
|
** avoid any chance of an incompatibility.
|
||||||
*/
|
*/
|
||||||
zLowerName = sqlite3DbStrDup(db, pDef->zName);
|
#ifdef SQLITE_DEBUG
|
||||||
if( zLowerName ){
|
{
|
||||||
for(z=(unsigned char*)zLowerName; *z; z++){
|
int i;
|
||||||
*z = sqlite3UpperToLower[*z];
|
for(i=0; pDef->zName[i]; i++){
|
||||||
|
unsigned char x = (unsigned char)pDef->zName[i];
|
||||||
|
assert( x==sqlite3UpperToLower[x] );
|
||||||
}
|
}
|
||||||
rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg);
|
|
||||||
sqlite3DbFree(db, zLowerName);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg);
|
||||||
if( rc==0 ){
|
if( rc==0 ){
|
||||||
return pDef;
|
return pDef;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user