diff options
author | dan <dan@noemail.net> | 2016-11-08 19:22:32 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2016-11-08 19:22:32 +0000 |
commit | 3b908d41a0d3800a6ebe5dff42f4117fc342105c (patch) | |
tree | 242e72091b2d7747b23816f006bf885fe42d61ca /src/insert.c | |
parent | 9d06ff2cb7f4ae51be6f394532fc8a8a2b25758b (diff) | |
download | sqlite-3b908d41a0d3800a6ebe5dff42f4117fc342105c.tar.gz sqlite-3b908d41a0d3800a6ebe5dff42f4117fc342105c.zip |
Avoid superfluous cursor seeks in "INSERT OR REPLACE" statements.
FossilOrigin-Name: bec5b6d4d083556d111a89186b4f7b35b5e7cebf
Diffstat (limited to 'src/insert.c')
-rw-r--r-- | src/insert.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/insert.c b/src/insert.c index 8167ff78c..6ea3810a2 100644 --- a/src/insert.c +++ b/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 + ); } } |