mirror of https://github.com/sqlite/sqlite
Improvements to the application-defined function mechanism so that it is
more compact and runs faster, especially when the application defines thousands of new SQL functions. FossilOrigin-Name: 3201fbcc5105d23132e6b8b7ac825e66af4f8a39
This commit is contained in:
parent
e75a9eb9bb
commit
80738d9c3e
39
manifest
39
manifest
|
@ -1,5 +1,5 @@
|
||||||
C Provide\sSqlite3_SafeInit()\sand\sSqlite3_SafeUnload()\sentry\spoints\son\sthe\sTCL\ninterface,\sbut\shave\sthe\salways\sreturn\sTCL_ERROR,\sbecause\sthe\snon-standard\s\nTCL\sbuilds\son\sMacs\srequire\sthis.
|
C Improvements\sto\sthe\sapplication-defined\sfunction\smechanism\sso\sthat\sit\sis\nmore\scompact\sand\sruns\sfaster,\sespecially\swhen\sthe\sapplication\sdefines\nthousands\sof\snew\sSQL\sfunctions.
|
||||||
D 2016-02-13T18:54:10.051
|
D 2016-02-15T00:34:16.170
|
||||||
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
|
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 30f075dc4f27a07abb76088946b2944178d85347
|
F Makefile.msc 30f075dc4f27a07abb76088946b2944178d85347
|
||||||
|
@ -284,9 +284,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||||
F src/alter.c 1fbb01c26c64528088f1df8015992fefda387889
|
F src/alter.c 7603afbd61f55e7c644b8de4a42f33e58c0b7eaa
|
||||||
F src/analyze.c fbf0e80d83cc893734e872f932f249a056b86e11
|
F src/analyze.c b148441c7d35b5514ec1a66f9df97be8fa4c68a1
|
||||||
F src/attach.c c16c2648a577fa3def2adfa48c28901376389bc5
|
F src/attach.c 07aa6e77c3906d46d4c36d7c81641dedd6adac91
|
||||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||||
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
|
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
|
||||||
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
|
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
|
||||||
|
@ -295,17 +295,17 @@ F src/btree.c 4c8caaeed7878aafdb607c3d2bcbc365bb0d19a1
|
||||||
F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e
|
F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e
|
||||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||||
F src/build.c 54866fbafa09d494269bdefc79995eb7207003a6
|
F src/build.c 54866fbafa09d494269bdefc79995eb7207003a6
|
||||||
F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce
|
F src/callback.c 0643b8fb06c95a8977beb201b268210d4b131a22
|
||||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||||
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||||
F src/date.c ca17321bc17cca8f40e0843edea4fafff974998e
|
F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1
|
||||||
F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c
|
F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c
|
||||||
F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f
|
F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f
|
||||||
F src/expr.c fbf0706199aea23c54efe36b6932d8307c4eb872
|
F src/expr.c 9adb58153f6e943b703d43e9a1f67f77b5a75721
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 08edad1fce30f761f14b3997e89bad58f9f7f4e0
|
F src/fkey.c 08edad1fce30f761f14b3997e89bad58f9f7f4e0
|
||||||
F src/func.c 86e55fee35b9577e485f47d9dd5c1d34cd513288
|
F src/func.c 552d300265aed09eea21f68ac742a440550c0062
|
||||||
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
|
F src/global.c ded7b97efd16efda5062b65e857198e46c40e652
|
||||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
|
@ -313,7 +313,7 @@ F src/insert.c 9ca97272e9f74ed0efddf3b4350ee12740cebbef
|
||||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||||
F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902
|
F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902
|
||||||
F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
|
F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
|
||||||
F src/main.c b67a45397b93b7ba8fbd6bfcb03423d245baed05
|
F src/main.c 17cfc8ba39fd86bc8201213140db53a65ff3cf2a
|
||||||
F src/malloc.c 337e9808b5231855fe28857950f4f60ae42c417f
|
F src/malloc.c 337e9808b5231855fe28857950f4f60ae42c417f
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||||
|
@ -346,14 +346,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||||
F src/prepare.c c12b786713df3e8270c0f85f988c5359d8b4d87c
|
F src/prepare.c c12b786713df3e8270c0f85f988c5359d8b4d87c
|
||||||
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
|
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
|
||||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||||
F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
|
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
|
||||||
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
||||||
F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d
|
F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d
|
||||||
F src/shell.c 0367440658104bf2ce8d8a9a5a713a4b11c9acbe
|
F src/shell.c 0367440658104bf2ce8d8a9a5a713a4b11c9acbe
|
||||||
F src/sqlite.h.in f80c6ebd85588fc514bfedf3ecb00cec269cb410
|
F src/sqlite.h.in f80c6ebd85588fc514bfedf3ecb00cec269cb410
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
||||||
F src/sqliteInt.h 04ca5b3cdb3bcf87ba6300d5d36b51498f65f28c
|
F src/sqliteInt.h ddd4a48f3ac2a423f003027e73bd8422bfa4d991
|
||||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||||
|
@ -411,7 +411,7 @@ F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b
|
||||||
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
||||||
F src/update.c a7eeeaffad59c6506f01303a071dac11de8269ca
|
F src/update.c a7eeeaffad59c6506f01303a071dac11de8269ca
|
||||||
F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18
|
F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18
|
||||||
F src/util.c 49ce0a65306c1c51d61cb5bc214c71cb62452de6
|
F src/util.c 8073bbdab9cc7209f6741bd44264ede606cbadc6
|
||||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||||
F src/vdbe.c c193299e595a13eba247738e22fce25c49346a6c
|
F src/vdbe.c c193299e595a13eba247738e22fce25c49346a6c
|
||||||
F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
|
F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
|
||||||
|
@ -419,7 +419,7 @@ F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79
|
||||||
F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459
|
F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459
|
||||||
F src/vdbeaux.c deae5d3bd45da0e57c7d9e1d7436333d142dc3bb
|
F src/vdbeaux.c deae5d3bd45da0e57c7d9e1d7436333d142dc3bb
|
||||||
F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db
|
F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db
|
||||||
F src/vdbemem.c 68fcfac37dc6601d98c32cc5adee4d39f2c1b7b4
|
F src/vdbemem.c e0dbb7bb9c2ec566c53c6575b4f51b3fcd426811
|
||||||
F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174
|
F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174
|
||||||
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
|
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
|
||||||
F src/vtab.c bef51b4f693d82b4b0184457faa8625654534091
|
F src/vtab.c bef51b4f693d82b4b0184457faa8625654534091
|
||||||
|
@ -1427,7 +1427,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f
|
F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P a049fbbde5da2e43d41aa8c2b41f9eb21507ac76
|
P 37ec3015ec95035d31e3672f520908a0d36c9d67
|
||||||
R 0ed7109e4c77d1cb323166614bc90c67
|
R 8daa9c28aeb9b7a90a9f45db47e6f0fa
|
||||||
|
T *branch * many-app-functions
|
||||||
|
T *sym-many-app-functions *
|
||||||
|
T -sym-trunk *
|
||||||
U drh
|
U drh
|
||||||
Z 0875f4eabfb763252145d2214f48fc91
|
Z 4df4dc22cfe3910711fb118d648968ac
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
37ec3015ec95035d31e3672f520908a0d36c9d67
|
3201fbcc5105d23132e6b8b7ac825e66af4f8a39
|
10
src/alter.c
10
src/alter.c
|
@ -229,7 +229,7 @@ static void renameTriggerFunc(
|
||||||
** Register built-in functions used to help implement ALTER TABLE
|
** Register built-in functions used to help implement ALTER TABLE
|
||||||
*/
|
*/
|
||||||
void sqlite3AlterFunctions(void){
|
void sqlite3AlterFunctions(void){
|
||||||
static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
|
static FuncDef aAlterTableFuncs[] = {
|
||||||
FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
|
FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
|
FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
|
||||||
|
@ -238,13 +238,7 @@ void sqlite3AlterFunctions(void){
|
||||||
FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
|
FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
int i;
|
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
|
||||||
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
|
||||||
FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
|
|
||||||
|
|
||||||
for(i=0; i<ArraySize(aAlterTableFuncs); i++){
|
|
||||||
sqlite3FuncDefInsert(pHash, &aFunc[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -481,8 +481,7 @@ static const FuncDef statInitFuncdef = {
|
||||||
statInit, /* xSFunc */
|
statInit, /* xSFunc */
|
||||||
0, /* xFinalize */
|
0, /* xFinalize */
|
||||||
"stat_init", /* zName */
|
"stat_init", /* zName */
|
||||||
0, /* pHash */
|
{0}
|
||||||
0 /* pDestructor */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_STAT4
|
#ifdef SQLITE_ENABLE_STAT4
|
||||||
|
@ -781,8 +780,7 @@ static const FuncDef statPushFuncdef = {
|
||||||
statPush, /* xSFunc */
|
statPush, /* xSFunc */
|
||||||
0, /* xFinalize */
|
0, /* xFinalize */
|
||||||
"stat_push", /* zName */
|
"stat_push", /* zName */
|
||||||
0, /* pHash */
|
{0}
|
||||||
0 /* pDestructor */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
|
#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
|
||||||
|
@ -927,8 +925,7 @@ static const FuncDef statGetFuncdef = {
|
||||||
statGet, /* xSFunc */
|
statGet, /* xSFunc */
|
||||||
0, /* xFinalize */
|
0, /* xFinalize */
|
||||||
"stat_get", /* zName */
|
"stat_get", /* zName */
|
||||||
0, /* pHash */
|
{0}
|
||||||
0 /* pDestructor */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
|
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
|
||||||
|
|
|
@ -392,8 +392,7 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){
|
||||||
detachFunc, /* xSFunc */
|
detachFunc, /* xSFunc */
|
||||||
0, /* xFinalize */
|
0, /* xFinalize */
|
||||||
"sqlite_detach", /* zName */
|
"sqlite_detach", /* zName */
|
||||||
0, /* pHash */
|
{0}
|
||||||
0 /* pDestructor */
|
|
||||||
};
|
};
|
||||||
codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
|
codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
|
||||||
}
|
}
|
||||||
|
@ -412,8 +411,7 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
|
||||||
attachFunc, /* xSFunc */
|
attachFunc, /* xSFunc */
|
||||||
0, /* xFinalize */
|
0, /* xFinalize */
|
||||||
"sqlite_attach", /* zName */
|
"sqlite_attach", /* zName */
|
||||||
0, /* pHash */
|
{0}
|
||||||
0 /* pDestructor */
|
|
||||||
};
|
};
|
||||||
codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
|
codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,14 +284,12 @@ static int matchQuality(
|
||||||
** a pointer to the matching FuncDef if found, or 0 if there is no match.
|
** a pointer to the matching FuncDef if found, or 0 if there is no match.
|
||||||
*/
|
*/
|
||||||
static FuncDef *functionSearch(
|
static FuncDef *functionSearch(
|
||||||
FuncDefHash *pHash, /* Hash table to search */
|
|
||||||
int h, /* Hash of the name */
|
int h, /* Hash of the name */
|
||||||
const char *zFunc, /* Name of function */
|
const char *zFunc /* Name of function */
|
||||||
int nFunc /* Number of bytes in zFunc */
|
|
||||||
){
|
){
|
||||||
FuncDef *p;
|
FuncDef *p;
|
||||||
for(p=pHash->a[h]; p; p=p->pHash){
|
for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
|
||||||
if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
|
if( sqlite3StrICmp(p->zName, zFunc)==0 ){
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,23 +299,26 @@ static FuncDef *functionSearch(
|
||||||
/*
|
/*
|
||||||
** Insert a new FuncDef into a FuncDefHash hash table.
|
** Insert a new FuncDef into a FuncDefHash hash table.
|
||||||
*/
|
*/
|
||||||
void sqlite3FuncDefInsert(
|
void sqlite3InsertBuiltinFuncs(
|
||||||
FuncDefHash *pHash, /* The hash table into which to insert */
|
FuncDef *aDef, /* List of global functions to be inserted */
|
||||||
FuncDef *pDef /* The function definition to insert */
|
int nDef /* Length of the apDef[] list */
|
||||||
){
|
){
|
||||||
FuncDef *pOther;
|
int i;
|
||||||
int nName = sqlite3Strlen30(pDef->zName);
|
for(i=0; i<nDef; i++){
|
||||||
u8 c1 = (u8)pDef->zName[0];
|
FuncDef *pOther;
|
||||||
int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
|
const char *zName = aDef[i].zName;
|
||||||
pOther = functionSearch(pHash, h, pDef->zName, nName);
|
int nName = sqlite3Strlen30(zName);
|
||||||
if( pOther ){
|
int h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
|
||||||
assert( pOther!=pDef && pOther->pNext!=pDef );
|
pOther = functionSearch(h, zName);
|
||||||
pDef->pNext = pOther->pNext;
|
if( pOther ){
|
||||||
pOther->pNext = pDef;
|
assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
|
||||||
}else{
|
aDef[i].pNext = pOther->pNext;
|
||||||
pDef->pNext = 0;
|
pOther->pNext = &aDef[i];
|
||||||
pDef->pHash = pHash->a[h];
|
}else{
|
||||||
pHash->a[h] = pDef;
|
aDef[i].pNext = 0;
|
||||||
|
aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
|
||||||
|
sqlite3BuiltinFunctions.a[h] = &aDef[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,8 +345,7 @@ void sqlite3FuncDefInsert(
|
||||||
*/
|
*/
|
||||||
FuncDef *sqlite3FindFunction(
|
FuncDef *sqlite3FindFunction(
|
||||||
sqlite3 *db, /* An open database */
|
sqlite3 *db, /* An open database */
|
||||||
const char *zName, /* Name of the function. Not null-terminated */
|
const char *zName, /* Name of the function. zero-terminated */
|
||||||
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 */
|
||||||
u8 createFlag /* Create new entry if true and does not otherwise exist */
|
u8 createFlag /* Create new entry if true and does not otherwise exist */
|
||||||
|
@ -354,14 +354,15 @@ FuncDef *sqlite3FindFunction(
|
||||||
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 */
|
||||||
|
int nName; /* Length of the name */
|
||||||
|
|
||||||
assert( nArg>=(-2) );
|
assert( nArg>=(-2) );
|
||||||
assert( nArg>=(-1) || createFlag==0 );
|
assert( nArg>=(-1) || createFlag==0 );
|
||||||
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
|
nName = sqlite3Strlen30(zName);
|
||||||
|
|
||||||
/* First search for a match amongst the application-defined functions.
|
/* First search for a match amongst the application-defined functions.
|
||||||
*/
|
*/
|
||||||
p = functionSearch(&db->aFunc, h, zName, nName);
|
p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
|
||||||
while( p ){
|
while( p ){
|
||||||
int score = matchQuality(p, nArg, enc);
|
int score = matchQuality(p, nArg, enc);
|
||||||
if( score>bestScore ){
|
if( score>bestScore ){
|
||||||
|
@ -384,9 +385,9 @@ FuncDef *sqlite3FindFunction(
|
||||||
** So we must not search for built-ins when creating a new function.
|
** So we must not search for built-ins when creating a new function.
|
||||||
*/
|
*/
|
||||||
if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
|
if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
|
||||||
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
|
||||||
bestScore = 0;
|
bestScore = 0;
|
||||||
p = functionSearch(pHash, h, zName, nName);
|
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
|
||||||
|
p = functionSearch(h, zName);
|
||||||
while( p ){
|
while( p ){
|
||||||
int score = matchQuality(p, nArg, enc);
|
int score = matchQuality(p, nArg, enc);
|
||||||
if( score>bestScore ){
|
if( score>bestScore ){
|
||||||
|
@ -403,12 +404,19 @@ 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;
|
||||||
pBest->zName = (char *)&pBest[1];
|
pBest->zName = (char *)&pBest[1];
|
||||||
pBest->nArg = (u16)nArg;
|
pBest->nArg = (u16)nArg;
|
||||||
pBest->funcFlags = enc;
|
pBest->funcFlags = enc;
|
||||||
memcpy(pBest->zName, zName, nName);
|
memcpy(pBest->zName, zName, nName+1);
|
||||||
pBest->zName[nName] = 0;
|
pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
|
||||||
sqlite3FuncDefInsert(&db->aFunc, pBest);
|
if( pOther==pBest ){
|
||||||
|
sqlite3DbFree(db, pBest);
|
||||||
|
sqlite3OomFault(db);
|
||||||
|
return 0;
|
||||||
|
}else{
|
||||||
|
pBest->pNext = pOther;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pBest && (pBest->xSFunc || createFlag) ){
|
if( pBest && (pBest->xSFunc || createFlag) ){
|
||||||
|
|
10
src/date.c
10
src/date.c
|
@ -1136,7 +1136,7 @@ static void currentTimeFunc(
|
||||||
** external linkage.
|
** external linkage.
|
||||||
*/
|
*/
|
||||||
void sqlite3RegisterDateTimeFunctions(void){
|
void sqlite3RegisterDateTimeFunctions(void){
|
||||||
static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
|
static FuncDef aDateTimeFuncs[] = {
|
||||||
#ifndef SQLITE_OMIT_DATETIME_FUNCS
|
#ifndef SQLITE_OMIT_DATETIME_FUNCS
|
||||||
DFUNCTION(julianday, -1, 0, 0, juliandayFunc ),
|
DFUNCTION(julianday, -1, 0, 0, juliandayFunc ),
|
||||||
DFUNCTION(date, -1, 0, 0, dateFunc ),
|
DFUNCTION(date, -1, 0, 0, dateFunc ),
|
||||||
|
@ -1152,11 +1152,5 @@ void sqlite3RegisterDateTimeFunctions(void){
|
||||||
STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
|
STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
int i;
|
sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
|
||||||
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
|
||||||
FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
|
|
||||||
|
|
||||||
for(i=0; i<ArraySize(aDateTimeFuncs); i++){
|
|
||||||
sqlite3FuncDefInsert(pHash, &aFunc[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2888,7 +2888,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||||
ExprList *pFarg; /* List of function arguments */
|
ExprList *pFarg; /* List of function arguments */
|
||||||
int nFarg; /* Number of function arguments */
|
int nFarg; /* Number of function arguments */
|
||||||
FuncDef *pDef; /* The function definition object */
|
FuncDef *pDef; /* The function definition object */
|
||||||
int nId; /* Length of the function name in bytes */
|
|
||||||
const char *zId; /* The function name */
|
const char *zId; /* The function name */
|
||||||
u32 constMask = 0; /* Mask of function arguments that are constant */
|
u32 constMask = 0; /* Mask of function arguments that are constant */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
|
@ -2904,10 +2903,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||||
nFarg = pFarg ? pFarg->nExpr : 0;
|
nFarg = pFarg ? pFarg->nExpr : 0;
|
||||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||||
zId = pExpr->u.zToken;
|
zId = pExpr->u.zToken;
|
||||||
nId = sqlite3Strlen30(zId);
|
pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
|
||||||
pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
|
|
||||||
if( pDef==0 || pDef->xFinalize!=0 ){
|
if( pDef==0 || pDef->xFinalize!=0 ){
|
||||||
sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
|
sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4132,7 +4130,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||||
pItem->iMem = ++pParse->nMem;
|
pItem->iMem = ++pParse->nMem;
|
||||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||||
pItem->pFunc = sqlite3FindFunction(pParse->db,
|
pItem->pFunc = sqlite3FindFunction(pParse->db,
|
||||||
pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
|
pExpr->u.zToken,
|
||||||
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
|
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
|
||||||
if( pExpr->flags & EP_Distinct ){
|
if( pExpr->flags & EP_Distinct ){
|
||||||
pItem->iDistinct = pParse->nTab++;
|
pItem->iDistinct = pParse->nTab++;
|
||||||
|
|
86
src/func.c
86
src/func.c
|
@ -1611,7 +1611,7 @@ static void groupConcatFinalize(sqlite3_context *context){
|
||||||
** of the built-in functions above are part of the global function set.
|
** of the built-in functions above are part of the global function set.
|
||||||
** This routine only deals with those that are not global.
|
** This routine only deals with those that are not global.
|
||||||
*/
|
*/
|
||||||
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
|
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
|
||||||
int rc = sqlite3_overload_function(db, "MATCH", 2);
|
int rc = sqlite3_overload_function(db, "MATCH", 2);
|
||||||
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
|
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
|
||||||
if( rc==SQLITE_NOMEM ){
|
if( rc==SQLITE_NOMEM ){
|
||||||
|
@ -1624,8 +1624,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
|
||||||
*/
|
*/
|
||||||
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
|
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
|
||||||
FuncDef *pDef;
|
FuncDef *pDef;
|
||||||
pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
|
pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
|
||||||
2, SQLITE_UTF8, 0);
|
|
||||||
if( ALWAYS(pDef) ){
|
if( ALWAYS(pDef) ){
|
||||||
pDef->funcFlags |= flagVal;
|
pDef->funcFlags |= flagVal;
|
||||||
}
|
}
|
||||||
|
@ -1673,9 +1672,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||||
pDef = sqlite3FindFunction(db, pExpr->u.zToken,
|
pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
|
||||||
sqlite3Strlen30(pExpr->u.zToken),
|
|
||||||
2, SQLITE_UTF8, 0);
|
|
||||||
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
|
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1696,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||||
**
|
**
|
||||||
** After this routine runs
|
** After this routine runs
|
||||||
*/
|
*/
|
||||||
void sqlite3RegisterGlobalFunctions(void){
|
void sqlite3RegisterBuiltinFunctions(void){
|
||||||
/*
|
/*
|
||||||
** The following array holds FuncDef structures for all of the functions
|
** The following array holds FuncDef structures for all of the functions
|
||||||
** defined in this file.
|
** defined in this file.
|
||||||
|
@ -1707,8 +1704,27 @@ void sqlite3RegisterGlobalFunctions(void){
|
||||||
** The array cannot be constant since changes are made to the
|
** The array cannot be constant since changes are made to the
|
||||||
** FuncDef.pHash elements at start-time. The elements of this array
|
** FuncDef.pHash elements at start-time. The elements of this array
|
||||||
** are read-only after initialization is complete.
|
** are read-only after initialization is complete.
|
||||||
|
**
|
||||||
|
** For peak efficiency, put the most frequently used function last.
|
||||||
*/
|
*/
|
||||||
static SQLITE_WSD FuncDef aBuiltinFunc[] = {
|
static FuncDef aBuiltinFunc[] = {
|
||||||
|
#ifdef SQLITE_SOUNDEX
|
||||||
|
FUNCTION(soundex, 1, 0, 0, soundexFunc ),
|
||||||
|
#endif
|
||||||
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
|
VFUNCTION(load_extension, 1, 0, 0, loadExt ),
|
||||||
|
VFUNCTION(load_extension, 2, 0, 0, loadExt ),
|
||||||
|
#endif
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
|
||||||
|
#endif
|
||||||
|
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
||||||
|
DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
|
||||||
|
DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
|
||||||
|
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
||||||
|
FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
|
||||||
|
FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
|
||||||
|
FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
|
||||||
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
|
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
|
||||||
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
|
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
|
||||||
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
|
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
|
||||||
|
@ -1726,8 +1742,6 @@ void sqlite3RegisterGlobalFunctions(void){
|
||||||
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
|
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
|
||||||
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
|
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
|
||||||
FUNCTION(instr, 2, 0, 0, instrFunc ),
|
FUNCTION(instr, 2, 0, 0, instrFunc ),
|
||||||
FUNCTION(substr, 2, 0, 0, substrFunc ),
|
|
||||||
FUNCTION(substr, 3, 0, 0, substrFunc ),
|
|
||||||
FUNCTION(printf, -1, 0, 0, printfFunc ),
|
FUNCTION(printf, -1, 0, 0, printfFunc ),
|
||||||
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
|
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
|
||||||
FUNCTION(char, -1, 0, 0, charFunc ),
|
FUNCTION(char, -1, 0, 0, charFunc ),
|
||||||
|
@ -1738,40 +1752,22 @@ void sqlite3RegisterGlobalFunctions(void){
|
||||||
#endif
|
#endif
|
||||||
FUNCTION(upper, 1, 0, 0, upperFunc ),
|
FUNCTION(upper, 1, 0, 0, upperFunc ),
|
||||||
FUNCTION(lower, 1, 0, 0, lowerFunc ),
|
FUNCTION(lower, 1, 0, 0, lowerFunc ),
|
||||||
FUNCTION(coalesce, 1, 0, 0, 0 ),
|
|
||||||
FUNCTION(coalesce, 0, 0, 0, 0 ),
|
|
||||||
FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
|
|
||||||
FUNCTION(hex, 1, 0, 0, hexFunc ),
|
FUNCTION(hex, 1, 0, 0, hexFunc ),
|
||||||
FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
|
FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
|
||||||
FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
|
|
||||||
FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
|
|
||||||
FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
|
|
||||||
VFUNCTION(random, 0, 0, 0, randomFunc ),
|
VFUNCTION(random, 0, 0, 0, randomFunc ),
|
||||||
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
|
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
|
||||||
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
|
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
|
||||||
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
|
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
|
||||||
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
|
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
|
||||||
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
|
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
|
||||||
#if SQLITE_USER_AUTHENTICATION
|
|
||||||
FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
|
|
||||||
#endif
|
|
||||||
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
|
||||||
DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
|
|
||||||
DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
|
|
||||||
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
|
||||||
FUNCTION(quote, 1, 0, 0, quoteFunc ),
|
FUNCTION(quote, 1, 0, 0, quoteFunc ),
|
||||||
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
|
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
|
||||||
VFUNCTION(changes, 0, 0, 0, changes ),
|
VFUNCTION(changes, 0, 0, 0, changes ),
|
||||||
VFUNCTION(total_changes, 0, 0, 0, total_changes ),
|
VFUNCTION(total_changes, 0, 0, 0, total_changes ),
|
||||||
FUNCTION(replace, 3, 0, 0, replaceFunc ),
|
FUNCTION(replace, 3, 0, 0, replaceFunc ),
|
||||||
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
|
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
|
||||||
#ifdef SQLITE_SOUNDEX
|
FUNCTION(substr, 2, 0, 0, substrFunc ),
|
||||||
FUNCTION(soundex, 1, 0, 0, soundexFunc ),
|
FUNCTION(substr, 3, 0, 0, substrFunc ),
|
||||||
#endif
|
|
||||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
|
||||||
VFUNCTION(load_extension, 1, 0, 0, loadExt ),
|
|
||||||
VFUNCTION(load_extension, 2, 0, 0, loadExt ),
|
|
||||||
#endif
|
|
||||||
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
|
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
|
||||||
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
|
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
|
||||||
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
|
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
|
||||||
|
@ -1789,20 +1785,32 @@ void sqlite3RegisterGlobalFunctions(void){
|
||||||
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
||||||
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
||||||
#endif
|
#endif
|
||||||
|
FUNCTION(coalesce, 1, 0, 0, 0 ),
|
||||||
|
FUNCTION(coalesce, 0, 0, 0, 0 ),
|
||||||
|
FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
|
||||||
};
|
};
|
||||||
|
|
||||||
int i;
|
|
||||||
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
|
||||||
FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
|
|
||||||
|
|
||||||
for(i=0; i<ArraySize(aBuiltinFunc); i++){
|
|
||||||
sqlite3FuncDefInsert(pHash, &aFunc[i]);
|
|
||||||
}
|
|
||||||
sqlite3RegisterDateTimeFunctions();
|
|
||||||
#ifndef SQLITE_OMIT_ALTERTABLE
|
#ifndef SQLITE_OMIT_ALTERTABLE
|
||||||
sqlite3AlterFunctions();
|
sqlite3AlterFunctions();
|
||||||
#endif
|
#endif
|
||||||
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
|
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
|
||||||
sqlite3AnalyzeFunctions();
|
sqlite3AnalyzeFunctions();
|
||||||
|
#endif
|
||||||
|
sqlite3RegisterDateTimeFunctions();
|
||||||
|
sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
|
||||||
|
|
||||||
|
#if 0 /* Enable to print out how the built-in functions are hashed */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
FuncDef *p;
|
||||||
|
for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
|
||||||
|
printf("FUNC-HASH %02d:", i);
|
||||||
|
for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
|
||||||
|
int n = sqlite3Strlen30(p->zName);
|
||||||
|
int h = p->zName[0] + n;
|
||||||
|
printf(" %s(%d)", p->zName, h);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||||
** database connections. After initialization, this table is
|
** database connections. After initialization, this table is
|
||||||
** read-only.
|
** read-only.
|
||||||
*/
|
*/
|
||||||
SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
|
FuncDefHash sqlite3BuiltinFunctions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Constant tokens for values 0 and 1.
|
** Constant tokens for values 0 and 1.
|
||||||
|
|
43
src/main.c
43
src/main.c
|
@ -218,7 +218,6 @@ int sqlite3_initialize(void){
|
||||||
*/
|
*/
|
||||||
sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
|
sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
|
||||||
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
|
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
|
||||||
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
|
||||||
sqlite3GlobalConfig.inProgress = 1;
|
sqlite3GlobalConfig.inProgress = 1;
|
||||||
#ifdef SQLITE_ENABLE_SQLLOG
|
#ifdef SQLITE_ENABLE_SQLLOG
|
||||||
{
|
{
|
||||||
|
@ -226,8 +225,8 @@ int sqlite3_initialize(void){
|
||||||
sqlite3_init_sqllog();
|
sqlite3_init_sqllog();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
|
memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
|
||||||
sqlite3RegisterGlobalFunctions();
|
sqlite3RegisterBuiltinFunctions();
|
||||||
if( sqlite3GlobalConfig.isPCacheInit==0 ){
|
if( sqlite3GlobalConfig.isPCacheInit==0 ){
|
||||||
rc = sqlite3PcacheInitialize();
|
rc = sqlite3PcacheInitialize();
|
||||||
}
|
}
|
||||||
|
@ -958,7 +957,7 @@ void sqlite3CloseSavepoints(sqlite3 *db){
|
||||||
** with SQLITE_ANY as the encoding.
|
** with SQLITE_ANY as the encoding.
|
||||||
*/
|
*/
|
||||||
static void functionDestroy(sqlite3 *db, FuncDef *p){
|
static void functionDestroy(sqlite3 *db, FuncDef *p){
|
||||||
FuncDestructor *pDestructor = p->pDestructor;
|
FuncDestructor *pDestructor = p->u.pDestructor;
|
||||||
if( pDestructor ){
|
if( pDestructor ){
|
||||||
pDestructor->nRef--;
|
pDestructor->nRef--;
|
||||||
if( pDestructor->nRef==0 ){
|
if( pDestructor->nRef==0 ){
|
||||||
|
@ -1140,18 +1139,17 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||||
*/
|
*/
|
||||||
sqlite3ConnectionClosed(db);
|
sqlite3ConnectionClosed(db);
|
||||||
|
|
||||||
for(j=0; j<ArraySize(db->aFunc.a); j++){
|
for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
|
||||||
FuncDef *pNext, *pHash, *p;
|
FuncDef *pNext, *p;
|
||||||
for(p=db->aFunc.a[j]; p; p=pHash){
|
p = sqliteHashData(i);
|
||||||
pHash = p->pHash;
|
do{
|
||||||
while( p ){
|
functionDestroy(db, p);
|
||||||
functionDestroy(db, p);
|
pNext = p->pNext;
|
||||||
pNext = p->pNext;
|
sqlite3DbFree(db, p);
|
||||||
sqlite3DbFree(db, p);
|
p = pNext;
|
||||||
p = pNext;
|
}while( p );
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
sqlite3HashClear(&db->aFunc);
|
||||||
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
|
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
|
||||||
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
|
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
|
||||||
/* Invoke any destructors registered for collation sequence user data. */
|
/* Invoke any destructors registered for collation sequence user data. */
|
||||||
|
@ -1630,7 +1628,7 @@ int sqlite3CreateFunc(
|
||||||
** is being overridden/deleted but there are no active VMs, allow the
|
** is being overridden/deleted but there are no active VMs, allow the
|
||||||
** operation to continue but invalidate all precompiled statements.
|
** operation to continue but invalidate all precompiled statements.
|
||||||
*/
|
*/
|
||||||
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
|
p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
|
||||||
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
|
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
|
||||||
if( db->nVdbeActive ){
|
if( db->nVdbeActive ){
|
||||||
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
|
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
|
||||||
|
@ -1642,7 +1640,7 @@ int sqlite3CreateFunc(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
|
p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
|
||||||
assert(p || db->mallocFailed);
|
assert(p || db->mallocFailed);
|
||||||
if( !p ){
|
if( !p ){
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
|
@ -1655,7 +1653,7 @@ int sqlite3CreateFunc(
|
||||||
if( pDestructor ){
|
if( pDestructor ){
|
||||||
pDestructor->nRef++;
|
pDestructor->nRef++;
|
||||||
}
|
}
|
||||||
p->pDestructor = pDestructor;
|
p->u.pDestructor = pDestructor;
|
||||||
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
|
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
|
||||||
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
|
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
|
||||||
p->xSFunc = xSFunc ? xSFunc : xStep;
|
p->xSFunc = xSFunc ? xSFunc : xStep;
|
||||||
|
@ -1770,7 +1768,6 @@ int sqlite3_overload_function(
|
||||||
const char *zName,
|
const char *zName,
|
||||||
int nArg
|
int nArg
|
||||||
){
|
){
|
||||||
int nName = sqlite3Strlen30(zName);
|
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||||
|
@ -1779,7 +1776,7 @@ int sqlite3_overload_function(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
|
if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
|
||||||
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
|
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
|
||||||
0, sqlite3InvalidFunction, 0, 0, 0);
|
0, sqlite3InvalidFunction, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -2361,8 +2358,8 @@ static const int aHardLimit[] = {
|
||||||
#if SQLITE_MAX_VDBE_OP<40
|
#if SQLITE_MAX_VDBE_OP<40
|
||||||
# error SQLITE_MAX_VDBE_OP must be at least 40
|
# error SQLITE_MAX_VDBE_OP must be at least 40
|
||||||
#endif
|
#endif
|
||||||
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
|
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
|
||||||
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
|
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
|
||||||
#endif
|
#endif
|
||||||
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
|
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
|
||||||
# error SQLITE_MAX_ATTACHED must be between 0 and 125
|
# error SQLITE_MAX_ATTACHED must be between 0 and 125
|
||||||
|
@ -2886,7 +2883,7 @@ static int openDatabase(
|
||||||
** is accessed.
|
** is accessed.
|
||||||
*/
|
*/
|
||||||
sqlite3Error(db, SQLITE_OK);
|
sqlite3Error(db, SQLITE_OK);
|
||||||
sqlite3RegisterBuiltinFunctions(db);
|
sqlite3RegisterPerConnectionBuiltinFunctions(db);
|
||||||
|
|
||||||
/* Load automatic extensions - extensions that have been registered
|
/* Load automatic extensions - extensions that have been registered
|
||||||
** using the sqlite3_automatic_extension() API.
|
** using the sqlite3_automatic_extension() API.
|
||||||
|
|
|
@ -656,9 +656,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||||
notValid(pParse, pNC, "functions", NC_PartIdx);
|
notValid(pParse, pNC, "functions", NC_PartIdx);
|
||||||
zId = pExpr->u.zToken;
|
zId = pExpr->u.zToken;
|
||||||
nId = sqlite3Strlen30(zId);
|
nId = sqlite3Strlen30(zId);
|
||||||
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
|
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
|
||||||
if( pDef==0 ){
|
if( pDef==0 ){
|
||||||
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
|
pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
|
||||||
if( pDef==0 ){
|
if( pDef==0 ){
|
||||||
no_such_func = 1;
|
no_such_func = 1;
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -1109,13 +1109,15 @@ struct LookasideSlot {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** A hash table for function definitions.
|
** A hash table for built-in function definitions. (Application-defined
|
||||||
|
** functions use a regular table table from hash.h.)
|
||||||
**
|
**
|
||||||
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
|
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
|
||||||
** Collisions are on the FuncDef.pHash chain.
|
** Collisions are on the FuncDef.u.pHash chain.
|
||||||
*/
|
*/
|
||||||
|
#define SQLITE_FUNC_HASH_SZ 23
|
||||||
struct FuncDefHash {
|
struct FuncDefHash {
|
||||||
FuncDef *a[23]; /* Hash table for functions */
|
FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SQLITE_USER_AUTHENTICATION
|
#ifdef SQLITE_USER_AUTHENTICATION
|
||||||
|
@ -1243,7 +1245,7 @@ struct sqlite3 {
|
||||||
VTable **aVTrans; /* Virtual tables with open transactions */
|
VTable **aVTrans; /* Virtual tables with open transactions */
|
||||||
VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
|
VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
|
||||||
#endif
|
#endif
|
||||||
FuncDefHash aFunc; /* Hash table of connection functions */
|
Hash aFunc; /* Hash table of connection functions */
|
||||||
Hash aCollSeq; /* All collating sequences */
|
Hash aCollSeq; /* All collating sequences */
|
||||||
BusyHandler busyHandler; /* Busy callback */
|
BusyHandler busyHandler; /* Busy callback */
|
||||||
Db aDbStatic[2]; /* Static space for the 2 default backends */
|
Db aDbStatic[2]; /* Static space for the 2 default backends */
|
||||||
|
@ -1370,20 +1372,26 @@ struct sqlite3 {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Each SQL function is defined by an instance of the following
|
** Each SQL function is defined by an instance of the following
|
||||||
** structure. A pointer to this structure is stored in the sqlite.aFunc
|
** structure. For global built-in functions (ex: substr(), max(), count())
|
||||||
** hash table. When multiple functions have the same name, the hash table
|
** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
|
||||||
** points to a linked list of these structures.
|
** For per-connection application-defined functions, a pointer to this
|
||||||
|
** structure is held in the db->aHash hash table.
|
||||||
|
**
|
||||||
|
** The u.pHash field is used by the global built-ins. The u.pDestructor
|
||||||
|
** field is used by per-connection app-def functions.
|
||||||
*/
|
*/
|
||||||
struct FuncDef {
|
struct FuncDef {
|
||||||
i16 nArg; /* Number of arguments. -1 means unlimited */
|
i8 nArg; /* Number of arguments. -1 means unlimited */
|
||||||
u16 funcFlags; /* Some combination of SQLITE_FUNC_* */
|
u16 funcFlags; /* Some combination of SQLITE_FUNC_* */
|
||||||
void *pUserData; /* User data parameter */
|
void *pUserData; /* User data parameter */
|
||||||
FuncDef *pNext; /* Next function with same name */
|
FuncDef *pNext; /* Next function with same name */
|
||||||
void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
|
void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
|
||||||
void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
|
void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
|
||||||
char *zName; /* SQL name of the function. */
|
char *zName; /* SQL name of the function. */
|
||||||
FuncDef *pHash; /* Next with a different name but the same hash */
|
union {
|
||||||
FuncDestructor *pDestructor; /* Reference counted destructor function */
|
FuncDef *pHash; /* Next with a different name but the same hash */
|
||||||
|
FuncDestructor *pDestructor; /* Reference counted destructor function */
|
||||||
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1463,28 +1471,28 @@ struct FuncDestructor {
|
||||||
*/
|
*/
|
||||||
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
||||||
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
||||||
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
|
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
|
||||||
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
||||||
{nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
{nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
||||||
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
|
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
|
||||||
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
||||||
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
||||||
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
|
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
|
||||||
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
|
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
|
||||||
{nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
|
{nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
|
||||||
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
|
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
|
||||||
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
|
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
|
||||||
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
|
||||||
pArg, 0, xFunc, 0, #zName, 0, 0}
|
pArg, 0, xFunc, 0, #zName, }
|
||||||
#define LIKEFUNC(zName, nArg, arg, flags) \
|
#define LIKEFUNC(zName, nArg, arg, flags) \
|
||||||
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
|
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
|
||||||
(void *)arg, 0, likeFunc, 0, #zName, 0, 0}
|
(void *)arg, 0, likeFunc, 0, #zName, {0} }
|
||||||
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
|
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
|
||||||
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
|
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
|
||||||
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
|
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
|
||||||
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
|
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
|
||||||
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
|
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
|
||||||
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
|
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** All current savepoints are stored in a linked list starting at
|
** All current savepoints are stored in a linked list starting at
|
||||||
|
@ -3225,7 +3233,7 @@ int sqlite3IsIdChar(u8);
|
||||||
/*
|
/*
|
||||||
** Internal function prototypes
|
** Internal function prototypes
|
||||||
*/
|
*/
|
||||||
#define sqlite3StrICmp sqlite3_stricmp
|
int sqlite3StrICmp(const char*,const char*);
|
||||||
int sqlite3Strlen30(const char*);
|
int sqlite3Strlen30(const char*);
|
||||||
#define sqlite3StrNICmp sqlite3_strnicmp
|
#define sqlite3StrNICmp sqlite3_strnicmp
|
||||||
|
|
||||||
|
@ -3572,11 +3580,11 @@ void sqlite3SelectSetName(Select*,const char*);
|
||||||
#else
|
#else
|
||||||
# define sqlite3SelectSetName(A,B)
|
# define sqlite3SelectSetName(A,B)
|
||||||
#endif
|
#endif
|
||||||
void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
|
void sqlite3InsertBuiltinFuncs(FuncDef*,int);
|
||||||
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
|
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
|
||||||
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
void sqlite3RegisterBuiltinFunctions(void);
|
||||||
void sqlite3RegisterDateTimeFunctions(void);
|
void sqlite3RegisterDateTimeFunctions(void);
|
||||||
void sqlite3RegisterGlobalFunctions(void);
|
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
|
||||||
int sqlite3SafetyCheckOk(sqlite3*);
|
int sqlite3SafetyCheckOk(sqlite3*);
|
||||||
int sqlite3SafetyCheckSickOrOk(sqlite3*);
|
int sqlite3SafetyCheckSickOrOk(sqlite3*);
|
||||||
void sqlite3ChangeCookie(Parse*, int);
|
void sqlite3ChangeCookie(Parse*, int);
|
||||||
|
@ -3737,7 +3745,7 @@ extern const unsigned char sqlite3UpperToLower[];
|
||||||
extern const unsigned char sqlite3CtypeMap[];
|
extern const unsigned char sqlite3CtypeMap[];
|
||||||
extern const Token sqlite3IntTokens[];
|
extern const Token sqlite3IntTokens[];
|
||||||
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
|
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
|
||||||
extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
|
extern FuncDefHash sqlite3BuiltinFunctions;
|
||||||
#ifndef SQLITE_OMIT_WSD
|
#ifndef SQLITE_OMIT_WSD
|
||||||
extern int sqlite3PendingByte;
|
extern int sqlite3PendingByte;
|
||||||
#endif
|
#endif
|
||||||
|
|
15
src/util.c
15
src/util.c
|
@ -256,16 +256,25 @@ void sqlite3TokenInit(Token *p, char *z){
|
||||||
** independence" that SQLite uses internally when comparing identifiers.
|
** independence" that SQLite uses internally when comparing identifiers.
|
||||||
*/
|
*/
|
||||||
int sqlite3_stricmp(const char *zLeft, const char *zRight){
|
int sqlite3_stricmp(const char *zLeft, const char *zRight){
|
||||||
register unsigned char *a, *b;
|
|
||||||
if( zLeft==0 ){
|
if( zLeft==0 ){
|
||||||
return zRight ? -1 : 0;
|
return zRight ? -1 : 0;
|
||||||
}else if( zRight==0 ){
|
}else if( zRight==0 ){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
return sqlite3StrICmp(zLeft, zRight);
|
||||||
|
}
|
||||||
|
int sqlite3StrICmp(const char *zLeft, const char *zRight){
|
||||||
|
unsigned char *a, *b;
|
||||||
|
int c;
|
||||||
a = (unsigned char *)zLeft;
|
a = (unsigned char *)zLeft;
|
||||||
b = (unsigned char *)zRight;
|
b = (unsigned char *)zRight;
|
||||||
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
for(;;){
|
||||||
return UpperToLower[*a] - UpperToLower[*b];
|
c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
|
||||||
|
if( c || *a==0 ) break;
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
|
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
|
||||||
register unsigned char *a, *b;
|
register unsigned char *a, *b;
|
||||||
|
|
|
@ -1186,7 +1186,6 @@ static int valueFromFunction(
|
||||||
FuncDef *pFunc = 0; /* Function definition */
|
FuncDef *pFunc = 0; /* Function definition */
|
||||||
sqlite3_value *pVal = 0; /* New value */
|
sqlite3_value *pVal = 0; /* New value */
|
||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
int nName; /* Size of function name in bytes */
|
|
||||||
ExprList *pList = 0; /* Function arguments */
|
ExprList *pList = 0; /* Function arguments */
|
||||||
int i; /* Iterator variable */
|
int i; /* Iterator variable */
|
||||||
|
|
||||||
|
@ -1194,8 +1193,7 @@ static int valueFromFunction(
|
||||||
assert( (p->flags & EP_TokenOnly)==0 );
|
assert( (p->flags & EP_TokenOnly)==0 );
|
||||||
pList = p->x.pList;
|
pList = p->x.pList;
|
||||||
if( pList ) nVal = pList->nExpr;
|
if( pList ) nVal = pList->nExpr;
|
||||||
nName = sqlite3Strlen30(p->u.zToken);
|
pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
|
||||||
pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
|
|
||||||
assert( pFunc );
|
assert( pFunc );
|
||||||
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|
||||||
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
|
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
|
||||||
|
@ -1457,15 +1455,10 @@ static void recordFunc(
|
||||||
** Register built-in functions used to help read ANALYZE data.
|
** Register built-in functions used to help read ANALYZE data.
|
||||||
*/
|
*/
|
||||||
void sqlite3AnalyzeFunctions(void){
|
void sqlite3AnalyzeFunctions(void){
|
||||||
static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
|
static FuncDef aAnalyzeTableFuncs[] = {
|
||||||
FUNCTION(sqlite_record, 1, 0, 0, recordFunc),
|
FUNCTION(sqlite_record, 1, 0, 0, recordFunc),
|
||||||
};
|
};
|
||||||
int i;
|
sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
|
||||||
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
|
||||||
FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
|
|
||||||
for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
|
|
||||||
sqlite3FuncDefInsert(pHash, &aFunc[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue