/ Check-in [df51cb16]
Login

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

Overview
Comment:Fix for ticket #110: return an error if trying to start a transaction within a transaction or when attempting to commit or rollback outside of a transaction. (CVS 721)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:df51cb166bf7c5b8b0530cc86df8d2d68de81a40
User & Date: drh 2002-08-18 20:28:07
Context
2002-08-18
22:41
This COLLATE keyword was not being parsed correctly inside CREATE TABLE statements - it was being included as part of the datatype. This fixes the problem. (CVS 722) check-in: 39bd52d3 user: drh tags: trunk
20:28
Fix for ticket #110: return an error if trying to start a transaction within a transaction or when attempting to commit or rollback outside of a transaction. (CVS 721) check-in: df51cb16 user: drh tags: trunk
19:09
Documentation updates. (CVS 720) check-in: e372a60b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    21     21   **     COPY
    22     22   **     VACUUM
    23     23   **     BEGIN TRANSACTION
    24     24   **     COMMIT
    25     25   **     ROLLBACK
    26     26   **     PRAGMA
    27     27   **
    28         -** $Id: build.c,v 1.108 2002/08/15 01:26:09 drh Exp $
           28  +** $Id: build.c,v 1.109 2002/08/18 20:28:07 drh Exp $
    29     29   */
    30     30   #include "sqliteInt.h"
    31     31   #include <ctype.h>
    32     32   
    33     33   /*
    34     34   ** This routine is called when a new SQL statement is beginning to
    35     35   ** be parsed.  Check to see if the schema for the database needs
................................................................................
  1725   1725   ** Begin a transaction
  1726   1726   */
  1727   1727   void sqliteBeginTransaction(Parse *pParse, int onError){
  1728   1728     sqlite *db;
  1729   1729   
  1730   1730     if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
  1731   1731     if( pParse->nErr || sqlite_malloc_failed ) return;
  1732         -  if( db->flags & SQLITE_InTrans ) return;
         1732  +  if( db->flags & SQLITE_InTrans ){
         1733  +    pParse->nErr++;
         1734  +    sqliteSetString(&pParse->zErrMsg, "cannot start a transaction "
         1735  +       "within a transaction", 0);
         1736  +    return;
         1737  +  }
  1733   1738     sqliteBeginWriteOperation(pParse, 0);
  1734   1739     db->flags |= SQLITE_InTrans;
  1735   1740     db->onError = onError;
  1736   1741   }
  1737   1742   
  1738   1743   /*
  1739   1744   ** Commit a transaction
  1740   1745   */
  1741   1746   void sqliteCommitTransaction(Parse *pParse){
  1742   1747     sqlite *db;
  1743   1748   
  1744   1749     if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
  1745   1750     if( pParse->nErr || sqlite_malloc_failed ) return;
  1746         -  if( (db->flags & SQLITE_InTrans)==0 ) return;
         1751  +  if( (db->flags & SQLITE_InTrans)==0 ){
         1752  +    pParse->nErr++;
         1753  +    sqliteSetString(&pParse->zErrMsg, 
         1754  +       "cannot commit - no transaction is active", 0);
         1755  +    return;
         1756  +  }
  1747   1757     db->flags &= ~SQLITE_InTrans;
  1748   1758     sqliteEndWriteOperation(pParse);
  1749   1759     db->onError = OE_Default;
  1750   1760   }
  1751   1761   
  1752   1762   /*
  1753   1763   ** Rollback a transaction
................................................................................
  1754   1764   */
  1755   1765   void sqliteRollbackTransaction(Parse *pParse){
  1756   1766     sqlite *db;
  1757   1767     Vdbe *v;
  1758   1768   
  1759   1769     if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
  1760   1770     if( pParse->nErr || sqlite_malloc_failed ) return;
  1761         -  if( (db->flags & SQLITE_InTrans)==0 ) return;
         1771  +  if( (db->flags & SQLITE_InTrans)==0 ){
         1772  +    pParse->nErr++;
         1773  +    sqliteSetString(&pParse->zErrMsg,
         1774  +       "cannot rollback - no transaction is active", 0);
         1775  +    return; 
         1776  +  }
  1762   1777     v = sqliteGetVdbe(pParse);
  1763   1778     if( v ){
  1764   1779       sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
  1765   1780     }
  1766   1781     db->flags &= ~SQLITE_InTrans;
  1767   1782     db->onError = OE_Default;
  1768   1783   }

Changes to test/conflict.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests for the conflict resolution extension
    14     14   # to SQLite.
    15     15   #
    16         -# $Id: conflict.test,v 1.13 2002/06/28 12:18:48 drh Exp $
           16  +# $Id: conflict.test,v 1.14 2002/08/18 20:28:07 drh Exp $
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
    21     21   # Create tables for the first group of tests.
    22     22   #
    23     23   do_test conflict-1.0 {
................................................................................
    63     63         DELETE FROM t1;
    64     64         DELETE FROM t2;
    65     65         INSERT INTO t1 VALUES(1,2,3);
    66     66         BEGIN $conf;
    67     67         INSERT INTO t2 VALUES(1); 
    68     68         $cmd INTO t1 VALUES(1,2,4);
    69     69       }]} r1]
    70         -    execsql {COMMIT}
           70  +    catch {execsql {COMMIT}}
    71     71       if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    72     72       set r2 [execsql {SELECT x FROM t2}]
    73     73       list $r0 $r1 $r2
    74     74     } [list $t0 $t1 $t2]
    75     75   }
    76     76   
    77     77   # Create tables for the first group of tests.
................................................................................
   121    121         DELETE FROM t1;
   122    122         DELETE FROM t2;
   123    123         INSERT INTO t1 VALUES(1,2,3);
   124    124         BEGIN $conf;
   125    125         INSERT INTO t2 VALUES(1); 
   126    126         $cmd INTO t1 VALUES(1,2,4);
   127    127       }]} r1]
   128         -    execsql {COMMIT}
          128  +    catch {execsql {COMMIT}}
   129    129       if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
   130    130       set r2 [execsql {SELECT x FROM t2}]
   131    131       list $r0 $r1 $r2
   132    132     } [list $t0 $t1 $t2]
   133    133   }
   134    134   
   135    135   # Create tables for the first group of tests.
................................................................................
   179    179         DELETE FROM t1;
   180    180         DELETE FROM t2;
   181    181         INSERT INTO t1 VALUES(1,2,3);
   182    182         BEGIN $conf;
   183    183         INSERT INTO t2 VALUES(1); 
   184    184         $cmd INTO t1 VALUES(1,2,4);
   185    185       }]} r1]
   186         -    execsql {COMMIT}
          186  +    catch {execsql {COMMIT}}
   187    187       if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
   188    188       set r2 [execsql {SELECT x FROM t2}]
   189    189       list $r0 $r1 $r2
   190    190     } [list $t0 $t1 $t2]
   191    191   }
   192    192   
   193    193   do_test conflict-4.0 {
................................................................................
   234    234         CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
   235    235         DELETE FROM t2;
   236    236         INSERT INTO t1 VALUES(1,2,3);
   237    237         BEGIN $conf2;
   238    238         INSERT INTO t2 VALUES(1); 
   239    239         $cmd INTO t1 VALUES(1,2,4);
   240    240       }]} r1]
   241         -    execsql {COMMIT}
          241  +    catch {execsql {COMMIT}}
   242    242       if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
   243    243       set r2 [execsql {SELECT x FROM t2}]
   244    244       list $r0 $r1 $r2
   245    245     } [list $t0 $t1 $t2]
   246    246   }
   247    247   
   248    248   do_test conflict-5.0 {
................................................................................
   296    296         DROP TABLE t1;
   297    297         CREATE TABLE t1(a,b,c NOT NULL $conf1 DEFAULT 5);
   298    298         DELETE FROM t2;
   299    299         BEGIN $conf2;
   300    300         INSERT INTO t2 VALUES(1); 
   301    301         $cmd INTO t1 VALUES(1,2,NULL);
   302    302       }]} r1]
   303         -    execsql {COMMIT}
          303  +    catch {execsql {COMMIT}}
   304    304       if {!$r0} {set r1 [execsql {SELECT c FROM t1}]}
   305    305       set r2 [execsql {SELECT x FROM t2}]
   306    306       list $r0 $r1 $r2
   307    307     } [list $t0 $t1 $t2]
   308    308   }
   309    309   
   310    310   do_test conflict-6.0 {
................................................................................
   366    366         INSERT INTO t1 SELECT * FROM t2;
   367    367         UPDATE t3 SET x=0;
   368    368         BEGIN $conf2;
   369    369         $cmd t3 SET x=1;
   370    370         $cmd t1 SET b=b*2;
   371    371         $cmd t1 SET a=c+5;
   372    372       }]} r1]
   373         -    execsql {COMMIT}
          373  +    catch {execsql {COMMIT}}
   374    374       if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
   375    375       set r2 [execsql {SELECT x FROM t3}]
   376    376       list $r0 $r1 $r2
   377    377     } [list $t0 $t1 $t2]
   378    378   }
   379    379   
   380    380   # Test to make sure a lot of IGNOREs don't cause a stack overflow
................................................................................
   616    616       BEGIN;
   617    617       UPDATE t3 SET x=x+1;
   618    618       INSERT INTO t2 VALUES(3,3,3,3,1);
   619    619       SELECT * FROM t2;
   620    620     }
   621    621   } {1 {constraint failed}}
   622    622   do_test conflict-9.20 {
   623         -  execsql {COMMIT}
          623  +  catch {execsql {COMMIT}}
   624    624     execsql {SELECT * FROM t3}
   625    625   } {5}
   626    626   do_test conflict-9.21 {
   627    627     catchsql {
   628    628       BEGIN;
   629    629       UPDATE t3 SET x=x+1;
   630    630       UPDATE t2 SET e=e+1 WHERE e=1;
   631    631       SELECT * FROM t2;
   632    632     }
   633    633   } {1 {constraint failed}}
   634    634   do_test conflict-9.22 {
   635         -  execsql {COMMIT}
          635  +  catch {execsql {COMMIT}}
   636    636     execsql {SELECT * FROM t3}
   637    637   } {5}
   638    638   do_test conflict-9.23 {
   639    639     catchsql {
   640    640       INSERT INTO t2 VALUES(3,3,1,3,3);
   641    641       SELECT * FROM t2;
   642    642     }
................................................................................
   652    652       BEGIN;
   653    653       UPDATE t3 SET x=x+1;
   654    654       INSERT INTO t2 VALUES(3,3,1,3,3);
   655    655       SELECT * FROM t2;
   656    656     }
   657    657   } {0 {3 3 1 3 3}}
   658    658   do_test conflict-9.26 {
   659         -  execsql {COMMIT}
          659  +  catch {execsql {COMMIT}}
   660    660     execsql {SELECT * FROM t3}
   661    661   } {6}
   662    662   
   663    663   finish_test

Changes to test/lock.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is database locks.
    13     13   #
    14         -# $Id: lock.test,v 1.15 2002/06/25 13:16:04 drh Exp $
           14  +# $Id: lock.test,v 1.16 2002/08/18 20:28:07 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Create an alternative connection to the database
    21     21   #
................................................................................
   237    237   # Try to start two transactions in a row
   238    238   #
   239    239   do_test lock-3.1 {
   240    240     execsql {BEGIN TRANSACTION}
   241    241     set r [catch {execsql {BEGIN TRANSACTION}} msg]
   242    242     execsql {ROLLBACK}
   243    243     lappend r $msg
   244         -} {0 {}}
          244  +} {1 {cannot start a transaction within a transaction}}
   245    245   integrity_check lock-3.2
   246    246   
   247    247   do_test lock-999.1 {
   248    248     rename db2 {}
   249    249   } {}
   250    250   
   251    251   finish_test

Changes to test/trans.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is database locks.
    13     13   #
    14         -# $Id: trans.test,v 1.15 2002/08/13 00:01:18 drh Exp $
           14  +# $Id: trans.test,v 1.16 2002/08/18 20:28:07 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   
    21     21   # Create several tables to work with.
................................................................................
   169    169   integrity_check trans-3.15
   170    170   
   171    171   do_test trans-4.1 {
   172    172     set v [catch {execsql {
   173    173       COMMIT;
   174    174     } db} msg]
   175    175     lappend v $msg
   176         -} {0 {}}
          176  +} {1 {cannot commit - no transaction is active}}
   177    177   do_test trans-4.2 {
   178    178     set v [catch {execsql {
   179    179       ROLLBACK;
   180    180     } db} msg]
   181    181     lappend v $msg
   182         -} {0 {}}
          182  +} {1 {cannot rollback - no transaction is active}}
   183    183   do_test trans-4.3 {
   184    184     set v [catch {execsql {
   185    185       BEGIN TRANSACTION;
   186    186       SELECT a FROM two ORDER BY a;
   187    187     } db} msg]
   188    188     lappend v $msg
   189    189   } {0 {1 4 5 10}}
................................................................................
   201    201   } {1 {database is locked}}
   202    202   do_test trans-4.6 {
   203    203     set v [catch {execsql {
   204    204       BEGIN TRANSACTION;
   205    205       SELECT a FROM one ORDER BY a;
   206    206     } db} msg]
   207    207     lappend v $msg
   208         -} {0 {1 2 3 4}}
          208  +} {1 {cannot start a transaction within a transaction}}
   209    209   do_test trans-4.7 {
   210    210     set v [catch {execsql {
   211    211       SELECT a FROM two ORDER BY a;
   212    212     } altdb} msg]
   213    213     lappend v $msg
   214    214   } {1 {database is locked}}
   215    215   do_test trans-4.8 {

Changes to test/trigger3.test.

    65     65           INSERT INTO tbl VALUES (5, 5, 6);
    66     66           INSERT INTO tbl VALUES (3, 5, 6);
    67     67       }
    68     68   } {1 {Trigger rollback}}
    69     69   do_test trig-raise-3.2 {
    70     70       execsql {
    71     71   	SELECT * FROM tbl;
    72         -	ROLLBACK;
    73     72       }
    74     73   } {}
    75     74   # IGNORE
    76     75   do_test trig-raise-4.1 {
    77     76       catchsql {
    78     77   	BEGIN;
    79     78           INSERT INTO tbl VALUES (5, 5, 6);