Index: third_party/sqlite/src/src/loadext.c |
diff --git a/third_party/sqlite/src/src/loadext.c b/third_party/sqlite/src/src/loadext.c |
index c832e684ef593733ea8361a0e0e1fcf21d798f37..2a2afd8654c4aa58e976c8a317d0ec66d277eae5 100644 |
--- a/third_party/sqlite/src/src/loadext.c |
+++ b/third_party/sqlite/src/src/loadext.c |
@@ -84,6 +84,8 @@ |
# define sqlite3_create_module 0 |
# define sqlite3_create_module_v2 0 |
# define sqlite3_declare_vtab 0 |
+# define sqlite3_vtab_config 0 |
+# define sqlite3_vtab_on_conflict 0 |
#endif |
#ifdef SQLITE_OMIT_SHARED_CACHE |
@@ -107,6 +109,7 @@ |
#define sqlite3_blob_open 0 |
#define sqlite3_blob_read 0 |
#define sqlite3_blob_write 0 |
+#define sqlite3_blob_reopen 0 |
#endif |
/* |
@@ -372,6 +375,35 @@ static const sqlite3_api_routines sqlite3Apis = { |
0, |
0, |
#endif |
+ sqlite3_blob_reopen, |
+ sqlite3_vtab_config, |
+ sqlite3_vtab_on_conflict, |
+ sqlite3_close_v2, |
+ sqlite3_db_filename, |
+ sqlite3_db_readonly, |
+ sqlite3_db_release_memory, |
+ sqlite3_errstr, |
+ sqlite3_stmt_busy, |
+ sqlite3_stmt_readonly, |
+ sqlite3_stricmp, |
+ sqlite3_uri_boolean, |
+ sqlite3_uri_int64, |
+ sqlite3_uri_parameter, |
+ sqlite3_vsnprintf, |
+ sqlite3_wal_checkpoint_v2, |
+ /* Version 3.8.7 and later */ |
+ sqlite3_auto_extension, |
+ sqlite3_bind_blob64, |
+ sqlite3_bind_text64, |
+ sqlite3_cancel_auto_extension, |
+ sqlite3_load_extension, |
+ sqlite3_malloc64, |
+ sqlite3_msize, |
+ sqlite3_realloc64, |
+ sqlite3_reset_auto_extension, |
+ sqlite3_result_blob64, |
+ sqlite3_result_text64, |
+ sqlite3_strglob |
}; |
/* |
@@ -396,8 +428,23 @@ static int sqlite3LoadExtension( |
void *handle; |
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); |
char *zErrmsg = 0; |
+ const char *zEntry; |
+ char *zAltEntry = 0; |
void **aHandle; |
- const int nMsg = 300; |
+ int nMsg = 300 + sqlite3Strlen30(zFile); |
+ int ii; |
+ |
+ /* Shared library endings to try if zFile cannot be loaded as written */ |
+ static const char *azEndings[] = { |
+#if SQLITE_OS_WIN |
+ "dll" |
+#elif defined(__APPLE__) |
+ "dylib" |
+#else |
+ "so" |
+#endif |
+ }; |
+ |
if( pzErrMsg ) *pzErrMsg = 0; |
@@ -414,11 +461,17 @@ static int sqlite3LoadExtension( |
return SQLITE_ERROR; |
} |
- if( zProc==0 ){ |
- zProc = "sqlite3_extension_init"; |
- } |
+ zEntry = zProc ? zProc : "sqlite3_extension_init"; |
handle = sqlite3OsDlOpen(pVfs, zFile); |
+#if SQLITE_OS_UNIX || SQLITE_OS_WIN |
+ for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){ |
+ char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]); |
+ if( zAltFile==0 ) return SQLITE_NOMEM; |
+ handle = sqlite3OsDlOpen(pVfs, zAltFile); |
+ sqlite3_free(zAltFile); |
+ } |
+#endif |
if( handle==0 ){ |
if( pzErrMsg ){ |
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); |
@@ -431,19 +484,57 @@ static int sqlite3LoadExtension( |
return SQLITE_ERROR; |
} |
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) |
- sqlite3OsDlSym(pVfs, handle, zProc); |
+ sqlite3OsDlSym(pVfs, handle, zEntry); |
+ |
+ /* If no entry point was specified and the default legacy |
+ ** entry point name "sqlite3_extension_init" was not found, then |
+ ** construct an entry point name "sqlite3_X_init" where the X is |
+ ** replaced by the lowercase value of every ASCII alphabetic |
+ ** character in the filename after the last "/" upto the first ".", |
+ ** and eliding the first three characters if they are "lib". |
+ ** Examples: |
+ ** |
+ ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init |
+ ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init |
+ */ |
+ if( xInit==0 && zProc==0 ){ |
+ int iFile, iEntry, c; |
+ int ncFile = sqlite3Strlen30(zFile); |
+ zAltEntry = sqlite3_malloc(ncFile+30); |
+ if( zAltEntry==0 ){ |
+ sqlite3OsDlClose(pVfs, handle); |
+ return SQLITE_NOMEM; |
+ } |
+ memcpy(zAltEntry, "sqlite3_", 8); |
+ for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){} |
+ iFile++; |
+ if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; |
+ for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ |
+ if( sqlite3Isalpha(c) ){ |
+ zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; |
+ } |
+ } |
+ memcpy(zAltEntry+iEntry, "_init", 6); |
+ zEntry = zAltEntry; |
+ xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) |
+ sqlite3OsDlSym(pVfs, handle, zEntry); |
+ } |
if( xInit==0 ){ |
if( pzErrMsg ){ |
+ nMsg += sqlite3Strlen30(zEntry); |
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); |
if( zErrmsg ){ |
sqlite3_snprintf(nMsg, zErrmsg, |
- "no entry point [%s] in shared library [%s]", zProc,zFile); |
+ "no entry point [%s] in shared library [%s]", zEntry, zFile); |
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); |
} |
- sqlite3OsDlClose(pVfs, handle); |
} |
+ sqlite3OsDlClose(pVfs, handle); |
+ sqlite3_free(zAltEntry); |
return SQLITE_ERROR; |
- }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){ |
+ } |
+ sqlite3_free(zAltEntry); |
+ if( xInit(db, &zErrmsg, &sqlite3Apis) ){ |
if( pzErrMsg ){ |
*pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); |
} |
@@ -591,6 +682,35 @@ int sqlite3_auto_extension(void (*xInit)(void)){ |
} |
/* |
+** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the |
+** set of routines that is invoked for each new database connection, if it |
+** is currently on the list. If xInit is not on the list, then this |
+** routine is a no-op. |
+** |
+** Return 1 if xInit was found on the list and removed. Return 0 if xInit |
+** was not on the list. |
+*/ |
+int sqlite3_cancel_auto_extension(void (*xInit)(void)){ |
+#if SQLITE_THREADSAFE |
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
+#endif |
+ int i; |
+ int n = 0; |
+ wsdAutoextInit; |
+ sqlite3_mutex_enter(mutex); |
+ for(i=wsdAutoext.nExt-1; i>=0; i--){ |
+ if( wsdAutoext.aExt[i]==xInit ){ |
+ wsdAutoext.nExt--; |
+ wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; |
+ n++; |
+ break; |
+ } |
+ } |
+ sqlite3_mutex_leave(mutex); |
+ return n; |
+} |
+ |
+/* |
** Reset the automatic extension loading mechanism. |
*/ |
void sqlite3_reset_auto_extension(void){ |
@@ -618,6 +738,7 @@ void sqlite3_reset_auto_extension(void){ |
void sqlite3AutoLoadExtensions(sqlite3 *db){ |
int i; |
int go = 1; |
+ int rc; |
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); |
wsdAutoextInit; |
@@ -640,8 +761,8 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ |
} |
sqlite3_mutex_leave(mutex); |
zErrmsg = 0; |
- if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){ |
- sqlite3Error(db, SQLITE_ERROR, |
+ if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ |
+ sqlite3ErrorWithMsg(db, rc, |
"automatic extension loading failed: %s", zErrmsg); |
go = 0; |
} |