/ Changes On Branch sqlite3_drop_modules_except
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch sqlite3_drop_modules_except Excluding Merge-Ins

This is equivalent to a diff from 5d6f4dfe to e5ba47c2

2019-08-19
20:44
Add the sqlite3_drop_modules() interface. check-in: e2c6fed8 user: drh tags: trunk
20:35
Omit the "_except" term from the name of the new interface. Closed-Leaf check-in: e5ba47c2 user: drh tags: sqlite3_drop_modules_except
2019-08-17
19:55
Fix to the query planner for the LSM1 extension. check-in: 7496e872 user: drh tags: trunk
19:45
The experimental sqlite3_drop_modules_except() interface. check-in: 0851db4d user: drh tags: sqlite3_drop_modules_except
19:31
Fix the new ability to unregister virtual table modules so that it works for the automatic PRAGMA virtual tables. check-in: 5d6f4dfe user: drh tags: trunk
19:13
When populating an ephemeral b-tree for the RHS of an IN(...) clause, avoid applying an affinity to a value that may be used later on for some other purpose. Fix for [c7a117190]. check-in: 43e8b143 user: dan tags: trunk

Changes to src/shell.c.in.

  3647   3647     "    --stmt                  Trace statement execution (SQLITE_TRACE_STMT)",
  3648   3648     "    --profile               Profile statements (SQLITE_TRACE_PROFILE)",
  3649   3649     "    --row                   Trace each row (SQLITE_TRACE_ROW)",
  3650   3650     "    --close                 Trace connection close (SQLITE_TRACE_CLOSE)",
  3651   3651   #endif /* SQLITE_OMIT_TRACE */
  3652   3652   #ifdef SQLITE_DEBUG
  3653   3653     ".unmodule NAME ...       Unregister virtual table modules",
         3654  +  "    --allexcept             Unregister everything except those named",
  3654   3655   #endif
  3655   3656     ".vfsinfo ?AUX?           Information about the top-level VFS",
  3656   3657     ".vfslist                 List all available VFSes",
  3657   3658     ".vfsname ?AUX?           Print the name of the VFS stack",
  3658   3659     ".width NUM1 NUM2 ...     Set column widths for \"column\" mode",
  3659   3660     "     Negative values right-justify",
  3660   3661   };
................................................................................
  6888   6889   ** Return 1 on error, 2 to exit, and 0 otherwise.
  6889   6890   */
  6890   6891   static int do_meta_command(char *zLine, ShellState *p){
  6891   6892     int h = 1;
  6892   6893     int nArg = 0;
  6893   6894     int n, c;
  6894   6895     int rc = 0;
  6895         -  char *azArg[50];
         6896  +  char *azArg[52];
  6896   6897   
  6897   6898   #ifndef SQLITE_OMIT_VIRTUALTABLE
  6898   6899     if( p->expert.pExpert ){
  6899   6900       expertFinish(p, 1, 0);
  6900   6901     }
  6901   6902   #endif
  6902   6903   
  6903   6904     /* Parse the input line into tokens.
  6904   6905     */
  6905         -  while( zLine[h] && nArg<ArraySize(azArg) ){
         6906  +  while( zLine[h] && nArg<ArraySize(azArg)-1 ){
  6906   6907       while( IsSpace(zLine[h]) ){ h++; }
  6907   6908       if( zLine[h]==0 ) break;
  6908   6909       if( zLine[h]=='\'' || zLine[h]=='"' ){
  6909   6910         int delim = zLine[h++];
  6910   6911         azArg[nArg++] = &zLine[h];
  6911   6912         while( zLine[h] && zLine[h]!=delim ){
  6912   6913           if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
................................................................................
  6919   6920       }else{
  6920   6921         azArg[nArg++] = &zLine[h];
  6921   6922         while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
  6922   6923         if( zLine[h] ) zLine[h++] = 0;
  6923   6924         resolve_backslashes(azArg[nArg-1]);
  6924   6925       }
  6925   6926     }
         6927  +  azArg[nArg] = 0;
  6926   6928   
  6927   6929     /* Process the input line.
  6928   6930     */
  6929   6931     if( nArg==0 ) return 0; /* no tokens, no error */
  6930   6932     n = strlen30(azArg[0]);
  6931   6933     c = azArg[0][0];
  6932   6934     clearTempFile(p);
................................................................................
  9403   9405       }
  9404   9406     }else
  9405   9407   #endif /* !defined(SQLITE_OMIT_TRACE) */
  9406   9408   
  9407   9409   #ifdef SQLITE_DEBUG
  9408   9410     if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
  9409   9411       int ii;
         9412  +    int lenOpt;
         9413  +    char *zOpt;
  9410   9414       if( nArg<2 ){
  9411         -      raw_printf(stderr, "Usage: .unmodule NAME ...\n");
         9415  +      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
  9412   9416         rc = 1;
  9413   9417         goto meta_command_exit;
  9414   9418       }
  9415   9419       open_db(p, 0);
  9416         -    for(ii=1; ii<nArg; ii++){
  9417         -      sqlite3_create_module(p->db, azArg[ii], 0, 0);
         9420  +    zOpt = azArg[1];
         9421  +    if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
         9422  +    lenOpt = (int)strlen(zOpt);
         9423  +    if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
         9424  +      assert( azArg[nArg]==0 );
         9425  +      sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
         9426  +    }else{
         9427  +      for(ii=1; ii<nArg; ii++){
         9428  +        sqlite3_create_module(p->db, azArg[ii], 0, 0);
         9429  +      }
  9418   9430       }
  9419   9431     }else
  9420   9432   #endif
  9421   9433   
  9422   9434   #if SQLITE_USER_AUTHENTICATION
  9423   9435     if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
  9424   9436       if( nArg<2 ){

Changes to src/sqlite.h.in.

  6635   6635   ** ^The sqlite3_create_module()
  6636   6636   ** interface is equivalent to sqlite3_create_module_v2() with a NULL
  6637   6637   ** destructor.
  6638   6638   **
  6639   6639   ** ^If the third parameter (the pointer to the sqlite3_module object) is
  6640   6640   ** NULL then no new module is create and any existing modules with the
  6641   6641   ** same name are dropped.
         6642  +**
         6643  +** See also: [sqlite3_drop_modules()]
  6642   6644   */
  6643   6645   int sqlite3_create_module(
  6644   6646     sqlite3 *db,               /* SQLite connection to register module with */
  6645   6647     const char *zName,         /* Name of the module */
  6646   6648     const sqlite3_module *p,   /* Methods for the module */
  6647   6649     void *pClientData          /* Client data for xCreate/xConnect */
  6648   6650   );
................................................................................
  6649   6651   int sqlite3_create_module_v2(
  6650   6652     sqlite3 *db,               /* SQLite connection to register module with */
  6651   6653     const char *zName,         /* Name of the module */
  6652   6654     const sqlite3_module *p,   /* Methods for the module */
  6653   6655     void *pClientData,         /* Client data for xCreate/xConnect */
  6654   6656     void(*xDestroy)(void*)     /* Module destructor function */
  6655   6657   );
         6658  +
         6659  +/*
         6660  +** CAPI3REF: Remove Unnecessary Virtual Table Implementations
         6661  +** METHOD: sqlite3
         6662  +**
         6663  +** ^The sqlite3_drop_modules(D,L) interface removes all virtual
         6664  +** table modules from database connection D except those named on list L.
         6665  +** The L parameter must be either NULL or a pointer to an array of pointers
         6666  +** to strings where the array is terminated by a single NULL pointer.
         6667  +** ^If the L parameter is NULL, then all virtual table modules are removed.
         6668  +**
         6669  +** See also: [sqlite3_create_module()]
         6670  +*/
         6671  +int sqlite3_drop_modules(
         6672  +  sqlite3 *db,                /* Remove modules from this connection */
         6673  +  const char **azKeep         /* Except, do not remove the ones named here */
         6674  +);
  6656   6675   
  6657   6676   /*
  6658   6677   ** CAPI3REF: Virtual Table Instance Object
  6659   6678   ** KEYWORDS: sqlite3_vtab
  6660   6679   **
  6661   6680   ** Every [virtual table module] implementation uses a subclass
  6662   6681   ** of this object to describe a particular instance

Changes to src/test1.c.

  1105   1105     }
  1106   1106   #endif
  1107   1107   
  1108   1108     if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  1109   1109     Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  1110   1110     return TCL_OK;
  1111   1111   }
         1112  +
         1113  +/*
         1114  +** Usage:  sqlite3_drop_modules DB ?NAME ...?
         1115  +**
         1116  +** Invoke the sqlite3_drop_modules(D,L) interface on database
         1117  +** connection DB, in order to drop all modules except those named in
         1118  +** the argument.
         1119  +*/
         1120  +static int SQLITE_TCLAPI test_drop_modules(
         1121  +  void *NotUsed,
         1122  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         1123  +  int argc,              /* Number of arguments */
         1124  +  char **argv            /* Text of each argument */
         1125  +){
         1126  +  int rc;
         1127  +  sqlite3 *db;
         1128  +
         1129  +  if( argc!=2 ){
         1130  +    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
         1131  +       " DB\"", 0);
         1132  +    return TCL_ERROR;
         1133  +  }
         1134  +  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
         1135  +  sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
         1136  +  return TCL_OK;
         1137  +}
  1112   1138   
  1113   1139   /*
  1114   1140   ** Routines to implement the x_count() aggregate function.
  1115   1141   **
  1116   1142   ** x_count() counts the number of non-null arguments.  But there are
  1117   1143   ** some twists for testing purposes.
  1118   1144   **
................................................................................
  7856   7882   #ifndef SQLITE_OMIT_GET_TABLE
  7857   7883        { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
  7858   7884   #endif
  7859   7885        { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
  7860   7886        { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
  7861   7887        { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
  7862   7888        { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
         7889  +     { "sqlite3_drop_modules",          (Tcl_CmdProc*)test_drop_modules     },
  7863   7890        { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
  7864   7891        { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
  7865   7892        { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
  7866   7893        { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
  7867   7894        { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
  7868   7895        { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
  7869   7896        { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },

Changes to src/vtab.c.

   128    128     void (*xDestroy)(void *)        /* Module destructor function */
   129    129   ){
   130    130   #ifdef SQLITE_ENABLE_API_ARMOR
   131    131     if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
   132    132   #endif
   133    133     return createModule(db, zName, pModule, pAux, xDestroy);
   134    134   }
          135  +
          136  +/*
          137  +** External API to drop all virtual-table modules, except those named
          138  +** on the azNames list.
          139  +*/
          140  +int sqlite3_drop_modules(sqlite3 *db, const char** azNames){
          141  +  HashElem *pThis, *pNext;
          142  +#ifdef SQLITE_ENABLE_API_ARMOR
          143  +  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
          144  +#endif
          145  +  for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){
          146  +    Module *pMod = (Module*)sqliteHashData(pThis);
          147  +    pNext = sqliteHashNext(pThis);
          148  +    if( azNames ){
          149  +      int ii;
          150  +      for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){}
          151  +      if( azNames[ii]!=0 ) continue;
          152  +    }
          153  +    createModule(db, pMod->zName, 0, 0, 0);
          154  +  }
          155  +  return SQLITE_OK;
          156  +}
   135    157   
   136    158   /*
   137    159   ** Decrement the reference count on a Module object.  Destroy the
   138    160   ** module when the reference count reaches zero.
   139    161   */
   140    162   void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){
   141    163     assert( pMod->nRefModule>0 );