SQLite

Check-in [adb2bd6143]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When in PAGER_RESERVED state, don't write to the main file when rolling back a statement transaction. (CVS 1560)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: adb2bd61436927d37b23bae857089d62e12397af
User & Date: danielk1977 2004-06-10 04:32:17.000
Context
2004-06-10
05:59
Misc fixes for test cases failing due to the new locking model. (CVS 1561) (check-in: 71e98d0d08 user: danielk1977 tags: trunk)
04:32
When in PAGER_RESERVED state, don't write to the main file when rolling back a statement transaction. (CVS 1560) (check-in: adb2bd6143 user: danielk1977 tags: trunk)
02:16
Change the collation sequence interface to allow collation sequences that use UTF-16 in non-native byte order to be registered. (CVS 1559) (check-in: b8aaa3a29e user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.120 2004/06/10 02:16:02 danielk1977 Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>








|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.121 2004/06/10 04:32:17 danielk1977 Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

513
514
515
516
517
518
519

520


521



522
523

524

525
526

527
528
529
530
531
532
533
    rc = read32bits(jfd, &cksum);
    if( rc ) return rc;
    if( pager_cksum(pPager, pgno, aData)!=cksum ){
      return SQLITE_DONE;
    }
  }


  /* Playback the page.  Update the in-memory copy of the page


  ** at the same time, if there is one.



  */
  pPg = pager_lookup(pPager, pgno);

  TRACE2("PLAYBACK page %d\n", pgno);

  sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
  rc = sqlite3OsWrite(&pPager->fd, aData, SQLITE_PAGE_SIZE);

  if( pPg ){
    /* No page should ever be rolled back that is in use, except for page
    ** 1 which is held in use in order to keep the lock on the database
    ** active.
    */
    void *pData;
    assert( pPg->nRef==0 || pPg->pgno==1 );







>
|
>
>
|
>
>
>


>

>
|
|
>







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
    rc = read32bits(jfd, &cksum);
    if( rc ) return rc;
    if( pager_cksum(pPager, pgno, aData)!=cksum ){
      return SQLITE_DONE;
    }
  }

  assert( pPager->state==PAGER_RESERVED || pPager->state==PAGER_EXCLUSIVE );

  /* If the pager is in RESERVED state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file.
  **
  ** If in EXCLUSIVE state, then we update the pager cache if it exists
  ** and the main file. The page is then marked not dirty.
  */
  pPg = pager_lookup(pPager, pgno);
  assert( pPager->state==PAGER_EXCLUSIVE || pPg );
  TRACE2("PLAYBACK page %d\n", pgno);
  if( pPager->state==PAGER_EXCLUSIVE ){
    sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
    rc = sqlite3OsWrite(&pPager->fd, aData, SQLITE_PAGE_SIZE);
  }
  if( pPg ){
    /* No page should ever be rolled back that is in use, except for page
    ** 1 which is held in use in order to keep the lock on the database
    ** active.
    */
    void *pData;
    assert( pPg->nRef==0 || pPg->pgno==1 );
Changes to src/vdbeaux.c.
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
    }else if( p->errorAction==OE_Abort ){
      xFunc = sqlite3BtreeRollbackStmt;
    }else{
      xFunc = sqlite3BtreeRollback;
      db->autoCommit = 1;
    }
  }


  /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
  ** each backend. If an error occurs and the return code is still
  ** SQLITE_OK, set the return code to the new error value.
  */
  for(i=0; xFunc && i<db->nDb; i++){ 







>







1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
    }else if( p->errorAction==OE_Abort ){
      xFunc = sqlite3BtreeRollbackStmt;
    }else{
      xFunc = sqlite3BtreeRollback;
      db->autoCommit = 1;
    }
  }
  p->autoCommitOn = 0;

  /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
  ** each backend. If an error occurs and the return code is still
  ** SQLITE_OK, set the return code to the new error value.
  */
  for(i=0; xFunc && i<db->nDb; i++){ 
Changes to test/trigger3.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#
# This file tests the RAISE() function.
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl
set sqlite_os_trace 1
execsql {
 PRAGMA vdbe_listing=on;
 PRAGMA sql_trace=on;
 PRAGMA vdbe_trace=on;
}

# Test that we can cause ROLLBACK, FAIL and ABORT correctly
# catchsql { DROP TABLE tbl; }
catchsql { CREATE TABLE tbl (a, b, c) }

execsql {
    CREATE TRIGGER before_tbl_insert BEFORE INSERT ON tbl BEGIN SELECT CASE 







<
<
<
<
<
<







9
10
11
12
13
14
15






16
17
18
19
20
21
22
#
# This file tests the RAISE() function.
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl







# Test that we can cause ROLLBACK, FAIL and ABORT correctly
# catchsql { DROP TABLE tbl; }
catchsql { CREATE TABLE tbl (a, b, c) }

execsql {
    CREATE TRIGGER before_tbl_insert BEFORE INSERT ON tbl BEGIN SELECT CASE 
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	SELECT * FROM tbl;
	ROLLBACK;
    }
} {5 5 6}
do_test trigger3-1.3 {
    execsql {SELECT * FROM tbl}
} {}
exit

# FAIL
do_test trigger3-2.1 {
    catchsql {
	BEGIN;
        INSERT INTO tbl VALUES (5, 5, 6);
        INSERT INTO tbl VALUES (2, 5, 6);







<







42
43
44
45
46
47
48

49
50
51
52
53
54
55
	SELECT * FROM tbl;
	ROLLBACK;
    }
} {5 5 6}
do_test trigger3-1.3 {
    execsql {SELECT * FROM tbl}
} {}


# FAIL
do_test trigger3-2.1 {
    catchsql {
	BEGIN;
        INSERT INTO tbl VALUES (5, 5, 6);
        INSERT INTO tbl VALUES (2, 5, 6);