]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix comments in fkey2.c to reflect the immediate-constraint-counter approach.
authordan <dan@noemail.net>
Fri, 25 Sep 2009 12:00:01 +0000 (12:00 +0000)
committerdan <dan@noemail.net>
Fri, 25 Sep 2009 12:00:01 +0000 (12:00 +0000)
FossilOrigin-Name: 9fd54b0aa73ed74c65f7db53cb666752f13263f9

manifest
manifest.uuid
src/fkey.c
test/fkey2.test

index 8f9f8b76a5df854392ed5dbf9ce6058a4eb0ef25..f4a6ddd82cede0e82a960b2f2e29fea90210c3d2 100644 (file)
--- a/manifest
+++ b/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
index 5fb63b8f31ebe24c2b14f924850fde65f7aedbf8..f4a31f8d7029e8e3ab33104608a103e1a6567bed 100644 (file)
@@ -1 +1 @@
-353b1b18253ab71ba38a887e555994f5469b87bd
\ No newline at end of file
+9fd54b0aa73ed74c65f7db53cb666752f13263f9
\ No newline at end of file
index f81c6a8e238ae2331d6be288c23ace869483bca0..acac588cf445b76338413ee105e79e699e49b395 100644 (file)
 ** 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
     );
index f0d0bed3c885e4c9675a19a9398e19d235ad49ee..0b4402c7d5a74a47bb087c1194640cd0a9546d79 100644 (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.