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:
14
manifest
14
manifest
@@ -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
|
||||
|
||||
@@ -1 +1 @@
|
||||
353b1b18253ab71ba38a887e555994f5469b87bd
|
||||
9fd54b0aa73ed74c65f7db53cb666752f13263f9
|
||||
50
src/fkey.c
50
src/fkey.c
@@ -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
|
||||
);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user