]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix fts3 and fts4 so that they can still be used even if the other is dropped by...
authordan <Dan Kennedy>
Thu, 16 Dec 2021 15:29:49 +0000 (15:29 +0000)
committerdan <Dan Kennedy>
Thu, 16 Dec 2021 15:29:49 +0000 (15:29 +0000)
FossilOrigin-Name: a0a8d6c9f0e91996003626e4f80dfac278e3c5bddd9ace5d442061e6c95e49dc

ext/fts3/fts3.c
ext/fts3/fts3Int.h
ext/fts3/fts3_tokenize_vtab.c
manifest
manifest.uuid
src/test1.c
test/fts3dropmod.test [new file with mode: 0644]

index d72945463489ef8e5a1edf7031b4d7b375300737..9a341a89a098a67631124e79f1dd0139531c3402 100644 (file)
   SQLITE_EXTENSION_INIT1
 #endif
 
+typedef struct Fts3HashWrapper Fts3HashWrapper;
+struct Fts3HashWrapper {
+  Fts3Hash hash;                  /* Hash table */
+  int nRef;                       /* Number of pointers to this object */
+};
+
 static int fts3EvalNext(Fts3Cursor *pCsr);
 static int fts3EvalStart(Fts3Cursor *pCsr);
 static int fts3TermSegReaderCursor(
@@ -1172,7 +1178,7 @@ static int fts3InitVtab(
   sqlite3_vtab **ppVTab,          /* Write the resulting vtab structure here */
   char **pzErr                    /* Write any error message here */
 ){
-  Fts3Hash *pHash = (Fts3Hash *)pAux;
+  Fts3Hash *pHash = &((Fts3HashWrapper*)pAux)->hash;
   Fts3Table *p = 0;               /* Pointer to allocated vtab */
   int rc = SQLITE_OK;             /* Return code */
   int i;                          /* Iterator variable */
@@ -4007,9 +4013,12 @@ static const sqlite3_module fts3Module = {
 ** allocated for the tokenizer hash table.
 */
 static void hashDestroy(void *p){
-  Fts3Hash *pHash = (Fts3Hash *)p;
-  sqlite3Fts3HashClear(pHash);
-  sqlite3_free(pHash);
+  Fts3HashWrapper *pHash = (Fts3HashWrapper *)p;
+  pHash->nRef--;
+  if( pHash->nRef<=0 ){
+    sqlite3Fts3HashClear(&pHash->hash);
+    sqlite3_free(pHash);
+  }
 }
 
 /*
@@ -4039,7 +4048,7 @@ void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
 */
 int sqlite3Fts3Init(sqlite3 *db){
   int rc = SQLITE_OK;
-  Fts3Hash *pHash = 0;
+  Fts3HashWrapper *pHash = 0;
   const sqlite3_tokenizer_module *pSimple = 0;
   const sqlite3_tokenizer_module *pPorter = 0;
 #ifndef SQLITE_DISABLE_FTS3_UNICODE
@@ -4067,23 +4076,24 @@ int sqlite3Fts3Init(sqlite3 *db){
   sqlite3Fts3PorterTokenizerModule(&pPorter);
 
   /* Allocate and initialize the hash-table used to store tokenizers. */
-  pHash = sqlite3_malloc(sizeof(Fts3Hash));
+  pHash = sqlite3_malloc(sizeof(Fts3HashWrapper));
   if( !pHash ){
     rc = SQLITE_NOMEM;
   }else{
-    sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
+    sqlite3Fts3HashInit(&pHash->hash, FTS3_HASH_STRING, 1);
+    pHash->nRef = 0;
   }
 
   /* Load the built-in tokenizers into the hash table */
   if( rc==SQLITE_OK ){
-    if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
-     || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) 
+    if( sqlite3Fts3HashInsert(&pHash->hash, "simple", 7, (void *)pSimple)
+     || sqlite3Fts3HashInsert(&pHash->hash, "porter", 7, (void *)pPorter) 
 
 #ifndef SQLITE_DISABLE_FTS3_UNICODE
-     || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) 
+     || sqlite3Fts3HashInsert(&pHash->hash, "unicode61", 10, (void *)pUnicode) 
 #endif
 #ifdef SQLITE_ENABLE_ICU
-     || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
+     || (pIcu && sqlite3Fts3HashInsert(&pHash->hash, "icu", 4, (void *)pIcu))
 #endif
     ){
       rc = SQLITE_NOMEM;
@@ -4092,7 +4102,7 @@ int sqlite3Fts3Init(sqlite3 *db){
 
 #ifdef SQLITE_TEST
   if( rc==SQLITE_OK ){
-    rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
+    rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash);
   }
 #endif
 
@@ -4101,23 +4111,26 @@ int sqlite3Fts3Init(sqlite3 *db){
   ** module with sqlite.
   */
   if( SQLITE_OK==rc 
-   && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer"))
+   && SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer"))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1))
   ){
+    pHash->nRef++;
     rc = sqlite3_create_module_v2(
         db, "fts3", &fts3Module, (void *)pHash, hashDestroy
     );
     if( rc==SQLITE_OK ){
+      pHash->nRef++;
       rc = sqlite3_create_module_v2(
-          db, "fts4", &fts3Module, (void *)pHash, 0
+          db, "fts4", &fts3Module, (void *)pHash, hashDestroy
       );
     }
     if( rc==SQLITE_OK ){
-      rc = sqlite3Fts3InitTok(db, (void *)pHash);
+      pHash->nRef++;
+      rc = sqlite3Fts3InitTok(db, (void *)pHash, hashDestroy);
     }
     return rc;
   }
@@ -4126,7 +4139,7 @@ int sqlite3Fts3Init(sqlite3 *db){
   /* An error has occurred. Delete the hash table and return the error code. */
   assert( rc!=SQLITE_OK );
   if( pHash ){
-    sqlite3Fts3HashClear(pHash);
+    sqlite3Fts3HashClear(&pHash->hash);
     sqlite3_free(pHash);
   }
   return rc;
index 3a62ccc7a7d061f2419e7f3cc291dd3ee96056a5..0626486edff3a74bfc6fa88c7fe244e06324e6e2 100644 (file)
@@ -641,7 +641,7 @@ int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
 int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
 
 /* fts3_tokenize_vtab.c */
-int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *);
+int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*));
 
 /* fts3_unicode2.c (functions generated by parsing unicode text files) */
 #ifndef SQLITE_DISABLE_FTS3_UNICODE
index 8bd22230cc98354318b180c2bc3545570eccb392..65d7eef4c33d193ccf86d4cc27ea1d213d5a843e 100644 (file)
@@ -420,7 +420,7 @@ static int fts3tokRowidMethod(
 ** Register the fts3tok module with database connection db. Return SQLITE_OK
 ** if successful or an error code if sqlite3_create_module() fails.
 */
-int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
+int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){
   static const sqlite3_module fts3tok_module = {
      0,                           /* iVersion      */
      fts3tokConnectMethod,        /* xCreate       */
@@ -449,7 +449,9 @@ int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
   };
   int rc;                         /* Return code */
 
-  rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
+  rc = sqlite3_create_module_v2(
+      db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy
+  );
   return rc;
 }
 
index c5d96cdc93a7b9f3e58d3f02f8762b624d2ec672..5b9ccfd3e67ef0efc733eb76d6e225af30339c53 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\smemory\sleak\sin\sthe\sCLI\sthat\soccurs\safter\san\serror\sin\sthe\s".open"\scommand.
-D 2021-12-16T14:59:25.008
+C Fix\sfts3\sand\sfts4\sso\sthat\sthey\scan\sstill\sbe\sused\seven\sif\sthe\sother\sis\sdropped\sby\sa\scall\sto\ssqlite3_drop_modules().
+D 2021-12-16T15:29:49.836
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -84,9 +84,9 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c da41de21622774b1cb8c3415e8d2a6961ad7c978ab534f2a54434f76a5c4dfbc
+F ext/fts3/fts3.c f27e890395640be4938b9b554cad46fdf1e42e6bd7d64154bbac27d079d00f9e
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h cff59b8b13dafe9d59924a5d710f771ed8b121a55cccbc99b6e2a723fcde14dc
+F ext/fts3/fts3Int.h dafdc371f9fbab175744b06cfe019d5f040cdfdbd11fea752f5dc28d45b04c05
 F ext/fts3/fts3_aux.c f0dc9bd98582615b7750218899bd0c729879b6bbf94d1be57ca1833ff49afc6f
 F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a
 F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
@@ -96,7 +96,7 @@ F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
 F ext/fts3/fts3_snippet.c f9a8149173553113f3c495a503843e30028b5dc3723d0ca798c5ad6142e130e6
 F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1
 F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454
-F ext/fts3/fts3_tokenize_vtab.c 8d15b148e7d88a4280389a200b26e8d52abda4c4ec2e9a35e9d7a1fa50e5aa03
+F ext/fts3/fts3_tokenize_vtab.c a95feda3590f3c3e17672fe35b67ea6112471aeea4c07ef7744a6606b66549aa
 F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7
 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
@@ -561,7 +561,7 @@ F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a3
 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c 48f291e1a7e672a7204884d4c164a8ed3a522ff087c361ada2991f5d54e987f6
-F src/test1.c d6c945a8bb211ed72ea515f0b9743caeaf38c66da6418a7b1dcf3764e1368bbb
+F src/test1.c 37b323d74aef3156394478bd09dff855332077e537b37c9a7e455c03cb04da09
 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
@@ -991,6 +991,7 @@ F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4
 F test/fts3defer2.test 3da52ca2114e300e9971eee2f0cc1a2e5f27e6a9ee67957d49e63e41fdfcc0e7
 F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd
 F test/fts3drop.test 1b906e293d6773812587b3dc458cb9e8f3f0c297
+F test/fts3dropmod.test 30e0e43011ccb5aa8920922b123480415d8504cc4192d7cf342a45dcabea54a7
 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
 F test/fts3expr.test ebae205a7a89446c32583bcd492dcb817b9f6b31819bb4dde2583bb99c77e526
 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
@@ -1934,7 +1935,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9406d95d3fbaf0d8e65623adb790845f78a7456fb32aafd7fa4f74eda2f2dacc
-R e0df8ce6fe4f8339b59c88c348589e55
-U drh
-Z 6900fb872cf581b1501f7decf3624ec2
+P d156123885abe6bf23c3530de99be257f82ef85b89fbe019568ac60fa1ed5bb7
+R a5bbf409ca818885e606c4cbcf796195
+U dan
+Z ded9a804bf5da97234a4d2625392c243
index 74e74828c8ebb34c1321df9315279b27259d1778..be87a011d53842a49351e9a875614c5f37de6580 100644 (file)
@@ -1 +1 @@
-d156123885abe6bf23c3530de99be257f82ef85b89fbe019568ac60fa1ed5bb7
\ No newline at end of file
+a0a8d6c9f0e91996003626e4f80dfac278e3c5bddd9ace5d442061e6c95e49dc
\ No newline at end of file
index 6060290b98dcee854c0f0f5b4d77310c969481eb..8cdb7b285e391244bc6a28bf6872dfb763871ed5 100644 (file)
@@ -1097,7 +1097,7 @@ static int SQLITE_TCLAPI test_drop_modules(
 ){
   sqlite3 *db;
 
-  if( argc!=2 ){
+  if( argc<2 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
        " DB\"", 0);
     return TCL_ERROR;
diff --git a/test/fts3dropmod.test b/test/fts3dropmod.test
new file mode 100644 (file)
index 0000000..3739c31
--- /dev/null
@@ -0,0 +1,44 @@
+# 2021 December 16
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#*************************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this script is testing the FTS3 module.
+#
+# $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix fts3dropmod
+
+# If SQLITE_ENABLE_FTS3 is defined, omit this file.
+ifcapable !fts3 {
+  finish_test
+  return
+}
+
+sqlite3_drop_modules db fts3
+do_execsql_test 1.0 {
+  CREATE VIRTUAL TABLE t1 USING fts3(x);
+} 
+do_catchsql_test 1.1 {
+  CREATE VIRTUAL TABLE t2 USING fts4(x);
+} {1 {no such module: fts4}}
+
+reset_db
+sqlite3_drop_modules db fts4
+do_execsql_test 2.0 {
+  CREATE VIRTUAL TABLE t1 USING fts4(x);
+} 
+do_catchsql_test 2.1 {
+  CREATE VIRTUAL TABLE t2 USING fts3(x);
+} {1 {no such module: fts4}}
+
+finish_test