1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-01-06 08:01:16 +03:00

Fix comments in fkey2.c to reflect the immediate-constraint-counter approach.

FossilOrigin-Name: 9fd54b0aa73ed74c65f7db53cb666752f13263f9
This commit is contained in:
dan
2009-09-25 12:00:01 +00:00
parent 53c3fa8dbe
commit bd74783270
4 changed files with 66 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
C Prevent\sALTER\sTABLE\sfrom\sbeing\sused\sto\sadd\sa\scolumn\swith\sa\sREFERENCES\sclause\sand\sa\snon-NULL\sdefault\svalue\swhile\sforeign\skey\ssupport\sis\senabled.
D 2009-09-25T11:26:55
C Fix\scomments\sin\sfkey2.c\sto\sreflect\sthe\simmediate-constraint-counter\sapproach.
D 2009-09-25T12:00:02
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -116,7 +116,7 @@ F src/date.c 657ff12ca0f1195b531561afacbb38b772d16638
F src/delete.c 2a3d6fc0861b2f8dbd9feb7847b390267b281c60
F src/expr.c c7f3f718bd5c392344ec8694a41c1824f30cf375
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/fkey.c 5ec139b6d22a981a777fb195d9311068f5a8c75b
F src/fkey.c 8719d0fa09f8f08d5b21abf54a59cbcb88172b1b
F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
@@ -330,7 +330,7 @@ F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
F test/fkey2.test ad58088fbc09231f125b6c7e9594720aa1374019
F test/fkey2.test 8f857439feef71b11a13821aa407399e3ed9f494
F test/fkey3.test 2183cac9075f3aae4875106eb9255bb73618444e
F test/fkey_malloc.test da912d000bb6ceb1cd11b655de1989762fa71ceb
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
@@ -755,7 +755,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 76e8e74b49be4c80b9fb20d52e9b39db8001362e
R 136d37129ec61260ba7a30de652f5973
P 353b1b18253ab71ba38a887e555994f5469b87bd
R 686fb8f7dc051b5c786ec23c8c348ab4
U dan
Z 5dd61108ad33d708be4c046f1054dc1d
Z 007854d1d118a1cdcf5b42c76aa6bc04

View File

@@ -1 +1 @@
353b1b18253ab71ba38a887e555994f5469b87bd
9fd54b0aa73ed74c65f7db53cb666752f13263f9

View File

@@ -83,6 +83,16 @@
** is thrown, even if the FK constraint would be satisfied after the new
** row is inserted.
**
** Immediate constraints are usually handled similarly. The only difference
** is that the counter used is stored as part of each individual statement
** object (struct Vdbe). If, after the statement has run, its immediate
** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
** and the statement transaction is rolled back. An exception is an INSERT
** statement that inserts a single row only (no triggers). In this case,
** instead of using a counter, an exception is thrown immediately if the
** INSERT violates a foreign key constraint. This is necessary as such
** an INSERT does not open a statement transaction.
**
** TODO: How should dropping a table be handled? How should renaming a
** table be handled?
**
@@ -259,10 +269,9 @@ static int locateFkeyIndex(
}
/*
** This function is called when a row is inserted into the child table of
** foreign key constraint pFKey and, if pFKey is deferred, when a row is
** deleted from the child table of pFKey. If an SQL UPDATE is executed on
** the child table of pFKey, this function is invoked twice for each row
** This function is called when a row is inserted into or deleted from the
** child table of foreign key constraint pFKey. If an SQL UPDATE is executed
** on the child table of pFKey, this function is invoked twice for each row
** affected - once to "delete" the old row, and then again to "insert" the
** new row.
**
@@ -274,15 +283,16 @@ static int locateFkeyIndex(
**
** Operation | FK type | Action taken
** --------------------------------------------------------------------------
** INSERT immediate Throw a "foreign key constraint failed" exception.
** INSERT immediate Increment the "immediate constraint counter".
**
** DELETE immediate Decrement the "immediate constraint counter".
**
** INSERT deferred Increment the "deferred constraint counter".
**
** DELETE deferred Decrement the "deferred constraint counter".
**
** This function is never called for a delete on the child table of an
** immediate foreign key constraint. These operations are identified in
** the comment at the top of this file (fkey.c) as "I.1" and "D.1".
** These operations are identified in the comment at the top of this file
** (fkey.c) as "I.1" and "D.1".
*/
static void fkLookupParent(
Parse *pParse, /* Parse context */
@@ -378,7 +388,11 @@ static void fkLookupParent(
**
** Operation | FK type | Action taken
** --------------------------------------------------------------------------
** DELETE immediate Throw a "foreign key constraint failed" exception.
** DELETE immediate Increment the "immediate constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
** throw a "foreign key constraint failed" exception.
**
** INSERT immediate Decrement the "immediate constraint counter".
**
** DELETE deferred Increment the "deferred constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
@@ -386,9 +400,8 @@ static void fkLookupParent(
**
** INSERT deferred Decrement the "deferred constraint counter".
**
** This function is never called for an INSERT operation on the parent table
** of an immediate foreign key constraint. These operations are identified in
** the comment at the top of this file (fkey.c) as "I.2" and "D.2".
** These operations are identified in the comment at the top of this file
** (fkey.c) as "I.2" and "D.2".
*/
static void fkScanChildren(
Parse *pParse, /* Parse context */
@@ -405,6 +418,14 @@ static void fkScanChildren(
NameContext sNameContext; /* Context used to resolve WHERE clause */
WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */
/* Create an Expr object representing an SQL expression like:
**
** <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
**
** The collation sequence used for the comparison should be that of
** the parent key columns. The affinity of the parent key column should
** be applied to each child key value before the comparison takes place.
*/
for(i=0; i<pFKey->nCol; i++){
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
@@ -414,6 +435,8 @@ static void fkScanChildren(
pLeft = sqlite3Expr(db, TK_REGISTER, 0);
if( pLeft ){
/* Set the collation sequence and affinity of the LHS of each TK_EQ
** expression to the parent key column defaults. */
if( pIdx ){
int iCol = pIdx->aiColumn[i];
Column *pCol = &pIdx->pTable->aCol[iCol];
@@ -445,7 +468,8 @@ static void fkScanChildren(
** deferred constraint counter by nIncr for each row selected. */
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0);
if( nIncr==0 ){
/* A RESTRICT Action. */
/* Special case: A RESTRICT Action. Throw an error immediately if one
** of these is encountered. */
sqlite3HaltConstraint(
pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
);

View File

@@ -188,7 +188,7 @@ do_test fkey2-1.5.2 {
# Use a collation sequence on the parent key.
drop_all_tables
do_test fkey2-1.5.1 {
do_test fkey2-1.6.1 {
execsql {
CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
@@ -198,6 +198,26 @@ do_test fkey2-1.5.1 {
catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}}
# Use the parent key collation even if it is default and the child key
# has an explicit value.
drop_all_tables
do_test fkey2-1.6.2 {
execsql {
CREATE TABLE i(i TEXT PRIMARY KEY); -- Colseq is "BINARY"
CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));
INSERT INTO i VALUES('SQLite');
}
catchsql { INSERT INTO j VALUES('sqlite') }
} {1 {foreign key constraint failed}}
do_test fkey2-1.6.3 {
execsql {
INSERT INTO i VALUES('sqlite');
INSERT INTO j VALUES('sqlite');
DELETE FROM i WHERE i = 'SQLite';
}
catchsql { DELETE FROM i WHERE i = 'sqlite' }
} {1 {foreign key constraint failed}}
#-------------------------------------------------------------------------
# This section (test cases fkey2-2.*) contains tests to check that the
# deferred foreign key constraint logic works.