/ Check-in [61148f4c]
Login

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

Overview
Comment:Do not call the xDisconnect method on a virtual table while xUpdate is pending. Instead, defer the xDisconnect until after xUpdate completes. (CVS 3387)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:61148f4c36255c4ed3552f888fa75252b300589d
User & Date: drh 2006-09-02 20:57:52
Context
2006-09-02
20:58
Add a TRACE macro to the FTS1 module for troubleshooting. Turned off by default. (CVS 3388) check-in: d4923e98 user: drh tags: trunk
20:57
Do not call the xDisconnect method on a virtual table while xUpdate is pending. Instead, defer the xDisconnect until after xUpdate completes. (CVS 3387) check-in: 61148f4c user: drh tags: trunk
14:50
Test for busted TCL builds that do not support 64-bit integers and print a warning message to users that test failures may be a result of the bad TCL build and not some problem with SQLite. Ticket #1953. (CVS 3386) check-in: ca864ee9 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1858
1859
1860
1861
1862
1863
1864


1865
1866
1867
1868
1869
1870
1871
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.524 2006/08/23 20:07:22 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
#  define sqlite3VtabCommit(X)
#else
   void sqlite3VtabClear(Table*);
   int sqlite3VtabSync(sqlite3 *db, int rc);
   int sqlite3VtabRollback(sqlite3 *db);
   int sqlite3VtabCommit(sqlite3 *db);
#endif


void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
void sqlite3VtabFinishParse(Parse*, Token*);
void sqlite3VtabArgInit(Parse*);
void sqlite3VtabArgExtend(Parse*, Token*);
int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
int sqlite3VtabCallConnect(Parse*, Table*);
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);







|







 







>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.525 2006/09/02 20:57:52 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
#  define sqlite3VtabCommit(X)
#else
   void sqlite3VtabClear(Table*);
   int sqlite3VtabSync(sqlite3 *db, int rc);
   int sqlite3VtabRollback(sqlite3 *db);
   int sqlite3VtabCommit(sqlite3 *db);
#endif
void sqlite3VtabLock(sqlite3_vtab*);
void sqlite3VtabUnlock(sqlite3_vtab*);
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
void sqlite3VtabFinishParse(Parse*, Token*);
void sqlite3VtabArgInit(Parse*);
void sqlite3VtabArgExtend(Parse*, Token*);
int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
int sqlite3VtabCallConnect(Parse*, Table*);
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4853
4854
4855
4856
4857
4858
4859

4860

4861
4862
4863
4864
4865
4866
4867
**
** 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.574 2006/08/15 14:21:16 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
    Mem **apArg = p->apArg;
    Mem *pX = &pTos[1-nArg];
    for(i = 0; i<nArg; i++, pX++){
      storeTypeInfo(pX, 0);
      apArg[i] = pX;
    }
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;

    rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);

    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
    if( pOp->p1 && rc==SQLITE_OK ){
      assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
      db->lastRowid = rowid;
    }
  }
  popStack(&pTos, nArg);







|







 







>

>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
**
** 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.575 2006/09/02 20:57:52 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
    Mem **apArg = p->apArg;
    Mem *pX = &pTos[1-nArg];
    for(i = 0; i<nArg; i++, pX++){
      storeTypeInfo(pX, 0);
      apArg[i] = pX;
    }
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    sqlite3VtabLock(pVtab);
    rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
    sqlite3VtabUnlock(pVtab);
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
    if( pOp->p1 && rc==SQLITE_OK ){
      assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
      db->lastRowid = rowid;
    }
  }
  popStack(&pTos, nArg);

Changes to src/vtab.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
35
36
37
38
39
40
41























42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
**    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 contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.30 2006/09/02 14:17:00 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

/*
** External API function used to create a new virtual-table module.
*/
................................................................................
    pMod->pAux = pAux;
    pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
    sqliteFree(pMod);
    sqlite3ResetInternalSchema(db, 0);
  }
  return sqlite3ApiExit(db, SQLITE_OK);
}
























/*
** Clear any and all virtual-table information from the Table record.
** This routine is called, for example, just before deleting the Table
** record.
*/
void sqlite3VtabClear(Table *p){
  sqlite3_vtab *pVtab = p->pVtab;
  if( pVtab ){
    assert( p->pMod && p->pMod->pModule );
    pVtab->nRef--;
    if( pVtab->nRef==0 ){
      pVtab->pModule->xDisconnect(pVtab);
    }
    p->pVtab = 0;
  }
  if( p->azModuleArg ){
    int i;
    for(i=0; i<p->nModuleArg; i++){
      sqliteFree(p->azModuleArg[i]);
    }
................................................................................
    }
    memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
    db->aVTrans = aVTrans;
  }

  /* Add pVtab to the end of sqlite3.aVTrans */
  db->aVTrans[db->nVTrans++] = pVtab;
  pVtab->nRef++;
  return SQLITE_OK;
}

/*
** This function is invoked by the vdbe to call the xCreate method
** of the virtual table named zTab in database iDb. 
**
................................................................................
static void callFinaliser(sqlite3 *db, int offset){
  int i;
  for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){
    sqlite3_vtab *pVtab = db->aVTrans[i];
    int (*x)(sqlite3_vtab *);
    x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
    if( x ) x(pVtab);
    pVtab->nRef--;
    if( pVtab->nRef==0 ){
      pVtab->pModule->xDisconnect(pVtab);
    }
  }
  sqliteFree(db->aVTrans);
  db->nVTrans = 0;
  db->aVTrans = 0;
}

/*







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
<
<
<







 







|







 







|
<
<
<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75



76
77
78
79
80
81
82
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
...
508
509
510
511
512
513
514
515



516
517
518
519
520
521
522
**    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 contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.31 2006/09/02 20:57:52 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

/*
** External API function used to create a new virtual-table module.
*/
................................................................................
    pMod->pAux = pAux;
    pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
    sqliteFree(pMod);
    sqlite3ResetInternalSchema(db, 0);
  }
  return sqlite3ApiExit(db, SQLITE_OK);
}

/*
** Lock the virtual table so that it cannot be disconnected.
** Locks nest.  Every lock should have a corresponding unlock.
** If an unlock is omitted, resources leaks will occur.  
**
** If a disconnect is attempted while a virtual table is locked,
** the disconnect is deferred until all locks have been removed.
*/
void sqlite3VtabLock(sqlite3_vtab *pVtab){
  pVtab->nRef++;
}

/*
** Unlock a virtual table.  When the last lock is removed,
** disconnect the virtual table.
*/
void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
  pVtab->nRef--;
  if( pVtab->nRef==0 ){
    pVtab->pModule->xDisconnect(pVtab);
  }
}

/*
** Clear any and all virtual-table information from the Table record.
** This routine is called, for example, just before deleting the Table
** record.
*/
void sqlite3VtabClear(Table *p){
  sqlite3_vtab *pVtab = p->pVtab;
  if( pVtab ){
    assert( p->pMod && p->pMod->pModule );
    sqlite3VtabUnlock(pVtab);



    p->pVtab = 0;
  }
  if( p->azModuleArg ){
    int i;
    for(i=0; i<p->nModuleArg; i++){
      sqliteFree(p->azModuleArg[i]);
    }
................................................................................
    }
    memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
    db->aVTrans = aVTrans;
  }

  /* Add pVtab to the end of sqlite3.aVTrans */
  db->aVTrans[db->nVTrans++] = pVtab;
  sqlite3VtabLock(pVtab);
  return SQLITE_OK;
}

/*
** This function is invoked by the vdbe to call the xCreate method
** of the virtual table named zTab in database iDb. 
**
................................................................................
static void callFinaliser(sqlite3 *db, int offset){
  int i;
  for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){
    sqlite3_vtab *pVtab = db->aVTrans[i];
    int (*x)(sqlite3_vtab *);
    x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
    if( x ) x(pVtab);
    sqlite3VtabUnlock(pVtab);



  }
  sqliteFree(db->aVTrans);
  db->nVTrans = 0;
  db->aVTrans = 0;
}

/*