mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-06 15:49:35 +03:00
Make sure a transaction is available for rollback whenever a REDUCE conflict
resolution occurs and there is the possibility to ABORT. Ticket [4a03edc4c8c] FossilOrigin-Name: f0c56fa90dc95aff6fe6764b5ab75a90199247b0
This commit is contained in:
31
manifest
31
manifest
@@ -1,5 +1,8 @@
|
||||
C More\sfkey\stests.
|
||||
D 2009-09-23T18:49:41
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
C Make\ssure\sa\stransaction\sis\savailable\sfor\srollback\swhenever\sa\sREDUCE\sconflict\nresolution\soccurs\sand\sthere\sis\sthe\spossibility\sto\sABORT.\nTicket\s[4a03edc4c8c]
|
||||
D 2009-09-24T00:09:58
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@@ -109,7 +112,7 @@ F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
||||
F src/btree.c 9c425425784c5d569bc0309c22251698ba906451
|
||||
F src/btree.h 577448a890c2ab9b21e6ab74f073526184bceebe
|
||||
F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705
|
||||
F src/build.c a6bd2dd725847bb4870f1b3f87d64730773c92bb
|
||||
F src/build.c c6c8d4ce8c0a464bb25d0c3bfdb27834ad16d902
|
||||
F src/callback.c 10d237171472865f58fb07d515737238c9e06688
|
||||
F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0
|
||||
F src/date.c 657ff12ca0f1195b531561afacbb38b772d16638
|
||||
@@ -122,7 +125,7 @@ F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
|
||||
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
|
||||
F src/hash.h 35b216c13343d0b4f87d9f21969ac55ad72174e1
|
||||
F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb
|
||||
F src/insert.c e4ca9ed8db8ae84b9c020a3d548fb8d6a355e625
|
||||
F src/insert.c 3ff8f07ad36f5b3b2affb8e3fa99c24772b08fc4
|
||||
F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0
|
||||
F src/legacy.c 303b4ffcf1ae652fcf5ef635846c563c254564f6
|
||||
F src/lempar.c 0c4d1ab0a5ef2b0381eb81a732c54f68f27a574d
|
||||
@@ -164,7 +167,7 @@ F src/select.c 1d0a13137532321b4364f964e46f057d271691e3
|
||||
F src/shell.c d6e64471aafb81f355262533393169a70529847a
|
||||
F src/sqlite.h.in 5af8181f815831a8672c3834c60e6b4418448bcc
|
||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||
F src/sqliteInt.h 98ad725d6915a1f1c618ff317e7b09d79efffe57
|
||||
F src/sqliteInt.h 6b1fef0ef9aa6bf22e846d96cd3927cf7f55057d
|
||||
F src/sqliteLimit.h 504a3161886d2938cbd163054ad620b8356df758
|
||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
||||
@@ -210,7 +213,7 @@ F src/vdbe.c a5da14fe8d89f9ad2cd4911a9d7df79c74a6b84c
|
||||
F src/vdbe.h 7d5075e3fa4e5587a9be8d5e503857c825490cef
|
||||
F src/vdbeInt.h 7afb76c0296f9a2310e565803fa66798ef47e9d5
|
||||
F src/vdbeapi.c 524d79eb17bbcbe31c37c908b8e01edc5c684a90
|
||||
F src/vdbeaux.c 32d77382469c20aa5a971a8794deb1eafa8d5cb6
|
||||
F src/vdbeaux.c c36bb6674d43c8a1f553648c15fcd078c7357262
|
||||
F src/vdbeblob.c 3ba0f7ba1b3afce2d37a18e4f437992d430f0eae
|
||||
F src/vdbemem.c 0ff2b209fccade3ff6709286057b82ed7f6c1e70
|
||||
F src/vtab.c 3e54fe39374e5feb8b174de32a90e7a21966025d
|
||||
@@ -586,6 +589,7 @@ F test/thread_common.tcl b65e6b1d1d90dc885e10ad080896c6c56eef0819
|
||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||
F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
|
||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||
F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e
|
||||
F test/tkt1435.test f8c52c41de6e5ca02f1845f3a46e18e25cadac00
|
||||
F test/tkt1443.test bacc311da5c96a227bf8c167e77a30c99f8e8368
|
||||
F test/tkt1444.test a9d72f9e942708bd82dde6c707da61c489e213e9
|
||||
@@ -754,7 +758,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P e0a48d53110130de75602603f524539e421a9dba
|
||||
R ff71547a957706a79706e81913a173d1
|
||||
U shane
|
||||
Z 95291c1566a042bd72f53d01f2664d90
|
||||
P 2d544bd53d0fb9633aca40841529aec8e7df61f8
|
||||
R 3842168b1b7758c2297668effb3e745f
|
||||
U drh
|
||||
Z 3a3c7d1ce176416e380730f2a219861d
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFKurjZoxKgR168RlERArl8AJ0WnGHXqijj8D2EisZs22gnQG5PdQCffs5H
|
||||
7Kh3yhpsQRwB0Gtl6moTZKc=
|
||||
=J9+X
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
@@ -1 +1 @@
|
||||
2d544bd53d0fb9633aca40841529aec8e7df61f8
|
||||
f0c56fa90dc95aff6fe6764b5ab75a90199247b0
|
||||
28
src/build.c
28
src/build.c
@@ -3494,8 +3494,32 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the "may throw abort exception" flag for the statement currently
|
||||
** being coded.
|
||||
** Indicate that the statement currently under construction might write
|
||||
** more than one entry (example: deleting one row then inserting another,
|
||||
** inserting multiple rows in a table, or inserting a row and index entries.)
|
||||
** If an abort occurs after some of these writes have completed, then it will
|
||||
** be necessary to undo the completed writes.
|
||||
*/
|
||||
void sqlite3MultiWrite(Parse *pParse){
|
||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||
pToplevel->isMultiWrite = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** The code generator calls this routine if is discovers that it is
|
||||
** possible to abort a statement prior to completion. In order to
|
||||
** perform this abort without corrupting the database, we need to make
|
||||
** sure that the statement is protected by a statement transaction.
|
||||
**
|
||||
** Technically, we only need to set the mayAbort flag if the
|
||||
** isMultiWrite flag was previously set. There is a time dependency
|
||||
** such that the abort must occur after the multiwrite. This makes
|
||||
** some statements involving the REPLACE conflict resolution algorithm
|
||||
** go a little faster. But taking advantage of this time dependency
|
||||
** makes it more difficult to prove that the code is correct (in
|
||||
** particular, it prevents us from writing an effective
|
||||
** implementation of sqlite3AssertMayAbort()) and so we have chosen
|
||||
** to take the safe route and skip the optimization.
|
||||
*/
|
||||
void sqlite3MayAbort(Parse *pParse){
|
||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||
|
||||
@@ -1278,6 +1278,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
}else{
|
||||
sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
|
||||
}
|
||||
sqlite3MultiWrite(pParse);
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
@@ -1385,6 +1386,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
sqlite3GenerateRowDelete(
|
||||
pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
|
||||
);
|
||||
sqlite3MultiWrite(pParse);
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2663,7 +2663,8 @@ void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
|
||||
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
|
||||
int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
|
||||
void sqlite3BeginWriteOperation(Parse*, int, int);
|
||||
void sqlite3MayAbort(Parse *);
|
||||
void sqlite3MultiWrite(Parse*);
|
||||
void sqlite3MayAbort(Parse*);
|
||||
void sqlite3HaltConstraint(Parse*, int, char*, int);
|
||||
Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
|
||||
ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
|
||||
|
||||
@@ -240,7 +240,7 @@ void sqlite3VdbeResolveLabel(Vdbe *p, int x){
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
|
||||
|
||||
/*
|
||||
** The following type and function are used to iterate through all opcodes
|
||||
@@ -312,7 +312,7 @@ static Op *opIterNext(VdbeOpIter *p){
|
||||
|
||||
/*
|
||||
** Check if the program stored in the VM associated with pParse may
|
||||
** throw an ABORT exception (causing the statement, but not transaction
|
||||
** throw an ABORT exception (causing the statement, but not entire transaction
|
||||
** to be rolled back). This condition is true if the main program or any
|
||||
** sub-programs contains any of the following:
|
||||
**
|
||||
@@ -359,7 +359,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
** from failing. */
|
||||
return ( v->db->mallocFailed || hasAbort==mayAbort );
|
||||
}
|
||||
#endif
|
||||
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
|
||||
|
||||
/*
|
||||
** Loop through the program looking for P2 values that are negative
|
||||
|
||||
46
test/tkt-4a03edc4c8.test
Normal file
46
test/tkt-4a03edc4c8.test
Normal file
@@ -0,0 +1,46 @@
|
||||
# 2009 September 23
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This file implements tests to verify that
|
||||
# ticket [4a03edc4c8c028c93e9269f64fc5e97f632c1166] has been fixed.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test tkt-4a03ed-1.1 {
|
||||
db eval {
|
||||
CREATE TABLE t1(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b UNIQUE ON CONFLICT FAIL
|
||||
);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2);
|
||||
}
|
||||
catchsql {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
COMMIT;
|
||||
}
|
||||
} {1 {column b is not unique}}
|
||||
do_test tkt-4a03ed-1.2 {
|
||||
db eval {
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
do_test tkt-4a03ed-1.3 {
|
||||
db eval {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
}
|
||||
} {1 1 2 2}
|
||||
|
||||
finish_test
|
||||
Reference in New Issue
Block a user