| OLD | NEW | 
 | (Empty) | 
|    1 # 2004 June 30 |  | 
|    2 # |  | 
|    3 # The author disclaims copyright to this source code.  In place of |  | 
|    4 # a legal notice, here is a blessing: |  | 
|    5 # |  | 
|    6 #    May you do good and not evil. |  | 
|    7 #    May you find forgiveness for yourself and forgive others. |  | 
|    8 #    May you share freely, never taking more than you give. |  | 
|    9 # |  | 
|   10 #*********************************************************************** |  | 
|   11 # This file implements regression tests for SQLite library.  The |  | 
|   12 # focus of this file is verifying that a rollback in one statement |  | 
|   13 # caused by an ON CONFLICT ROLLBACK clause aborts any other pending |  | 
|   14 # statements. |  | 
|   15 # |  | 
|   16 # $Id: rollback.test,v 1.11 2009/06/26 07:12:07 danielk1977 Exp $ |  | 
|   17  |  | 
|   18 set testdir [file dirname $argv0] |  | 
|   19 source $testdir/tester.tcl |  | 
|   20  |  | 
|   21 set DB [sqlite3_connection_pointer db] |  | 
|   22  |  | 
|   23 do_test rollback-1.1 { |  | 
|   24   execsql { |  | 
|   25     CREATE TABLE t1(a); |  | 
|   26     INSERT INTO t1 VALUES(1); |  | 
|   27     INSERT INTO t1 VALUES(2); |  | 
|   28     INSERT INTO t1 VALUES(3); |  | 
|   29     INSERT INTO t1 VALUES(4); |  | 
|   30     SELECT * FROM t1; |  | 
|   31   } |  | 
|   32 } {1 2 3 4} |  | 
|   33  |  | 
|   34 ifcapable conflict { |  | 
|   35   do_test rollback-1.2 { |  | 
|   36     execsql { |  | 
|   37       CREATE TABLE t3(a unique on conflict rollback); |  | 
|   38       INSERT INTO t3 SELECT a FROM t1; |  | 
|   39       BEGIN; |  | 
|   40       INSERT INTO t1 SELECT * FROM t1; |  | 
|   41     } |  | 
|   42   } {} |  | 
|   43 } |  | 
|   44 do_test rollback-1.3 { |  | 
|   45   set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL] |  | 
|   46   sqlite3_step $STMT |  | 
|   47 } {SQLITE_ROW} |  | 
|   48  |  | 
|   49 ifcapable conflict { |  | 
|   50   # This causes a ROLLBACK, which deletes the table out from underneath the |  | 
|   51   # SELECT statement. |  | 
|   52   # |  | 
|   53   do_test rollback-1.4 { |  | 
|   54     catchsql { |  | 
|   55       INSERT INTO t3 SELECT a FROM t1; |  | 
|   56     } |  | 
|   57   } {1 {column a is not unique}} |  | 
|   58    |  | 
|   59   # Try to continue with the SELECT statement |  | 
|   60   # |  | 
|   61   do_test rollback-1.5 { |  | 
|   62     sqlite3_step $STMT |  | 
|   63   } {SQLITE_ERROR} |  | 
|   64  |  | 
|   65   # Restart the SELECT statement |  | 
|   66   # |  | 
|   67   do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_ABORT} |  | 
|   68 } else { |  | 
|   69   do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_OK} |  | 
|   70 } |  | 
|   71  |  | 
|   72 do_test rollback-1.7 { |  | 
|   73   sqlite3_step $STMT |  | 
|   74 } {SQLITE_ROW} |  | 
|   75 do_test rollback-1.8 { |  | 
|   76   sqlite3_step $STMT |  | 
|   77 } {SQLITE_ROW} |  | 
|   78 do_test rollback-1.9 { |  | 
|   79   sqlite3_finalize $STMT |  | 
|   80 } {SQLITE_OK} |  | 
|   81  |  | 
|   82 set permutation "" |  | 
|   83 catch {set permutation $::permutations_test_prefix} |  | 
|   84 if {$tcl_platform(platform) == "unix"  |  | 
|   85  && $permutation ne "onefile" |  | 
|   86  && $permutation ne "inmemory_journal" |  | 
|   87 } { |  | 
|   88   do_test rollback-2.1 { |  | 
|   89     execsql { |  | 
|   90       BEGIN; |  | 
|   91       INSERT INTO t3 VALUES('hello world'); |  | 
|   92     } |  | 
|   93     file copy -force test.db testA.db |  | 
|   94     file copy -force test.db-journal testA.db-journal |  | 
|   95     execsql { |  | 
|   96       COMMIT; |  | 
|   97     } |  | 
|   98   } {} |  | 
|   99  |  | 
|  100   # At this point files testA.db and testA.db-journal are present in the |  | 
|  101   # file system. This block adds a master-journal file pointer to the |  | 
|  102   # end of testA.db-journal. The master-journal file does not exist. |  | 
|  103   #  |  | 
|  104   set mj [file normalize testA.db-mj-123] |  | 
|  105   binary scan $mj c* a |  | 
|  106   set cksum 0 |  | 
|  107   foreach i $a { incr cksum $i } |  | 
|  108   set mj_pgno [expr $sqlite_pending_byte / 1024] |  | 
|  109   set zAppend [binary format Ia*IIa8 $mj_pgno $mj [string length $mj] $cksum \ |  | 
|  110     "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" |  | 
|  111   ] |  | 
|  112   set iOffset [expr (([file size testA.db-journal] + 511)/512)*512] |  | 
|  113   set fd [open testA.db-journal a+] |  | 
|  114   fconfigure $fd -encoding binary -translation binary |  | 
|  115   seek $fd $iOffset |  | 
|  116   puts -nonewline $fd $zAppend |  | 
|  117  |  | 
|  118   # Also, fix the first journal-header in the journal-file. Because the |  | 
|  119   # journal file has not yet been synced, the 8-byte magic string at the |  | 
|  120   # start of the first journal-header has not been written by SQLite. |  | 
|  121   # So write it now. |  | 
|  122   seek $fd 0 |  | 
|  123   puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" |  | 
|  124   close $fd |  | 
|  125  |  | 
|  126   # Open a handle on testA.db and use it to query the database. At one |  | 
|  127   # point the first query would attempt a hot rollback, attempt to open |  | 
|  128   # the master-journal file and return SQLITE_CANTOPEN when it could not |  | 
|  129   # be opened. This is incorrect, it should simply delete the journal |  | 
|  130   # file and proceed with the query. |  | 
|  131   #  |  | 
|  132   do_test rollback-2.2 { |  | 
|  133     sqlite3 db2 testA.db |  | 
|  134     execsql { |  | 
|  135       SELECT distinct tbl_name FROM sqlite_master; |  | 
|  136     } db2 |  | 
|  137   } {t1 t3} |  | 
|  138   if {[lsearch {exclusive persistent_journal no_journal} $permutation]<0} { |  | 
|  139     do_test rollback-2.3 { |  | 
|  140       file exists testA.db-journal |  | 
|  141     } 0 |  | 
|  142   } |  | 
|  143   do_test rollback-2.4 { |  | 
|  144     execsql { |  | 
|  145       SELECT distinct tbl_name FROM sqlite_master; |  | 
|  146     } db2 |  | 
|  147   } {t1 t3} |  | 
|  148  |  | 
|  149   db2 close |  | 
|  150 } |  | 
|  151  |  | 
|  152 finish_test |  | 
| OLD | NEW |