Index: src/test8.c ================================================================== --- src/test8.c +++ src/test8.c @@ -1229,17 +1229,55 @@ sqlite3_free(zSql); } return rc; } + +static int echoSavepoint(sqlite3_vtab *pVTab, int iSavepoint){ + assert( pVTab ); + return SQLITE_OK; +} + +static int echoRelease(sqlite3_vtab *pVTab, int iSavepoint){ + assert( pVTab ); + return SQLITE_OK; +} + +static int echoRollbackTo(sqlite3_vtab *pVTab, int iSavepoint){ + assert( pVTab ); + return SQLITE_OK; +} /* ** A virtual table module that merely "echos" the contents of another ** table (like an SQL VIEW). */ static sqlite3_module echoModule = { - 0, /* iVersion */ + 1, /* iVersion */ + echoCreate, + echoConnect, + echoBestIndex, + echoDisconnect, + echoDestroy, + echoOpen, /* xOpen - open a cursor */ + echoClose, /* xClose - close a cursor */ + echoFilter, /* xFilter - configure scan constraints */ + echoNext, /* xNext - advance a cursor */ + echoEof, /* xEof */ + echoColumn, /* xColumn - read data */ + echoRowid, /* xRowid - read data */ + echoUpdate, /* xUpdate - write data */ + echoBegin, /* xBegin - begin transaction */ + echoSync, /* xSync - sync transaction */ + echoCommit, /* xCommit - commit transaction */ + echoRollback, /* xRollback - rollback transaction */ + echoFindFunction, /* xFindFunction - function overloading */ + echoRename /* xRename - rename the table */ +}; + +static sqlite3_module echoModuleV2 = { + 2, /* iVersion */ echoCreate, echoConnect, echoBestIndex, echoDisconnect, echoDestroy, @@ -1255,10 +1293,13 @@ echoSync, /* xSync - sync transaction */ echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ echoFindFunction, /* xFindFunction - function overloading */ echoRename, /* xRename - rename the table */ + echoSavepoint, + echoRelease, + echoRollbackTo }; /* ** Decode a pointer to an sqlite3 object. */ @@ -1282,13 +1323,22 @@ if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + + /* Virtual table module "echo" */ pMod = sqlite3_malloc(sizeof(EchoModule)); pMod->interp = interp; sqlite3_create_module_v2(db, "echo", &echoModule, (void*)pMod, moduleDestroy); + + /* Virtual table module "echo_v2" */ + pMod = sqlite3_malloc(sizeof(EchoModule)); + pMod->interp = interp; + sqlite3_create_module_v2(db, "echo_v2", + &echoModuleV2, (void*)pMod, moduleDestroy + ); return TCL_OK; } /* ** Tcl interface to sqlite3_declare_vtab, invoked as follows from Tcl: Index: test/vtab1.test ================================================================== --- test/vtab1.test +++ test/vtab1.test @@ -1175,8 +1175,23 @@ 'table', 't3', 't3', 0, 'INSERT INTO "%s%s" VALUES(1)' ); } catchsql { CREATE VIRTUAL TABLE t4 USING echo(t3); } } {1 {vtable constructor failed: t4}} + +# This test verifies that ticket 48f29963 is fixed. +# +do_test vtab1-17.1 { + execsql { + CREATE TABLE t5(a, b); + CREATE VIRTUAL TABLE e5 USING echo_v2(t5); + BEGIN; + INSERT INTO e5 VALUES(1, 2); + DROP TABLE e5; + SAVEPOINT one; + ROLLBACK TO one; + COMMIT; + } +} {} unset -nocomplain echo_module_begin_fail finish_test