Ensure sqlite3_finalize() can be called from within the xDisconnect() method of virtual tables. (CVS 3845)
FossilOrigin-Name: 8d6c3bfc4dfdd380a2915d778e256d3e49d22d72
This commit is contained in:
parent
86a88114fa
commit
a04a34ff1a
32
manifest
32
manifest
@ -1,5 +1,5 @@
|
||||
C Detect\sdatabase\sfile\schanges\susing\sa\s128-bit\ssegment\sof\sthe\sfile\sheader\nthat\sincludes\sthe\schange\scounter.\s\sTicket\s#2303.\s(CVS\s3844)
|
||||
D 2007-04-16T15:02:19
|
||||
C Ensure\ssqlite3_finalize()\scan\sbe\scalled\sfrom\swithin\sthe\sxDisconnect()\smethod\sof\svirtual\stables.\s(CVS\s3845)
|
||||
D 2007-04-16T15:06:25
|
||||
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -60,11 +60,11 @@ F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
||||
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
||||
F src/btree.c 2023a8371bd23c300571a4ce9673b8859c44be36
|
||||
F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
|
||||
F src/build.c 7c2efa468f0c404ef5aa648d43c383318390937f
|
||||
F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
|
||||
F src/build.c 8ad4f8944d0f4cc93175bbfa8ca2a53e137072c5
|
||||
F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e
|
||||
F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
|
||||
F src/date.c 74b76691bddf58b634f6bf4a77c8c58234268c6e
|
||||
F src/delete.c 151d08386bf9c9e7f92f6b9106c71efec2def184
|
||||
F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c 2c32c546006627d70a7b941b318489980fd1912e
|
||||
F src/func.c 007d957c057bb42b0d37aa6ad4be0e1c67a8871b
|
||||
@ -73,7 +73,7 @@ F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
|
||||
F src/insert.c f3cd178575bd2a4b65a9a1313f391e1f78221ca3
|
||||
F src/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6
|
||||
F src/loadext.c 146fb9b9dc6133e763888d710205c32ebf8eeca2
|
||||
F src/main.c c8915777ae8e50823d01eefe2b674ef68c32bf61
|
||||
F src/main.c a8f5c62b51e7581b814745aee6fef03f8641119f
|
||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||
F src/os.c 4650e98aadd27abfe1698ff58edf6893c58d4881
|
||||
F src/os.h 9240adf088fd55732f8926f9017601ba3430ead8
|
||||
@ -93,12 +93,12 @@ F src/pragma.c 3b992b5b2640d6ae25cef05aa6a42cd1d6c43234
|
||||
F src/prepare.c 37207b2b2ccb41d379b01dd62231686bcc48ef1f
|
||||
F src/printf.c 0c6f40648770831341ac45ab32423a80b4c87f05
|
||||
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
|
||||
F src/select.c 4fa2b45a9c19988f295ea118d95ce68a56a00eb4
|
||||
F src/select.c f120e927198532ebb53cfccaa742585f49ac9ac7
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 3ae4654560e91220a95738a73d135d91d937cda1
|
||||
F src/sqlite.h.in e429f66f9245c7f8675db24b230c950b8672ad1c
|
||||
F src/sqlite3ext.h 7d0d363ea7327e817ef0dfe1b7eee1f171b72890
|
||||
F src/sqliteInt.h 6c25db3cdf91d26ffe66c685812c808291c241de
|
||||
F src/sqliteInt.h 047af0e4c38bbb8652836f72adc9e9199c51a1ba
|
||||
F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
|
||||
F src/tclsqlite.c ec69eb9ad56d03fbf7570ca1ca5ea947d1ec4b6f
|
||||
F src/test1.c b96f80e68cd50e10e10cda8bb762152bae52a8d2
|
||||
@ -118,20 +118,20 @@ F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
||||
F src/test_schema.c ced72140a3a25c148975428e170ec1850d3c3a7d
|
||||
F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
|
||||
F src/test_tclvar.c 315e77c17f128ff8c06b38c08617fd07c825a95b
|
||||
F src/tokenize.c bb1732ef2b6fc2143f93ff28a45d3dcb04c1d396
|
||||
F src/tokenize.c 7d611fc942ca0b12514eea2e1fbb148a65af23f2
|
||||
F src/trigger.c 420192efe3e6f03addf7897c60c3c8bf913d3493
|
||||
F src/update.c 3359041db390a8f856d67272f299600e2104f350
|
||||
F src/utf.c e64a48bc21aa973eb622dd47da87d56a4cdcf528
|
||||
F src/util.c b6344325378e75b9e18175d8b6aed1723d73dad9
|
||||
F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef
|
||||
F src/vdbe.c 87e31f0790ac8a5aad7b7fcd5b97948943fccba3
|
||||
F src/vdbe.c 8f5faea02cfcd21cd0799fe170e76ab0f99295d8
|
||||
F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691
|
||||
F src/vdbeInt.h 4b19fd8febad3fd14c4c97adaefc06754d323132
|
||||
F src/vdbeapi.c 1fca7ff056d03f131caa6b1296bb221da65ed7f4
|
||||
F src/vdbeaux.c 0bae26de1ba1683de80c89ba1d4081b4c809d05b
|
||||
F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
|
||||
F src/vdbemem.c 981a113405bd9b80aeb71fe246a2f01708e8a8f7
|
||||
F src/vtab.c 7fbda947e28cbe7adb3ba752a76ca9ef29936750
|
||||
F src/vtab.c 6dd9dd6ef4fef10e32c05452d3dd0b8bec9d7cb6
|
||||
F src/where.c fce0dad6b230eb7ea844e8b8667c074d07e3fdd5
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -377,7 +377,7 @@ F test/vtab5.test 9fb8f335651afe8f870011e2f68e5b00c5ad03cd
|
||||
F test/vtab6.test ec0036f29f8a803da9935206f2d9d1b6a8026392
|
||||
F test/vtab7.test 5f9ef9fb84733e928d5d0267c821072561b198d5
|
||||
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
|
||||
F test/vtab9.test 87afba55339b0c255e9697fbfb5bfb6120505d9d
|
||||
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
|
||||
F test/vtab_err.test 224cc80ad700797c48b9cd2c1e0bd7a8517d8609
|
||||
F test/where.test 1d020f50c77f37b2dbab9766ca959e6e3278ecdb
|
||||
F test/where2.test 3249d426b3fc7a106713d784e1628307fc308d2e
|
||||
@ -458,7 +458,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 2c8e2a5be34cdfe11ef22bd6f78ec0519f497392
|
||||
R 814512695981b3392256843a965db823
|
||||
U drh
|
||||
Z 2bdc95de39af6db85ea861709e0ec935
|
||||
P e44995debf2456e55b502783849e93a045a527c8
|
||||
R 279638657fd09ef4747823ac0decb770
|
||||
U danielk1977
|
||||
Z b90c16751ca25c9a5de2c4519a248aa8
|
||||
|
@ -1 +1 @@
|
||||
e44995debf2456e55b502783849e93a045a527c8
|
||||
8d6c3bfc4dfdd380a2915d778e256d3e49d22d72
|
23
src/build.c
23
src/build.c
@ -22,7 +22,7 @@
|
||||
** COMMIT
|
||||
** ROLLBACK
|
||||
**
|
||||
** $Id: build.c,v 1.419 2007/04/05 11:25:58 drh Exp $
|
||||
** $Id: build.c,v 1.420 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -478,18 +478,11 @@ static void sqliteResetColumnNames(Table *pTable){
|
||||
** foreign keys from the sqlite.aFKey hash table. But it does destroy
|
||||
** memory structures of the indices and foreign keys associated with
|
||||
** the table.
|
||||
**
|
||||
** Indices associated with the table are unlinked from the "db"
|
||||
** data structure if db!=NULL. If db==NULL, indices attached to
|
||||
** the table are deleted, but it is assumed they have already been
|
||||
** unlinked.
|
||||
*/
|
||||
void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
|
||||
void sqlite3DeleteTable(Table *pTable){
|
||||
Index *pIndex, *pNext;
|
||||
FKey *pFKey, *pNextFKey;
|
||||
|
||||
db = 0;
|
||||
|
||||
if( pTable==0 ) return;
|
||||
|
||||
/* Do not delete the table until the reference count reaches zero. */
|
||||
@ -509,7 +502,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
|
||||
|
||||
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
||||
/* Delete all foreign keys associated with this table. The keys
|
||||
** should have already been unlinked from the db->aFKey hash table
|
||||
** should have already been unlinked from the pSchema->aFKey hash table
|
||||
*/
|
||||
for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
|
||||
pNextFKey = pFKey->pNextFrom;
|
||||
@ -561,7 +554,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sqlite3DeleteTable(db, p);
|
||||
sqlite3DeleteTable(p);
|
||||
}
|
||||
db->flags |= SQLITE_InternChanges;
|
||||
}
|
||||
@ -810,7 +803,7 @@ void sqlite3StartTable(
|
||||
pTable->iPKey = -1;
|
||||
pTable->pSchema = db->aDb[iDb].pSchema;
|
||||
pTable->nRef = 1;
|
||||
if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
|
||||
if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
|
||||
pParse->pNewTable = pTable;
|
||||
|
||||
/* If this is the magic sqlite_sequence table used by autoincrement,
|
||||
@ -1484,7 +1477,7 @@ void sqlite3EndTable(
|
||||
p->aCol = pSelTab->aCol;
|
||||
pSelTab->nCol = 0;
|
||||
pSelTab->aCol = 0;
|
||||
sqlite3DeleteTable(0, pSelTab);
|
||||
sqlite3DeleteTable(pSelTab);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1712,7 +1705,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
pTable->aCol = pSelTab->aCol;
|
||||
pSelTab->nCol = 0;
|
||||
pSelTab->aCol = 0;
|
||||
sqlite3DeleteTable(0, pSelTab);
|
||||
sqlite3DeleteTable(pSelTab);
|
||||
pTable->pSchema->flags |= DB_UnresetViews;
|
||||
}else{
|
||||
pTable->nCol = 0;
|
||||
@ -2959,7 +2952,7 @@ void sqlite3SrcListDelete(SrcList *pList){
|
||||
sqliteFree(pItem->zDatabase);
|
||||
sqliteFree(pItem->zName);
|
||||
sqliteFree(pItem->zAlias);
|
||||
sqlite3DeleteTable(0, pItem->pTab);
|
||||
sqlite3DeleteTable(pItem->pTab);
|
||||
sqlite3SelectDelete(pItem->pSelect);
|
||||
sqlite3ExprDelete(pItem->pOn);
|
||||
sqlite3IdListDelete(pItem->pUsing);
|
||||
|
@ -13,7 +13,7 @@
|
||||
** This file contains functions used to access the internal hash tables
|
||||
** of user defined functions and collation sequences.
|
||||
**
|
||||
** $Id: callback.c,v 1.16 2007/02/02 12:44:37 drh Exp $
|
||||
** $Id: callback.c,v 1.17 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@ -344,7 +344,7 @@ void sqlite3SchemaFree(void *p){
|
||||
sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
|
||||
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
|
||||
Table *pTab = sqliteHashData(pElem);
|
||||
sqlite3DeleteTable(0, pTab);
|
||||
sqlite3DeleteTable(pTab);
|
||||
}
|
||||
sqlite3HashClear(&temp1);
|
||||
pSchema->pSeqTab = 0;
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** in order to generate code for DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.128 2007/02/07 01:06:53 drh Exp $
|
||||
** $Id: delete.c,v 1.129 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -27,7 +27,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
|
||||
struct SrcList_item *pItem;
|
||||
for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
|
||||
pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
|
||||
sqlite3DeleteTable(pParse->db, pItem->pTab);
|
||||
sqlite3DeleteTable(pItem->pTab);
|
||||
pItem->pTab = pTab;
|
||||
if( pTab ){
|
||||
pTab->nRef++;
|
||||
|
@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.368 2007/04/02 16:40:38 drh Exp $
|
||||
** $Id: main.c,v 1.369 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -127,8 +127,9 @@ int sqlite3_close(sqlite3 *db){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there are any outstanding VMs, return SQLITE_BUSY. */
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
|
||||
/* If there are any outstanding VMs, return SQLITE_BUSY. */
|
||||
if( db->pVdbe ){
|
||||
sqlite3Error(db, SQLITE_BUSY,
|
||||
"Unable to close due to unfinalised statements");
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle SELECT statements in SQLite.
|
||||
**
|
||||
** $Id: select.c,v 1.336 2007/04/13 16:06:33 drh Exp $
|
||||
** $Id: select.c,v 1.337 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -1097,7 +1097,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
|
||||
sqlite3Dequote(zName);
|
||||
if( sqlite3MallocFailed() ){
|
||||
sqliteFree(zName);
|
||||
sqlite3DeleteTable(0, pTab);
|
||||
sqlite3DeleteTable(pTab);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2216,7 +2216,7 @@ static int flattenSubquery(
|
||||
int nSubSrc = pSubSrc->nSrc;
|
||||
int jointype = pSubitem->jointype;
|
||||
|
||||
sqlite3DeleteTable(0, pSubitem->pTab);
|
||||
sqlite3DeleteTable(pSubitem->pTab);
|
||||
sqliteFree(pSubitem->zDatabase);
|
||||
sqliteFree(pSubitem->zName);
|
||||
sqliteFree(pSubitem->zAlias);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.551 2007/04/12 03:54:39 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.552 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -381,6 +381,14 @@ struct Db {
|
||||
|
||||
/*
|
||||
** An instance of the following structure stores a database schema.
|
||||
**
|
||||
** If there are no virtual tables configured in this schema, the
|
||||
** Schema.db variable is set to NULL. After the first virtual table
|
||||
** has been added, it is set to point to the database connection
|
||||
** used to create the connection. Once a virtual table has been
|
||||
** added to the Schema structure and the Schema.db variable populated,
|
||||
** only that database connection may use the Schema to prepare
|
||||
** statements.
|
||||
*/
|
||||
struct Schema {
|
||||
int schema_cookie; /* Database schema version number for this file */
|
||||
@ -393,6 +401,9 @@ struct Schema {
|
||||
u8 enc; /* Text encoding used by this database */
|
||||
u16 flags; /* Flags associated with this schema */
|
||||
int cache_size; /* Number of pages to use in the cache */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3 *db; /* "Owner" connection. See comment above */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1632,7 +1643,7 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
|
||||
#endif
|
||||
|
||||
void sqlite3DropTable(Parse*, SrcList*, int, int);
|
||||
void sqlite3DeleteTable(sqlite3*, Table*);
|
||||
void sqlite3DeleteTable(Table*);
|
||||
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
|
||||
void *sqlite3ArrayAllocate(void*,int,int,int*,int*,int*);
|
||||
IdList *sqlite3IdListAppend(IdList*, Token*);
|
||||
@ -1890,7 +1901,7 @@ int sqlite3OpenTempDatabase(Parse *);
|
||||
int sqlite3VtabCommit(sqlite3 *db);
|
||||
#endif
|
||||
void sqlite3VtabLock(sqlite3_vtab*);
|
||||
void sqlite3VtabUnlock(sqlite3_vtab*);
|
||||
void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*);
|
||||
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
|
||||
void sqlite3VtabFinishParse(Parse*, Token*);
|
||||
void sqlite3VtabArgInit(Parse*);
|
||||
|
@ -15,7 +15,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** parser for analysis.
|
||||
**
|
||||
** $Id: tokenize.c,v 1.125 2007/01/26 19:31:01 drh Exp $
|
||||
** $Id: tokenize.c,v 1.126 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -495,7 +495,7 @@ abort_parse:
|
||||
** structure built up in pParse->pNewTable. The calling code (see vtab.c)
|
||||
** will take responsibility for freeing the Table structure.
|
||||
*/
|
||||
sqlite3DeleteTable(pParse->db, pParse->pNewTable);
|
||||
sqlite3DeleteTable(pParse->pNewTable);
|
||||
}
|
||||
|
||||
sqlite3DeleteTrigger(pParse->pNewTrigger);
|
||||
|
@ -43,7 +43,7 @@
|
||||
** 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.598 2007/03/30 18:42:56 drh Exp $
|
||||
** $Id: vdbe.c,v 1.599 2007/04/16 15:06:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -4881,7 +4881,7 @@ case OP_VUpdate: { /* no-push */
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
sqlite3VtabLock(pVtab);
|
||||
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
|
||||
sqlite3VtabUnlock(pVtab);
|
||||
sqlite3VtabUnlock(db, 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) );
|
||||
|
21
src/vtab.c
21
src/vtab.c
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to help implement virtual tables.
|
||||
**
|
||||
** $Id: vtab.c,v 1.39 2007/01/09 14:01:14 drh Exp $
|
||||
** $Id: vtab.c,v 1.40 2007/04/16 15:06:26 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h"
|
||||
@ -56,10 +56,18 @@ void sqlite3VtabLock(sqlite3_vtab *pVtab){
|
||||
** Unlock a virtual table. When the last lock is removed,
|
||||
** disconnect the virtual table.
|
||||
*/
|
||||
void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
|
||||
void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){
|
||||
pVtab->nRef--;
|
||||
assert(db);
|
||||
assert(!sqlite3SafetyCheck(db));
|
||||
if( pVtab->nRef==0 ){
|
||||
pVtab->pModule->xDisconnect(pVtab);
|
||||
if( db->magic==SQLITE_MAGIC_BUSY ){
|
||||
sqlite3SafetyOff(db);
|
||||
pVtab->pModule->xDisconnect(pVtab);
|
||||
sqlite3SafetyOn(db);
|
||||
} else {
|
||||
pVtab->pModule->xDisconnect(pVtab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +80,7 @@ void sqlite3VtabClear(Table *p){
|
||||
sqlite3_vtab *pVtab = p->pVtab;
|
||||
if( pVtab ){
|
||||
assert( p->pMod && p->pMod->pModule );
|
||||
sqlite3VtabUnlock(pVtab);
|
||||
sqlite3VtabUnlock(p->pSchema->db, pVtab);
|
||||
p->pVtab = 0;
|
||||
}
|
||||
if( p->azModuleArg ){
|
||||
@ -248,6 +256,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
|
||||
return;
|
||||
}
|
||||
pSchema->db = pParse->db;
|
||||
pParse->pNewTable = 0;
|
||||
}
|
||||
}
|
||||
@ -465,7 +474,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
sParse.declareVtab = 0;
|
||||
|
||||
sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
|
||||
sqlite3DeleteTable(0, sParse.pNewTable);
|
||||
sqlite3DeleteTable(sParse.pNewTable);
|
||||
sParse.pNewTable = 0;
|
||||
db->pVTab = 0;
|
||||
|
||||
@ -518,7 +527,7 @@ static void callFinaliser(sqlite3 *db, int offset){
|
||||
int (*x)(sqlite3_vtab *);
|
||||
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
|
||||
if( x ) x(pVtab);
|
||||
sqlite3VtabUnlock(pVtab);
|
||||
sqlite3VtabUnlock(db, pVtab);
|
||||
}
|
||||
sqliteFree(db->aVTrans);
|
||||
db->nVTrans = 0;
|
||||
|
@ -12,7 +12,7 @@
|
||||
# focus of this file inserting into virtual tables from a SELECT
|
||||
# statement.
|
||||
#
|
||||
# $Id: vtab9.test,v 1.1 2006/08/29 18:46:14 drh Exp $
|
||||
# $Id: vtab9.test,v 1.2 2007/04/16 15:06:26 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -46,5 +46,25 @@ do_test vtab9-1.2 {
|
||||
}
|
||||
} {1 1 2 3 2 a b c 3 {} x 123.456 4 hi 123456789 -12345}
|
||||
|
||||
# do_test vtab9-2.1 {
|
||||
# execsql {
|
||||
# CREATE TABLE t4(a);
|
||||
# CREATE VIRTUAL TABLE t5 USING echo(t4);
|
||||
# INSERT INTO t4 VALUES('hello');
|
||||
# SELECT rowid, a FROM t5;
|
||||
# }
|
||||
# } {1 hello}
|
||||
# do_test vtab9-2.2 {
|
||||
# execsql {
|
||||
# INSERT INTO t5(rowid, a) VALUES(1, 'goodbye');
|
||||
# }
|
||||
# } {1 hello}
|
||||
# do_test vtab9-2.3 {
|
||||
# execsql {
|
||||
# REPLACE INTO t5(rowid, a) VALUES(1, 'goodbye');
|
||||
# SELECT * FROM t5;
|
||||
# }
|
||||
# } {1 goodbye}
|
||||
|
||||
unset -nocomplain echo_module_begin_fail
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user