diff options
author | drh <drh@noemail.net> | 2011-02-04 05:47:51 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2011-02-04 05:47:51 +0000 |
commit | 9ab724f196854bc9d4f2eca00b9fbe4c6726174a (patch) | |
tree | 109de8cbbd5821f82d3a42cd14bb244fee3d3c22 /src | |
parent | 0097eb39422fc18f8e43eef119a43272137d368d (diff) | |
parent | 19611b1a88c97e00600025b2087202808a037c85 (diff) | |
download | sqlite-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.c | 25 |
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); } |