Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem with FK constraints that implicitly map to a composite primary key. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e0a48d53110130de75602603f524539e |
User & Date: | dan 2009-09-23 18:07:22.000 |
Context
2009-09-23
| ||
18:49 | More fkey tests. (check-in: 2d544bd53d user: shane tags: trunk) | |
18:07 | Fix a problem with FK constraints that implicitly map to a composite primary key. (check-in: e0a48d5311 user: dan tags: trunk) | |
17:31 | Fix a problem in the fkey_malloc.test script. (check-in: 0ce1efa460 user: dan tags: trunk) | |
Changes
Changes to src/fkey.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | #ifndef SQLITE_OMIT_TRIGGER /* ** Deferred and Immediate FKs ** -------------------------- ** ** Foreign keys in SQLite come in two flavours: deferred and immediate. | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #ifndef SQLITE_OMIT_TRIGGER /* ** Deferred and Immediate FKs ** -------------------------- ** ** Foreign keys in SQLite come in two flavours: deferred and immediate. ** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT ** is returned and the current statement transaction rolled back. If a ** deferred foreign key constraint is violated, no action is taken ** immediately. However if the application attempts to commit the ** transaction before fixing the constraint violation, the attempt fails. ** ** Deferred constraints are implemented using a simple counter associated ** with the database handle. The counter is set to zero each time a ** database transaction is opened. Each time a statement is executed |
︙ | ︙ | |||
45 46 47 48 49 50 51 | ** ** Despite these problems, this approach is adopted as it seems simpler ** than the alternatives. ** ** INSERT operations: ** ** I.1) For each FK for which the table is the child table, search | | < | | | | < | 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 | ** ** Despite these problems, this approach is adopted as it seems simpler ** than the alternatives. ** ** INSERT operations: ** ** I.1) For each FK for which the table is the child table, search ** the parent table for a match. If none is found increment the ** constraint counter. ** ** I.2) For each FK for which the table is the parent table, ** search the child table for rows that correspond to the new ** row in the parent table. Decrement the counter for each row ** found (as the constraint is now satisfied). ** ** DELETE operations: ** ** D.1) For each FK for which the table is the child table, ** search the parent table for a row that corresponds to the ** deleted row in the child table. If such a row is not found, ** decrement the counter. ** ** D.2) For each FK for which the table is the parent table, search ** the child table for rows that correspond to the deleted row ** in the parent table. For each found increment the counter. ** ** UPDATE operations: ** ** An UPDATE command requires that all 4 steps above are taken, but only ** for FK constraints for which the affected columns are actually ** modified (values must be compared at runtime). ** |
︙ | ︙ | |||
220 221 222 223 224 225 226 | ** column of pFKey, then this index is a winner. */ if( zKey==0 ){ /* If zKey is NULL, then this foreign key is implicitly mapped to ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be ** identified by the test (Index.autoIndex==2). */ if( pIdx->autoIndex==2 ){ | | > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | ** column of pFKey, then this index is a winner. */ if( zKey==0 ){ /* If zKey is NULL, then this foreign key is implicitly mapped to ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be ** identified by the test (Index.autoIndex==2). */ if( pIdx->autoIndex==2 ){ if( aiCol ){ int i; for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom; } break; } }else{ /* If zKey is non-NULL, then this foreign key was declared to ** map to an explicit list of columns in table pParent. Check if this ** index matches those columns. */ int i, j; |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
386 387 388 389 390 391 392 | void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int sqlite3VdbeReleaseBuffers(Vdbe *p); #endif #ifndef SQLITE_OMIT_FOREIGN_KEY | | | | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int sqlite3VdbeReleaseBuffers(Vdbe *p); #endif #ifndef SQLITE_OMIT_FOREIGN_KEY int sqlite3VdbeCheckFk(Vdbe *, int); #else # define sqlite3VdbeCheckFk(p,i) 0 #endif #ifndef SQLITE_OMIT_SHARED_CACHE void sqlite3VdbeMutexArrayEnter(Vdbe *p); #else # define sqlite3VdbeMutexArrayEnter(p) #endif |
︙ | ︙ |