/ Check-in [a56bfa56]
Login

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

Overview
Comment:Allow xDestroy methods to execute "DROP TABLE" statements. (CVS 3287)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a56bfa560425a5dc9273229f8838471dfc402024
User & Date: danielk1977 2006-06-23 14:32:08
Context
2006-06-23
14:43
Modify the test cases in tkt1444.test that were failing. I am convinced that the test cases were incorrect. (CVS 3288) check-in: 0534f6e1 user: danielk1977 tags: trunk
14:32
Allow xDestroy methods to execute "DROP TABLE" statements. (CVS 3287) check-in: a56bfa56 user: danielk1977 tags: trunk
11:34
Fix some memory leaks that occur when malloc() fails. (CVS 3286) check-in: b56cc035 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test8.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the virtual table interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test8.c,v 1.33 2006/06/23 11:34:55 danielk1977 Exp $
           16  +** $Id: test8.c,v 1.34 2006/06/23 14:32:08 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include "os.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
   234    234     echo_vtab *p = (echo_vtab*)pVtab;
   235    235     sqliteFree(p->aIndex);
   236    236     for(ii=0; ii<p->nCol; ii++){
   237    237       sqliteFree(p->aCol[ii]);
   238    238     }
   239    239     sqliteFree(p->aCol);
   240    240     sqliteFree(p->zTableName);
          241  +  sqliteFree(p->zLogName);
   241    242     sqliteFree(p);
   242    243     return 0;
   243    244   }
   244    245   
   245    246   static int echoConstructor(
   246    247     sqlite3 *db,
   247    248     void *pAux,
................................................................................
   282    283     void *pAux,
   283    284     int argc, char **argv,
   284    285     sqlite3_vtab **ppVtab
   285    286   ){
   286    287     int rc = SQLITE_OK;
   287    288     appendToEchoModule((Tcl_Interp *)(pAux), "xCreate");
   288    289     rc = echoConstructor(db, pAux, argc, argv, ppVtab);
   289         -#if 0
          290  +#if 1
   290    291     if( rc==SQLITE_OK && argc==5 ){
   291    292       char *zSql;
   292    293       echo_vtab *pVtab = *(echo_vtab **)ppVtab;
   293    294       pVtab->zLogName = sqlite3MPrintf("%s", argv[4]);
   294    295       zSql = sqlite3MPrintf("CREATE TABLE %Q(logmsg)", pVtab->zLogName);
   295    296       rc = sqlite3_exec(db, zSql, 0, 0, 0);
   296    297       sqliteFree(zSql);
................................................................................
   312    313     appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect");
   313    314     return echoDestructor(pVtab);
   314    315   }
   315    316   static int echoDestroy(sqlite3_vtab *pVtab){
   316    317     int rc = SQLITE_OK;
   317    318     echo_vtab *p = (echo_vtab *)pVtab;
   318    319     appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDestroy");
   319         -#if 0
          320  +#if 1
   320    321     if( p && p->zLogName ){
   321    322       char *zSql;
   322    323       zSql = sqlite3MPrintf("DROP TABLE %Q", p->zLogName);
   323    324       rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
   324    325       sqliteFree(zSql);
   325    326     }
   326    327   #endif

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.567 2006/06/23 11:34:55 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.568 2006/06/23 14:32:08 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  3890   3890   ** a zero is pushed onto the stack.  If AUTOVACUUM is disabled
  3891   3891   ** then a zero is pushed onto the stack.
  3892   3892   **
  3893   3893   ** See also: Clear
  3894   3894   */
  3895   3895   case OP_Destroy: {
  3896   3896     int iMoved;
  3897         -  if( db->activeVdbeCnt>1 ){
         3897  +  Vdbe *pVdbe;
         3898  +  int iCnt = db->activeVdbeCnt;
         3899  +#ifndef SQLITE_OMIT_VIRTUALTABLE
         3900  +  iCnt = 0;
         3901  +  for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
         3902  +    if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
         3903  +      iCnt++;
         3904  +    }
         3905  +  }
         3906  +#endif
         3907  +  if( iCnt>1 ){
  3898   3908       rc = SQLITE_LOCKED;
  3899   3909     }else{
  3900         -    assert( db->activeVdbeCnt==1 );
         3910  +    assert( iCnt==1 );
  3901   3911       rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved);
  3902   3912       pTos++;
  3903   3913       pTos->flags = MEM_Int;
  3904   3914       pTos->i = iMoved;
  3905   3915     #ifndef SQLITE_OMIT_AUTOVACUUM
  3906   3916       if( rc==SQLITE_OK && iMoved!=0 ){
  3907   3917         sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1);
................................................................................
  4564   4574   #ifndef SQLITE_OMIT_VIRTUALTABLE
  4565   4575   /* Opcode: VDestroy P1 * P3
  4566   4576   **
  4567   4577   ** P3 is the name of a virtual table in database P1.  Call the xDestroy method
  4568   4578   ** of that table.
  4569   4579   */
  4570   4580   case OP_VDestroy: {   /* no-push */
         4581  +  p->inVtabMethod = 2;
  4571   4582     rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3);
         4583  +  p->inVtabMethod = 0;
  4572   4584     break;
  4573   4585   }
  4574   4586   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  4575   4587   
  4576   4588   #ifndef SQLITE_OMIT_VIRTUALTABLE
  4577   4589   /* Opcode: VOpen P1 * P3
  4578   4590   **

Changes to src/vdbeInt.h.

   268    268   
   269    269   /*
   270    270   ** An instance of the virtual machine.  This structure contains the complete
   271    271   ** state of the virtual machine.
   272    272   **
   273    273   ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
   274    274   ** is really a pointer to an instance of this structure.
          275  +**
          276  +** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
          277  +** any virtual table method invocations made by the vdbe program. It is
          278  +** set to 2 for xDestroy method calls and 1 for all other methods. This
          279  +** variable is used for two purposes: to allow xDestroy methods to execute
          280  +** "DROP TABLE" statements and to prevent some nasty side effects of
          281  +** malloc failure when SQLite is invoked recursively by a virtual table 
          282  +** method function.
   275    283   */
   276    284   struct Vdbe {
   277    285     sqlite3 *db;        /* The whole database */
   278    286     Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
   279    287     FILE *trace;        /* Write an execution trace here, if not NULL */
   280    288     int nOp;            /* Number of instructions in the program */
   281    289     int nOpAlloc;       /* Number of slots allocated for aOp[] */
................................................................................
   322    330     int nChange;            /* Number of db changes made since last reset */
   323    331     i64 startTime;          /* Time when query started - used for profiling */
   324    332   #ifdef SQLITE_SSE
   325    333     int fetchId;          /* Statement number used by sqlite3_fetch_statement */
   326    334     int lru;              /* Counter used for LRU cache replacement */
   327    335   #endif
   328    336   #ifndef SQLITE_OMIT_VIRTUALTABLE
   329         -  int inVtabMethod;
          337  +  int inVtabMethod;     /* See comments above */
   330    338   #endif
   331    339   };
   332    340   
   333    341   /*
   334    342   ** The following are allowed values for Vdbe.magic
   335    343   */
   336    344   #define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */

Changes to test/vtab1.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is creating and dropping virtual tables.
    13     13   #
    14         -# $Id: vtab1.test,v 1.29 2006/06/22 09:53:50 danielk1977 Exp $
           14  +# $Id: vtab1.test,v 1.30 2006/06/23 14:32:09 danielk1977 Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   ifcapable !vtab||!schema_pragmas {
    20     20     finish_test
    21     21     return
................................................................................
   744    744       DROP TABLE treal;
   745    745       DROP TABLE techo;
   746    746       DROP TABLE echo_abc;
   747    747       DROP TABLE real_abc;
   748    748     }
   749    749   } {}
   750    750   
   751         -if 0 {
   752         -  do_test vtab1.9-1 {
   753         -    set echo_module ""
   754         -    execsql {
   755         -      CREATE TABLE r(a, b, c);
   756         -      CREATE VIRTUAL TABLE e USING echo(r, e_log);
   757         -      SELECT name FROM sqlite_master;
   758         -    }
   759         -  } {r e e_log}
   760         -  do_test vtab1.9-2 {
   761         -    explain {
   762         -      DROP TABLE e;
   763         -    }
   764         -    execsql {
   765         -      PRAGMA vdbe_trace = 1;
   766         -      DROP TABLE e;
   767         -      SELECT name FROM sqlite_master;
   768         -    }
   769         -  } {r}
   770         -}
          751  +do_test vtab1.9-1 {
          752  +  set echo_module ""
          753  +  execsql {
          754  +    CREATE TABLE r(a, b, c);
          755  +    CREATE VIRTUAL TABLE e USING echo(r, e_log);
          756  +    SELECT name FROM sqlite_master;
          757  +  }
          758  +} {r e e_log}
          759  +do_test vtab1.9-2 {
          760  +  execsql {
          761  +    DROP TABLE e;
          762  +    SELECT name FROM sqlite_master;
          763  +  }
          764  +} {r}
   771    765   
   772    766   finish_test
   773    767