]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid updating unaffected indexes on a table as part of an UPDATE that requires fkey-optimization
authordan <dan@noemail.net>
Tue, 11 Apr 2017 19:58:55 +0000 (19:58 +0000)
committerdan <dan@noemail.net>
Tue, 11 Apr 2017 19:58:55 +0000 (19:58 +0000)
foreign key processing in some cases.

FossilOrigin-Name: 477bea9ed0dd0fa69896bfd16d9b1d22170cbab784e3279ce65c29c47e032f34

manifest
manifest.uuid
src/fkey.c
src/update.c

index e085e3f18cf7a9ecd6347f0e7881c7a5542ee386..103f117e15e13051ac7c1591e3437a0a21d9a545 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Limit\sthe\sdepth\sof\srecursion\sfor\svalid\sJSON\sin\sthe\sJSON1\sextension\sin\sorder\nto\savoid\susing\sexcess\sstack\sspace\sin\sthe\srecursive\sdescent\sparser.\nFix\sfor\sticket\s[981329adeef51011052667a9].
-D 2017-04-11T18:55:05.542
+C Avoid\supdating\sunaffected\sindexes\son\sa\stable\sas\spart\sof\san\sUPDATE\sthat\srequires\nforeign\skey\sprocessing\sin\ssome\scases.
+D 2017-04-11T19:58:55.816
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
@@ -356,7 +356,7 @@ F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
 F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
 F src/expr.c f6572c7690fa619e85b1192b683ccc30cd123363415963c061ada3770b18f6a7
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
-F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
+F src/fkey.c db65492ae549c3b548c9ef1f279ce1684f1c473b116e1c56a90878cd5dcf968d
 F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174
 F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955
 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
@@ -464,7 +464,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5
 F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8
 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
-F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
+F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
 F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
@@ -1571,7 +1571,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 76cd611d41465fcec61c21520d55172cb236530f38386b7d4a5544ba87de2353
-R 4121191f9cbabfb85c1e92872e6e98a5
-U drh
-Z 8a8f0ee4e24e0270c8727f53d830c8c6
+P 1f68c184596912d742b50b1ca38252a9e783aacf121619a27b17a7ae9f6df041
+R 64d829e1406f8fce120ec976a7526a63
+T *branch * fkey-optimization
+T *sym-fkey-optimization *
+T -sym-trunk *
+U dan
+Z 11630915b607d65a1bf3ba20257e205b
index fa40f168fae14a0146ec25a58146b0bf152afe78..b8b2d6e02b5decb62c20c9377a5fa7139100df1d 100644 (file)
@@ -1 +1 @@
-1f68c184596912d742b50b1ca38252a9e783aacf121619a27b17a7ae9f6df041
\ No newline at end of file
+477bea9ed0dd0fa69896bfd16d9b1d22170cbab784e3279ce65c29c47e032f34
\ No newline at end of file
index cb78764f513a8fe0c29fdd2484783e2a487e99b4..f91a6de547088afc3504ae6cacf5e1549c68dcae 100644 (file)
@@ -1087,8 +1087,16 @@ u32 sqlite3FkOldmask(
 ** UPDATE statement modifies the rowid fields of the table.
 **
 ** If any foreign key processing will be required, this function returns
-** true. If there is no foreign key related processing, this function 
-** returns false.
+** non-zero. If there is no foreign key related processing, this function 
+** returns zero.
+**
+** For an UPDATE, this function returns 2 if:
+**
+**   * There are any FKs for which pTab is the child and the parent table, or
+**   * the UPDATE modifies one or more parent keys for which the action is
+**     not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
+**
+** Or, assuming some other foreign key processing is required, 1.
 */
 int sqlite3FkRequired(
   Parse *pParse,                  /* Parse context */
@@ -1096,12 +1104,13 @@ int sqlite3FkRequired(
   int *aChange,                   /* Non-NULL for UPDATE operations */
   int chngRowid                   /* True for UPDATE that affects rowid */
 ){
+  int eRet = 0;
   if( pParse->db->flags&SQLITE_ForeignKeys ){
     if( !aChange ){
       /* A DELETE operation. Foreign key processing is required if the 
       ** table in question is either the child or parent table for any 
       ** foreign key constraint.  */
-      return (sqlite3FkReferences(pTab) || pTab->pFKey);
+      eRet = (sqlite3FkReferences(pTab) || pTab->pFKey);
     }else{
       /* This is an UPDATE. Foreign key processing is only required if the
       ** operation modifies one or more child or parent key columns. */
@@ -1109,16 +1118,22 @@ int sqlite3FkRequired(
 
       /* Check if any child key columns are being modified. */
       for(p=pTab->pFKey; p; p=p->pNextFrom){
-        if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
+        if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
+        if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
+          eRet = 1;
+        }
       }
 
       /* Check if any parent key columns are being modified. */
       for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
-        if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
+        if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
+          if( p->aAction[1]!=OE_None ) return 2;
+          eRet = 1;
+        }
       }
     }
   }
-  return 0;
+  return eRet;
 }
 
 /*
index 8fca7eb9882e2e980b5b886c639e51516d4e1041..fa8885be6655fb78fd0d0ffa8fd9fb209671b24e 100644 (file)
@@ -285,7 +285,7 @@ void sqlite3Update(
   */
   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
     int reg;
-    if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
+    if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
       reg = ++pParse->nMem;
       pParse->nMem += pIdx->nColumn;
     }else{
@@ -640,7 +640,7 @@ void sqlite3Update(
     assert( regNew==regNewRowid+1 );
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
     sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
-        OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
+        OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
         regNewRowid
     );
     if( eOnePass==ONEPASS_MULTI ){
@@ -651,7 +651,7 @@ void sqlite3Update(
       sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
     }
 #else
-    if( hasFK || chngKey ){
+    if( hasFK>1 || chngKey ){
       sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
     }
 #endif