/ Check-in [31942b3d]
Login

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

Overview
Comment:Initial code to make shadow tables read-only to ordinary SQL. The now xShadowName method is added to the sqlite3_module object and is used to identify potential shadow tables. The SQLITE_PREPARE_SHADOW argument to sqlite3_prepare_v3() is defined. It is designed to permit writing to shadow tables, but is currently an unused placeholder.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | read-only-shadow
Files: files | file ages | folders
SHA3-256: 31942b3dd3f66eb0d9977bf1cadc2f2d7be7967cce2b55784be0b939dfef1985
User & Date: drh 2018-11-05 23:01:45
Context
2018-11-06
13:37
Add enforcement of read-only on shadow tables. This does not currently work since some virtual tables are attempting to update shadow tables using sqlite3_exec(). check-in: f79b47c9 user: drh tags: read-only-shadow
2018-11-05
23:01
Initial code to make shadow tables read-only to ordinary SQL. The now xShadowName method is added to the sqlite3_module object and is used to identify potential shadow tables. The SQLITE_PREPARE_SHADOW argument to sqlite3_prepare_v3() is defined. It is designed to permit writing to shadow tables, but is currently an unused placeholder. check-in: 31942b3d user: drh tags: read-only-shadow
19:37
Add the SQLITE_DBCONFIG_DEFENSIVE flag. check-in: 11d98414 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to ext/expert/sqlite3expert.c.

   640    640       0,                            /* xCommit - commit transaction */
   641    641       0,                            /* xRollback - rollback transaction */
   642    642       0,                            /* xFindFunction - function overloading */
   643    643       0,                            /* xRename - rename the table */
   644    644       0,                            /* xSavepoint */
   645    645       0,                            /* xRelease */
   646    646       0,                            /* xRollbackTo */
          647  +    0,                            /* xShadowName */
   647    648     };
   648    649   
   649    650     return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
   650    651   }
   651    652   /*
   652    653   ** End of virtual table implementation.
   653    654   *************************************************************************/

Changes to ext/fts3/fts3.c.

  3841   3841     UNUSED_PARAMETER(iSavepoint);
  3842   3842     assert( p->inTransaction );
  3843   3843     assert( p->mxSavepoint >= iSavepoint );
  3844   3844     TESTONLY( p->mxSavepoint = iSavepoint );
  3845   3845     sqlite3Fts3PendingTermsClear(p);
  3846   3846     return SQLITE_OK;
  3847   3847   }
         3848  +
         3849  +/*
         3850  +** Return true if zName is the extension on one of the shadow tables used
         3851  +** by this module.
         3852  +*/
         3853  +static int fts3ShadowName(const char *zName){
         3854  +  static const char *azName[] = {
         3855  +    "content", "docsize", "segdir", "segments", "stat", 
         3856  +  };
         3857  +  unsigned int i;
         3858  +  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
         3859  +    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
         3860  +  }
         3861  +  return 0;
         3862  +}
  3848   3863   
  3849   3864   static const sqlite3_module fts3Module = {
  3850         -  /* iVersion      */ 2,
         3865  +  /* iVersion      */ 3,
  3851   3866     /* xCreate       */ fts3CreateMethod,
  3852   3867     /* xConnect      */ fts3ConnectMethod,
  3853   3868     /* xBestIndex    */ fts3BestIndexMethod,
  3854   3869     /* xDisconnect   */ fts3DisconnectMethod,
  3855   3870     /* xDestroy      */ fts3DestroyMethod,
  3856   3871     /* xOpen         */ fts3OpenMethod,
  3857   3872     /* xClose        */ fts3CloseMethod,
................................................................................
  3866   3881     /* xCommit       */ fts3CommitMethod,
  3867   3882     /* xRollback     */ fts3RollbackMethod,
  3868   3883     /* xFindFunction */ fts3FindFunctionMethod,
  3869   3884     /* xRename */       fts3RenameMethod,
  3870   3885     /* xSavepoint    */ fts3SavepointMethod,
  3871   3886     /* xRelease      */ fts3ReleaseMethod,
  3872   3887     /* xRollbackTo   */ fts3RollbackToMethod,
         3888  +  /* xShadowName   */ fts3ShadowName,
  3873   3889   };
  3874   3890   
  3875   3891   /*
  3876   3892   ** This function is registered as the module destructor (called when an
  3877   3893   ** FTS3 enabled database connection is closed). It frees the memory
  3878   3894   ** allocated for the tokenizer hash table.
  3879   3895   */

Changes to ext/fts3/fts3_aux.c.

   535    535        0,                           /* xSync         */
   536    536        0,                           /* xCommit       */
   537    537        0,                           /* xRollback     */
   538    538        0,                           /* xFindFunction */
   539    539        0,                           /* xRename       */
   540    540        0,                           /* xSavepoint    */
   541    541        0,                           /* xRelease      */
   542         -     0                            /* xRollbackTo   */
          542  +     0,                           /* xRollbackTo   */
          543  +     0                            /* xShadowName   */
   543    544     };
   544    545     int rc;                         /* Return code */
   545    546   
   546    547     rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
   547    548     return rc;
   548    549   }
   549    550   
   550    551   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_term.c.

   357    357        0,                           /* xSync         */
   358    358        0,                           /* xCommit       */
   359    359        0,                           /* xRollback     */
   360    360        0,                           /* xFindFunction */
   361    361        0,                           /* xRename       */
   362    362        0,                           /* xSavepoint    */
   363    363        0,                           /* xRelease      */
   364         -     0                            /* xRollbackTo   */
          364  +     0,                           /* xRollbackTo   */
          365  +     0                            /* xShadowName   */
   365    366     };
   366    367     int rc;                         /* Return code */
   367    368   
   368    369     rc = sqlite3_create_module(db, "fts4term", &fts3term_module, 0);
   369    370     return rc;
   370    371   }
   371    372   
   372    373   #endif
   373    374   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_tokenize_vtab.c.

   439    439        0,                           /* xSync         */
   440    440        0,                           /* xCommit       */
   441    441        0,                           /* xRollback     */
   442    442        0,                           /* xFindFunction */
   443    443        0,                           /* xRename       */
   444    444        0,                           /* xSavepoint    */
   445    445        0,                           /* xRelease      */
   446         -     0                            /* xRollbackTo   */
          446  +     0,                           /* xRollbackTo   */
          447  +     0                            /* xShadowName   */
   447    448     };
   448    449     int rc;                         /* Return code */
   449    450   
   450    451     rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
   451    452     return rc;
   452    453   }
   453    454   
   454    455   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_write.c.

   403    403         zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
   404    404       }else{
   405    405         zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
   406    406       }
   407    407       if( !zSql ){
   408    408         rc = SQLITE_NOMEM;
   409    409       }else{
   410         -      rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
          410  +      rc = sqlite3_prepare_v3(p->db, zSql, -1,
          411  +                              SQLITE_PREPARE_PERSISTENT | SQLITE_PREPARE_SHADOW,
   411    412                                 &pStmt, NULL);
   412    413         sqlite3_free(zSql);
   413    414         assert( rc==SQLITE_OK || pStmt==0 );
   414    415         p->aStmt[eStmt] = pStmt;
   415    416       }
   416    417     }
   417    418     if( apVal ){

Changes to ext/fts5/fts5_index.c.

   725    725     Fts5Index *p,
   726    726     sqlite3_stmt **ppStmt,
   727    727     char *zSql
   728    728   ){
   729    729     if( p->rc==SQLITE_OK ){
   730    730       if( zSql ){
   731    731         p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
   732         -                                 SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
          732  +                                SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_SHADOW,
          733  +                                ppStmt, 0);
   733    734       }else{
   734    735         p->rc = SQLITE_NOMEM;
   735    736       }
   736    737     }
   737    738     sqlite3_free(zSql);
   738    739     return p->rc;
   739    740   }
................................................................................
   776    777           "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", 
   777    778             pConfig->zDb, pConfig->zName
   778    779       );
   779    780       if( zSql==0 ){
   780    781         rc = SQLITE_NOMEM;
   781    782       }else{
   782    783         rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
   783         -                              SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
          784  +                              SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_SHADOW,
          785  +                              &p->pDeleter, 0);
   784    786         sqlite3_free(zSql);
   785    787       }
   786    788       if( rc!=SQLITE_OK ){
   787    789         p->rc = rc;
   788    790         return;
   789    791       }
   790    792     }

Changes to ext/fts5/fts5_main.c.

   886    886   
   887    887     va_start(ap, zFmt);
   888    888     zSql = sqlite3_vmprintf(zFmt, ap);
   889    889     if( zSql==0 ){
   890    890       rc = SQLITE_NOMEM; 
   891    891     }else{
   892    892       rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, 
   893         -                            SQLITE_PREPARE_PERSISTENT, &pRet, 0);
          893  +                            SQLITE_PREPARE_PERSISTENT |SQLITE_PREPARE_SHADOW,
          894  +                            &pRet, 0);
   894    895       if( rc!=SQLITE_OK ){
   895    896         *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
   896    897       }
   897    898       sqlite3_free(zSql);
   898    899     }
   899    900   
   900    901     va_end(ap);
................................................................................
  2640   2641     int nArg,                       /* Number of args */
  2641   2642     sqlite3_value **apUnused        /* Function arguments */
  2642   2643   ){
  2643   2644     assert( nArg==0 );
  2644   2645     UNUSED_PARAM2(nArg, apUnused);
  2645   2646     sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
  2646   2647   }
         2648  +
         2649  +/*
         2650  +** Return true if zName is the extension on one of the shadow tables used
         2651  +** by this module.
         2652  +*/
         2653  +static int fts5ShadowName(const char *zName){
         2654  +  static const char *azName[] = {
         2655  +    "config", "content", "data", "docsize", "idx"
         2656  +  };
         2657  +  unsigned int i;
         2658  +  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
         2659  +    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
         2660  +  }
         2661  +  return 0;
         2662  +}
  2647   2663   
  2648   2664   static int fts5Init(sqlite3 *db){
  2649   2665     static const sqlite3_module fts5Mod = {
  2650         -    /* iVersion      */ 2,
         2666  +    /* iVersion      */ 3,
  2651   2667       /* xCreate       */ fts5CreateMethod,
  2652   2668       /* xConnect      */ fts5ConnectMethod,
  2653   2669       /* xBestIndex    */ fts5BestIndexMethod,
  2654   2670       /* xDisconnect   */ fts5DisconnectMethod,
  2655   2671       /* xDestroy      */ fts5DestroyMethod,
  2656   2672       /* xOpen         */ fts5OpenMethod,
  2657   2673       /* xClose        */ fts5CloseMethod,
................................................................................
  2666   2682       /* xCommit       */ fts5CommitMethod,
  2667   2683       /* xRollback     */ fts5RollbackMethod,
  2668   2684       /* xFindFunction */ fts5FindFunctionMethod,
  2669   2685       /* xRename       */ fts5RenameMethod,
  2670   2686       /* xSavepoint    */ fts5SavepointMethod,
  2671   2687       /* xRelease      */ fts5ReleaseMethod,
  2672   2688       /* xRollbackTo   */ fts5RollbackToMethod,
         2689  +    /* xShadowName   */ fts5ShadowName
  2673   2690     };
  2674   2691   
  2675   2692     int rc;
  2676   2693     Fts5Global *pGlobal = 0;
  2677   2694   
  2678   2695     pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
  2679   2696     if( pGlobal==0 ){

Changes to ext/fts5/fts5_storage.c.

   133    133           break;
   134    134       }
   135    135   
   136    136       if( zSql==0 ){
   137    137         rc = SQLITE_NOMEM;
   138    138       }else{
   139    139         rc = sqlite3_prepare_v3(pC->db, zSql, -1,
   140         -                              SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
          140  +                              SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_SHADOW,
          141  +                              &p->aStmt[eStmt], 0);
   141    142         sqlite3_free(zSql);
   142    143         if( rc!=SQLITE_OK && pzErrMsg ){
   143    144           *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
   144    145         }
   145    146       }
   146    147     }
   147    148   

Changes to ext/fts5/fts5_test_tok.c.

   467    467        0,                           /* xSync         */
   468    468        0,                           /* xCommit       */
   469    469        0,                           /* xRollback     */
   470    470        0,                           /* xFindFunction */
   471    471        0,                           /* xRename       */
   472    472        0,                           /* xSavepoint    */
   473    473        0,                           /* xRelease      */
   474         -     0                            /* xRollbackTo   */
          474  +     0,                           /* xRollbackTo   */
          475  +     0                            /* xShadowName   */
   475    476     };
   476    477     int rc;                         /* Return code */
   477    478   
   478    479     rc = sqlite3_create_module(db, "fts5tokenize", &fts5tok_module, (void*)pApi);
   479    480     return rc;
   480    481   }
   481    482   
   482    483   #endif /* defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5) */

Changes to ext/fts5/fts5_vocab.c.

   751    751       /* xCommit       */ 0,
   752    752       /* xRollback     */ 0,
   753    753       /* xFindFunction */ 0,
   754    754       /* xRename       */ 0,
   755    755       /* xSavepoint    */ 0,
   756    756       /* xRelease      */ 0,
   757    757       /* xRollbackTo   */ 0,
          758  +    /* xShadowName   */ 0
   758    759     };
   759    760     void *p = (void*)pGlobal;
   760    761   
   761    762     return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
   762    763   }
   763         -
   764         -

Changes to ext/misc/amatch.c.

  1469   1469     0,                      /* xSync */
  1470   1470     0,                      /* xCommit */
  1471   1471     0,                      /* xRollback */
  1472   1472     0,                      /* xFindMethod */
  1473   1473     0,                      /* xRename */
  1474   1474     0,                      /* xSavepoint */
  1475   1475     0,                      /* xRelease */
  1476         -  0                       /* xRollbackTo */
         1476  +  0,                      /* xRollbackTo */
         1477  +  0                       /* xShadowName */
  1477   1478   };
  1478   1479   
  1479   1480   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  1480   1481   
  1481   1482   /*
  1482   1483   ** Register the amatch virtual table
  1483   1484   */

Changes to ext/misc/btreeinfo.c.

   407    407       0,                           /* xCommit */
   408    408       0,                           /* xRollback */
   409    409       0,                           /* xFindMethod */
   410    410       0,                           /* xRename */
   411    411       0,                           /* xSavepoint */
   412    412       0,                           /* xRelease */
   413    413       0,                           /* xRollbackTo */
          414  +    0                            /* xShadowName */
   414    415     };
   415    416     return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0);
   416    417   }
   417    418   
   418    419   #ifdef _WIN32
   419    420   __declspec(dllexport)
   420    421   #endif

Changes to ext/misc/closure.c.

   934    934     0,                      /* xSync */
   935    935     0,                      /* xCommit */
   936    936     0,                      /* xRollback */
   937    937     0,                      /* xFindMethod */
   938    938     0,                      /* xRename */
   939    939     0,                      /* xSavepoint */
   940    940     0,                      /* xRelease */
   941         -  0                       /* xRollbackTo */
          941  +  0,                      /* xRollbackTo */
          942  +  0                       /* xShadowName */
   942    943   };
   943    944   
   944    945   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   945    946   
   946    947   /*
   947    948   ** Register the closure virtual table
   948    949   */

Changes to ext/misc/completion.c.

   464    464     0,                         /* xSync */
   465    465     0,                         /* xCommit */
   466    466     0,                         /* xRollback */
   467    467     0,                         /* xFindMethod */
   468    468     0,                         /* xRename */
   469    469     0,                         /* xSavepoint */
   470    470     0,                         /* xRelease */
   471         -  0                          /* xRollbackTo */
          471  +  0,                         /* xRollbackTo */
          472  +  0                          /* xShadowName */
   472    473   };
   473    474   
   474    475   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   475    476   
   476    477   int sqlite3CompletionVtabInit(sqlite3 *db){
   477    478     int rc = SQLITE_OK;
   478    479   #ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/explain.c.

   276    276     0,                         /* xCommit */
   277    277     0,                         /* xRollback */
   278    278     0,                         /* xFindMethod */
   279    279     0,                         /* xRename */
   280    280     0,                         /* xSavepoint */
   281    281     0,                         /* xRelease */
   282    282     0,                         /* xRollbackTo */
          283  +  0,                         /* xShadowName */
   283    284   };
   284    285   
   285    286   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   286    287   
   287    288   int sqlite3ExplainVtabInit(sqlite3 *db){
   288    289     int rc = SQLITE_OK;
   289    290   #ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/fileio.c.

   884    884       0,                         /* xSync */
   885    885       0,                         /* xCommit */
   886    886       0,                         /* xRollback */
   887    887       0,                         /* xFindMethod */
   888    888       0,                         /* xRename */
   889    889       0,                         /* xSavepoint */
   890    890       0,                         /* xRelease */
   891         -    0                          /* xRollbackTo */
          891  +    0,                         /* xRollbackTo */
          892  +    0,                         /* xShadowName */
   892    893     };
   893    894   
   894    895     int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
   895    896     return rc;
   896    897   }
   897    898   #else         /* SQLITE_OMIT_VIRTUALTABLE */
   898    899   # define fsdirRegister(x) SQLITE_OK

Changes to ext/misc/json1.c.

  2384   2384     0,                         /* xSync */
  2385   2385     0,                         /* xCommit */
  2386   2386     0,                         /* xRollback */
  2387   2387     0,                         /* xFindMethod */
  2388   2388     0,                         /* xRename */
  2389   2389     0,                         /* xSavepoint */
  2390   2390     0,                         /* xRelease */
  2391         -  0                          /* xRollbackTo */
         2391  +  0,                         /* xRollbackTo */
         2392  +  0                          /* xShadowName */
  2392   2393   };
  2393   2394   
  2394   2395   /* The methods of the json_tree virtual table. */
  2395   2396   static sqlite3_module jsonTreeModule = {
  2396   2397     0,                         /* iVersion */
  2397   2398     0,                         /* xCreate */
  2398   2399     jsonEachConnect,           /* xConnect */
................................................................................
  2411   2412     0,                         /* xSync */
  2412   2413     0,                         /* xCommit */
  2413   2414     0,                         /* xRollback */
  2414   2415     0,                         /* xFindMethod */
  2415   2416     0,                         /* xRename */
  2416   2417     0,                         /* xSavepoint */
  2417   2418     0,                         /* xRelease */
  2418         -  0                          /* xRollbackTo */
         2419  +  0,                         /* xRollbackTo */
         2420  +  0                          /* xShadowName */
  2419   2421   };
  2420   2422   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  2421   2423   
  2422   2424   /****************************************************************************
  2423   2425   ** The following routines are the only publically visible identifiers in this
  2424   2426   ** file.  Call the following routines in order to register the various SQL
  2425   2427   ** functions and the virtual table implemented by this file.

Changes to ext/misc/memstat.c.

   391    391     0,                         /* xCommit */
   392    392     0,                         /* xRollback */
   393    393     0,                         /* xFindMethod */
   394    394     0,                         /* xRename */
   395    395     0,                         /* xSavepoint */
   396    396     0,                         /* xRelease */
   397    397     0,                         /* xRollbackTo */
          398  +  0,                         /* xShadowName */
   398    399   };
   399    400   
   400    401   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   401    402   
   402    403   int sqlite3MemstatVtabInit(sqlite3 *db){
   403    404     int rc = SQLITE_OK;
   404    405   #ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/stmt.c.

   262    262     0,                         /* xCommit */
   263    263     0,                         /* xRollback */
   264    264     0,                         /* xFindMethod */
   265    265     0,                         /* xRename */
   266    266     0,                         /* xSavepoint */
   267    267     0,                         /* xRelease */
   268    268     0,                         /* xRollbackTo */
          269  +  0,                         /* xShadowName */
   269    270   };
   270    271   
   271    272   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   272    273   
   273    274   int sqlite3StmtVtabInit(sqlite3 *db){
   274    275     int rc = SQLITE_OK;
   275    276   #ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/templatevtab.c.

   244    244     /* xSync       */ 0,
   245    245     /* xCommit     */ 0,
   246    246     /* xRollback   */ 0,
   247    247     /* xFindMethod */ 0,
   248    248     /* xRename     */ 0,
   249    249     /* xSavepoint  */ 0,
   250    250     /* xRelease    */ 0,
   251         -  /* xRollbackTo */ 0
          251  +  /* xRollbackTo */ 0,
          252  +  /* xShadowName */ 0
   252    253   };
   253    254   
   254    255   
   255    256   #ifdef _WIN32
   256    257   __declspec(dllexport)
   257    258   #endif
   258    259   int sqlite3_templatevtab_init(

Changes to ext/misc/unionvtab.c.

  1346   1346       0,                            /* xSync */
  1347   1347       0,                            /* xCommit */
  1348   1348       0,                            /* xRollback */
  1349   1349       0,                            /* xFindMethod */
  1350   1350       0,                            /* xRename */
  1351   1351       0,                            /* xSavepoint */
  1352   1352       0,                            /* xRelease */
  1353         -    0                             /* xRollbackTo */
         1353  +    0,                            /* xRollbackTo */
         1354  +    0                             /* xShadowName */
  1354   1355     };
  1355   1356     int rc;
  1356   1357   
  1357   1358     rc = sqlite3_create_module(db, "unionvtab", &unionModule, 0);
  1358   1359     if( rc==SQLITE_OK ){
  1359   1360       rc = sqlite3_create_module(db, "swarmvtab", &unionModule, (void*)db);
  1360   1361     }

Changes to ext/misc/vtablog.c.

   488    488     0,                         /* xCommit */
   489    489     0,                         /* xRollback */
   490    490     0,                         /* xFindMethod */
   491    491     0,                         /* xRename */
   492    492     0,                         /* xSavepoint */
   493    493     0,                         /* xRelease */
   494    494     0,                         /* xRollbackTo */
          495  +  0,                         /* xShadowName */
   495    496   };
   496    497   
   497    498   #ifdef _WIN32
   498    499   __declspec(dllexport)
   499    500   #endif
   500    501   int sqlite3_vtablog_init(
   501    502     sqlite3 *db, 

Changes to ext/rtree/geopoly.c.

  1721   1721       return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
  1722   1722     }
  1723   1723     return 0;
  1724   1724   }
  1725   1725   
  1726   1726   
  1727   1727   static sqlite3_module geopolyModule = {
  1728         -  2,                          /* iVersion */
         1728  +  3,                          /* iVersion */
  1729   1729     geopolyCreate,              /* xCreate - create a table */
  1730   1730     geopolyConnect,             /* xConnect - connect to an existing table */
  1731   1731     geopolyBestIndex,           /* xBestIndex - Determine search strategy */
  1732   1732     rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
  1733   1733     rtreeDestroy,               /* xDestroy - Drop a table */
  1734   1734     rtreeOpen,                  /* xOpen - open a cursor */
  1735   1735     rtreeClose,                 /* xClose - close a cursor */
................................................................................
  1744   1744     rtreeEndTransaction,        /* xCommit - commit transaction */
  1745   1745     rtreeEndTransaction,        /* xRollback - rollback transaction */
  1746   1746     geopolyFindFunction,        /* xFindFunction - function overloading */
  1747   1747     rtreeRename,                /* xRename - rename the table */
  1748   1748     rtreeSavepoint,             /* xSavepoint */
  1749   1749     0,                          /* xRelease */
  1750   1750     0,                          /* xRollbackTo */
         1751  +  rtreeShadowName             /* xShadowName */
  1751   1752   };
  1752   1753   
  1753   1754   static int sqlite3_geopoly_init(sqlite3 *db){
  1754   1755     int rc = SQLITE_OK;
  1755   1756     static const struct {
  1756   1757       void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  1757   1758       signed char nArg;

Changes to ext/rtree/rtree.c.

  3321   3321       }
  3322   3322       sqlite3_free(zSql);
  3323   3323     }
  3324   3324   
  3325   3325     return rc;
  3326   3326   }
  3327   3327   
         3328  +
         3329  +/*
         3330  +** Return true if zName is the extension on one of the shadow tables used
         3331  +** by this module.
         3332  +*/
         3333  +static int rtreeShadowName(const char *zName){
         3334  +  static const char *azName[] = {
         3335  +    "node", "parent", "rowid"
         3336  +  };
         3337  +  unsigned int i;
         3338  +  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
         3339  +    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
         3340  +  }
         3341  +  return 0;
         3342  +}
         3343  +
  3328   3344   static sqlite3_module rtreeModule = {
  3329         -  2,                          /* iVersion */
         3345  +  3,                          /* iVersion */
  3330   3346     rtreeCreate,                /* xCreate - create a table */
  3331   3347     rtreeConnect,               /* xConnect - connect to an existing table */
  3332   3348     rtreeBestIndex,             /* xBestIndex - Determine search strategy */
  3333   3349     rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
  3334   3350     rtreeDestroy,               /* xDestroy - Drop a table */
  3335   3351     rtreeOpen,                  /* xOpen - open a cursor */
  3336   3352     rtreeClose,                 /* xClose - close a cursor */
................................................................................
  3345   3361     rtreeEndTransaction,        /* xCommit - commit transaction */
  3346   3362     rtreeEndTransaction,        /* xRollback - rollback transaction */
  3347   3363     0,                          /* xFindFunction - function overloading */
  3348   3364     rtreeRename,                /* xRename - rename the table */
  3349   3365     rtreeSavepoint,             /* xSavepoint */
  3350   3366     0,                          /* xRelease */
  3351   3367     0,                          /* xRollbackTo */
         3368  +  rtreeShadowName             /* xShadowName */
  3352   3369   };
  3353   3370   
  3354   3371   static int rtreeSqlInit(
  3355   3372     Rtree *pRtree, 
  3356   3373     sqlite3 *db, 
  3357   3374     const char *zDb, 
  3358   3375     const char *zPrefix, 
................................................................................
  3430   3447          /* An UPSERT is very slightly slower than REPLACE, but it is needed
  3431   3448          ** if there are auxiliary columns */
  3432   3449          zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
  3433   3450                     "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
  3434   3451       }
  3435   3452       zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
  3436   3453       if( zSql ){
  3437         -      rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
         3454  +      rc = sqlite3_prepare_v3(db, zSql, -1,
         3455  +                              SQLITE_PREPARE_PERSISTENT | SQLITE_PREPARE_SHADOW,
  3438   3456                                 appStmt[i], 0); 
  3439   3457       }else{
  3440   3458         rc = SQLITE_NOMEM;
  3441   3459       }
  3442   3460       sqlite3_free(zSql);
  3443   3461     }
  3444   3462     if( pRtree->nAux ){

Changes to src/build.c.

  1889   1889       assert( pPk->nColumn==j );
  1890   1890       assert( pTab->nCol==j );
  1891   1891     }else{
  1892   1892       pPk->nColumn = pTab->nCol;
  1893   1893     }
  1894   1894     recomputeColumnsNotIndexed(pPk);
  1895   1895   }
         1896  +
         1897  +/*
         1898  +** Return true if zName is a shadow table name in the current database
         1899  +** connection.
         1900  +**
         1901  +** zName is temporarily modified while this routine is running, but is
         1902  +** restored to its original value prior to this routine returning.
         1903  +*/
         1904  +static int isShadowTableName(sqlite3 *db, char *zName){
         1905  +  char *zTail;                  /* Pointer to the last "_" in zName */
         1906  +  Table *pTab;                  /* Table that zName is a shadow of */
         1907  +  VTable *pVTab;                /* Virtual table corresponding to pTab */
         1908  +  const sqlite3_module *pMod;   /* module methods for pVTab */
         1909  +  zTail = strrchr(zName, '_');
         1910  +  if( zTail==0 ) return 0;
         1911  +  *zTail = 0;
         1912  +  pTab = sqlite3FindTable(db, zName, 0);
         1913  +  *zTail = '_';
         1914  +  if( pTab==0 ) return 0;
         1915  +  if( !IsVirtual(pTab) ) return 0;
         1916  +  pVTab = sqlite3GetVTable(db, pTab);
         1917  +  if( pVTab==0 ) return 0;
         1918  +  if( pVTab->pMod==0 ) return 0;
         1919  +  pMod = pVTab->pMod->pModule;
         1920  +  assert( pMod!=0 );
         1921  +  if( pMod->iVersion<3 ) return 0;
         1922  +  if( pMod->xShadowName==0 ) return 0;
         1923  +  return pMod->xShadowName(zTail+1);
         1924  +}
  1896   1925   
  1897   1926   /*
  1898   1927   ** This routine is called to report the final ")" that terminates
  1899   1928   ** a CREATE TABLE statement.
  1900   1929   **
  1901   1930   ** The table structure that other action routines have been building
  1902   1931   ** is added to the internal hash tables, assuming no errors have
................................................................................
  1928   1957   
  1929   1958     if( pEnd==0 && pSelect==0 ){
  1930   1959       return;
  1931   1960     }
  1932   1961     assert( !db->mallocFailed );
  1933   1962     p = pParse->pNewTable;
  1934   1963     if( p==0 ) return;
         1964  +
         1965  +  if( pSelect==0 && isShadowTableName(db, p->zName) ){
         1966  +    p->tabFlags |= TF_Shadow;
         1967  +  }
  1935   1968   
  1936   1969     /* If the db->init.busy is 1 it means we are reading the SQL off the
  1937   1970     ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  1938   1971     ** So do not write to the disk again.  Extract the root page number
  1939   1972     ** for the table from the db->init.newTnum field.  (The page number
  1940   1973     ** should have been put there by the sqliteOpenCb routine.)
  1941   1974     **

Changes to src/dbpage.c.

   403    403       0,                            /* xCommit */
   404    404       0,                            /* xRollback */
   405    405       0,                            /* xFindMethod */
   406    406       0,                            /* xRename */
   407    407       0,                            /* xSavepoint */
   408    408       0,                            /* xRelease */
   409    409       0,                            /* xRollbackTo */
          410  +    0                             /* xShadowName */
   410    411     };
   411    412     return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
   412    413   }
   413    414   #elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
   414    415   int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
   415    416   #endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/dbstat.c.

   716    716       0,                            /* xCommit */
   717    717       0,                            /* xRollback */
   718    718       0,                            /* xFindMethod */
   719    719       0,                            /* xRename */
   720    720       0,                            /* xSavepoint */
   721    721       0,                            /* xRelease */
   722    722       0,                            /* xRollbackTo */
          723  +    0                             /* xShadowName */
   723    724     };
   724    725     return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
   725    726   }
   726    727   #elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
   727    728   int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
   728    729   #endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/pragma.c.

  2473   2473     0,                           /* xSync - sync transaction */
  2474   2474     0,                           /* xCommit - commit transaction */
  2475   2475     0,                           /* xRollback - rollback transaction */
  2476   2476     0,                           /* xFindFunction - function overloading */
  2477   2477     0,                           /* xRename - rename the table */
  2478   2478     0,                           /* xSavepoint */
  2479   2479     0,                           /* xRelease */
  2480         -  0                            /* xRollbackTo */
         2480  +  0,                           /* xRollbackTo */
         2481  +  0                            /* xShadowName */
  2481   2482   };
  2482   2483   
  2483   2484   /*
  2484   2485   ** Check to see if zTabName is really the name of a pragma.  If it is,
  2485   2486   ** then register an eponymous virtual table for that pragma and return
  2486   2487   ** a pointer to the Module object for the new virtual table.
  2487   2488   */

Changes to src/sqlite.h.in.

  3638   3638   ** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
  3639   3639   ** representation of the SQL statement should be calculated and then
  3640   3640   ** associated with the prepared statement, which can be obtained via
  3641   3641   ** the [sqlite3_normalized_sql()] interface.  The semantics used to
  3642   3642   ** normalize a SQL statement are unspecified and subject to change.
  3643   3643   ** At a minimum, literal values will be replaced with suitable
  3644   3644   ** placeholders.
         3645  +**
         3646  +** [[SQLITE_PREPARE_SHADOW]] ^(<dt>SQLITE_PREPARE_SHADOW</dt>
         3647  +** <dd>When the SQLITE_PREPARE_SHADOW flag is set, writes to shadow
         3648  +** tables are allowed.  Shadow tables are ordinary tables associated
         3649  +** with some virtual tables that serve as the storage for the virtual
         3650  +** table.  Shadow tables are normally read-only.  Virtual table
         3651  +** implementations use this flag so that they can write to their own
         3652  +** shadow tables.
  3645   3653   ** </dl>
  3646   3654   */
  3647   3655   #define SQLITE_PREPARE_PERSISTENT              0x01
  3648   3656   #define SQLITE_PREPARE_NORMALIZE               0x02
         3657  +#define SQLITE_PREPARE_SHADOW                  0x04
  3649   3658   
  3650   3659   /*
  3651   3660   ** CAPI3REF: Compiling An SQL Statement
  3652   3661   ** KEYWORDS: {SQL statement compiler}
  3653   3662   ** METHOD: sqlite3
  3654   3663   ** CONSTRUCTOR: sqlite3_stmt
  3655   3664   **
................................................................................
  6318   6327                          void **ppArg);
  6319   6328     int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
  6320   6329     /* The methods above are in version 1 of the sqlite_module object. Those 
  6321   6330     ** below are for version 2 and greater. */
  6322   6331     int (*xSavepoint)(sqlite3_vtab *pVTab, int);
  6323   6332     int (*xRelease)(sqlite3_vtab *pVTab, int);
  6324   6333     int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
         6334  +  /* The methods above are in versions 1 and 2 of the sqlite_module object.
         6335  +  ** Those below are for version 3 and greater. */
         6336  +  int (*xShadowName)(const char*);
  6325   6337   };
  6326   6338   
  6327   6339   /*
  6328   6340   ** CAPI3REF: Virtual Table Indexing Information
  6329   6341   ** KEYWORDS: sqlite3_index_info
  6330   6342   **
  6331   6343   ** The sqlite3_index_info structure and its substructures is used as part

Changes to src/sqliteInt.h.

  1997   1997   #define TF_HasStat1        0x0010    /* nRowLogEst set from sqlite_stat1 */
  1998   1998   #define TF_WithoutRowid    0x0020    /* No rowid.  PRIMARY KEY is the key */
  1999   1999   #define TF_NoVisibleRowid  0x0040    /* No user-visible "rowid" column */
  2000   2000   #define TF_OOOHidden       0x0080    /* Out-of-Order hidden columns */
  2001   2001   #define TF_StatsUsed       0x0100    /* Query planner decisions affected by
  2002   2002                                        ** Index.aiRowLogEst[] values */
  2003   2003   #define TF_HasNotNull      0x0200    /* Contains NOT NULL constraints */
         2004  +#define TF_Shadow          0x0400    /* True for a shadow table */
  2004   2005   
  2005   2006   /*
  2006   2007   ** Test to see whether or not a table is a virtual table.  This is
  2007   2008   ** done as a macro so that it will be optimized out when virtual
  2008   2009   ** table support is omitted from the build.
  2009   2010   */
  2010   2011   #ifndef SQLITE_OMIT_VIRTUALTABLE