Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When a statement causes a ROLLBACK due to an ON CONFLICT clause, other active VMs abort. (CVS 1778) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0fedf74e30026afe2c8caacff3d62cf5 |
User & Date: | drh 2004-06-30 11:14:19.000 |
Context
2004-06-30
| ||
11:28 | Skip bigfile.test on Mac OS X. Darwin does not handle large sparse files efficiently and so this test takes a really long time. (CVS 1779) (check-in: a3c38a6d28 user: drh tags: trunk) | |
11:14 | When a statement causes a ROLLBACK due to an ON CONFLICT clause, other active VMs abort. (CVS 1778) (check-in: 0fedf74e30 user: drh tags: trunk) | |
10:54 | Make sure vacuum.test closes all files. (CVS 1777) (check-in: 4077f9a30b user: danielk1977 tags: trunk) | |
Changes
Changes to src/vdbeInt.h.
︙ | ︙ | |||
338 339 340 341 342 343 344 | int nResColumn; /* Number of columns in one row of the result set */ char **azResColumn; /* Values for one row of result */ int popStack; /* Pop the stack this much on entry to VdbeExec() */ char *zErrMsg; /* Error message written here */ u8 resOnStack; /* True if there are result values on the stack */ u8 explain; /* True if EXPLAIN present on SQL command */ u8 autoCommitOn; /* True if autocommit got turned on by this program */ | < > > | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | int nResColumn; /* Number of columns in one row of the result set */ char **azResColumn; /* Values for one row of result */ int popStack; /* Pop the stack this much on entry to VdbeExec() */ char *zErrMsg; /* Error message written here */ u8 resOnStack; /* True if there are result values on the stack */ u8 explain; /* True if EXPLAIN present on SQL command */ u8 autoCommitOn; /* True if autocommit got turned on by this program */ u8 changeCntOn; /* True to update the change-counter */ u8 aborted; /* True if ROLLBACK in another VM causes an abort */ int nChange; /* Number of db changes made since last reset */ }; /* ** The following are allowed values for Vdbe.magic */ #define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
145 146 147 148 149 150 151 152 153 154 155 156 157 158 | Vdbe *p = (Vdbe*)pStmt; sqlite *db; int rc; if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ db->activeVdbeCnt++; | > > > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | Vdbe *p = (Vdbe*)pStmt; sqlite *db; int rc; if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ return SQLITE_ABORT; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ db->activeVdbeCnt++; |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 | sqlite3BtreeCommit(pBt); } } } return rc; } /* ** This routine checks that the sqlite3.activeVdbeCnt count variable ** matches the number of vdbe's in the list sqlite3.pVdbe that are ** currently active. An assertion fails if the two counts do not match. ** ** This is a no-op if NDEBUG is defined. | > > > > > > > > > > > > > > | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 | sqlite3BtreeCommit(pBt); } } } return rc; } /* ** Find every active VM other than pVdbe and change its status to ** aborted. This happens when on VM causes a rollback. */ static void abortOtherActiveVdbes(Vdbe *pVdbe){ Vdbe *pOther; for(pOther=pVdbe->db->pVdbe; pOther; pOther=pOther->pNext){ if( pOther==pVdbe ) continue; if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue; closeAllCursors(pOther); pOther->aborted = 1; } } /* ** This routine checks that the sqlite3.activeVdbeCnt count variable ** matches the number of vdbe's in the list sqlite3.pVdbe that are ** currently active. An assertion fails if the two counts do not match. ** ** This is a no-op if NDEBUG is defined. |
︙ | ︙ | |||
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ xFunc = sqlite3BtreeCommitStmt; }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 | > | 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 | if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ xFunc = sqlite3BtreeCommitStmt; }else if( p->errorAction==OE_Abort ){ xFunc = sqlite3BtreeRollbackStmt; }else{ xFunc = sqlite3BtreeRollback; db->autoCommit = 1; abortOtherActiveVdbes(p); } } 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 |
︙ | ︙ | |||
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 | sqlite3VdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } } #endif p->magic = VDBE_MAGIC_INIT; return p->rc; } /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ | > | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 | sqlite3VdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } } #endif p->magic = VDBE_MAGIC_INIT; p->aborted = 0; return p->rc; } /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ |
︙ | ︙ |
Added test/rollback.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # 2004 June 30 # # 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 file is verifying that a rollback in one statement # caused by an ON CONFLICT ROLLBACK clause aborts any other pending # statements. # # $Id: rollback.test,v 1.1 2004/06/30 11:14:19 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl db close set DB [sqlite3 db test.db] do_test rollback-1.1 { execsql { CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); INSERT INTO t1 VALUES(4); SELECT * FROM t1; } } {1 2 3 4} do_test rollback-1.2 { execsql { CREATE TABLE t3(a unique on conflict rollback); INSERT INTO t3 SELECT a FROM t1; BEGIN; INSERT INTO t1 SELECT * FROM t1; } } {} do_test rollback-1.3 { set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL] sqlite3_step $STMT } {SQLITE_ROW} # This causes a ROLLBACK, which deletes the table out from underneath the # SELECT statement. # do_test rollback-1.4 { catchsql { INSERT INTO t3 SELECT a FROM t1; } } {1 {column a is not unique}} # Try to continue with the SELECT statement # do_test rollback-1.5 { sqlite3_step $STMT } {SQLITE_ABORT} # Restart the SELECT statement # do_test rollback-1.6 { sqlite3_reset $STMT } {} do_test rollback-1.7 { sqlite3_step $STMT } {SQLITE_ROW} do_test rollback-1.8 { sqlite3_step $STMT } {SQLITE_ROW} do_test rollback-1.9 { sqlite3_finalize $STMT } {SQLITE_OK} finish_test |