Add savepoint2.test, a file containing savepoint tests similar to tests in trans.test and avtrans.test. And a few savepoint bug fixes. (CVS 6039)

FossilOrigin-Name: 98a53d91f6c0c2692d3b56687fdaba8eeab0959d
This commit is contained in:
danielk1977 2008-12-18 15:45:07 +00:00
parent 78d41832fc
commit 12dd54962d
5 changed files with 185 additions and 18 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\sbug\sin\sicuOpen()\sin\sfts2.\s(CVS\s6038)
D 2008-12-18T05:30:26
C Add\ssavepoint2.test,\sa\sfile\scontaining\ssavepoint\stests\ssimilar\sto\stests\sin\strans.test\sand\savtrans.test.\sAnd\sa\sfew\ssavepoint\sbug\sfixes.\s(CVS\s6039)
D 2008-12-18T15:45:07
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in f7e4c81c347b04f7b0f1c1b081a168645d7b8af7
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -102,7 +102,7 @@ F src/attach.c 1c35f95da3c62d19de75b44cfefd12c81c1791b3
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/bitvec.c 4300d311b17fb3c1476623fd895a8feac02a0b08
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
F src/btree.c c402a9a15fe62508b332517b162f6fdbcf1bfb47
F src/btree.c ad51b56b1a90e3c9ad39aabd9368325aba5a6730
F src/btree.h 4f141cf748d2ee7c6d7fc175f64f87a45cd44113
F src/btreeInt.h 7ef2c872371d7508657f8d7a4efe651c741d6ee6
F src/build.c f3e8377cbc0d007b01aab1e7d4fc1d5b296c422e
@ -141,7 +141,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
F src/os_unix.c 96b4a6e87335ba943455740f311b4dfb63f26756
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
F src/pager.c dd1aba4a1dc246b72d15fa9ffcf59902cea51d54
F src/pager.c 9c1663c9406743f30cdad532c01c47f71bfac577
F src/pager.h 7191294438881eb4d13eedade97891e8dc993905
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
@ -491,6 +491,7 @@ F test/rowid.test 1c8fc43c60d273e6ea44dfb992db587f3164312c
F test/rtree.test b85fd4f0861a40ca366ac195e363be2528dcfadf
F test/safety.test b69e2b2dd5d52a3f78e216967086884bbc1a09c6
F test/savepoint.test fdad3b61f4a00a96cd773ca0c758cf2f53918ae3
F test/savepoint2.test dcaf442a9eea4e91c27fce339fd74c3eaa66577e
F test/schema.test a8b000723375fd42c68d310091bdbd744fde647c
F test/schema2.test 35e1c9696443d6694c8980c411497c2b5190d32e
F test/select1.test d0a4cad954fd41c030ec16ffbd2d08a4c0548742
@ -679,7 +680,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 78401b33febf678cfeec2a35514eb4172de420ab
R 09419362acc9ec794afd36b3528f0694
P b9c722bd96b44e0fabd1564ddd982d2aabb7047c
R e8991f966fc1a93805d33d53f39d5eb2
U danielk1977
Z 152f2d9b602bfeed8b492ec878934f0b
Z 23f7ea8ae683063fc7d5590449b66501

View File

@ -1 +1 @@
b9c722bd96b44e0fabd1564ddd982d2aabb7047c
98a53d91f6c0c2692d3b56687fdaba8eeab0959d

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.549 2008/12/17 17:30:26 danielk1977 Exp $
** $Id: btree.c,v 1.550 2008/12/18 15:45:07 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
@ -2060,8 +2060,13 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
trans_begun:
if( rc==SQLITE_OK && wrflag ){
/* This call makes sure that the pager has the correct number of
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
}
btreeIntegrity(p);
sqlite3BtreeLeave(p);
return rc;
@ -2740,8 +2745,7 @@ int sqlite3BtreeBeginStmt(Btree *p){
** SQL statements. It is illegal to open, release or rollback any
** such savepoints while the statement transaction savepoint is active.
*/
int iStmtpoint = p->db->nSavepoint + 1;
rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStmtpoint);
rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint+1);
}
pBt->inStmt = 1;
}
@ -2797,8 +2801,14 @@ int sqlite3BtreeRollbackStmt(Btree *p){
/*
** The second argument to this function, op, is always SAVEPOINT_ROLLBACK
** or SAVEPOINT_RELEASE. This function either releases or rolls back the
** savepoint identified by parameter iSavepoint, depending on the value of
** op.
** savepoint identified by parameter iSavepoint, depending on the value
** of op.
**
** Normally, iSavepoint is greater than or equal to zero. However, if op is
** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the
** contents of the entire transaction are rolled back. This is different
** from a normal transaction rollback, as no locks are released and the
** transaction remains open.
*/
int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
int rc = SQLITE_OK;

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.515 2008/12/17 17:30:26 danielk1977 Exp $
** @(#) $Id: pager.c,v 1.516 2008/12/18 15:45:07 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@ -1649,7 +1649,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
if( nJRec==0 ){
nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
}
for(ii=0; rc==SQLITE_OK && ii<nJRec; ii++){
for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
rc = pager_playback_one_page(pPager, 1, pPager->journalOff, pDone);
assert( rc!=SQLITE_DONE );
}
@ -2437,6 +2437,7 @@ static int pager_write_pagelist(PgHdr *pList){
if( pList->pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
char *pData = CODEC2(pPager, pList->pData, pList->pgno, 6);
PAGERTRACE4("STORE %d page %d hash(%08x)\n",
PAGERID(pPager), pList->pgno, pager_pagehash(pList));
IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno));
@ -3548,7 +3549,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirect){
#ifndef SQLITE_ENABLE_ATOMIC_WRITE
assert( isDirect==0 ); /* isDirect is only true for atomic writes */
#endif
if( !pPager->changeCountDone ){
if( !pPager->changeCountDone && pPager->dbSize>0 ){
/* Open page 1 of the file for writing. */
rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
if( rc!=SQLITE_OK ) return rc;
@ -3900,7 +3901,7 @@ int sqlite3PagerIsMemdb(Pager *pPager){
int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
int rc = SQLITE_OK;
if( nSavepoint>pPager->nSavepoint ){
if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){
int ii;
/* Either the sub-journal is open or there are no active savepoints. */
@ -3925,7 +3926,7 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
/* Populate the PagerSavepoint structures just allocated. */
for(/* no-op */; ii<nSavepoint; ii++){
assert( pPager->dbSize>=0 );
assert( pPager->dbSizeValid );
aNew[ii].nOrig = pPager->dbSize;
aNew[ii].iOffset = (pPager->journalOpen ? pPager->journalOff : 0);
aNew[ii].iSubRec = pPager->stmtNRec;

155
test/savepoint2.test Normal file
View File

@ -0,0 +1,155 @@
# 2008 December 15
#
# 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.
#
#***********************************************************************
#
# $Id: savepoint2.test,v 1.1 2008/12/18 15:45:07 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Tests in this file are quite similar to those run by trans.test and
# avtrans.test.
#
proc signature {} {
return [db eval {SELECT count(*), md5sum(x) FROM t3}]
}
do_test savepoint2-1 {
execsql {
PRAGMA cache_size=10;
}
db close
sqlite3 db test.db
execsql {
BEGIN;
CREATE TABLE t3(x TEXT);
INSERT INTO t3 VALUES(randstr(10,400));
INSERT INTO t3 VALUES(randstr(10,400));
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
INSERT INTO t3 SELECT randstr(10,400) FROM t3;
COMMIT;
SELECT count(*) FROM t3;
}
} {1024}
unset -nocomplain ::sig
unset -nocomplain SQL
set iterations 20
set SQL(1) {
DELETE FROM t3 WHERE random()%10!=0;
INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
}
set SQL(2) {
DELETE FROM t3 WHERE random()%10!=0;
INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
DELETE FROM t3 WHERE random()%10!=0;
INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
}
set SQL(3) {
UPDATE t3 SET x = randstr(10, 400) WHERE random()%10;
INSERT INTO t3 SELECT x FROM t3 WHERE random()%10;
DELETE FROM t3 WHERE random()%10;
}
set SQL(4) {
INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE (random()%10 == 0);
}
for {set ii 2} {$ii < ($iterations+2)} {incr ii} {
# Record the database signature. Optionally (every second run) open a
# transaction. In all cases open savepoint "one", which may or may
# not be a transaction savepoint, depending on whether or not a real
# transaction has been opened.
#
do_test savepoint2-$ii.1 {
if {$ii % 2} { execsql BEGIN }
set ::sig(one) [signature]
execsql "SAVEPOINT one"
} {}
# Execute some SQL on the database. Then rollback to savepoint "one".
# Check that the database signature is as it was when "one" was opened.
#
do_test savepoint2-$ii.2 {
execsql $SQL(1)
execsql "ROLLBACK to one"
signature
} $::sig(one)
integrity_check savepoint2-$ii.2.1
# Execute some SQL. Then open savepoint "two". Savepoint "two" is therefore
# nested in savepoint "one".
#
do_test savepoint2-$ii.3 {
execsql $SQL(1)
set ::sig(two) [signature]
execsql "SAVEPOINT two"
} {}
# More SQL changes. The rollback to savepoint "two". Check that the
# signature is as it was when savepoint "two" was opened.
#
do_test savepoint2-$ii.4 {
execsql $SQL(2)
execsql "ROLLBACK to two"
signature
} $::sig(two)
integrity_check savepoint2-$ii.4.1
# More SQL changes. The rollback to savepoint "two". Check that the
# signature is as it was when savepoint "two" was opened.
#
do_test savepoint2-$ii.5 {
execsql $SQL(2)
execsql "SAVEPOINT three"
execsql $SQL(3)
execsql "RELEASE three"
execsql "ROLLBACK to one"
signature
} $::sig(one)
# By this point the database is in the same state as it was at the
# top of the for{} loop (everything having been rolled back by the
# "ROLLBACK TO one" command above). So make a few changes to the
# database and COMMIT the open transaction, so that the next iteration
# of the for{} loop works on a different dataset.
#
# The transaction being committed here may have been opened normally using
# "BEGIN", or may have been opened using a transaction savepoint created
# by the "SAVEPOINT one" statement.
#
do_test savepoint2-$ii.6 {
execsql $SQL(4)
execsql COMMIT
sqlite3_get_autocommit db
} {1}
integrity_check savepoint2-$ii.6.1
}
unset -nocomplain ::sig
unset -nocomplain SQL
finish_test