mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Allow database writes from within virtual table module xSync() callbacks. (CVS 3334)
FossilOrigin-Name: d5a608d0a412e13dfced6a3827574a2cff802f25
This commit is contained in:
17
manifest
17
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\slemon\sso\sthat\sit\sdoes\snot\scrash\son\sa\sempty\sreduce\saction.\s\sTicket\s#1892.\s(CVS\s3333)
|
C Allow\sdatabase\swrites\sfrom\swithin\svirtual\stable\smodule\sxSync()\scallbacks.\s(CVS\s3334)
|
||||||
D 2006-07-17T00:19:39
|
D 2006-07-25T15:14:53
|
||||||
F Makefile.in 9c2a76055c305868cc5f5b73e29a252ff3632c0a
|
F Makefile.in 9c2a76055c305868cc5f5b73e29a252ff3632c0a
|
||||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -101,10 +101,10 @@ F src/vdbe.c 3ffc96ec2e870b3ab3e59d1f6fe34687e4ed1db6
|
|||||||
F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
|
F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
|
||||||
F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
|
F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
|
||||||
F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
|
F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
|
||||||
F src/vdbeaux.c 51722bb3661f2d836c1a7a8e7eac242859ddbd07
|
F src/vdbeaux.c 0088120c4e321f680d2728d26770f35c10dc64b1
|
||||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||||
F src/vtab.c 34b20b011147ca6df6bda565f7c791760698279f
|
F src/vtab.c 1fe25b3e59f92ed1f29b63ac9c6f954eb6907a29
|
||||||
F src/where.c 75a89957fcb8c068bec55caa4e9d2ed5fa0b0724
|
F src/where.c 75a89957fcb8c068bec55caa4e9d2ed5fa0b0724
|
||||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@@ -299,6 +299,7 @@ F test/vtab3.test f38d6d7d19f08bffdadce4d5b8cba078f8118587
|
|||||||
F test/vtab4.test 4b4293341443839ef6dc02f8d9e614702a6c67ff
|
F test/vtab4.test 4b4293341443839ef6dc02f8d9e614702a6c67ff
|
||||||
F test/vtab5.test 9fb8f335651afe8f870011e2f68e5b00c5ad03cd
|
F test/vtab5.test 9fb8f335651afe8f870011e2f68e5b00c5ad03cd
|
||||||
F test/vtab6.test ec0036f29f8a803da9935206f2d9d1b6a8026392
|
F test/vtab6.test ec0036f29f8a803da9935206f2d9d1b6a8026392
|
||||||
|
F test/vtab7.test b87ed57f6f635728c86fbad556e7844927dbc9a8
|
||||||
F test/vtab_err.test 11b90203ad60d63746d0de547b1ca014704d8f0e
|
F test/vtab_err.test 11b90203ad60d63746d0de547b1ca014704d8f0e
|
||||||
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
||||||
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
||||||
@@ -375,7 +376,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P b0d19e575b14778e76ae5d6546fba0d2e9f25e33
|
P 4207ebc4e107df9f9f046be652f061e53263c8dd
|
||||||
R 561f99ebf82ea369ef9b3313bf8e7d52
|
R b62c9f53d5d9aafa4e186b1b50a281ff
|
||||||
U drh
|
U danielk1977
|
||||||
Z 12ff8c7d7f4fc93ec58cc516f73d8e63
|
Z 4145b3acb8db85dcd373c4df89f46175
|
||||||
|
@@ -1 +1 @@
|
|||||||
4207ebc4e107df9f9f046be652f061e53263c8dd
|
d5a608d0a412e13dfced6a3827574a2cff802f25
|
@@ -868,7 +868,9 @@ void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){
|
|||||||
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
|
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
|
||||||
const sqlite3_module *pModule = pCx->pModule;
|
const sqlite3_module *pModule = pCx->pModule;
|
||||||
p->inVtabMethod = 1;
|
p->inVtabMethod = 1;
|
||||||
|
sqlite3SafetyOff(p->db);
|
||||||
pModule->xClose(pVtabCursor);
|
pModule->xClose(pVtabCursor);
|
||||||
|
sqlite3SafetyOn(p->db);
|
||||||
p->inVtabMethod = 0;
|
p->inVtabMethod = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -983,6 +985,23 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int needXcommit = 0;
|
int needXcommit = 0;
|
||||||
|
|
||||||
|
/* Before doing anything else, call the xSync() callback for any
|
||||||
|
** virtual module tables written in this transaction. This has to
|
||||||
|
** be done before determining whether a master journal file is
|
||||||
|
** required, as an xSync() callback may add an attached database
|
||||||
|
** to the transaction.
|
||||||
|
*/
|
||||||
|
rc = sqlite3VtabSync(db, rc);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This loop determines (a) if the commit hook should be invoked and
|
||||||
|
** (b) how many database files have open write transactions, not
|
||||||
|
** including the temp database. (b) is important because if more than
|
||||||
|
** one database file has an open write transaction, a master journal
|
||||||
|
** file is required for an atomic commit.
|
||||||
|
*/
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
Btree *pBt = db->aDb[i].pBt;
|
Btree *pBt = db->aDb[i].pBt;
|
||||||
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
||||||
@@ -1017,7 +1036,6 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
rc = sqlite3BtreeSync(pBt, 0);
|
rc = sqlite3BtreeSync(pBt, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = sqlite3VtabSync(db, rc);
|
|
||||||
|
|
||||||
/* Do the commit only if all databases successfully synced */
|
/* Do the commit only if all databases successfully synced */
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@@ -1109,20 +1127,17 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
** file name was written into the journal file before the failure
|
** file name was written into the journal file before the failure
|
||||||
** occured.
|
** occured.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||||
Btree *pBt = db->aDb[i].pBt;
|
Btree *pBt = db->aDb[i].pBt;
|
||||||
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
||||||
rc = sqlite3BtreeSync(pBt, zMaster);
|
rc = sqlite3BtreeSync(pBt, zMaster);
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
sqlite3OsClose(&master);
|
|
||||||
sqliteFree(zMaster);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = sqlite3VtabSync(db, SQLITE_OK);
|
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
|
||||||
sqlite3OsClose(&master);
|
sqlite3OsClose(&master);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqliteFree(zMaster);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delete the master journal file. This commits the transaction. After
|
/* Delete the master journal file. This commits the transaction. After
|
||||||
** doing this the directory is synced again before any individual
|
** doing this the directory is synced again before any individual
|
||||||
@@ -1426,7 +1441,9 @@ int sqlite3VdbeReset(Vdbe *p){
|
|||||||
** error, then it might not have been halted properly. So halt
|
** error, then it might not have been halted properly. So halt
|
||||||
** it now.
|
** it now.
|
||||||
*/
|
*/
|
||||||
|
sqlite3SafetyOn(p->db);
|
||||||
sqlite3VdbeHalt(p);
|
sqlite3VdbeHalt(p);
|
||||||
|
sqlite3SafetyOff(p->db);
|
||||||
|
|
||||||
/* If the VDBE has be run even partially, then transfer the error code
|
/* If the VDBE has be run even partially, then transfer the error code
|
||||||
** and error message from the VDBE into the main database structure. But
|
** and error message from the VDBE into the main database structure. But
|
||||||
@@ -1495,7 +1512,6 @@ int sqlite3VdbeReset(Vdbe *p){
|
|||||||
*/
|
*/
|
||||||
int sqlite3VdbeFinalize(Vdbe *p){
|
int sqlite3VdbeFinalize(Vdbe *p){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
|
if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
|
||||||
rc = sqlite3VdbeReset(p);
|
rc = sqlite3VdbeReset(p);
|
||||||
}else if( p->magic!=VDBE_MAGIC_INIT ){
|
}else if( p->magic!=VDBE_MAGIC_INIT ){
|
||||||
|
13
src/vtab.c
13
src/vtab.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to help implement virtual tables.
|
** This file contains code used to help implement virtual tables.
|
||||||
**
|
**
|
||||||
** $Id: vtab.c,v 1.27 2006/07/08 18:09:15 drh Exp $
|
** $Id: vtab.c,v 1.28 2006/07/25 15:14:53 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -503,7 +503,7 @@ static void callFinaliser(sqlite3 *db, int offset){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If argument rc is not SQLITE_OK, then return it and do nothing.
|
** If argument rc2 is not SQLITE_OK, then return it and do nothing.
|
||||||
** Otherwise, invoke the xSync method of all virtual tables in the
|
** Otherwise, invoke the xSync method of all virtual tables in the
|
||||||
** sqlite3.aVTrans array. Return the error code for the first error
|
** sqlite3.aVTrans array. Return the error code for the first error
|
||||||
** that occurs, or SQLITE_OK if all xSync operations are successful.
|
** that occurs, or SQLITE_OK if all xSync operations are successful.
|
||||||
@@ -511,7 +511,9 @@ static void callFinaliser(sqlite3 *db, int offset){
|
|||||||
int sqlite3VtabSync(sqlite3 *db, int rc2){
|
int sqlite3VtabSync(sqlite3 *db, int rc2){
|
||||||
int i;
|
int i;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
int rcsafety;
|
||||||
if( rc2!=SQLITE_OK ) return rc2;
|
if( rc2!=SQLITE_OK ) return rc2;
|
||||||
|
rc = sqlite3SafetyOff(db);
|
||||||
for(i=0; rc==SQLITE_OK && i<db->nVTrans && db->aVTrans[i]; i++){
|
for(i=0; rc==SQLITE_OK && i<db->nVTrans && db->aVTrans[i]; i++){
|
||||||
sqlite3_vtab *pVtab = db->aVTrans[i];
|
sqlite3_vtab *pVtab = db->aVTrans[i];
|
||||||
int (*x)(sqlite3_vtab *);
|
int (*x)(sqlite3_vtab *);
|
||||||
@@ -520,6 +522,10 @@ int sqlite3VtabSync(sqlite3 *db, int rc2){
|
|||||||
rc = x(pVtab);
|
rc = x(pVtab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rcsafety = sqlite3SafetyOn(db);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = rcsafety;
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,7 +602,6 @@ FuncDef *sqlite3VtabOverloadFunction(
|
|||||||
sqlite3_module *pMod;
|
sqlite3_module *pMod;
|
||||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
|
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
|
||||||
void *pArg;
|
void *pArg;
|
||||||
int rc;
|
|
||||||
FuncDef *pNew;
|
FuncDef *pNew;
|
||||||
|
|
||||||
/* Check to see the left operand is a column in a virtual table */
|
/* Check to see the left operand is a column in a virtual table */
|
||||||
@@ -608,7 +613,7 @@ FuncDef *sqlite3VtabOverloadFunction(
|
|||||||
pVtab = pTab->pVtab;
|
pVtab = pTab->pVtab;
|
||||||
assert( pVtab!=0 );
|
assert( pVtab!=0 );
|
||||||
assert( pVtab->pModule!=0 );
|
assert( pVtab->pModule!=0 );
|
||||||
pMod = pVtab->pModule;
|
pMod = (sqlite3_module *)pVtab->pModule;
|
||||||
if( pMod->xFindFunction==0 ) return pDef;
|
if( pMod->xFindFunction==0 ) return pDef;
|
||||||
|
|
||||||
/* Call the xFuncFunction method on the virtual table implementation
|
/* Call the xFuncFunction method on the virtual table implementation
|
||||||
|
163
test/vtab7.test
Normal file
163
test/vtab7.test
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# 2006 July 25
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# of this test is reading and writing to the database from within a
|
||||||
|
# virtual table xSync() callback.
|
||||||
|
#
|
||||||
|
# $Id: vtab7.test,v 1.1 2006/07/25 15:14:53 danielk1977 Exp $
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
ifcapable !vtab {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register the echo module. Code inside the echo module appends elements
|
||||||
|
# to the global tcl list variable ::echo_module whenever SQLite invokes
|
||||||
|
# certain module callbacks. This includes the xSync(), xCommit() and
|
||||||
|
# xRollback() callbacks. For each of these callback, two elements are
|
||||||
|
# appended to ::echo_module, as follows:
|
||||||
|
#
|
||||||
|
# Module method Elements appended to ::echo_module
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# xSync() xSync echo($tablename)
|
||||||
|
# xCommit() xCommit echo($tablename)
|
||||||
|
# xRollback() xRollback echo($tablename)
|
||||||
|
# -------------------------------------------------------
|
||||||
|
#
|
||||||
|
# In each case, $tablename is replaced by the name of the real table (not
|
||||||
|
# the echo table). By setting up a tcl trace on the ::echo_module variable,
|
||||||
|
# code in this file arranges for a Tcl script to be executed from within
|
||||||
|
# the echo module xSync() callback.
|
||||||
|
#
|
||||||
|
register_echo_module [sqlite3_connection_pointer db]
|
||||||
|
trace add variable ::echo_module write echo_module_trace
|
||||||
|
|
||||||
|
# This Tcl proc is invoked whenever the ::echo_module variable is written.
|
||||||
|
#
|
||||||
|
proc echo_module_trace {args} {
|
||||||
|
# Filter out writes to ::echo_module that are not xSync, xCommit or
|
||||||
|
# xRollback callbacks.
|
||||||
|
if {[llength $::echo_module] < 2} return
|
||||||
|
set x [lindex $::echo_module end-1]
|
||||||
|
if {$x ne "xSync" && $x ne "xCommit" && $x ne "xRollback"} return
|
||||||
|
|
||||||
|
regexp {^echo.(.*).$} [lindex $::echo_module end] dummy tablename
|
||||||
|
# puts "Ladies and gentlemen, an $x on $tablename!"
|
||||||
|
|
||||||
|
if {[info exists ::callbacks($x,$tablename)]} {
|
||||||
|
eval $::callbacks($x,$tablename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# The following tests, vtab7-1.*, test that the trace callback on
|
||||||
|
# ::echo_module is providing the expected tcl callbacks.
|
||||||
|
do_test vtab7-1.1 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE abc(a, b, c);
|
||||||
|
CREATE VIRTUAL TABLE abc2 USING echo(abc);
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_test vtab7-1.2 {
|
||||||
|
set ::callbacks(xSync,abc) {incr ::counter}
|
||||||
|
set ::counter 0
|
||||||
|
execsql {
|
||||||
|
INSERT INTO abc2 VALUES(1, 2, 3);
|
||||||
|
}
|
||||||
|
set ::counter
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
# Write to an existing database table from within an xSync callback.
|
||||||
|
do_test vtab7-2.1 {
|
||||||
|
set ::callbacks(xSync,abc) {
|
||||||
|
execsql {INSERT INTO log VALUES('xSync');}
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE log(msg);
|
||||||
|
INSERT INTO abc2 VALUES(4, 5, 6);
|
||||||
|
SELECT * FROM log;
|
||||||
|
}
|
||||||
|
} {xSync}
|
||||||
|
do_test vtab7-2.3 {
|
||||||
|
execsql {
|
||||||
|
INSERT INTO abc2 VALUES(4, 5, 6);
|
||||||
|
SELECT * FROM log;
|
||||||
|
}
|
||||||
|
} {xSync xSync}
|
||||||
|
do_test vtab7-2.4 {
|
||||||
|
execsql {
|
||||||
|
INSERT INTO abc2 VALUES(4, 5, 6);
|
||||||
|
SELECT * FROM log;
|
||||||
|
}
|
||||||
|
} {xSync xSync xSync}
|
||||||
|
|
||||||
|
# Create a database table from within xSync callback.
|
||||||
|
do_test vtab7-2.5 {
|
||||||
|
set ::callbacks(xSync,abc) {
|
||||||
|
execsql { CREATE TABLE newtab(d, e, f); }
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
INSERT INTO abc2 VALUES(1, 2, 3);
|
||||||
|
SELECT name FROM sqlite_master ORDER BY name;
|
||||||
|
}
|
||||||
|
} {abc abc2 log newtab}
|
||||||
|
|
||||||
|
# Drop a database table from within xSync callback.
|
||||||
|
do_test vtab7-2.6 {
|
||||||
|
set ::callbacks(xSync,abc) {
|
||||||
|
execsql { DROP TABLE newtab }
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
INSERT INTO abc2 VALUES(1, 2, 3);
|
||||||
|
SELECT name FROM sqlite_master ORDER BY name;
|
||||||
|
}
|
||||||
|
} {abc abc2 log}
|
||||||
|
|
||||||
|
# Write to an attached database from xSync().
|
||||||
|
do_test vtab7-3.1 {
|
||||||
|
file delete -force test2.db
|
||||||
|
file delete -force test2.db-journal
|
||||||
|
execsql {
|
||||||
|
ATTACH 'test2.db' AS db2;
|
||||||
|
CREATE TABLE db2.stuff(description, shape, color);
|
||||||
|
}
|
||||||
|
set ::callbacks(xSync,abc) {
|
||||||
|
execsql { INSERT INTO db2.stuff VALUES('abc', 'square', 'green'); }
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
INSERT INTO abc2 VALUES(1, 2, 3);
|
||||||
|
SELECT * from stuff;
|
||||||
|
}
|
||||||
|
} {abc square green}
|
||||||
|
|
||||||
|
# UPDATE: The next test passes, but leaks memory. So leave it out.
|
||||||
|
#
|
||||||
|
# The following tests test that writing to the database from within
|
||||||
|
# the xCommit callback causes a misuse error.
|
||||||
|
# do_test vtab7-4.1 {
|
||||||
|
# unset -nocomplain ::callbacks(xSync,abc)
|
||||||
|
# set ::callbacks(xCommit,abc) {
|
||||||
|
# execsql { INSERT INTO log VALUES('hello') }
|
||||||
|
# }
|
||||||
|
# catchsql {
|
||||||
|
# INSERT INTO abc2 VALUES(1, 2, 3);
|
||||||
|
# }
|
||||||
|
# } {1 {library routine called out of sequence}}
|
||||||
|
|
||||||
|
|
||||||
|
trace remove variable ::echo_module write echo_module_trace
|
||||||
|
unset -nocomplain ::callbacks
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
Reference in New Issue
Block a user