aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2011-02-04 05:47:51 +0000
committerdrh <drh@noemail.net>2011-02-04 05:47:51 +0000
commit9ab724f196854bc9d4f2eca00b9fbe4c6726174a (patch)
tree109de8cbbd5821f82d3a42cd14bb244fee3d3c22 /src
parent0097eb39422fc18f8e43eef119a43272137d368d (diff)
parent19611b1a88c97e00600025b2087202808a037c85 (diff)
downloadsqlite-9ab724f196854bc9d4f2eca00b9fbe4c6726174a.tar.gz
sqlite-9ab724f196854bc9d4f2eca00b9fbe4c6726174a.zip
If a deferred foreign key constraint fails on a statement that is not part
of a larger transation, make sure that the statement fully ends so that subsequent invocations of the same statement will not pass the constraint because they think the transaction is not closed. This is a merge of the deferred-fk-quirk branch together with a test case. FossilOrigin-Name: 2f94d4623f9aae1b5bc7041bd85f4e3a7462c60e
Diffstat (limited to 'src')
-rw-r--r--src/vdbeaux.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index de69e544e..7567df91a 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -2108,16 +2108,21 @@ int sqlite3VdbeHalt(Vdbe *p){
&& db->writeVdbeCnt==(p->readOnly==0)
){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
- if( sqlite3VdbeCheckFk(p, 1) ){
- sqlite3BtreeMutexArrayLeave(&p->aMutex);
- return SQLITE_ERROR;
+ rc = sqlite3VdbeCheckFk(p, 1);
+ if( rc!=SQLITE_OK ){
+ if( p->readOnly ){
+ sqlite3BtreeMutexArrayLeave(&p->aMutex);
+ return SQLITE_ERROR;
+ }
+ rc = SQLITE_CONSTRAINT;
+ }else{
+ /* The auto-commit flag is true, the vdbe program was successful
+ ** or hit an 'OR FAIL' constraint and there are no deferred foreign
+ ** key constraints to hold up the transaction. This means a commit
+ ** is required. */
+ rc = vdbeCommit(db, p);
}
- /* The auto-commit flag is true, the vdbe program was successful
- ** or hit an 'OR FAIL' constraint and there are no deferred foreign
- ** key constraints to hold up the transaction. This means a commit
- ** is required. */
- rc = vdbeCommit(db, p);
- if( rc==SQLITE_BUSY ){
+ if( rc==SQLITE_BUSY && p->readOnly ){
sqlite3BtreeMutexArrayLeave(&p->aMutex);
return SQLITE_BUSY;
}else if( rc!=SQLITE_OK ){
@@ -2216,7 +2221,7 @@ int sqlite3VdbeHalt(Vdbe *p){
}
assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
- return SQLITE_OK;
+ return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}