From d457271130985a26c10b2b2d2c853fb27cfcdcb7 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 17 Dec 2014 14:38:45 +0000 Subject: [PATCH] Fix some comments in fkey.c. Add tests to fkey8.test. FossilOrigin-Name: 210cb2a6aaf780365064a26c0c99926bd6346e19 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/fkey.c | 28 ++++++++++++++++++++-------- test/fkey8.test | 25 +++++++++++++++++++++++-- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index d7fc48ce45..ec31cc9e8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\sopimizations\sto\sspeed\sup\sFK\sconstraint\sCASCADE\sand\sSET\sNULL\saction\sprocessing. -D 2014-12-16T20:13:30.440 +C Fix\ssome\scomments\sin\sfkey.c.\sAdd\stests\sto\sfkey8.test. +D 2014-12-17T14:38:45.643 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c4f961fa91d0b4fa121946a19f9e5eac2f2f809 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -184,7 +184,7 @@ F src/date.c 93594514aae68de117ca4a2a0d6cc63eddf26744 F src/delete.c 0750b1eb4d96cd3fb2c798599a3a7c85e92f1417 F src/expr.c 00da3072f362b06f39ce4052baa1d4ce2bb36d1c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c eab56799b0339b04c258233b0f462b6e9317f90f +F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12 F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430 F src/global.c 6ded36dda9466fc1c9a3c5492ded81d79bf3977d F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 @@ -504,7 +504,7 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 8a1fde4e7721ae00b05b3178888833726ca2df8d F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 -F test/fkey8.test 2d58cfb990cdd56b2fbac9f4ae54ee53968b3e06 +F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c @@ -1233,10 +1233,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ae43539e62e76676a3daf561b629a1b9b4e2d2c9 -R ea6275c5fe67bcf602365c1ede77fced -T *branch * experimental-fk-actions -T *sym-experimental-fk-actions * -T -sym-trunk * +P 35a20a5f22245c70faa51965951e8cc011defa93 +R c39a2128ba39a16276f2dc7a158fbe28 U dan -Z b6352d484674a0d7b3ae6d8d076cd106 +Z 96b8a9e537739194255aed7e579f65ad diff --git a/manifest.uuid b/manifest.uuid index 859f607ae0..367ac4e6aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35a20a5f22245c70faa51965951e8cc011defa93 \ No newline at end of file +210cb2a6aaf780365064a26c0c99926bd6346e19 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 7ea48f5058..fa148ba6a3 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -629,9 +629,8 @@ static void fkScanChildren( sqlite3ResolveExprNames(&sNameContext, pWhere); /* Create VDBE to loop through the entries in pSrc that match the WHERE - ** clause. If the constraint is not deferred, throw an exception for - ** each row found. Otherwise, for deferred constraints, increment the - ** deferred constraint counter by nIncr for each row selected. */ + ** clause. For each row found, increment either the deferred or immediate + ** foreign key constraint counter. */ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); if( pWInfo ){ @@ -963,9 +962,9 @@ void sqlite3FkCheck( ** ** If this operation is being performed as part of a trigger program ** that is actually a "SET NULL" action belonging to this very - ** foreign key, then omit this scan altogether. As the child keys + ** foreign key, then omit this scan altogether. As all child key ** values are guaranteed to be NULL, it is not possible for adding - ** this row to cause an FK violation. */ + ** this row to cause an FK violation. */ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore); } @@ -1015,9 +1014,22 @@ void sqlite3FkCheck( int eAction = pFKey->aAction[aChange!=0]; fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); /* If this is a deferred FK constraint, or a CASCADE or SET NULL - ** action applies, do not set the may-abort flag on this statement. - ** The flag may be set on this statement for some other reason, but - ** not as a result of this FK constraint. */ + ** action applies, then any foreign key violations caused by + ** removing the parent key will be rectified by the action trigger. + ** So do not set the "may-abort" flag in this case. + ** + ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the + ** may-abort flag will eventually be set on this statement anyway + ** (when this function is called as part of processing the UPDATE + ** within the action trigger). + ** + ** Note 2: At first glance it may seem like SQLite could simply omit + ** all OP_FkCounter related scans when either CASCADE or SET NULL + ** applies. The trouble starts if the CASCADE or SET NULL action + ** trigger causes other triggers or action rules attached to the + ** child table to fire. In these cases the fk constraint counters + ** might be set incorrectly if any OP_FkCounter related scans are + ** omitted. */ if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){ sqlite3MayAbort(pParse); } diff --git a/test/fkey8.test b/test/fkey8.test index e9f3093930..60bb8e4640 100644 --- a/test/fkey8.test +++ b/test/fkey8.test @@ -67,6 +67,28 @@ foreach {tn use_stmt sql schema} { CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE, c PRIMARY KEY); CREATE TABLE cc1(d REFERENCES c1 ON DELETE SET NULL); } + 5.3 1 "DELETE FROM p1" { + CREATE TABLE p1(a PRIMARY KEY); + CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE, c PRIMARY KEY); + CREATE TABLE cc1(d REFERENCES c1 ON DELETE SET DEFAULT); + } + + 6.1 1 "UPDATE p1 SET a = ?" { + CREATE TABLE p1(a PRIMARY KEY); + CREATE TABLE c1(b REFERENCES p1 ON UPDATE SET NULL, c); + } + 6.2 0 "UPDATE OR IGNORE p1 SET a = ?" { + CREATE TABLE p1(a PRIMARY KEY); + CREATE TABLE c1(b REFERENCES p1 ON UPDATE SET NULL, c); + } + 6.3 1 "UPDATE OR IGNORE p1 SET a = ?" { + CREATE TABLE p1(a PRIMARY KEY); + CREATE TABLE c1(b REFERENCES p1 ON UPDATE CASCADE, c); + } + 6.4 1 "UPDATE OR IGNORE p1 SET a = ?" { + CREATE TABLE p1(a PRIMARY KEY); + CREATE TABLE c1(b NOT NULL REFERENCES p1 ON UPDATE SET NULL, c); + } } { drop_all_tables @@ -80,6 +102,5 @@ foreach {tn use_stmt sql schema} { } - - finish_test + -- 2.47.2