Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2f94d4623f9aae1b5bc7041bd85f4e3a |
User & Date: | drh 2011-02-04 05:47:51.496 |
Context
2011-02-04
| ||
06:36 | Merge the stat2 query planner enhancements into the trunk. (check-in: 499edcbc8a user: drh tags: trunk) | |
05:47 | 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. (check-in: 2f94d4623f user: drh tags: trunk) | |
00:51 | Fix the ATTACH command so that the filename argument can be any expression and so that if authorizer callback gets a NULL pointer for the filename if the filename argument is anything other than a string literal. Ticket [9013e13dba5b58c7] (check-in: e64e1453a9 user: drh tags: trunk) | |
2011-01-24
| ||
16:00 | Ensure that if a deferred FK constraint is violated by a statement that creates its own implicit transaction, the statement is not an "active-write" after sqlite3_step() returns. (Closed-Leaf check-in: 8063197ef1 user: dan tags: deferred-fk-quirk) | |
Changes
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | ** above has occurred. */ if( !sqlite3VtabInSync(db) && db->autoCommit && db->writeVdbeCnt==(p->readOnly==0) ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ | | > > | | | > > | | | | | > | | 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 | ** above has occurred. */ if( !sqlite3VtabInSync(db) && db->autoCommit && db->writeVdbeCnt==(p->readOnly==0) ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ 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); } if( rc==SQLITE_BUSY && p->readOnly ){ sqlite3BtreeMutexArrayLeave(&p->aMutex); return SQLITE_BUSY; }else if( rc!=SQLITE_OK ){ p->rc = rc; sqlite3RollbackAll(db); }else{ db->nDeferredCons = 0; |
︙ | ︙ | |||
2212 2213 2214 2215 2216 2217 2218 | ** to invoke any required unlock-notify callbacks. */ if( db->autoCommit ){ sqlite3ConnectionUnlocked(db); } assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 ); | | | 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 | ** to invoke any required unlock-notify callbacks. */ if( db->autoCommit ){ sqlite3ConnectionUnlocked(db); } assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 ); return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); } /* ** Each VDBE holds the result of the most recent sqlite3_step() call ** in p->rc. This routine sets that result back to SQLITE_OK. */ |
︙ | ︙ |
Added test/fkey4.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 | # 2011 Feb 04 # # 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 test deferred foreign key constraint processing to make # sure that when a statement not within BEGIN...END fails a constraint, # that statement doesn't hold the transaction open thus allowing # a subsequent statement to fail a deferred constraint with impunity. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!foreignkey||!trigger} { finish_test return } # Create a table and some data to work with. # do_test fkey4-1.1 { execsql { PRAGMA foreign_keys = ON; CREATE TABLE t1(a PRIMARY KEY, b); CREATE TABLE t2(c REFERENCES t1 DEFERRABLE INITIALLY DEFERRED, d); INSERT INTO t1 VALUES(1,2); INSERT INTO t2 VALUES(1,3); } } {} do_test fkey4-1.2 { set ::DB [sqlite3_connection_pointer db] set ::SQL {INSERT INTO t2 VALUES(2,4)} set ::STMT1 [sqlite3_prepare_v2 $::DB $::SQL -1 TAIL] sqlite3_step $::STMT1 } {SQLITE_CONSTRAINT} do_test fkey4-1.3 { set ::STMT2 [sqlite3_prepare_v2 $::DB $::SQL -1 TAIL] sqlite3_step $::STMT2 } {SQLITE_CONSTRAINT} do_test fkey4-1.4 { db eval {SELECT * FROM t2} } {1 3} sqlite3_finalize $::STMT1 sqlite3_finalize $::STMT2 finish_test |