1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-19 21:43:15 +03:00

Avoid updating unaffected indexes on a table as part of an UPDATE that requires

foreign key processing in some cases.

FossilOrigin-Name: 477bea9ed0dd0fa69896bfd16d9b1d22170cbab784e3279ce65c29c47e032f34
This commit is contained in:
dan
2017-04-11 19:58:55 +00:00
parent ff6d50e973
commit 940b5eaa5e
4 changed files with 36 additions and 18 deletions

View 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;
}
/*