mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add newly created virtual tables to the current transaction. (CVS 3267)
FossilOrigin-Name: ea7e4eca106cea27d5dc447d2afcd45448152151
This commit is contained in:
17
manifest
17
manifest
@ -1,5 +1,5 @@
|
||||
C Clear\sa\scompiler\swarning\sby\sadding\sa\sprototype\sto\ssqliteInt.h.\s(CVS\s3266)
|
||||
D 2006-06-17T10:44:42
|
||||
C Add\snewly\screated\svirtual\stables\sto\sthe\scurrent\stransaction.\s(CVS\s3267)
|
||||
D 2006-06-17T11:30:32
|
||||
F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -104,7 +104,7 @@ F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
|
||||
F src/vdbeaux.c dc5cfd11a0529fcfd217a1807f7c9df513f1c276
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||
F src/vtab.c d9f19d0d5afe2ebf68f111672a4d24deb3231fe3
|
||||
F src/vtab.c 8fbf4a8f718229d2158826ed6e440f2d32a07c80
|
||||
F src/where.c d7c3cc011834882b2d58ebb3a6a1a569ead7ebd7
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -291,7 +291,8 @@ F test/vacuum.test 37f998b841cb335397c26d9bbc3457182af2565f
|
||||
F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5
|
||||
F test/vtab1.test 6a7defe56939acae6d4f725f2837468e4e212bff
|
||||
F test/vtab1.test cb90ff6852a0dcb72965939df5da2bb1b3fcbcf9
|
||||
F test/vtab2.test a0968c4e5e1b4197bd9a5a348bd4022196711a65
|
||||
F test/vtab3.test b3ea5dfdc36ba23ba5136928b6c307c5125ababc
|
||||
F test/vtab4.test 4b4293341443839ef6dc02f8d9e614702a6c67ff
|
||||
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
||||
@ -369,7 +370,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 8a5b121f2f26bebe3f1164bc2f504d29b74400f4
|
||||
R 401ddf160aa3c954727e040c555b14f8
|
||||
U drh
|
||||
Z 98a57c00f7372ac68514301d821c7a26
|
||||
P ca541ef3c464c5627596a48ee7f1ec40948cf65d
|
||||
R faa9d9cb2a77be8fd7c7ebc5ab33c027
|
||||
U danielk1977
|
||||
Z 34ba78ce8d03975fc32264aceaa96871
|
||||
|
@ -1 +1 @@
|
||||
ca541ef3c464c5627596a48ee7f1ec40948cf65d
|
||||
ea7e4eca106cea27d5dc447d2afcd45448152151
|
107
src/vtab.c
107
src/vtab.c
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to help implement virtual tables.
|
||||
**
|
||||
** $Id: vtab.c,v 1.17 2006/06/17 09:39:56 danielk1977 Exp $
|
||||
** $Id: vtab.c,v 1.18 2006/06/17 11:30:32 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h"
|
||||
@ -331,6 +331,29 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add the virtual table pVtab to the array sqlite3.aVTrans[].
|
||||
*/
|
||||
int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
|
||||
const int ARRAY_INCR = 5;
|
||||
|
||||
/* Grow the sqlite3.aVTrans array if required */
|
||||
if( (db->nVTrans%ARRAY_INCR)==0 ){
|
||||
sqlite3_vtab **aVTrans;
|
||||
int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
|
||||
aVTrans = sqliteRealloc((void *)db->aVTrans, nBytes);
|
||||
if( !aVTrans ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
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;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is invoked by the vdbe to call the xCreate method
|
||||
** of the virtual table named zTab in database iDb.
|
||||
@ -361,6 +384,10 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
|
||||
rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && pTab->pVtab ){
|
||||
rc = addToVTrans(db, pTab->pVtab);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -441,39 +468,51 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int callFinaliser(sqlite3 *db, int offset, int doDelete){
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
for(i=0; rc==SQLITE_OK && 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 ){
|
||||
rc = x(pVtab);
|
||||
}
|
||||
}
|
||||
if( doDelete ){
|
||||
sqliteFree(db->aVTrans);
|
||||
db->nVTrans = 0;
|
||||
db->aVTrans = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void sqlite3VtabCodeLock(Parse *pParse, Table *pTab){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeOp3(v, OP_VBegin, 0, 0, (const char*)pTab->pVtab, P3_VTAB);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function invokes either the xRollback or xCommit method
|
||||
** of each of the virtual tables in the sqlite3.aVTrans array. The method
|
||||
** called is identified by the second argument, "offset", which is
|
||||
** the offset of the method to call in the sqlite3_module structure.
|
||||
**
|
||||
** The array is cleared after invoking the callbacks.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
sqliteFree(db->aVTrans);
|
||||
db->nVTrans = 0;
|
||||
db->aVTrans = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** If argument rc is not SQLITE_OK, then return it and do nothing.
|
||||
** Otherwise, invoke the xSync method of all virtual tables in the
|
||||
** sqlite3.aVTrans array. Return the error code for the first error
|
||||
** that occurs, or SQLITE_OK if all xSync operations are successful.
|
||||
*/
|
||||
int sqlite3VtabSync(sqlite3 *db, int rc){
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
return callFinaliser(db, (int)(&((sqlite3_module *)0)->xSync), 0);
|
||||
int sqlite3VtabSync(sqlite3 *db, int rc2){
|
||||
int i;
|
||||
int rc = SQLITE_OK;
|
||||
if( rc2!=SQLITE_OK ) return rc2;
|
||||
for(i=0; rc==SQLITE_OK && i<db->nVTrans && db->aVTrans[i]; i++){
|
||||
sqlite3_vtab *pVtab = db->aVTrans[i];
|
||||
int (*x)(sqlite3_vtab *);
|
||||
x = pVtab->pModule->xSync;
|
||||
if( x ){
|
||||
rc = x(pVtab);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -481,7 +520,8 @@ int sqlite3VtabSync(sqlite3 *db, int rc){
|
||||
** sqlite3.aVTrans array. Then clear the array itself.
|
||||
*/
|
||||
int sqlite3VtabRollback(sqlite3 *db){
|
||||
return callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback), 1);
|
||||
callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -489,7 +529,8 @@ int sqlite3VtabRollback(sqlite3 *db){
|
||||
** sqlite3.aVTrans array. Then clear the array itself.
|
||||
*/
|
||||
int sqlite3VtabCommit(sqlite3 *db){
|
||||
return callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit), 1);
|
||||
callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -502,7 +543,6 @@ int sqlite3VtabCommit(sqlite3 *db){
|
||||
*/
|
||||
int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
|
||||
int rc = SQLITE_OK;
|
||||
const int ARRAY_INCR = 5;
|
||||
const sqlite3_module *pModule = pVtab->pModule;
|
||||
if( pModule->xBegin ){
|
||||
int i;
|
||||
@ -520,20 +560,7 @@ int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Grow the sqlite3.aVTrans array if required */
|
||||
if( (db->nVTrans%ARRAY_INCR)==0 ){
|
||||
sqlite3_vtab **aVTrans;
|
||||
int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
|
||||
aVTrans = sqliteRealloc((void *)db->aVTrans, nBytes);
|
||||
if( !aVTrans ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
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;
|
||||
rc = addToVTrans(db, pVtab);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is creating and dropping virtual tables.
|
||||
#
|
||||
# $Id: vtab1.test,v 1.20 2006/06/17 03:27:23 danielk1977 Exp $
|
||||
# $Id: vtab1.test,v 1.21 2006/06/17 11:30:33 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -234,7 +234,10 @@ do_test vtab1-3.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING echo(treal);
|
||||
}
|
||||
set echo_module
|
||||
} [list xCreate echo treal]
|
||||
} [list xCreate echo treal \
|
||||
xSync echo(treal) \
|
||||
xCommit echo(treal) \
|
||||
]
|
||||
|
||||
# Test that a SELECT on t1 doesn't crash. No rows are returned
|
||||
# because the underlying real table is currently empty.
|
||||
|
41
test/vtab2.test
Normal file
41
test/vtab2.test
Normal file
@ -0,0 +1,41 @@
|
||||
# 2006 June 10
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# 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 implements regression tests for SQLite library.
|
||||
#
|
||||
# $Id: vtab2.test,v 1.1 2006/06/17 11:30:33 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !vtab {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
register_schema_module [sqlite3_connection_pointer db]
|
||||
do_test vtab2-1.1 {
|
||||
execsql {
|
||||
CREATE VIRTUAL TABLE schema USING schema;
|
||||
SELECT * FROM schema;
|
||||
}
|
||||
} [list \
|
||||
main schema 0 database {} 0 {} 0 \
|
||||
main schema 1 tablename {} 0 {} 0 \
|
||||
main schema 2 cid {} 0 {} 0 \
|
||||
main schema 3 name {} 0 {} 0 \
|
||||
main schema 4 type {} 0 {} 0 \
|
||||
main schema 5 not_null {} 0 {} 0 \
|
||||
main schema 6 dflt_value {} 0 {} 0 \
|
||||
main schema 7 pk {} 0 {} 0 \
|
||||
]
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user