1
0
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:
drh
2018-05-26 16:00:26 +00:00
parent 7fc86b96ba
commit 9201184711
8 changed files with 63 additions and 55 deletions

View File

@@ -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

View File

@@ -1 +1 @@
27b4fa5dd0defc6ddaf5d8cde6a1e1162b70d99bfdc69c1d2290621a6d23ed91 777189ce88799f93f393fd14fd716111c85bcdcb23690fd561f78ea2bd2ce5da

View File

@@ -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);

View File

@@ -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

View File

@@ -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 *);

View File

@@ -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.

View File

@@ -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.

View File

@@ -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;
} }