/ 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 Unified Diffs Ignore Whitespace Patch

Changes to src/test8.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
234
235
236
237
238
239
240

241
242
243
244
245
246
247
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.33 2006/06/23 11:34:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  echo_vtab *p = (echo_vtab*)pVtab;
  sqliteFree(p->aIndex);
  for(ii=0; ii<p->nCol; ii++){
    sqliteFree(p->aCol[ii]);
  }
  sqliteFree(p->aCol);
  sqliteFree(p->zTableName);

  sqliteFree(p);
  return 0;
}

static int echoConstructor(
  sqlite3 *db,
  void *pAux,
................................................................................
  void *pAux,
  int argc, char **argv,
  sqlite3_vtab **ppVtab
){
  int rc = SQLITE_OK;
  appendToEchoModule((Tcl_Interp *)(pAux), "xCreate");
  rc = echoConstructor(db, pAux, argc, argv, ppVtab);
#if 0
  if( rc==SQLITE_OK && argc==5 ){
    char *zSql;
    echo_vtab *pVtab = *(echo_vtab **)ppVtab;
    pVtab->zLogName = sqlite3MPrintf("%s", argv[4]);
    zSql = sqlite3MPrintf("CREATE TABLE %Q(logmsg)", pVtab->zLogName);
    rc = sqlite3_exec(db, zSql, 0, 0, 0);
    sqliteFree(zSql);
................................................................................
  appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect");
  return echoDestructor(pVtab);
}
static int echoDestroy(sqlite3_vtab *pVtab){
  int rc = SQLITE_OK;
  echo_vtab *p = (echo_vtab *)pVtab;
  appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDestroy");
#if 0
  if( p && p->zLogName ){
    char *zSql;
    zSql = sqlite3MPrintf("DROP TABLE %Q", p->zLogName);
    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
    sqliteFree(zSql);
  }
#endif







|







 







>







 







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
...
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.34 2006/06/23 14:32:08 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  echo_vtab *p = (echo_vtab*)pVtab;
  sqliteFree(p->aIndex);
  for(ii=0; ii<p->nCol; ii++){
    sqliteFree(p->aCol[ii]);
  }
  sqliteFree(p->aCol);
  sqliteFree(p->zTableName);
  sqliteFree(p->zLogName);
  sqliteFree(p);
  return 0;
}

static int echoConstructor(
  sqlite3 *db,
  void *pAux,
................................................................................
  void *pAux,
  int argc, char **argv,
  sqlite3_vtab **ppVtab
){
  int rc = SQLITE_OK;
  appendToEchoModule((Tcl_Interp *)(pAux), "xCreate");
  rc = echoConstructor(db, pAux, argc, argv, ppVtab);
#if 1
  if( rc==SQLITE_OK && argc==5 ){
    char *zSql;
    echo_vtab *pVtab = *(echo_vtab **)ppVtab;
    pVtab->zLogName = sqlite3MPrintf("%s", argv[4]);
    zSql = sqlite3MPrintf("CREATE TABLE %Q(logmsg)", pVtab->zLogName);
    rc = sqlite3_exec(db, zSql, 0, 0, 0);
    sqliteFree(zSql);
................................................................................
  appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect");
  return echoDestructor(pVtab);
}
static int echoDestroy(sqlite3_vtab *pVtab){
  int rc = SQLITE_OK;
  echo_vtab *p = (echo_vtab *)pVtab;
  appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDestroy");
#if 1
  if( p && p->zLogName ){
    char *zSql;
    zSql = sqlite3MPrintf("DROP TABLE %Q", p->zLogName);
    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
    sqliteFree(zSql);
  }
#endif

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
3890
3891
3892
3893
3894
3895
3896

3897









3898
3899
3900

3901
3902
3903
3904
3905
3906
3907
....
4564
4565
4566
4567
4568
4569
4570

4571

4572
4573
4574
4575
4576
4577
4578
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.567 2006/06/23 11:34:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** a zero is pushed onto the stack.  If AUTOVACUUM is disabled
** then a zero is pushed onto the stack.
**
** See also: Clear
*/
case OP_Destroy: {
  int iMoved;

  if( db->activeVdbeCnt>1 ){









    rc = SQLITE_LOCKED;
  }else{
    assert( db->activeVdbeCnt==1 );

    rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved);
    pTos++;
    pTos->flags = MEM_Int;
    pTos->i = iMoved;
  #ifndef SQLITE_OMIT_AUTOVACUUM
    if( rc==SQLITE_OK && iMoved!=0 ){
      sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1);
................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * P3
**
** P3 is the name of a virtual table in database P1.  Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {   /* no-push */

  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3);

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * P3
**







|







 







>
|
>
>
>
>
>
>
>
>
>


<
>







 







>

>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909

3910
3911
3912
3913
3914
3915
3916
3917
....
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.568 2006/06/23 14:32:08 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** a zero is pushed onto the stack.  If AUTOVACUUM is disabled
** then a zero is pushed onto the stack.
**
** See also: Clear
*/
case OP_Destroy: {
  int iMoved;
  Vdbe *pVdbe;
  int iCnt = db->activeVdbeCnt;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  iCnt = 0;
  for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
    if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
      iCnt++;
    }
  }
#endif
  if( iCnt>1 ){
    rc = SQLITE_LOCKED;
  }else{

    assert( iCnt==1 );
    rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved);
    pTos++;
    pTos->flags = MEM_Int;
    pTos->i = iMoved;
  #ifndef SQLITE_OMIT_AUTOVACUUM
    if( rc==SQLITE_OK && iMoved!=0 ){
      sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1);
................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * P3
**
** P3 is the name of a virtual table in database P1.  Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {   /* no-push */
  p->inVtabMethod = 2;
  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3);
  p->inVtabMethod = 0;
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * P3
**

Changes to src/vdbeInt.h.

268
269
270
271
272
273
274








275
276
277
278
279
280
281
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
** is really a pointer to an instance of this structure.








*/
struct Vdbe {
  sqlite3 *db;        /* The whole database */
  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
  FILE *trace;        /* Write an execution trace here, if not NULL */
  int nOp;            /* Number of instructions in the program */
  int nOpAlloc;       /* Number of slots allocated for aOp[] */
................................................................................
  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
#ifdef SQLITE_SSE
  int fetchId;          /* Statement number used by sqlite3_fetch_statement */
  int lru;              /* Counter used for LRU cache replacement */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int inVtabMethod;
#endif
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */







>
>
>
>
>
>
>
>







 







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
** is really a pointer to an instance of this structure.
**
** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
** any virtual table method invocations made by the vdbe program. It is
** set to 2 for xDestroy method calls and 1 for all other methods. This
** variable is used for two purposes: to allow xDestroy methods to execute
** "DROP TABLE" statements and to prevent some nasty side effects of
** malloc failure when SQLite is invoked recursively by a virtual table 
** method function.
*/
struct Vdbe {
  sqlite3 *db;        /* The whole database */
  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
  FILE *trace;        /* Write an execution trace here, if not NULL */
  int nOp;            /* Number of instructions in the program */
  int nOpAlloc;       /* Number of slots allocated for aOp[] */
................................................................................
  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
#ifdef SQLITE_SSE
  int fetchId;          /* Statement number used by sqlite3_fetch_statement */
  int lru;              /* Counter used for LRU cache replacement */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int inVtabMethod;     /* See comments above */
#endif
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */

Changes to test/vtab1.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
#    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 file is creating and dropping virtual tables.
#
# $Id: vtab1.test,v 1.29 2006/06/22 09:53:50 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab||!schema_pragmas {
  finish_test
  return
................................................................................
    DROP TABLE treal;
    DROP TABLE techo;
    DROP TABLE echo_abc;
    DROP TABLE real_abc;
  }
} {}

if 0 {
  do_test vtab1.9-1 {
    set echo_module ""
    execsql {
      CREATE TABLE r(a, b, c);
      CREATE VIRTUAL TABLE e USING echo(r, e_log);
      SELECT name FROM sqlite_master;
    }
  } {r e e_log}
  do_test vtab1.9-2 {
    explain {
      DROP TABLE e;
    }
    execsql {
      PRAGMA vdbe_trace = 1;
      DROP TABLE e;
      SELECT name FROM sqlite_master;
    }
  } {r}
}

finish_test








|







 







<
|
|
|
|
|
|
|
|
|
<
<
<
|
<
|
|
|
|
|
<


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
744
745
746
747
748
749
750

751
752
753
754
755
756
757
758
759



760

761
762
763
764
765

766
767
#    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 file is creating and dropping virtual tables.
#
# $Id: vtab1.test,v 1.30 2006/06/23 14:32:09 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab||!schema_pragmas {
  finish_test
  return
................................................................................
    DROP TABLE treal;
    DROP TABLE techo;
    DROP TABLE echo_abc;
    DROP TABLE real_abc;
  }
} {}


do_test vtab1.9-1 {
  set echo_module ""
  execsql {
    CREATE TABLE r(a, b, c);
    CREATE VIRTUAL TABLE e USING echo(r, e_log);
    SELECT name FROM sqlite_master;
  }
} {r e e_log}
do_test vtab1.9-2 {



  execsql {

    DROP TABLE e;
    SELECT name FROM sqlite_master;
  }
} {r}


finish_test