mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Avoid superfluous cursor seeks in "INSERT OR REPLACE" statements.
FossilOrigin-Name: bec5b6d4d083556d111a89186b4f7b35b5e7cebf
This commit is contained in:
16
src/insert.c
16
src/insert.c
@@ -995,12 +995,26 @@ void sqlite3Insert(
|
||||
#endif
|
||||
{
|
||||
int isReplace; /* Set to true if constraints may cause a replace */
|
||||
int bUseSeek; /* True to use OPFLAG_SEEKRESULT */
|
||||
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
|
||||
regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
|
||||
);
|
||||
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
|
||||
|
||||
/* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
|
||||
** constraints or (b) there are no triggers and this table is not a
|
||||
** parent table in a foreign key constraint. It is safe to set the
|
||||
** flag in the second case as if any REPLACE constraint is hit, an
|
||||
** OP_Delete or OP_IdxDelete instruction will be executed on each
|
||||
** cursor that is disturbed. And these instructions both clear the
|
||||
** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
|
||||
** functionality. */
|
||||
bUseSeek = (isReplace==0 || (pTrigger==0 &&
|
||||
((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
|
||||
));
|
||||
sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
|
||||
regIns, aRegIdx, 0, appendFlag, isReplace==0);
|
||||
regIns, aRegIdx, 0, appendFlag, bUseSeek
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user