Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 676f17a570 |
@@ -1,5 +1,5 @@
|
||||
C For\sthe\s"Valgrind"\stest\sscenario,\sset\sLONGDOUBLE_TYPE=double\sas\svalgrind\ndoes\snot\scorrectly\semulated\sextended\sprecision\son\sx64.
|
||||
D 2023-07-07T12:18:26.936
|
||||
C Proof\sof\sconcept\sfor\sa\snew\ssqlite3_function_needed()\sinterface.
|
||||
D 2023-07-07T16:58:20.565
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -580,7 +580,7 @@ F src/btree.c c0c93b6cb4dc133b528c1290bb4ad0f2414452f9a5758ff2b106af718874f39e
|
||||
F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc
|
||||
F src/btreeInt.h 3b4eff7155c0cea6971dc51f62e3529934a15a6640ec607dd42a767e379cb3a9
|
||||
F src/build.c a8ae3b32d9aa9bbd2c0e97d7c0dd80def9fbca408425de1608f57ee6f47f45f4
|
||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||
F src/callback.c 3520e686ab1d427f33cffb46d554d0a0a2a588866a195c69d1a17103b67dde18
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
|
||||
F src/date.c f73f203b3877cef866c60ab402aec2bf89597219b60635cf50cbe3c5e4533e94
|
||||
@@ -600,7 +600,7 @@ F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
||||
F src/json.c 14c474fb1249a46eb44e878e2361f36abfe686b134039b0d1883d93d61505b4a
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
|
||||
F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002
|
||||
F src/main.c d869b4032a2717b24ad0fd82266ea4d79304a25d942a4b332ff307009f6f10e3
|
||||
F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@@ -638,11 +638,11 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 37953a5f36c60bea413c3c04efcd433b6177009f508ef2ace0494728912fe2e9
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 3ab1186290a311a8ceed1286c0e286209f7fe97b2d02c7593258004ce295dd88
|
||||
F src/shell.c.in d320d8a13636de06d777cc1eab981caca304e175464e98183cf4ea68d93db818
|
||||
F src/sqlite.h.in f999ef3642f381d69679b2516b430dbcb6c5a2a951b7f5e43dc4751b474a5774
|
||||
F src/shell.c.in d6c9ac6ab2c56eac0009ad383f6fd31a410d4cfa04ddf5875496207773fc60b1
|
||||
F src/sqlite.h.in 287bce997bc287c251558b41ffb4ec025b98e7d0c74e3bf22c4919d2edb6d44c
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||
F src/sqliteInt.h f6c5470b7db42318a3de1115757e94b76570ad7697ac547823e01f1166756f1d
|
||||
F src/sqlite3ext.h 51ee0eff1f843bd233c3441d220812964d2166f3c5e5714e7a3d847a778310c4
|
||||
F src/sqliteInt.h 3323b237e3f951a4e0297ce797fb7e65bade820f04aa90876a3cf7c1eee029eb
|
||||
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
|
||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -2043,8 +2043,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 64e6bd1c25d8e1dbfe511cba1921ff052c0fa4fe410fc9ce4435700a70cb88b1
|
||||
R 938acc948a8d28aa6e5bbb237d21a380
|
||||
P d3532eaed1cc671d8149b1bd34ead2a88fb83502a2898a5f60aea0a7daf18958
|
||||
R d4ed9da3aa6365c836a379cf03c29a8d
|
||||
T *branch * need-function
|
||||
T *sym-need-function *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 95c647057214d80d38fbb5e9ad4c9cbc
|
||||
Z e80e56952de95f04df4da782eb785cf5
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
d3532eaed1cc671d8149b1bd34ead2a88fb83502a2898a5f60aea0a7daf18958
|
||||
cd67edc032983b5111ffcf6c73ca1308ef67cf2f16baa25788121827b3038d2f
|
||||
@@ -474,7 +474,28 @@ FuncDef *sqlite3FindFunction(
|
||||
|
||||
if( pBest && (pBest->xSFunc || createFlag) ){
|
||||
return pBest;
|
||||
}else if( db->xFuncNeeded!=0 ){
|
||||
int rc;
|
||||
int (*xFN)(void*,sqlite3*,const char*,int,int) = db->xFuncNeeded;
|
||||
db->xFuncNeeded = 0;
|
||||
rc = xFN(db->pFuncNeededArg,db,zName,nArg,enc);
|
||||
db->xFuncNeeded = xFN;
|
||||
pBest = 0;
|
||||
bestScore = 0;
|
||||
if( rc==SQLITE_OK ){
|
||||
p = (FuncDef*)sqlite3HashFind(&db->aFunc,zName);
|
||||
while( p ){
|
||||
int score = matchQuality(p, nArg, enc);
|
||||
if( score>bestScore ){
|
||||
pBest = p;
|
||||
bestScore = score;
|
||||
}
|
||||
p = p->pNext;
|
||||
}
|
||||
return pBest;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+25
@@ -1219,6 +1219,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
|
||||
db->trace.xV2(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
|
||||
}
|
||||
|
||||
/* Free the function-needed payload pointer */
|
||||
if( db->xFuncNeededFree ) db->xFuncNeededFree(db->pFuncNeededArg);
|
||||
|
||||
/* Force xDisconnect calls on all virtual tables */
|
||||
disconnectAllVtab(db);
|
||||
|
||||
@@ -3705,6 +3708,28 @@ int sqlite3_collation_needed16(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
|
||||
/*
|
||||
** Register a collation sequence factory callback with the database handle
|
||||
** db. Replace any previously installed collation sequence factory.
|
||||
*/
|
||||
int sqlite3_function_needed(
|
||||
sqlite3 *db,
|
||||
void *pFuncNeededArg,
|
||||
int (*xFuncNeeded)(void*,sqlite3*,const char*,int,int),
|
||||
void (*xFuncNeededFree)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( db->xFuncNeededFree ) db->xFuncNeededFree(db->pFuncNeededArg);
|
||||
db->pFuncNeededArg = pFuncNeededArg;
|
||||
db->xFuncNeeded = xFuncNeeded;
|
||||
db->xFuncNeededFree = xFuncNeededFree;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
** This function is now an anachronism. It used to be used to recover from a
|
||||
|
||||
+53
-20
@@ -5383,6 +5383,57 @@ static void shellUSleepFunc(
|
||||
#define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */
|
||||
#define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */
|
||||
|
||||
/*
|
||||
** Unknown function callback
|
||||
*/
|
||||
static int shellUnknownFunction(
|
||||
void *pUserData,
|
||||
sqlite3 *db,
|
||||
const char *zFunc,
|
||||
int nArg,
|
||||
int enc
|
||||
){
|
||||
ShellState *p = (ShellState*)pUserData;
|
||||
(void)enc;
|
||||
(void)nArg;
|
||||
if( sqlite3_stricmp(zFunc,"strtod")==0 ){
|
||||
sqlite3_create_function(db, "strtod", 1, SQLITE_UTF8, 0,
|
||||
shellStrtod, 0, 0);
|
||||
}else
|
||||
if( sqlite3_stricmp(zFunc,"dtostr")==0 ){
|
||||
sqlite3_create_function(db, "dtostr", 1, SQLITE_UTF8, 0,
|
||||
shellDtostr, 0, 0);
|
||||
sqlite3_create_function(db, "dtostr", 2, SQLITE_UTF8, 0,
|
||||
shellDtostr, 0, 0);
|
||||
}else
|
||||
if( sqlite3_stricmp(zFunc,"shell_add_schema")==0 ){
|
||||
sqlite3_create_function(db, "shell_add_schema", 3, SQLITE_UTF8, 0,
|
||||
shellAddSchemaName, 0, 0);
|
||||
}else
|
||||
if( sqlite3_stricmp(zFunc,"shell_module_schema")==0 ){
|
||||
sqlite3_create_function(db, "shell_module_schema", 1, SQLITE_UTF8, 0,
|
||||
shellModuleSchema, 0, 0);
|
||||
}else
|
||||
if( sqlite3_stricmp(zFunc,"shell_putsnl")==0 ){
|
||||
sqlite3_create_function(db, "shell_putsnl", 1, SQLITE_UTF8, p,
|
||||
shellPutsFunc, 0, 0);
|
||||
}else
|
||||
if( sqlite3_stricmp(zFunc,"usleep")==0 ){
|
||||
sqlite3_create_function(db, "usleep",1,SQLITE_UTF8,0,
|
||||
shellUSleepFunc, 0, 0);
|
||||
}
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
else
|
||||
if( sqlite3_stricmp(zFunc,"edit")==0 ){
|
||||
sqlite3_create_function(db, "edit", 1, SQLITE_UTF8, 0,
|
||||
editFunc, 0, 0);
|
||||
sqlite3_create_function(db, "edit", 2, SQLITE_UTF8, 0,
|
||||
editFunc, 0, 0);
|
||||
}
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure the database is open. If it is not, then open it. If
|
||||
** the database fails to open, print an error message and exit.
|
||||
@@ -5503,27 +5554,9 @@ static void open_db(ShellState *p, int openFlags){
|
||||
}
|
||||
#endif
|
||||
|
||||
sqlite3_create_function(p->db, "strtod", 1, SQLITE_UTF8, 0,
|
||||
shellStrtod, 0, 0);
|
||||
sqlite3_create_function(p->db, "dtostr", 1, SQLITE_UTF8, 0,
|
||||
shellDtostr, 0, 0);
|
||||
sqlite3_create_function(p->db, "dtostr", 2, SQLITE_UTF8, 0,
|
||||
shellDtostr, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
|
||||
shellAddSchemaName, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
|
||||
shellModuleSchema, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
|
||||
shellPutsFunc, 0, 0);
|
||||
sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
|
||||
shellUSleepFunc, 0, 0);
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
|
||||
editFunc, 0, 0);
|
||||
sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
|
||||
editFunc, 0, 0);
|
||||
#endif
|
||||
sqlite3_function_needed(p->db, p, shellUnknownFunction, 0);
|
||||
|
||||
|
||||
if( p->openMode==SHELL_OPEN_ZIPFILE ){
|
||||
char *zSql = sqlite3_mprintf(
|
||||
"CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename);
|
||||
|
||||
@@ -6206,6 +6206,54 @@ int sqlite3_create_collation16(
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Function Needed Callbacks
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** The sqlite3_function_needed(D,P,C,X) interface registers a callback
|
||||
** function C which is invoked whenever the SQL parser encounters an
|
||||
** unknown SQL function. The callback may optionally register a suitable
|
||||
** implementation for that unknown function (using [sqlite3_create_function()]
|
||||
** or similar), in which case parsing will continue normally. In this way,
|
||||
** applications with hundreds or thousands of seldom-used application defined
|
||||
** SQL functions can avoid having register them at start-up and instead
|
||||
** register each function if and only if it it actually gets used.
|
||||
**
|
||||
** ^If the callback function C has been registered using the
|
||||
** sqlite3_function_needed(D,P,C,X), then whenever the SQL parser encounters
|
||||
** an unknown SQL function, it will invoke the C callback with 5 arguments:
|
||||
** P, D, F, N, E. P is a copy of the generic pointer P parameter to
|
||||
** the original sqlite3_function_needed() call that registered the
|
||||
** callback. D is the database connection. F is the name of the unknown
|
||||
** function (UTF-8 encoded and zero-terminated but in an arbitrary case).
|
||||
** N is the number of arguments on the F function.
|
||||
** E is the preferred text encoding.
|
||||
**
|
||||
** If the C callback registers a new function with the correct
|
||||
** name and number of arguments and if the callback returns SQLITE_OK, then
|
||||
** the newly registered function is used and parsing continues. If an
|
||||
** appropriate function does not get registered, or if the callback returns
|
||||
** anything other than SQLITE_OK, then an "unknown function" error is generated
|
||||
** as normal.
|
||||
**
|
||||
** Only a single function-needed callback is supported per database connection.
|
||||
** Each call to sqlite3_function_needed() replaces the callback identified
|
||||
** by the previous call to sqlite3_function_needed(). The function-needed
|
||||
** callback mechanism may be disabled by invoking sqlite3_function_needed(D,P,C,X)
|
||||
** using a NULL pointer for the C parameter.
|
||||
**
|
||||
** The X argument to sqlite3_function_needed(D,P,C,X) is an optional
|
||||
** destructor for generic pointer parameter P. If X and C are both not NULL,
|
||||
** then X(P) is invoked when the database connection closes or at the next
|
||||
** call to sqlite3_function_needed().
|
||||
*/
|
||||
int sqlite3_function_needed(
|
||||
sqlite3*,
|
||||
void*,
|
||||
int(*)(void*,sqlite3*,const char*,int,int),
|
||||
void(*)(void*)
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Collation Needed Callbacks
|
||||
** METHOD: sqlite3
|
||||
|
||||
@@ -361,6 +361,8 @@ struct sqlite3_api_routines {
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*function_needed)(sqlite3*,void*,const char*,int,int);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -689,6 +691,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_function_needed sqlite3_api->function_needed
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
@@ -1674,6 +1674,9 @@ struct sqlite3 {
|
||||
int (*xWalCallback)(void *, sqlite3 *, const char *, int);
|
||||
void *pWalArg;
|
||||
#endif
|
||||
int(*xFuncNeeded)(void*,sqlite3*,const char*,int,int);
|
||||
void *pFuncNeededArg;
|
||||
void(*xFuncNeededFree)(void*);
|
||||
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
|
||||
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
|
||||
void *pCollNeededArg;
|
||||
|
||||
Reference in New Issue
Block a user