From c69cdfd4ecce182b60d459520de81a366c2555b1 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Sat, 17 Jun 2006 09:39:55 +0000 Subject: [PATCH] Add tests (and fixes) for the virtual table transaction interface. (CVS 3265) FossilOrigin-Name: 8a5b121f2f26bebe3f1164bc2f504d29b74400f4 --- manifest | 21 +++--- manifest.uuid | 2 +- src/sqlite.h.in | 3 +- src/test8.c | 60 ++++++++++++++- src/update.c | 3 +- src/vtab.c | 4 +- test/auth.test | 3 +- test/vtab4.test | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 267 insertions(+), 21 deletions(-) create mode 100644 test/vtab4.test diff --git a/manifest b/manifest index 88c6ce227f..09e00a8758 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\supdating\sa\sview,\sinvoke\sthe\sauthorization\scallback\sfor\sreading\sthe\sview\sbefore\ssetting\sthe\sauthorization-context\sto\sthe\sview\sname.\s(CVS\s3264) -D 2006-06-17T06:31:19 +C Add\stests\s(and\sfixes)\sfor\sthe\svirtual\stable\stransaction\sinterface.\s(CVS\s3265) +D 2006-06-17T09:39:56 F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -72,7 +72,7 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261 F src/select.c c1965c636482bf96754c518b91600f81e17f5c85 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36 -F src/sqlite.h.in 77b42d1bb5deafa04ae156d24cd243c2d75800ac +F src/sqlite.h.in 7855b46387f3f6ac1925301f450df9cbd7a1269b F src/sqlite3ext.h e334107f6cad0d00c0414e04189742a45ce916b1 F src/sqliteInt.h dc69927751ee107aa5232e5c3aa7dd1d4329bb15 F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e @@ -84,7 +84,7 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25 F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3 -F src/test8.c 75d9ef60e12ea8a281ab6cd9643992a5a99b2c6a +F src/test8.c 9641e41a7d35588fc0a834439b6c404700e7c148 F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3 @@ -93,7 +93,7 @@ F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c F src/test_tclvar.c c52f67fbe06d32804af2ba9a2d7aadfc15f5910c F src/tokenize.c 6ebcafa6622839968dda4418a7b6945f277a128f F src/trigger.c 0fc40125820409a6274834a6e04ad804d96e2793 -F src/update.c 81e8d54aa970e045f930cd5c918363f669db0420 +F src/update.c 23a71ccef6b26e8fddfc2e5b3d36f3e8d0fa868d F src/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44 F src/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d F src/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9 @@ -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 a0bcc2da7e27fbfa2635c2dc4b964a641f220c78 +F src/vtab.c d9f19d0d5afe2ebf68f111672a4d24deb3231fe3 F src/where.c d7c3cc011834882b2d58ebb3a6a1a569ead7ebd7 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -120,7 +120,7 @@ F test/attach.test c616a88eab6b6fd99b7b2fcf449420f14628bc0b F test/attach2.test 0e6a7c54343c85dd877a1e86073a05176043ed40 F test/attach3.test fc0302e8fe9c172fb49e000227c19b5c428a9429 F test/attachmalloc.test cdb26c42850f04698377ccec05f5fa89d987837c -F test/auth.test b7db5241345bc6cb4164cdef2dd687576c4611d4 +F test/auth.test 5e27e39ed196bea6ddb5f4a55e1a202062ea2cf8 F test/autoinc.test 60005a676e3e4e17dfa9dbd08aa0b76587ff97e3 F test/autovacuum.test eee7e67d80f7839d11435660ae0a5566a9f7558c F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31 @@ -293,6 +293,7 @@ F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5 F test/vtab1.test 6a7defe56939acae6d4f725f2837468e4e212bff F test/vtab3.test b3ea5dfdc36ba23ba5136928b6c307c5125ababc +F test/vtab4.test 4b4293341443839ef6dc02f8d9e614702a6c67ff F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394 F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa @@ -368,7 +369,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 81c5a5b48b05186a1690198092ac92006d9f7020 -R 4bd1f7bb52bbedc6bf653776cdf0cb73 +P 48d297c561b8d3d670ab425115ef50d1901523b6 +R 5211a47fbe9c7d890a08bd8b570a8a1d U danielk1977 -Z 949ec801aa978076825007b5248ff956 +Z 158058c4c02e6113c0e6c0e187c6e004 diff --git a/manifest.uuid b/manifest.uuid index 2ad6b3e455..7b9a9b7a83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48d297c561b8d3d670ab425115ef50d1901523b6 \ No newline at end of file +8a5b121f2f26bebe3f1164bc2f504d29b74400f4 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 6fefee6a58..426ba73574 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.179 2006/06/16 08:01:04 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.180 2006/06/17 09:39:56 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -1558,7 +1558,6 @@ struct sqlite3_module { int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); - int (*xIsInTrans)(sqlite3_vtab *pVTab); }; /* diff --git a/src/test8.c b/src/test8.c index 563d2799d0..5e412e1c68 100644 --- a/src/test8.c +++ b/src/test8.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test8.c,v 1.24 2006/06/16 06:17:47 danielk1977 Exp $ +** $Id: test8.c,v 1.25 2006/06/17 09:39:56 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -24,6 +24,14 @@ typedef struct echo_vtab echo_vtab; typedef struct echo_cursor echo_cursor; +/* +** The test module defined in this file uses two global Tcl variables to +** commicate with test-scripts: +** +** $::echo_module +** $::echo_module_sync_fail +*/ + /* ** An echo virtual-table object. ** @@ -32,7 +40,8 @@ typedef struct echo_cursor echo_cursor; ** (implicit or otherwise). In other words, if SQLite can optimize ** a query like "SELECT * FROM real_table WHERE col = ?". ** -** Member variable contains copies of the column names of the real table. +** Member variable aCol[] contains copies of the column names of the real +** table. */ struct echo_vtab { sqlite3_vtab base; @@ -614,6 +623,47 @@ int echoUpdate( return rc; } +/* +** xBegin, xSync, xCommit and xRollback callbacks for echo module +** virtual tables. Do nothing other than add the name of the callback +** to the $::echo_module Tcl variable. +*/ +static int echoTransactionCall(sqlite3_vtab *tab, const char *zCall){ + char *z; + echo_vtab *pVtab = (echo_vtab *)tab; + z = sqlite3_mprintf("echo(%s)", pVtab->zTableName); + appendToEchoModule(pVtab->interp, zCall); + appendToEchoModule(pVtab->interp, z); + sqlite3_free(z); + return SQLITE_OK; +} +static int echoBegin(sqlite3_vtab *tab){ + return echoTransactionCall(tab, "xBegin"); +} +static int echoSync(sqlite3_vtab *tab){ + echo_vtab *pVtab = (echo_vtab *)tab; + Tcl_Interp *interp = pVtab->interp; + const char *zVal; + + echoTransactionCall(tab, "xSync"); + + /* Check if the $::echo_module_sync_fail variable is defined. If it is, + ** and it is set to the name of the real table underlying this virtual + ** echo module table, then cause this xSync operation to fail. + */ + zVal = Tcl_GetVar(interp, "echo_module_sync_fail", TCL_GLOBAL_ONLY); + if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){ + return -1; + } + return SQLITE_OK; +} +static int echoCommit(sqlite3_vtab *tab){ + return echoTransactionCall(tab, "xCommit"); +} +static int echoRollback(sqlite3_vtab *tab){ + return echoTransactionCall(tab, "xRollback"); +} + /* ** A virtual table module that merely echos method calls into TCL ** variables. @@ -632,7 +682,11 @@ static sqlite3_module echoModule = { echoNext, /* xNext - advance a cursor */ echoColumn, /* xColumn - read data */ echoRowid, /* xRowid - read data */ - echoUpdate /* xUpdate - write data */ + echoUpdate, /* xUpdate - write data */ + echoBegin, /* xBegin - begin transaction */ + echoSync, /* xSync - sync transaction */ + echoCommit, /* xCommit - commit transaction */ + echoRollback /* xRollback - rollback transaction */ }; /* diff --git a/src/update.c b/src/update.c index d56dde4efa..9118492f97 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.129 2006/06/17 06:31:19 danielk1977 Exp $ +** $Id: update.c,v 1.130 2006/06/17 09:39:56 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -611,6 +611,7 @@ static void updateVirtualTable( for(i=0; inCol; i++){ sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0)); } + pParse->pVirtualLock = pTab; sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, (const char*)pTab->pVtab, P3_VTAB); sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr); diff --git a/src/vtab.c b/src/vtab.c index e950a1b53f..0c5eeab6b3 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.16 2006/06/17 03:27:23 danielk1977 Exp $ +** $Id: vtab.c,v 1.17 2006/06/17 09:39:56 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -447,7 +447,7 @@ static int callFinaliser(sqlite3 *db, int offset, int doDelete){ 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); + x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); if( x ){ rc = x(pVtab); } diff --git a/test/auth.test b/test/auth.test index 70a8a0bb91..1efd099445 100644 --- a/test/auth.test +++ b/test/auth.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # -# $Id: auth.test,v 1.35 2006/06/17 06:31:19 danielk1977 Exp $ +# $Id: auth.test,v 1.36 2006/06/17 09:39:56 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -2225,7 +2225,6 @@ do_test auth-4.2 { } {115 117} do_test auth-4.3 { set authargs {} -breakpoint execsql { UPDATE v1 SET x=1 WHERE x=117 } diff --git a/test/vtab4.test b/test/vtab4.test new file mode 100644 index 0000000000..abd32e37da --- /dev/null +++ b/test/vtab4.test @@ -0,0 +1,192 @@ +# 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. The +# focus is on testing the following virtual table methods: +# +# xBegin +# xSync +# xCommit +# xRollback +# +# $Id: vtab4.test,v 1.1 2006/06/17 09:39:56 danielk1977 Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !vtab { + finish_test + return +} + +# Register the echo module +db cache size 0 +register_echo_module [sqlite3_connection_pointer db] + +do_test vtab4-1.1 { + execsql { + CREATE TABLE treal(a PRIMARY KEY, b, c); + CREATE VIRTUAL TABLE techo USING echo(treal); + } +} {} + +# Test an INSERT, UPDATE and DELETE statement on the virtual table +# in an implicit transaction. Each should result in a single call +# to xBegin, xSync and xCommit. +# +do_test vtab4-1.2 { + set echo_module [list] + execsql { + INSERT INTO techo VALUES(1, 2, 3); + } + set echo_module +} {xBegin echo(treal) xSync echo(treal) xCommit echo(treal)} +do_test vtab4-1.3 { + set echo_module [list] + execsql { + UPDATE techo SET a = 2; + } + set echo_module +} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ + xBegin echo(treal) \ + xFilter {SELECT rowid, * FROM 'treal'} \ + xSync echo(treal) \ + xCommit echo(treal) \ +] +do_test vtab4-1.4 { + set echo_module [list] + execsql { + DELETE FROM techo; + } + set echo_module +} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ + xBegin echo(treal) \ + xFilter {SELECT rowid, * FROM 'treal'} \ + xSync echo(treal) \ + xCommit echo(treal) \ +] + +# Ensure xBegin is not called more than once in a single transaction. +# +do_test vtab4-2.1 { + set echo_module [list] + execsql { + BEGIN; + INSERT INTO techo VALUES(1, 2, 3); + INSERT INTO techo VALUES(4, 5, 6); + INSERT INTO techo VALUES(7, 8, 9); + COMMIT; + } + set echo_module +} {xBegin echo(treal) xSync echo(treal) xCommit echo(treal)} + +# Try a transaction with two virtual tables. +# +do_test vtab4-2.2 { + execsql { + CREATE TABLE sreal(a, b, c UNIQUE); + CREATE VIRTUAL TABLE secho USING echo(sreal); + } + set echo_module [list] + execsql { + BEGIN; + INSERT INTO secho SELECT * FROM techo; + DELETE FROM techo; + COMMIT; + } + set echo_module +} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ + xBegin echo(sreal) \ + xFilter {SELECT rowid, * FROM 'treal'} \ + xBestIndex {SELECT rowid, * FROM 'treal'} \ + xBegin echo(treal) \ + xFilter {SELECT rowid, * FROM 'treal'} \ + xSync echo(sreal) \ + xSync echo(treal) \ + xCommit echo(sreal) \ + xCommit echo(treal) \ +] +do_test vtab4-2.3 { + execsql { + SELECT * FROM secho; + } +} {1 2 3 4 5 6 7 8 9} +do_test vtab4-2.4 { + execsql { + SELECT * FROM techo; + } +} {} + +# Try an explicit ROLLBACK on a transaction with two open virtual tables. +do_test vtab4-2.5 { + set echo_module [list] + execsql { + BEGIN; + INSERT INTO techo SELECT * FROM secho; + DELETE FROM secho; + ROLLBACK; + } + set echo_module +} [list xBestIndex {SELECT rowid, * FROM 'sreal'} \ + xBegin echo(treal) \ + xFilter {SELECT rowid, * FROM 'sreal'} \ + xBestIndex {SELECT rowid, * FROM 'sreal'} \ + xBegin echo(sreal) \ + xFilter {SELECT rowid, * FROM 'sreal'} \ + xRollback echo(treal) \ + xRollback echo(sreal) \ +] +do_test vtab4-2.6 { + execsql { + SELECT * FROM secho; + } +} {1 2 3 4 5 6 7 8 9} +do_test vtab4-2.7 { + execsql { + SELECT * FROM techo; + } +} {} + +do_test vtab4-3.1 { + set echo_module [list] + set echo_module_sync_fail treal + catchsql { + INSERT INTO techo VALUES(1, 2, 3); + } +} {1 {unknown error}} +do_test vtab4-3.2 { + set echo_module +} {xBegin echo(treal) xSync echo(treal) xRollback echo(treal)} + +breakpoint +do_test vtab4-3.3 { + set echo_module [list] + set echo_module_sync_fail sreal + catchsql { + BEGIN; + INSERT INTO techo SELECT * FROM secho; + DELETE FROM secho; + COMMIT; + } + set echo_module +} [list xBestIndex {SELECT rowid, * FROM 'sreal'} \ + xBegin echo(treal) \ + xFilter {SELECT rowid, * FROM 'sreal'} \ + xBestIndex {SELECT rowid, * FROM 'sreal'} \ + xBegin echo(sreal) \ + xFilter {SELECT rowid, * FROM 'sreal'} \ + xSync echo(treal) \ + xSync echo(sreal) \ + xRollback echo(treal) \ + xRollback echo(sreal) \ +] + +finish_test +