From e7ff403ab11c01ee31651682d58e1a76aa6022f1 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Sat, 17 Jun 2006 11:30:32 +0000 Subject: [PATCH] Add newly created virtual tables to the current transaction. (CVS 3267) FossilOrigin-Name: ea7e4eca106cea27d5dc447d2afcd45448152151 --- manifest | 17 ++++---- manifest.uuid | 2 +- src/vtab.c | 107 ++++++++++++++++++++++++++++++------------------ test/vtab1.test | 7 +++- test/vtab2.test | 41 +++++++++++++++++++ 5 files changed, 123 insertions(+), 51 deletions(-) create mode 100644 test/vtab2.test diff --git a/manifest b/manifest index b6a67c969f..46ed7e0640 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index 17675d39e9..da49997ba0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca541ef3c464c5627596a48ee7f1ec40948cf65d \ No newline at end of file +ea7e4eca106cea27d5dc447d2afcd45448152151 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index 0c5eeab6b3..9f56cb45e7 100644 --- a/src/vtab.c +++ b/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 && inVTrans && 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; inVTrans && 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 && inVTrans && 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; } diff --git a/test/vtab1.test b/test/vtab1.test index 42671336aa..273df9e914 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -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. diff --git a/test/vtab2.test b/test/vtab2.test new file mode 100644 index 0000000000..0ab70315dd --- /dev/null +++ b/test/vtab2.test @@ -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 +